diff options
Diffstat (limited to 'chromium/third_party/blink/renderer/modules/imagecapture')
7 files changed, 156 insertions, 71 deletions
diff --git a/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.cc b/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.cc index b88de431f99..79767cd1334 100644 --- a/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.cc +++ b/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.cc @@ -7,9 +7,10 @@ #include <memory> #include <utility> +#include "mojo/public/cpp/bindings/pending_remote.h" #include "third_party/blink/public/common/browser_interface_broker_proxy.h" +#include "third_party/blink/public/mojom/permissions/permission_status.mojom-blink.h" #include "third_party/blink/public/platform/platform.h" -#include "third_party/blink/public/platform/web_media_stream_track.h" #include "third_party/blink/renderer/bindings/core/v8/callback_promise_adapter.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_media_track_capabilities.h" @@ -23,8 +24,10 @@ #include "third_party/blink/renderer/modules/imagecapture/media_settings_range.h" #include "third_party/blink/renderer/modules/imagecapture/photo_capabilities.h" #include "third_party/blink/renderer/modules/mediastream/media_stream_track.h" +#include "third_party/blink/renderer/modules/permissions/permission_utils.h" #include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/instrumentation/use_counter.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h" #include "third_party/blink/renderer/platform/mojo/mojo_helper.h" #include "third_party/blink/renderer/platform/wtf/functional.h" @@ -95,7 +98,14 @@ ImageCapture* ImageCapture::Create(ExecutionContext* context, return nullptr; } - return MakeGarbageCollected<ImageCapture>(context, track); + // The initial PTZ permission comes from the internal ImageCapture object of + // the track, if already created. + bool pan_tilt_zoom_allowed = + (track->GetImageCapture() && + track->GetImageCapture()->HasPanTiltZoomPermissionGranted()); + + return MakeGarbageCollected<ImageCapture>(context, track, + pan_tilt_zoom_allowed); } ImageCapture::~ImageCapture() { @@ -258,39 +268,6 @@ ScriptPromise ImageCapture::setOptions(ScriptState* script_state, return promise; } -ScriptPromise ImageCapture::takePhoto(ScriptState* script_state) { - TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("video_and_image_capture"), - "ImageCapture::takePhoto", TRACE_EVENT_SCOPE_PROCESS); - auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); - ScriptPromise promise = resolver->Promise(); - - if (TrackIsInactive(*stream_track_)) { - resolver->Reject(MakeGarbageCollected<DOMException>( - DOMExceptionCode::kInvalidStateError, - "The associated Track is in an invalid state.")); - return promise; - } - if (!service_.is_bound()) { - resolver->Reject(MakeGarbageCollected<DOMException>( - DOMExceptionCode::kNotFoundError, kNoServiceError)); - return promise; - } - - service_requests_.insert(resolver); - - // m_streamTrack->component()->source()->id() is the renderer "name" of the - // camera; - // TODO(mcasas) consider sending the security origin as well: - // scriptState->getExecutionContext()->getSecurityOrigin()->toString() - TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("video_and_image_capture"), - "ImageCapture::takePhoto", TRACE_EVENT_SCOPE_PROCESS); - service_->TakePhoto( - stream_track_->Component()->Source()->Id(), - WTF::Bind(&ImageCapture::OnMojoTakePhoto, WrapPersistent(this), - WrapPersistent(resolver))); - return promise; -} - ScriptPromise ImageCapture::takePhoto(ScriptState* script_state, const PhotoSettings* photo_settings) { TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("video_and_image_capture"), @@ -323,19 +300,63 @@ ScriptPromise ImageCapture::grabFrame(ScriptState* script_state) { return promise; } - // The platform does not know about MediaStreamTrack, so we wrap it up. - WebMediaStreamTrack track(stream_track_->Component()); auto resolver_callback_adapter = std::make_unique<CallbackPromiseAdapter<ImageBitmap, void>>(resolver); - frame_grabber_->GrabFrame(&track, std::move(resolver_callback_adapter), + frame_grabber_->GrabFrame(stream_track_->Component(), + std::move(resolver_callback_adapter), ExecutionContext::From(script_state) ->GetTaskRunner(TaskType::kDOMManipulation)); return promise; } -MediaTrackCapabilities* ImageCapture::GetMediaTrackCapabilities() const { - return capabilities_; +void ImageCapture::GetMediaTrackCapabilities( + MediaTrackCapabilities* capabilities) const { + // Merge any present |capabilities_| members into |capabilities|. + + if (capabilities_->hasWhiteBalanceMode()) + capabilities->setWhiteBalanceMode(capabilities_->whiteBalanceMode()); + if (capabilities_->hasExposureMode()) + capabilities->setExposureMode(capabilities_->exposureMode()); + if (capabilities_->hasFocusMode()) + capabilities->setFocusMode(capabilities_->focusMode()); + if (capabilities_->hasExposureCompensation()) { + capabilities->setExposureCompensation( + capabilities_->exposureCompensation()); + } + if (capabilities_->hasExposureTime()) + capabilities->setExposureTime(capabilities_->exposureTime()); + + if (capabilities_->hasColorTemperature()) + capabilities->setColorTemperature(capabilities_->colorTemperature()); + if (capabilities_->hasIso()) + capabilities->setIso(capabilities_->iso()); + + if (capabilities_->hasBrightness()) + capabilities->setBrightness(capabilities_->brightness()); + if (capabilities_->hasContrast()) + capabilities->setContrast(capabilities_->contrast()); + if (capabilities_->hasSaturation()) + capabilities->setSaturation(capabilities_->saturation()); + if (capabilities_->hasSharpness()) + capabilities->setSharpness(capabilities_->sharpness()); + + if (capabilities_->hasFocusDistance()) + capabilities->setFocusDistance(capabilities_->focusDistance()); + + if (HasPanTiltZoomPermissionGranted()) { + if (capabilities_->hasPan()) + capabilities->setPan(capabilities_->pan()); + if (capabilities_->hasTilt()) + capabilities->setTilt(capabilities_->tilt()); + } + // TODO(crbug.com/934063): Check HasPanTiltZoomPermissionGranted() as well if + // upcoming metrics show that zoom may be moved under this permission. + if (capabilities_->hasZoom()) + capabilities->setZoom(capabilities_->zoom()); + + if (capabilities_->hasTorch()) + capabilities->setTorch(capabilities_->torch()); } // TODO(mcasas): make the implementation fully Spec compliant, see the TODOs @@ -404,8 +425,12 @@ void ImageCapture::SetMediaTrackConstraints( (constraints->hasSaturation() && !capabilities_->hasSaturation()) || (constraints->hasSharpness() && !capabilities_->hasSharpness()) || (constraints->hasFocusDistance() && !capabilities_->hasFocusDistance()) || - (constraints->hasPan() && !capabilities_->hasPan()) || - (constraints->hasTilt() && !capabilities_->hasTilt()) || + (constraints->hasPan() && + !(capabilities_->hasPan() && HasPanTiltZoomPermissionGranted())) || + (constraints->hasTilt() && + !(capabilities_->hasTilt() && HasPanTiltZoomPermissionGranted())) || + // TODO(crbug.com/934063): Check HasPanTiltZoomPermissionGranted() as well + // if upcoming metrics show that zoom may be moved under this permission. (constraints->hasZoom() && !capabilities_->hasZoom()) || (constraints->hasTorch() && !capabilities_->hasTorch())) { resolver->Reject(MakeGarbageCollected<DOMException>( @@ -716,26 +741,39 @@ void ImageCapture::GetMediaTrackSettings(MediaTrackSettings* settings) const { if (settings_->hasFocusDistance()) settings->setFocusDistance(settings_->focusDistance()); - if (settings_->hasPan()) - settings->setPan(settings_->pan()); - if (settings_->hasTilt()) - settings->setTilt(settings_->tilt()); + if (HasPanTiltZoomPermissionGranted()) { + if (settings_->hasPan()) + settings->setPan(settings_->pan()); + if (settings_->hasTilt()) + settings->setTilt(settings_->tilt()); + } + // TODO(crbug.com/934063): Check HasPanTiltZoomPermissionGranted() as well if + // upcoming metrics show that zoom may be moved under this permission. if (settings_->hasZoom()) settings->setZoom(settings_->zoom()); + if (settings_->hasTorch()) settings->setTorch(settings_->torch()); } -ImageCapture::ImageCapture(ExecutionContext* context, MediaStreamTrack* track) +ImageCapture::ImageCapture(ExecutionContext* context, + MediaStreamTrack* track, + bool pan_tilt_zoom_allowed) : ExecutionContextLifecycleObserver(context), stream_track_(track), service_(context), + pan_tilt_zoom_permission_(pan_tilt_zoom_allowed + ? mojom::blink::PermissionStatus::GRANTED + : mojom::blink::PermissionStatus::ASK), + permission_service_(context), + permission_observer_receiver_(this, context), capabilities_(MediaTrackCapabilities::Create()), settings_(MediaTrackSettings::Create()), current_constraints_(MediaTrackConstraintSet::Create()), photo_settings_(PhotoSettings::Create()) { DCHECK(stream_track_); DCHECK(!service_.is_bound()); + DCHECK(!permission_service_.is_bound()); // This object may be constructed over an ExecutionContext that has already // been detached. In this case the ImageCapture service will not be available. @@ -754,6 +792,30 @@ ImageCapture::ImageCapture(ExecutionContext* context, MediaStreamTrack* track) service_->GetPhotoState(stream_track_->Component()->Source()->Id(), WTF::Bind(&ImageCapture::UpdateMediaTrackCapabilities, WrapPersistent(this))); + + ConnectToPermissionService( + context, permission_service_.BindNewPipeAndPassReceiver( + context->GetTaskRunner(TaskType::kMiscPlatformAPI))); + + mojo::PendingRemote<mojom::blink::PermissionObserver> observer; + permission_observer_receiver_.Bind( + observer.InitWithNewPipeAndPassReceiver(), + context->GetTaskRunner(TaskType::kMiscPlatformAPI)); + permission_service_->AddPermissionObserver( + CreateVideoCapturePermissionDescriptor(/*pan_tilt_zoom=*/true), + pan_tilt_zoom_permission_, std::move(observer)); +} + +void ImageCapture::OnPermissionStatusChange( + mojom::blink::PermissionStatus status) { + pan_tilt_zoom_permission_ = status; +} + +bool ImageCapture::HasPanTiltZoomPermissionGranted() const { + if (!RuntimeEnabledFeatures::MediaCapturePanTiltEnabled()) + return false; + + return pan_tilt_zoom_permission_ == mojom::blink::PermissionStatus::GRANTED; } void ImageCapture::OnMojoGetPhotoState( @@ -951,14 +1013,18 @@ void ImageCapture::UpdateMediaTrackCapabilities( settings_->setFocusDistance(photo_state->focus_distance->current); } - if (photo_state->pan->max != photo_state->pan->min) { - capabilities_->setPan(MediaSettingsRange::Create(*photo_state->pan)); - settings_->setPan(photo_state->pan->current); - } - if (photo_state->tilt->max != photo_state->tilt->min) { - capabilities_->setTilt(MediaSettingsRange::Create(*photo_state->tilt)); - settings_->setTilt(photo_state->tilt->current); + if (HasPanTiltZoomPermissionGranted()) { + if (photo_state->pan->max != photo_state->pan->min) { + capabilities_->setPan(MediaSettingsRange::Create(*photo_state->pan)); + settings_->setPan(photo_state->pan->current); + } + if (photo_state->tilt->max != photo_state->tilt->min) { + capabilities_->setTilt(MediaSettingsRange::Create(*photo_state->tilt)); + settings_->setTilt(photo_state->tilt->current); + } } + // TODO(crbug.com/934063): Check HasPanTiltZoomPermissionGranted() as well if + // upcoming metrics show that zoom may be moved under this permission. if (photo_state->zoom->max != photo_state->zoom->min) { capabilities_->setZoom(MediaSettingsRange::Create(*photo_state->zoom)); settings_->setZoom(photo_state->zoom->current); @@ -995,9 +1061,11 @@ void ImageCapture::ResolveWithPhotoCapabilities( resolver->Resolve(photo_capabilities_); } -void ImageCapture::Trace(Visitor* visitor) { +void ImageCapture::Trace(Visitor* visitor) const { visitor->Trace(stream_track_); visitor->Trace(service_); + visitor->Trace(permission_service_); + visitor->Trace(permission_observer_receiver_); visitor->Trace(capabilities_); visitor->Trace(settings_); visitor->Trace(photo_settings_); diff --git a/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.h b/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.h index d35156e61bf..7a5365b2ed4 100644 --- a/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.h +++ b/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.h @@ -7,6 +7,7 @@ #include <memory> #include "media/capture/mojom/image_capture.mojom-blink.h" +#include "third_party/blink/public/mojom/permissions/permission.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_media_track_capabilities.h" @@ -17,6 +18,7 @@ #include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h" #include "third_party/blink/renderer/modules/event_target_modules.h" #include "third_party/blink/renderer/modules/modules_export.h" +#include "third_party/blink/renderer/platform/mojo/heap_mojo_receiver.h" #include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h" #include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h" @@ -33,7 +35,8 @@ class ScriptPromiseResolver; class MODULES_EXPORT ImageCapture final : public EventTargetWithInlineData, public ActiveScriptWrappable<ImageCapture>, - public ExecutionContextLifecycleObserver { + public ExecutionContextLifecycleObserver, + public mojom::blink::PermissionObserver { USING_GARBAGE_COLLECTED_MIXIN(ImageCapture); DEFINE_WRAPPERTYPEINFO(); @@ -42,7 +45,9 @@ class MODULES_EXPORT ImageCapture final MediaStreamTrack*, ExceptionState&); - ImageCapture(ExecutionContext*, MediaStreamTrack*); + ImageCapture(ExecutionContext*, + MediaStreamTrack*, + bool pan_tilt_zoom_allowed); ~ImageCapture() override; // EventTarget implementation. @@ -64,12 +69,11 @@ class MODULES_EXPORT ImageCapture final const PhotoSettings*, bool trigger_take_photo = false); - ScriptPromise takePhoto(ScriptState*); ScriptPromise takePhoto(ScriptState*, const PhotoSettings*); ScriptPromise grabFrame(ScriptState*); - MediaTrackCapabilities* GetMediaTrackCapabilities() const; + void GetMediaTrackCapabilities(MediaTrackCapabilities*) const; void SetMediaTrackConstraints( ScriptPromiseResolver*, const HeapVector<Member<MediaTrackConstraintSet>>&); @@ -77,12 +81,18 @@ class MODULES_EXPORT ImageCapture final void ClearMediaTrackConstraints(); void GetMediaTrackSettings(MediaTrackSettings*) const; - void Trace(Visitor*) override; + bool HasPanTiltZoomPermissionGranted() const; + + void Trace(Visitor*) const override; private: using PromiseResolverFunction = base::OnceCallback<void(ScriptPromiseResolver*)>; + // mojom::blink::PermissionObserver implementation. + // Called when we get an updated PTZ permission value from the browser. + void OnPermissionStatusChange(mojom::blink::PermissionStatus) override; + void OnMojoGetPhotoState(ScriptPromiseResolver*, PromiseResolverFunction, bool trigger_take_photo, @@ -105,6 +115,13 @@ class MODULES_EXPORT ImageCapture final HeapMojoWrapperMode::kWithoutContextObserver> service_; + // Whether the user has granted permission for the user to control camera PTZ. + mojom::blink::PermissionStatus pan_tilt_zoom_permission_; + // The permission service, enabling us to check for the PTZ permission. + HeapMojoRemote<mojom::blink::PermissionService> permission_service_; + HeapMojoReceiver<mojom::blink::PermissionObserver, ImageCapture> + permission_observer_receiver_; + Member<MediaTrackCapabilities> capabilities_; Member<MediaTrackSettings> settings_; Member<MediaTrackConstraintSet> current_constraints_; diff --git a/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.idl b/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.idl index d27b2659a99..9f70ed62bde 100644 --- a/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.idl +++ b/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.idl @@ -13,6 +13,6 @@ [CallWith=ScriptState] Promise<PhotoCapabilities> getPhotoCapabilities(); [CallWith=ScriptState] Promise<PhotoSettings> getPhotoSettings(); - [CallWith=ScriptState] Promise<Blob> takePhoto(optional PhotoSettings photoSettings); + [CallWith=ScriptState] Promise<Blob> takePhoto(optional PhotoSettings photoSettings = {}); [CallWith=ScriptState] Promise<ImageBitmap> grabFrame(); }; diff --git a/chromium/third_party/blink/renderer/modules/imagecapture/image_capture_frame_grabber.cc b/chromium/third_party/blink/renderer/modules/imagecapture/image_capture_frame_grabber.cc index dfc36212876..211f6e2e831 100644 --- a/chromium/third_party/blink/renderer/modules/imagecapture/image_capture_frame_grabber.cc +++ b/chromium/third_party/blink/renderer/modules/imagecapture/image_capture_frame_grabber.cc @@ -9,9 +9,9 @@ #include "media/base/video_types.h" #include "media/base/video_util.h" #include "skia/ext/platform_canvas.h" -#include "third_party/blink/public/platform/web_media_stream_source.h" -#include "third_party/blink/public/platform/web_media_stream_track.h" #include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_source.h" #include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h" #include "third_party/blink/renderer/platform/wtf/functional.h" #include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h" @@ -187,14 +187,14 @@ ImageCaptureFrameGrabber::~ImageCaptureFrameGrabber() { } void ImageCaptureFrameGrabber::GrabFrame( - WebMediaStreamTrack* track, + MediaStreamComponent* component, std::unique_ptr<ImageCaptureGrabFrameCallbacks> callbacks, scoped_refptr<base::SingleThreadTaskRunner> task_runner) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(!!callbacks); - DCHECK(track && !track->IsNull() && track->GetPlatformTrack()); - DCHECK_EQ(WebMediaStreamSource::kTypeVideo, track->Source().GetType()); + DCHECK(component && component->GetPlatformTrack()); + DCHECK_EQ(MediaStreamSource::kTypeVideo, component->Source()->GetType()); if (frame_grab_in_progress_) { // Reject grabFrame()s too close back to back. @@ -212,7 +212,7 @@ void ImageCaptureFrameGrabber::GrabFrame( // https://crbug.com/623042. frame_grab_in_progress_ = true; MediaStreamVideoSink::ConnectToTrack( - *track, + component, ConvertToBaseRepeatingCallback(CrossThreadBindRepeating( &SingleShotFrameHandler::OnVideoFrameOnIOThread, base::MakeRefCounted<SingleShotFrameHandler>(), diff --git a/chromium/third_party/blink/renderer/modules/imagecapture/image_capture_frame_grabber.h b/chromium/third_party/blink/renderer/modules/imagecapture/image_capture_frame_grabber.h index f050a850607..a4376955763 100644 --- a/chromium/third_party/blink/renderer/modules/imagecapture/image_capture_frame_grabber.h +++ b/chromium/third_party/blink/renderer/modules/imagecapture/image_capture_frame_grabber.h @@ -22,7 +22,7 @@ class SkImage; namespace blink { class ImageBitmap; -class WebMediaStreamTrack; +class MediaStreamComponent; // A ScopedWebCallbacks is a move-only scoper which helps manage the lifetime of // a blink::WebCallbacks object. This is particularly useful when you're @@ -130,7 +130,7 @@ class ImageCaptureFrameGrabber final : public MediaStreamVideoSink { ImageCaptureFrameGrabber(); ~ImageCaptureFrameGrabber() override; - void GrabFrame(WebMediaStreamTrack* track, + void GrabFrame(MediaStreamComponent* component, std::unique_ptr<ImageCaptureGrabFrameCallbacks> callbacks, scoped_refptr<base::SingleThreadTaskRunner> task_runner); diff --git a/chromium/third_party/blink/renderer/modules/imagecapture/photo_capabilities.cc b/chromium/third_party/blink/renderer/modules/imagecapture/photo_capabilities.cc index 04cea46c1d5..e3121991b06 100644 --- a/chromium/third_party/blink/renderer/modules/imagecapture/photo_capabilities.cc +++ b/chromium/third_party/blink/renderer/modules/imagecapture/photo_capabilities.cc @@ -45,7 +45,7 @@ bool PhotoCapabilities::IsRedEyeReductionControllable() const { media::mojom::blink::RedEyeReduction::CONTROLLABLE; } -void PhotoCapabilities::Trace(Visitor* visitor) { +void PhotoCapabilities::Trace(Visitor* visitor) const { visitor->Trace(image_height_); visitor->Trace(image_width_); ScriptWrappable::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/imagecapture/photo_capabilities.h b/chromium/third_party/blink/renderer/modules/imagecapture/photo_capabilities.h index 273ec23828b..ec69a6f3014 100644 --- a/chromium/third_party/blink/renderer/modules/imagecapture/photo_capabilities.h +++ b/chromium/third_party/blink/renderer/modules/imagecapture/photo_capabilities.h @@ -38,7 +38,7 @@ class PhotoCapabilities final : public ScriptWrappable { } bool IsRedEyeReductionControllable() const; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<MediaSettingsRange> image_height_; |