Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(279)

Side by Side Diff: third_party/WebKit/Source/modules/imagecapture/ImageCapture.cpp

Issue 1926873002: MediaStream Image Capture (3): Adding mojo and browser impl for dummy takePhoto(). (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Removed isActive() in favour of checking m_serviceRequests.isEmpty() Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/frame/ImageBitmap.h" 12 #include "core/frame/ImageBitmap.h"
12 #include "modules/EventTargetModules.h" 13 #include "modules/EventTargetModules.h"
13 #include "modules/mediastream/MediaStreamTrack.h" 14 #include "modules/mediastream/MediaStreamTrack.h"
15 #include "platform/mojo/MojoHelper.h"
14 #include "public/platform/Platform.h" 16 #include "public/platform/Platform.h"
17 #include "public/platform/ServiceRegistry.h"
15 #include "public/platform/WebImageCaptureFrameGrabber.h" 18 #include "public/platform/WebImageCaptureFrameGrabber.h"
16 #include "public/platform/WebMediaStreamTrack.h" 19 #include "public/platform/WebMediaStreamTrack.h"
17 20
18 namespace blink { 21 namespace blink {
19 22
23 namespace {
24
25 const char kNoServiceError[] = "ImageCapture service unavailable.";
26
27 bool trackIsInactive(const MediaStreamTrack& track)
28 {
29 // Spec instructs to return an exception if the Track's readyState() is not
30 // "live". Also reject if the track is disabled or muted.
31 return track.readyState() != "live" || !track.enabled() || track.muted();
32 }
33
34 } // anonymous namespace
35
20 ImageCapture* ImageCapture::create(ExecutionContext* context, MediaStreamTrack* track, ExceptionState& exceptionState) 36 ImageCapture* ImageCapture::create(ExecutionContext* context, MediaStreamTrack* track, ExceptionState& exceptionState)
21 { 37 {
22 if (track->kind() != "video") { 38 if (track->kind() != "video") {
23 exceptionState.throwDOMException(NotSupportedError, "Cannot create an Im ageCapturer from a non-video Track."); 39 exceptionState.throwDOMException(NotSupportedError, "Cannot create an Im ageCapturer from a non-video Track.");
24 return nullptr; 40 return nullptr;
25 } 41 }
26 42
27 return new ImageCapture(context, track); 43 return new ImageCapture(context, track);
28 } 44 }
29 45
30 ImageCapture::~ImageCapture() 46 ImageCapture::~ImageCapture()
31 { 47 {
32 DCHECK(!hasEventListeners()); 48 DCHECK(!hasEventListeners());
49 // There should be no more outstanding |m_serviceRequests| at this point
50 // since each of them holds a persistent handle to this object.
51 DCHECK(m_serviceRequests.isEmpty());
33 } 52 }
34 53
35 const AtomicString& ImageCapture::interfaceName() const 54 const AtomicString& ImageCapture::interfaceName() const
36 { 55 {
37 return EventTargetNames::ImageCapture; 56 return EventTargetNames::ImageCapture;
38 } 57 }
39 58
40 ExecutionContext* ImageCapture::getExecutionContext() const 59 ExecutionContext* ImageCapture::getExecutionContext() const
41 { 60 {
42 return ContextLifecycleObserver::getExecutionContext(); 61 return ContextLifecycleObserver::getExecutionContext();
43 } 62 }
44 63
45 bool ImageCapture::hasPendingActivity() const 64 bool ImageCapture::hasPendingActivity() const
46 { 65 {
47 return hasEventListeners(); 66 return hasEventListeners();
48 } 67 }
49 68
50 void ImageCapture::contextDestroyed() 69 void ImageCapture::contextDestroyed()
51 { 70 {
52 removeAllEventListeners(); 71 removeAllEventListeners();
72 m_serviceRequests.clear();
haraken 2016/04/29 06:50:20 I'm just curious but don't you need to reject the
mcasas 2016/04/29 21:03:14 I'm checking other callers like USB::contextDestro
53 DCHECK(!hasEventListeners()); 73 DCHECK(!hasEventListeners());
54 } 74 }
55 75
76 ScriptPromise ImageCapture::takePhoto(ScriptState* scriptState, ExceptionState& exceptionState)
77 {
78
79 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
80 ScriptPromise promise = resolver->promise();
81
82 if (trackIsInactive(*m_streamTrack)) {
83 resolver->reject(DOMException::create(InvalidStateError, "The associated Track is in an invalid state."));
84 return promise;
85 }
86
87 if (!m_service) {
88 resolver->reject(DOMException::create(NotFoundError, kNoServiceError));
89 return promise;
90 }
91
92 m_serviceRequests.add(resolver);
93
94 // m_streamTrack->component()->source()->id() is the renderer "name" of the camera;
95 // TODO(mcasas) consider sending the security origin as well:
96 // scriptState->getExecutionContext()->getSecurityOrigin()->toString()
97 m_service->TakePhoto(m_streamTrack->component()->source()->id(), createBaseC allback(bind<String, String>(&ImageCapture::onTakePhoto, this, resolver)));
98 return promise;
99 }
100
56 ScriptPromise ImageCapture::grabFrame(ScriptState* scriptState, ExceptionState& exceptionState) 101 ScriptPromise ImageCapture::grabFrame(ScriptState* scriptState, ExceptionState& exceptionState)
57 { 102 {
58 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 103 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
59 ScriptPromise promise = resolver->promise(); 104 ScriptPromise promise = resolver->promise();
60 105
61 // Spec instructs to return an exception if the track's ready state is not " live". Also reject if the track is disabled or muted. 106 if (trackIsInactive(*m_streamTrack)) {
62 if (m_streamTrack->readyState() != "live" || !m_streamTrack->enabled() || m_ streamTrack->muted()) {
63 resolver->reject(DOMException::create(InvalidStateError, "The associated Track is in an invalid state.")); 107 resolver->reject(DOMException::create(InvalidStateError, "The associated Track is in an invalid state."));
64 return promise; 108 return promise;
65 } 109 }
66 110
67 // Create |m_frameGrabber| the first time. 111 // Create |m_frameGrabber| the first time.
68 if (!m_frameGrabber) { 112 if (!m_frameGrabber)
69 m_frameGrabber = adoptPtr(Platform::current()->createImageCaptureFrameGr abber()); 113 m_frameGrabber = adoptPtr(Platform::current()->createImageCaptureFrameGr abber());
70 114
71 }
72
73 if (!m_frameGrabber) { 115 if (!m_frameGrabber) {
74 resolver->reject(DOMException::create(UnknownError, "Couldn't create pla tform resources")); 116 resolver->reject(DOMException::create(UnknownError, "Couldn't create pla tform resources"));
75 return promise; 117 return promise;
76 } 118 }
77 119
78 // The platform does not know about MediaStreamTrack, so we wrap it up. 120 // The platform does not know about MediaStreamTrack, so we wrap it up.
79 WebMediaStreamTrack track(m_streamTrack->component()); 121 WebMediaStreamTrack track(m_streamTrack->component());
80 m_frameGrabber->grabFrame(&track, new CallbackPromiseAdapter<ImageBitmap, vo id>(resolver)); 122 m_frameGrabber->grabFrame(&track, new CallbackPromiseAdapter<ImageBitmap, vo id>(resolver));
81 123
82 return promise; 124 return promise;
83 } 125 }
84 126
85 ImageCapture::ImageCapture(ExecutionContext* context, MediaStreamTrack* track) 127 ImageCapture::ImageCapture(ExecutionContext* context, MediaStreamTrack* track)
86 : ActiveScriptWrappable(this) 128 : ActiveScriptWrappable(this)
87 , ContextLifecycleObserver(context) 129 , ContextLifecycleObserver(context)
88 , m_streamTrack(track) 130 , m_streamTrack(track)
89 { 131 {
90 DCHECK(m_streamTrack); 132 DCHECK(m_streamTrack);
133 DCHECK(!m_service.is_bound());
134
135 Platform::current()->serviceRegistry()->connectToRemoteService(mojo::GetProx y(&m_service));
136
137 m_service.set_connection_error_handler(createBaseCallback(bind(&ImageCapture ::onServiceConnectionError, WeakPersistentThisPointer<ImageCapture>(this))));
138 }
139
140 void ImageCapture::onTakePhoto(ScriptPromiseResolver* resolver, const String& mi meType, const String& data)
141 {
142 if (m_serviceRequests.isEmpty())
haraken 2016/04/29 06:50:20 Nit: A better check might be if(!m_serviceRequests
mcasas 2016/04/29 21:03:14 Done.
143 return;
144
145 WTF::CString string = data.utf8();
146 DCHECK(!string.isNull());
147 resolver->resolve(Blob::create(reinterpret_cast<unsigned char*>(string.mutab leData()), string.length(), mimeType));
148 m_serviceRequests.remove(resolver);
149 }
150
151 void ImageCapture::onServiceConnectionError()
152 {
153 m_service.reset();
154 for (ScriptPromiseResolver* resolver : m_serviceRequests)
155 resolver->reject(DOMException::create(NotFoundError, kNoServiceError));
156 m_serviceRequests.clear();
91 } 157 }
92 158
93 bool ImageCapture::addEventListenerInternal(const AtomicString& eventType, Event Listener* listener, const EventListenerOptions& options) 159 bool ImageCapture::addEventListenerInternal(const AtomicString& eventType, Event Listener* listener, const EventListenerOptions& options)
94 { 160 {
95 return EventTarget::addEventListenerInternal(eventType, listener, options); 161 return EventTarget::addEventListenerInternal(eventType, listener, options);
96 } 162 }
97 163
98 DEFINE_TRACE(ImageCapture) 164 DEFINE_TRACE(ImageCapture)
99 { 165 {
100 visitor->trace(m_streamTrack); 166 visitor->trace(m_streamTrack);
167 visitor->trace(m_serviceRequests);
101 EventTargetWithInlineData::trace(visitor); 168 EventTargetWithInlineData::trace(visitor);
102 ContextLifecycleObserver::trace(visitor); 169 ContextLifecycleObserver::trace(visitor);
103 } 170 }
104 171
105 } // namespace blink 172 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698