Add support for toggling device orientation API support per site
authorcdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 4 Jan 2019 22:11:58 +0000 (22:11 +0000)
committercdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 4 Jan 2019 22:11:58 +0000 (22:11 +0000)
https://bugs.webkit.org/show_bug.cgi?id=193143
<rdar://problem/46605724>

Reviewed by Alex Christensen.

Source/WebCore:

Add support for toggling device orientation API support per site via _WKWebsitePolicies.

* dom/Document.cpp:
(WebCore::Document::simulateDeviceOrientationChange):
* dom/Document.h:
* loader/DocumentLoader.h:
(WebCore::DocumentLoader::deviceOrientationEventEnabled const):
(WebCore::DocumentLoader::setDeviceOrientationEventEnabled):
* page/DOMWindow.cpp:
(WebCore::DOMWindow::addEventListener):

Source/WebKit:

Add support for toggling device orientation API support per site via _WKWebsitePolicies.

* Shared/WebsitePoliciesData.cpp:
(WebKit::WebsitePoliciesData::encode const):
(WebKit::WebsitePoliciesData::decode):
(WebKit::WebsitePoliciesData::applyToDocumentLoader):
* Shared/WebsitePoliciesData.h:
* UIProcess/API/APIWebsitePolicies.cpp:
(API::WebsitePolicies::data):
* UIProcess/API/APIWebsitePolicies.h:
* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView _simulateDeviceOrientationChangeWithAlpha:beta:gamma:]):
* UIProcess/API/Cocoa/WKWebViewPrivate.h:
* UIProcess/API/Cocoa/_WKWebsitePolicies.h:
* UIProcess/API/Cocoa/_WKWebsitePolicies.mm:
(-[_WKWebsitePolicies setDeviceOrientationEventEnabled:]):
(-[_WKWebsitePolicies deviceOrientationEventEnabled]):
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::simulateDeviceOrientationChange):
* UIProcess/WebPageProxy.h:
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::simulateDeviceOrientationChange):
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in:

Tools:

Add API test coverage.

* TestWebKitAPI/Tests/WebKitCocoa/WebsitePolicies.mm:
(-[DataMappingSchemeHandler setTaskHandler:]):
(-[DataMappingSchemeHandler webView:startURLSchemeTask:]):
(-[WebsitePoliciesDeviceOrientationDelegate initWithDeviceOrientationEventEnabled:]):
(-[WebsitePoliciesDeviceOrientationDelegate _webView:decidePolicyForNavigationAction:userInfo:decisionHandler:]):
(-[WebsitePoliciesDeviceOrientationDelegate webView:didFinishNavigation:]):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@239639 268f45cc-cd09-0410-ab3c-d52691b4dbfc

21 files changed:
Source/WebCore/ChangeLog
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/Document.h
Source/WebCore/loader/DocumentLoader.h
Source/WebCore/page/DOMWindow.cpp
Source/WebKit/ChangeLog
Source/WebKit/Shared/WebsitePoliciesData.cpp
Source/WebKit/Shared/WebsitePoliciesData.h
Source/WebKit/UIProcess/API/APIWebsitePolicies.cpp
Source/WebKit/UIProcess/API/APIWebsitePolicies.h
Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm
Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h
Source/WebKit/UIProcess/API/Cocoa/_WKWebsitePolicies.h
Source/WebKit/UIProcess/API/Cocoa/_WKWebsitePolicies.mm
Source/WebKit/UIProcess/WebPageProxy.cpp
Source/WebKit/UIProcess/WebPageProxy.h
Source/WebKit/WebProcess/WebPage/WebPage.cpp
Source/WebKit/WebProcess/WebPage/WebPage.h
Source/WebKit/WebProcess/WebPage/WebPage.messages.in
Tools/ChangeLog
Tools/TestWebKitAPI/Tests/WebKitCocoa/WebsitePolicies.mm

index 8d9dfc6..56aa4f4 100644 (file)
@@ -1,3 +1,22 @@
+2019-01-04  Chris Dumez  <cdumez@apple.com>
+
+        Add support for toggling device orientation API support per site
+        https://bugs.webkit.org/show_bug.cgi?id=193143
+        <rdar://problem/46605724>
+
+        Reviewed by Alex Christensen.
+
+        Add support for toggling device orientation API support per site via _WKWebsitePolicies.
+
+        * dom/Document.cpp:
+        (WebCore::Document::simulateDeviceOrientationChange):
+        * dom/Document.h:
+        * loader/DocumentLoader.h:
+        (WebCore::DocumentLoader::deviceOrientationEventEnabled const):
+        (WebCore::DocumentLoader::setDeviceOrientationEventEnabled):
+        * page/DOMWindow.cpp:
+        (WebCore::DOMWindow::addEventListener):
+
 2019-01-04  Jer Noble  <jer.noble@apple.com>
 
         Web Content process main thread blocked beneath ImageDecoderAVFObjC::readSamples for many seconds on imgur.com
index ec66be7..78d0f44 100644 (file)
@@ -6230,6 +6230,12 @@ DeviceOrientationController* Document::deviceOrientationController() const
     return m_deviceOrientationController.get();
 }
 
+void Document::simulateDeviceOrientationChange(double alpha, double beta, double gamma)
+{
+    auto orientation = DeviceOrientationData::create(alpha, beta, gamma, WTF::nullopt, WTF::nullopt);
+    deviceOrientationController()->didChangeDeviceOrientation(orientation.ptr());
+}
+
 #endif
 
 #if ENABLE(FULLSCREEN_API)
index 8a0ffe1..6bedf75 100644 (file)
@@ -1229,6 +1229,7 @@ public:
 #if ENABLE(DEVICE_ORIENTATION) && PLATFORM(IOS_FAMILY)
     DeviceMotionController* deviceMotionController() const;
     DeviceOrientationController* deviceOrientationController() const;
+    WEBCORE_EXPORT void simulateDeviceOrientationChange(double alpha, double beta, double gamma);
 #endif
 
     const DocumentTiming& timing() const { return m_documentTiming; }
index bc3b196..f4c6377 100644 (file)
@@ -261,6 +261,9 @@ public:
     bool userContentExtensionsEnabled() const { return m_userContentExtensionsEnabled; }
     void setUserContentExtensionsEnabled(bool enabled) { m_userContentExtensionsEnabled = enabled; }
 
+    bool deviceOrientationEventEnabled() const { return m_deviceOrientationEventEnabled; }
+    void setDeviceOrientationEventEnabled(bool enabled) { m_deviceOrientationEventEnabled = enabled; }
+
     AutoplayPolicy autoplayPolicy() const { return m_autoplayPolicy; }
     void setAutoplayPolicy(AutoplayPolicy policy) { m_autoplayPolicy = policy; }
 
@@ -541,6 +544,7 @@ private:
     String m_customUserAgent;
     String m_customNavigatorPlatform;
     bool m_userContentExtensionsEnabled { true };
+    bool m_deviceOrientationEventEnabled { true };
     AutoplayPolicy m_autoplayPolicy { AutoplayPolicy::Default };
     OptionSet<AutoplayQuirk> m_allowedAutoplayQuirks;
     PopUpPolicy m_popUpPolicy { PopUpPolicy::Default };
index 19f8f52..1759def 100644 (file)
@@ -1839,9 +1839,9 @@ bool DOMWindow::addEventListener(const AtomicString& eventType, Ref<EventListene
 #endif
 
 #if ENABLE(DEVICE_ORIENTATION)
-    if (frame() && frame()->settings().deviceOrientationEventEnabled()) {
+    if (frame() && frame()->settings().deviceOrientationEventEnabled() && document() && document()->loader() && document()->loader()->deviceOrientationEventEnabled()) {
 #if PLATFORM(IOS_FAMILY)
-        if ((eventType == eventNames().devicemotionEvent || eventType == eventNames().deviceorientationEvent) && document()) {
+        if ((eventType == eventNames().devicemotionEvent || eventType == eventNames().deviceorientationEvent)) {
             if (isSameSecurityOriginAsMainFrame() && isSecureContext()) {
                 if (eventType == eventNames().deviceorientationEvent)
                     document()->deviceOrientationController()->addDeviceEventListener(this);
@@ -1859,13 +1859,13 @@ bool DOMWindow::addEventListener(const AtomicString& eventType, Ref<EventListene
             if (isSameSecurityOriginAsMainFrame() && isSecureContext()) {
                 if (DeviceMotionController* controller = DeviceMotionController::from(page()))
                     controller->addDeviceEventListener(this);
-            } else if (document())
+            } else
                 document()->addConsoleMessage(MessageSource::JS, MessageLevel::Warning, "Blocked attempt to add a device motion listener from child frame that wasn't the same security origin as the main page."_s);
         } else if (eventType == eventNames().deviceorientationEvent) {
             if (isSameSecurityOriginAsMainFrame() && isSecureContext()) {
                 if (DeviceOrientationController* controller = DeviceOrientationController::from(page()))
                     controller->addDeviceEventListener(this);
-            } else if (document()) {
+            } else {
                 if (isSecureContext())
                     document()->addConsoleMessage(MessageSource::JS, MessageLevel::Warning, "Blocked attempt to add a device orientation listener from child frame that wasn't the same security origin as the main page."_s);
                 else
index 0bcba59..ee26420 100644 (file)
@@ -1,5 +1,38 @@
 2019-01-04  Chris Dumez  <cdumez@apple.com>
 
+        Add support for toggling device orientation API support per site
+        https://bugs.webkit.org/show_bug.cgi?id=193143
+        <rdar://problem/46605724>
+
+        Reviewed by Alex Christensen.
+
+        Add support for toggling device orientation API support per site via _WKWebsitePolicies.
+
+        * Shared/WebsitePoliciesData.cpp:
+        (WebKit::WebsitePoliciesData::encode const):
+        (WebKit::WebsitePoliciesData::decode):
+        (WebKit::WebsitePoliciesData::applyToDocumentLoader):
+        * Shared/WebsitePoliciesData.h:
+        * UIProcess/API/APIWebsitePolicies.cpp:
+        (API::WebsitePolicies::data):
+        * UIProcess/API/APIWebsitePolicies.h:
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView _simulateDeviceOrientationChangeWithAlpha:beta:gamma:]):
+        * UIProcess/API/Cocoa/WKWebViewPrivate.h:
+        * UIProcess/API/Cocoa/_WKWebsitePolicies.h:
+        * UIProcess/API/Cocoa/_WKWebsitePolicies.mm:
+        (-[_WKWebsitePolicies setDeviceOrientationEventEnabled:]):
+        (-[_WKWebsitePolicies deviceOrientationEventEnabled]):
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::simulateDeviceOrientationChange):
+        * UIProcess/WebPageProxy.h:
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::simulateDeviceOrientationChange):
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/WebPage.messages.in:
+
+2019-01-04  Chris Dumez  <cdumez@apple.com>
+
         Crash under WebPageProxy::continueNavigationInNewProcess()
         https://bugs.webkit.org/show_bug.cgi?id=193113
         <rdar://problem/46938686>
index 414cb42..b734f0e 100644 (file)
@@ -37,6 +37,7 @@ namespace WebKit {
 void WebsitePoliciesData::encode(IPC::Encoder& encoder) const
 {
     encoder << contentBlockersEnabled;
+    encoder << deviceOrientationEventEnabled;
     encoder << autoplayPolicy;
     encoder << allowedAutoplayQuirks;
     encoder << customHeaderFields;
@@ -52,6 +53,11 @@ Optional<WebsitePoliciesData> WebsitePoliciesData::decode(IPC::Decoder& decoder)
     decoder >> contentBlockersEnabled;
     if (!contentBlockersEnabled)
         return WTF::nullopt;
+
+    Optional<bool> deviceOrientationEventEnabled;
+    decoder >> deviceOrientationEventEnabled;
+    if (!deviceOrientationEventEnabled)
+        return WTF::nullopt;
     
     Optional<WebsiteAutoplayPolicy> autoplayPolicy;
     decoder >> autoplayPolicy;
@@ -90,6 +96,7 @@ Optional<WebsitePoliciesData> WebsitePoliciesData::decode(IPC::Decoder& decoder)
     
     return { {
         WTFMove(*contentBlockersEnabled),
+        WTFMove(*deviceOrientationEventEnabled),
         WTFMove(*allowedAutoplayQuirks),
         WTFMove(*autoplayPolicy),
         WTFMove(*customHeaderFields),
@@ -105,6 +112,7 @@ void WebsitePoliciesData::applyToDocumentLoader(WebsitePoliciesData&& websitePol
     documentLoader.setCustomHeaderFields(WTFMove(websitePolicies.customHeaderFields));
     documentLoader.setCustomUserAgent(websitePolicies.customUserAgent);
     documentLoader.setCustomNavigatorPlatform(websitePolicies.customNavigatorPlatform);
+    documentLoader.setDeviceOrientationEventEnabled(websitePolicies.deviceOrientationEventEnabled);
     
     // Only setUserContentExtensionsEnabled if it hasn't already been disabled by reloading without content blockers.
     if (documentLoader.userContentExtensionsEnabled())
index a7ab13a..fcaed27 100644 (file)
@@ -47,6 +47,7 @@ struct WebsitePoliciesData {
     static void applyToDocumentLoader(WebsitePoliciesData&&, WebCore::DocumentLoader&);
 
     bool contentBlockersEnabled { true };
+    bool deviceOrientationEventEnabled { true };
     OptionSet<WebsiteAutoplayQuirk> allowedAutoplayQuirks;
     WebsiteAutoplayPolicy autoplayPolicy { WebsiteAutoplayPolicy::Default };
     Vector<WebCore::HTTPHeaderField> customHeaderFields;
index 65918a8..8447696 100644 (file)
@@ -56,7 +56,7 @@ WebKit::WebsitePoliciesData WebsitePolicies::data()
     Optional<WebKit::WebsiteDataStoreParameters> parameters;
     if (m_websiteDataStore)
         parameters = m_websiteDataStore->websiteDataStore().parameters();
-    return { contentBlockersEnabled(), allowedAutoplayQuirks(), autoplayPolicy(), customHeaderFields(), popUpPolicy(), WTFMove(parameters), m_customUserAgent, m_customNavigatorPlatform };
+    return { contentBlockersEnabled(), deviceOrientationEventEnabled(), allowedAutoplayQuirks(), autoplayPolicy(), customHeaderFields(), popUpPolicy(), WTFMove(parameters), m_customUserAgent, m_customNavigatorPlatform };
 }
 
 }
index 3f7aa06..718c755 100644 (file)
@@ -50,6 +50,9 @@ public:
 
     bool contentBlockersEnabled() const { return m_contentBlockersEnabled; }
     void setContentBlockersEnabled(bool enabled) { m_contentBlockersEnabled = enabled; }
+
+    bool deviceOrientationEventEnabled() const { return m_deviceOrientationEventEnabled; }
+    void setDeviceOrientationEventEnabled(bool enabled) { m_deviceOrientationEventEnabled = enabled; }
     
     OptionSet<WebKit::WebsiteAutoplayQuirk> allowedAutoplayQuirks() const { return m_allowedAutoplayQuirks; }
     void setAllowedAutoplayQuirks(OptionSet<WebKit::WebsiteAutoplayQuirk> quirks) { m_allowedAutoplayQuirks = quirks; }
@@ -79,6 +82,7 @@ private:
     WebsitePolicies(bool contentBlockersEnabled, OptionSet<WebKit::WebsiteAutoplayQuirk>, WebKit::WebsiteAutoplayPolicy, Vector<WebCore::HTTPHeaderField>&&, WebKit::WebsitePopUpPolicy, RefPtr<WebsiteDataStore>&&);
 
     bool m_contentBlockersEnabled { true };
+    bool m_deviceOrientationEventEnabled { true };
     OptionSet<WebKit::WebsiteAutoplayQuirk> m_allowedAutoplayQuirks;
     WebKit::WebsiteAutoplayPolicy m_autoplayPolicy { WebKit::WebsiteAutoplayPolicy::Default };
     Vector<WebCore::HTTPHeaderField> m_customHeaderFields;
index 3c5bebf..8443643 100644 (file)
@@ -4806,6 +4806,11 @@ FOR_EACH_PRIVATE_WKCONTENTVIEW_ACTION(FORWARD_ACTION_TO_WKCONTENTVIEW)
     return nil;
 }
 
+- (void)_simulateDeviceOrientationChangeWithAlpha:(double)alpha beta:(double)beta gamma:(double)gamma
+{
+    _page->simulateDeviceOrientationChange(alpha, beta, gamma);
+}
+
 + (BOOL)_handlesSafeBrowsing
 {
     return true;
index e709409..079a812 100644 (file)
@@ -190,6 +190,8 @@ typedef NS_OPTIONS(NSUInteger, _WKRectEdge) {
 - (_WKAttachment *)_insertAttachmentWithFileWrapper:(NSFileWrapper *)fileWrapper contentType:(NSString *)contentType completion:(void(^)(BOOL success))completionHandler WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
 - (_WKAttachment *)_attachmentForIdentifier:(NSString *)identifier WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
 
+- (void)_simulateDeviceOrientationChangeWithAlpha:(double)alpha beta:(double)beta gamma:(double)gamma WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
+
 + (BOOL)_handlesSafeBrowsing WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
 + (NSURL *)_confirmMalwareSentinel WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
 + (NSURL *)_visitUnsafeWebsiteSentinel WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
index 621a156..6a2d32f 100644 (file)
@@ -59,6 +59,7 @@ WK_CLASS_AVAILABLE(macosx(10.12.3), ios(10.3))
 @property (nonatomic, strong) WKWebsiteDataStore *websiteDataStore WK_API_AVAILABLE(macosx(10.13.4), ios(11.3));
 @property (nonatomic, copy) NSString *customUserAgent WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
 @property (nonatomic, copy) NSString *customNavigatorPlatform WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
+@property (nonatomic) BOOL deviceOrientationEventEnabled WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
 
 @end
 
index 7f3c822..46286cd 100644 (file)
     return _websitePolicies->contentBlockersEnabled();
 }
 
+- (void)setDeviceOrientationEventEnabled:(BOOL)deviceOrientationEventEnabled
+{
+    _websitePolicies->setDeviceOrientationEventEnabled(deviceOrientationEventEnabled);
+}
+
+- (BOOL)deviceOrientationEventEnabled
+{
+    return _websitePolicies->deviceOrientationEventEnabled();
+}
+
 - (void)setAllowedAutoplayQuirks:(_WKWebsiteAutoplayQuirk)allowedQuirks
 {
     OptionSet<WebKit::WebsiteAutoplayQuirk> quirks;
index a7be3fe..da78ab3 100644 (file)
@@ -8472,6 +8472,11 @@ void WebPageProxy::willAcquireUniversalFileReadSandboxExtension()
     process().willAcquireUniversalFileReadSandboxExtension();
 }
 
+void WebPageProxy::simulateDeviceOrientationChange(double alpha, double beta, double gamma)
+{
+    m_process->send(Messages::WebPage::SimulateDeviceOrientationChange(alpha, beta, gamma), m_pageID);
+}
+
 #if ENABLE(DATA_DETECTION)
 
 void WebPageProxy::detectDataInAllFrames(WebCore::DataDetectorTypes types, CompletionHandler<void(const DataDetectionResult&)>&& completionHandler)
index 9d621cf..c18095b 100644 (file)
@@ -487,6 +487,8 @@ public:
     void loadWebArchiveData(API::Data*, API::Object* userData = nullptr);
     void navigateToPDFLinkWithSimulatedClick(const String& url, WebCore::IntPoint documentPoint, WebCore::IntPoint screenPoint);
 
+    void simulateDeviceOrientationChange(double alpha, double beta, double gamma);
+
     void stopLoading();
     RefPtr<API::Navigation> reload(OptionSet<WebCore::ReloadOption>);
 
index a97901d..dba4447 100644 (file)
@@ -6385,6 +6385,17 @@ void WebPage::didCompleteShareSheet(bool wasGranted, ShareSheetCallbackID callba
     callback(wasGranted);
 }
 
+void WebPage::simulateDeviceOrientationChange(double alpha, double beta, double gamma)
+{
+#if ENABLE(DEVICE_ORIENTATION) && PLATFORM(IOS_FAMILY)
+    auto* frame = mainFrame();
+    if (!frame || !frame->document())
+        return;
+
+    frame->document()->simulateDeviceOrientationChange(alpha, beta, gamma);
+#endif
+}
+
 #if ENABLE(ATTACHMENT_ELEMENT)
 
 void WebPage::insertAttachment(const String& identifier, Optional<uint64_t>&& fileSize, const String& fileName, const String& contentType, CallbackID callbackID)
index 0b42a61..e3d15c3 100644 (file)
@@ -1459,6 +1459,8 @@ private:
     void didReceivePasswordForQuickLookDocument(const String&);
 #endif
 
+    void simulateDeviceOrientationChange(double alpha, double beta, double gamma);
+
     void frameBecameRemote(uint64_t frameID, WebCore::GlobalFrameIdentifier&& remoteFrameIdentifier, WebCore::GlobalWindowIdentifier&& remoteWindowIdentifier);
 
     void registerURLSchemeHandler(uint64_t identifier, const String& scheme);
index e2654d9..34be71c 100644 (file)
@@ -543,4 +543,5 @@ messages -> WebPage LegacyReceiver {
     SetDefersLoading(bool defersLoading)
 
     UpdateCurrentModifierState(OptionSet<WebCore::PlatformEvent::Modifier> modifiers)
+    SimulateDeviceOrientationChange(double alpha, double beta, double gamma)
 }
index 8b42f6e..b498214 100644 (file)
@@ -1,3 +1,20 @@
+2019-01-04  Chris Dumez  <cdumez@apple.com>
+
+        Add support for toggling device orientation API support per site
+        https://bugs.webkit.org/show_bug.cgi?id=193143
+        <rdar://problem/46605724>
+
+        Reviewed by Alex Christensen.
+
+        Add API test coverage.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/WebsitePolicies.mm:
+        (-[DataMappingSchemeHandler setTaskHandler:]):
+        (-[DataMappingSchemeHandler webView:startURLSchemeTask:]):
+        (-[WebsitePoliciesDeviceOrientationDelegate initWithDeviceOrientationEventEnabled:]):
+        (-[WebsitePoliciesDeviceOrientationDelegate _webView:decidePolicyForNavigationAction:userInfo:decisionHandler:]):
+        (-[WebsitePoliciesDeviceOrientationDelegate webView:didFinishNavigation:]):
+
 2019-01-04  Aakash Jain  <aakash_jain@apple.com>
 
         [ews-build] use svn-apply script to apply the patches
index f148b45..be0ed94 100644 (file)
@@ -38,6 +38,7 @@
 #import <WebKit/_WKUserContentExtensionStorePrivate.h>
 #import <WebKit/_WKWebsiteDataStoreConfiguration.h>
 #import <WebKit/_WKWebsitePolicies.h>
+#import <wtf/Function.h>
 #import <wtf/HashMap.h>
 #import <wtf/MainThread.h>
 #import <wtf/RetainPtr.h>
@@ -908,8 +909,10 @@ static unsigned loadCount;
 
 @interface DataMappingSchemeHandler : NSObject <WKURLSchemeHandler> {
     HashMap<String, RetainPtr<NSData *>> _dataMappings;
+    Function<void(id <WKURLSchemeTask>)> _taskHandler;
 }
 - (void)addMappingFromURLString:(NSString *)urlString toData:(const char*)data;
+- (void)setTaskHandler:(Function<void(id <WKURLSchemeTask>)>&&)handler;
 @end
 
 @implementation DataMappingSchemeHandler
@@ -919,12 +922,18 @@ static unsigned loadCount;
     _dataMappings.set(urlString, [NSData dataWithBytesNoCopy:(void*)data length:strlen(data) freeWhenDone:NO]);
 }
 
+- (void)setTaskHandler:(Function<void(id <WKURLSchemeTask>)>&&)handler
+{
+    _taskHandler = WTFMove(handler);
+}
+
 - (void)webView:(WKWebView *)webView startURLSchemeTask:(id <WKURLSchemeTask>)task
 {
     NSURL *finalURL = task.request.URL;
 
     ++loadCount;
-    EXPECT_STREQ("Foo Custom UserAgent", [[task.request valueForHTTPHeaderField:@"User-Agent"] UTF8String]);
+    if (_taskHandler)
+        _taskHandler(task);
 
     auto response = adoptNS([[NSURLResponse alloc] initWithURL:finalURL MIMEType:@"text/html" expectedContentLength:1 textEncodingName:nil]);
     [task didReceiveResponse:response.get()];
@@ -997,6 +1006,9 @@ TEST(WebKit, WebsitePoliciesCustomUserAgent)
     auto schemeHandler = adoptNS([[DataMappingSchemeHandler alloc] init]);
     [schemeHandler addMappingFromURLString:@"test://www.webkit.org/main.html" toData:customUserAgentMainFrameTestBytes];
     [schemeHandler addMappingFromURLString:@"test://www.apple.com/subframe.html" toData:customUserAgentSubFrameTestBytes];
+    [schemeHandler setTaskHandler:[](id <WKURLSchemeTask> task) {
+        EXPECT_STREQ("Foo Custom UserAgent", [[task.request valueForHTTPHeaderField:@"User-Agent"] UTF8String]);
+    }];
     [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"test"];
 
     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
@@ -1065,6 +1077,90 @@ TEST(WebKit, WebsitePoliciesCustomNavigatorPlatform)
     EXPECT_STREQ("Test Custom Platform", [[webView stringByEvaluatingJavaScript:@"navigator.platform"] UTF8String]);
 }
 
+#if PLATFORM(IOS_FAMILY)
+
+static const char* deviceOrientationEventTestBytes = R"TESTRESOURCE(
+<script>
+addEventListener("deviceorientation", (event) => {
+    webkit.messageHandlers.testHandler.postMessage("received-device-orientation-event");
+});
+</script>
+)TESTRESOURCE";
+
+@interface WebsitePoliciesDeviceOrientationDelegate : NSObject <WKNavigationDelegate> {
+    BOOL _deviceOrientationEventEnabled;
+}
+- (instancetype)initWithDeviceOrientationEventEnabled:(BOOL)enabled;
+@end
+
+@implementation WebsitePoliciesDeviceOrientationDelegate
+
+- (instancetype)initWithDeviceOrientationEventEnabled:(BOOL)enabled
+{
+    self = [super init];
+    _deviceOrientationEventEnabled = enabled;
+    return self;
+}
+
+- (void)_webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction userInfo:(id <NSSecureCoding>)userInfo decisionHandler:(void (^)(WKNavigationActionPolicy, _WKWebsitePolicies *))decisionHandler
+{
+    _WKWebsitePolicies *websitePolicies = [[[_WKWebsitePolicies alloc] init] autorelease];
+    [websitePolicies setDeviceOrientationEventEnabled:_deviceOrientationEventEnabled];
+
+    decisionHandler(WKNavigationActionPolicyAllow, websitePolicies);
+}
+
+- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
+{
+    finishedNavigation = true;
+}
+
+@end
+
+static void runWebsitePoliciesDeviceOrientationEventTest(bool websitePolicyValue)
+{
+    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+
+    auto schemeHandler = adoptNS([[DataMappingSchemeHandler alloc] init]);
+    [schemeHandler addMappingFromURLString:@"test://localhost/main.html" toData:deviceOrientationEventTestBytes];
+    [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:@"test"];
+
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
+
+    auto delegate = adoptNS([[WebsitePoliciesDeviceOrientationDelegate alloc] initWithDeviceOrientationEventEnabled:websitePolicyValue]);
+    [webView setNavigationDelegate:delegate.get()];
+
+    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"test://localhost/main.html"]];
+    [webView loadRequest:request];
+    TestWebKitAPI::Util::run(&finishedNavigation);
+    finishedNavigation = false;
+
+    __block bool didReceiveMessage = false;
+    [webView performAfterReceivingMessage:@"received-device-orientation-event" action:^{
+        didReceiveMessage = true;
+    }];
+
+    [webView _simulateDeviceOrientationChangeWithAlpha:1.0 beta:2.0 gamma:3.0];
+
+    if (websitePolicyValue)
+        TestWebKitAPI::Util::run(&didReceiveMessage);
+    else {
+        TestWebKitAPI::Util::sleep(0.1);
+        EXPECT_FALSE(didReceiveMessage);
+    }
+}
+
+TEST(WebKit, WebsitePoliciesDeviceOrientationEventEnabled)
+{
+    runWebsitePoliciesDeviceOrientationEventTest(true);
+}
+
+TEST(WebKit, WebsitePoliciesDeviceOrientationEventDisabled)
+{
+    runWebsitePoliciesDeviceOrientationEventTest(false);
+}
+
+#endif // PLATFORM(IOS_FAMILY)
 
 @interface PopUpPoliciesDelegate : NSObject <WKNavigationDelegate, WKUIDelegatePrivate>
 @property (nonatomic, copy) _WKWebsitePopUpPolicy(^popUpPolicyForURL)(NSURL *);