Add support for Device Orientation / Motion permission API
authorcdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 9 Mar 2019 00:30:45 +0000 (00:30 +0000)
committercdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 9 Mar 2019 00:30:45 +0000 (00:30 +0000)
https://bugs.webkit.org/show_bug.cgi?id=195329
<rdar://problem/47645367>

Reviewed by Geoffrey Garen.

Source/WebCore:

Add support for Device Orientation / Motion permission API:
- https://github.com/w3c/deviceorientation/issues/57

Pages can add event listeners for 'deviceorientation' / 'devicemotion' events but
such events will not be fired until the page's JavaScript calls
DeviceOrientationEvent.requestPermission() / DeviceMotionEvent.requestPermission()
and the user grants the request.

The feature is currently behind an experimental feature flag, off by default.

Tests: fast/device-orientation/device-motion-request-permission-denied.html
       fast/device-orientation/device-motion-request-permission-granted.html
       fast/device-orientation/device-motion-request-permission-user-gesture.html
       fast/device-orientation/device-orientation-request-permission-denied.html
       fast/device-orientation/device-orientation-request-permission-granted.html
       fast/device-orientation/device-orientation-request-permission-user-gesture.html

* CMakeLists.txt:
* DerivedSources-input.xcfilelist:
* DerivedSources-output.xcfilelist:
* DerivedSources.make:
* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* dom/DeviceMotionEvent.h:
* dom/DeviceMotionEvent.idl:
* dom/DeviceOrientationAndMotionAccessController.cpp: Added.
(WebCore::DeviceOrientationAndMotionAccessController::DeviceOrientationAndMotionAccessController):
(WebCore::DeviceOrientationAndMotionAccessController::shouldAllowAccess):
(WebCore::DeviceOrientationAndMotionAccessController::setAccessState):
* dom/DeviceOrientationAndMotionAccessController.h: Added.
(WebCore::DeviceOrientationAndMotionAccessController::accessState const):
* dom/DeviceOrientationEvent.h:
* dom/DeviceOrientationEvent.idl:
* dom/DeviceOrientationOrMotionEvent.cpp: Added.
(WebCore::DeviceOrientationOrMotionEvent::requestPermission):
* dom/DeviceOrientationOrMotionEvent.h: Added.
* dom/DeviceOrientationOrMotionEvent.idl: Added.
* dom/DeviceOrientationOrMotionPermissionState.h: Added.
* dom/DeviceOrientationOrMotionPermissionState.idl: Added.
* dom/Document.cpp:
(WebCore::Document::deviceOrientationAndMotionAccessController):
* dom/Document.h:
* dom/Event.cpp:
* dom/MessagePort.cpp:
* dom/Microtasks.cpp:
* page/ChromeClient.h:
* page/DOMWindow.cpp:
(WebCore::DOMWindow::addEventListener):
(WebCore::DOMWindow::deviceOrientationController const):
(WebCore::DOMWindow::deviceMotionController const):
(WebCore::DOMWindow::isAllowedToUseDeviceMotionOrientation const):
(WebCore::DOMWindow::isAllowedToAddDeviceMotionOrientationListener const):
(WebCore::DOMWindow::startListeningForDeviceOrientationIfNecessary):
(WebCore::DOMWindow::stopListeningForDeviceOrientationIfNecessary):
(WebCore::DOMWindow::startListeningForDeviceMotionIfNecessary):
(WebCore::DOMWindow::stopListeningForDeviceMotionIfNecessary):
(WebCore::DOMWindow::removeEventListener):
(WebCore::DOMWindow::removeAllEventListeners):
* page/DOMWindow.h:
* page/DeviceController.cpp:
(WebCore::DeviceController::hasDeviceEventListener const):
* page/DeviceController.h:
* page/Settings.yaml:

Source/WebKit:

Add support for Device Orientation / Motion permission API:
- https://github.com/w3c/deviceorientation/issues/57

This adds new SPI to WKUIDelegatePrivate, until we can make this API.

* Shared/WebPreferences.yaml:
* UIProcess/API/APIUIClient.h:
(API::UIClient::shouldAllowDeviceOrientationAndMotionAccess):
* UIProcess/API/C/WKPage.cpp:
(WKPageSetPageUIClient):
* UIProcess/API/C/WKPageUIClient.h:
* UIProcess/API/Cocoa/WKUIDelegate.h:
* UIProcess/API/Cocoa/WKUIDelegatePrivate.h:
* UIProcess/Cocoa/UIDelegate.h:
* UIProcess/Cocoa/UIDelegate.mm:
(WebKit::UIDelegate::setDelegate):
(WebKit::UIDelegate::UIClient::shouldAllowDeviceOrientationAndMotionAccess):
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::requestDeviceOrientationAndMotionAccess):
* UIProcess/WebPageProxy.h:
* UIProcess/WebPageProxy.messages.in:
* WebProcess/WebCoreSupport/WebChromeClient.cpp:
(WebKit::WebChromeClient::shouldAllowDeviceOrientationAndMotionAccess):
* WebProcess/WebCoreSupport/WebChromeClient.h:
* WebProcess/WebPage/WebPage.cpp:
(WebKit::nextDeviceOrientationAndMotionPermissionCallbackID):
(WebKit::WebPage::shouldAllowDeviceOrientationAndMotionAccess):
(WebKit::WebPage::didReceiveDeviceOrientationAndMotionAccessDecision):
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in:

Tools:

Add test infrastructure to help test the Device Orientation / Motion permission API.

* WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
* WebKitTestRunner/InjectedBundle/TestRunner.cpp:
(WTR::TestRunner::setShouldAllowDeviceOrientationAndMotionAccess):
* WebKitTestRunner/InjectedBundle/TestRunner.h:
* WebKitTestRunner/TestController.cpp:
(WTR::shouldAllowDeviceOrientationAndMotionAccess):
(WTR::TestController::createWebViewWithOptions):
(WTR::TestController::resetStateToConsistentValues):
(WTR::TestController::handleDeviceOrientationAndMotionAccessRequest):
* WebKitTestRunner/TestController.h:
(WTR::TestController::setShouldAllowDeviceOrientationAndMotionAccess):
* WebKitTestRunner/TestInvocation.cpp:
(WTR::TestInvocation::didReceiveMessageFromInjectedBundle):

LayoutTests:

Add layout test coverage.

* TestExpectations:
* fast/device-orientation/device-motion-request-permission-denied-expected.txt: Added.
* fast/device-orientation/device-motion-request-permission-denied.html: Added.
* fast/device-orientation/device-motion-request-permission-granted-expected.txt: Added.
* fast/device-orientation/device-motion-request-permission-granted.html: Added.
* fast/device-orientation/device-motion-request-permission-user-gesture-expected.txt: Added.
* fast/device-orientation/device-motion-request-permission-user-gesture.html: Added.
* fast/device-orientation/device-orientation-request-permission-denied-expected.txt: Added.
* fast/device-orientation/device-orientation-request-permission-denied.html: Added.
* fast/device-orientation/device-orientation-request-permission-granted-expected.txt: Added.
* fast/device-orientation/device-orientation-request-permission-granted.html: Added.
* fast/device-orientation/device-orientation-request-permission-user-gesture-expected.txt: Added.
* fast/device-orientation/device-orientation-request-permission-user-gesture.html: Added.
* http/tests/events/device-orientation-motion-non-secure-context.html:
* http/tests/events/device-orientation-motion-secure-context-expected.txt:
* http/tests/events/device-orientation-motion-secure-context.html:
* platform/ios-wk2/TestExpectations:
* platform/ios/http/tests/events/device-orientation-motion-non-secure-context-expected.txt:
* platform/ios/http/tests/events/device-orientation-motion-secure-context-expected.txt:

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

76 files changed:
LayoutTests/ChangeLog
LayoutTests/TestExpectations
LayoutTests/fast/device-orientation/device-motion-request-permission-denied-expected.txt [new file with mode: 0644]
LayoutTests/fast/device-orientation/device-motion-request-permission-denied.html [new file with mode: 0644]
LayoutTests/fast/device-orientation/device-motion-request-permission-granted-expected.txt [new file with mode: 0644]
LayoutTests/fast/device-orientation/device-motion-request-permission-granted.html [new file with mode: 0644]
LayoutTests/fast/device-orientation/device-motion-request-permission-user-gesture-expected.txt [new file with mode: 0644]
LayoutTests/fast/device-orientation/device-motion-request-permission-user-gesture.html [new file with mode: 0644]
LayoutTests/fast/device-orientation/device-orientation-request-permission-denied-expected.txt [new file with mode: 0644]
LayoutTests/fast/device-orientation/device-orientation-request-permission-denied.html [new file with mode: 0644]
LayoutTests/fast/device-orientation/device-orientation-request-permission-granted-expected.txt [new file with mode: 0644]
LayoutTests/fast/device-orientation/device-orientation-request-permission-granted.html [new file with mode: 0644]
LayoutTests/fast/device-orientation/device-orientation-request-permission-user-gesture-expected.txt [new file with mode: 0644]
LayoutTests/fast/device-orientation/device-orientation-request-permission-user-gesture.html [new file with mode: 0644]
LayoutTests/http/tests/events/device-orientation-motion-non-secure-context.html
LayoutTests/http/tests/events/device-orientation-motion-secure-context-expected.txt
LayoutTests/http/tests/events/device-orientation-motion-secure-context.html
LayoutTests/platform/ios-wk2/TestExpectations
LayoutTests/platform/ios/http/tests/events/device-orientation-motion-non-secure-context-expected.txt
LayoutTests/platform/ios/http/tests/events/device-orientation-motion-secure-context-expected.txt
Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/DerivedSources-input.xcfilelist
Source/WebCore/DerivedSources-output.xcfilelist
Source/WebCore/DerivedSources.make
Source/WebCore/Sources.txt
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/dom/DeviceMotionEvent.h
Source/WebCore/dom/DeviceMotionEvent.idl
Source/WebCore/dom/DeviceOrientationAndMotionAccessController.cpp [new file with mode: 0644]
Source/WebCore/dom/DeviceOrientationAndMotionAccessController.h [new file with mode: 0644]
Source/WebCore/dom/DeviceOrientationEvent.h
Source/WebCore/dom/DeviceOrientationEvent.idl
Source/WebCore/dom/DeviceOrientationOrMotionEvent.cpp [new file with mode: 0644]
Source/WebCore/dom/DeviceOrientationOrMotionEvent.h [new file with mode: 0644]
Source/WebCore/dom/DeviceOrientationOrMotionEvent.idl [new file with mode: 0644]
Source/WebCore/dom/DeviceOrientationOrMotionPermissionState.h [new file with mode: 0644]
Source/WebCore/dom/DeviceOrientationOrMotionPermissionState.idl [new file with mode: 0644]
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/Document.h
Source/WebCore/dom/Event.cpp
Source/WebCore/dom/MessagePort.cpp
Source/WebCore/dom/Microtasks.cpp
Source/WebCore/page/ChromeClient.h
Source/WebCore/page/DOMWindow.cpp
Source/WebCore/page/DOMWindow.h
Source/WebCore/page/DeviceController.cpp
Source/WebCore/page/DeviceController.h
Source/WebCore/page/Settings.yaml
Source/WebKit/ChangeLog
Source/WebKit/Shared/WebPreferences.yaml
Source/WebKit/Shared/WebPreferencesDefaultValues.cpp
Source/WebKit/Shared/WebPreferencesDefaultValues.h
Source/WebKit/UIProcess/API/APIUIClient.h
Source/WebKit/UIProcess/API/C/WKPage.cpp
Source/WebKit/UIProcess/API/C/WKPageUIClient.h
Source/WebKit/UIProcess/API/Cocoa/WKUIDelegate.h
Source/WebKit/UIProcess/API/Cocoa/WKUIDelegatePrivate.h
Source/WebKit/UIProcess/Cocoa/UIDelegate.h
Source/WebKit/UIProcess/Cocoa/UIDelegate.mm
Source/WebKit/UIProcess/Cocoa/VersionChecks.h
Source/WebKit/UIProcess/WebPageProxy.cpp
Source/WebKit/UIProcess/WebPageProxy.h
Source/WebKit/UIProcess/WebPageProxy.messages.in
Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp
Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h
Source/WebKit/WebProcess/WebPage/WebPage.cpp
Source/WebKit/WebProcess/WebPage/WebPage.h
Source/WebKit/WebProcess/WebPage/WebPage.messages.in
Tools/ChangeLog
Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl
Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp
Tools/WebKitTestRunner/InjectedBundle/TestRunner.h
Tools/WebKitTestRunner/TestController.cpp
Tools/WebKitTestRunner/TestController.h
Tools/WebKitTestRunner/TestInvocation.cpp

index 56235c4..a0b193b 100644 (file)
@@ -1,3 +1,33 @@
+2019-03-08  Chris Dumez  <cdumez@apple.com>
+
+        Add support for Device Orientation / Motion permission API
+        https://bugs.webkit.org/show_bug.cgi?id=195329
+        <rdar://problem/47645367>
+
+        Reviewed by Geoffrey Garen.
+
+        Add layout test coverage.
+
+        * TestExpectations:
+        * fast/device-orientation/device-motion-request-permission-denied-expected.txt: Added.
+        * fast/device-orientation/device-motion-request-permission-denied.html: Added.
+        * fast/device-orientation/device-motion-request-permission-granted-expected.txt: Added.
+        * fast/device-orientation/device-motion-request-permission-granted.html: Added.
+        * fast/device-orientation/device-motion-request-permission-user-gesture-expected.txt: Added.
+        * fast/device-orientation/device-motion-request-permission-user-gesture.html: Added.
+        * fast/device-orientation/device-orientation-request-permission-denied-expected.txt: Added.
+        * fast/device-orientation/device-orientation-request-permission-denied.html: Added.
+        * fast/device-orientation/device-orientation-request-permission-granted-expected.txt: Added.
+        * fast/device-orientation/device-orientation-request-permission-granted.html: Added.
+        * fast/device-orientation/device-orientation-request-permission-user-gesture-expected.txt: Added.
+        * fast/device-orientation/device-orientation-request-permission-user-gesture.html: Added.
+        * http/tests/events/device-orientation-motion-non-secure-context.html:
+        * http/tests/events/device-orientation-motion-secure-context-expected.txt:
+        * http/tests/events/device-orientation-motion-secure-context.html:
+        * platform/ios-wk2/TestExpectations:
+        * platform/ios/http/tests/events/device-orientation-motion-non-secure-context-expected.txt:
+        * platform/ios/http/tests/events/device-orientation-motion-secure-context-expected.txt:
+
 2019-03-08  Zalan Bujtas  <zalan@apple.com>
 
         [ContentChangeObserver] Expand "isConsideredClickable" to descendants
 2019-03-08  Zalan Bujtas  <zalan@apple.com>
 
         [ContentChangeObserver] Expand "isConsideredClickable" to descendants
index 6506afa..aea2920 100644 (file)
@@ -33,6 +33,7 @@ fast/zooming/ios [ Skip ]
 fast/forms/ios [ Skip ]
 fast/viewport/ios [ Skip ]
 fast/visual-viewport/ios/ [ Skip ]
 fast/forms/ios [ Skip ]
 fast/viewport/ios [ Skip ]
 fast/visual-viewport/ios/ [ Skip ]
+fast/device-orientation [ Skip ]
 fast/events/ios [ Skip ]
 fast/events/watchos [ Skip ]
 fast/events/pointer/ios [ Skip ]
 fast/events/ios [ Skip ]
 fast/events/watchos [ Skip ]
 fast/events/pointer/ios [ Skip ]
diff --git a/LayoutTests/fast/device-orientation/device-motion-request-permission-denied-expected.txt b/LayoutTests/fast/device-orientation/device-motion-request-permission-denied-expected.txt
new file mode 100644 (file)
index 0000000..c6d3e1c
--- /dev/null
@@ -0,0 +1,14 @@
+CONSOLE MESSAGE: line 12: No device motion or orientation events will be fired until permission has been requested and granted.
+Received device orientation & motion access request for security origin "".
+CONSOLE MESSAGE: line 19: No device motion or orientation events will be fired because permission to use the API was denied.
+Basic testing for DeviceMotionEvent.requestPermission().
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS result is "denied"
+PASS result is "denied"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/device-orientation/device-motion-request-permission-denied.html b/LayoutTests/fast/device-orientation/device-motion-request-permission-denied.html
new file mode 100644 (file)
index 0000000..30cd0a2
--- /dev/null
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src="../../resources/js-test.js"></script>
+<script>
+description("Basic testing for DeviceMotionEvent.requestPermission().");
+jsTestIsAsync = true;
+
+if (window.testRunner)
+    testRunner.setShouldAllowDeviceOrientationAndMotionAccess(false);
+
+addEventListener("devicemotion", () => {});
+
+internals.withUserGesture(() => {
+    DeviceMotionEvent.requestPermission().then((_result) => {
+        result = _result;
+        shouldBeEqualToString("result", "denied");
+
+        addEventListener("devicemotion", () => {});
+
+        internals.withUserGesture(() => {
+            DeviceMotionEvent.requestPermission().then((_result) => {
+                result = _result;
+                shouldBeEqualToString("result", "denied");
+                finishJSTest();
+            });
+        });
+    });
+});
+</script>
+</body>
+</html>
diff --git a/LayoutTests/fast/device-orientation/device-motion-request-permission-granted-expected.txt b/LayoutTests/fast/device-orientation/device-motion-request-permission-granted-expected.txt
new file mode 100644 (file)
index 0000000..1e320a0
--- /dev/null
@@ -0,0 +1,13 @@
+CONSOLE MESSAGE: line 12: No device motion or orientation events will be fired until permission has been requested and granted.
+Received device orientation & motion access request for security origin "".
+Basic testing for DeviceMotionEvent.requestPermission().
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS result is "granted"
+PASS result is "granted"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/device-orientation/device-motion-request-permission-granted.html b/LayoutTests/fast/device-orientation/device-motion-request-permission-granted.html
new file mode 100644 (file)
index 0000000..cdc11e9
--- /dev/null
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src="../../resources/js-test.js"></script>
+<script>
+description("Basic testing for DeviceMotionEvent.requestPermission().");
+jsTestIsAsync = true;
+
+if (window.testRunner)
+    testRunner.setShouldAllowDeviceOrientationAndMotionAccess(true);
+
+addEventListener("devicemotion", () => {});
+
+internals.withUserGesture(() => {
+    DeviceMotionEvent.requestPermission().then((_result) => {
+        result = _result;
+        shouldBeEqualToString("result", "granted");
+
+        addEventListener("devicemotion", () => {});
+
+        internals.withUserGesture(() => {
+            DeviceMotionEvent.requestPermission().then((_result) => {
+                result = _result;
+                shouldBeEqualToString("result", "granted");
+                finishJSTest();
+            });
+        });
+    });
+});
+</script>
+</body>
+</html>
diff --git a/LayoutTests/fast/device-orientation/device-motion-request-permission-user-gesture-expected.txt b/LayoutTests/fast/device-orientation/device-motion-request-permission-user-gesture-expected.txt
new file mode 100644 (file)
index 0000000..90cf576
--- /dev/null
@@ -0,0 +1,11 @@
+CONSOLE MESSAGE: line 14: NotAllowedError: Calling requestPermission() requires a user gesture
+Tests that DeviceMotionEvent.requestPermission() requires a user gesture.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS e.name is "NotAllowedError"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/device-orientation/device-motion-request-permission-user-gesture.html b/LayoutTests/fast/device-orientation/device-motion-request-permission-user-gesture.html
new file mode 100644 (file)
index 0000000..3d471c5
--- /dev/null
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src="../../resources/js-test.js"></script>
+<script>
+description("Tests that DeviceMotionEvent.requestPermission() requires a user gesture.");
+jsTestIsAsync = true;
+
+
+DeviceMotionEvent.requestPermission().then((result) => {
+    testFailed("requestPermission promise was not rejected");
+}, (_e) => {
+    e = _e;
+    console.log(e);
+    shouldBeEqualToString("e.name", "NotAllowedError");
+    finishJSTest();
+});
+</script>
+</body>
+</html>
diff --git a/LayoutTests/fast/device-orientation/device-orientation-request-permission-denied-expected.txt b/LayoutTests/fast/device-orientation/device-orientation-request-permission-denied-expected.txt
new file mode 100644 (file)
index 0000000..e6ddd6f
--- /dev/null
@@ -0,0 +1,14 @@
+CONSOLE MESSAGE: line 12: No device motion or orientation events will be fired until permission has been requested and granted.
+Received device orientation & motion access request for security origin "".
+CONSOLE MESSAGE: line 19: No device motion or orientation events will be fired because permission to use the API was denied.
+Basic testing for DeviceOrientationEvent.requestPermission().
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS result is "denied"
+PASS result is "denied"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/device-orientation/device-orientation-request-permission-denied.html b/LayoutTests/fast/device-orientation/device-orientation-request-permission-denied.html
new file mode 100644 (file)
index 0000000..938d73c
--- /dev/null
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src="../../resources/js-test.js"></script>
+<script>
+description("Basic testing for DeviceOrientationEvent.requestPermission().");
+jsTestIsAsync = true;
+
+if (window.testRunner)
+    testRunner.setShouldAllowDeviceOrientationAndMotionAccess(false);
+
+addEventListener("deviceorientation", () => {});
+
+internals.withUserGesture(() => {
+    DeviceOrientationEvent.requestPermission().then((_result) => {
+        result = _result;
+        shouldBeEqualToString("result", "denied");
+
+        addEventListener("deviceorientation", () => {});
+
+        internals.withUserGesture(() => {
+            DeviceOrientationEvent.requestPermission().then((_result) => {
+                result = _result;
+                shouldBeEqualToString("result", "denied");
+                finishJSTest();
+            });
+        });
+    });
+});
+</script>
+</body>
+</html>
diff --git a/LayoutTests/fast/device-orientation/device-orientation-request-permission-granted-expected.txt b/LayoutTests/fast/device-orientation/device-orientation-request-permission-granted-expected.txt
new file mode 100644 (file)
index 0000000..012ee1a
--- /dev/null
@@ -0,0 +1,13 @@
+CONSOLE MESSAGE: line 12: No device motion or orientation events will be fired until permission has been requested and granted.
+Received device orientation & motion access request for security origin "".
+Basic testing for DeviceOrientationEvent.requestPermission().
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS result is "granted"
+PASS result is "granted"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/device-orientation/device-orientation-request-permission-granted.html b/LayoutTests/fast/device-orientation/device-orientation-request-permission-granted.html
new file mode 100644 (file)
index 0000000..c41badb
--- /dev/null
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src="../../resources/js-test.js"></script>
+<script>
+description("Basic testing for DeviceOrientationEvent.requestPermission().");
+jsTestIsAsync = true;
+
+if (window.testRunner)
+    testRunner.setShouldAllowDeviceOrientationAndMotionAccess(true);
+
+addEventListener("deviceorientation", () => {});
+
+internals.withUserGesture(() => {
+    DeviceOrientationEvent.requestPermission().then((_result) => {
+        result = _result;
+        shouldBeEqualToString("result", "granted");
+
+        addEventListener("deviceorientation", () => {});
+
+        internals.withUserGesture(() => {
+            DeviceOrientationEvent.requestPermission().then((_result) => {
+                result = _result;
+                shouldBeEqualToString("result", "granted");
+                finishJSTest();
+            });
+        });
+    });
+});
+</script>
+</body>
+</html>
diff --git a/LayoutTests/fast/device-orientation/device-orientation-request-permission-user-gesture-expected.txt b/LayoutTests/fast/device-orientation/device-orientation-request-permission-user-gesture-expected.txt
new file mode 100644 (file)
index 0000000..bab426a
--- /dev/null
@@ -0,0 +1,11 @@
+CONSOLE MESSAGE: line 14: NotAllowedError: Calling requestPermission() requires a user gesture
+Tests that DeviceOrientationEvent.requestPermission() requires a user gesture.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS e.name is "NotAllowedError"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/device-orientation/device-orientation-request-permission-user-gesture.html b/LayoutTests/fast/device-orientation/device-orientation-request-permission-user-gesture.html
new file mode 100644 (file)
index 0000000..926992a
--- /dev/null
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src="../../resources/js-test.js"></script>
+<script>
+description("Tests that DeviceOrientationEvent.requestPermission() requires a user gesture.");
+jsTestIsAsync = true;
+
+
+DeviceOrientationEvent.requestPermission().then((result) => {
+    testFailed("requestPermission promise was not rejected");
+}, (_e) => {
+    e = _e;
+    console.log(e);
+    shouldBeEqualToString("e.name", "NotAllowedError");
+    finishJSTest();
+});
+</script>
+</body>
+</html>
index ed2dd20..38f2d42 100644 (file)
@@ -27,7 +27,7 @@ function runDeviceMotionTest()
     debug("* Registering device motion listener");
     addEventListener("devicemotion", function() { });
     internals.postTask(() => {
     debug("* Registering device motion listener");
     addEventListener("devicemotion", function() { });
     internals.postTask(() => {
-        shouldBeEqualToString("lastConsoleMessage", "Blocked attempt to add a device motion or orientation listener because the browsing context is not secure.");
+        shouldBeEqualToString("lastConsoleMessage", "Blocked attempt to add a device motion or orientation event listener, reason: Browsing context is not secure.");
         finishJSTest();
     });
 }
         finishJSTest();
     });
 }
@@ -44,7 +44,7 @@ function runDeviceOrientationTest()
     debug("* Registering device orientation listener");
     addEventListener("deviceorientation", function() { });
     internals.postTask(() => {
     debug("* Registering device orientation listener");
     addEventListener("deviceorientation", function() { });
     internals.postTask(() => {
-        shouldBeEqualToString("lastConsoleMessage", "Blocked attempt to add a device motion or orientation listener because the browsing context is not secure.");
+        shouldBeEqualToString("lastConsoleMessage", "Blocked attempt to add a device motion or orientation event listener, reason: Browsing context is not secure.");
         runDeviceMotionTest();
     });
 }
         runDeviceMotionTest();
     });
 }
index 0fb7d7e..0fad0a8 100644 (file)
@@ -1,10 +1,11 @@
-CONSOLE MESSAGE: line 37: Device Orientation API is not supported
-CONSOLE MESSAGE: line 19: Device Motion API is not supported
+CONSOLE MESSAGE: line 50: Device Orientation API is not supported
+CONSOLE MESSAGE: line 25: Device Motion API is not supported
 Tests that trying to set an event listener for deviceorientation and deviceorientation does not log an error in secure contexts.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
 Tests that trying to set an event listener for deviceorientation and deviceorientation does not log an error in secure contexts.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
+
 PASS successfullyParsed is true
 
 TEST COMPLETE
 PASS successfullyParsed is true
 
 TEST COMPLETE
index 4e54d11..f11ac2f 100644 (file)
@@ -6,6 +6,11 @@
 description("Tests that trying to set an event listener for deviceorientation and deviceorientation does not log an error in secure contexts.");
 jsTestIsAsync = true;
 
 description("Tests that trying to set an event listener for deviceorientation and deviceorientation does not log an error in secure contexts.");
 jsTestIsAsync = true;
 
+if (window.testRunner) {
+    if (testRunner.setShouldAllowDeviceOrientationAndMotionAccess)
+        testRunner.setShouldAllowDeviceOrientationAndMotionAccess(true);
+}
+
 // localhost is secure by default.
 
 let lastConsoleMessage = null;
 // localhost is secure by default.
 
 let lastConsoleMessage = null;
@@ -15,19 +20,27 @@ internals.setConsoleMessageListener((message) => {
 
 function runDeviceMotionTest()
 {
 
 function runDeviceMotionTest()
 {
+    debug("");
     if (!window.DeviceMotionEvent) {
         console.log("Device Motion API is not supported");
         finishJSTest();
         return;
     }
 
     if (!window.DeviceMotionEvent) {
         console.log("Device Motion API is not supported");
         finishJSTest();
         return;
     }
 
-    lastConsoleMessage = null;
-    debug("");
-    debug("* Registering device motion listener");
-    addEventListener("devicemotion", function() { });
-    internals.postTask(() => {
-        shouldBeNull("lastConsoleMessage");
-        finishJSTest();
+    debug("* Requesting device motion access...");
+    internals.withUserGesture(() => {
+        DeviceMotionEvent.requestPermission().then((_result) => {
+            result = _result;
+            shouldBeEqualToString("result", "granted");
+
+            lastConsoleMessage = null;
+            debug("* Registering device motion listener");
+            addEventListener("devicemotion", function() { });
+            internals.postTask(() => {
+                shouldBeNull("lastConsoleMessage");
+                finishJSTest();
+            });
+        });
     });
 }
 
     });
 }
 
@@ -39,12 +52,20 @@ function runDeviceOrientationTest()
         return;
     }
 
         return;
     }
 
-    lastConsoleMessage = null;
-    debug("* Registering device orientation listener");
-    addEventListener("deviceorientation", function() { });
-    internals.postTask(() => {
-        shouldBeNull("lastConsoleMessage");
-        runDeviceMotionTest();
+    debug("* Requesting device orientation access...");
+    internals.withUserGesture(() => {
+        DeviceOrientationEvent.requestPermission().then((_result) => {
+            result = _result;
+            shouldBeEqualToString("result", "granted");
+
+            lastConsoleMessage = null;
+            debug("* Registering device orientation listener");
+            addEventListener("deviceorientation", function() { });
+            internals.postTask(() => {
+                shouldBeNull("lastConsoleMessage");
+                runDeviceMotionTest();
+            });
+        });
     });
 }
 
     });
 }
 
index 69c8384..0b8e84d 100644 (file)
@@ -7,6 +7,7 @@
 #//////////////////////////////////////////////////////////////////////////////////////////
 
 compositing/ios [ Pass ]
 #//////////////////////////////////////////////////////////////////////////////////////////
 
 compositing/ios [ Pass ]
+fast/device-orientation [ Pass ]
 fast/history/ios [ Pass ]
 fast/scrolling/ios [ Pass ]
 fast/viewport/ios [ Pass ]
 fast/history/ios [ Pass ]
 fast/scrolling/ios [ Pass ]
 fast/viewport/ios [ Pass ]
index 86779af..7827abc 100644 (file)
@@ -1,15 +1,15 @@
-CONSOLE MESSAGE: line 45: Blocked attempt to add a device motion or orientation listener because the browsing context is not secure.
-CONSOLE MESSAGE: line 28: Blocked attempt to add a device motion or orientation listener because the browsing context is not secure.
+CONSOLE MESSAGE: line 45: Blocked attempt to add a device motion or orientation event listener, reason: Browsing context is not secure.
+CONSOLE MESSAGE: line 28: Blocked attempt to add a device motion or orientation event listener, reason: Browsing context is not secure.
 Tests that trying to set an event listener for deviceorientation and deviceorientation logs an error in non-secure contexts.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
 * Registering device orientation listener
 Tests that trying to set an event listener for deviceorientation and deviceorientation logs an error in non-secure contexts.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
 * Registering device orientation listener
-PASS lastConsoleMessage is "Blocked attempt to add a device motion or orientation listener because the browsing context is not secure."
+PASS lastConsoleMessage is "Blocked attempt to add a device motion or orientation event listener, reason: Browsing context is not secure."
 
 * Registering device motion listener
 
 * Registering device motion listener
-PASS lastConsoleMessage is "Blocked attempt to add a device motion or orientation listener because the browsing context is not secure."
+PASS lastConsoleMessage is "Blocked attempt to add a device motion or orientation event listener, reason: Browsing context is not secure."
 PASS successfullyParsed is true
 
 TEST COMPLETE
 PASS successfullyParsed is true
 
 TEST COMPLETE
index 31b85f5..44fc18f 100644 (file)
@@ -1,11 +1,16 @@
+Received device orientation & motion access request for security origin "http://127.0.0.1:8000".
 Tests that trying to set an event listener for deviceorientation and deviceorientation does not log an error in secure contexts.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
 Tests that trying to set an event listener for deviceorientation and deviceorientation does not log an error in secure contexts.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
+* Requesting device orientation access...
+PASS result is "granted"
 * Registering device orientation listener
 PASS lastConsoleMessage is null
 
 * Registering device orientation listener
 PASS lastConsoleMessage is null
 
+* Requesting device motion access...
+PASS result is "granted"
 * Registering device motion listener
 PASS lastConsoleMessage is null
 PASS successfullyParsed is true
 * Registering device motion listener
 PASS lastConsoleMessage is null
 PASS successfullyParsed is true
index 6aab575..c03cabd 100644 (file)
@@ -671,6 +671,8 @@ set(WebCore_NON_SVG_IDL_FILES
     dom/DataTransferItemList.idl
     dom/DeviceMotionEvent.idl
     dom/DeviceOrientationEvent.idl
     dom/DataTransferItemList.idl
     dom/DeviceMotionEvent.idl
     dom/DeviceOrientationEvent.idl
+    dom/DeviceOrientationOrMotionEvent.idl
+    dom/DeviceOrientationOrMotionPermissionState.idl
     dom/Document.idl
     dom/DocumentAndElementEventHandlers.idl
     dom/DocumentFragment.idl
     dom/Document.idl
     dom/DocumentAndElementEventHandlers.idl
     dom/DocumentFragment.idl
index 5a530fa..4b37824 100644 (file)
@@ -1,3 +1,75 @@
+2019-03-08  Chris Dumez  <cdumez@apple.com>
+
+        Add support for Device Orientation / Motion permission API
+        https://bugs.webkit.org/show_bug.cgi?id=195329
+        <rdar://problem/47645367>
+
+        Reviewed by Geoffrey Garen.
+
+        Add support for Device Orientation / Motion permission API:
+        - https://github.com/w3c/deviceorientation/issues/57
+
+        Pages can add event listeners for 'deviceorientation' / 'devicemotion' events but
+        such events will not be fired until the page's JavaScript calls
+        DeviceOrientationEvent.requestPermission() / DeviceMotionEvent.requestPermission()
+        and the user grants the request.
+
+        The feature is currently behind an experimental feature flag, off by default.
+
+        Tests: fast/device-orientation/device-motion-request-permission-denied.html
+               fast/device-orientation/device-motion-request-permission-granted.html
+               fast/device-orientation/device-motion-request-permission-user-gesture.html
+               fast/device-orientation/device-orientation-request-permission-denied.html
+               fast/device-orientation/device-orientation-request-permission-granted.html
+               fast/device-orientation/device-orientation-request-permission-user-gesture.html
+
+        * CMakeLists.txt:
+        * DerivedSources-input.xcfilelist:
+        * DerivedSources-output.xcfilelist:
+        * DerivedSources.make:
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * dom/DeviceMotionEvent.h:
+        * dom/DeviceMotionEvent.idl:
+        * dom/DeviceOrientationAndMotionAccessController.cpp: Added.
+        (WebCore::DeviceOrientationAndMotionAccessController::DeviceOrientationAndMotionAccessController):
+        (WebCore::DeviceOrientationAndMotionAccessController::shouldAllowAccess):
+        (WebCore::DeviceOrientationAndMotionAccessController::setAccessState):
+        * dom/DeviceOrientationAndMotionAccessController.h: Added.
+        (WebCore::DeviceOrientationAndMotionAccessController::accessState const):
+        * dom/DeviceOrientationEvent.h:
+        * dom/DeviceOrientationEvent.idl:
+        * dom/DeviceOrientationOrMotionEvent.cpp: Added.
+        (WebCore::DeviceOrientationOrMotionEvent::requestPermission):
+        * dom/DeviceOrientationOrMotionEvent.h: Added.
+        * dom/DeviceOrientationOrMotionEvent.idl: Added.
+        * dom/DeviceOrientationOrMotionPermissionState.h: Added.
+        * dom/DeviceOrientationOrMotionPermissionState.idl: Added.
+        * dom/Document.cpp:
+        (WebCore::Document::deviceOrientationAndMotionAccessController):
+        * dom/Document.h:
+        * dom/Event.cpp:
+        * dom/MessagePort.cpp:
+        * dom/Microtasks.cpp:
+        * page/ChromeClient.h:
+        * page/DOMWindow.cpp:
+        (WebCore::DOMWindow::addEventListener):
+        (WebCore::DOMWindow::deviceOrientationController const):
+        (WebCore::DOMWindow::deviceMotionController const):
+        (WebCore::DOMWindow::isAllowedToUseDeviceMotionOrientation const):
+        (WebCore::DOMWindow::isAllowedToAddDeviceMotionOrientationListener const):
+        (WebCore::DOMWindow::startListeningForDeviceOrientationIfNecessary):
+        (WebCore::DOMWindow::stopListeningForDeviceOrientationIfNecessary):
+        (WebCore::DOMWindow::startListeningForDeviceMotionIfNecessary):
+        (WebCore::DOMWindow::stopListeningForDeviceMotionIfNecessary):
+        (WebCore::DOMWindow::removeEventListener):
+        (WebCore::DOMWindow::removeAllEventListeners):
+        * page/DOMWindow.h:
+        * page/DeviceController.cpp:
+        (WebCore::DeviceController::hasDeviceEventListener const):
+        * page/DeviceController.h:
+        * page/Settings.yaml:
+
 2019-03-08  Zalan Bujtas  <zalan@apple.com>
 
         [ContentChangeObserver] Expand "isConsideredClickable" to descendants
 2019-03-08  Zalan Bujtas  <zalan@apple.com>
 
         [ContentChangeObserver] Expand "isConsideredClickable" to descendants
index 27b72b7..eac9ec9 100644 (file)
@@ -564,6 +564,8 @@ $(PROJECT_DIR)/dom/DataTransferItem.idl
 $(PROJECT_DIR)/dom/DataTransferItemList.idl
 $(PROJECT_DIR)/dom/DeviceMotionEvent.idl
 $(PROJECT_DIR)/dom/DeviceOrientationEvent.idl
 $(PROJECT_DIR)/dom/DataTransferItemList.idl
 $(PROJECT_DIR)/dom/DeviceMotionEvent.idl
 $(PROJECT_DIR)/dom/DeviceOrientationEvent.idl
+$(PROJECT_DIR)/dom/DeviceOrientationOrMotionEvent.idl
+$(PROJECT_DIR)/dom/DeviceOrientationOrMotionPermissionState.idl
 $(PROJECT_DIR)/dom/Document.idl
 $(PROJECT_DIR)/dom/DocumentAndElementEventHandlers.idl
 $(PROJECT_DIR)/dom/DocumentFragment.idl
 $(PROJECT_DIR)/dom/Document.idl
 $(PROJECT_DIR)/dom/DocumentAndElementEventHandlers.idl
 $(PROJECT_DIR)/dom/DocumentFragment.idl
index ac2b638..f8d29b6 100644 (file)
@@ -459,6 +459,10 @@ $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSDeviceMotionEvent.cpp
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSDeviceMotionEvent.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSDeviceOrientationEvent.cpp
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSDeviceOrientationEvent.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSDeviceMotionEvent.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSDeviceOrientationEvent.cpp
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSDeviceOrientationEvent.h
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSDeviceOrientationOrMotionEvent.cpp
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSDeviceOrientationOrMotionEvent.h
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSDeviceOrientationOrMotionPermissionState.cpp
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSDeviceOrientationOrMotionPermissionState.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSDocument.cpp
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSDocument.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSDocumentAndElementEventHandlers.cpp
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSDocument.cpp
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSDocument.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSDocumentAndElementEventHandlers.cpp
index e4b825d..2afe350 100644 (file)
@@ -571,6 +571,8 @@ JS_BINDING_IDLS = \
     $(WebCore)/dom/DataTransferItemList.idl \
     $(WebCore)/dom/DeviceMotionEvent.idl \
     $(WebCore)/dom/DeviceOrientationEvent.idl \
     $(WebCore)/dom/DataTransferItemList.idl \
     $(WebCore)/dom/DeviceMotionEvent.idl \
     $(WebCore)/dom/DeviceOrientationEvent.idl \
+    $(WebCore)/dom/DeviceOrientationOrMotionEvent.idl \
+    $(WebCore)/dom/DeviceOrientationOrMotionPermissionState.idl \
     $(WebCore)/dom/Document.idl \
     $(WebCore)/dom/DocumentAndElementEventHandlers.idl \
     $(WebCore)/dom/DocumentFragment.idl \
     $(WebCore)/dom/Document.idl \
     $(WebCore)/dom/DocumentAndElementEventHandlers.idl \
     $(WebCore)/dom/DocumentFragment.idl \
index 6711fe3..d2fcdf2 100644 (file)
@@ -820,9 +820,11 @@ dom/DecodedDataDocumentParser.cpp
 dom/DeviceMotionController.cpp
 dom/DeviceMotionData.cpp
 dom/DeviceMotionEvent.cpp
 dom/DeviceMotionController.cpp
 dom/DeviceMotionData.cpp
 dom/DeviceMotionEvent.cpp
+dom/DeviceOrientationAndMotionAccessController.cpp
 dom/DeviceOrientationController.cpp
 dom/DeviceOrientationData.cpp
 dom/DeviceOrientationEvent.cpp
 dom/DeviceOrientationController.cpp
 dom/DeviceOrientationData.cpp
 dom/DeviceOrientationEvent.cpp
+dom/DeviceOrientationOrMotionEvent.cpp
 dom/Document.cpp
 dom/DocumentEventQueue.cpp
 dom/DocumentFragment.cpp
 dom/Document.cpp
 dom/DocumentEventQueue.cpp
 dom/DocumentFragment.cpp
@@ -2723,6 +2725,8 @@ JSDeprecatedCSSOMValue.cpp
 JSDeprecatedCSSOMValueList.cpp
 JSDeviceMotionEvent.cpp
 JSDeviceOrientationEvent.cpp
 JSDeprecatedCSSOMValueList.cpp
 JSDeviceMotionEvent.cpp
 JSDeviceOrientationEvent.cpp
+JSDeviceOrientationOrMotionPermissionState.cpp
+JSDeviceOrientationOrMotionEvent.cpp
 JSDocument.cpp
 JSDocumentAndElementEventHandlers.cpp
 JSDocumentFragment.cpp
 JSDocument.cpp
 JSDocumentAndElementEventHandlers.cpp
 JSDocumentFragment.cpp
index 48422a7..8d7d739 100644 (file)
                45FEA5D0156DDE8C00654101 /* Decimal.h in Headers */ = {isa = PBXBuildFile; fileRef = 45FEA5CE156DDE8C00654101 /* Decimal.h */; settings = {ATTRIBUTES = (Private, ); }; };
                460BB6161D0A1BF000221812 /* Base64Utilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 460BB6141D0A1BEC00221812 /* Base64Utilities.h */; settings = {ATTRIBUTES = (Private, ); }; };
                460CBF361D4BCD0E0092E88E /* JSDOMWindowProperties.h in Headers */ = {isa = PBXBuildFile; fileRef = 460CBF341D4BCCFE0092E88E /* JSDOMWindowProperties.h */; };
                45FEA5D0156DDE8C00654101 /* Decimal.h in Headers */ = {isa = PBXBuildFile; fileRef = 45FEA5CE156DDE8C00654101 /* Decimal.h */; settings = {ATTRIBUTES = (Private, ); }; };
                460BB6161D0A1BF000221812 /* Base64Utilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 460BB6141D0A1BEC00221812 /* Base64Utilities.h */; settings = {ATTRIBUTES = (Private, ); }; };
                460CBF361D4BCD0E0092E88E /* JSDOMWindowProperties.h in Headers */ = {isa = PBXBuildFile; fileRef = 460CBF341D4BCCFE0092E88E /* JSDOMWindowProperties.h */; };
+               460E3075222F4EFD009A0606 /* DeviceOrientationOrMotionEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 461DA52A222F486F00D05A87 /* DeviceOrientationOrMotionEvent.h */; };
+               460E3077222F4F03009A0606 /* DeviceOrientationOrMotionPermissionState.h in Headers */ = {isa = PBXBuildFile; fileRef = 465EDD9F222F4EC300B46E16 /* DeviceOrientationOrMotionPermissionState.h */; };
                46218ACB1F72D64E00574FBE /* DOMHighResTimeStamp.h in Headers */ = {isa = PBXBuildFile; fileRef = 46E016AD1F72D61E00282B2C /* DOMHighResTimeStamp.h */; settings = {ATTRIBUTES = (Private, ); }; };
                463521AD2081092A00C28922 /* WindowProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 463521AA2081090B00C28922 /* WindowProxy.h */; settings = {ATTRIBUTES = (Private, ); }; };
                463EB6231B8789E00096ED51 /* TagCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = 463EB6211B8789CB0096ED51 /* TagCollection.h */; };
                46218ACB1F72D64E00574FBE /* DOMHighResTimeStamp.h in Headers */ = {isa = PBXBuildFile; fileRef = 46E016AD1F72D61E00282B2C /* DOMHighResTimeStamp.h */; settings = {ATTRIBUTES = (Private, ); }; };
                463521AD2081092A00C28922 /* WindowProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 463521AA2081090B00C28922 /* WindowProxy.h */; settings = {ATTRIBUTES = (Private, ); }; };
                463EB6231B8789E00096ED51 /* TagCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = 463EB6211B8789CB0096ED51 /* TagCollection.h */; };
                46B95198207D634700A7D2DD /* GlobalFrameIdentifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 46B95191207D632D00A7D2DD /* GlobalFrameIdentifier.h */; settings = {ATTRIBUTES = (Private, ); }; };
                46B95199207D634D00A7D2DD /* RemoteDOMWindow.h in Headers */ = {isa = PBXBuildFile; fileRef = 46B9518E207D632A00A7D2DD /* RemoteDOMWindow.h */; settings = {ATTRIBUTES = (Private, ); }; };
                46B9519A207D635400A7D2DD /* RemoteFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 46B95192207D632E00A7D2DD /* RemoteFrame.h */; settings = {ATTRIBUTES = (Private, ); }; };
                46B95198207D634700A7D2DD /* GlobalFrameIdentifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 46B95191207D632D00A7D2DD /* GlobalFrameIdentifier.h */; settings = {ATTRIBUTES = (Private, ); }; };
                46B95199207D634D00A7D2DD /* RemoteDOMWindow.h in Headers */ = {isa = PBXBuildFile; fileRef = 46B9518E207D632A00A7D2DD /* RemoteDOMWindow.h */; settings = {ATTRIBUTES = (Private, ); }; };
                46B9519A207D635400A7D2DD /* RemoteFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 46B95192207D632E00A7D2DD /* RemoteFrame.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               46B95BF52231CFD60053A504 /* DeviceOrientationAndMotionAccessController.h in Headers */ = {isa = PBXBuildFile; fileRef = 46B95BF42231CFB80053A504 /* DeviceOrientationAndMotionAccessController.h */; };
                46BCBBC22085008F00710638 /* JSRemoteDOMWindowBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 46BCBBC02085007F00710638 /* JSRemoteDOMWindowBase.h */; settings = {ATTRIBUTES = (Private, ); }; };
                46C376622085177D00C73829 /* JSRemoteDOMWindow.h in Headers */ = {isa = PBXBuildFile; fileRef = 46C376612085176D00C73829 /* JSRemoteDOMWindow.h */; };
                46C696CB1E7205F700597937 /* CPUMonitor.h in Headers */ = {isa = PBXBuildFile; fileRef = 46C696C91E7205E400597937 /* CPUMonitor.h */; settings = {ATTRIBUTES = (Private, ); }; };
                46BCBBC22085008F00710638 /* JSRemoteDOMWindowBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 46BCBBC02085007F00710638 /* JSRemoteDOMWindowBase.h */; settings = {ATTRIBUTES = (Private, ); }; };
                46C376622085177D00C73829 /* JSRemoteDOMWindow.h in Headers */ = {isa = PBXBuildFile; fileRef = 46C376612085176D00C73829 /* JSRemoteDOMWindow.h */; };
                46C696CB1E7205F700597937 /* CPUMonitor.h in Headers */ = {isa = PBXBuildFile; fileRef = 46C696C91E7205E400597937 /* CPUMonitor.h */; settings = {ATTRIBUTES = (Private, ); }; };
                460CBF331D4BCCFE0092E88E /* JSDOMWindowProperties.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDOMWindowProperties.cpp; sourceTree = "<group>"; };
                460CBF341D4BCCFE0092E88E /* JSDOMWindowProperties.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMWindowProperties.h; sourceTree = "<group>"; };
                460D19441FCE21DD00C3DB85 /* JSServiceWorkerGlobalScopeCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSServiceWorkerGlobalScopeCustom.cpp; sourceTree = "<group>"; };
                460CBF331D4BCCFE0092E88E /* JSDOMWindowProperties.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDOMWindowProperties.cpp; sourceTree = "<group>"; };
                460CBF341D4BCCFE0092E88E /* JSDOMWindowProperties.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMWindowProperties.h; sourceTree = "<group>"; };
                460D19441FCE21DD00C3DB85 /* JSServiceWorkerGlobalScopeCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSServiceWorkerGlobalScopeCustom.cpp; sourceTree = "<group>"; };
+               461DA52A222F486F00D05A87 /* DeviceOrientationOrMotionEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DeviceOrientationOrMotionEvent.h; sourceTree = "<group>"; };
+               461DA52C222F486F00D05A87 /* DeviceOrientationOrMotionEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DeviceOrientationOrMotionEvent.cpp; sourceTree = "<group>"; };
                4634592B1AC2271000ECB71C /* PowerObserverMac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PowerObserverMac.cpp; sourceTree = "<group>"; };
                463521AA2081090B00C28922 /* WindowProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WindowProxy.h; sourceTree = "<group>"; };
                463521AC2081090E00C28922 /* WindowProxy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WindowProxy.cpp; sourceTree = "<group>"; };
                4634592B1AC2271000ECB71C /* PowerObserverMac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PowerObserverMac.cpp; sourceTree = "<group>"; };
                463521AA2081090B00C28922 /* WindowProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WindowProxy.h; sourceTree = "<group>"; };
                463521AC2081090E00C28922 /* WindowProxy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WindowProxy.cpp; sourceTree = "<group>"; };
                463EB6211B8789CB0096ED51 /* TagCollection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TagCollection.h; sourceTree = "<group>"; };
                4642404520EAF0ED00B29FD2 /* DatabaseManagerCocoa.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = DatabaseManagerCocoa.mm; sourceTree = "<group>"; };
                465A8E781C8A24CE00E7D3E4 /* RuntimeApplicationChecksCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RuntimeApplicationChecksCocoa.mm; sourceTree = "<group>"; };
                463EB6211B8789CB0096ED51 /* TagCollection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TagCollection.h; sourceTree = "<group>"; };
                4642404520EAF0ED00B29FD2 /* DatabaseManagerCocoa.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = DatabaseManagerCocoa.mm; sourceTree = "<group>"; };
                465A8E781C8A24CE00E7D3E4 /* RuntimeApplicationChecksCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RuntimeApplicationChecksCocoa.mm; sourceTree = "<group>"; };
+               465EDD9D222F4EC300B46E16 /* DeviceOrientationOrMotionEvent.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DeviceOrientationOrMotionEvent.idl; sourceTree = "<group>"; };
+               465EDD9F222F4EC300B46E16 /* DeviceOrientationOrMotionPermissionState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DeviceOrientationOrMotionPermissionState.h; sourceTree = "<group>"; };
+               465EDDA0222F4EC400B46E16 /* DeviceOrientationOrMotionPermissionState.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DeviceOrientationOrMotionPermissionState.idl; sourceTree = "<group>"; };
                466DC6AB1EDE021D00746224 /* JSDOMRectList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDOMRectList.cpp; sourceTree = "<group>"; };
                466ED8D21EDE0135005E43F6 /* JSDOMRectList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMRectList.h; sourceTree = "<group>"; };
                4671E0631D67A57B00C6B497 /* CanvasPath.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CanvasPath.cpp; sourceTree = "<group>"; };
                466DC6AB1EDE021D00746224 /* JSDOMRectList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDOMRectList.cpp; sourceTree = "<group>"; };
                466ED8D21EDE0135005E43F6 /* JSDOMRectList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMRectList.h; sourceTree = "<group>"; };
                4671E0631D67A57B00C6B497 /* CanvasPath.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CanvasPath.cpp; sourceTree = "<group>"; };
                46B95192207D632E00A7D2DD /* RemoteFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RemoteFrame.h; sourceTree = "<group>"; };
                46B95193207D632F00A7D2DD /* AbstractDOMWindow.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AbstractDOMWindow.cpp; sourceTree = "<group>"; };
                46B95194207D633000A7D2DD /* AbstractFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AbstractFrame.cpp; sourceTree = "<group>"; };
                46B95192207D632E00A7D2DD /* RemoteFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RemoteFrame.h; sourceTree = "<group>"; };
                46B95193207D632F00A7D2DD /* AbstractDOMWindow.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AbstractDOMWindow.cpp; sourceTree = "<group>"; };
                46B95194207D633000A7D2DD /* AbstractFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AbstractFrame.cpp; sourceTree = "<group>"; };
+               46B95BF22231CFB80053A504 /* DeviceOrientationAndMotionAccessController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DeviceOrientationAndMotionAccessController.cpp; sourceTree = "<group>"; };
+               46B95BF42231CFB80053A504 /* DeviceOrientationAndMotionAccessController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DeviceOrientationAndMotionAccessController.h; sourceTree = "<group>"; };
                46BCBBBE2085005B00710638 /* JSRemoteDOMWindowCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSRemoteDOMWindowCustom.cpp; sourceTree = "<group>"; };
                46BCBBC02085007F00710638 /* JSRemoteDOMWindowBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSRemoteDOMWindowBase.h; sourceTree = "<group>"; };
                46BCBBC12085008000710638 /* JSRemoteDOMWindowBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSRemoteDOMWindowBase.cpp; sourceTree = "<group>"; };
                46BCBBBE2085005B00710638 /* JSRemoteDOMWindowCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSRemoteDOMWindowCustom.cpp; sourceTree = "<group>"; };
                46BCBBC02085007F00710638 /* JSRemoteDOMWindowBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSRemoteDOMWindowBase.h; sourceTree = "<group>"; };
                46BCBBC12085008000710638 /* JSRemoteDOMWindowBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSRemoteDOMWindowBase.cpp; sourceTree = "<group>"; };
                                31FB1A54120A5D0600DC02A0 /* DeviceMotionEvent.cpp */,
                                31FB1A55120A5D0600DC02A0 /* DeviceMotionEvent.h */,
                                31FB1A56120A5D0600DC02A0 /* DeviceMotionEvent.idl */,
                                31FB1A54120A5D0600DC02A0 /* DeviceMotionEvent.cpp */,
                                31FB1A55120A5D0600DC02A0 /* DeviceMotionEvent.h */,
                                31FB1A56120A5D0600DC02A0 /* DeviceMotionEvent.idl */,
+                               46B95BF22231CFB80053A504 /* DeviceOrientationAndMotionAccessController.cpp */,
+                               46B95BF42231CFB80053A504 /* DeviceOrientationAndMotionAccessController.h */,
                                59A8F1D711A69520001AC34A /* DeviceOrientationClient.h */,
                                59A8F1D311A69508001AC34A /* DeviceOrientationController.cpp */,
                                59A8F1D511A69513001AC34A /* DeviceOrientationController.h */,
                                59A8F1D711A69520001AC34A /* DeviceOrientationClient.h */,
                                59A8F1D311A69508001AC34A /* DeviceOrientationController.cpp */,
                                59A8F1D511A69513001AC34A /* DeviceOrientationController.h */,
                                59A85EA1119D68D900DEF1EF /* DeviceOrientationEvent.cpp */,
                                59A85EA3119D68EC00DEF1EF /* DeviceOrientationEvent.h */,
                                59A85EAA119D7B6E00DEF1EF /* DeviceOrientationEvent.idl */,
                                59A85EA1119D68D900DEF1EF /* DeviceOrientationEvent.cpp */,
                                59A85EA3119D68EC00DEF1EF /* DeviceOrientationEvent.h */,
                                59A85EAA119D7B6E00DEF1EF /* DeviceOrientationEvent.idl */,
+                               461DA52C222F486F00D05A87 /* DeviceOrientationOrMotionEvent.cpp */,
+                               461DA52A222F486F00D05A87 /* DeviceOrientationOrMotionEvent.h */,
+                               465EDD9D222F4EC300B46E16 /* DeviceOrientationOrMotionEvent.idl */,
+                               465EDD9F222F4EC300B46E16 /* DeviceOrientationOrMotionPermissionState.h */,
+                               465EDDA0222F4EC400B46E16 /* DeviceOrientationOrMotionPermissionState.idl */,
                                A8185F3409765765005826D9 /* Document.cpp */,
                                A8185F3809765765005826D9 /* Document.h */,
                                6548E24809E1E04D00AF8020 /* Document.idl */,
                                A8185F3409765765005826D9 /* Document.cpp */,
                                A8185F3809765765005826D9 /* Document.h */,
                                6548E24809E1E04D00AF8020 /* Document.idl */,
                                31FB1A59120A5D0600DC02A0 /* DeviceMotionController.h in Headers */,
                                31FB1A5B120A5D0600DC02A0 /* DeviceMotionData.h in Headers */,
                                31FB1A5D120A5D0600DC02A0 /* DeviceMotionEvent.h in Headers */,
                                31FB1A59120A5D0600DC02A0 /* DeviceMotionController.h in Headers */,
                                31FB1A5B120A5D0600DC02A0 /* DeviceMotionData.h in Headers */,
                                31FB1A5D120A5D0600DC02A0 /* DeviceMotionEvent.h in Headers */,
+                               46B95BF52231CFD60053A504 /* DeviceOrientationAndMotionAccessController.h in Headers */,
                                59A8F1D811A69520001AC34A /* DeviceOrientationClient.h in Headers */,
                                3140379D124BEA7F00AF40E4 /* DeviceOrientationClientIOS.h in Headers */,
                                59309A1311F4AE6A00250603 /* DeviceOrientationClientMock.h in Headers */,
                                59A8F1D611A69513001AC34A /* DeviceOrientationController.h in Headers */,
                                590E1B4911E4EF4B0069F784 /* DeviceOrientationData.h in Headers */,
                                59A85EA4119D68EC00DEF1EF /* DeviceOrientationEvent.h in Headers */,
                                59A8F1D811A69520001AC34A /* DeviceOrientationClient.h in Headers */,
                                3140379D124BEA7F00AF40E4 /* DeviceOrientationClientIOS.h in Headers */,
                                59309A1311F4AE6A00250603 /* DeviceOrientationClientMock.h in Headers */,
                                59A8F1D611A69513001AC34A /* DeviceOrientationController.h in Headers */,
                                590E1B4911E4EF4B0069F784 /* DeviceOrientationData.h in Headers */,
                                59A85EA4119D68EC00DEF1EF /* DeviceOrientationEvent.h in Headers */,
+                               460E3075222F4EFD009A0606 /* DeviceOrientationOrMotionEvent.h in Headers */,
+                               460E3077222F4F03009A0606 /* DeviceOrientationOrMotionPermissionState.h in Headers */,
                                572B401F21757A64000AD43E /* DeviceRequestConverter.h in Headers */,
                                572B403A21772581000AD43E /* DeviceResponseConverter.h in Headers */,
                                267725FD1A5B3AD9003C24DD /* DFA.h in Headers */,
                                572B401F21757A64000AD43E /* DeviceRequestConverter.h in Headers */,
                                572B403A21772581000AD43E /* DeviceResponseConverter.h in Headers */,
                                267725FD1A5B3AD9003C24DD /* DFA.h in Headers */,
index 3ecc5bd..51d71a0 100644 (file)
 
 #pragma once
 
 
 #pragma once
 
+#include "DeviceOrientationOrMotionEvent.h"
 #include "Event.h"
 
 namespace WebCore {
 
 class DeviceMotionData;
 
 #include "Event.h"
 
 namespace WebCore {
 
 class DeviceMotionData;
 
-class DeviceMotionEvent final : public Event {
+class DeviceMotionEvent final : public Event, public DeviceOrientationOrMotionEvent {
 public:
     virtual ~DeviceMotionEvent();
 
 public:
     virtual ~DeviceMotionEvent();
 
index f2f5df2..27f2c55 100644 (file)
@@ -57,3 +57,5 @@
     double? beta;
     double? gamma;
 };
     double? beta;
     double? gamma;
 };
+
+DeviceMotionEvent implements DeviceOrientationOrMotionEvent;
diff --git a/Source/WebCore/dom/DeviceOrientationAndMotionAccessController.cpp b/Source/WebCore/dom/DeviceOrientationAndMotionAccessController.cpp
new file mode 100644 (file)
index 0000000..d49268d
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DeviceOrientationAndMotionAccessController.h"
+
+#if ENABLE(DEVICE_ORIENTATION)
+
+#include "Chrome.h"
+#include "ChromeClient.h"
+#include "DOMWindow.h"
+#include "Document.h"
+#include "Frame.h"
+#include "Page.h"
+
+namespace WebCore {
+
+DeviceOrientationAndMotionAccessController::DeviceOrientationAndMotionAccessController(Document& document)
+    : m_document(document)
+{
+    ASSERT(&m_document.topDocument() == &m_document);
+}
+
+void DeviceOrientationAndMotionAccessController::shouldAllowAccess(Function<void(bool granted)>&& callback)
+{
+    if (m_accessState)
+        return callback(*m_accessState);
+
+    auto* page = m_document.page();
+    if (!page)
+        return callback(false);
+
+    m_pendingRequests.append(WTFMove(callback));
+    if (m_pendingRequests.size() > 1)
+        return;
+
+    page->chrome().client().shouldAllowDeviceOrientationAndMotionAccess(m_document.securityOrigin(), [this, weakThis = makeWeakPtr(*this)](bool granted) mutable {
+        if (weakThis)
+            setAccessState(granted);
+    });
+}
+
+void DeviceOrientationAndMotionAccessController::setAccessState(bool granted)
+{
+    ASSERT(!m_accessState);
+
+    m_accessState = granted;
+
+    auto pendingRequests = WTFMove(m_pendingRequests);
+    for (auto& request : pendingRequests)
+        request(granted);
+
+    if (!granted)
+        return;
+
+    for (auto* frame = m_document.frame(); frame && frame->window(); frame = frame->tree().traverseNext(m_document.frame())) {
+        frame->window()->startListeningForDeviceOrientationIfNecessary();
+        frame->window()->startListeningForDeviceMotionIfNecessary();
+    }
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(DEVICE_ORIENTATION)
diff --git a/Source/WebCore/dom/DeviceOrientationAndMotionAccessController.h b/Source/WebCore/dom/DeviceOrientationAndMotionAccessController.h
new file mode 100644 (file)
index 0000000..71fc792
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(DEVICE_ORIENTATION)
+
+#include <wtf/Function.h>
+#include <wtf/Vector.h>
+#include <wtf/WeakPtr.h>
+
+namespace WebCore {
+
+class Document;
+
+class DeviceOrientationAndMotionAccessController : public CanMakeWeakPtr<DeviceOrientationAndMotionAccessController> {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    explicit DeviceOrientationAndMotionAccessController(Document&);
+
+    const Optional<bool>& accessState() const { return m_accessState; }
+    void shouldAllowAccess(Function<void(bool granted)>&&);
+
+private:
+    void setAccessState(bool);
+
+    Document& m_document;
+    Optional<bool> m_accessState;
+    Vector<Function<void(bool)>> m_pendingRequests;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(DEVICE_ORIENTATION)
index 025b2e3..628708b 100644 (file)
 
 #pragma once
 
 
 #pragma once
 
+#include "DeviceOrientationOrMotionEvent.h"
 #include "Event.h"
 
 namespace WebCore {
 
 class DeviceOrientationData;
 
 #include "Event.h"
 
 namespace WebCore {
 
 class DeviceOrientationData;
 
-class DeviceOrientationEvent final : public Event {
+class DeviceOrientationEvent final : public Event, public DeviceOrientationOrMotionEvent {
 public:
     static Ref<DeviceOrientationEvent> create(const AtomicString& eventType, DeviceOrientationData* orientation)
     {
 public:
     static Ref<DeviceOrientationEvent> create(const AtomicString& eventType, DeviceOrientationData* orientation)
     {
index 13ff7ba..7f35f10 100644 (file)
@@ -55,3 +55,4 @@
 #endif
 };
 
 #endif
 };
 
+DeviceOrientationEvent implements DeviceOrientationOrMotionEvent;
diff --git a/Source/WebCore/dom/DeviceOrientationOrMotionEvent.cpp b/Source/WebCore/dom/DeviceOrientationOrMotionEvent.cpp
new file mode 100644 (file)
index 0000000..ae09616
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DeviceOrientationOrMotionEvent.h"
+
+#include "Document.h"
+#include "UserGestureIndicator.h"
+
+namespace WebCore {
+
+#if ENABLE(DEVICE_ORIENTATION)
+void DeviceOrientationOrMotionEvent::requestPermission(Document& document, PermissionPromise&& promise)
+{
+    auto* window = document.domWindow();
+    if (!window)
+        return promise.reject(Exception { InvalidStateError, "No browsing context"_s });
+
+    if (!UserGestureIndicator::processingUserGesture())
+        return promise.reject(Exception { NotAllowedError, "Calling requestPermission() requires a user gesture"_s });
+
+    String errorMessage;
+    if (!window->isAllowedToUseDeviceMotionOrientation(errorMessage)) {
+        document.addConsoleMessage(MessageSource::JS, MessageLevel::Warning, makeString("Call to requestPermission() failed, reason: ", errorMessage, "."));
+        return promise.resolve(PermissionState::Denied);
+    }
+
+    document.deviceOrientationAndMotionAccessController().shouldAllowAccess([promise = WTFMove(promise)](bool granted) mutable {
+        promise.resolve(granted ? PermissionState::Granted : PermissionState::Denied);
+    });
+}
+#endif
+
+} // namespace WebCore
diff --git a/Source/WebCore/dom/DeviceOrientationOrMotionEvent.h b/Source/WebCore/dom/DeviceOrientationOrMotionEvent.h
new file mode 100644 (file)
index 0000000..1bae681
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "DeviceOrientationOrMotionPermissionState.h"
+#include "JSDOMPromiseDeferred.h"
+
+namespace WebCore {
+
+class Document;
+
+class DeviceOrientationOrMotionEvent {
+public:
+
+#if ENABLE(DEVICE_ORIENTATION)
+    using PermissionState = DeviceOrientationOrMotionPermissionState;
+    using PermissionPromise = DOMPromiseDeferred<IDLEnumeration<PermissionState>>;
+    static void requestPermission(Document&, PermissionPromise&&);
+#endif
+
+protected:
+    DeviceOrientationOrMotionEvent() = default;
+    ~DeviceOrientationOrMotionEvent() = default;
+};
+
+} // namespace WebCore
diff --git a/Source/WebCore/dom/DeviceOrientationOrMotionEvent.idl b/Source/WebCore/dom/DeviceOrientationOrMotionEvent.idl
new file mode 100644 (file)
index 0000000..6831a46
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+[
+    Conditional=DEVICE_ORIENTATION,
+    NoInterfaceObject
+] interface DeviceOrientationOrMotionEvent {
+    [CallWith=Document, EnabledBySetting=DeviceOrientationPermissionAPI] static Promise<DeviceOrientationOrMotionPermissionState> requestPermission();
+};
diff --git a/Source/WebCore/dom/DeviceOrientationOrMotionPermissionState.h b/Source/WebCore/dom/DeviceOrientationOrMotionPermissionState.h
new file mode 100644 (file)
index 0000000..dd65edb
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+namespace WebCore {
+
+enum class DeviceOrientationOrMotionPermissionState { Granted, Denied };
+
+}
diff --git a/Source/WebCore/dom/DeviceOrientationOrMotionPermissionState.idl b/Source/WebCore/dom/DeviceOrientationOrMotionPermissionState.idl
new file mode 100644 (file)
index 0000000..b181403
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+enum DeviceOrientationOrMotionPermissionState { "granted", "denied" };
index e184c1f..a1c0ad3 100644 (file)
 
 #if ENABLE(DEVICE_ORIENTATION)
 #include "DeviceMotionEvent.h"
 
 #if ENABLE(DEVICE_ORIENTATION)
 #include "DeviceMotionEvent.h"
+#include "DeviceOrientationAndMotionAccessController.h"
 #include "DeviceOrientationEvent.h"
 #endif
 
 #include "DeviceOrientationEvent.h"
 #endif
 
@@ -8611,6 +8612,20 @@ void Document::frameWasDisconnectedFromOwner()
     detachFromFrame();
 }
 
     detachFromFrame();
 }
 
+#if ENABLE(DEVICE_ORIENTATION)
+
+DeviceOrientationAndMotionAccessController& Document::deviceOrientationAndMotionAccessController()
+{
+    if (&topDocument() != this)
+        return topDocument().deviceOrientationAndMotionAccessController();
+
+    if (!m_deviceOrientationAndMotionAccessController)
+        m_deviceOrientationAndMotionAccessController = std::make_unique<DeviceOrientationAndMotionAccessController>(*this);
+    return *m_deviceOrientationAndMotionAccessController;
+}
+
+#endif
+
 #if ENABLE(CSS_PAINTING_API)
 Worklet& Document::ensurePaintWorklet()
 {
 #if ENABLE(CSS_PAINTING_API)
 Worklet& Document::ensurePaintWorklet()
 {
index d9dcef5..2b99d44 100644 (file)
@@ -224,12 +224,15 @@ class Touch;
 class TouchList;
 #endif
 
 class TouchList;
 #endif
 
+#if ENABLE(DEVICE_ORIENTATION)
 #if PLATFORM(IOS_FAMILY)
 class DeviceMotionClient;
 class DeviceMotionController;
 class DeviceOrientationClient;
 class DeviceOrientationController;
 #endif
 #if PLATFORM(IOS_FAMILY)
 class DeviceMotionClient;
 class DeviceMotionController;
 class DeviceOrientationClient;
 class DeviceOrientationController;
 #endif
+class DeviceOrientationAndMotionAccessController;
+#endif
 
 #if ENABLE(TEXT_AUTOSIZING)
 class TextAutoSizing;
 
 #if ENABLE(TEXT_AUTOSIZING)
 class TextAutoSizing;
@@ -1216,12 +1219,16 @@ public:
 #include <WebKitAdditions/DocumentIOS.h>
 #endif
 
 #include <WebKitAdditions/DocumentIOS.h>
 #endif
 
-#if ENABLE(DEVICE_ORIENTATION) && PLATFORM(IOS_FAMILY)
+#if ENABLE(DEVICE_ORIENTATION)
+#if PLATFORM(IOS_FAMILY)
     DeviceMotionController& deviceMotionController() const;
     DeviceOrientationController& deviceOrientationController() const;
     WEBCORE_EXPORT void simulateDeviceOrientationChange(double alpha, double beta, double gamma);
 #endif
 
     DeviceMotionController& deviceMotionController() const;
     DeviceOrientationController& deviceOrientationController() const;
     WEBCORE_EXPORT void simulateDeviceOrientationChange(double alpha, double beta, double gamma);
 #endif
 
+    DeviceOrientationAndMotionAccessController& deviceOrientationAndMotionAccessController();
+#endif // ENABLE(DEVICE_ORIENTATION)
+
     const DocumentTiming& timing() const { return m_documentTiming; }
 
     WEBCORE_EXPORT double monotonicTimestamp() const;
     const DocumentTiming& timing() const { return m_documentTiming; }
 
     WEBCORE_EXPORT double monotonicTimestamp() const;
@@ -1869,12 +1876,15 @@ private:
     void setHasFrameSpecificStorageAccess(bool);
 #endif
 
     void setHasFrameSpecificStorageAccess(bool);
 #endif
 
-#if ENABLE(DEVICE_ORIENTATION) && PLATFORM(IOS_FAMILY)
+#if ENABLE(DEVICE_ORIENTATION)
+#if PLATFORM(IOS_FAMILY)
     std::unique_ptr<DeviceMotionClient> m_deviceMotionClient;
     std::unique_ptr<DeviceMotionController> m_deviceMotionController;
     std::unique_ptr<DeviceOrientationClient> m_deviceOrientationClient;
     std::unique_ptr<DeviceOrientationController> m_deviceOrientationController;
 #endif
     std::unique_ptr<DeviceMotionClient> m_deviceMotionClient;
     std::unique_ptr<DeviceMotionController> m_deviceMotionController;
     std::unique_ptr<DeviceOrientationClient> m_deviceOrientationClient;
     std::unique_ptr<DeviceOrientationController> m_deviceOrientationController;
 #endif
+    std::unique_ptr<DeviceOrientationAndMotionAccessController> m_deviceOrientationAndMotionAccessController;
+#endif
 
     GenericTaskQueue<Timer> m_logMessageTaskQueue;
 
 
     GenericTaskQueue<Timer> m_logMessageTaskQueue;
 
index c0db291..9371190 100644 (file)
@@ -28,6 +28,7 @@
 #include "EventNames.h"
 #include "EventPath.h"
 #include "EventTarget.h"
 #include "EventNames.h"
 #include "EventPath.h"
 #include "EventTarget.h"
+#include "InspectorInstrumentation.h"
 #include "Performance.h"
 #include "UserGestureIndicator.h"
 #include "WorkerGlobalScope.h"
 #include "Performance.h"
 #include "UserGestureIndicator.h"
 #include "WorkerGlobalScope.h"
index 188cc31..40224f8 100644 (file)
@@ -35,6 +35,7 @@
 #include "MessageWithMessagePorts.h"
 #include "WorkerGlobalScope.h"
 #include "WorkerThread.h"
 #include "MessageWithMessagePorts.h"
 #include "WorkerGlobalScope.h"
 #include "WorkerThread.h"
+#include <wtf/CompletionHandler.h>
 
 namespace WebCore {
 
 
 namespace WebCore {
 
index 25a47a6..2cccf0b 100644 (file)
@@ -22,6 +22,7 @@
 #include "config.h"
 #include "Microtasks.h"
 
 #include "config.h"
 #include "Microtasks.h"
 
+#include "WorkerGlobalScope.h"
 #include <wtf/MainThread.h>
 #include <wtf/NeverDestroyed.h>
 #include <wtf/SetForScope.h>
 #include <wtf/MainThread.h>
 #include <wtf/NeverDestroyed.h>
 #include <wtf/SetForScope.h>
index 3a0dc3b..47e3c5a 100644 (file)
@@ -482,6 +482,10 @@ public:
     virtual void hasStorageAccess(String&& /*subFrameHost*/, String&& /*topFrameHost*/, uint64_t /*frameID*/, uint64_t /*pageID*/, WTF::CompletionHandler<void (bool)>&& callback) { callback(false); }
     virtual void requestStorageAccess(String&& /*subFrameHost*/, String&& /*topFrameHost*/, uint64_t /*frameID*/, uint64_t /*pageID*/, WTF::CompletionHandler<void (bool)>&& callback) { callback(false); }
 
     virtual void hasStorageAccess(String&& /*subFrameHost*/, String&& /*topFrameHost*/, uint64_t /*frameID*/, uint64_t /*pageID*/, WTF::CompletionHandler<void (bool)>&& callback) { callback(false); }
     virtual void requestStorageAccess(String&& /*subFrameHost*/, String&& /*topFrameHost*/, uint64_t /*frameID*/, uint64_t /*pageID*/, WTF::CompletionHandler<void (bool)>&& callback) { callback(false); }
 
+#if ENABLE(DEVICE_ORIENTATION)
+    virtual void shouldAllowDeviceOrientationAndMotionAccess(const SecurityOrigin&, WTF::CompletionHandler<void(bool)>&& callback) { callback(true); }
+#endif
+
     virtual void didInsertMenuElement(HTMLMenuElement&) { }
     virtual void didRemoveMenuElement(HTMLMenuElement&) { }
     virtual void didInsertMenuItemElement(HTMLMenuItemElement&) { }
     virtual void didInsertMenuElement(HTMLMenuElement&) { }
     virtual void didRemoveMenuElement(HTMLMenuElement&) { }
     virtual void didInsertMenuItemElement(HTMLMenuItemElement&) { }
index dfa1124..59891d2 100644 (file)
@@ -49,6 +49,7 @@
 #include "DeviceMotionController.h"
 #include "DeviceMotionData.h"
 #include "DeviceMotionEvent.h"
 #include "DeviceMotionController.h"
 #include "DeviceMotionData.h"
 #include "DeviceMotionEvent.h"
+#include "DeviceOrientationAndMotionAccessController.h"
 #include "DeviceOrientationController.h"
 #include "Document.h"
 #include "DocumentLoader.h"
 #include "DeviceOrientationController.h"
 #include "Document.h"
 #include "DocumentLoader.h"
@@ -1826,50 +1827,134 @@ bool DOMWindow::addEventListener(const AtomicString& eventType, Ref<EventListene
     else if (eventNames().isGamepadEventType(eventType))
         incrementGamepadEventListenerCount();
 #endif
     else if (eventNames().isGamepadEventType(eventType))
         incrementGamepadEventListenerCount();
 #endif
+#if ENABLE(DEVICE_ORIENTATION)
+    else if (eventType == eventNames().deviceorientationEvent)
+        startListeningForDeviceOrientationIfNecessary();
+    else if (eventType == eventNames().devicemotionEvent)
+        startListeningForDeviceMotionIfNecessary();
+#endif
+
+    return true;
+}
 
 #if ENABLE(DEVICE_ORIENTATION)
 
 #if ENABLE(DEVICE_ORIENTATION)
-    if (frame() && frame()->settings().deviceOrientationEventEnabled() && document() && document()->loader() && document()->loader()->deviceOrientationEventEnabled()) {
+
+DeviceOrientationController* DOMWindow::deviceOrientationController() const
+{
 #if PLATFORM(IOS_FAMILY)
 #if PLATFORM(IOS_FAMILY)
-        if ((eventType == eventNames().devicemotionEvent || eventType == eventNames().deviceorientationEvent)) {
-            if (isSameSecurityOriginAsMainFrame() && isSecureContext()) {
-                if (eventType == eventNames().deviceorientationEvent)
-                    document()->deviceOrientationController().addDeviceEventListener(*this);
-                else
-                    document()->deviceMotionController().addDeviceEventListener(*this);
-            } else if (document()) {
-                if (isSecureContext())
-                    document()->addConsoleMessage(MessageSource::JS, MessageLevel::Warning, "Blocked attempt to add a device motion or orientation listener from child frame that wasn't the same security origin as the main page."_s);
-                else
-                    document()->addConsoleMessage(MessageSource::JS, MessageLevel::Warning, "Blocked attempt to add a device motion or orientation listener because the browsing context is not secure."_s);
-            }
-        }
+    return document() ? &document()->deviceOrientationController() : nullptr;
 #else
 #else
-        if (eventType == eventNames().devicemotionEvent) {
-            if (isSameSecurityOriginAsMainFrame() && isSecureContext()) {
-                if (DeviceMotionController* controller = DeviceMotionController::from(page()))
-                    controller->addDeviceEventListener(*this);
-            } 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 (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
-                    document()->addConsoleMessage(MessageSource::JS, MessageLevel::Warning, "Blocked attempt to add a device motion or orientation listener because the browsing context is not secure."_s);
-            }
+    return DeviceOrientationController::from(page());
+#endif
+}
+
+DeviceMotionController* DOMWindow::deviceMotionController() const
+{
+#if PLATFORM(IOS_FAMILY)
+    return document() ? &document()->deviceMotionController() : nullptr;
+#else
+    return DeviceMotionController::from(page());
+#endif
+}
+
+bool DOMWindow::isAllowedToUseDeviceMotionOrientation(String& message) const
+{
+    if (!frame() || !frame()->settings().deviceOrientationEventEnabled() || !document() || !document()->loader() || !document()->loader()->deviceOrientationEventEnabled()) {
+        message = "API is disabled"_s;
+        return false;
+    }
+
+    if (!isSecureContext()) {
+        message = "Browsing context is not secure"_s;
+        return false;
+    }
+
+    if (!isSameSecurityOriginAsMainFrame()) {
+        message = "Source frame did not have the same security origin as the main page"_s;
+        return false;
+    }
+    return true;
+}
+
+bool DOMWindow::isAllowedToAddDeviceMotionOrientationListener(String& message) const
+{
+    String innerMessage;
+    if (!isAllowedToUseDeviceMotionOrientation(innerMessage)) {
+        message = makeString("Blocked attempt to add a device motion or orientation event listener, reason: ", innerMessage, ".");
+        return false;
+    }
+
+    if (frame()->settings().deviceOrientationPermissionAPIEnabled()) {
+        auto accessState = document()->deviceOrientationAndMotionAccessController().accessState();
+        if (accessState && !*accessState) {
+            message = "No device motion or orientation events will be fired because permission to use the API was denied."_s;
+            return false;
         }
         }
-#endif // PLATFORM(IOS_FAMILY)
-    } else if (eventType == eventNames().devicemotionEvent)
-        failedToRegisterDeviceMotionEventListener();
-#endif // ENABLE(DEVICE_ORIENTATION)
+        if (!accessState) {
+            message = "No device motion or orientation events will be fired until permission has been requested and granted."_s;
+            return false;
+        }
+    }
 
     return true;
 }
 
 
     return true;
 }
 
-#if ENABLE(DEVICE_ORIENTATION)
+void DOMWindow::startListeningForDeviceOrientationIfNecessary()
+{
+    if (!hasEventListeners(eventNames().deviceorientationEvent))
+        return;
+
+    auto* deviceController = deviceOrientationController();
+    if (!deviceController || deviceController->hasDeviceEventListener(*this))
+        return;
+
+    String errorMessage;
+    if (!isAllowedToAddDeviceMotionOrientationListener(errorMessage)) {
+        if (auto* document = this->document())
+            document->addConsoleMessage(MessageSource::JS, MessageLevel::Warning, errorMessage);
+        return;
+    }
+
+    deviceController->addDeviceEventListener(*this);
+}
+
+void DOMWindow::stopListeningForDeviceOrientationIfNecessary()
+{
+    if (hasEventListeners(eventNames().deviceorientationEvent))
+        return;
+
+    if (auto* deviceController = deviceOrientationController())
+        deviceController->removeDeviceEventListener(*this);
+}
+
+void DOMWindow::startListeningForDeviceMotionIfNecessary()
+{
+    if (!hasEventListeners(eventNames().devicemotionEvent))
+        return;
+
+    auto* deviceController = deviceMotionController();
+    if (!deviceController || deviceController->hasDeviceEventListener(*this))
+        return;
+
+    String errorMessage;
+    if (!isAllowedToAddDeviceMotionOrientationListener(errorMessage)) {
+        failedToRegisterDeviceMotionEventListener();
+        if (auto* document = this->document())
+            document->addConsoleMessage(MessageSource::JS, MessageLevel::Warning, errorMessage);
+        return;
+    }
+
+    deviceController->addDeviceEventListener(*this);
+}
+
+void DOMWindow::stopListeningForDeviceMotionIfNecessary()
+{
+    if (hasEventListeners(eventNames().devicemotionEvent))
+        return;
+
+    if (auto* deviceController = deviceMotionController())
+        deviceController->removeDeviceEventListener(*this);
+}
 
 void DOMWindow::failedToRegisterDeviceMotionEventListener()
 {
 
 void DOMWindow::failedToRegisterDeviceMotionEventListener()
 {
@@ -1941,22 +2026,6 @@ bool DOMWindow::removeEventListener(const AtomicString& eventType, EventListener
         removeUnloadEventListener(this);
     else if (eventType == eventNames().beforeunloadEvent && allowsBeforeUnloadListeners(this))
         removeBeforeUnloadEventListener(this);
         removeUnloadEventListener(this);
     else if (eventType == eventNames().beforeunloadEvent && allowsBeforeUnloadListeners(this))
         removeBeforeUnloadEventListener(this);
-#if ENABLE(DEVICE_ORIENTATION)
-#if PLATFORM(IOS_FAMILY)
-    else if (eventType == eventNames().devicemotionEvent && document())
-        document()->deviceMotionController().removeDeviceEventListener(*this);
-    else if (eventType == eventNames().deviceorientationEvent && document())
-        document()->deviceOrientationController().removeDeviceEventListener(*this);
-#else
-    else if (eventType == eventNames().devicemotionEvent) {
-        if (DeviceMotionController* controller = DeviceMotionController::from(page()))
-            controller->removeDeviceEventListener(*this);
-    } else if (eventType == eventNames().deviceorientationEvent) {
-        if (DeviceOrientationController* controller = DeviceOrientationController::from(page()))
-            controller->removeDeviceEventListener(*this);
-    }
-#endif // PLATFORM(IOS_FAMILY)
-#endif // ENABLE(DEVICE_ORIENTATION)
 #if PLATFORM(IOS_FAMILY)
     else if (eventType == eventNames().scrollEvent)
         decrementScrollEventListenersCount();
 #if PLATFORM(IOS_FAMILY)
     else if (eventType == eventNames().scrollEvent)
         decrementScrollEventListenersCount();
@@ -1977,6 +2046,12 @@ bool DOMWindow::removeEventListener(const AtomicString& eventType, EventListener
     else if (eventNames().isGamepadEventType(eventType))
         decrementGamepadEventListenerCount();
 #endif
     else if (eventNames().isGamepadEventType(eventType))
         decrementGamepadEventListenerCount();
 #endif
+#if ENABLE(DEVICE_ORIENTATION)
+    else if (eventType == eventNames().deviceorientationEvent)
+        stopListeningForDeviceOrientationIfNecessary();
+    else if (eventType == eventNames().devicemotionEvent)
+        stopListeningForDeviceMotionIfNecessary();
+#endif
 
     return true;
 }
 
     return true;
 }
@@ -2059,18 +2134,9 @@ void DOMWindow::removeAllEventListeners()
     EventTarget::removeAllEventListeners();
 
 #if ENABLE(DEVICE_ORIENTATION)
     EventTarget::removeAllEventListeners();
 
 #if ENABLE(DEVICE_ORIENTATION)
-#if PLATFORM(IOS_FAMILY)
-    if (Document* document = this->document()) {
-        document->deviceMotionController().removeAllDeviceEventListeners(*this);
-        document->deviceOrientationController().removeAllDeviceEventListeners(*this);
-    }
-#else
-    if (DeviceMotionController* controller = DeviceMotionController::from(page()))
-        controller->removeAllDeviceEventListeners(*this);
-    if (DeviceOrientationController* controller = DeviceOrientationController::from(page()))
-        controller->removeAllDeviceEventListeners(*this);
-#endif // PLATFORM(IOS_FAMILY)
-#endif // ENABLE(DEVICE_ORIENTATION)
+        stopListeningForDeviceOrientationIfNecessary();
+        stopListeningForDeviceMotionIfNecessary();
+#endif
 
 #if PLATFORM(IOS_FAMILY)
     if (m_scrollEventListenerCount) {
 
 #if PLATFORM(IOS_FAMILY)
     if (m_scrollEventListenerCount) {
index bbbfa95..1d8a642 100644 (file)
@@ -82,6 +82,11 @@ class VisualViewport;
 class WebKitNamespace;
 class WebKitPoint;
 
 class WebKitNamespace;
 class WebKitPoint;
 
+#if ENABLE(DEVICE_ORIENTATION)
+class DeviceMotionController;
+class DeviceOrientationController;
+#endif
+
 struct ImageBitmapOptions;
 struct WindowFeatures;
 
 struct ImageBitmapOptions;
 struct WindowFeatures;
 
@@ -311,6 +316,19 @@ public:
     unsigned scrollEventListenerCount() const { return m_scrollEventListenerCount; }
 #endif
 
     unsigned scrollEventListenerCount() const { return m_scrollEventListenerCount; }
 #endif
 
+#if ENABLE(DEVICE_ORIENTATION)
+    void startListeningForDeviceOrientationIfNecessary();
+    void stopListeningForDeviceOrientationIfNecessary();
+    void startListeningForDeviceMotionIfNecessary();
+    void stopListeningForDeviceMotionIfNecessary();
+
+    bool isAllowedToUseDeviceMotionOrientation(String& message) const;
+    bool isAllowedToAddDeviceMotionOrientationListener(String& message) const;
+
+    DeviceOrientationController* deviceOrientationController() const;
+    DeviceMotionController* deviceMotionController() const;
+#endif
+
     void resetAllGeolocationPermission();
 
 #if ENABLE(IOS_TOUCH_EVENTS) || ENABLE(IOS_GESTURE_EVENTS)
     void resetAllGeolocationPermission();
 
 #if ENABLE(IOS_TOUCH_EVENTS) || ENABLE(IOS_GESTURE_EVENTS)
index 3367d3d..842b854 100644 (file)
@@ -69,6 +69,11 @@ void DeviceController::removeAllDeviceEventListeners(DOMWindow& window)
         m_client.stopUpdating();
 }
 
         m_client.stopUpdating();
 }
 
+bool DeviceController::hasDeviceEventListener(DOMWindow& window) const
+{
+    return m_listeners.contains(&window);
+}
+
 void DeviceController::dispatchDeviceEvent(Event& event)
 {
     for (auto& listener : copyToVector(m_listeners.values())) {
 void DeviceController::dispatchDeviceEvent(Event& event)
 {
     for (auto& listener : copyToVector(m_listeners.values())) {
index e160385..3d5f90c 100644 (file)
@@ -46,6 +46,7 @@ public:
     void addDeviceEventListener(DOMWindow&);
     void removeDeviceEventListener(DOMWindow&);
     void removeAllDeviceEventListeners(DOMWindow&);
     void addDeviceEventListener(DOMWindow&);
     void removeDeviceEventListener(DOMWindow&);
     void removeAllDeviceEventListeners(DOMWindow&);
+    bool hasDeviceEventListener(DOMWindow&) const;
 
     void dispatchDeviceEvent(Event&);
     bool isActive() { return !m_listeners.isEmpty(); }
 
     void dispatchDeviceEvent(Event&);
     bool isActive() { return !m_listeners.isEmpty(); }
index 58d93c9..bf83eeb 100644 (file)
@@ -767,6 +767,11 @@ deviceOrientationEventEnabled:
   initial: true
   conditional: DEVICE_ORIENTATION
 
   initial: true
   conditional: DEVICE_ORIENTATION
 
+deviceOrientationPermissionAPIEnabled:
+  type: bool
+  initial: false
+  conditional: DEVICE_ORIENTATION
+
 shouldEnableTextAutosizingBoost:
   type: bool
   initial: false
 shouldEnableTextAutosizingBoost:
   type: bool
   initial: false
index bef18c5..9272563 100644 (file)
@@ -1,3 +1,42 @@
+2019-03-08  Chris Dumez  <cdumez@apple.com>
+
+        Add support for Device Orientation / Motion permission API
+        https://bugs.webkit.org/show_bug.cgi?id=195329
+        <rdar://problem/47645367>
+
+        Reviewed by Geoffrey Garen.
+
+        Add support for Device Orientation / Motion permission API:
+        - https://github.com/w3c/deviceorientation/issues/57
+
+        This adds new SPI to WKUIDelegatePrivate, until we can make this API.
+
+        * Shared/WebPreferences.yaml:
+        * UIProcess/API/APIUIClient.h:
+        (API::UIClient::shouldAllowDeviceOrientationAndMotionAccess):
+        * UIProcess/API/C/WKPage.cpp:
+        (WKPageSetPageUIClient):
+        * UIProcess/API/C/WKPageUIClient.h:
+        * UIProcess/API/Cocoa/WKUIDelegate.h:
+        * UIProcess/API/Cocoa/WKUIDelegatePrivate.h:
+        * UIProcess/Cocoa/UIDelegate.h:
+        * UIProcess/Cocoa/UIDelegate.mm:
+        (WebKit::UIDelegate::setDelegate):
+        (WebKit::UIDelegate::UIClient::shouldAllowDeviceOrientationAndMotionAccess):
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::requestDeviceOrientationAndMotionAccess):
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/WebPageProxy.messages.in:
+        * WebProcess/WebCoreSupport/WebChromeClient.cpp:
+        (WebKit::WebChromeClient::shouldAllowDeviceOrientationAndMotionAccess):
+        * WebProcess/WebCoreSupport/WebChromeClient.h:
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::nextDeviceOrientationAndMotionPermissionCallbackID):
+        (WebKit::WebPage::shouldAllowDeviceOrientationAndMotionAccess):
+        (WebKit::WebPage::didReceiveDeviceOrientationAndMotionAccessDecision):
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/WebPage.messages.in:
+
 2019-03-08  Brady Eidson  <beidson@apple.com>
 
         Have the UIProcess take the UnboundedNetworking assertion when downloads are in progress.
 2019-03-08  Brady Eidson  <beidson@apple.com>
 
         Have the UIProcess take the UnboundedNetworking assertion when downloads are in progress.
index 4e981f8..66b4bc6 100644 (file)
@@ -12,6 +12,15 @@ DeviceOrientationEventEnabled:
   condition: ENABLE(DEVICE_ORIENTATION)
   webcoreName: deviceOrientationEventEnabled
 
   condition: ENABLE(DEVICE_ORIENTATION)
   webcoreName: deviceOrientationEventEnabled
 
+DeviceOrientationPermissionAPIEnabled:
+  type: bool
+  defaultValue: defaultDeviceOrientationPermissionAPIEnabled()
+  condition: ENABLE(DEVICE_ORIENTATION)
+  webcoreName: deviceOrientationPermissionAPIEnabled
+  humanReadableName: "Permission API for device orientation / motion access."
+  humanReadableDescription: "DeviceOrientationEvent.requestPermission() / DeviceMotionEvent.requestPermission()"
+  category: experimental
+
 JavaScriptEnabled:
   type: bool
   defaultValue: true
 JavaScriptEnabled:
   type: bool
   defaultValue: true
index fa18251..cbf7d09 100644 (file)
@@ -44,6 +44,15 @@ bool defaultPassiveTouchListenersAsDefaultOnDocument()
 #endif
 }
 
 #endif
 }
 
+bool defaultDeviceOrientationPermissionAPIEnabled()
+{
+#if PLATFORM(IOS) && ENABLE(DEVICE_ORIENTATION)
+    return linkedOnOrAfter(WebKit::SDKVersion::FirstWithDeviceOrientationAndMotionPermissionAPI);
+#else
+    return false;
+#endif
+}
+
 bool defaultCustomPasteboardDataEnabled()
 {
 #if PLATFORM(IOSMAC)
 bool defaultCustomPasteboardDataEnabled()
 {
 #if PLATFORM(IOSMAC)
index 6e82173..84d2210 100644 (file)
 #endif
 
 bool defaultPassiveTouchListenersAsDefaultOnDocument();
 #endif
 
 bool defaultPassiveTouchListenersAsDefaultOnDocument();
+bool defaultDeviceOrientationPermissionAPIEnabled();
 bool defaultCustomPasteboardDataEnabled();
 
 #if PLATFORM(MAC)
 bool defaultCustomPasteboardDataEnabled();
 
 #if PLATFORM(MAC)
index 3ec6f00..940b697 100644 (file)
@@ -173,6 +173,10 @@ public:
     virtual void didLosePointerLock(WebKit::WebPageProxy*) { }
 #endif
 
     virtual void didLosePointerLock(WebKit::WebPageProxy*) { }
 #endif
 
+#if ENABLE(DEVICE_ORIENTATION)
+    virtual void shouldAllowDeviceOrientationAndMotionAccess(WebKit::WebPageProxy&, SecurityOrigin&, CompletionHandler<void(bool)>&& completionHandler) { completionHandler(true); }
+#endif
+
     virtual void didClickAutoFillButton(WebKit::WebPageProxy&, Object*) { }
 
     virtual void didResignInputElementStrongPasswordAppearance(WebKit::WebPageProxy&, Object*) { }
     virtual void didClickAutoFillButton(WebKit::WebPageProxy&, Object*) { }
 
     virtual void didResignInputElementStrongPasswordAppearance(WebKit::WebPageProxy&, Object*) { }
index a416766..38e5b17 100644 (file)
@@ -115,7 +115,7 @@ template<> struct ClientTraits<WKPagePolicyClientBase> {
 };
 
 template<> struct ClientTraits<WKPageUIClientBase> {
 };
 
 template<> struct ClientTraits<WKPageUIClientBase> {
-    typedef std::tuple<WKPageUIClientV0, WKPageUIClientV1, WKPageUIClientV2, WKPageUIClientV3, WKPageUIClientV4, WKPageUIClientV5, WKPageUIClientV6, WKPageUIClientV7, WKPageUIClientV8, WKPageUIClientV9, WKPageUIClientV10, WKPageUIClientV11, WKPageUIClientV12> Versions;
+    typedef std::tuple<WKPageUIClientV0, WKPageUIClientV1, WKPageUIClientV2, WKPageUIClientV3, WKPageUIClientV4, WKPageUIClientV5, WKPageUIClientV6, WKPageUIClientV7, WKPageUIClientV8, WKPageUIClientV9, WKPageUIClientV10, WKPageUIClientV11, WKPageUIClientV12, WKPageUIClientV13> Versions;
 };
 
 #if ENABLE(CONTEXT_MENUS)
 };
 
 #if ENABLE(CONTEXT_MENUS)
@@ -1903,6 +1903,16 @@ void WKPageSetPageUIClient(WKPageRef pageRef, const WKPageUIClientBase* wkClient
             m_client.requestStorageAccessConfirm(toAPI(&page), toAPI(frame), toAPI(requestingDomain.impl()), toAPI(currentDomain.impl()), toAPI(listener.ptr()), m_client.base.clientInfo);
         }
 
             m_client.requestStorageAccessConfirm(toAPI(&page), toAPI(frame), toAPI(requestingDomain.impl()), toAPI(currentDomain.impl()), toAPI(listener.ptr()), m_client.base.clientInfo);
         }
 
+#if ENABLE(DEVICE_ORIENTATION)
+        void shouldAllowDeviceOrientationAndMotionAccess(WebPageProxy& page, API::SecurityOrigin& origin, CompletionHandler<void(bool)>&& completionHandler) final
+        {
+            if (!m_client.shouldAllowDeviceOrientationAndMotionAccess)
+                return completionHandler(true);
+
+            completionHandler(m_client.shouldAllowDeviceOrientationAndMotionAccess(toAPI(&page), toAPI(&origin), m_client.base.clientInfo));
+        }
+#endif
+
         // Printing.
         float headerHeight(WebPageProxy& page, WebFrameProxy& frame) final
         {
         // Printing.
         float headerHeight(WebPageProxy& page, WebFrameProxy& frame) final
         {
index 5e5973f..ea88727 100644 (file)
@@ -134,6 +134,7 @@ typedef void (*WKDidLosePointerLockCallback)(WKPageRef page, const void* clientI
 typedef void (*WKHasVideoInPictureInPictureDidChangeCallback)(WKPageRef page, bool hasVideoInPictureInPicture, const void* clientInfo);
 typedef void (*WKDidExceedBackgroundResourceLimitWhileInForegroundCallback)(WKPageRef page, WKResourceLimit limit, const void* clientInfo);
 typedef void (*WKPageDidResignInputElementStrongPasswordAppearanceCallback)(WKPageRef page, WKTypeRef userData, const void *clientInfo);
 typedef void (*WKHasVideoInPictureInPictureDidChangeCallback)(WKPageRef page, bool hasVideoInPictureInPicture, const void* clientInfo);
 typedef void (*WKDidExceedBackgroundResourceLimitWhileInForegroundCallback)(WKPageRef page, WKResourceLimit limit, const void* clientInfo);
 typedef void (*WKPageDidResignInputElementStrongPasswordAppearanceCallback)(WKPageRef page, WKTypeRef userData, const void *clientInfo);
+typedef bool (*WKPageShouldAllowDeviceOrientationAndMotionAccessCallback)(WKPageRef page, WKSecurityOriginRef securityOrigin, const void *clientInfo);
 
 // Deprecated
 typedef WKPageRef (*WKPageCreateNewPageCallback_deprecatedForUseWithV0)(WKPageRef page, WKDictionaryRef features, WKEventModifiers modifiers, WKEventMouseButton mouseButton, const void *clientInfo);
 
 // Deprecated
 typedef WKPageRef (*WKPageCreateNewPageCallback_deprecatedForUseWithV0)(WKPageRef page, WKDictionaryRef features, WKEventModifiers modifiers, WKEventMouseButton mouseButton, const void *clientInfo);
@@ -1140,6 +1141,110 @@ typedef struct WKPageUIClientV12 {
     WKPageRequestStorageAccessConfirmCallback                           requestStorageAccessConfirm;
 } WKPageUIClientV12;
 
     WKPageRequestStorageAccessConfirmCallback                           requestStorageAccessConfirm;
 } WKPageUIClientV12;
 
+typedef struct WKPageUIClientV13 {
+    WKPageUIClientBase                                                  base;
+
+    // Version 0.
+    WKPageCreateNewPageCallback_deprecatedForUseWithV0                  createNewPage_deprecatedForUseWithV0;
+    WKPageUIClientCallback                                              showPage;
+    WKPageUIClientCallback                                              close;
+    WKPageTakeFocusCallback                                             takeFocus;
+    WKPageFocusCallback                                                 focus;
+    WKPageUnfocusCallback                                               unfocus;
+    WKPageRunJavaScriptAlertCallback_deprecatedForUseWithV0             runJavaScriptAlert_deprecatedForUseWithV0;
+    WKPageRunJavaScriptConfirmCallback_deprecatedForUseWithV0           runJavaScriptConfirm_deprecatedForUseWithV0;
+    WKPageRunJavaScriptPromptCallback_deprecatedForUseWithV0            runJavaScriptPrompt_deprecatedForUseWithV0;
+    WKPageSetStatusTextCallback                                         setStatusText;
+    WKPageMouseDidMoveOverElementCallback_deprecatedForUseWithV0        mouseDidMoveOverElement_deprecatedForUseWithV0;
+    WKPageMissingPluginButtonClickedCallback_deprecatedForUseWithV0     missingPluginButtonClicked_deprecatedForUseWithV0;
+    WKPageDidNotHandleKeyEventCallback                                  didNotHandleKeyEvent;
+    WKPageDidNotHandleWheelEventCallback                                didNotHandleWheelEvent;
+    WKPageGetToolbarsAreVisibleCallback                                 toolbarsAreVisible;
+    WKPageSetToolbarsAreVisibleCallback                                 setToolbarsAreVisible;
+    WKPageGetMenuBarIsVisibleCallback                                   menuBarIsVisible;
+    WKPageSetMenuBarIsVisibleCallback                                   setMenuBarIsVisible;
+    WKPageGetStatusBarIsVisibleCallback                                 statusBarIsVisible;
+    WKPageSetStatusBarIsVisibleCallback                                 setStatusBarIsVisible;
+    WKPageGetIsResizableCallback                                        isResizable;
+    WKPageSetIsResizableCallback                                        setIsResizable;
+    WKPageGetWindowFrameCallback                                        getWindowFrame;
+    WKPageSetWindowFrameCallback                                        setWindowFrame;
+    WKPageRunBeforeUnloadConfirmPanelCallback_deprecatedForUseWithV6    runBeforeUnloadConfirmPanel_deprecatedForUseWithV6;
+    WKPageUIClientCallback                                              didDraw;
+    WKPageUIClientCallback                                              pageDidScroll;
+    WKPageExceededDatabaseQuotaCallback                                 exceededDatabaseQuota;
+    WKPageRunOpenPanelCallback                                          runOpenPanel;
+    WKPageDecidePolicyForGeolocationPermissionRequestCallback           decidePolicyForGeolocationPermissionRequest;
+    WKPageHeaderHeightCallback                                          headerHeight;
+    WKPageFooterHeightCallback                                          footerHeight;
+    WKPageDrawHeaderCallback                                            drawHeader;
+    WKPageDrawFooterCallback                                            drawFooter;
+    WKPagePrintFrameCallback                                            printFrame;
+    WKPageUIClientCallback                                              runModal;
+    void*                                                               unused1; // Used to be didCompleteRubberBandForMainFrame
+    WKPageSaveDataToFileInDownloadsFolderCallback                       saveDataToFileInDownloadsFolder;
+    void*                                                               shouldInterruptJavaScript_unavailable;
+
+    // Version 1.
+    WKPageCreateNewPageCallback_deprecatedForUseWithV1                  createNewPage_deprecatedForUseWithV1;
+    WKPageMouseDidMoveOverElementCallback                               mouseDidMoveOverElement;
+    WKPageDecidePolicyForNotificationPermissionRequestCallback          decidePolicyForNotificationPermissionRequest;
+    WKPageUnavailablePluginButtonClickedCallback_deprecatedForUseWithV1 unavailablePluginButtonClicked_deprecatedForUseWithV1;
+
+    // Version 2.
+    WKPageShowColorPickerCallback                                       showColorPicker;
+    WKPageHideColorPickerCallback                                       hideColorPicker;
+    WKPageUnavailablePluginButtonClickedCallback                        unavailablePluginButtonClicked;
+
+    // Version 3.
+    WKPagePinnedStateDidChangeCallback                                  pinnedStateDidChange;
+
+    // Version 4.
+    void*                                                               unused2; // Used to be didBeginTrackingPotentialLongMousePress.
+    void*                                                               unused3; // Used to be didRecognizeLongMousePress.
+    void*                                                               unused4; // Used to be didCancelTrackingPotentialLongMousePress.
+    WKPageIsPlayingAudioDidChangeCallback                               isPlayingAudioDidChange;
+
+    // Version 5.
+    WKPageDecidePolicyForUserMediaPermissionRequestCallback             decidePolicyForUserMediaPermissionRequest;
+    WKPageDidClickAutoFillButtonCallback                                didClickAutoFillButton;
+    WKPageRunJavaScriptAlertCallback_deprecatedForUseWithV5             runJavaScriptAlert_deprecatedForUseWithV5;
+    WKPageRunJavaScriptConfirmCallback_deprecatedForUseWithV5           runJavaScriptConfirm_deprecatedForUseWithV5;
+    WKPageRunJavaScriptPromptCallback_deprecatedForUseWithV5            runJavaScriptPrompt_deprecatedForUseWithV5;
+    WKPageMediaSessionMetadataDidChangeCallback                         mediaSessionMetadataDidChange;
+
+    // Version 6.
+    WKPageCreateNewPageCallback                                         createNewPage;
+    WKPageRunJavaScriptAlertCallback                                    runJavaScriptAlert;
+    WKPageRunJavaScriptConfirmCallback                                  runJavaScriptConfirm;
+    WKPageRunJavaScriptPromptCallback                                   runJavaScriptPrompt;
+    WKCheckUserMediaPermissionCallback                                  checkUserMediaPermissionForOrigin;
+
+    // Version 7.
+    WKPageRunBeforeUnloadConfirmPanelCallback                           runBeforeUnloadConfirmPanel;
+    WKFullscreenMayReturnToInlineCallback                               fullscreenMayReturnToInline;
+
+    // Version 8.
+    WKRequestPointerLockCallback                                        requestPointerLock;
+    WKDidLosePointerLockCallback                                        didLosePointerLock;
+
+    // Version 9.
+    WKHandleAutoplayEventCallback                                       handleAutoplayEvent;
+
+    // Version 10.
+    WKHasVideoInPictureInPictureDidChangeCallback                       hasVideoInPictureInPictureDidChange;
+    WKDidExceedBackgroundResourceLimitWhileInForegroundCallback         didExceedBackgroundResourceLimitWhileInForeground;
+
+    // Version 11.
+    WKPageDidResignInputElementStrongPasswordAppearanceCallback         didResignInputElementStrongPasswordAppearance;
+
+    // Version 12.
+    WKPageRequestStorageAccessConfirmCallback                           requestStorageAccessConfirm;
+
+    // Version 13.
+    WKPageShouldAllowDeviceOrientationAndMotionAccessCallback           shouldAllowDeviceOrientationAndMotionAccess;
+} WKPageUIClientV13;
+
 #ifdef __cplusplus
 }
 #endif
 #ifdef __cplusplus
 }
 #endif
index da0314a..815e801 100644 (file)
@@ -34,6 +34,7 @@ NS_ASSUME_NONNULL_BEGIN
 @class WKNavigationAction;
 @class WKOpenPanelParameters;
 @class WKPreviewElementInfo;
 @class WKNavigationAction;
 @class WKOpenPanelParameters;
 @class WKPreviewElementInfo;
+@class WKSecurityOrigin;
 @class WKWebView;
 @class WKWebViewConfiguration;
 @class WKWindowFeatures;
 @class WKWebView;
 @class WKWebViewConfiguration;
 @class WKWindowFeatures;
index dbd053e..3d77716 100644 (file)
@@ -171,6 +171,15 @@ struct UIEdgeInsets;
 - (void)_webView:(WKWebView *)webView didChangeSafeAreaShouldAffectObscuredInsets:(BOOL)safeAreaShouldAffectObscuredInsets WK_API_AVAILABLE(ios(11.0));
 - (void)_webView:(WKWebView *)webView didPresentFocusedElementViewController:(UIViewController *)controller WK_API_AVAILABLE(ios(12.0));
 - (void)_webView:(WKWebView *)webView didDismissFocusedElementViewController:(UIViewController *)controller WK_API_AVAILABLE(ios(12.0));
 - (void)_webView:(WKWebView *)webView didChangeSafeAreaShouldAffectObscuredInsets:(BOOL)safeAreaShouldAffectObscuredInsets WK_API_AVAILABLE(ios(11.0));
 - (void)_webView:(WKWebView *)webView didPresentFocusedElementViewController:(UIViewController *)controller WK_API_AVAILABLE(ios(12.0));
 - (void)_webView:(WKWebView *)webView didDismissFocusedElementViewController:(UIViewController *)controller WK_API_AVAILABLE(ios(12.0));
+
+/*! @abstract Allows your app to determine whether or not the given security origin should have access to the device's orientation and motion.
+ @param securityOrigin The security origin which requested access to the device's orientation and motion.
+ @param decisionHandler The decision handler to call once the app has made its decision. Pass YES to allow the origin access, NO otherwise.
+
+ If you do not implement this method, access to the device's orientation and motion will be granted.
+ */
+- (void)_webView:(WKWebView *)webView shouldAllowDeviceOrientationAndMotionAccessForSecurityOrigin:(WKSecurityOrigin *)securityOrigin decisionHandler:(void (^)(BOOL))decisionHandler WK_API_AVAILABLE(ios(WK_IOS_TBA));
+
 #else // TARGET_OS_IPHONE
 - (void)_prepareForImmediateActionAnimationForWebView:(WKWebView *)webView WK_API_AVAILABLE(macosx(10.13.4));
 - (void)_cancelImmediateActionAnimationForWebView:(WKWebView *)webView WK_API_AVAILABLE(macosx(10.13.4));
 #else // TARGET_OS_IPHONE
 - (void)_prepareForImmediateActionAnimationForWebView:(WKWebView *)webView WK_API_AVAILABLE(macosx(10.13.4));
 - (void)_cancelImmediateActionAnimationForWebView:(WKWebView *)webView WK_API_AVAILABLE(macosx(10.13.4));
index ccb78a2..63f55c4 100644 (file)
@@ -120,6 +120,9 @@ private:
         void didExceedBackgroundResourceLimitWhileInForeground(WebPageProxy&, WKResourceLimit) final;
         void saveDataToFileInDownloadsFolder(WebPageProxy*, const WTF::String&, const WTF::String&, const URL&, API::Data&) final;
 #endif
         void didExceedBackgroundResourceLimitWhileInForeground(WebPageProxy&, WKResourceLimit) final;
         void saveDataToFileInDownloadsFolder(WebPageProxy*, const WTF::String&, const WTF::String&, const URL&, API::Data&) final;
 #endif
+#if ENABLE(DEVICE_ORIENTATION)
+        void shouldAllowDeviceOrientationAndMotionAccess(WebKit::WebPageProxy&, API::SecurityOrigin&, CompletionHandler<void(bool)>&&) final;
+#endif
         bool needsFontAttributes() const final { return m_uiDelegate.m_delegateMethods.webViewDidChangeFontAttributes; }
         void didChangeFontAttributes(const WebCore::FontAttributes&) final;
         void decidePolicyForUserMediaPermissionRequest(WebPageProxy&, WebFrameProxy&, API::SecurityOrigin&, API::SecurityOrigin&, UserMediaPermissionRequestProxy&) final;
         bool needsFontAttributes() const final { return m_uiDelegate.m_delegateMethods.webViewDidChangeFontAttributes; }
         void didChangeFontAttributes(const WebCore::FontAttributes&) final;
         void decidePolicyForUserMediaPermissionRequest(WebPageProxy&, WebFrameProxy&, API::SecurityOrigin&, API::SecurityOrigin&, UserMediaPermissionRequestProxy&) final;
@@ -188,6 +191,9 @@ private:
         bool webViewRunOpenPanelWithParametersInitiatedByFrameCompletionHandler : 1;
         bool webViewRequestNotificationPermissionForSecurityOriginDecisionHandler : 1;
 #endif
         bool webViewRunOpenPanelWithParametersInitiatedByFrameCompletionHandler : 1;
         bool webViewRequestNotificationPermissionForSecurityOriginDecisionHandler : 1;
 #endif
+#if ENABLE(DEVICE_ORIENTATION)
+        bool webViewShouldAllowDeviceOrientationAndMotionAccessForSecurityOriginDecisionHandler : 1;
+#endif
         bool webViewDecideDatabaseQuotaForSecurityOriginCurrentQuotaCurrentOriginUsageCurrentDatabaseUsageExpectedUsageDecisionHandler : 1;
         bool webViewDecideDatabaseQuotaForSecurityOriginDatabaseNameDisplayNameCurrentQuotaCurrentOriginUsageCurrentDatabaseUsageExpectedUsageDecisionHandler : 1;
         bool webViewDecideWebApplicationCacheQuotaForSecurityOriginCurrentQuotaTotalBytesNeeded : 1;
         bool webViewDecideDatabaseQuotaForSecurityOriginCurrentQuotaCurrentOriginUsageCurrentDatabaseUsageExpectedUsageDecisionHandler : 1;
         bool webViewDecideDatabaseQuotaForSecurityOriginDatabaseNameDisplayNameCurrentQuotaCurrentOriginUsageCurrentDatabaseUsageExpectedUsageDecisionHandler : 1;
         bool webViewDecideWebApplicationCacheQuotaForSecurityOriginCurrentQuotaTotalBytesNeeded : 1;
index b5a0a50..9260725 100644 (file)
@@ -133,6 +133,9 @@ void UIDelegate::setDelegate(id <WKUIDelegate> delegate)
     m_delegateMethods.webViewRunOpenPanelWithParametersInitiatedByFrameCompletionHandler = [delegate respondsToSelector:@selector(webView:runOpenPanelWithParameters:initiatedByFrame:completionHandler:)];
     m_delegateMethods.webViewRequestNotificationPermissionForSecurityOriginDecisionHandler = [delegate respondsToSelector:@selector(_webView:requestNotificationPermissionForSecurityOrigin:decisionHandler:)];
 #endif
     m_delegateMethods.webViewRunOpenPanelWithParametersInitiatedByFrameCompletionHandler = [delegate respondsToSelector:@selector(webView:runOpenPanelWithParameters:initiatedByFrame:completionHandler:)];
     m_delegateMethods.webViewRequestNotificationPermissionForSecurityOriginDecisionHandler = [delegate respondsToSelector:@selector(_webView:requestNotificationPermissionForSecurityOrigin:decisionHandler:)];
 #endif
+#if ENABLE(DEVICE_ORIENTATION)
+    m_delegateMethods.webViewShouldAllowDeviceOrientationAndMotionAccessForSecurityOriginDecisionHandler = [delegate respondsToSelector:@selector(_webView:shouldAllowDeviceOrientationAndMotionAccessForSecurityOrigin:decisionHandler:)];
+#endif
     m_delegateMethods.webViewDecideDatabaseQuotaForSecurityOriginCurrentQuotaCurrentOriginUsageCurrentDatabaseUsageExpectedUsageDecisionHandler = [delegate respondsToSelector:@selector(_webView:decideDatabaseQuotaForSecurityOrigin:currentQuota:currentOriginUsage:currentDatabaseUsage:expectedUsage:decisionHandler:)];
     m_delegateMethods.webViewDecideDatabaseQuotaForSecurityOriginDatabaseNameDisplayNameCurrentQuotaCurrentOriginUsageCurrentDatabaseUsageExpectedUsageDecisionHandler = [delegate respondsToSelector:@selector(_webView:decideDatabaseQuotaForSecurityOrigin:databaseName:displayName:currentQuota:currentOriginUsage:currentDatabaseUsage:expectedUsage:decisionHandler:)];
     m_delegateMethods.webViewDecideWebApplicationCacheQuotaForSecurityOriginCurrentQuotaTotalBytesNeeded = [delegate respondsToSelector:@selector(_webView:decideWebApplicationCacheQuotaForSecurityOrigin:currentQuota:totalBytesNeeded:decisionHandler:)];
     m_delegateMethods.webViewDecideDatabaseQuotaForSecurityOriginCurrentQuotaCurrentOriginUsageCurrentDatabaseUsageExpectedUsageDecisionHandler = [delegate respondsToSelector:@selector(_webView:decideDatabaseQuotaForSecurityOrigin:currentQuota:currentOriginUsage:currentDatabaseUsage:expectedUsage:decisionHandler:)];
     m_delegateMethods.webViewDecideDatabaseQuotaForSecurityOriginDatabaseNameDisplayNameCurrentQuotaCurrentOriginUsageCurrentDatabaseUsageExpectedUsageDecisionHandler = [delegate respondsToSelector:@selector(_webView:decideDatabaseQuotaForSecurityOrigin:databaseName:displayName:currentQuota:currentOriginUsage:currentDatabaseUsage:expectedUsage:decisionHandler:)];
     m_delegateMethods.webViewDecideWebApplicationCacheQuotaForSecurityOriginCurrentQuotaTotalBytesNeeded = [delegate respondsToSelector:@selector(_webView:decideWebApplicationCacheQuotaForSecurityOrigin:currentQuota:totalBytesNeeded:decisionHandler:)];
@@ -844,6 +847,26 @@ bool UIDelegate::UIClient::runOpenPanel(WebPageProxy*, WebFrameProxy* webFramePr
 }
 #endif
 
 }
 #endif
 
+#if ENABLE(DEVICE_ORIENTATION)
+void UIDelegate::UIClient::shouldAllowDeviceOrientationAndMotionAccess(WebKit::WebPageProxy&, API::SecurityOrigin& securityOrigin, CompletionHandler<void(bool)>&& completionHandler)
+{
+    if (!m_uiDelegate.m_delegateMethods.webViewShouldAllowDeviceOrientationAndMotionAccessForSecurityOriginDecisionHandler)
+        return completionHandler(true);
+
+    auto delegate = m_uiDelegate.m_delegate.get();
+    if (!delegate)
+        return completionHandler(true);
+
+    auto checker = CompletionHandlerCallChecker::create(delegate.get(), @selector(_webView:shouldAllowDeviceOrientationAndMotionAccessForSecurityOrigin:decisionHandler:));
+    [(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate.m_webView shouldAllowDeviceOrientationAndMotionAccessForSecurityOrigin:wrapper(securityOrigin) decisionHandler:makeBlockPtr([completionHandler = WTFMove(completionHandler), checker = WTFMove(checker)] (BOOL granted) mutable {
+        if (checker->completionHandlerHasBeenCalled())
+            return;
+        checker->didCallCompletionHandler();
+        completionHandler(granted);
+    }).get()];
+}
+#endif
+
 void UIDelegate::UIClient::didChangeFontAttributes(const WebCore::FontAttributes& fontAttributes)
 {
     if (!needsFontAttributes())
 void UIDelegate::UIClient::didChangeFontAttributes(const WebCore::FontAttributes& fontAttributes)
 {
     if (!needsFontAttributes())
index ed1668c..3b350be 100644 (file)
 #define DYLD_MACOS_VERSION_FIRST_WHERE_DOWNLOAD_ATTRIBUTE_DOES_NOT_OVERRIDE_NAVIGATION_DELEGATE 0
 #endif
 
 #define DYLD_MACOS_VERSION_FIRST_WHERE_DOWNLOAD_ATTRIBUTE_DOES_NOT_OVERRIDE_NAVIGATION_DELEGATE 0
 #endif
 
+#ifndef DYLD_IOS_VERSION_FIRST_WITH_DEVICE_ORIENTATION_AND_MOTION_PERMISSION_API
+#define DYLD_IOS_VERSION_FIRST_WITH_DEVICE_ORIENTATION_AND_MOTION_PERMISSION_API 0
+#endif
+
 namespace WebKit {
 
 enum class SDKVersion : uint32_t {
 namespace WebKit {
 
 enum class SDKVersion : uint32_t {
@@ -56,6 +60,7 @@ enum class SDKVersion : uint32_t {
     FirstWithProcessSwapOnCrossSiteNavigation = DYLD_IOS_VERSION_FIRST_WITH_PROCESS_SWAP_ON_CROSS_SITE_NAVIGATION,
     FirstWithSnapshotAfterScreenUpdates = DYLD_IOS_VERSION_FIRST_WITH_SNAPSHOT_AFTER_SCREEN_UPDATES,
     FirstWhereDownloadAttributeDoesNotOverrideNavigationDelegate = DYLD_IOS_VERSION_FIRST_WHERE_DOWNLOAD_ATTRIBUTE_DOES_NOT_OVERRIDE_NAVIGATION_DELEGATE,
     FirstWithProcessSwapOnCrossSiteNavigation = DYLD_IOS_VERSION_FIRST_WITH_PROCESS_SWAP_ON_CROSS_SITE_NAVIGATION,
     FirstWithSnapshotAfterScreenUpdates = DYLD_IOS_VERSION_FIRST_WITH_SNAPSHOT_AFTER_SCREEN_UPDATES,
     FirstWhereDownloadAttributeDoesNotOverrideNavigationDelegate = DYLD_IOS_VERSION_FIRST_WHERE_DOWNLOAD_ATTRIBUTE_DOES_NOT_OVERRIDE_NAVIGATION_DELEGATE,
+    FirstWithDeviceOrientationAndMotionPermissionAPI = DYLD_IOS_VERSION_FIRST_WITH_DEVICE_ORIENTATION_AND_MOTION_PERMISSION_API,
 #elif PLATFORM(MAC)
     FirstWithNetworkCache = DYLD_MACOSX_VERSION_10_11,
     FirstWithExceptionsForDuplicateCompletionHandlerCalls = DYLD_MACOSX_VERSION_10_13,
 #elif PLATFORM(MAC)
     FirstWithNetworkCache = DYLD_MACOSX_VERSION_10_11,
     FirstWithExceptionsForDuplicateCompletionHandlerCalls = DYLD_MACOSX_VERSION_10_13,
index 4bafd30..de136c0 100644 (file)
@@ -7174,6 +7174,18 @@ void WebPageProxy::clearUserMediaState()
 #endif
 }
 
 #endif
 }
 
+#if ENABLE(DEVICE_ORIENTATION)
+void WebPageProxy::requestDeviceOrientationAndMotionAccess(WebCore::SecurityOriginData&& originData, uint64_t callbackID)
+{
+    auto origin = API::SecurityOrigin::create(originData.securityOrigin());
+    m_uiClient->shouldAllowDeviceOrientationAndMotionAccess(*this, origin.get(), [this, weakThis = makeWeakPtr(*this), callbackID](bool granted) {
+        if (!weakThis || !isValid())
+            return;
+        m_process->send(Messages::WebPage::DidReceiveDeviceOrientationAndMotionAccessDecision(callbackID, granted), m_pageID);
+    });
+}
+#endif
+
 void WebPageProxy::requestNotificationPermission(uint64_t requestID, const String& originString)
 {
     if (!isRequestIDValid(requestID))
 void WebPageProxy::requestNotificationPermission(uint64_t requestID, const String& originString)
 {
     if (!isRequestIDValid(requestID))
index d210859..a802b10 100644 (file)
@@ -1401,6 +1401,10 @@ public:
     void requestStorageAccessConfirm(const WebCore::RegistrableDomain& subFrameDomain, const WebCore::RegistrableDomain& topFrameDomain, uint64_t frameID, CompletionHandler<void(bool)>&&);
 #endif
 
     void requestStorageAccessConfirm(const WebCore::RegistrableDomain& subFrameDomain, const WebCore::RegistrableDomain& topFrameDomain, uint64_t frameID, CompletionHandler<void(bool)>&&);
 #endif
 
+#if ENABLE(DEVICE_ORIENTATION)
+    void requestDeviceOrientationAndMotionAccess(WebCore::SecurityOriginData&&, uint64_t callbackID);
+#endif
+
     static WebPageProxy* nonEphemeralWebPageProxy();
 
 #if ENABLE(ATTACHMENT_ELEMENT)
     static WebPageProxy* nonEphemeralWebPageProxy();
 
 #if ENABLE(ATTACHMENT_ELEMENT)
index afa1d67..0b12e2b 100644 (file)
@@ -533,6 +533,10 @@ messages -> WebPageProxy {
     StopURLSchemeTask(uint64_t handlerIdentifier, uint64_t taskIdentifier)
     LoadSynchronousURLSchemeTask(struct WebKit::URLSchemeTaskParameters parameters) -> (WebCore::ResourceResponse response, WebCore::ResourceError error, IPC::DataReference data) Delayed
 
     StopURLSchemeTask(uint64_t handlerIdentifier, uint64_t taskIdentifier)
     LoadSynchronousURLSchemeTask(struct WebKit::URLSchemeTaskParameters parameters) -> (WebCore::ResourceResponse response, WebCore::ResourceError error, IPC::DataReference data) Delayed
 
+#if ENABLE(DEVICE_ORIENTATION)
+    RequestDeviceOrientationAndMotionAccess(struct WebCore::SecurityOriginData origin, uint64_t callbackID);
+#endif
+
 #if ENABLE(ATTACHMENT_ELEMENT)
     RegisterAttachmentIdentifierFromData(String identifier, String contentType, String preferredFileName, IPC::SharedBufferDataReference data)
     RegisterAttachmentIdentifierFromFilePath(String identifier, String contentType, String filePath)
 #if ENABLE(ATTACHMENT_ELEMENT)
     RegisterAttachmentIdentifierFromData(String identifier, String contentType, String preferredFileName, IPC::SharedBufferDataReference data)
     RegisterAttachmentIdentifierFromFilePath(String identifier, String contentType, String filePath)
index 67fd7a7..62b5efb 100644 (file)
@@ -1320,4 +1320,11 @@ void WebChromeClient::requestStorageAccess(String&& subFrameHost, String&& topFr
 }
 #endif
 
 }
 #endif
 
+#if ENABLE(DEVICE_ORIENTATION)
+void WebChromeClient::shouldAllowDeviceOrientationAndMotionAccess(const SecurityOrigin& origin, CompletionHandler<void(bool)>&& callback)
+{
+    m_page.shouldAllowDeviceOrientationAndMotionAccess(origin, WTFMove(callback));
+}
+#endif
+
 } // namespace WebKit
 } // namespace WebKit
index f926a25..227b814 100644 (file)
@@ -366,6 +366,10 @@ private:
     void requestStorageAccess(String&& subFrameHost, String&& topFrameHost, uint64_t frameID, uint64_t pageID, WTF::CompletionHandler<void (bool)>&&) final;
 #endif
 
     void requestStorageAccess(String&& subFrameHost, String&& topFrameHost, uint64_t frameID, uint64_t pageID, WTF::CompletionHandler<void (bool)>&&) final;
 #endif
 
+#if ENABLE(DEVICE_ORIENTATION)
+    void shouldAllowDeviceOrientationAndMotionAccess(const WebCore::SecurityOrigin&, CompletionHandler<void(bool)>&&) final;
+#endif
+
     String m_cachedToolTip;
     mutable RefPtr<WebFrame> m_cachedFrameSetLargestFrame;
     mutable bool m_cachedMainFrameHasHorizontalScrollbar { false };
     String m_cachedToolTip;
     mutable RefPtr<WebFrame> m_cachedFrameSetLargestFrame;
     mutable bool m_cachedMainFrameHasHorizontalScrollbar { false };
index 785aa42..609e369 100644 (file)
@@ -6339,6 +6339,30 @@ void WebPage::requestStorageAccess(String&& subFrameHost, String&& topFrameHost,
     WebProcess::singleton().ensureNetworkProcessConnection().connection().sendWithAsyncReply(Messages::NetworkConnectionToWebProcess::RequestStorageAccess(sessionID(), RegistrableDomain::uncheckedCreateFromHost(subFrameHost), RegistrableDomain::uncheckedCreateFromHost(topFrameHost), frameID, m_pageID, promptEnabled), WTFMove(completionHandler));
 }
 #endif
     WebProcess::singleton().ensureNetworkProcessConnection().connection().sendWithAsyncReply(Messages::NetworkConnectionToWebProcess::RequestStorageAccess(sessionID(), RegistrableDomain::uncheckedCreateFromHost(subFrameHost), RegistrableDomain::uncheckedCreateFromHost(topFrameHost), frameID, m_pageID, promptEnabled), WTFMove(completionHandler));
 }
 #endif
+
+#if ENABLE(DEVICE_ORIENTATION)
+static uint64_t nextDeviceOrientationAndMotionPermissionCallbackID()
+{
+    static uint64_t nextCallbackID = 0;
+    return ++nextCallbackID;
+}
+
+void WebPage::shouldAllowDeviceOrientationAndMotionAccess(const WebCore::SecurityOrigin& origin, CompletionHandler<void(bool)>&& callback)
+{
+    auto callbackID = nextDeviceOrientationAndMotionPermissionCallbackID();
+    ASSERT(!m_deviceOrientationAndMotionPermissionCallbackMap.contains(callbackID));
+    m_deviceOrientationAndMotionPermissionCallbackMap.add(callbackID, WTFMove(callback));
+
+    send(Messages::WebPageProxy::RequestDeviceOrientationAndMotionAccess(origin.data(), callbackID));
+}
+
+void WebPage::didReceiveDeviceOrientationAndMotionAccessDecision(uint64_t callbackID, bool granted)
+{
+    auto callback = m_deviceOrientationAndMotionPermissionCallbackMap.take(callbackID);
+    ASSERT(callback);
+    callback(granted);
+}
+#endif
     
 static ShareSheetCallbackID nextShareSheetCallbackID()
 {
     
 static ShareSheetCallbackID nextShareSheetCallbackID()
 {
index 28e5679..25ef232 100644 (file)
@@ -1110,6 +1110,10 @@ public:
     void requestStorageAccess(String&& subFrameHost, String&& topFrameHost, uint64_t frameID, CompletionHandler<void(bool)>&& callback);
 #endif
 
     void requestStorageAccess(String&& subFrameHost, String&& topFrameHost, uint64_t frameID, CompletionHandler<void(bool)>&& callback);
 #endif
 
+#if ENABLE(DEVICE_ORIENTATION)
+    void shouldAllowDeviceOrientationAndMotionAccess(const WebCore::SecurityOrigin&, CompletionHandler<void(bool)>&&);
+#endif
+
     void showShareSheet(WebCore::ShareDataWithParsedURL&, WTF::CompletionHandler<void(bool)>&& callback);
     void didCompleteShareSheet(bool wasCompleted, ShareSheetCallbackID contextId);
     
     void showShareSheet(WebCore::ShareDataWithParsedURL&, WTF::CompletionHandler<void(bool)>&& callback);
     void didCompleteShareSheet(bool wasCompleted, ShareSheetCallbackID contextId);
     
@@ -1206,6 +1210,10 @@ private:
     void requestAdditionalItemsForDragSession(const WebCore::IntPoint& clientPosition, const WebCore::IntPoint& globalPosition);
 #endif
 
     void requestAdditionalItemsForDragSession(const WebCore::IntPoint& clientPosition, const WebCore::IntPoint& globalPosition);
 #endif
 
+#if ENABLE(DEVICE_ORIENTATION)
+    void didReceiveDeviceOrientationAndMotionAccessDecision(uint64_t callbackID, bool granted);
+#endif
+
 #if !PLATFORM(COCOA) && !PLATFORM(WPE)
     static const char* interpretKeyEvent(const WebCore::KeyboardEvent*);
 #endif
 #if !PLATFORM(COCOA) && !PLATFORM(WPE)
     static const char* interpretKeyEvent(const WebCore::KeyboardEvent*);
 #endif
@@ -1836,6 +1844,10 @@ private:
     HashMap<uint64_t, WTF::Function<void(bool granted)>> m_storageAccessResponseCallbackMap;
     HashMap<ShareSheetCallbackID, WTF::Function<void(bool completed)>> m_shareSheetResponseCallbackMap;
 
     HashMap<uint64_t, WTF::Function<void(bool granted)>> m_storageAccessResponseCallbackMap;
     HashMap<ShareSheetCallbackID, WTF::Function<void(bool completed)>> m_shareSheetResponseCallbackMap;
 
+#if ENABLE(DEVICE_ORIENTATION)
+    HashMap<uint64_t, WTF::CompletionHandler<void(bool granted)>> m_deviceOrientationAndMotionPermissionCallbackMap;
+#endif
+
 #if ENABLE(APPLICATION_MANIFEST)
     HashMap<uint64_t, uint64_t> m_applicationManifestFetchCallbackMap;
 #endif
 #if ENABLE(APPLICATION_MANIFEST)
     HashMap<uint64_t, uint64_t> m_applicationManifestFetchCallbackMap;
 #endif
index cce7722..9d7239d 100644 (file)
@@ -363,6 +363,10 @@ messages -> WebPage LegacyReceiver {
     # Notification
     DidReceiveNotificationPermissionDecision(uint64_t notificationID, bool allowed)
 
     # Notification
     DidReceiveNotificationPermissionDecision(uint64_t notificationID, bool allowed)
 
+#if ENABLE(DEVICE_ORIENTATION)
+    DidReceiveDeviceOrientationAndMotionAccessDecision(uint64_t callbackID, bool granted)
+#endif
+
     # Printing.
     BeginPrinting(uint64_t frameID, struct WebKit::PrintInfo printInfo)
     EndPrinting()
     # Printing.
     BeginPrinting(uint64_t frameID, struct WebKit::PrintInfo printInfo)
     EndPrinting()
index 6ae8ba0..46d0066 100644 (file)
@@ -1,3 +1,27 @@
+2019-03-08  Chris Dumez  <cdumez@apple.com>
+
+        Add support for Device Orientation / Motion permission API
+        https://bugs.webkit.org/show_bug.cgi?id=195329
+        <rdar://problem/47645367>
+
+        Reviewed by Geoffrey Garen.
+
+        Add test infrastructure to help test the Device Orientation / Motion permission API.
+
+        * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
+        * WebKitTestRunner/InjectedBundle/TestRunner.cpp:
+        (WTR::TestRunner::setShouldAllowDeviceOrientationAndMotionAccess):
+        * WebKitTestRunner/InjectedBundle/TestRunner.h:
+        * WebKitTestRunner/TestController.cpp:
+        (WTR::shouldAllowDeviceOrientationAndMotionAccess):
+        (WTR::TestController::createWebViewWithOptions):
+        (WTR::TestController::resetStateToConsistentValues):
+        (WTR::TestController::handleDeviceOrientationAndMotionAccessRequest):
+        * WebKitTestRunner/TestController.h:
+        (WTR::TestController::setShouldAllowDeviceOrientationAndMotionAccess):
+        * WebKitTestRunner/TestInvocation.cpp:
+        (WTR::TestInvocation::didReceiveMessageFromInjectedBundle):
+
 2019-03-08  Saam barati  <sbarati@apple.com>
 
         Add a compare-results script to compare benchmark results
 2019-03-08  Saam barati  <sbarati@apple.com>
 
         Add a compare-results script to compare benchmark results
index 9cf4493..c253289 100644 (file)
@@ -104,6 +104,9 @@ interface TestRunner {
     boolean isCommandEnabled(DOMString name);
     unsigned long windowCount();
 
     boolean isCommandEnabled(DOMString name);
     unsigned long windowCount();
 
+    // Device Orientation Motion.
+    void setShouldAllowDeviceOrientationAndMotionAccess(boolean value);
+
     // Special DOM variables.
     attribute boolean globalFlag;
 
     // Special DOM variables.
     attribute boolean globalFlag;
 
index 824a5f6..b79d08a 100644 (file)
@@ -1294,6 +1294,13 @@ void TestRunner::setShouldDownloadUndisplayableMIMETypes(bool value)
     WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get());
 }
 
     WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get());
 }
 
+void TestRunner::setShouldAllowDeviceOrientationAndMotionAccess(bool value)
+{
+    WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetShouldAllowDeviceOrientationAndMotionAccess"));
+    WKRetainPtr<WKBooleanRef> messageBody(AdoptWK, WKBooleanCreate(value));
+    WKBundlePagePostMessage(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get());
+}
+
 void TestRunner::terminateNetworkProcess()
 {
     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("TerminateNetworkProcess"));
 void TestRunner::terminateNetworkProcess()
 {
     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("TerminateNetworkProcess"));
index 6d11648..8dfcf6c 100644 (file)
@@ -348,6 +348,7 @@ public:
     void setNavigationGesturesEnabled(bool);
     void setIgnoresViewportScaleLimits(bool);
     void setShouldDownloadUndisplayableMIMETypes(bool);
     void setNavigationGesturesEnabled(bool);
     void setIgnoresViewportScaleLimits(bool);
     void setShouldDownloadUndisplayableMIMETypes(bool);
+    void setShouldAllowDeviceOrientationAndMotionAccess(bool);
 
     bool didCancelClientRedirect() const { return m_didCancelClientRedirect; }
     void setDidCancelClientRedirect(bool value) { m_didCancelClientRedirect = value; }
 
     bool didCancelClientRedirect() const { return m_didCancelClientRedirect; }
     void setDidCancelClientRedirect(bool value) { m_didCancelClientRedirect = value; }
index 554e03a..08964cd 100644 (file)
@@ -262,6 +262,11 @@ static void requestPointerLock(WKPageRef page, const void*)
     WKPageDidAllowPointerLock(page);
 }
 
     WKPageDidAllowPointerLock(page);
 }
 
+static bool shouldAllowDeviceOrientationAndMotionAccess(WKPageRef, WKSecurityOriginRef origin, const void*)
+{
+    return TestController::singleton().handleDeviceOrientationAndMotionAccessRequest(origin);
+}
+
 WKPageRef TestController::createOtherPage(WKPageRef, WKPageConfigurationRef configuration, WKNavigationActionRef navigationAction, WKWindowFeaturesRef windowFeatures, const void *clientInfo)
 {
     PlatformWebView* parentView = static_cast<PlatformWebView*>(const_cast<void*>(clientInfo));
 WKPageRef TestController::createOtherPage(WKPageRef, WKPageConfigurationRef configuration, WKNavigationActionRef navigationAction, WKWindowFeaturesRef windowFeatures, const void *clientInfo)
 {
     PlatformWebView* parentView = static_cast<PlatformWebView*>(const_cast<void*>(clientInfo));
@@ -570,8 +575,8 @@ void TestController::createWebViewWithOptions(const TestOptions& options)
     resetPreferencesToConsistentValues(options);
 
     platformCreateWebView(configuration.get(), options);
     resetPreferencesToConsistentValues(options);
 
     platformCreateWebView(configuration.get(), options);
-    WKPageUIClientV8 pageUIClient = {
-        { 8, m_mainWebView.get() },
+    WKPageUIClientV13 pageUIClient = {
+        { 13, m_mainWebView.get() },
         0, // createNewPage_deprecatedForUseWithV0
         0, // showPage
         0, // close
         0, // createNewPage_deprecatedForUseWithV0
         0, // showPage
         0, // close
@@ -637,7 +642,13 @@ void TestController::createWebViewWithOptions(const TestOptions& options)
         0, // runBeforeUnloadConfirmPanel
         0, // fullscreenMayReturnToInline
         requestPointerLock,
         0, // runBeforeUnloadConfirmPanel
         0, // fullscreenMayReturnToInline
         requestPointerLock,
-        0,
+        0, // didLosePointerLock
+        0, // handleAutoplayEvent
+        0, // hasVideoInPictureInPictureDidChange
+        0, // didExceedBackgroundResourceLimitWhileInForeground
+        0, // didResignInputElementStrongPasswordAppearance
+        0, // requestStorageAccessConfirm
+        shouldAllowDeviceOrientationAndMotionAccess
     };
     WKPageSetPageUIClient(m_mainWebView->page(), &pageUIClient.base);
 
     };
     WKPageSetPageUIClient(m_mainWebView->page(), &pageUIClient.base);
 
@@ -943,6 +954,8 @@ bool TestController::resetStateToConsistentValues(const TestOptions& options, Re
 
     m_shouldDownloadUndisplayableMIMETypes = false;
 
 
     m_shouldDownloadUndisplayableMIMETypes = false;
 
+    m_shouldAllowDeviceOrientationAndMotionAccess = false;
+
     m_workQueueManager.clearWorkQueue();
 
     m_rejectsProtectionSpaceAndContinueForAuthenticationChallenges = false;
     m_workQueueManager.clearWorkQueue();
 
     m_rejectsProtectionSpaceAndContinueForAuthenticationChallenges = false;
@@ -2548,6 +2561,12 @@ void TestController::handleCheckOfUserMediaPermissionForOrigin(WKFrameRef frame,
     WKUserMediaPermissionCheckSetUserMediaAccessInfo(checkRequest, saltString.get(), settingsForOrigin(originHash).persistentPermission());
 }
 
     WKUserMediaPermissionCheckSetUserMediaAccessInfo(checkRequest, saltString.get(), settingsForOrigin(originHash).persistentPermission());
 }
 
+bool TestController::handleDeviceOrientationAndMotionAccessRequest(WKSecurityOriginRef origin)
+{
+    m_currentInvocation->outputText(makeString("Received device orientation & motion access request for security origin \"", originUserVisibleName(origin), "\".\n"));
+    return m_shouldAllowDeviceOrientationAndMotionAccess;
+}
+
 void TestController::handleUserMediaPermissionRequest(WKFrameRef frame, WKSecurityOriginRef userMediaDocumentOrigin, WKSecurityOriginRef topLevelDocumentOrigin, WKUserMediaPermissionRequestRef request)
 {
     auto originHash = userMediaOriginHash(userMediaDocumentOrigin, topLevelDocumentOrigin);
 void TestController::handleUserMediaPermissionRequest(WKFrameRef frame, WKSecurityOriginRef userMediaDocumentOrigin, WKSecurityOriginRef topLevelDocumentOrigin, WKUserMediaPermissionRequestRef request)
 {
     auto originHash = userMediaOriginHash(userMediaDocumentOrigin, topLevelDocumentOrigin);
index 4b353db..3abe2db 100644 (file)
@@ -150,6 +150,9 @@ public:
     unsigned userMediaPermissionRequestCountForOrigin(WKStringRef userMediaDocumentOriginString, WKStringRef topLevelDocumentOriginString);
     void resetUserMediaPermissionRequestCountForOrigin(WKStringRef userMediaDocumentOriginString, WKStringRef topLevelDocumentOriginString);
 
     unsigned userMediaPermissionRequestCountForOrigin(WKStringRef userMediaDocumentOriginString, WKStringRef topLevelDocumentOriginString);
     void resetUserMediaPermissionRequestCountForOrigin(WKStringRef userMediaDocumentOriginString, WKStringRef topLevelDocumentOriginString);
 
+    // Device Orientation / Motion.
+    bool handleDeviceOrientationAndMotionAccessRequest(WKSecurityOriginRef);
+
     // Content Extensions.
     void configureContentExtensionForTest(const TestInvocation&);
     void resetContentExtensions();
     // Content Extensions.
     void configureContentExtensionForTest(const TestInvocation&);
     void resetContentExtensions();
@@ -199,6 +202,7 @@ public:
     void setIgnoresViewportScaleLimits(bool);
 
     void setShouldDownloadUndisplayableMIMETypes(bool value) { m_shouldDownloadUndisplayableMIMETypes = value; }
     void setIgnoresViewportScaleLimits(bool);
 
     void setShouldDownloadUndisplayableMIMETypes(bool value) { m_shouldDownloadUndisplayableMIMETypes = value; }
+    void setShouldAllowDeviceOrientationAndMotionAccess(bool value) { m_shouldAllowDeviceOrientationAndMotionAccess = value; }
 
     void setStatisticsDebugMode(bool value);
     void setStatisticsPrevalentResourceForDebugMode(WKStringRef hostName);
 
     void setStatisticsDebugMode(bool value);
     void setStatisticsPrevalentResourceForDebugMode(WKStringRef hostName);
@@ -509,6 +513,7 @@ private:
     bool m_policyDelegateEnabled { false };
     bool m_policyDelegatePermissive { false };
     bool m_shouldDownloadUndisplayableMIMETypes { false };
     bool m_policyDelegateEnabled { false };
     bool m_policyDelegatePermissive { false };
     bool m_shouldDownloadUndisplayableMIMETypes { false };
+    bool m_shouldAllowDeviceOrientationAndMotionAccess { false };
 
     bool m_rejectsProtectionSpaceAndContinueForAuthenticationChallenges { false };
     bool m_handlesAuthenticationChallenges { false };
 
     bool m_rejectsProtectionSpaceAndContinueForAuthenticationChallenges { false };
     bool m_handlesAuthenticationChallenges { false };
index 0bdc417..7732918 100644 (file)
@@ -747,6 +747,13 @@ void TestInvocation::didReceiveMessageFromInjectedBundle(WKStringRef messageName
         return;
     }
 
         return;
     }
 
+    if (WKStringIsEqualToUTF8CString(messageName, "SetShouldAllowDeviceOrientationAndMotionAccess")) {
+        ASSERT(WKGetTypeID(messageBody) == WKBooleanGetTypeID());
+        WKBooleanRef value = static_cast<WKBooleanRef>(messageBody);
+        TestController::singleton().setShouldAllowDeviceOrientationAndMotionAccess(WKBooleanGetValue(value));
+        return;
+    }
+
     if (WKStringIsEqualToUTF8CString(messageName, "RunUIProcessScript")) {
         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
         WKRetainPtr<WKStringRef> scriptKey(AdoptWK, WKStringCreateWithUTF8CString("Script"));
     if (WKStringIsEqualToUTF8CString(messageName, "RunUIProcessScript")) {
         WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
         WKRetainPtr<WKStringRef> scriptKey(AdoptWK, WKStringCreateWithUTF8CString("Script"));