Changeset 86583 in webkit
- Timestamp:
- May 16, 2011 10:16:31 AM (13 years ago)
- Location:
- trunk
- Files:
-
- 15 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r86579 r86583 1 2011-05-16 Leandro Gracia Gil <leandrogracia@chromium.org> 2 3 Reviewed by Tony Gentilcore. 4 5 Media Stream API: add local stream requests. 6 https://bugs.webkit.org/show_bug.cgi?id=60177 7 8 Re-enable the argument-types test as the navigator.getUserMedia options 9 are now being parsed and raise the appropriate exceptions. 10 11 * platform/chromium/test_expectations.txt: 12 1 13 2011-05-16 Mark Pilgrim <pilgrim@chromium.org> 2 14 -
trunk/LayoutTests/platform/chromium/test_expectations.txt
r86570 r86583 4026 4026 BUGWK54181 : fast/events/page-visibility-transition-test.html = TIMEOUT 4027 4027 4028 // To be re-enabled after landing https://bugs.webkit.org/show_bug.cgi?id=60177.4029 BUGWK60387 : fast/dom/MediaStream/argument-types.html = FAIL4030 4031 4028 BUGCR82281 : fast/xpath/xpath-iterator-result-should-mark-its-nodeset.html = TEXT 4032 4029 BUGCR82281 : fast/xpath/xpath-other-nodeset-result-should-mark-its-nodeset.html = TEXT -
trunk/Source/WebCore/ChangeLog
r86581 r86583 1 2011-05-16 Leandro Gracia Gil <leandrogracia@chromium.org> 2 3 Reviewed by Tony Gentilcore. 4 5 Media Stream API: add local stream requests. 6 https://bugs.webkit.org/show_bug.cgi?id=60177 7 8 Add the code and messages for requesting the generation of local streams and getting the reply back. 9 10 Tests for the Media Stream API will be provided by the bug 56587. 11 One test is re-enabled with this patch. 12 13 Test: fast/dom/MediaStream/argument-types.html 14 15 * GNUmakefile.list.am: 16 * WebCore.gypi: 17 * WebCore.pro: 18 * WebCore.vcproj/WebCore.vcproj: 19 * WebCore.xcodeproj/project.pbxproj: 20 * page/CallbackTask.h: Added. 21 (WebCore::CallbackTask1::create): 22 (WebCore::CallbackTask1::performTask): 23 (WebCore::CallbackTask1::Scheduler::scheduleCallback): 24 (WebCore::CallbackTask1::CallbackTask1): 25 * page/MediaStreamClient.h: 26 * page/MediaStreamController.cpp: 27 (WebCore::MediaStreamController::isClientAvailable): 28 (WebCore::MediaStreamController::unregisterFrameController): 29 (WebCore::MediaStreamController::registerRequest): 30 (WebCore::MediaStreamController::registerStream): 31 (WebCore::MediaStreamController::generateStream): 32 (WebCore::MediaStreamController::streamGenerated): 33 (WebCore::MediaStreamController::streamGenerationFailed): 34 * page/MediaStreamController.h: 35 * page/MediaStreamFrameController.cpp: 36 (WebCore::MediaStreamFrameController::GenerateStreamRequest::GenerateStreamRequest): 37 (WebCore::MediaStreamFrameController::GenerateStreamRequest::~GenerateStreamRequest): 38 (WebCore::MediaStreamFrameController::GenerateStreamRequest::isGenerateStreamRequest): 39 (WebCore::MediaStreamFrameController::GenerateStreamRequest::abort): 40 (WebCore::MediaStreamFrameController::GenerateStreamRequest::successCallback): 41 (WebCore::MediaStreamFrameController::GenerateStreamRequest::errorCallback): 42 (WebCore::::unregisterAll): 43 (WebCore::::detachEmbedder): 44 (WebCore::MediaStreamFrameController::MediaStreamFrameController): 45 (WebCore::MediaStreamFrameController::pageController): 46 (WebCore::MediaStreamFrameController::unregister): 47 (WebCore::MediaStreamFrameController::enterDetachedState): 48 (WebCore::MediaStreamFrameController::isClientAvailable): 49 (WebCore::MediaStreamFrameController::disconnectFrame): 50 (WebCore::MediaStreamFrameController::parseGenerateStreamOptions): 51 (WebCore::MediaStreamFrameController::generateStream): 52 (WebCore::MediaStreamFrameController::streamGenerated): 53 (WebCore::MediaStreamFrameController::streamGenerationFailed): 54 * page/MediaStreamFrameController.h: 55 (WebCore::MediaStreamFrameController::ClientBase::ClientBase): 56 (WebCore::MediaStreamFrameController::ClientBase::~ClientBase): 57 (WebCore::MediaStreamFrameController::ClientBase::mediaStreamFrameController): 58 (WebCore::MediaStreamFrameController::ClientBase::clientId): 59 (WebCore::MediaStreamFrameController::ClientBase::isStream): 60 (WebCore::MediaStreamFrameController::ClientBase::isGeneratedStream): 61 (WebCore::MediaStreamFrameController::ClientBase::detachEmbedder): 62 (WebCore::MediaStreamFrameController::ClientBase::associateFrameController): 63 (WebCore::MediaStreamFrameController::ClientBase::unregisterClient): 64 (WebCore::MediaStreamFrameController::StreamClient::StreamClient): 65 (WebCore::MediaStreamFrameController::StreamClient::~StreamClient): 66 (WebCore::MediaStreamFrameController::StreamClient::isStream): 67 (WebCore::MediaStreamFrameController::StreamClient::unregister): 68 (WebCore::MediaStreamFrameController::IdGenerator::IdGenerator): 69 (WebCore::MediaStreamFrameController::IdGenerator::getNextId): 70 (WebCore::MediaStreamFrameController::ClientMapBase::ClientMapBase): 71 * page/Navigator.cpp: 72 (WebCore::Navigator::webkitGetUserMedia): 73 * page/NavigatorUserMediaErrorCallback.h: 74 1 75 2011-05-16 Pavel Podivilov <podivilov@chromium.org> 2 76 -
trunk/Source/WebCore/GNUmakefile.list.am
r86451 r86583 2136 2136 Source/WebCore/page/BarInfo.cpp \ 2137 2137 Source/WebCore/page/BarInfo.h \ 2138 Source/WebCore/page/CallbackTask.h \ 2138 2139 Source/WebCore/page/Chrome.cpp \ 2139 2140 Source/WebCore/page/Chrome.h \ -
trunk/Source/WebCore/WebCore.gypi
r86315 r86583 3392 3392 'page/BarInfo.cpp', 3393 3393 'page/BarInfo.h', 3394 'page/CallbackTask.h', 3394 3395 'page/Chrome.cpp', 3395 3396 'page/Console.cpp', -
trunk/Source/WebCore/WebCore.pro
r86451 r86583 3103 3103 contains(DEFINES, ENABLE_MEDIA_STREAM=1) { 3104 3104 HEADERS += \ 3105 page/CallbackTask.h \ 3105 3106 page/MediaStreamClient.h \ 3106 3107 page/MediaStreamController.h \ -
trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj
r86451 r86583 24407 24407 </File> 24408 24408 <File 24409 RelativePath="..\page\CallbackTask.h" 24410 > 24411 </File> 24412 <File 24409 24413 RelativePath="..\page\Chrome.cpp" 24410 24414 > -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r86472 r86583 4092 4092 B1E54597134629C10092A545 /* MediaStreamController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B1E5458B134629C10092A545 /* MediaStreamController.cpp */; }; 4093 4093 B1E54598134629C10092A545 /* MediaStreamController.h in Headers */ = {isa = PBXBuildFile; fileRef = B1E5458C134629C10092A545 /* MediaStreamController.h */; }; 4094 B1E54593134629C10092A545 /* CallbackTask.h in Headers */ = {isa = PBXBuildFile; fileRef = B1E54587134629C10092A545 /* CallbackTask.h */; }; 4094 4095 B1E54599134629C10092A545 /* NavigatorUserMediaError.h in Headers */ = {isa = PBXBuildFile; fileRef = B1E5458D134629C10092A545 /* NavigatorUserMediaError.h */; }; 4095 4096 B1E5459B134629C10092A545 /* NavigatorUserMediaErrorCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = B1E5458F134629C10092A545 /* NavigatorUserMediaErrorCallback.h */; }; … … 10349 10350 B1E5458B134629C10092A545 /* MediaStreamController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MediaStreamController.cpp; sourceTree = "<group>"; }; 10350 10351 B1E5458C134629C10092A545 /* MediaStreamController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaStreamController.h; sourceTree = "<group>"; }; 10352 B1E54587134629C10092A545 /* CallbackTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallbackTask.h; sourceTree = "<group>"; }; 10351 10353 B1E5458D134629C10092A545 /* NavigatorUserMediaError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NavigatorUserMediaError.h; sourceTree = "<group>"; }; 10352 10354 B1E5458E134629C10092A545 /* NavigatorUserMediaError.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = NavigatorUserMediaError.idl; sourceTree = "<group>"; }; … … 14097 14099 BC124EE50C2641CD009E2349 /* BarInfo.h */, 14098 14100 BC124EE60C2641CD009E2349 /* BarInfo.idl */, 14101 B1E54587134629C10092A545 /* CallbackTask.h */, 14099 14102 14D8238A0AF92DF60004F057 /* Chrome.cpp */, 14100 14103 14D823500AF92A790004F057 /* Chrome.h */, … … 22774 22777 BCE5644E137A34D6007D2934 /* ConsoleTypes.h in Headers */, 22775 22778 BCF7E491137CD7C7001DDAE7 /* AdjustViewSizeOrNot.h in Headers */, 22779 B1E54593134629C10092A545 /* CallbackTask.h in Headers */, 22776 22780 ); 22777 22781 runOnlyForDeploymentPostprocessing = 0; -
trunk/Source/WebCore/page/CallbackTask.h
r86582 r86583 23 23 */ 24 24 25 #ifndef MediaStreamFrameController_h26 #define MediaStreamFrameController_h25 #ifndef CallbackTask_h 26 #define CallbackTask_h 27 27 28 28 #if ENABLE(MEDIA_STREAM) 29 29 30 #include "ScriptExecutionContext.h" 30 31 #include <wtf/Forward.h> 31 #include <wtf/ HashMap.h>32 #include <wtf/ Noncopyable.h>32 #include <wtf/PassRefPtr.h> 33 #include <wtf/RefPtr.h> 33 34 34 35 namespace WebCore { 35 36 36 class Frame; 37 class MediaStreamController; 38 class Page; 39 class ScriptExecutionContext; 40 class SecurityOrigin; 37 // Helper template to schedule calls to callbacks using their own script execution context. 38 // CallbackType is assumed to implement Scheduler and to be reference-counted. 39 template <typename CallbackType, typename ArgumentType> 40 class CallbackTask1 : public ScriptExecutionContext::Task { 41 public: 42 static PassOwnPtr<CallbackTask1> create(PassRefPtr<CallbackType> callback, PassRefPtr<ArgumentType> data) 43 { 44 return adoptPtr(new CallbackTask1(callback, data)); 45 } 41 46 42 class MediaStreamFrameController { 43 WTF_MAKE_NONCOPYABLE(MediaStreamFrameController); 44 public: 45 MediaStreamFrameController(Frame*); 46 virtual ~MediaStreamFrameController(); 47 virtual void performTask(ScriptExecutionContext*) 48 { 49 m_callback->handleEvent(m_data.get()); 50 } 47 51 48 SecurityOrigin* securityOrigin() const; 49 ScriptExecutionContext* scriptExecutionContext() const; 50 51 void disconnectPage(); 52 void disconnectFrame(); 53 void transferToNewPage(Page*); 52 class Scheduler { 53 public: 54 bool scheduleCallback(ScriptExecutionContext* context, PassRefPtr<ArgumentType> data) 55 { 56 if (context) { 57 context->postTask(CallbackTask1<CallbackType, ArgumentType>::create(static_cast<CallbackType*>(this), data)); 58 return true; 59 } 60 return false; 61 } 62 }; 54 63 55 64 private: 56 class Request; 65 CallbackTask1(PassRefPtr<CallbackType> callback, PassRefPtr<ArgumentType> data) 66 : m_callback(callback) 67 , m_data(data) 68 { 69 } 57 70 58 class RequestMap : public HashMap<int, RefPtr<Request> > { 59 public: 60 void abort(int requestId); 61 void abortAll(); 62 }; 63 64 // Detached from a page, and hence from a embedder client. 65 void enterDetachedState(); 66 67 MediaStreamController* pageController() const; 68 69 RequestMap m_requests; 70 71 Frame* m_frame; 72 bool m_isInDetachedState; 71 RefPtr<CallbackType> m_callback; 72 RefPtr<ArgumentType> m_data; 73 73 }; 74 74 75 } // namespace WebCore75 } 76 76 77 77 #endif // ENABLE(MEDIA_STREAM) 78 78 79 #endif // MediaStreamFrameController_h79 #endif // CallbackTask_h -
trunk/Source/WebCore/page/MediaStreamClient.h
r85745 r86583 28 28 #if ENABLE(MEDIA_STREAM) 29 29 30 #include <wtf/Forward.h> 31 30 32 namespace WebCore { 33 34 class SecurityOrigin; 35 36 enum GenerateStreamOptionFlag { 37 GenerateStreamRequestAudio = 1, 38 GenerateStreamRequestVideoFacingUser = 1 << 1, 39 GenerateStreamRequestVideoFacingEnvironment = 1 << 2, 40 }; 41 42 typedef unsigned GenerateStreamOptionFlags; 31 43 32 44 class MediaStreamClient { … … 35 47 virtual void mediaStreamDestroyed() = 0; 36 48 37 // FIXME: add here the requests to the embedder. 49 // Generate a new local stream. 50 virtual void generateStream(int requestId, GenerateStreamOptionFlags, PassRefPtr<SecurityOrigin>) = 0; 38 51 39 52 protected: -
trunk/Source/WebCore/page/MediaStreamController.cpp
r85745 r86583 28 28 #if ENABLE(MEDIA_STREAM) 29 29 30 #include "MediaStreamClient.h"31 30 #include "MediaStreamFrameController.h" 31 #include "SecurityOrigin.h" 32 32 #include <wtf/Vector.h> 33 33 … … 64 64 } 65 65 66 bool MediaStreamController::isClientAvailable() const 67 { 68 return m_client; 69 } 70 66 71 void MediaStreamController::unregisterFrameController(MediaStreamFrameController* frameController) 67 72 { … … 76 81 for (Vector<int>::iterator it = frameRequests.begin(); it != frameRequests.end(); ++it) 77 82 m_requests.remove(*it); 83 84 Vector<String> frameStreams; 85 for (StreamMap::iterator it = m_streams.begin(); it != m_streams.end(); ++it) 86 if (it->second == frameController) 87 frameStreams.append(it->first); 88 89 for (Vector<String>::iterator it = frameStreams.begin(); it != frameStreams.end(); ++it) 90 m_streams.remove(*it); 78 91 } 79 92 80 93 int MediaStreamController::registerRequest(int localId, MediaStreamFrameController* frameController) 81 94 { 95 ASSERT(localId > 0); 96 ASSERT(frameController); 82 97 m_requests.add(m_nextGlobalRequestId, Request(localId, frameController)); 83 98 return m_nextGlobalRequestId++; 99 } 100 101 void MediaStreamController::registerStream(const String& streamLabel, MediaStreamFrameController* frameController) 102 { 103 ASSERT(frameController); 104 ASSERT(!m_streams.contains(streamLabel)); 105 m_streams.add(streamLabel, frameController); 106 } 107 108 void MediaStreamController::generateStream(MediaStreamFrameController* frameController, int localId, GenerateStreamOptionFlags flags, PassRefPtr<SecurityOrigin> securityOrigin) 109 { 110 ASSERT(m_client); 111 int controllerRequestId = registerRequest(localId, frameController); 112 m_client->generateStream(controllerRequestId, flags, securityOrigin); 113 } 114 115 void MediaStreamController::streamGenerated(int controllerRequestId, const String& streamLabel) 116 { 117 // Don't assert since the frame controller can have been destroyed while the request reply was coming back. 118 if (m_requests.contains(controllerRequestId)) { 119 const Request& request = m_requests.get(controllerRequestId); 120 registerStream(streamLabel, request.frameController()); 121 m_requests.remove(controllerRequestId); 122 ASSERT(request.frameController()); 123 request.frameController()->streamGenerated(request.localId(), streamLabel); 124 } 125 } 126 127 void MediaStreamController::streamGenerationFailed(int controllerRequestId, NavigatorUserMediaError::ErrorCode code) 128 { 129 // Don't assert since the frame controller can have been destroyed while the request reply was coming back. 130 if (m_requests.contains(controllerRequestId)) { 131 const Request& request = m_requests.get(controllerRequestId); 132 m_requests.remove(controllerRequestId); 133 request.frameController()->streamGenerationFailed(request.localId(), code); 134 } 84 135 } 85 136 -
trunk/Source/WebCore/page/MediaStreamController.h
r85745 r86583 28 28 #if ENABLE(MEDIA_STREAM) 29 29 30 #include "MediaStreamClient.h" 31 #include "NavigatorUserMediaError.h" 30 32 #include <wtf/Forward.h> 31 33 #include <wtf/HashMap.h> 32 34 #include <wtf/Noncopyable.h> 35 #include <wtf/text/StringHash.h> 33 36 34 37 namespace WebCore { … … 36 39 class MediaStreamClient; 37 40 class MediaStreamFrameController; 41 class SecurityOrigin; 38 42 39 43 class MediaStreamController { … … 43 47 virtual ~MediaStreamController(); 44 48 49 bool isClientAvailable() const; 45 50 void unregisterFrameController(MediaStreamFrameController*); 51 52 void generateStream(MediaStreamFrameController*, int requestId, GenerateStreamOptionFlags, PassRefPtr<SecurityOrigin>); 53 54 void streamGenerated(int requestId, const String& streamLabel); 55 void streamGenerationFailed(int requestId, NavigatorUserMediaError::ErrorCode); 46 56 47 57 private: 48 58 int registerRequest(int localRequestId, MediaStreamFrameController*); 59 void registerStream(const String& streamLabel, MediaStreamFrameController*); 49 60 50 61 class Request; 51 62 typedef HashMap<int, Request> RequestMap; 63 typedef HashMap<String, MediaStreamFrameController*> StreamMap; 52 64 53 65 RequestMap m_requests; 66 StreamMap m_streams; 54 67 55 68 MediaStreamClient* m_client; -
trunk/Source/WebCore/page/MediaStreamFrameController.cpp
r85745 r86583 41 41 42 42 class MediaStreamFrameController::Request : public RefCounted<Request> { 43 WTF_MAKE_NONCOPYABLE(Request); 43 44 public: 44 45 Request(ScriptExecutionContext* scriptExecutionContext) … … 59 60 }; 60 61 62 class MediaStreamFrameController::GenerateStreamRequest : public Request { 63 WTF_MAKE_NONCOPYABLE(GenerateStreamRequest); 64 public: 65 GenerateStreamRequest(ScriptExecutionContext* scriptExecutionContext, 66 PassRefPtr<NavigatorUserMediaSuccessCallback> successCallback, 67 PassRefPtr<NavigatorUserMediaErrorCallback> errorCallback) 68 : Request(scriptExecutionContext) 69 , m_successCallback(successCallback) 70 , m_errorCallback(errorCallback) { } 71 72 virtual ~GenerateStreamRequest() { } 73 74 virtual bool isGenerateStreamRequest() const { return true; } 75 76 virtual void abort() 77 { 78 if (m_errorCallback) { 79 RefPtr<NavigatorUserMediaError> error = adoptRef(new NavigatorUserMediaError(NavigatorUserMediaError::PERMISSION_DENIED)); 80 // The callback itself is made with the JS callback's context, not with the frame's context. 81 m_errorCallback->scheduleCallback(scriptExecutionContext(), error); 82 } 83 } 84 85 PassRefPtr<NavigatorUserMediaSuccessCallback> successCallback() const { return m_successCallback; } 86 PassRefPtr<NavigatorUserMediaErrorCallback> errorCallback() const { return m_errorCallback; } 87 88 private: 89 RefPtr<NavigatorUserMediaSuccessCallback> m_successCallback; 90 RefPtr<NavigatorUserMediaErrorCallback> m_errorCallback; 91 }; 92 61 93 void MediaStreamFrameController::RequestMap::abort(int requestId) 62 94 { … … 73 105 } 74 106 107 template <typename T> 108 void MediaStreamFrameController::ClientMapBase<T>::unregisterAll() 109 { 110 while (!this->isEmpty()) { 111 T key = this->begin()->first; 112 // unregister should remove the element from the map. 113 this->begin()->second->unregister(); 114 ASSERT_UNUSED(key, !this->contains(key)); 115 } 116 } 117 118 template <typename T> 119 void MediaStreamFrameController::ClientMapBase<T>::detachEmbedder() 120 { 121 for (typename MapType::iterator it = this->begin(); it != this->end(); ++it) 122 it->second->detachEmbedder(); 123 } 124 75 125 MediaStreamFrameController::MediaStreamFrameController(Frame* frame) 76 126 : m_frame(frame) 77 127 , m_isInDetachedState(false) 78 128 { 129 if (!isClientAvailable()) 130 enterDetachedState(); 79 131 } 80 132 … … 95 147 MediaStreamController* MediaStreamFrameController::pageController() const 96 148 { 97 return !m_isInDetachedState && m_frame && m_frame->page() ? m_frame->page()->mediaStreamController() : 0; 149 return m_frame && m_frame->page() ? m_frame->page()->mediaStreamController() : 0; 150 } 151 152 void MediaStreamFrameController::unregister(StreamClient* client) 153 { 154 ASSERT(m_streams.contains(client->clientId())); 155 m_streams.remove(client->clientId()); 98 156 } 99 157 … … 106 164 107 165 m_requests.abortAll(); 166 m_streams.detachEmbedder(); 108 167 m_isInDetachedState = true; 168 } 169 170 bool MediaStreamFrameController::isClientAvailable() const 171 { 172 if (m_isInDetachedState) 173 return false; 174 175 MediaStreamController* controller = pageController(); 176 return controller && controller->isClientAvailable(); 109 177 } 110 178 … … 124 192 125 193 ASSERT(m_requests.isEmpty()); 194 m_streams.unregisterAll(); 126 195 127 196 m_frame = 0; … … 135 204 } 136 205 206 GenerateStreamOptionFlags MediaStreamFrameController::parseGenerateStreamOptions(const String& options) 207 { 208 GenerateStreamOptionFlags flags = 0; 209 Vector<String> optionList; 210 options.split(',', optionList); 211 212 for (Vector<String>::const_iterator option = optionList.begin(); option != optionList.end(); ++option) { 213 Vector<String> suboptionList; 214 option->split(' ', suboptionList); 215 216 if (suboptionList.first() == "audio") 217 flags |= GenerateStreamRequestAudio; 218 else if (suboptionList.first() == "video") { 219 bool videoSuboptions = false; 220 Vector<String>::const_iterator suboption = suboptionList.begin(); 221 for (++suboption; suboption != suboptionList.end(); ++suboption) 222 if (*suboption == "user") { 223 flags |= GenerateStreamRequestVideoFacingUser; 224 videoSuboptions = true; 225 } else if (*suboption == "environment") { 226 flags |= GenerateStreamRequestVideoFacingEnvironment; 227 videoSuboptions = true; 228 } 229 230 // Ask for all kind of cameras if no suboption was specified. 231 if (!videoSuboptions) 232 flags |= GenerateStreamRequestVideoFacingUser | GenerateStreamRequestVideoFacingEnvironment; 233 } 234 } 235 236 return flags; 237 } 238 239 // Implements the getUserMedia method from http://www.whatwg.org/specs/web-apps/current-work/#dom-navigator-getusermedia. 240 void MediaStreamFrameController::generateStream(const String& options, 241 PassRefPtr<NavigatorUserMediaSuccessCallback> successCallback, 242 PassRefPtr<NavigatorUserMediaErrorCallback> errorCallback, 243 ExceptionCode& ec) 244 { 245 ec = 0; 246 if (!successCallback) 247 return; 248 249 GenerateStreamOptionFlags flags = parseGenerateStreamOptions(options); 250 if (!flags) { 251 ec = NOT_SUPPORTED_ERR; 252 return; 253 } 254 255 int requestId = m_requests.getNextId(); 256 m_requests.add(requestId, adoptRef(new GenerateStreamRequest(scriptExecutionContext(), successCallback, errorCallback))); 257 258 if (!isClientAvailable()) { 259 // This makes sure to call the error callback if provided. 260 m_requests.abort(requestId); 261 return; 262 } 263 264 pageController()->generateStream(this, requestId, flags, securityOrigin()); 265 } 266 267 void MediaStreamFrameController::streamGenerated(int requestId, const String& label) 268 { 269 // Don't assert since the request can have been aborted as a result of embedder detachment. 270 if (m_requests.contains(requestId)) { 271 ASSERT(m_requests.get(requestId)->isGenerateStreamRequest()); 272 ASSERT(!label.isNull()); 273 274 // FIXME: create a GeneratedStream object and invoke the callback when the class is available. 275 m_requests.remove(requestId); 276 } 277 } 278 279 void MediaStreamFrameController::streamGenerationFailed(int requestId, NavigatorUserMediaError::ErrorCode code) 280 { 281 // Don't assert since the request can have been aborted as a result of embedder detachment. 282 if (m_requests.contains(requestId)) { 283 ASSERT(m_requests.get(requestId)->isGenerateStreamRequest()); 284 285 RefPtr<GenerateStreamRequest> streamRequest = static_cast<GenerateStreamRequest*>(m_requests.get(requestId).get()); 286 m_requests.remove(requestId); 287 288 if (streamRequest->errorCallback()) { 289 RefPtr<NavigatorUserMediaError> error = adoptRef(new NavigatorUserMediaError(code)); 290 streamRequest->errorCallback()->handleEvent(error.get()); 291 } 292 } 293 } 294 137 295 } // namespace WebCore 138 296 -
trunk/Source/WebCore/page/MediaStreamFrameController.h
r85745 r86583 28 28 #if ENABLE(MEDIA_STREAM) 29 29 30 #include "ExceptionCode.h" 31 #include "MediaStreamClient.h" 32 #include "NavigatorUserMediaError.h" 30 33 #include <wtf/Forward.h> 31 34 #include <wtf/HashMap.h> 32 35 #include <wtf/Noncopyable.h> 36 #include <wtf/text/StringHash.h> 33 37 34 38 namespace WebCore { … … 36 40 class Frame; 37 41 class MediaStreamController; 42 class NavigatorUserMediaErrorCallback; 43 class NavigatorUserMediaSuccessCallback; 38 44 class Page; 39 45 class ScriptExecutionContext; … … 43 49 WTF_MAKE_NONCOPYABLE(MediaStreamFrameController); 44 50 public: 51 template <typename IdType> 52 class ClientBase { 53 WTF_MAKE_NONCOPYABLE(ClientBase); 54 public: 55 ClientBase() : m_frameController(0), m_clientId(0) { } 56 57 ClientBase(MediaStreamFrameController* frameController, const IdType& id) 58 : m_frameController(frameController) 59 , m_clientId(id) { } 60 61 virtual ~ClientBase() { } 62 63 MediaStreamFrameController* mediaStreamFrameController() const { return m_frameController; } 64 const IdType& clientId() const { return m_clientId; } 65 66 virtual bool isStream() const { return false; } 67 virtual bool isGeneratedStream() const { return false; } 68 69 // Called when the frame controller is being disconnected to the MediaStreamClient embedder. 70 // Clients should override this to send any required shutdown messages. 71 virtual void detachEmbedder() { } 72 73 protected: 74 // Used for objects that are optionally associated to the frame controller after construction, like the track lists. 75 void associateFrameController(MediaStreamFrameController* frameController, const IdType& id) 76 { 77 ASSERT(!m_frameController && !m_clientId); 78 m_frameController = frameController; 79 m_clientId = id; 80 } 81 82 // Avoids repeating the same code in the unregister method of each derived class. 83 // This is required since the controller's unregister methods make use of the isObject virtuals, 84 // and the unregistration can be triggered either by the destructor of the client or by the disconnection of the frame. 85 template <typename ClientType> 86 void unregisterClient(ClientType* client) 87 { 88 if (!m_frameController) 89 return; 90 91 m_frameController->unregister(static_cast<ClientType*>(client)); 92 m_frameController = 0; 93 } 94 95 virtual void unregister() = 0; 96 friend class MediaStreamFrameController; 97 98 MediaStreamFrameController* m_frameController; 99 IdType m_clientId; 100 }; 101 102 class StreamClient : public ClientBase<String> { 103 public: 104 StreamClient(MediaStreamFrameController* frameController, const String& label) : ClientBase<String>(frameController, label) { } 105 virtual ~StreamClient() { unregister(); } 106 107 virtual bool isStream() const { return true; } 108 109 // Stream has ended for some external reason. 110 virtual void streamEnded() = 0; 111 112 private: 113 virtual void unregister() { unregisterClient(this); } 114 }; 115 45 116 MediaStreamFrameController(Frame*); 46 117 virtual ~MediaStreamFrameController(); … … 49 120 ScriptExecutionContext* scriptExecutionContext() const; 50 121 122 bool isClientAvailable() const; 51 123 void disconnectPage(); 52 124 void disconnectFrame(); 53 125 void transferToNewPage(Page*); 54 126 127 // Parse the options string provided to the generateStream method. 128 static GenerateStreamOptionFlags parseGenerateStreamOptions(const String&); 129 130 // Create a new generated stream asynchronously with the provided options. 131 void generateStream(const String& options, PassRefPtr<NavigatorUserMediaSuccessCallback>, PassRefPtr<NavigatorUserMediaErrorCallback>, ExceptionCode&); 132 133 // --- Calls coming back from the controller. --- // 134 135 // Report the generation of a new local stream. 136 void streamGenerated(int requestId, const String& streamLabel); 137 138 // Report a failure in the generation of a new stream. 139 void streamGenerationFailed(int requestId, NavigatorUserMediaError::ErrorCode); 140 55 141 private: 56 142 class Request; 143 class GenerateStreamRequest; 57 144 58 class RequestMap : public HashMap<int, RefPtr<Request> > { 145 class IdGenerator { 146 WTF_MAKE_NONCOPYABLE(IdGenerator); 147 public: 148 IdGenerator() : m_id(0) { } 149 int getNextId() { return ++m_id; } 150 151 private: 152 int m_id; 153 }; 154 155 class RequestMap : public IdGenerator, public HashMap<int, RefPtr<Request> > { 59 156 public: 60 157 void abort(int requestId); … … 62 159 }; 63 160 161 template <typename IdType> 162 class ClientMapBase : public HashMap<IdType, ClientBase<IdType>* > { 163 WTF_MAKE_NONCOPYABLE(ClientMapBase); 164 public: 165 typedef HashMap<IdType, ClientBase<IdType>* > MapType; 166 167 ClientMapBase() { } 168 void unregisterAll(); 169 void detachEmbedder(); 170 }; 171 172 // Streams are a special class of clients since they are identified by a global label string instead of an id. 173 typedef ClientMapBase<String> StreamMap; 174 64 175 // Detached from a page, and hence from a embedder client. 65 176 void enterDetachedState(); 66 177 178 void unregister(StreamClient*); 67 179 MediaStreamController* pageController() const; 68 180 69 181 RequestMap m_requests; 182 StreamMap m_streams; 70 183 71 184 Frame* m_frame; -
trunk/Source/WebCore/page/Navigator.cpp
r86055 r86583 36 36 #include "KURL.h" 37 37 #include "Language.h" 38 #include "MediaStreamFrameController.h" 38 39 #include "NavigatorUserMediaErrorCallback.h" 39 40 #include "NavigatorUserMediaSuccessCallback.h" … … 246 247 247 248 #if ENABLE(MEDIA_STREAM) 248 void Navigator::webkitGetUserMedia(const String&, PassRefPtr<NavigatorUserMediaSuccessCallback>, PassRefPtr<NavigatorUserMediaErrorCallback>, ExceptionCode&) 249 { 250 // FIXME: implement a call to the media stream context when available. 249 void Navigator::webkitGetUserMedia(const String& options, PassRefPtr<NavigatorUserMediaSuccessCallback> successCallback, PassRefPtr<NavigatorUserMediaErrorCallback> errorCallback, ExceptionCode& ec) 250 { 251 if (m_frame && m_frame->mediaStreamFrameController()) 252 m_frame->mediaStreamFrameController()->generateStream(options, successCallback, errorCallback, ec); 251 253 } 252 254 #endif -
trunk/Source/WebCore/page/NavigatorUserMediaErrorCallback.h
r83287 r86583 28 28 #if ENABLE(MEDIA_STREAM) 29 29 30 #include "CallbackTask.h" 31 #include "NavigatorUserMediaError.h" 30 32 #include <wtf/RefCounted.h> 31 33 32 34 namespace WebCore { 33 35 34 class NavigatorUserMediaError; 35 36 class NavigatorUserMediaErrorCallback : public RefCounted<NavigatorUserMediaErrorCallback> { 36 class NavigatorUserMediaErrorCallback : public RefCounted<NavigatorUserMediaErrorCallback>, 37 public CallbackTask1<NavigatorUserMediaErrorCallback, NavigatorUserMediaError>::Scheduler { 37 38 public: 38 39 virtual ~NavigatorUserMediaErrorCallback() { }
Note: See TracChangeset
for help on using the changeset viewer.