Changeset 245185 in webkit


Ignore:
Timestamp:
May 10, 2019 12:01:12 PM (5 years ago)
Author:
Chris Dumez
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):

Location:
trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r245183 r245185  
     12019-05-10  Chris Dumez  <cdumez@apple.com>
     2
     3        Do not wait until requestPermission() is called to fire deviceorientation events if permission was already granted
     4        https://bugs.webkit.org/show_bug.cgi?id=197750
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        The UIProcess remembers previous device orientation permission decisions per origin for the duration of the browsing
     9        session. However, the WebContent process was not aware of previous decisions and would therefore not fire any
     10        deviceorientation / devicemotion events until the JS has called requestPermission(). This patches addresses this
     11        problem by having the UIProcess communicate any previous permission decision for the origin via WebSitePolicies.
     12
     13        * UIProcess/WebPageProxy.cpp:
     14        (WebKit::WebPageProxy::receivedNavigationPolicyDecision):
     15        * UIProcess/WebsiteData/WebDeviceOrientationAndMotionAccessController.cpp:
     16        (WebKit::WebDeviceOrientationAndMotionAccessController::shouldAllowAccess):
     17        (WebKit::WebDeviceOrientationAndMotionAccessController::cachedDeviceOrientationPermission const):
     18        (WebKit::WebDeviceOrientationAndMotionAccessController::deviceOrientationPermission const): Deleted.
     19        * UIProcess/WebsiteData/WebDeviceOrientationAndMotionAccessController.h:
     20
    1212019-05-10  Chris Dumez  <cdumez@apple.com>
    222
  • trunk/Source/WebKit/UIProcess/WebPageProxy.cpp

    r245183 r245185  
    27812781    }
    27822782
     2783#if ENABLE(DEVICE_ORIENTATION)
     2784    if (navigation && (!data || data->deviceOrientationAndMotionAccessState == WebCore::DeviceOrientationOrMotionPermissionState::Prompt)) {
     2785        auto deviceOrientationPermission = websiteDataStore->deviceOrientationAndMotionAccessController().cachedDeviceOrientationPermission(SecurityOriginData::fromURL(navigation->currentRequest().url()));
     2786        if (deviceOrientationPermission != WebCore::DeviceOrientationOrMotionPermissionState::Prompt) {
     2787            if (!data)
     2788                data = WebsitePoliciesData { };
     2789            data->deviceOrientationAndMotionAccessState = deviceOrientationPermission;
     2790        }
     2791    }
     2792#endif
     2793
    27832794#if PLATFORM(COCOA)
    27842795    static const bool forceDownloadFromDownloadAttribute = false;
  • trunk/Source/WebKit/UIProcess/WebsiteData/WebDeviceOrientationAndMotionAccessController.cpp

    r244382 r245185  
    3838void WebDeviceOrientationAndMotionAccessController::shouldAllowAccess(WebPageProxy& page, WebFrameProxy& frame, WebCore::SecurityOriginData&& originData, bool mayPrompt, CompletionHandler<void(DeviceOrientationOrMotionPermissionState)>&& completionHandler)
    3939{
    40     auto currentPermission = deviceOrientationPermission(originData);
     40    auto currentPermission = cachedDeviceOrientationPermission(originData);
    4141    if (currentPermission != DeviceOrientationOrMotionPermissionState::Prompt || !mayPrompt)
    4242        return completionHandler(currentPermission);
     
    5959}
    6060
    61 DeviceOrientationOrMotionPermissionState WebDeviceOrientationAndMotionAccessController::deviceOrientationPermission(const SecurityOriginData& origin) const
     61DeviceOrientationOrMotionPermissionState WebDeviceOrientationAndMotionAccessController::cachedDeviceOrientationPermission(const SecurityOriginData& origin) const
    6262{
    6363    auto it = m_deviceOrientationPermissionDecisions.find(origin);
  • trunk/Source/WebKit/UIProcess/WebsiteData/WebDeviceOrientationAndMotionAccessController.h

    r244382 r245185  
    4545    void clearPermissions();
    4646
     47    WebCore::DeviceOrientationOrMotionPermissionState cachedDeviceOrientationPermission(const WebCore::SecurityOriginData&) const;
     48
    4749private:
    48     WebCore::DeviceOrientationOrMotionPermissionState deviceOrientationPermission(const WebCore::SecurityOriginData&) const;
    49 
    5050    HashMap<WebCore::SecurityOriginData, bool> m_deviceOrientationPermissionDecisions;
    5151    HashMap<WebCore::SecurityOriginData, Vector<CompletionHandler<void(WebCore::DeviceOrientationOrMotionPermissionState)>>> m_pendingRequests;
  • trunk/Tools/ChangeLog

    r245184 r245185  
     12019-05-10  Chris Dumez  <cdumez@apple.com>
     2
     3        Do not wait until requestPermission() is called to fire deviceorientation events if permission was already granted
     4        https://bugs.webkit.org/show_bug.cgi?id=197750
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        Add API test coverage.
     9
     10        * TestWebKitAPI/Tests/WebKitCocoa/DeviceOrientation.mm:
     11        (TEST):
     12
    1132019-05-10  Keith Miller  <keith_miller@apple.com>
    214
  • trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/DeviceOrientation.mm

    r244382 r245185  
    251251}
    252252
     253TEST(DeviceOrientation, FireOrientationEventsRightAwayIfPermissionAlreadyGranted)
     254{
     255    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
     256    configuration.get().websiteDataStore = [WKWebsiteDataStore defaultDataStore];
     257
     258    auto messageHandler = adoptNS([[DeviceOrientationMessageHandler alloc] init]);
     259    [[configuration userContentController] addScriptMessageHandler:messageHandler.get() name:@"testHandler"];
     260
     261    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
     262    RetainPtr<DeviceOrientationPermissionUIDelegate> uiDelegate = adoptNS([[DeviceOrientationPermissionUIDelegate alloc] initWithHandler:[] { return true; }]);
     263    [webView setUIDelegate:uiDelegate.get()];
     264
     265    NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"simple" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
     266    [webView loadRequest:request];
     267    [webView _test_waitForDidFinishNavigation];
     268
     269    // Request permission.
     270    [webView evaluateJavaScript:@"DeviceOrientationEvent.requestPermission().then((granted) => { webkit.messageHandlers.testHandler.postMessage(granted) });" completionHandler: [&] (id result, NSError *error) { }];
     271
     272    TestWebKitAPI::Util::run(&didReceiveMessage);
     273    didReceiveMessage = false;
     274
     275    EXPECT_TRUE(askedClientForPermission);
     276    askedClientForPermission = false;
     277    EXPECT_WK_STREQ(@"granted", receivedMessages.get()[0]);
     278
     279    // Go to the same origin again in a new view.
     280    webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
     281    [webView setUIDelegate:uiDelegate.get()];
     282
     283    [webView loadRequest:request];
     284    [webView _test_waitForDidFinishNavigation];
     285
     286    // This time, we do not request permission but set our event listener.
     287    bool addedEventListener = false;
     288    [webView evaluateJavaScript:@"addEventListener('deviceorientation', (e) => { webkit.messageHandlers.testHandler.postMessage('received-event') });" completionHandler: [&] (id result, NSError *error) {
     289        addedEventListener = true;
     290    }];
     291
     292    TestWebKitAPI::Util::run(&addedEventListener);
     293    addedEventListener = false;
     294
     295    // Simulate a device orientation event. The page's event listener should get called even though it did not request permission,
     296    // because it was previously granted permission during this browsing session.
     297    [webView _simulateDeviceOrientationChangeWithAlpha:1.0 beta:2.0 gamma:3.0];
     298
     299    TestWebKitAPI::Util::run(&didReceiveMessage);
     300    EXPECT_WK_STREQ(@"received-event", receivedMessages.get()[1]);
     301}
     302
    253303#endif // PLATFORM(IOS_FAMILY)
Note: See TracChangeset for help on using the changeset viewer.