Title: [248104] trunk
Revision
248104
Author
you...@apple.com
Date
2019-08-01 09:17:56 -0700 (Thu, 01 Aug 2019)

Log Message

UserMediaPermissionRequestManagerProxy should not use audio+video denied requests to deny audio-only or video-only requests
https://bugs.webkit.org/show_bug.cgi?id=200317

Reviewed by Eric Carlson.

Source/WebKit:

Only match audio+video denied requests with new audio+video requests.
That will ensure that audio can still be captured if user denied access to the camera through preferences
and website started with a getUserMedia({audio: true, video: true}) call.
Covered by added API test.

* UIProcess/UserMediaPermissionRequestManagerProxy.cpp:
(WebKit::UserMediaPermissionRequestManagerProxy::wasRequestDenied):

Tools:

* TestWebKitAPI/Tests/WebKit/getUserMediaAudioVideoCapture.html: Added
* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebKit/GetUserMediaReprompt.mm:
(-[GetUserMediaOnlyAudioUIDelegate _webView:requestMediaCaptureAuthorization:decisionHandler:]):
(-[GetUserMediaOnlyAudioUIDelegate _webView:checkUserMediaPermissionForURL:mainFrameURL:frameIdentifier:decisionHandler:]):
(TestWebKitAPI::TEST):

LayoutTests:

Update existing test with new behavior.
Added new test for the case where video is blocked but not audio.

* fast/mediastream/getUserMedia-deny-persistency3-expected.txt:
* fast/mediastream/getUserMedia-deny-persistency3.html:
* fast/mediastream/getUserMedia-deny-persistency4-expected.txt: Added.
* fast/mediastream/getUserMedia-deny-persistency4.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (248103 => 248104)


--- trunk/LayoutTests/ChangeLog	2019-08-01 15:14:16 UTC (rev 248103)
+++ trunk/LayoutTests/ChangeLog	2019-08-01 16:17:56 UTC (rev 248104)
@@ -1,3 +1,18 @@
+2019-08-01  Youenn Fablet  <you...@apple.com>
+
+        UserMediaPermissionRequestManagerProxy should not use audio+video denied requests to deny audio-only or video-only requests
+        https://bugs.webkit.org/show_bug.cgi?id=200317
+
+        Reviewed by Eric Carlson.
+
+        Update existing test with new behavior.
+        Added new test for the case where video is blocked but not audio.
+
+        * fast/mediastream/getUserMedia-deny-persistency3-expected.txt:
+        * fast/mediastream/getUserMedia-deny-persistency3.html:
+        * fast/mediastream/getUserMedia-deny-persistency4-expected.txt: Added.
+        * fast/mediastream/getUserMedia-deny-persistency4.html: Added.
+
 2019-08-01  Carlos Garcia Campos  <cgar...@igalia.com>
 
         [SOUP] WebSockets: add support for extensions when using web sockets libsoup API

Modified: trunk/LayoutTests/fast/mediastream/getUserMedia-deny-persistency3-expected.txt (248103 => 248104)


--- trunk/LayoutTests/fast/mediastream/getUserMedia-deny-persistency3-expected.txt	2019-08-01 15:14:16 UTC (rev 248103)
+++ trunk/LayoutTests/fast/mediastream/getUserMedia-deny-persistency3-expected.txt	2019-08-01 16:17:56 UTC (rev 248104)
@@ -1,3 +1,3 @@
 
-PASS Testing same page getUserMedia deny persistency with audio and video denied 
+PASS Testing same page getUserMedia deny persistency, the first denied request being audio and video, the second granted request being audio 
 

Modified: trunk/LayoutTests/fast/mediastream/getUserMedia-deny-persistency3.html (248103 => 248104)


--- trunk/LayoutTests/fast/mediastream/getUserMedia-deny-persistency3.html	2019-08-01 15:14:16 UTC (rev 248103)
+++ trunk/LayoutTests/fast/mediastream/getUserMedia-deny-persistency3.html	2019-08-01 16:17:56 UTC (rev 248104)
@@ -6,23 +6,23 @@
     </head>
     <body>
         <script>
-
-promise_test((test) => {
+promise_test(async (test) => {
     if (window.testRunner)
         testRunner.setUserMediaPermission(false);
-    return navigator.mediaDevices.getUserMedia({audio:true, video:true}).then(assert_unreached, (e) => {
+    await navigator.mediaDevices.getUserMedia({audio:true, video:true}).then(assert_unreached, (e) => {
         assert_equals(e.name, "NotAllowedError");
-        if (window.testRunner)
-            testRunner.setUserMediaPermission(true);
-        return navigator.mediaDevices.getUserMedia({audio:true, video:false}).then(assert_unreached, (e) => {
-            assert_equals(e.name, "NotAllowedError");
-        });
-    }).then(() => {
-        return navigator.mediaDevices.getUserMedia({audio:true, video:false}).then(assert_unreached, (e) => {
-            assert_equals(e.name, "NotAllowedError");
-        });
     });
-}, "Testing same page getUserMedia deny persistency with audio and video denied");
+    if (window.testRunner)
+        testRunner.setUserMediaPermission(true);
+    await navigator.mediaDevices.getUserMedia({audio:true});
+    if (window.testRunner)
+        testRunner.setUserMediaPermission(false);
+    await navigator.mediaDevices.getUserMedia({audio:true});
+
+    await navigator.mediaDevices.getUserMedia({video:true}).then(assert_unreached, (e) => {
+        assert_equals(e.name, "NotAllowedError");
+    });
+}, "Testing same page getUserMedia deny persistency, the first denied request being audio and video, the second granted request being audio");
         </script>
     </body>
 </html>

Added: trunk/LayoutTests/fast/mediastream/getUserMedia-deny-persistency4-expected.txt (0 => 248104)


--- trunk/LayoutTests/fast/mediastream/getUserMedia-deny-persistency4-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/mediastream/getUserMedia-deny-persistency4-expected.txt	2019-08-01 16:17:56 UTC (rev 248104)
@@ -0,0 +1,3 @@
+
+PASS Testing same page getUserMedia deny persistency, the first denied request being audio and video, the second granted request being video 
+

Added: trunk/LayoutTests/fast/mediastream/getUserMedia-deny-persistency4.html (0 => 248104)


--- trunk/LayoutTests/fast/mediastream/getUserMedia-deny-persistency4.html	                        (rev 0)
+++ trunk/LayoutTests/fast/mediastream/getUserMedia-deny-persistency4.html	2019-08-01 16:17:56 UTC (rev 248104)
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML>
+<html>
+    <head>
+        <script src=""
+        <script src=""
+    </head>
+    <body>
+        <script>
+promise_test(async (test) => {
+    if (window.testRunner)
+        testRunner.setUserMediaPermission(false);
+    await navigator.mediaDevices.getUserMedia({audio:true, video:true}).then(assert_unreached, (e) => {
+        assert_equals(e.name, "NotAllowedError");
+    });
+    if (window.testRunner)
+        testRunner.setUserMediaPermission(true);
+    await navigator.mediaDevices.getUserMedia({video:true});
+    if (window.testRunner)
+        testRunner.setUserMediaPermission(false);
+    await navigator.mediaDevices.getUserMedia({video:true});
+
+    await navigator.mediaDevices.getUserMedia({audio:true}).then(assert_unreached, (e) => {
+        assert_equals(e.name, "NotAllowedError");
+    });
+}, "Testing same page getUserMedia deny persistency, the first denied request being audio and video, the second granted request being video");
+        </script>
+    </body>
+</html>

Modified: trunk/Source/WebKit/ChangeLog (248103 => 248104)


--- trunk/Source/WebKit/ChangeLog	2019-08-01 15:14:16 UTC (rev 248103)
+++ trunk/Source/WebKit/ChangeLog	2019-08-01 16:17:56 UTC (rev 248104)
@@ -1,3 +1,18 @@
+2019-08-01  Youenn Fablet  <you...@apple.com>
+
+        UserMediaPermissionRequestManagerProxy should not use audio+video denied requests to deny audio-only or video-only requests
+        https://bugs.webkit.org/show_bug.cgi?id=200317
+
+        Reviewed by Eric Carlson.
+
+        Only match audio+video denied requests with new audio+video requests.
+        That will ensure that audio can still be captured if user denied access to the camera through preferences
+        and website started with a getUserMedia({audio: true, video: true}) call.
+        Covered by added API test.
+
+        * UIProcess/UserMediaPermissionRequestManagerProxy.cpp:
+        (WebKit::UserMediaPermissionRequestManagerProxy::wasRequestDenied):
+
 2019-08-01  Carlos Garcia Campos  <cgar...@igalia.com>
 
         [SOUP] WebSockets: add support for extensions when using web sockets libsoup API

Modified: trunk/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.cpp (248103 => 248104)


--- trunk/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.cpp	2019-08-01 15:14:16 UTC (rev 248103)
+++ trunk/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.cpp	2019-08-01 16:17:56 UTC (rev 248104)
@@ -291,12 +291,21 @@
             continue;
         if (deniedRequest.mainFrameID != mainFrameID)
             continue;
+
+        if (deniedRequest.isScreenCaptureDenied && needsScreenCapture)
+            return true;
+
+        // In case we asked for both audio and video, maybe the callback would have returned true for just audio or just video.
+        if (deniedRequest.isAudioDenied && deniedRequest.isVideoDenied) {
+            if (needsAudio && needsVideo)
+                return true;
+            continue;
+        }
+
         if (deniedRequest.isAudioDenied && needsAudio)
             return true;
         if (deniedRequest.isVideoDenied && needsVideo)
             return true;
-        if (deniedRequest.isScreenCaptureDenied && needsScreenCapture)
-            return true;
     }
     return false;
 }

Modified: trunk/Tools/ChangeLog (248103 => 248104)


--- trunk/Tools/ChangeLog	2019-08-01 15:14:16 UTC (rev 248103)
+++ trunk/Tools/ChangeLog	2019-08-01 16:17:56 UTC (rev 248104)
@@ -1,3 +1,17 @@
+2019-08-01  Youenn Fablet  <you...@apple.com>
+
+        UserMediaPermissionRequestManagerProxy should not use audio+video denied requests to deny audio-only or video-only requests
+        https://bugs.webkit.org/show_bug.cgi?id=200317
+
+        Reviewed by Eric Carlson.
+
+        * TestWebKitAPI/Tests/WebKit/getUserMediaAudioVideoCapture.html: Added
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebKit/GetUserMediaReprompt.mm:
+        (-[GetUserMediaOnlyAudioUIDelegate _webView:requestMediaCaptureAuthorization:decisionHandler:]):
+        (-[GetUserMediaOnlyAudioUIDelegate _webView:checkUserMediaPermissionForURL:mainFrameURL:frameIdentifier:decisionHandler:]):
+        (TestWebKitAPI::TEST):
+
 2019-08-01  Aakash Jain  <aakash_j...@apple.com>
 
         New EWS: Cannot see build status page when patch is waiting for tester

Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (248103 => 248104)


--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2019-08-01 15:14:16 UTC (rev 248103)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2019-08-01 16:17:56 UTC (rev 248104)
@@ -38,6 +38,7 @@
 		07492B3B1DF8B14C00633DE1 /* EnumerateMediaDevices.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07492B3A1DF8AE2D00633DE1 /* EnumerateMediaDevices.cpp */; };
 		07492B3C1DF8B86600633DE1 /* enumerateMediaDevices.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 07492B391DF8ADA400633DE1 /* enumerateMediaDevices.html */; };
 		074994421EA5034B000DA44E /* getUserMedia.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 4A410F4D19AF7BEF002EBAB5 /* getUserMedia.html */; };
+		074994421EA5034B000DA45E /* getUserMediaAudioVideoCapture.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 4A410F4D19AF7BEF002EBAC5 /* getUserMediaAudioVideoCapture.html */; };
 		074994421EA5034B000DA44F /* ondevicechange.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 4A410F4D19AF7BEF002EBAB6 /* ondevicechange.html */; };
 		076E507F1F4513D6006E9F5A /* Logging.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 076E507E1F45031E006E9F5A /* Logging.cpp */; };
 		0799C3491EBA2D7B003B7532 /* UserMediaDisabled.mm in Sources */ = {isa = PBXBuildFile; fileRef = 07EDEFAC1EB9400C00D43292 /* UserMediaDisabled.mm */; };
@@ -1205,6 +1206,7 @@
 				07E1F6A21FFC44FA0096C7EC /* getDisplayMedia.html in Copy Resources */,
 				467C565321B5ED130057516D /* GetSessionCookie.html in Copy Resources */,
 				074994421EA5034B000DA44E /* getUserMedia.html in Copy Resources */,
+				074994421EA5034B000DA45E /* getUserMediaAudioVideoCapture.html in Copy Resources */,
 				F46A095B1ED8A6E600D4AA55 /* gif-and-file-input.html in Copy Resources */,
 				573255A522139BC700396AE8 /* helloworld.webarchive in Copy Resources */,
 				9B4F8FA7159D52DD002D9F94 /* HTMLCollectionNamedItem.html in Copy Resources */,
@@ -1668,6 +1670,7 @@
 		46E816F71E79E29100375ADC /* RestoreStateAfterTermination.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RestoreStateAfterTermination.mm; sourceTree = "<group>"; };
 		4A410F4B19AF7BD6002EBAB5 /* UserMedia.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UserMedia.cpp; sourceTree = "<group>"; };
 		4A410F4D19AF7BEF002EBAB5 /* getUserMedia.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = getUserMedia.html; sourceTree = "<group>"; };
+		4A410F4D19AF7BEF002EBAC5 /* getUserMediaAudioVideoCapture.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = getUserMediaAudioVideoCapture.html; sourceTree = "<group>"; };
 		4A410F4D19AF7BEF002EBAB6 /* ondevicechange.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = ondevicechange.html; sourceTree = "<group>"; };
 		4BB4160116815B2600824238 /* JSWrapperForNodeInWebFrame.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = JSWrapperForNodeInWebFrame.mm; sourceTree = "<group>"; };
 		4BB4160316815F9100824238 /* ElementAtPointInWebFrame.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ElementAtPointInWebFrame.mm; sourceTree = "<group>"; };
@@ -3623,6 +3626,7 @@
 				26F52EB018288F0F0023D412 /* geolocationWatchPosition.html */,
 				26F52EB118288F0F0023D412 /* geolocationWatchPositionWithHighAccuracy.html */,
 				4A410F4D19AF7BEF002EBAB5 /* getUserMedia.html */,
+				4A410F4D19AF7BEF002EBAC5 /* getUserMediaAudioVideoCapture.html */,
 				BCBD372E125ABBE600D2C29F /* icon.png */,
 				CE3524F51B142BBB0028A7C5 /* input-focus-blur.html */,
 				C9B4AD2B1ECA6F7600F5FEA0 /* js-autoplay-audio.html */,

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKit/GetUserMediaReprompt.mm (248103 => 248104)


--- trunk/Tools/TestWebKitAPI/Tests/WebKit/GetUserMediaReprompt.mm	2019-08-01 15:14:16 UTC (rev 248103)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit/GetUserMediaReprompt.mm	2019-08-01 16:17:56 UTC (rev 248104)
@@ -58,6 +58,25 @@
 }
 @end
 
+@interface GetUserMediaOnlyAudioUIDelegate : NSObject<WKUIDelegate>
+- (void)_webView:(WKWebView *)webView requestMediaCaptureAuthorization: (_WKCaptureDevices)devices decisionHandler:(void (^)(BOOL))decisionHandler;
+- (void)_webView:(WKWebView *)webView checkUserMediaPermissionForURL:(NSURL *)url mainFrameURL:(NSURL *)mainFrameURL frameIdentifier:(NSUInteger)frameIdentifier decisionHandler:(void (^)(NSString *salt, BOOL authorized))decisionHandler;
+@end
+
+@implementation GetUserMediaOnlyAudioUIDelegate
+- (void)_webView:(WKWebView *)webView requestMediaCaptureAuthorization: (_WKCaptureDevices)devices decisionHandler:(void (^)(BOOL))decisionHandler
+{
+    numberOfPrompts++;
+    wasPrompted = true;
+    decisionHandler((devices == _WKCaptureDeviceMicrophone) ? YES : NO);
+}
+
+- (void)_webView:(WKWebView *)webView checkUserMediaPermissionForURL:(NSURL *)url mainFrameURL:(NSURL *)mainFrameURL frameIdentifier:(NSUInteger)frameIdentifier decisionHandler:(void (^)(NSString *salt, BOOL authorized))decisionHandler
+{
+    decisionHandler(@"0x987654321", YES);
+}
+@end
+
 @interface GetUserMediaRepromptTestView : TestWKWebView
 - (BOOL)haveStream:(BOOL)expected;
 @end
@@ -119,6 +138,29 @@
     EXPECT_TRUE([webView haveStream:YES]);
 }
 
+TEST(WebKit2, GetUserMediaRepromptAfterAudioVideoBeingDenied)
+{
+    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    auto processPoolConfig = adoptNS([[_WKProcessPoolConfiguration alloc] init]);
+    auto preferences = [configuration preferences];
+    preferences._mediaCaptureRequiresSecureConnection = NO;
+    preferences._mediaDevicesEnabled = YES;
+    preferences._mockCaptureDevicesEnabled = YES;
+    auto webView = [[GetUserMediaRepromptTestView alloc] initWithFrame:CGRectMake(0, 0, 320, 500) configuration:configuration.get() processPoolConfiguration:processPoolConfig.get()];
+    auto delegate = adoptNS([[GetUserMediaOnlyAudioUIDelegate alloc] init]);
+    webView.UIDelegate = delegate.get();
+
+    wasPrompted = false;
+    [webView loadTestPageNamed:@"getUserMediaAudioVideoCapture"];
+    TestWebKitAPI::Util::run(&wasPrompted);
+    EXPECT_TRUE([webView haveStream:NO]);
+
+    wasPrompted = false;
+    [webView stringByEvaluatingJavaScript:@"promptForAudioOnly()"];
+    TestWebKitAPI::Util::run(&wasPrompted);
+    EXPECT_TRUE([webView haveStream:YES]);
+}
+
 TEST(WebKit2, MultipleGetUserMediaSynchronously)
 {
     auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);

Added: trunk/Tools/TestWebKitAPI/Tests/WebKit/getUserMediaAudioVideoCapture.html (0 => 248104)


--- trunk/Tools/TestWebKitAPI/Tests/WebKit/getUserMediaAudioVideoCapture.html	                        (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit/getUserMediaAudioVideoCapture.html	2019-08-01 16:17:56 UTC (rev 248104)
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <script>
+            let stream = null;
+
+            function promptForAudioAndVideo()
+            {
+                navigator.mediaDevices.getUserMedia({ audio: true, video: true }).then((s) => {
+                    stream = s;
+                    console.log("Got user media");
+                }).catch((error) => console.log(`Failed with error: ${error}`));
+            }
+
+            function promptForAudioOnly()
+            {
+                navigator.mediaDevices.getUserMedia({ audio: true, video: false }).then((s) => {
+                    stream = s;
+                    console.log("Got user media");
+                }).catch((error) => console.log(`Failed with error: ${error}`));
+            }
+
+            function haveStream()
+            {
+                return stream !== null;
+            }
+        </script>
+    <head>
+
+    <body _onload_="promptForAudioAndVideo()">
+    </body>
+</html>
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to