summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/modules/imagecapture
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/blink/renderer/modules/imagecapture')
-rw-r--r--chromium/third_party/blink/renderer/modules/imagecapture/image_capture.cc178
-rw-r--r--chromium/third_party/blink/renderer/modules/imagecapture/image_capture.h27
-rw-r--r--chromium/third_party/blink/renderer/modules/imagecapture/image_capture.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/imagecapture/image_capture_frame_grabber.cc12
-rw-r--r--chromium/third_party/blink/renderer/modules/imagecapture/image_capture_frame_grabber.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/imagecapture/photo_capabilities.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/imagecapture/photo_capabilities.h2
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_;