- 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));
}