Title: [245185] trunk
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)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to