MediaDevices.getUserMedia should migrate from callbacks to DOMPromise
authoryouenn.fablet@crf.canon.fr <youenn.fablet@crf.canon.fr@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 23 Jun 2015 14:10:06 +0000 (14:10 +0000)
committeryouenn.fablet@crf.canon.fr <youenn.fablet@crf.canon.fr@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 23 Jun 2015 14:10:06 +0000 (14:10 +0000)
https://bugs.webkit.org/show_bug.cgi?id=146200

Reviewed by Darin Adler.

Source/WebCore:

Introduced DOMPromiseWithCallback to resolve/reject promises while allowing promise clients to use a typed callback approach.
Migrated MediaDevices.getUserMedia from callbacks to DOMPromiseWithCallback.
Removed MediaDevices.getUserMedia custom binding.

Covered by existing tests.

* CMakeLists.txt: Removing custom binding.
* Modules/mediastream/MediaDevices.cpp:
(WebCore::MediaDevices::getUserMedia): Moving from callback to promise.
* Modules/mediastream/MediaDevices.h: Ditto.
* Modules/mediastream/MediaDevices.idl: Removing custom binding.
* Modules/mediastream/NavigatorUserMedia.cpp:
(WebCore::NavigatorUserMedia::webkitGetUserMedia): Converting from promise callback to API callbacks.
* Modules/mediastream/UserMediaRequest.cpp:
(WebCore::UserMediaRequest::create): Moving from callback to promise.
(WebCore::UserMediaRequest::UserMediaRequest): Ditto.
(WebCore::UserMediaRequest::didCreateStream): Ditto.
(WebCore::UserMediaRequest::failedToCreateStreamWithConstraintsError): Ditto.
(WebCore::UserMediaRequest::failedToCreateStreamWithPermissionError): Ditto.
* Modules/mediastream/UserMediaRequest.h: Ditto.
* bindings/js/JSDOMPromise.h: Introducing DOMPromiseWithCallback and removing crypto specific header.
(WebCore::DOMPromiseWithCallback::DOMPromiseWithCallback):
(WebCore::Error>::resolve):
(WebCore::Error>::reject):
* bindings/js/JSMediaDevicesCustom.cpp: Removed.
* bindings/js/JSSubtleCryptoCustom.cpp: Updating headers.

LayoutTests:

* fast/mediastream/MediaDevices-getUserMedia-expected.txt:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@185873 268f45cc-cd09-0410-ab3c-d52691b4dbfc

14 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/mediastream/MediaDevices-getUserMedia-expected.txt
Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/Modules/mediastream/MediaDevices.cpp
Source/WebCore/Modules/mediastream/MediaDevices.h
Source/WebCore/Modules/mediastream/MediaDevices.idl
Source/WebCore/Modules/mediastream/NavigatorUserMedia.cpp
Source/WebCore/Modules/mediastream/UserMediaRequest.cpp
Source/WebCore/Modules/mediastream/UserMediaRequest.h
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/bindings/js/JSDOMPromise.h
Source/WebCore/bindings/js/JSMediaDevicesCustom.cpp [deleted file]
Source/WebCore/bindings/js/JSSubtleCryptoCustom.cpp

index b87be73..70a3caa 100644 (file)
@@ -1,3 +1,12 @@
+2015-06-23  Youenn Fablet  <youenn.fablet@crf.canon.fr>
+
+        MediaDevices.getUserMedia should migrate from callbacks to DOMPromise
+        https://bugs.webkit.org/show_bug.cgi?id=146200
+
+        Reviewed by Darin Adler.
+
+        * fast/mediastream/MediaDevices-getUserMedia-expected.txt:
+
 2015-06-23  Xabier Rodriguez Calvar  <calvaris@igalia.com> and Youenn Fablet  <youenn.fablet@crf.canon.fr>
 
         [Streams API] Implement ReadableStream js source "'cancel" callback
index e059e31..19f5bb1 100644 (file)
@@ -5,7 +5,7 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
 
 PASS typeof navigator.mediaDevices.webkitGetUserMedia is 'undefined'
 PASS navigator.mediaDevices.getUserMedia({audio:true}).then(gotStream1); did not throw exception.
-PASS navigator.mediaDevices.getUserMedia() rejected with error: TypeError: First argument of getUserMedia must be a valid Dictionary
+PASS navigator.mediaDevices.getUserMedia() rejected with error: TypeError: Not enough arguments
 PASS  navigator.mediaDevices.getUserMedia({}) rejected with error: Error: NotSupportedError: DOM Exception 9
 PASS Stream generated.
 PASS stream.getAudioTracks().length is 1
index a5cdb68..d18e423 100644 (file)
@@ -1153,7 +1153,6 @@ set(WebCore_SOURCES
     bindings/js/JSLazyEventListener.cpp
     bindings/js/JSLocationCustom.cpp
     bindings/js/JSMainThreadExecState.cpp
-    bindings/js/JSMediaDevicesCustom.cpp
     bindings/js/JSMediaSourceStatesCustom.cpp
     bindings/js/JSMediaStreamCapabilitiesCustom.cpp
     bindings/js/JSMessageChannelCustom.cpp
index f183948..1024510 100644 (file)
@@ -1,3 +1,37 @@
+2015-06-23  Youenn Fablet  <youenn.fablet@crf.canon.fr>
+
+        MediaDevices.getUserMedia should migrate from callbacks to DOMPromise
+        https://bugs.webkit.org/show_bug.cgi?id=146200
+
+        Reviewed by Darin Adler.
+
+        Introduced DOMPromiseWithCallback to resolve/reject promises while allowing promise clients to use a typed callback approach.
+        Migrated MediaDevices.getUserMedia from callbacks to DOMPromiseWithCallback.
+        Removed MediaDevices.getUserMedia custom binding.
+
+        Covered by existing tests.
+
+        * CMakeLists.txt: Removing custom binding.
+        * Modules/mediastream/MediaDevices.cpp:
+        (WebCore::MediaDevices::getUserMedia): Moving from callback to promise.
+        * Modules/mediastream/MediaDevices.h: Ditto.
+        * Modules/mediastream/MediaDevices.idl: Removing custom binding.
+        * Modules/mediastream/NavigatorUserMedia.cpp:
+        (WebCore::NavigatorUserMedia::webkitGetUserMedia): Converting from promise callback to API callbacks.
+        * Modules/mediastream/UserMediaRequest.cpp:
+        (WebCore::UserMediaRequest::create): Moving from callback to promise.
+        (WebCore::UserMediaRequest::UserMediaRequest): Ditto.
+        (WebCore::UserMediaRequest::didCreateStream): Ditto.
+        (WebCore::UserMediaRequest::failedToCreateStreamWithConstraintsError): Ditto.
+        (WebCore::UserMediaRequest::failedToCreateStreamWithPermissionError): Ditto.
+        * Modules/mediastream/UserMediaRequest.h: Ditto.
+        * bindings/js/JSDOMPromise.h: Introducing DOMPromiseWithCallback and removing crypto specific header.
+        (WebCore::DOMPromiseWithCallback::DOMPromiseWithCallback):
+        (WebCore::Error>::resolve):
+        (WebCore::Error>::reject):
+        * bindings/js/JSMediaDevicesCustom.cpp: Removed.
+        * bindings/js/JSSubtleCryptoCustom.cpp: Updating headers.
+
 2015-06-23  Xabier Rodriguez Calvar  <calvaris@igalia.com> and Youenn Fablet  <youenn.fablet@crf.canon.fr>
 
         [Streams API] Implement ReadableStream js source "'cancel" callback
index 02fbc86..6a94bb2 100644 (file)
@@ -60,8 +60,13 @@ Document* MediaDevices::document() const
     return downcast<Document>(scriptExecutionContext());
 }
 
-void MediaDevices::getUserMedia(const Dictionary& options, ResolveCallback resolveCallback, RejectCallback rejectCallback, ExceptionCode& ec) const
+void MediaDevices::getUserMedia(const Dictionary& options, Promise&& promise, ExceptionCode& ec) const
 {
+    if (!options.isObject()) {
+        ec = TypeError;
+        return;
+    }
+
     UserMediaController* userMedia = UserMediaController::from(document() ? document()->page() : nullptr);
     if (!userMedia) {
         // FIXME: We probably want to return a MediaStreamError here using the rejectCallback, and get rid off the ExceptionCode parameter.
@@ -69,7 +74,7 @@ void MediaDevices::getUserMedia(const Dictionary& options, ResolveCallback resol
         return;
     }
 
-    RefPtr<UserMediaRequest> request = UserMediaRequest::create(document(), userMedia, options, WTF::move(resolveCallback), WTF::move(rejectCallback), ec);
+    RefPtr<UserMediaRequest> request = UserMediaRequest::create(document(), userMedia, options, WTF::move(promise), ec);
     if (!request) {
         ec = NOT_SUPPORTED_ERR;
         return;
index 74a781c..3758a10 100644 (file)
@@ -34,6 +34,7 @@
 #if ENABLE(MEDIA_STREAM)
 
 #include "ContextDestructionObserver.h"
+#include "JSDOMPromise.h"
 #include "ScriptWrappable.h"
 #include <functional>
 #include <wtf/RefCounted.h>
@@ -55,10 +56,8 @@ public:
 
     Document* document() const;
 
-    typedef std::function<void(MediaStream&)> ResolveCallback;
-    typedef std::function<void(NavigatorUserMediaError&)> RejectCallback;
-
-    void getUserMedia(const Dictionary&, ResolveCallback, RejectCallback, ExceptionCode&) const;
+    typedef DOMPromiseWithCallback<RefPtr<MediaStream>, RefPtr<NavigatorUserMediaError>> Promise;
+    void getUserMedia(const Dictionary&, Promise&&, ExceptionCode&) const;
 
 private:
     explicit MediaDevices(ScriptExecutionContext*);
index 533f10f..6b0b843 100644 (file)
@@ -32,5 +32,5 @@
     NoInterfaceObject,
     Conditional=MEDIA_STREAM
 ] interface MediaDevices {
-    [Custom, RaisesException] Promise getUserMedia(Dictionary options);
+    [RaisesException] Promise getUserMedia(Dictionary options);
 };
index 19abe4d..e03c6ac 100644 (file)
@@ -29,7 +29,9 @@
 #include "Document.h"
 #include "ExceptionCode.h"
 #include "Frame.h"
+#include "MediaStream.h"
 #include "Navigator.h"
+#include "NavigatorUserMediaError.h"
 #include "NavigatorUserMediaErrorCallback.h"
 #include "NavigatorUserMediaSuccessCallback.h"
 #include "Page.h"
@@ -48,6 +50,7 @@ NavigatorUserMedia::~NavigatorUserMedia()
 
 void NavigatorUserMedia::webkitGetUserMedia(Navigator* navigator, const Dictionary& options, PassRefPtr<NavigatorUserMediaSuccessCallback> successCallback, PassRefPtr<NavigatorUserMediaErrorCallback> errorCallback, ExceptionCode& ec)
 {
+    // FIXME: Remove this test once IDL is updated to make errroCallback parameter mandatory.
     if (!successCallback || !errorCallback) {
         ec = TYPE_MISMATCH_ERR;
         return;
@@ -59,7 +62,25 @@ void NavigatorUserMedia::webkitGetUserMedia(Navigator* navigator, const Dictiona
         return;
     }
 
-    RefPtr<UserMediaRequest> request = UserMediaRequest::create(navigator->frame()->document(), userMedia, options, successCallback, errorCallback, ec);
+    // We do not need to protect the context (i.e. document) here as UserMediaRequest is observing context destruction and will check validity before resolving/rejecting promise.
+    Document* document = navigator->frame()->document();
+
+    ASSERT(errorCallback);
+    ASSERT(successCallback);
+    auto resolveCallback = [successCallback, document](const RefPtr<MediaStream>& stream) mutable {
+        RefPtr<MediaStream> protectedStream = stream;
+        document->postTask([successCallback, protectedStream](ScriptExecutionContext&) {
+            successCallback->handleEvent(protectedStream.get());
+        });
+    };
+    auto rejectCallback = [errorCallback, document](const RefPtr<NavigatorUserMediaError>& error) mutable {
+        RefPtr<NavigatorUserMediaError> protectedError = error;
+        document->postTask([errorCallback, protectedError](ScriptExecutionContext&) {
+            errorCallback->handleEvent(protectedError.get());
+        });
+    };
+
+    auto request = UserMediaRequest::create(navigator->frame()->document(), userMedia, options, MediaDevices::Promise(WTF::move(resolveCallback), WTF::move(rejectCallback)), ec);
     if (!request) {
         ec = NOT_SUPPORTED_ERR;
         return;
index 0597470..d09e080 100644 (file)
@@ -41,6 +41,8 @@
 #include "Document.h"
 #include "ExceptionCode.h"
 #include "Frame.h"
+#include "JSMediaStream.h"
+#include "JSNavigatorUserMediaError.h"
 #include "MediaConstraintsImpl.h"
 #include "MediaStream.h"
 #include "MediaStreamPrivate.h"
@@ -71,36 +73,8 @@ static PassRefPtr<MediaConstraints> parseOptions(const Dictionary& options, cons
     return constraints.release();
 }
 
-RefPtr<UserMediaRequest> UserMediaRequest::create(ScriptExecutionContext* context, UserMediaController* controller, const Dictionary& options, PassRefPtr<NavigatorUserMediaSuccessCallback> successCallback, PassRefPtr<NavigatorUserMediaErrorCallback> errorCallback, ExceptionCode& ec)
+RefPtr<UserMediaRequest> UserMediaRequest::create(ScriptExecutionContext* context, UserMediaController* controller, const Dictionary& options, MediaDevices::Promise&& promise, ExceptionCode& ec)
 {
-    ASSERT(successCallback);
-
-    auto resolveCallback = [successCallback, context](MediaStream& stream) mutable {
-        ASSERT(context);
-
-        RefPtr<MediaStream> mediaStream = &stream;
-        context->postTask([successCallback, mediaStream](ScriptExecutionContext&) {
-            successCallback->handleEvent(mediaStream.get());
-        });
-    };
-    auto rejectCallback = [errorCallback, context](NavigatorUserMediaError& error) mutable {
-        ASSERT(context);
-
-        if (errorCallback) {
-            RefPtr<NavigatorUserMediaError> eventError = &error;
-            context->postTask([errorCallback, eventError](ScriptExecutionContext&) {
-                errorCallback->handleEvent(eventError.get());
-            });
-        }
-    };
-
-    return UserMediaRequest::create(context, controller, options, WTF::move(resolveCallback), WTF::move(rejectCallback), ec);
-}
-
-RefPtr<UserMediaRequest> UserMediaRequest::create(ScriptExecutionContext* context, UserMediaController* controller, const Dictionary& options, MediaDevices::ResolveCallback&& resolveCallback, MediaDevices::RejectCallback&& rejectCallback, ExceptionCode& ec)
-{
-    ASSERT(resolveCallback && rejectCallback);
-
     RefPtr<MediaConstraints> audioConstraints = parseOptions(options, AtomicString("audio", AtomicString::ConstructFromLiteral), ec);
     if (ec)
         return nullptr;
@@ -112,16 +86,15 @@ RefPtr<UserMediaRequest> UserMediaRequest::create(ScriptExecutionContext* contex
     if (!audioConstraints && !videoConstraints)
         return nullptr;
 
-    return adoptRef(*new UserMediaRequest(context, controller, audioConstraints.release(), videoConstraints.release(), WTF::move(resolveCallback), WTF::move(rejectCallback)));
+    return adoptRef(*new UserMediaRequest(context, controller, audioConstraints.release(), videoConstraints.release(), WTF::move(promise)));
 }
 
-UserMediaRequest::UserMediaRequest(ScriptExecutionContext* context, UserMediaController* controller, PassRefPtr<MediaConstraints> audioConstraints, PassRefPtr<MediaConstraints> videoConstraints, MediaDevices::ResolveCallback&& resolveCallback, MediaDevices::RejectCallback&& rejectCallback)
+UserMediaRequest::UserMediaRequest(ScriptExecutionContext* context, UserMediaController* controller, PassRefPtr<MediaConstraints> audioConstraints, PassRefPtr<MediaConstraints> videoConstraints, MediaDevices::Promise&& promise)
     : ContextDestructionObserver(context)
     , m_audioConstraints(audioConstraints)
     , m_videoConstraints(videoConstraints)
     , m_controller(controller)
-    , m_resolveCallback(WTF::move(resolveCallback))
-    , m_rejectCallback(WTF::move(rejectCallback))
+    , m_promise(WTF::move(promise))
 {
 }
 
@@ -144,7 +117,6 @@ void UserMediaRequest::start()
     RealtimeMediaSourceCenter::singleton().validateRequestConstraints(this, m_audioConstraints, m_videoConstraints);
 }
 
-    
 void UserMediaRequest::constraintsValidated()
 {
     RefPtr<UserMediaRequest> protectedThis(this);
@@ -186,7 +158,7 @@ void UserMediaRequest::didCreateStream(PassRefPtr<MediaStreamPrivate> privateStr
     for (auto& track : stream->getVideoTracks())
         track->applyConstraints(m_videoConstraints);
 
-    m_resolveCallback(*stream);
+    m_promise.resolve(stream);
 }
 
 void UserMediaRequest::failedToCreateStreamWithConstraintsError(const String& constraintName)
@@ -195,7 +167,7 @@ void UserMediaRequest::failedToCreateStreamWithConstraintsError(const String& co
     if (!m_scriptExecutionContext)
         return;
 
-    m_rejectCallback(NavigatorUserMediaError::create(NavigatorUserMediaError::constraintNotSatisfiedErrorName(), constraintName).get());
+    m_promise.reject(NavigatorUserMediaError::create(NavigatorUserMediaError::constraintNotSatisfiedErrorName(), constraintName));
 }
 
 void UserMediaRequest::failedToCreateStreamWithPermissionError()
@@ -204,7 +176,7 @@ void UserMediaRequest::failedToCreateStreamWithPermissionError()
         return;
 
     // FIXME: Replace NavigatorUserMediaError with MediaStreamError (see bug 143335)
-    m_rejectCallback(NavigatorUserMediaError::create(NavigatorUserMediaError::permissionDeniedErrorName(), emptyString()));
+    m_promise.reject(NavigatorUserMediaError::create(NavigatorUserMediaError::permissionDeniedErrorName(), emptyString()));
 }
 
 void UserMediaRequest::contextDestroyed()
index f3539db..a93f2bd 100644 (file)
@@ -58,8 +58,7 @@ typedef int ExceptionCode;
 
 class UserMediaRequest : public MediaStreamCreationClient, public ContextDestructionObserver {
 public:
-    static RefPtr<UserMediaRequest> create(ScriptExecutionContext*, UserMediaController*, const Dictionary& options, PassRefPtr<NavigatorUserMediaSuccessCallback>, PassRefPtr<NavigatorUserMediaErrorCallback>, ExceptionCode&);
-    static RefPtr<UserMediaRequest> create(ScriptExecutionContext*, UserMediaController*, const Dictionary& options, MediaDevices::ResolveCallback&&, MediaDevices::RejectCallback&&, ExceptionCode&);
+    static RefPtr<UserMediaRequest> create(ScriptExecutionContext*, UserMediaController*, const Dictionary& options, MediaDevices::Promise&&, ExceptionCode&);
     ~UserMediaRequest();
 
     WEBCORE_EXPORT SecurityOrigin* securityOrigin() const;
@@ -72,7 +71,7 @@ public:
     bool requiresVideo() const { return m_videoConstraints; }
 
 private:
-    UserMediaRequest(ScriptExecutionContext*, UserMediaController*, PassRefPtr<MediaConstraints> audioConstraints, PassRefPtr<MediaConstraints> videoConstraints, MediaDevices::ResolveCallback&&, MediaDevices::RejectCallback&&);
+    UserMediaRequest(ScriptExecutionContext*, UserMediaController*, PassRefPtr<MediaConstraints> audioConstraints, PassRefPtr<MediaConstraints> videoConstraints, MediaDevices::Promise&&);
 
     // MediaStreamCreationClient
     virtual void constraintsValidated() override final;
@@ -89,8 +88,7 @@ private:
 
     UserMediaController* m_controller;
 
-    MediaDevices::ResolveCallback m_resolveCallback;
-    MediaDevices::RejectCallback m_rejectCallback;
+    MediaDevices::Promise m_promise;
 };
 
 } // namespace WebCore
index 34be221..a97cf64 100644 (file)
                5DFE8F560D16477B0076E937 /* ScheduledAction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCA378BA0D15F64200B793D6 /* ScheduledAction.cpp */; };
                5DFE8F570D16477C0076E937 /* ScheduledAction.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA378BB0D15F64200B793D6 /* ScheduledAction.h */; settings = {ATTRIBUTES = (Private, ); }; };
                5DFEBAB718592B6D00C75BEB /* WebKitAvailability.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DFEBAB618592B6D00C75BEB /* WebKitAvailability.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               5EA725D11ACABD3800EAD17B /* JSMediaDevicesCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5EA725D01ACABD2700EAD17B /* JSMediaDevicesCustom.cpp */; };
                5EA725D21ACABD4700EAD17B /* MediaDevices.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5EA725CD1ACABCD900EAD17B /* MediaDevices.cpp */; };
                5EA725D31ACABD4700EAD17B /* MediaDevices.h in Headers */ = {isa = PBXBuildFile; fileRef = 5EA725CE1ACABCD900EAD17B /* MediaDevices.h */; };
                5EA725D51ACABD5700EAD17B /* NavigatorMediaDevices.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5EA725CA1ACABCB500EAD17B /* NavigatorMediaDevices.cpp */; };
                5EA725CD1ACABCD900EAD17B /* MediaDevices.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MediaDevices.cpp; sourceTree = "<group>"; };
                5EA725CE1ACABCD900EAD17B /* MediaDevices.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaDevices.h; sourceTree = "<group>"; };
                5EA725CF1ACABCD900EAD17B /* MediaDevices.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = MediaDevices.idl; sourceTree = "<group>"; };
-               5EA725D01ACABD2700EAD17B /* JSMediaDevicesCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSMediaDevicesCustom.cpp; sourceTree = "<group>"; };
                5F2DBBE7178E332D00141486 /* CertificateInfoMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CertificateInfoMac.mm; sourceTree = "<group>"; };
                5F2DBBE8178E336900141486 /* CertificateInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CertificateInfo.h; sourceTree = "<group>"; };
                5FC7DC26CFE2563200B85AE5 /* JSEventTarget.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSEventTarget.h; sourceTree = "<group>"; };
                                A7D0318D0E93540300E24ACD /* JSImageDataCustom.cpp */,
                                7A74ECBC101839DA00BF939E /* JSInspectorFrontendHostCustom.cpp */,
                                BCE1C43F0D9830F4003B02F2 /* JSLocationCustom.cpp */,
-                               5EA725D01ACABD2700EAD17B /* JSMediaDevicesCustom.cpp */,
                                AD726FE716D9F204003A4E6D /* JSMediaListCustom.h */,
                                07C59B6D17F794F6000FBCBB /* JSMediaSourceStatesCustom.cpp */,
                                0705851617FB40E9005F2BCB /* JSMediaStreamCapabilitiesCustom.cpp */,
                                8FAC774D119872CB0015AE94 /* JSMainThreadExecState.cpp in Sources */,
                                CD27F6E51457685A0078207D /* JSMediaController.cpp in Sources */,
                                CDAB6D2D17C814EE00C60B34 /* JSMediaControlsHost.cpp in Sources */,
-                               5EA725D11ACABD3800EAD17B /* JSMediaDevicesCustom.cpp in Sources */,
                                FD23A12513F5FA5900F67001 /* JSMediaElementAudioSourceNode.cpp in Sources */,
                                E44614180CD6826900FADA75 /* JSMediaError.cpp in Sources */,
                                CDA98DA31601464100FEA3B1 /* JSMediaKeyError.cpp in Sources */,
index 08db29c..a8aad03 100644 (file)
 
 #if ENABLE(PROMISES)
 
-#include "JSCryptoKey.h"
-#include "JSCryptoKeyPair.h"
 #include "JSDOMBinding.h"
 #include <heap/StrongInlines.h>
 #include <runtime/JSPromiseDeferred.h>
+#include <wtf/Optional.h>
 
 namespace WebCore {
 
@@ -86,6 +85,31 @@ private:
     DeferredWrapper m_wrapper;
 };
 
+template<typename Value, typename Error>
+class DOMPromiseWithCallback {
+public:
+    DOMPromiseWithCallback(DeferredWrapper&& wrapper) : m_wrapper(WTF::move(wrapper)) { }
+    DOMPromiseWithCallback(std::function<void(const Value&)> resolve, std::function<void(const Error&)> reject)
+        : m_resolveCallback(WTF::move(resolve))
+        , m_rejectCallback(WTF::move(reject))
+    {
+        ASSERT(m_resolveCallback);
+        ASSERT(m_rejectCallback);
+    }
+    explicit DOMPromiseWithCallback(DOMPromiseWithCallback&& promise)
+        : m_wrapper(WTF::move(promise.m_wrapper))
+        , m_resolveCallback(WTF::move(promise.m_resolveCallback))
+        , m_rejectCallback(WTF::move(promise.m_rejectCallback)) { }
+
+    void resolve(const Value&);
+    void reject(const Error&);
+
+private:
+    Optional<DOMPromise<Value, Error>> m_wrapper;
+    std::function<void(const Value&)> m_resolveCallback;
+    std::function<void(const Error&)> m_rejectCallback;
+};
+
 template<class ResolveResultType>
 inline void DeferredWrapper::resolve(const ResolveResultType& result)
 {
@@ -196,6 +220,28 @@ inline void DeferredWrapper::reject<String>(const String& result)
     reject(*exec, jsString(exec, result));
 }
 
+template<typename Value, typename Error>
+inline void DOMPromiseWithCallback<Value, Error>::resolve(const Value& value)
+{
+    if (m_resolveCallback) {
+        m_resolveCallback(value);
+        return;
+    }
+    ASSERT(m_wrapper);
+    m_wrapper.value().resolve(value);
+}
+
+template<typename Value, typename Error>
+inline void DOMPromiseWithCallback<Value, Error>::reject(const Error& error)
+{
+    if (m_rejectCallback) {
+        m_rejectCallback(error);
+        return;
+    }
+    ASSERT(m_wrapper);
+    m_wrapper.value().reject(error);
+}
+
 }
 
 #endif // ENABLE(PROMISES)
diff --git a/Source/WebCore/bindings/js/JSMediaDevicesCustom.cpp b/Source/WebCore/bindings/js/JSMediaDevicesCustom.cpp
deleted file mode 100644 (file)
index 6bd2a72..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2015 Ericsson AB. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer
- *    in the documentation and/or other materials provided with the
- *    distribution.
- * 3. Neither the name of Ericsson nor the names of its contributors
- *    may be used to endorse or promote products derived from this
- *    software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#if ENABLE(MEDIA_STREAM)
-#include "JSMediaDevices.h"
-
-#include "Dictionary.h"
-#include "ExceptionCode.h"
-#include "JSDOMBinding.h"
-#include "JSDOMPromise.h"
-#include "JSMediaStream.h"
-#include "JSNavigatorUserMediaError.h"
-#include <runtime/Exception.h>
-
-using namespace JSC;
-
-namespace WebCore {
-
-JSValue JSMediaDevices::getUserMedia(ExecState* exec)
-{
-    JSPromiseDeferred* promiseDeferred = JSPromiseDeferred::create(exec, globalObject());
-    DeferredWrapper wrapper(exec, globalObject(), promiseDeferred);
-
-    Dictionary options(exec, exec->argument(0));
-    if (exec->hadException()) {
-        Exception* exception = exec->exception();
-        exec->clearException();
-        wrapper.reject(exception->value());
-        return promiseDeferred->promise();
-    }
-
-    if (!options.isObject()) {
-        JSValue error = createTypeError(exec, "First argument of getUserMedia must be a valid Dictionary");
-        wrapper.reject(error);
-        return promiseDeferred->promise();
-    }
-
-    auto resolveCallback = [wrapper](MediaStream& stream) mutable {
-        wrapper.resolve(&stream);
-    };
-    auto rejectCallback = [wrapper](NavigatorUserMediaError& error) mutable {
-        wrapper.reject(&error);
-    };
-
-    ExceptionCode ec = 0;
-    impl().getUserMedia(options, WTF::move(resolveCallback), WTF::move(rejectCallback), ec);
-    if (ec)
-        wrapper.reject(ec);
-
-    return promiseDeferred->promise();
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(MEDIA_STREAM)
index 4df5b26..d8c7ff1 100644 (file)
@@ -36,6 +36,8 @@
 #include "Document.h"
 #include "ExceptionCode.h"
 #include "JSCryptoAlgorithmDictionary.h"
+#include "JSCryptoKey.h"
+#include "JSCryptoKeyPair.h"
 #include "JSCryptoKeySerializationJWK.h"
 #include "JSCryptoOperationData.h"
 #include "JSDOMPromise.h"