[MediaStream] UIClient may not be notified of capture state change when leaving a...
authoreric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 2 Mar 2017 15:50:09 +0000 (15:50 +0000)
committereric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 2 Mar 2017 15:50:09 +0000 (15:50 +0000)
https://bugs.webkit.org/show_bug.cgi?id=169014
<rdar://problem/30632267>

Reviewed by Youenn Fablet.

Enable and update the WebKit API test WebKit2.UserMedia.

* dom/Document.cpp:
(WebCore::Document::prepareForDestruction): Always call page.updateIsPlayingMedia() if there
is active media in the document because it won't be possible when the state changes later
because the frame will have been cleared.

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

Source/WebCore/ChangeLog
Source/WebCore/dom/Document.cpp
Tools/TestWebKitAPI/Tests/WebKit2/UserMedia.cpp
Tools/TestWebKitAPI/Tests/WebKit2/getUserMedia.html

index deb7f46..d27abaa 100644 (file)
@@ -1,3 +1,18 @@
+2017-03-02  Eric Carlson  <eric.carlson@apple.com>
+
+        [MediaStream] UIClient may not be notified of capture state change when leaving a page
+        https://bugs.webkit.org/show_bug.cgi?id=169014
+        <rdar://problem/30632267>
+
+        Reviewed by Youenn Fablet.
+
+        Enable and update the WebKit API test WebKit2.UserMedia.
+
+        * dom/Document.cpp:
+        (WebCore::Document::prepareForDestruction): Always call page.updateIsPlayingMedia() if there
+        is active media in the document because it won't be possible when the state changes later
+        because the frame will have been cleared.
+
 2017-03-02  Tomas Popela  <tpopela@redhat.com>
 
         [WK2] Keyboard menu key should show context menu
index 9de7541..6bbc54f 100644 (file)
@@ -2327,6 +2327,11 @@ void Document::prepareForDestruction()
     }
 #endif
 
+    if (page() && m_mediaState != MediaProducer::IsNotPlaying) {
+        m_mediaState = MediaProducer::IsNotPlaying;
+        page()->updateIsPlayingMedia(HTMLMediaElementInvalidID);
+    }
+
     detachFromFrame();
 
     m_hasPreparedForDestruction = true;
index fc7ade4..e9bf547 100644 (file)
 #include "PlatformUtilities.h"
 #include "PlatformWebView.h"
 #include "Test.h"
+#include <WebKit/WKPagePrivate.h>
+#include <WebKit/WKPreferencesRef.h>
+#include <WebKit/WKPreferencesRefPrivate.h>
 #include <WebKit/WKRetainPtr.h>
 #include <string.h>
 #include <vector>
 
 namespace TestWebKitAPI {
 
-static bool done;
+static bool wasPrompted;
+static bool isPlayingChanged;
+static bool didFinishLoad;
 
-void decidePolicyForUserMediaPermissionRequestCallBack(WKPageRef, WKFrameRef, WKSecurityOriginRef, WKSecurityOriginRef, WKUserMediaPermissionRequestRef permissionRequest, const void* /* clientInfo */)
+static void nullJavaScriptCallback(WKSerializedScriptValueRef, WKErrorRef error, void*)
+{
+}
+
+static void decidePolicyForUserMediaPermissionRequestCallBack(WKPageRef, WKFrameRef, WKSecurityOriginRef, WKSecurityOriginRef, WKUserMediaPermissionRequestRef permissionRequest, const void* /* clientInfo */)
 {
     WKRetainPtr<WKArrayRef> audioDeviceUIDs = WKUserMediaPermissionRequestAudioDeviceUIDs(permissionRequest);
     WKRetainPtr<WKArrayRef> videoDeviceUIDs = WKUserMediaPermissionRequestVideoDeviceUIDs(permissionRequest);
@@ -54,27 +63,73 @@ void decidePolicyForUserMediaPermissionRequestCallBack(WKPageRef, WKFrameRef, WK
         WKUserMediaPermissionRequestAllow(permissionRequest, audioDeviceUID.get(), videoDeviceUID.get());
     }
 
-    done = true;
+    wasPrompted = true;
+}
+
+static void isPlayingDidChangeCallback(WKPageRef page, const void*)
+{
+    isPlayingChanged = true;
+}
+
+static void didFinishLoadForFrame(WKPageRef page, WKFrameRef, WKTypeRef, const void*)
+{
+    didFinishLoad = true;
 }
 
-TEST(WebKit2, DISABLED_UserMediaBasic)
+TEST(WebKit2, UserMediaBasic)
 {
     auto context = adoptWK(WKContextCreate());
-    PlatformWebView webView(context.get());
-    WKPageUIClientV5 uiClient;
-    memset(&uiClient, 0, sizeof(uiClient));
 
+    WKRetainPtr<WKPageGroupRef> pageGroup(AdoptWK, WKPageGroupCreateWithIdentifier(Util::toWK("GetUserMedia").get()));
+    WKPreferencesRef preferences = WKPageGroupGetPreferences(pageGroup.get());
+    WKPreferencesSetMediaStreamEnabled(preferences, true);
+    WKPreferencesSetFileAccessFromFileURLsAllowed(preferences, true);
+    WKPreferencesSetMediaCaptureRequiresSecureConnection(preferences, false);
+    WKPreferencesSetMockCaptureDevicesEnabled(preferences, true);
+
+    WKPageLoaderClientV0 loaderClient;
+    memset(&loaderClient, 0, sizeof(loaderClient));
+    loaderClient.base.version = 0;
+    loaderClient.didFinishLoadForFrame = didFinishLoadForFrame;
 
-    uiClient.base.version = 5;
+    WKPageUIClientV6 uiClient;
+    memset(&uiClient, 0, sizeof(uiClient));
+    uiClient.base.version = 6;
+    uiClient.isPlayingAudioDidChange = isPlayingDidChangeCallback;
     uiClient.decidePolicyForUserMediaPermissionRequest = decidePolicyForUserMediaPermissionRequestCallBack;
 
+    PlatformWebView webView(context.get(), pageGroup.get());
     WKPageSetPageUIClient(webView.page(), &uiClient.base);
+    WKPageSetPageLoaderClient(webView.page(), &loaderClient.base);
 
-    done = false;
     auto url = adoptWK(Util::createURLForResource("getUserMedia", "html"));
+    ASSERT(url.get());
     WKPageLoadURL(webView.page(), url.get());
+    Util::run(&didFinishLoad);
+
+    WKMediaState captureState = WKPageGetMediaState(webView.page());
+    EXPECT_FALSE(captureState & kWKMediaHasActiveVideoCaptureDevice);
+    EXPECT_FALSE(captureState & kWKMediaHasActiveAudioCaptureDevice);
+
+    WKPageRunJavaScriptInMainFrame(webView.page(), Util::toWK("requestAccess()").get(), 0, nullJavaScriptCallback);
+    Util::run(&wasPrompted);
+
+    captureState = WKPageGetMediaState(webView.page());
+    if (!(captureState & kWKMediaHasActiveVideoCaptureDevice)) {
+        Util::run(&isPlayingChanged);
+        captureState = WKPageGetMediaState(webView.page());
+    }
+
+    EXPECT_TRUE(captureState & kWKMediaHasActiveVideoCaptureDevice);
+    EXPECT_FALSE(captureState & kWKMediaHasActiveAudioCaptureDevice);
+
+    isPlayingChanged = false;
+    WKPageLoadURL(webView.page(), adoptWK(Util::createURLForResource("simple", "html")).get());
+    Util::run(&isPlayingChanged);
 
-    Util::run(&done);
+    captureState = WKPageGetMediaState(webView.page());
+    EXPECT_FALSE(captureState & kWKMediaHasActiveVideoCaptureDevice);
+    EXPECT_FALSE(captureState & kWKMediaHasActiveAudioCaptureDevice);
 }
 
 } // namespace TestWebKitAPI
index e54f853..adb3591 100644 (file)
@@ -1,14 +1,15 @@
-<script>
-function gotUserMedia(mediaStream)
-{
-    console.log("Got user media");
-}
-
-function userMediaError(error)
-{
-    console.log(error);
-}
-
-var options = { audio: false, video: true};
-navigator.webkitGetUserMedia(options, gotUserMedia, userMediaError);
-</script>
+<html>
+    <head>
+        <script>
+            function requestAccess()
+            {
+                var options = { audio: false, video: true };
+                navigator.mediaDevices.getUserMedia(options)
+                    .then(stream => { console.log("Got user media"); })
+                    .catch(error => { console.log(error); });
+            }
+        </script>
+    </head>
+    <body>
+    </body>
+</html>