- Revision
- 245185
- Author
- [email protected]
- Date
- 2019-05-10 12:01:12 -0700 (Fri, 10 May 2019)
Log Message
Do not wait until requestPermission() is called to fire deviceorientation events if permission was already granted
https://bugs.webkit.org/show_bug.cgi?id=197750
Reviewed by Geoffrey Garen.
Source/WebKit:
The UIProcess remembers previous device orientation permission decisions per origin for the duration of the browsing
session. However, the WebContent process was not aware of previous decisions and would therefore not fire any
deviceorientation / devicemotion events until the JS has called requestPermission(). This patches addresses this
problem by having the UIProcess communicate any previous permission decision for the origin via WebSitePolicies.
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::receivedNavigationPolicyDecision):
* UIProcess/WebsiteData/WebDeviceOrientationAndMotionAccessController.cpp:
(WebKit::WebDeviceOrientationAndMotionAccessController::shouldAllowAccess):
(WebKit::WebDeviceOrientationAndMotionAccessController::cachedDeviceOrientationPermission const):
(WebKit::WebDeviceOrientationAndMotionAccessController::deviceOrientationPermission const): Deleted.
* UIProcess/WebsiteData/WebDeviceOrientationAndMotionAccessController.h:
Tools:
Add API test coverage.
* TestWebKitAPI/Tests/WebKitCocoa/DeviceOrientation.mm:
(TEST):
Modified Paths
Diff
Modified: trunk/Source/WebKit/ChangeLog (245184 => 245185)
--- trunk/Source/WebKit/ChangeLog 2019-05-10 18:56:08 UTC (rev 245184)
+++ trunk/Source/WebKit/ChangeLog 2019-05-10 19:01:12 UTC (rev 245185)
@@ -1,5 +1,25 @@
2019-05-10 Chris Dumez <[email protected]>
+ Do not wait until requestPermission() is called to fire deviceorientation events if permission was already granted
+ https://bugs.webkit.org/show_bug.cgi?id=197750
+
+ Reviewed by Geoffrey Garen.
+
+ The UIProcess remembers previous device orientation permission decisions per origin for the duration of the browsing
+ session. However, the WebContent process was not aware of previous decisions and would therefore not fire any
+ deviceorientation / devicemotion events until the JS has called requestPermission(). This patches addresses this
+ problem by having the UIProcess communicate any previous permission decision for the origin via WebSitePolicies.
+
+ * UIProcess/WebPageProxy.cpp:
+ (WebKit::WebPageProxy::receivedNavigationPolicyDecision):
+ * UIProcess/WebsiteData/WebDeviceOrientationAndMotionAccessController.cpp:
+ (WebKit::WebDeviceOrientationAndMotionAccessController::shouldAllowAccess):
+ (WebKit::WebDeviceOrientationAndMotionAccessController::cachedDeviceOrientationPermission const):
+ (WebKit::WebDeviceOrientationAndMotionAccessController::deviceOrientationPermission const): Deleted.
+ * UIProcess/WebsiteData/WebDeviceOrientationAndMotionAccessController.h:
+
+2019-05-10 Chris Dumez <[email protected]>
+
Add WKWebViewConfiguration._canShowWhileLocked SPI
https://bugs.webkit.org/show_bug.cgi?id=197777
<rdar://problem/50065100>
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (245184 => 245185)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2019-05-10 18:56:08 UTC (rev 245184)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2019-05-10 19:01:12 UTC (rev 245185)
@@ -2780,6 +2780,17 @@
data->contentBlockersEnabled = false;
}
+#if ENABLE(DEVICE_ORIENTATION)
+ if (navigation && (!data || data->deviceOrientationAndMotionAccessState == WebCore::DeviceOrientationOrMotionPermissionState::Prompt)) {
+ auto deviceOrientationPermission = websiteDataStore->deviceOrientationAndMotionAccessController().cachedDeviceOrientationPermission(SecurityOriginData::fromURL(navigation->currentRequest().url()));
+ if (deviceOrientationPermission != WebCore::DeviceOrientationOrMotionPermissionState::Prompt) {
+ if (!data)
+ data = "" { };
+ data->deviceOrientationAndMotionAccessState = deviceOrientationPermission;
+ }
+ }
+#endif
+
#if PLATFORM(COCOA)
static const bool forceDownloadFromDownloadAttribute = false;
#else
Modified: trunk/Source/WebKit/UIProcess/WebsiteData/WebDeviceOrientationAndMotionAccessController.cpp (245184 => 245185)
--- trunk/Source/WebKit/UIProcess/WebsiteData/WebDeviceOrientationAndMotionAccessController.cpp 2019-05-10 18:56:08 UTC (rev 245184)
+++ trunk/Source/WebKit/UIProcess/WebsiteData/WebDeviceOrientationAndMotionAccessController.cpp 2019-05-10 19:01:12 UTC (rev 245185)
@@ -37,7 +37,7 @@
void WebDeviceOrientationAndMotionAccessController::shouldAllowAccess(WebPageProxy& page, WebFrameProxy& frame, WebCore::SecurityOriginData&& originData, bool mayPrompt, CompletionHandler<void(DeviceOrientationOrMotionPermissionState)>&& completionHandler)
{
- auto currentPermission = deviceOrientationPermission(originData);
+ auto currentPermission = cachedDeviceOrientationPermission(originData);
if (currentPermission != DeviceOrientationOrMotionPermissionState::Prompt || !mayPrompt)
return completionHandler(currentPermission);
@@ -58,7 +58,7 @@
});
}
-DeviceOrientationOrMotionPermissionState WebDeviceOrientationAndMotionAccessController::deviceOrientationPermission(const SecurityOriginData& origin) const
+DeviceOrientationOrMotionPermissionState WebDeviceOrientationAndMotionAccessController::cachedDeviceOrientationPermission(const SecurityOriginData& origin) const
{
auto it = m_deviceOrientationPermissionDecisions.find(origin);
if (it == m_deviceOrientationPermissionDecisions.end())
Modified: trunk/Source/WebKit/UIProcess/WebsiteData/WebDeviceOrientationAndMotionAccessController.h (245184 => 245185)
--- trunk/Source/WebKit/UIProcess/WebsiteData/WebDeviceOrientationAndMotionAccessController.h 2019-05-10 18:56:08 UTC (rev 245184)
+++ trunk/Source/WebKit/UIProcess/WebsiteData/WebDeviceOrientationAndMotionAccessController.h 2019-05-10 19:01:12 UTC (rev 245185)
@@ -44,9 +44,9 @@
void shouldAllowAccess(WebPageProxy&, WebFrameProxy&, WebCore::SecurityOriginData&&, bool mayPrompt, CompletionHandler<void(WebCore::DeviceOrientationOrMotionPermissionState)>&&);
void clearPermissions();
+ WebCore::DeviceOrientationOrMotionPermissionState cachedDeviceOrientationPermission(const WebCore::SecurityOriginData&) const;
+
private:
- WebCore::DeviceOrientationOrMotionPermissionState deviceOrientationPermission(const WebCore::SecurityOriginData&) const;
-
HashMap<WebCore::SecurityOriginData, bool> m_deviceOrientationPermissionDecisions;
HashMap<WebCore::SecurityOriginData, Vector<CompletionHandler<void(WebCore::DeviceOrientationOrMotionPermissionState)>>> m_pendingRequests;
};
Modified: trunk/Tools/ChangeLog (245184 => 245185)
--- trunk/Tools/ChangeLog 2019-05-10 18:56:08 UTC (rev 245184)
+++ trunk/Tools/ChangeLog 2019-05-10 19:01:12 UTC (rev 245185)
@@ -1,3 +1,15 @@
+2019-05-10 Chris Dumez <[email protected]>
+
+ Do not wait until requestPermission() is called to fire deviceorientation events if permission was already granted
+ https://bugs.webkit.org/show_bug.cgi?id=197750
+
+ Reviewed by Geoffrey Garen.
+
+ Add API test coverage.
+
+ * TestWebKitAPI/Tests/WebKitCocoa/DeviceOrientation.mm:
+ (TEST):
+
2019-05-10 Keith Miller <[email protected]>
Remove legacy test262 import script
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/DeviceOrientation.mm (245184 => 245185)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/DeviceOrientation.mm 2019-05-10 18:56:08 UTC (rev 245184)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/DeviceOrientation.mm 2019-05-10 19:01:12 UTC (rev 245185)
@@ -250,4 +250,54 @@
askedClientForPermission = false;
}
+TEST(DeviceOrientation, FireOrientationEventsRightAwayIfPermissionAlreadyGranted)
+{
+ auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+ configuration.get().websiteDataStore = [WKWebsiteDataStore defaultDataStore];
+
+ auto messageHandler = adoptNS([[DeviceOrientationMessageHandler alloc] init]);
+ [[configuration userContentController] addScriptMessageHandler:messageHandler.get() name:@"testHandler"];
+
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
+ RetainPtr<DeviceOrientationPermissionUIDelegate> uiDelegate = adoptNS([[DeviceOrientationPermissionUIDelegate alloc] initWithHandler:[] { return true; }]);
+ [webView setUIDelegate:uiDelegate.get()];
+
+ NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"simple" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
+ [webView loadRequest:request];
+ [webView _test_waitForDidFinishNavigation];
+
+ // Request permission.
+ [webView evaluateJavaScript:@"DeviceOrientationEvent.requestPermission().then((granted) => { webkit.messageHandlers.testHandler.postMessage(granted) });" completionHandler: [&] (id result, NSError *error) { }];
+
+ TestWebKitAPI::Util::run(&didReceiveMessage);
+ didReceiveMessage = false;
+
+ EXPECT_TRUE(askedClientForPermission);
+ askedClientForPermission = false;
+ EXPECT_WK_STREQ(@"granted", receivedMessages.get()[0]);
+
+ // Go to the same origin again in a new view.
+ webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
+ [webView setUIDelegate:uiDelegate.get()];
+
+ [webView loadRequest:request];
+ [webView _test_waitForDidFinishNavigation];
+
+ // This time, we do not request permission but set our event listener.
+ bool addedEventListener = false;
+ [webView evaluateJavaScript:@"addEventListener('deviceorientation', (e) => { webkit.messageHandlers.testHandler.postMessage('received-event') });" completionHandler: [&] (id result, NSError *error) {
+ addedEventListener = true;
+ }];
+
+ TestWebKitAPI::Util::run(&addedEventListener);
+ addedEventListener = false;
+
+ // Simulate a device orientation event. The page's event listener should get called even though it did not request permission,
+ // because it was previously granted permission during this browsing session.
+ [webView _simulateDeviceOrientationChangeWithAlpha:1.0 beta:2.0 gamma:3.0];
+
+ TestWebKitAPI::Util::run(&didReceiveMessage);
+ EXPECT_WK_STREQ(@"received-event", receivedMessages.get()[1]);
+}
+
#endif // PLATFORM(IOS_FAMILY)