Title: [291284] trunk
Revision
291284
Author
[email protected]
Date
2022-03-15 06:21:05 -0700 (Tue, 15 Mar 2022)

Log Message

Mark permission as denied if system forbids access to camera and/or microphone
https://bugs.webkit.org/show_bug.cgi?id=237823

Reviewed by Eric Carlson.

Source/WebKit:

If application has not set the camera/microphone usage string, we do not need to call ther permission delegate.
Ditto if TCC prompt is denied. Instead, we can return deny if possible or prompt otherwise.
Covered by API test.

* UIProcess/UserMediaPermissionRequestManagerProxy.cpp:
* UIProcess/UserMediaPermissionRequestManagerProxy.h:
* UIProcess/WebPageProxy.cpp:

Tools:

* TestWebKitAPI/Tests/WebKit/GetUserMedia.mm:
* TestWebKitAPI/Tests/WebKit/getUserMediaPermission.html:

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (291283 => 291284)


--- trunk/Source/WebKit/ChangeLog	2022-03-15 12:40:14 UTC (rev 291283)
+++ trunk/Source/WebKit/ChangeLog	2022-03-15 13:21:05 UTC (rev 291284)
@@ -1,5 +1,20 @@
 2022-03-15  Youenn Fablet  <[email protected]>
 
+        Mark permission as denied if system forbids access to camera and/or microphone
+        https://bugs.webkit.org/show_bug.cgi?id=237823
+
+        Reviewed by Eric Carlson.
+
+        If application has not set the camera/microphone usage string, we do not need to call ther permission delegate.
+        Ditto if TCC prompt is denied. Instead, we can return deny if possible or prompt otherwise.
+        Covered by API test.
+
+        * UIProcess/UserMediaPermissionRequestManagerProxy.cpp:
+        * UIProcess/UserMediaPermissionRequestManagerProxy.h:
+        * UIProcess/WebPageProxy.cpp:
+
+2022-03-15  Youenn Fablet  <[email protected]>
+
         Rename VideoSampleMetadata to VideoFrameTimeMetadata
         https://bugs.webkit.org/show_bug.cgi?id=237593
 

Modified: trunk/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.cpp (291283 => 291284)


--- trunk/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.cpp	2022-03-15 12:40:14 UTC (rev 291283)
+++ trunk/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.cpp	2022-03-15 13:21:05 UTC (rev 291284)
@@ -883,6 +883,21 @@
     syncWithWebCorePrefs();
 }
 
+bool UserMediaPermissionRequestManagerProxy::mockCaptureDevicesEnabled() const
+{
+    return m_mockDevicesEnabledOverride ? *m_mockDevicesEnabledOverride : m_page.preferences().mockCaptureDevicesEnabled();
+}
+
+bool UserMediaPermissionRequestManagerProxy::canAudioCaptureSucceed() const
+{
+    return mockCaptureDevicesEnabled() || permittedToCaptureAudio();
+}
+
+bool UserMediaPermissionRequestManagerProxy::canVideoCaptureSucceed() const
+{
+    return mockCaptureDevicesEnabled() || permittedToCaptureVideo();
+}
+
 void UserMediaPermissionRequestManagerProxy::syncWithWebCorePrefs() const
 {
 #if ENABLE(MEDIA_STREAM)

Modified: trunk/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.h (291283 => 291284)


--- trunk/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.h	2022-03-15 12:40:14 UTC (rev 291283)
+++ trunk/Source/WebKit/UIProcess/UserMediaPermissionRequestManagerProxy.h	2022-03-15 13:21:05 UTC (rev 291284)
@@ -100,6 +100,8 @@
         Prompt
     };
 
+    bool canAudioCaptureSucceed() const;
+    bool canVideoCaptureSucceed() const;
     void setMockCaptureDevicesEnabledOverride(std::optional<bool>);
     bool hasPendingCapture() const { return m_hasPendingCapture; }
 
@@ -157,6 +159,8 @@
     void platformValidateUserMediaRequestConstraints(WebCore::RealtimeMediaSourceCenter::ValidConstraintsHandler&& validHandler, WebCore::RealtimeMediaSourceCenter::InvalidConstraintsHandler&& invalidHandler, String&& deviceIDHashSalt);
 #endif
 
+    bool mockCaptureDevicesEnabled() const;
+
     void watchdogTimerFired();
 
     void processNextUserMediaRequestIfNeeded();

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (291283 => 291284)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2022-03-15 12:40:14 UTC (rev 291283)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2022-03-15 13:21:05 UTC (rev 291284)
@@ -8587,6 +8587,7 @@
 
 void WebPageProxy::queryPermission(const ClientOrigin& clientOrigin, const PermissionDescriptor& descriptor, CompletionHandler<void(std::optional<PermissionState>, bool shouldCache)>&& completionHandler)
 {
+    bool canAPISucceed = true;
     bool shouldChangeDeniedToPrompt = true;
     bool shouldChangePromptToGrant = false;
     String name;
@@ -8593,6 +8594,7 @@
     if (descriptor.name == PermissionName::Camera) {
 #if ENABLE(MEDIA_STREAM)
         name = "camera"_s;
+        canAPISucceed = userMediaPermissionRequestManager().canVideoCaptureSucceed();
         shouldChangeDeniedToPrompt = userMediaPermissionRequestManager().shouldChangeDeniedToPromptForCamera(clientOrigin);
         shouldChangePromptToGrant = userMediaPermissionRequestManager().shouldChangePromptToGrantForCamera(clientOrigin);
 #endif
@@ -8599,6 +8601,7 @@
     } else if (descriptor.name == PermissionName::Microphone) {
 #if ENABLE(MEDIA_STREAM)
         name = "microphone"_s;
+        canAPISucceed = userMediaPermissionRequestManager().canAudioCaptureSucceed();
         shouldChangeDeniedToPrompt = userMediaPermissionRequestManager().shouldChangeDeniedToPromptForMicrophone(clientOrigin);
         shouldChangePromptToGrant = userMediaPermissionRequestManager().shouldChangePromptToGrantForMicrophone(clientOrigin);
 #endif
@@ -8613,6 +8616,11 @@
         return;
     }
 
+    if (!canAPISucceed) {
+        completionHandler(shouldChangeDeniedToPrompt ? PermissionState::Prompt : PermissionState::Denied, false);
+        return;
+    }
+
     auto origin = API::SecurityOrigin::create(clientOrigin.topOrigin);
     m_uiClient->queryPermission(name, origin, [clientOrigin, shouldChangeDeniedToPrompt, shouldChangePromptToGrant, completionHandler = WTFMove(completionHandler)](auto result) mutable {
         if (!result) {

Modified: trunk/Tools/ChangeLog (291283 => 291284)


--- trunk/Tools/ChangeLog	2022-03-15 12:40:14 UTC (rev 291283)
+++ trunk/Tools/ChangeLog	2022-03-15 13:21:05 UTC (rev 291284)
@@ -1,3 +1,13 @@
+2022-03-15  Youenn Fablet  <[email protected]>
+
+        Mark permission as denied if system forbids access to camera and/or microphone
+        https://bugs.webkit.org/show_bug.cgi?id=237823
+
+        Reviewed by Eric Carlson.
+
+        * TestWebKitAPI/Tests/WebKit/GetUserMedia.mm:
+        * TestWebKitAPI/Tests/WebKit/getUserMediaPermission.html:
+
 2022-03-14  Wenson Hsieh  <[email protected]>
 
         [Mail compose] Allow copied resources with remote (HTTP/HTTPS) URLs to be pasted as attachments

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKit/GetUserMedia.mm (291283 => 291284)


--- trunk/Tools/TestWebKitAPI/Tests/WebKit/GetUserMedia.mm	2022-03-15 12:40:14 UTC (rev 291283)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit/GetUserMedia.mm	2022-03-15 13:21:05 UTC (rev 291284)
@@ -1057,6 +1057,61 @@
     done = false;
 }
 
+#if PLATFORM(IOS_FAMILY)
+TEST(WebKit2, CapturePermissionWithSystemBlocking)
+{
+    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    configuration.get()._mediaCaptureEnabled = YES;
+
+    auto preferences = [configuration preferences];
+    preferences._mediaCaptureRequiresSecureConnection = NO;
+    preferences._mockCaptureDevicesEnabled = NO;
+    preferences._getUserMediaRequiresFocus = NO;
+    [preferences _setEnabled:YES forExperimentalFeature:permissionsAPIEnabledExperimentalFeature()];
+
+    auto messageHandler = adoptNS([[GUMMessageHandler alloc] init]);
+    [[configuration.get() userContentController] addScriptMessageHandler:messageHandler.get() name:@"gum"];
+
+    auto processPoolConfig = adoptNS([[_WKProcessPoolConfiguration alloc] init]);
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500) configuration:configuration.get() processPoolConfiguration:processPoolConfig.get()]);
+    auto delegate = adoptNS([[UserMediaCaptureUIDelegate alloc] init]);
+    [webView setUIDelegate:delegate.get()];
+
+    done = false;
+    [webView loadTestPageNamed:@"getUserMediaPermission"];
+    TestWebKitAPI::Util::run(&done);
+    done = false;
+
+    [delegate setAudioDecision:WKPermissionDecisionGrant];
+    [delegate setVideoDecision:WKPermissionDecisionGrant];
+
+    // Given mock capture is not enabled, system is forbidding access to camera and microphone.
+    // Permission API should not show granted even if our callback grants access.
+    [webView stringByEvaluatingJavaScript:@"checkPermission('microphone', 'prompt')"];
+    TestWebKitAPI::Util::run(&done);
+    done = false;
+
+    [webView stringByEvaluatingJavaScript:@"checkPermission('camera', 'prompt')"];
+    TestWebKitAPI::Util::run(&done);
+    done = false;
+
+    // Permission API should show denied now that getUserMedia was called.
+    [webView stringByEvaluatingJavaScript:@"callGetUserMedia(true, false)"];
+    TestWebKitAPI::Util::run(&done);
+    done = false;
+
+    [webView stringByEvaluatingJavaScript:@"checkPermission('microphone', 'denied')"];
+    TestWebKitAPI::Util::run(&done);
+    done = false;
+
+    [webView stringByEvaluatingJavaScript:@"checkPermission('camera', 'prompt')"];
+    TestWebKitAPI::Util::run(&done);
+    done = false;
+
+    // We cannot start camera on iOS simulator as there might not be any camera available.
+}
+#endif
+
 } // namespace TestWebKitAPI
 
 #endif // ENABLE(MEDIA_STREAM)

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKit/getUserMediaPermission.html (291283 => 291284)


--- trunk/Tools/TestWebKitAPI/Tests/WebKit/getUserMediaPermission.html	2022-03-15 12:40:14 UTC (rev 291283)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit/getUserMediaPermission.html	2022-03-15 13:21:05 UTC (rev 291284)
@@ -19,9 +19,18 @@
                 navigator.mediaDevices.getUserMedia({video: true}).then(s => stream = s);
             }
 
+            function callGetUserMedia(audio, video)
+            {
+                navigator.mediaDevices.getUserMedia({audio: audio, video:video}).then(() => {
+                    window.webkit.messageHandlers.gum.postMessage("PASS");
+                }, () => {
+                    window.webkit.messageHandlers.gum.postMessage("PASS");
+                });
+            }
+
             function checkPermission(name, expected) {
                 navigator.permissions.query({ name }).then((status) => {
-                    window.webkit.messageHandlers.gum.postMessage(expected == status.state  ? "PASS" : ("FAILED, expected " + expected + " but got " + status.state));
+                    window.webkit.messageHandlers.gum.postMessage(expected == status.state  ? "PASS" : ("FAILED for " + name + ", expected " + expected + " but got " + status.state));
                 }, error => window.webkit.messageHandlers.gum.postMessage("Permission query failed with " + error));
             }
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to