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

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: comments; rebased; removed ImageCaptureContext. 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 bool isActive(ScriptPromiseResolver* resolver)
35 {
36 ExecutionContext* context = resolver->getExecutionContext();
37 return context && !context->activeDOMObjectsAreStopped();
38 }
39
40 } // anonymous namespace
41
20 ImageCapture* ImageCapture::create(ExecutionContext* context, MediaStreamTrack* track, ExceptionState& exceptionState) 42 ImageCapture* ImageCapture::create(ExecutionContext* context, MediaStreamTrack* track, ExceptionState& exceptionState)
21 { 43 {
22 if (track->kind() != "video") { 44 if (track->kind() != "video") {
23 exceptionState.throwDOMException(NotSupportedError, "Cannot create an Im ageCapturer from a non-video Track."); 45 exceptionState.throwDOMException(NotSupportedError, "Cannot create an Im ageCapturer from a non-video Track.");
24 return nullptr; 46 return nullptr;
25 } 47 }
26 48
27 return new ImageCapture(context, track); 49 return new ImageCapture(context, track);
28 } 50 }
29 51
30 ImageCapture::~ImageCapture() 52 ImageCapture::~ImageCapture()
31 { 53 {
32 DCHECK(!hasEventListeners()); 54 DCHECK(!hasEventListeners());
55 // There should be no more outstanding |m_serviceRequests| at this point
56 // since each of them holds a persistent handle to this object.
57 DCHECK(m_serviceRequests.isEmpty());
33 } 58 }
34 59
35 const AtomicString& ImageCapture::interfaceName() const 60 const AtomicString& ImageCapture::interfaceName() const
36 { 61 {
37 return EventTargetNames::ImageCapture; 62 return EventTargetNames::ImageCapture;
38 } 63 }
39 64
40 ExecutionContext* ImageCapture::getExecutionContext() const 65 ExecutionContext* ImageCapture::getExecutionContext() const
41 { 66 {
42 return ContextLifecycleObserver::getExecutionContext(); 67 return ContextLifecycleObserver::getExecutionContext();
43 } 68 }
44 69
45 bool ImageCapture::hasPendingActivity() const 70 bool ImageCapture::hasPendingActivity() const
46 { 71 {
47 return hasEventListeners(); 72 return hasEventListeners();
48 } 73 }
49 74
50 void ImageCapture::contextDestroyed() 75 void ImageCapture::contextDestroyed()
51 { 76 {
52 removeAllEventListeners(); 77 removeAllEventListeners();
78 m_serviceRequests.clear();
53 DCHECK(!hasEventListeners()); 79 DCHECK(!hasEventListeners());
54 } 80 }
55 81
82 ScriptPromise ImageCapture::takePhoto(ScriptState* scriptState, ExceptionState& exceptionState)
83 {
84
85 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
86 ScriptPromise promise = resolver->promise();
87
88 if (trackIsInactive(*m_streamTrack)) {
89 resolver->reject(DOMException::create(InvalidStateError, "The associated Track is in an invalid state."));
90 return promise;
91 }
92
93 if (!m_service) {
94 resolver->reject(DOMException::create(NotFoundError, kNoServiceError));
95 return promise;
96 }
97
98 m_serviceRequests.add(resolver);
99
100 // m_streamTrack->component()->source()->id() is the renderer "name" of the camera;
101 // TODO(mcasas) consider sending the security origin as well:
102 // scriptState->getExecutionContext()->getSecurityOrigin()->toString()
103 m_service->TakePhoto(m_streamTrack->component()->source()->id(), createBaseC allback(bind<String, String>(&ImageCapture::onTakePhoto, this, resolver)));
104 return promise;
105 }
106
56 ScriptPromise ImageCapture::grabFrame(ScriptState* scriptState, ExceptionState& exceptionState) 107 ScriptPromise ImageCapture::grabFrame(ScriptState* scriptState, ExceptionState& exceptionState)
57 { 108 {
58 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; 109 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
59 ScriptPromise promise = resolver->promise(); 110 ScriptPromise promise = resolver->promise();
60 111
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. 112 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.")); 113 resolver->reject(DOMException::create(InvalidStateError, "The associated Track is in an invalid state."));
64 return promise; 114 return promise;
65 } 115 }
66 116
67 // Create |m_frameGrabber| the first time. 117 // Create |m_frameGrabber| the first time.
68 if (!m_frameGrabber) { 118 if (!m_frameGrabber)
69 m_frameGrabber = adoptPtr(Platform::current()->createImageCaptureFrameGr abber()); 119 m_frameGrabber = adoptPtr(Platform::current()->createImageCaptureFrameGr abber());
70 120
71 }
72
73 if (!m_frameGrabber) { 121 if (!m_frameGrabber) {
74 resolver->reject(DOMException::create(UnknownError, "Couldn't create pla tform resources")); 122 resolver->reject(DOMException::create(UnknownError, "Couldn't create pla tform resources"));
75 return promise; 123 return promise;
76 } 124 }
77 125
78 // The platform does not know about MediaStreamTrack, so we wrap it up. 126 // The platform does not know about MediaStreamTrack, so we wrap it up.
79 WebMediaStreamTrack track(m_streamTrack->component()); 127 WebMediaStreamTrack track(m_streamTrack->component());
80 m_frameGrabber->grabFrame(&track, new CallbackPromiseAdapter<ImageBitmap, vo id>(resolver)); 128 m_frameGrabber->grabFrame(&track, new CallbackPromiseAdapter<ImageBitmap, vo id>(resolver));
81 129
82 return promise; 130 return promise;
83 } 131 }
84 132
85 ImageCapture::ImageCapture(ExecutionContext* context, MediaStreamTrack* track) 133 ImageCapture::ImageCapture(ExecutionContext* context, MediaStreamTrack* track)
86 : ActiveScriptWrappable(this) 134 : ActiveScriptWrappable(this)
87 , ContextLifecycleObserver(context) 135 , ContextLifecycleObserver(context)
88 , m_streamTrack(track) 136 , m_streamTrack(track)
89 { 137 {
90 DCHECK(m_streamTrack); 138 DCHECK(m_streamTrack);
139 DCHECK(!m_service.is_bound());
140
141 Platform::current()->serviceRegistry()->connectToRemoteService(mojo::GetProx y(&m_service));
142
143 m_service.set_connection_error_handler(createBaseCallback(bind(&ImageCapture ::onServiceConnectionError, WeakPersistentThisPointer<ImageCapture>(this))));
144 }
145
146 void ImageCapture::onTakePhoto(ScriptPromiseResolver* resolver, const String& mi meType, const String& data)
147 {
148 if (!isActive(resolver))
haraken 2016/04/28 19:41:36 Would you instead check if(m_serviceRequests.isEmp
mcasas 2016/04/28 20:13:15 Done.
149 return;
150
151 WTF::CString string = data.utf8();
152 DCHECK(!string.isNull());
153 resolver->resolve(Blob::create(reinterpret_cast<unsigned char*>(string.mutab leData()), string.length(), mimeType));
154 m_serviceRequests.remove(resolver);
155 }
156
157 void ImageCapture::onServiceConnectionError()
158 {
159 m_service.reset();
160 for (ScriptPromiseResolver* resolver : m_serviceRequests)
161 resolver->reject(DOMException::create(NotFoundError, kNoServiceError));
162 m_serviceRequests.clear();
91 } 163 }
92 164
93 bool ImageCapture::addEventListenerInternal(const AtomicString& eventType, Event Listener* listener, const EventListenerOptions& options) 165 bool ImageCapture::addEventListenerInternal(const AtomicString& eventType, Event Listener* listener, const EventListenerOptions& options)
94 { 166 {
95 return EventTarget::addEventListenerInternal(eventType, listener, options); 167 return EventTarget::addEventListenerInternal(eventType, listener, options);
96 } 168 }
97 169
98 DEFINE_TRACE(ImageCapture) 170 DEFINE_TRACE(ImageCapture)
99 { 171 {
100 visitor->trace(m_streamTrack); 172 visitor->trace(m_streamTrack);
173 visitor->trace(m_serviceRequests);
101 EventTargetWithInlineData::trace(visitor); 174 EventTargetWithInlineData::trace(visitor);
102 ContextLifecycleObserver::trace(visitor); 175 ContextLifecycleObserver::trace(visitor);
103 } 176 }
104 177
105 } // namespace blink 178 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698