OLD | NEW |
---|---|
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "modules/imagecapture/ImageCapture.h" | 5 #include "modules/imagecapture/ImageCapture.h" |
6 | 6 |
7 #include "bindings/core/v8/CallbackPromiseAdapter.h" | 7 #include "bindings/core/v8/CallbackPromiseAdapter.h" |
8 #include "bindings/core/v8/ScriptPromiseResolver.h" | 8 #include "bindings/core/v8/ScriptPromiseResolver.h" |
9 #include "core/dom/DOMException.h" | 9 #include "core/dom/DOMException.h" |
10 #include "core/dom/ExceptionCode.h" | 10 #include "core/dom/ExceptionCode.h" |
11 #include "core/fileapi/Blob.h" | 11 #include "core/fileapi/Blob.h" |
12 #include "core/frame/ImageBitmap.h" | 12 #include "core/frame/ImageBitmap.h" |
13 #include "modules/EventTargetModules.h" | 13 #include "modules/EventTargetModules.h" |
14 #include "modules/imagecapture/MediaSettingsRange.h" | 14 #include "modules/imagecapture/MediaSettingsRange.h" |
15 #include "modules/imagecapture/PhotoCapabilities.h" | 15 #include "modules/imagecapture/PhotoCapabilities.h" |
16 #include "modules/imagecapture/PhotoSettings.h" | 16 #include "modules/imagecapture/PhotoSettings.h" |
17 #include "modules/mediastream/MediaStreamTrack.h" | 17 #include "modules/mediastream/MediaStreamTrack.h" |
18 #include "modules/mediastream/MediaTrackCapabilities.h" | 18 #include "modules/mediastream/MediaTrackCapabilities.h" |
19 #include "modules/mediastream/MediaTrackConstraintSet.h" | |
19 #include "platform/WaitableEvent.h" | 20 #include "platform/WaitableEvent.h" |
20 #include "platform/mojo/MojoHelper.h" | 21 #include "platform/mojo/MojoHelper.h" |
21 #include "public/platform/InterfaceProvider.h" | 22 #include "public/platform/InterfaceProvider.h" |
22 #include "public/platform/Platform.h" | 23 #include "public/platform/Platform.h" |
23 #include "public/platform/WebImageCaptureFrameGrabber.h" | 24 #include "public/platform/WebImageCaptureFrameGrabber.h" |
24 #include "public/platform/WebMediaStreamTrack.h" | 25 #include "public/platform/WebMediaStreamTrack.h" |
25 #include "wtf/PtrUtil.h" | 26 #include "wtf/PtrUtil.h" |
26 | 27 |
27 namespace blink { | 28 namespace blink { |
28 | 29 |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
107 bool ImageCapture::hasPendingActivity() const { | 108 bool ImageCapture::hasPendingActivity() const { |
108 return getExecutionContext() && hasEventListeners(); | 109 return getExecutionContext() && hasEventListeners(); |
109 } | 110 } |
110 | 111 |
111 void ImageCapture::contextDestroyed(ExecutionContext*) { | 112 void ImageCapture::contextDestroyed(ExecutionContext*) { |
112 removeAllEventListeners(); | 113 removeAllEventListeners(); |
113 m_serviceRequests.clear(); | 114 m_serviceRequests.clear(); |
114 DCHECK(!hasEventListeners()); | 115 DCHECK(!hasEventListeners()); |
115 } | 116 } |
116 | 117 |
117 ScriptPromise ImageCapture::getPhotoCapabilities( | 118 ScriptPromise ImageCapture::getPhotoCapabilities(ScriptState* scriptState) { |
118 ScriptState* scriptState, | |
119 ExceptionState& exceptionState) { | |
120 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); | 119 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); |
121 ScriptPromise promise = resolver->promise(); | 120 ScriptPromise promise = resolver->promise(); |
122 | 121 |
123 if (!m_service) { | 122 if (!m_service) { |
124 resolver->reject(DOMException::create(NotFoundError, kNoServiceError)); | 123 resolver->reject(DOMException::create(NotFoundError, kNoServiceError)); |
125 return promise; | 124 return promise; |
126 } | 125 } |
127 | |
128 m_serviceRequests.insert(resolver); | 126 m_serviceRequests.insert(resolver); |
129 | 127 |
130 // m_streamTrack->component()->source()->id() is the renderer "name" of the | 128 // m_streamTrack->component()->source()->id() is the renderer "name" of the |
131 // camera; | 129 // camera; |
132 // TODO(mcasas) consider sending the security origin as well: | 130 // TODO(mcasas) consider sending the security origin as well: |
133 // scriptState->getExecutionContext()->getSecurityOrigin()->toString() | 131 // scriptState->getExecutionContext()->getSecurityOrigin()->toString() |
134 m_service->GetCapabilities( | 132 m_service->GetCapabilities( |
135 m_streamTrack->component()->source()->id(), | 133 m_streamTrack->component()->source()->id(), |
136 convertToBaseCallback(WTF::bind(&ImageCapture::onCapabilities, | 134 convertToBaseCallback(WTF::bind(&ImageCapture::onCapabilities, |
137 wrapPersistent(this), | 135 wrapPersistent(this), |
138 wrapPersistent(resolver)))); | 136 wrapPersistent(resolver)))); |
139 return promise; | 137 return promise; |
140 } | 138 } |
141 | 139 |
142 ScriptPromise ImageCapture::setOptions(ScriptState* scriptState, | 140 ScriptPromise ImageCapture::setOptions(ScriptState* scriptState, |
143 const PhotoSettings& photoSettings, | 141 const PhotoSettings& photoSettings) { |
144 ExceptionState& exceptionState) { | |
145 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); | 142 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); |
146 ScriptPromise promise = resolver->promise(); | 143 ScriptPromise promise = resolver->promise(); |
147 | 144 |
148 if (trackIsInactive(*m_streamTrack)) { | 145 if (trackIsInactive(*m_streamTrack)) { |
149 resolver->reject(DOMException::create( | 146 resolver->reject(DOMException::create( |
150 InvalidStateError, "The associated Track is in an invalid state.")); | 147 InvalidStateError, "The associated Track is in an invalid state.")); |
151 return promise; | 148 return promise; |
152 } | 149 } |
153 | 150 |
154 if (!m_service) { | 151 if (!m_service) { |
155 resolver->reject(DOMException::create(NotFoundError, kNoServiceError)); | 152 resolver->reject(DOMException::create(NotFoundError, kNoServiceError)); |
156 return promise; | 153 return promise; |
157 } | 154 } |
158 | |
159 m_serviceRequests.insert(resolver); | 155 m_serviceRequests.insert(resolver); |
160 | 156 |
161 // TODO(mcasas): should be using a mojo::StructTraits instead. | 157 // TODO(mcasas): should be using a mojo::StructTraits instead. |
162 media::mojom::blink::PhotoSettingsPtr settings = | 158 auto settings = media::mojom::blink::PhotoSettings::New(); |
163 media::mojom::blink::PhotoSettings::New(); | 159 |
164 settings->has_zoom = photoSettings.hasZoom(); | 160 settings->has_zoom = photoSettings.hasZoom(); |
165 if (settings->has_zoom) | 161 if (settings->has_zoom) |
166 settings->zoom = photoSettings.zoom(); | 162 settings->zoom = photoSettings.zoom(); |
167 settings->has_height = photoSettings.hasImageHeight(); | 163 settings->has_height = photoSettings.hasImageHeight(); |
168 if (settings->has_height) | 164 if (settings->has_height) |
169 settings->height = photoSettings.imageHeight(); | 165 settings->height = photoSettings.imageHeight(); |
170 settings->has_width = photoSettings.hasImageWidth(); | 166 settings->has_width = photoSettings.hasImageWidth(); |
171 if (settings->has_width) | 167 if (settings->has_width) |
172 settings->width = photoSettings.imageWidth(); | 168 settings->width = photoSettings.imageWidth(); |
173 settings->has_focus_mode = photoSettings.hasFocusMode(); | 169 settings->has_focus_mode = photoSettings.hasFocusMode(); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
218 settings->sharpness = photoSettings.sharpness(); | 214 settings->sharpness = photoSettings.sharpness(); |
219 | 215 |
220 m_service->SetOptions(m_streamTrack->component()->source()->id(), | 216 m_service->SetOptions(m_streamTrack->component()->source()->id(), |
221 std::move(settings), | 217 std::move(settings), |
222 convertToBaseCallback(WTF::bind( | 218 convertToBaseCallback(WTF::bind( |
223 &ImageCapture::onSetOptions, wrapPersistent(this), | 219 &ImageCapture::onSetOptions, wrapPersistent(this), |
224 wrapPersistent(resolver)))); | 220 wrapPersistent(resolver)))); |
225 return promise; | 221 return promise; |
226 } | 222 } |
227 | 223 |
228 ScriptPromise ImageCapture::takePhoto(ScriptState* scriptState, | 224 ScriptPromise ImageCapture::takePhoto(ScriptState* scriptState) { |
229 ExceptionState& exceptionState) { | |
230 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); | 225 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); |
231 ScriptPromise promise = resolver->promise(); | 226 ScriptPromise promise = resolver->promise(); |
232 | 227 |
233 if (trackIsInactive(*m_streamTrack)) { | 228 if (trackIsInactive(*m_streamTrack)) { |
234 resolver->reject(DOMException::create( | 229 resolver->reject(DOMException::create( |
235 InvalidStateError, "The associated Track is in an invalid state.")); | 230 InvalidStateError, "The associated Track is in an invalid state.")); |
236 return promise; | 231 return promise; |
237 } | 232 } |
238 | |
239 if (!m_service) { | 233 if (!m_service) { |
240 resolver->reject(DOMException::create(NotFoundError, kNoServiceError)); | 234 resolver->reject(DOMException::create(NotFoundError, kNoServiceError)); |
241 return promise; | 235 return promise; |
242 } | 236 } |
243 | 237 |
244 m_serviceRequests.insert(resolver); | 238 m_serviceRequests.insert(resolver); |
245 | 239 |
246 // m_streamTrack->component()->source()->id() is the renderer "name" of the | 240 // m_streamTrack->component()->source()->id() is the renderer "name" of the |
247 // camera; | 241 // camera; |
248 // TODO(mcasas) consider sending the security origin as well: | 242 // TODO(mcasas) consider sending the security origin as well: |
249 // scriptState->getExecutionContext()->getSecurityOrigin()->toString() | 243 // scriptState->getExecutionContext()->getSecurityOrigin()->toString() |
250 m_service->TakePhoto(m_streamTrack->component()->source()->id(), | 244 m_service->TakePhoto(m_streamTrack->component()->source()->id(), |
251 convertToBaseCallback(WTF::bind( | 245 convertToBaseCallback(WTF::bind( |
252 &ImageCapture::onTakePhoto, wrapPersistent(this), | 246 &ImageCapture::onTakePhoto, wrapPersistent(this), |
253 wrapPersistent(resolver)))); | 247 wrapPersistent(resolver)))); |
254 return promise; | 248 return promise; |
255 } | 249 } |
256 | 250 |
257 ScriptPromise ImageCapture::grabFrame(ScriptState* scriptState, | 251 ScriptPromise ImageCapture::grabFrame(ScriptState* scriptState) { |
258 ExceptionState& exceptionState) { | |
259 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); | 252 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); |
260 ScriptPromise promise = resolver->promise(); | 253 ScriptPromise promise = resolver->promise(); |
261 | 254 |
262 if (trackIsInactive(*m_streamTrack)) { | 255 if (trackIsInactive(*m_streamTrack)) { |
263 resolver->reject(DOMException::create( | 256 resolver->reject(DOMException::create( |
264 InvalidStateError, "The associated Track is in an invalid state.")); | 257 InvalidStateError, "The associated Track is in an invalid state.")); |
265 return promise; | 258 return promise; |
266 } | 259 } |
267 | 260 |
268 // Create |m_frameGrabber| the first time. | 261 // Create |m_frameGrabber| the first time. |
(...skipping 13 matching lines...) Expand all Loading... | |
282 m_frameGrabber->grabFrame( | 275 m_frameGrabber->grabFrame( |
283 &track, new CallbackPromiseAdapter<ImageBitmap, void>(resolver)); | 276 &track, new CallbackPromiseAdapter<ImageBitmap, void>(resolver)); |
284 | 277 |
285 return promise; | 278 return promise; |
286 } | 279 } |
287 | 280 |
288 MediaTrackCapabilities& ImageCapture::getMediaTrackCapabilities() { | 281 MediaTrackCapabilities& ImageCapture::getMediaTrackCapabilities() { |
289 return m_capabilities; | 282 return m_capabilities; |
290 } | 283 } |
291 | 284 |
285 void ImageCapture::setMediaTrackConstraints( | |
286 ScriptPromiseResolver* resolver, | |
Guido Urdaneta
2017/03/17 00:30:27
Maybe add a TODO indicating that the constraints a
mcasas
2017/03/17 00:49:22
Done.
| |
287 const MediaTrackConstraintSet& constraints) { | |
288 if (!m_service) { | |
289 resolver->reject(DOMException::create(NotFoundError, kNoServiceError)); | |
290 return; | |
291 } | |
292 m_serviceRequests.insert(resolver); | |
293 | |
294 auto settings = media::mojom::blink::PhotoSettings::New(); | |
295 | |
296 // TODO(mcasas): support other Mode types beyond simple string i.e. the | |
297 // equivalents of "sequence<DOMString>"" or "ConstrainDOMStringParameters". | |
298 settings->has_white_balance_mode = constraints.hasWhiteBalanceMode() && | |
299 constraints.whiteBalanceMode().isString(); | |
300 if (settings->has_white_balance_mode) { | |
301 settings->white_balance_mode = | |
302 parseMeteringMode(constraints.whiteBalanceMode().getAsString()); | |
303 } | |
304 settings->has_exposure_mode = | |
305 constraints.hasExposureMode() && constraints.exposureMode().isString(); | |
306 if (settings->has_exposure_mode) { | |
307 settings->exposure_mode = | |
308 parseMeteringMode(constraints.exposureMode().getAsString()); | |
309 } | |
310 | |
311 settings->has_focus_mode = | |
312 constraints.hasFocusMode() && constraints.focusMode().isString(); | |
313 if (settings->has_focus_mode) { | |
314 settings->focus_mode = | |
315 parseMeteringMode(constraints.focusMode().getAsString()); | |
316 } | |
317 | |
318 // TODO(mcasas): support ConstrainDoubleRange where applicable. | |
319 settings->has_exposure_compensation = | |
320 constraints.hasExposureCompensation() && | |
321 constraints.exposureCompensation().isDouble(); | |
322 if (settings->has_exposure_compensation) { | |
323 settings->exposure_compensation = | |
324 constraints.exposureCompensation().getAsDouble(); | |
325 } | |
326 settings->has_color_temperature = constraints.hasColorTemperature() && | |
327 constraints.colorTemperature().isDouble(); | |
328 if (settings->has_color_temperature) | |
329 settings->color_temperature = constraints.colorTemperature().getAsDouble(); | |
330 settings->has_iso = constraints.hasIso() && constraints.iso().isDouble(); | |
331 if (settings->has_iso) | |
332 settings->iso = constraints.iso().getAsDouble(); | |
333 | |
334 settings->has_brightness = | |
335 constraints.hasBrightness() && constraints.brightness().isDouble(); | |
336 if (settings->has_brightness) | |
337 settings->brightness = constraints.brightness().getAsDouble(); | |
338 settings->has_contrast = | |
339 constraints.hasContrast() && constraints.contrast().isDouble(); | |
340 if (settings->has_contrast) | |
341 settings->contrast = constraints.contrast().getAsDouble(); | |
342 settings->has_saturation = | |
343 constraints.hasSaturation() && constraints.saturation().isDouble(); | |
344 if (settings->has_saturation) | |
345 settings->saturation = constraints.saturation().getAsDouble(); | |
346 settings->has_sharpness = | |
347 constraints.hasSharpness() && constraints.sharpness().isDouble(); | |
348 if (settings->has_sharpness) | |
349 settings->sharpness = constraints.sharpness().getAsDouble(); | |
350 | |
351 settings->has_zoom = constraints.hasZoom() && constraints.zoom().isDouble(); | |
352 if (settings->has_zoom) | |
353 settings->zoom = constraints.zoom().getAsDouble(); | |
354 | |
355 // TODO(mcasas): add |torch| when the mojom interface is updated, | |
356 // https://crbug.com/700607. | |
357 | |
358 m_service->SetOptions(m_streamTrack->component()->source()->id(), | |
359 std::move(settings), | |
360 convertToBaseCallback(WTF::bind( | |
361 &ImageCapture::onSetOptions, wrapPersistent(this), | |
362 wrapPersistent(resolver)))); | |
363 } | |
364 | |
292 ImageCapture::ImageCapture(ExecutionContext* context, MediaStreamTrack* track) | 365 ImageCapture::ImageCapture(ExecutionContext* context, MediaStreamTrack* track) |
293 : ContextLifecycleObserver(context), m_streamTrack(track) { | 366 : ContextLifecycleObserver(context), m_streamTrack(track) { |
294 DCHECK(m_streamTrack); | 367 DCHECK(m_streamTrack); |
295 DCHECK(!m_service.is_bound()); | 368 DCHECK(!m_service.is_bound()); |
296 | 369 |
297 Platform::current()->interfaceProvider()->getInterface( | 370 Platform::current()->interfaceProvider()->getInterface( |
298 mojo::MakeRequest(&m_service)); | 371 mojo::MakeRequest(&m_service)); |
299 | 372 |
300 m_service.set_connection_error_handler(convertToBaseCallback(WTF::bind( | 373 m_service.set_connection_error_handler(convertToBaseCallback(WTF::bind( |
301 &ImageCapture::onServiceConnectionError, wrapWeakPersistent(this)))); | 374 &ImageCapture::onServiceConnectionError, wrapWeakPersistent(this)))); |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
444 | 517 |
445 DEFINE_TRACE(ImageCapture) { | 518 DEFINE_TRACE(ImageCapture) { |
446 visitor->trace(m_streamTrack); | 519 visitor->trace(m_streamTrack); |
447 visitor->trace(m_capabilities); | 520 visitor->trace(m_capabilities); |
448 visitor->trace(m_serviceRequests); | 521 visitor->trace(m_serviceRequests); |
449 EventTargetWithInlineData::trace(visitor); | 522 EventTargetWithInlineData::trace(visitor); |
450 ContextLifecycleObserver::trace(visitor); | 523 ContextLifecycleObserver::trace(visitor); |
451 } | 524 } |
452 | 525 |
453 } // namespace blink | 526 } // namespace blink |
OLD | NEW |