Title: [286318] trunk/Source
Revision
286318
Author
[email protected]
Date
2021-11-30 12:41:45 -0800 (Tue, 30 Nov 2021)

Log Message

[WebXR] Implement ChromeClient API to allow getting explicit consent from user on session features
https://bugs.webkit.org/show_bug.cgi?id=233617

Patch by Ada Chan <[email protected]> on 2021-11-30
Reviewed by Dean Jackson.

Source/WebCore:

Before this change, we just collect the features supported by the device/mode
and return them as resolved features. With this change, we introduce a ChromeClient
API that WebXRSystem::resolveFeaturePermissions() can call that allows clients to
implement a mechanism to ask user for explicit consent on session features.

* Modules/webxr/WebXRSystem.cpp:
(WebCore::WebXRSystem::resolveFeaturePermissions const):
Updated to call the new ChromeClient method requestPermissionOnXRSessionFeatures()
to get the resolved and user permitted XR session features. The feature list is
now returned via a CompletionHandler.
(WebCore::WebXRSystem::requestSession):
Updated now that WebXRSystem::resolveFeaturePermissions() is no longer synchronous.
* Modules/webxr/WebXRSystem.h:
* page/ChromeClient.h:
(WebCore::ChromeClient::requestPermissionOnXRSessionFeatures):
Default implementation preserves current behavior by returning the initial list
of granted features (based on what the device can support).
* platform/xr/PlatformXR.h:
Define EnumTraits for PlatformXR::SessionMode.

Source/WebKit:

Set up WKUIDelegate method for asking user for permission on XR session features.

* Scripts/webkit/messages.py:
(types_that_cannot_be_forward_declared):
(headers_for_type):
* UIProcess/API/APIUIClient.h:
(API::UIClient::requestPermissionOnXRSessionFeatures):
* UIProcess/API/Cocoa/WKUIDelegatePrivate.h:
Declare a WK enum that represents XR session mode and a WK flag
that represents XR session features for use in the new WKUIDelegate method.
Declare a new WKUIDelegate method for requesting user permission for
XR session features that takes in the security origin, the session mode,
the list of device supported features, the list of features that require consent,
and the list of features that optionally require consent.
* UIProcess/Cocoa/UIDelegate.h:
* UIProcess/Cocoa/UIDelegate.mm:
(WebKit::UIDelegate::setDelegate):
(WebKit::toWKXRSessionMode):
(WebKit::toWKXRSessionFeatureFlags):
(WebKit::toPlatformXRFeatures):
(WebKit::UIDelegate::UIClient::requestPermissionOnXRSessionFeatures):
If the WKUIDelegate method for requesting permission is implemented, call it to
get the list of user permitted features. Otherwise, preserve the current behavior
by returning the initially granted features based on device support.
* UIProcess/XR/PlatformXRCoordinator.h:
(WebKit::PlatformXRCoordinator::requestPermissionOnSessionFeatures):
Default implementation returns the initially granted features based on device support.
* UIProcess/XR/PlatformXRSystem.cpp:
(WebKit::PlatformXRSystem::requestPermissionOnSessionFeatures):
* UIProcess/XR/PlatformXRSystem.h:
* UIProcess/XR/PlatformXRSystem.messages.in:
* WebProcess/WebCoreSupport/WebChromeClient.cpp:
(WebKit::WebChromeClient::requestPermissionOnXRSessionFeatures):
* WebProcess/WebCoreSupport/WebChromeClient.h:
* WebProcess/XR/PlatformXRSystemProxy.cpp:
(WebKit::PlatformXRSystemProxy::requestPermissionOnSessionFeatures):
Send a message to the UI process to request user consent on session features.
* WebProcess/XR/PlatformXRSystemProxy.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (286317 => 286318)


--- trunk/Source/WebCore/ChangeLog	2021-11-30 20:40:10 UTC (rev 286317)
+++ trunk/Source/WebCore/ChangeLog	2021-11-30 20:41:45 UTC (rev 286318)
@@ -1,3 +1,30 @@
+2021-11-30  Ada Chan  <[email protected]>
+
+        [WebXR] Implement ChromeClient API to allow getting explicit consent from user on session features
+        https://bugs.webkit.org/show_bug.cgi?id=233617
+
+        Reviewed by Dean Jackson.
+
+        Before this change, we just collect the features supported by the device/mode
+        and return them as resolved features. With this change, we introduce a ChromeClient
+        API that WebXRSystem::resolveFeaturePermissions() can call that allows clients to
+        implement a mechanism to ask user for explicit consent on session features.
+
+        * Modules/webxr/WebXRSystem.cpp:
+        (WebCore::WebXRSystem::resolveFeaturePermissions const):
+        Updated to call the new ChromeClient method requestPermissionOnXRSessionFeatures()
+        to get the resolved and user permitted XR session features. The feature list is
+        now returned via a CompletionHandler.
+        (WebCore::WebXRSystem::requestSession):
+        Updated now that WebXRSystem::resolveFeaturePermissions() is no longer synchronous.
+        * Modules/webxr/WebXRSystem.h:
+        * page/ChromeClient.h:
+        (WebCore::ChromeClient::requestPermissionOnXRSessionFeatures):
+        Default implementation preserves current behavior by returning the initial list
+        of granted features (based on what the device can support).
+        * platform/xr/PlatformXR.h:
+        Define EnumTraits for PlatformXR::SessionMode.
+
 2021-11-30  Commit Queue  <[email protected]>
 
         Unreviewed, reverting r286227.

Modified: trunk/Source/WebCore/Modules/webxr/WebXRSystem.cpp (286317 => 286318)


--- trunk/Source/WebCore/Modules/webxr/WebXRSystem.cpp	2021-11-30 20:40:10 UTC (rev 286317)
+++ trunk/Source/WebCore/Modules/webxr/WebXRSystem.cpp	2021-11-30 20:41:45 UTC (rev 286318)
@@ -335,7 +335,7 @@
 }
 
 // https://immersive-web.github.io/webxr/#request-the-xr-permission
-std::optional<WebXRSystem::FeatureList> WebXRSystem::resolveFeaturePermissions(XRSessionMode mode, const XRSessionInit& init, PlatformXR::Device* device, JSC::JSGlobalObject& globalObject) const
+void WebXRSystem::resolveFeaturePermissions(XRSessionMode mode, const XRSessionInit& init, PlatformXR::Device* device, JSC::JSGlobalObject& globalObject, CompletionHandler<void(std::optional<FeatureList>&&)>&& completionHandler) const
 {
     // 1. Set status's granted to an empty FrozenArray.
     // 2. Let requiredFeatures be descriptor's requiredFeatures.
@@ -348,8 +348,10 @@
     // 6. If result is null, run the following steps:
     //  6.1. Set status's state to "denied".
     //  6.2. Abort these steps.
-    if (!resolvedFeatures)
-        return std::nullopt;
+    if (!resolvedFeatures) {
+        completionHandler(std::nullopt);
+        return;
+    }
 
     // 7. Let (consentRequired, consentOptional, granted) be the fields of result.
     // 8. The user agent MAY at this point ask the user's permission for the calling algorithm to use any of the features
@@ -366,12 +368,26 @@
     //        of these prompts should be included when determining if there is a clear signal of user intent to enable feature.
     //  10.2. If a clear signal of user intent to enable feature has not been determined, continue to the next entry.
     //  10.3. If feature is not in granted, append feature to granted.
-    // 11. Set status's granted to granted.
-    // 12. Set device's list of enabled features for mode to granted.
-    // 13. Set status's state to "granted".
-    device->setEnabledFeatures(mode, resolvedFeatures->granted);
+    auto document = downcast<Document>(scriptExecutionContext());
+    if (!document || !document->page()) {
+        completionHandler(std::nullopt);
+        return;
+    }
 
-    return resolvedFeatures->requested;
+    // FIXME: Replace with Permissions API implementation.
+    document->page()->chrome().client().requestPermissionOnXRSessionFeatures(document->securityOrigin().data(), mode, resolvedFeatures->granted, resolvedFeatures->consentRequired, resolvedFeatures->consentOptional, [device, mode, completionHandler = WTFMove(completionHandler)](std::optional<PlatformXR::Device::FeatureList>&& userGranted) mutable {
+        if (!userGranted) {
+            completionHandler(std::nullopt);
+            return;
+        }
+
+        // 11. Set status's granted to granted.
+        // 12. Set device's list of enabled features for mode to granted.
+        // 13. Set status's state to "granted".
+        device->setEnabledFeatures(mode, *userGranted);
+
+        completionHandler(*userGranted);
+    });
 }
 
 
@@ -426,37 +442,40 @@
         if (!globalObject)
             return;
 
+        rejectPromiseWithNotSupportedError.release();
+
         // WebKit does not currently support the Permissions API. https://w3c.github.io/permissions/
         // However we do implement here the permission request algorithm without the
         // Permissions API bits as it handles, among others, the session features parsing. We also
         // do it here before creating the session as there is no need to do it on advance.
-        // FIXME: we just perform basic checks without asking any permission to the user so far. Maybe we should implement
-        // a mechanism similar to what others do involving passing a message to the UI process.
 
         // 5.4.4 Let descriptor be an XRPermissionDescriptor initialized with session, requiredFeatures, and optionalFeatures
         // 5.4.5 Let status be an XRPermissionStatus, initially null
         // 5.4.6 Request the xr permission with descriptor and status.
         // 5.4.7 If status' state is "denied" run the following steps: (same as above in 5.4.1)
-        auto requestedFeatures = resolveFeaturePermissions(mode, init, device, *globalObject);
-        if (!requestedFeatures)
-            return;
+        resolveFeaturePermissions(mode, init, device, *globalObject, [this, weakThis = WeakPtr { *this }, protectedDocument, device, immersive, mode, promise](std::optional<FeatureList>&& requestedFeatures) mutable {
+            if (!weakThis || !requestedFeatures) {
+                promise.reject(Exception { NotSupportedError });
+                m_pendingImmersiveSession = false;
+                return;
+            }
 
-        // 5.4.2 Let session be a new XRSession object.
-        // 5.4.3 Initialize the session with session, mode, and device.
-        auto session = WebXRSession::create(protectedDocument.get(), *this, mode, *device, WTFMove(*requestedFeatures));
+            // 5.4.2 Let session be a new XRSession object.
+            // 5.4.3 Initialize the session with session, mode, and device.
+            auto session = WebXRSession::create(protectedDocument.get(), *this, mode, *device, WTFMove(*requestedFeatures));
 
-        // 5.4.8 Potentially set the active immersive session as follows:
-        if (immersive) {
-            m_activeImmersiveSession = session.copyRef();
-            m_pendingImmersiveSession = false;
-        } else
-            m_inlineSessions.add(session.copyRef());
+            // 5.4.8 Potentially set the active immersive session as follows:
+            if (immersive) {
+                m_activeImmersiveSession = session.copyRef();
+                m_pendingImmersiveSession = false;
+            } else
+                m_inlineSessions.add(session.copyRef());
 
-        // 5.4.9 Resolve promise with session.
-        promise.resolve(WTFMove(session));
-        rejectPromiseWithNotSupportedError.release();
+            // 5.4.9 Resolve promise with session.
+            promise.resolve(WTFMove(session));
 
-        // 5.4.10 is handled in WebXRSession::sessionDidInitializeInputSources.
+            // 5.4.10 is handled in WebXRSession::sessionDidInitializeInputSources.
+        });
     });
 }
 

Modified: trunk/Source/WebCore/Modules/webxr/WebXRSystem.h (286317 => 286318)


--- trunk/Source/WebCore/Modules/webxr/WebXRSystem.h	2021-11-30 20:40:10 UTC (rev 286317)
+++ trunk/Source/WebCore/Modules/webxr/WebXRSystem.h	2021-11-30 20:41:45 UTC (rev 286318)
@@ -103,7 +103,7 @@
 
     struct ResolvedRequestedFeatures;
     std::optional<ResolvedRequestedFeatures> resolveRequestedFeatures(XRSessionMode, const XRSessionInit&, PlatformXR::Device*, JSC::JSGlobalObject&) const;
-    std::optional<FeatureList> resolveFeaturePermissions(XRSessionMode, const XRSessionInit&, PlatformXR::Device*, JSC::JSGlobalObject&) const;
+    void resolveFeaturePermissions(XRSessionMode, const XRSessionInit&, PlatformXR::Device*, JSC::JSGlobalObject&, CompletionHandler<void(std::optional<FeatureList>&&)>&&) const;
 
     // https://immersive-web.github.io/webxr/#default-inline-xr-device
     class DummyInlineDevice final : public PlatformXR::Device, private ContextDestructionObserver {

Modified: trunk/Source/WebCore/page/ChromeClient.h (286317 => 286318)


--- trunk/Source/WebCore/page/ChromeClient.h	2021-11-30 20:40:10 UTC (rev 286317)
+++ trunk/Source/WebCore/page/ChromeClient.h	2021-11-30 20:41:45 UTC (rev 286318)
@@ -135,6 +135,7 @@
 struct DateTimeChooserParameters;
 struct GraphicsDeviceAdapter;
 struct MockWebAuthenticationConfiguration;
+struct SecurityOriginData;
 struct ShareDataWithParsedURL;
 struct TextIndicatorData;
 struct ViewportArguments;
@@ -603,6 +604,7 @@
 
 #if ENABLE(WEBXR)
     virtual void enumerateImmersiveXRDevices(CompletionHandler<void(const PlatformXR::Instance::DeviceList&)>&& completionHandler) { PlatformXR::Instance::singleton().enumerateImmersiveXRDevices(WTFMove(completionHandler)); }
+    virtual void requestPermissionOnXRSessionFeatures(const SecurityOriginData&, PlatformXR::SessionMode, const PlatformXR::Device::FeatureList& granted, const PlatformXR::Device::FeatureList& /* consentRequired */, const PlatformXR::Device::FeatureList& /* consentOptional */, CompletionHandler<void(std::optional<PlatformXR::Device::FeatureList>&&)>&& completionHandler) { completionHandler(granted); }
 #endif
 
 #if ENABLE(TEXT_AUTOSIZING)

Modified: trunk/Source/WebCore/platform/xr/PlatformXR.h (286317 => 286318)


--- trunk/Source/WebCore/platform/xr/PlatformXR.h	2021-11-30 20:40:10 UTC (rev 286317)
+++ trunk/Source/WebCore/platform/xr/PlatformXR.h	2021-11-30 20:41:45 UTC (rev 286318)
@@ -650,6 +650,15 @@
 
 namespace WTF {
 
+template<> struct EnumTraits<PlatformXR::SessionMode> {
+    using values = EnumValues<
+        PlatformXR::SessionMode,
+        PlatformXR::SessionMode::Inline,
+        PlatformXR::SessionMode::ImmersiveVr,
+        PlatformXR::SessionMode::ImmersiveAr
+    >;
+};
+
 template<> struct EnumTraits<PlatformXR::ReferenceSpaceType> {
     using values = EnumValues<
         PlatformXR::ReferenceSpaceType,

Modified: trunk/Source/WebKit/ChangeLog (286317 => 286318)


--- trunk/Source/WebKit/ChangeLog	2021-11-30 20:40:10 UTC (rev 286317)
+++ trunk/Source/WebKit/ChangeLog	2021-11-30 20:41:45 UTC (rev 286318)
@@ -1,3 +1,49 @@
+2021-11-30  Ada Chan  <[email protected]>
+
+        [WebXR] Implement ChromeClient API to allow getting explicit consent from user on session features
+        https://bugs.webkit.org/show_bug.cgi?id=233617
+
+        Reviewed by Dean Jackson.
+
+        Set up WKUIDelegate method for asking user for permission on XR session features.
+
+        * Scripts/webkit/messages.py:
+        (types_that_cannot_be_forward_declared):
+        (headers_for_type):
+        * UIProcess/API/APIUIClient.h:
+        (API::UIClient::requestPermissionOnXRSessionFeatures):
+        * UIProcess/API/Cocoa/WKUIDelegatePrivate.h:
+        Declare a WK enum that represents XR session mode and a WK flag
+        that represents XR session features for use in the new WKUIDelegate method.
+        Declare a new WKUIDelegate method for requesting user permission for
+        XR session features that takes in the security origin, the session mode,
+        the list of device supported features, the list of features that require consent,
+        and the list of features that optionally require consent.
+        * UIProcess/Cocoa/UIDelegate.h:
+        * UIProcess/Cocoa/UIDelegate.mm:
+        (WebKit::UIDelegate::setDelegate):
+        (WebKit::toWKXRSessionMode):
+        (WebKit::toWKXRSessionFeatureFlags):
+        (WebKit::toPlatformXRFeatures):
+        (WebKit::UIDelegate::UIClient::requestPermissionOnXRSessionFeatures):
+        If the WKUIDelegate method for requesting permission is implemented, call it to 
+        get the list of user permitted features. Otherwise, preserve the current behavior
+        by returning the initially granted features based on device support.
+        * UIProcess/XR/PlatformXRCoordinator.h:
+        (WebKit::PlatformXRCoordinator::requestPermissionOnSessionFeatures):
+        Default implementation returns the initially granted features based on device support.
+        * UIProcess/XR/PlatformXRSystem.cpp:
+        (WebKit::PlatformXRSystem::requestPermissionOnSessionFeatures):
+        * UIProcess/XR/PlatformXRSystem.h:
+        * UIProcess/XR/PlatformXRSystem.messages.in:
+        * WebProcess/WebCoreSupport/WebChromeClient.cpp:
+        (WebKit::WebChromeClient::requestPermissionOnXRSessionFeatures):
+        * WebProcess/WebCoreSupport/WebChromeClient.h:
+        * WebProcess/XR/PlatformXRSystemProxy.cpp:
+        (WebKit::PlatformXRSystemProxy::requestPermissionOnSessionFeatures):
+        Send a message to the UI process to request user consent on session features.
+        * WebProcess/XR/PlatformXRSystemProxy.h:
+
 2021-11-30  Commit Queue  <[email protected]>
 
         Unreviewed, reverting r286227.

Modified: trunk/Source/WebKit/Scripts/webkit/messages.py (286317 => 286318)


--- trunk/Source/WebKit/Scripts/webkit/messages.py	2021-11-30 20:40:10 UTC (rev 286317)
+++ trunk/Source/WebKit/Scripts/webkit/messages.py	2021-11-30 20:41:45 UTC (rev 286318)
@@ -270,6 +270,8 @@
         'IPC::Semaphore',
         'MachSendRight',
         'MediaTime',
+        'PlatformXR::ReferenceSpaceType',
+        'PlatformXR::SessionMode',
         'String',
         'WebCore::BroadcastChannelIdentifier',
         'WebCore::DestinationColorSpace',
@@ -739,6 +741,8 @@
         'PAL::WebGPU::VertexFormat': ['<pal/graphics/WebGPU/WebGPUVertexFormat.h>'],
         'PAL::WebGPU::VertexStepMode': ['<pal/graphics/WebGPU/WebGPUVertexStepMode.h>'],
         'PlatformXR::Device::FrameData': ['<WebCore/PlatformXR.h>'],
+        'PlatformXR::ReferenceSpaceType': ['<WebCore/PlatformXR.h>'],
+        'PlatformXR::SessionMode': ['<WebCore/PlatformXR.h>'],
         'Seconds': ['<wtf/Seconds.h>'],
         'String': ['<wtf/text/WTFString.h>'],
         'URL': ['<wtf/URLHash.h>'],

Modified: trunk/Source/WebKit/UIProcess/API/APIUIClient.h (286317 => 286318)


--- trunk/Source/WebKit/UIProcess/API/APIUIClient.h	2021-11-30 20:40:10 UTC (rev 286317)
+++ trunk/Source/WebKit/UIProcess/API/APIUIClient.h	2021-11-30 20:41:45 UTC (rev 286318)
@@ -47,6 +47,10 @@
 #include "WebAuthenticationFlags.h"
 #endif
 
+#if ENABLE(WEBXR) && PLATFORM(COCOA)
+#include <WebCore/PlatformXR.h>
+#endif
+
 namespace WebCore {
 class RegistrableDomain;
 class ResourceRequest;
@@ -210,6 +214,7 @@
     virtual void decidePolicyForMediaKeySystemPermissionRequest(WebKit::WebPageProxy& page, API::SecurityOrigin& origin, const WTF::String& keySystem, CompletionHandler<void(bool)>&& completionHandler) { page.requestMediaKeySystemPermissionByDefaultAction(origin.securityOrigin(), WTFMove(completionHandler)); }
 
 #if ENABLE(WEBXR) && PLATFORM(COCOA)
+    virtual void requestPermissionOnXRSessionFeatures(WebKit::WebPageProxy&, const WebCore::SecurityOriginData&, PlatformXR::SessionMode, const PlatformXR::Device::FeatureList& granted, const PlatformXR::Device::FeatureList& /* consentRequired */, const PlatformXR::Device::FeatureList& /* consentOptional */, CompletionHandler<void(std::optional<PlatformXR::Device::FeatureList>&&)>&& completionHandler) { completionHandler(granted); }    
     virtual void startXRSession(WebKit::WebPageProxy&, CompletionHandler<void(RetainPtr<id>)>&& completionHandler) { completionHandler(nil); }
 #endif
 };

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKUIDelegatePrivate.h (286317 => 286318)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKUIDelegatePrivate.h	2021-11-30 20:40:10 UTC (rev 286317)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKUIDelegatePrivate.h	2021-11-30 20:41:45 UTC (rev 286318)
@@ -88,6 +88,21 @@
     _WKFocusDirectionForward,
 } WK_API_AVAILABLE(macos(10.13.4), ios(12.2));
 
+typedef NS_ENUM(NSInteger, _WKXRSessionMode) {
+    _WKXRSessionModeInline,
+    _WKXRSessionModeImmersiveVr,
+    _WKXRSessionModeImmersiveAr,
+};
+
+typedef NS_OPTIONS(NSUInteger, _WKXRSessionFeatureFlags) {
+    _WKXRSessionFeatureFlagsNone = 0,
+    _WKXRSessionFeatureFlagsReferenceSpaceTypeViewer = 1 << 0,
+    _WKXRSessionFeatureFlagsReferenceSpaceTypeLocal = 1 << 1,
+    _WKXRSessionFeatureFlagsReferenceSpaceTypeLocalFloor = 1 << 2,
+    _WKXRSessionFeatureFlagsReferenceSpaceTypeBoundedFloor = 1 << 3,
+    _WKXRSessionFeatureFlagsReferenceSpaceTypeUnbounded = 1 << 4,
+};
+
 @protocol WKUIDelegatePrivate <WKUIDelegate>
 
 #ifdef FOUNDATION_HAS_DIRECTIONAL_GEOMETRY
@@ -158,6 +173,7 @@
 - (void)_webViewDidEnableInspectorBrowserDomain:(WKWebView *)webView WK_API_AVAILABLE(macos(12.0), ios(15.0));
 - (void)_webViewDidDisableInspectorBrowserDomain:(WKWebView *)webView WK_API_AVAILABLE(macos(12.0), ios(15.0));
 
+- (void)_webView:(WKWebView *)webView requestPermissionForXRSessionOrigin:(NSString *)originString mode:(_WKXRSessionMode)mode grantedFeatures:(_WKXRSessionFeatureFlags)grantedFeatures consentRequiredFeatures:(_WKXRSessionFeatureFlags)consentRequiredFeatures consentOptionalFeatures:(_WKXRSessionFeatureFlags)consentOptionalFeatures completionHandler:(void (^)(_WKXRSessionFeatureFlags))completionHandler;
 - (void)_webView:(WKWebView *)webView startXRSessionWithCompletionHandler:(void (^)(id))completionHandler WK_API_AVAILABLE(macos(12.0), ios(15.0));
 - (void)_webView:(WKWebView *)webView requestNotificationPermissionForSecurityOrigin:(WKSecurityOrigin *)securityOrigin decisionHandler:(void (^)(BOOL))decisionHandler WK_API_AVAILABLE(macos(10.13.4), ios(WK_IOS_TBA));
 

Modified: trunk/Source/WebKit/UIProcess/Cocoa/UIDelegate.h (286317 => 286318)


--- trunk/Source/WebKit/UIProcess/Cocoa/UIDelegate.h	2021-11-30 20:40:10 UTC (rev 286317)
+++ trunk/Source/WebKit/UIProcess/Cocoa/UIDelegate.h	2021-11-30 20:41:45 UTC (rev 286318)
@@ -173,6 +173,7 @@
         void didDisableInspectorBrowserDomain(WebPageProxy&) final;
 
 #if ENABLE(WEBXR) && PLATFORM(COCOA)
+        void requestPermissionOnXRSessionFeatures(WebPageProxy&, const WebCore::SecurityOriginData&, PlatformXR::SessionMode, const PlatformXR::Device::FeatureList& /* granted */, const PlatformXR::Device::FeatureList& /* consentRequired */, const PlatformXR::Device::FeatureList& /* consentOptional */, CompletionHandler<void(std::optional<PlatformXR::Device::FeatureList>&&)>&&) final;
         void startXRSession(WebPageProxy&, CompletionHandler<void(RetainPtr<id>)>&&) final;
 #endif
 
@@ -265,6 +266,7 @@
         bool webViewDidEnableInspectorBrowserDomain : 1;
         bool webViewDidDisableInspectorBrowserDomain : 1;
 #if ENABLE(WEBXR) && PLATFORM(COCOA)
+        bool webViewRequestPermissionForXRSessionOriginModeAndFeaturesWithCompletionHandler: 1;
         bool webViewStartXRSessionWithCompletionHandler : 1;
 #endif
         bool webViewRequestNotificationPermissionForSecurityOriginDecisionHandler : 1;

Modified: trunk/Source/WebKit/UIProcess/Cocoa/UIDelegate.mm (286317 => 286318)


--- trunk/Source/WebKit/UIProcess/Cocoa/UIDelegate.mm	2021-11-30 20:40:10 UTC (rev 286317)
+++ trunk/Source/WebKit/UIProcess/Cocoa/UIDelegate.mm	2021-11-30 20:41:45 UTC (rev 286318)
@@ -193,6 +193,7 @@
     m_delegateMethods.webViewDidDisableInspectorBrowserDomain = [delegate respondsToSelector:@selector(_webViewDidDisableInspectorBrowserDomain:)];
 
 #if ENABLE(WEBXR) && PLATFORM(COCOA)
+    m_delegateMethods.webViewRequestPermissionForXRSessionOriginModeAndFeaturesWithCompletionHandler = [delegate respondsToSelector:@selector(_webView:requestPermissionForXRSessionOrigin:mode:grantedFeatures:consentRequiredFeatures:consentOptionalFeatures:completionHandler:)];
     m_delegateMethods.webViewStartXRSessionWithCompletionHandler = [delegate respondsToSelector:@selector(_webView:startXRSessionWithCompletionHandler:)];
 #endif
     m_delegateMethods.webViewRequestNotificationPermissionForSecurityOriginDecisionHandler = [delegate respondsToSelector:@selector(_webView:requestNotificationPermissionForSecurityOrigin:decisionHandler:)];
@@ -1640,6 +1641,83 @@
 }
 
 #if ENABLE(WEBXR) && PLATFORM(COCOA)
+static _WKXRSessionMode toWKXRSessionMode(PlatformXR::SessionMode mode)
+{
+    switch (mode) {
+    case PlatformXR::SessionMode::Inline:
+        return _WKXRSessionModeInline;
+    case PlatformXR::SessionMode::ImmersiveVr:
+        return _WKXRSessionModeImmersiveVr;
+    case PlatformXR::SessionMode::ImmersiveAr:
+        return _WKXRSessionModeImmersiveAr;
+    }
+}
+
+static _WKXRSessionFeatureFlags toWKXRSessionFeatureFlags(PlatformXR::ReferenceSpaceType feature)
+{
+    switch (feature) {
+    case PlatformXR::ReferenceSpaceType::Viewer:
+        return _WKXRSessionFeatureFlagsReferenceSpaceTypeViewer;
+    case PlatformXR::ReferenceSpaceType::Local:
+        return _WKXRSessionFeatureFlagsReferenceSpaceTypeLocal;
+    case PlatformXR::ReferenceSpaceType::LocalFloor:
+        return _WKXRSessionFeatureFlagsReferenceSpaceTypeLocalFloor;
+    case PlatformXR::ReferenceSpaceType::BoundedFloor:
+        return _WKXRSessionFeatureFlagsReferenceSpaceTypeBoundedFloor;
+    case PlatformXR::ReferenceSpaceType::Unbounded:
+        return _WKXRSessionFeatureFlagsReferenceSpaceTypeUnbounded;
+    }
+}
+
+static _WKXRSessionFeatureFlags toWKXRSessionFeatureFlags(const PlatformXR::Device::FeatureList& features)
+{
+    _WKXRSessionFeatureFlags flags = _WKXRSessionFeatureFlagsNone;
+    for (auto feature : features)
+        flags |= toWKXRSessionFeatureFlags(feature);
+    return flags;
+}
+
+static std::optional<PlatformXR::Device::FeatureList> toPlatformXRFeatures(_WKXRSessionFeatureFlags featureFlags)
+{
+    if (featureFlags == _WKXRSessionFeatureFlagsNone)
+        return std::nullopt;
+
+    PlatformXR::Device::FeatureList features;
+    if (featureFlags & _WKXRSessionFeatureFlagsReferenceSpaceTypeViewer)
+        features.append(PlatformXR::ReferenceSpaceType::Viewer);
+    if (featureFlags & _WKXRSessionFeatureFlagsReferenceSpaceTypeLocal)
+        features.append(PlatformXR::ReferenceSpaceType::Local);
+    if (featureFlags & _WKXRSessionFeatureFlagsReferenceSpaceTypeLocalFloor)
+        features.append(PlatformXR::ReferenceSpaceType::LocalFloor);
+    if (featureFlags & _WKXRSessionFeatureFlagsReferenceSpaceTypeBoundedFloor)
+        features.append(PlatformXR::ReferenceSpaceType::BoundedFloor);
+    if (featureFlags & _WKXRSessionFeatureFlagsReferenceSpaceTypeUnbounded)
+        features.append(PlatformXR::ReferenceSpaceType::Unbounded);
+    return features;
+}
+
+void UIDelegate::UIClient::requestPermissionOnXRSessionFeatures(WebPageProxy&, const WebCore::SecurityOriginData& securityOriginData, PlatformXR::SessionMode mode, const PlatformXR::Device::FeatureList& granted, const PlatformXR::Device::FeatureList& consentRequired, const PlatformXR::Device::FeatureList& consentOptional, CompletionHandler<void(std::optional<PlatformXR::Device::FeatureList>&&)>&& completionHandler)
+{
+    if (!m_uiDelegate || !m_uiDelegate->m_delegateMethods.webViewRequestPermissionForXRSessionOriginModeAndFeaturesWithCompletionHandler) {
+        completionHandler(granted);
+        return;
+    }
+
+    auto delegate = (id <WKUIDelegatePrivate>)m_uiDelegate->m_delegate.get();
+    if (!delegate) {
+        completionHandler(granted);
+        return;
+    }
+
+    auto checker = CompletionHandlerCallChecker::create(delegate, @selector(_webView:requestPermissionForXRSessionOrigin:mode:grantedFeatures:consentRequiredFeatures:consentOptionalFeatures:completionHandler:));
+    [delegate _webView:m_uiDelegate->m_webView.get().get() requestPermissionForXRSessionOrigin:securityOriginData.toString() mode:toWKXRSessionMode(mode) grantedFeatures:toWKXRSessionFeatureFlags(granted) consentRequiredFeatures:toWKXRSessionFeatureFlags(consentRequired) consentOptionalFeatures:toWKXRSessionFeatureFlags(consentOptional) completionHandler:makeBlockPtr([completionHandler = WTFMove(completionHandler), checker = WTFMove(checker)] (_WKXRSessionFeatureFlags userGrantedFeatures) mutable {
+        if (checker->completionHandlerHasBeenCalled())
+            return;
+        checker->didCallCompletionHandler();
+        completionHandler(toPlatformXRFeatures(userGrantedFeatures));
+    }).get()];
+}
+
 void UIDelegate::UIClient::startXRSession(WebPageProxy&, CompletionHandler<void(RetainPtr<id>)>&& completionHandler)
 {
     if (!m_uiDelegate || !m_uiDelegate->m_delegateMethods.webViewStartXRSessionWithCompletionHandler) {

Modified: trunk/Source/WebKit/UIProcess/XR/PlatformXRCoordinator.h (286317 => 286318)


--- trunk/Source/WebKit/UIProcess/XR/PlatformXRCoordinator.h	2021-11-30 20:40:10 UTC (rev 286317)
+++ trunk/Source/WebKit/UIProcess/XR/PlatformXRCoordinator.h	2021-11-30 20:41:45 UTC (rev 286318)
@@ -32,6 +32,10 @@
 #include <WebCore/PlatformXR.h>
 #include <wtf/Function.h>
 
+namespace WebCore {
+struct SecurityOriginData;
+}
+
 namespace WebKit {
 
 class WebPageProxy;
@@ -46,6 +50,9 @@
     using DeviceInfoCallback = Function<void(std::optional<XRDeviceInfo>)>;
     virtual void getPrimaryDeviceInfo(DeviceInfoCallback&&) = 0;
 
+    using FeatureListCallback = CompletionHandler<void(std::optional<PlatformXR::Device::FeatureList>&&)>;
+    virtual void requestPermissionOnSessionFeatures(WebPageProxy&, const WebCore::SecurityOriginData&, PlatformXR::SessionMode, const PlatformXR::Device::FeatureList& granted, const PlatformXR::Device::FeatureList& /* consentRequired */, const PlatformXR::Device::FeatureList& /* consentOptional */, FeatureListCallback&& completionHandler) { completionHandler(granted); }
+    
     // Session creation/termination.
     using _OnSessionEndCallback_ = Function<void(XRDeviceIdentifier)>;
     virtual void startSession(WebPageProxy&, OnSessionEndCallback&&) = 0;

Modified: trunk/Source/WebKit/UIProcess/XR/PlatformXRSystem.cpp (286317 => 286318)


--- trunk/Source/WebKit/UIProcess/XR/PlatformXRSystem.cpp	2021-11-30 20:40:10 UTC (rev 286317)
+++ trunk/Source/WebKit/UIProcess/XR/PlatformXRSystem.cpp	2021-11-30 20:41:45 UTC (rev 286318)
@@ -33,6 +33,7 @@
 #include "PlatformXRSystemProxyMessages.h"
 #include "WebPageProxy.h"
 #include "WebProcessProxy.h"
+#include <WebCore/SecurityOriginData.h>
 
 namespace WebKit {
 
@@ -73,6 +74,17 @@
     });
 }
 
+void PlatformXRSystem::requestPermissionOnSessionFeatures(const WebCore::SecurityOriginData& securityOriginData, PlatformXR::SessionMode mode, const Vector<PlatformXR::ReferenceSpaceType>& granted, const Vector<PlatformXR::ReferenceSpaceType>& consentRequired, const Vector<PlatformXR::ReferenceSpaceType>& consentOptional,  CompletionHandler<void(std::optional<PlatformXR::Device::FeatureList>&&)>&& completionHandler)
+{
+    auto* xrCoordinator = PlatformXRSystem::xrCoordinator();
+    if (!xrCoordinator) {
+        completionHandler(granted);
+        return;
+    }
+
+    xrCoordinator->requestPermissionOnSessionFeatures(m_page, securityOriginData, mode, granted, consentRequired, consentOptional, WTFMove(completionHandler));
+}
+
 void PlatformXRSystem::initializeTrackingAndRendering()
 {
     auto* xrCoordinator = PlatformXRSystem::xrCoordinator();

Modified: trunk/Source/WebKit/UIProcess/XR/PlatformXRSystem.h (286317 => 286318)


--- trunk/Source/WebKit/UIProcess/XR/PlatformXRSystem.h	2021-11-30 20:40:10 UTC (rev 286317)
+++ trunk/Source/WebKit/UIProcess/XR/PlatformXRSystem.h	2021-11-30 20:41:45 UTC (rev 286318)
@@ -31,6 +31,10 @@
 #include "WebCoreArgumentCoders.h"
 #include <WebCore/PlatformXR.h>
 
+namespace WebCore {
+struct SecurityOriginData;
+}
+
 namespace WebKit {
 
 class PlatformXRCoordinator;
@@ -54,6 +58,7 @@
 
     // Message handlers
     void enumerateImmersiveXRDevices(CompletionHandler<void(Vector<XRDeviceInfo>&&)>&&);
+    void requestPermissionOnSessionFeatures(const WebCore::SecurityOriginData&, PlatformXR::SessionMode, const Vector<PlatformXR::ReferenceSpaceType>&, const Vector<PlatformXR::ReferenceSpaceType>&, const Vector<PlatformXR::ReferenceSpaceType>&,  CompletionHandler<void(std::optional<PlatformXR::Device::FeatureList>&&)>&&);
     void initializeTrackingAndRendering();
     void shutDownTrackingAndRendering();
     void requestFrame(CompletionHandler<void(PlatformXR::Device::FrameData&&)>&&);

Modified: trunk/Source/WebKit/UIProcess/XR/PlatformXRSystem.messages.in (286317 => 286318)


--- trunk/Source/WebKit/UIProcess/XR/PlatformXRSystem.messages.in	2021-11-30 20:40:10 UTC (rev 286317)
+++ trunk/Source/WebKit/UIProcess/XR/PlatformXRSystem.messages.in	2021-11-30 20:41:45 UTC (rev 286318)
@@ -27,6 +27,7 @@
 
 messages -> PlatformXRSystem NotRefCounted {
     EnumerateImmersiveXRDevices() -> (Vector<WebKit::XRDeviceInfo> devicesInfos) Async
+    RequestPermissionOnSessionFeatures(struct WebCore::SecurityOriginData origin, PlatformXR::SessionMode mode, Vector<PlatformXR::ReferenceSpaceType> granted, Vector<PlatformXR::ReferenceSpaceType> consentRequired, Vector<PlatformXR::ReferenceSpaceType> consentOptional) -> (std::optional<Vector<PlatformXR::ReferenceSpaceType>> userGranted) Async
     InitializeTrackingAndRendering()
     ShutDownTrackingAndRendering()
     RequestFrame() -> (struct PlatformXR::Device::FrameData frameData) Async

Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp (286317 => 286318)


--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp	2021-11-30 20:40:10 UTC (rev 286317)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp	2021-11-30 20:41:45 UTC (rev 286318)
@@ -1519,6 +1519,11 @@
 {
     m_page.xrSystemProxy().enumerateImmersiveXRDevices(WTFMove(completionHandler));
 }
+
+void WebChromeClient::requestPermissionOnXRSessionFeatures(const SecurityOriginData& origin, PlatformXR::SessionMode mode, const PlatformXR::Device::FeatureList& granted, const PlatformXR::Device::FeatureList& consentRequired, const PlatformXR::Device::FeatureList& consentOptional, CompletionHandler<void(std::optional<PlatformXR::Device::FeatureList>&&)>&& completionHandler)
+{
+    m_page.xrSystemProxy().requestPermissionOnSessionFeatures(origin, mode, granted, consentRequired, consentOptional, WTFMove(completionHandler));
+}
 #endif
 
 #if ENABLE(APPLE_PAY_AMS_UI)

Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h (286317 => 286318)


--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h	2021-11-30 20:40:10 UTC (rev 286317)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h	2021-11-30 20:41:45 UTC (rev 286318)
@@ -453,6 +453,7 @@
 
 #if ENABLE(WEBXR) && !USE(OPENXR)
     void enumerateImmersiveXRDevices(CompletionHandler<void(const PlatformXR::Instance::DeviceList&)>&&) final;
+    void requestPermissionOnXRSessionFeatures(const WebCore::SecurityOriginData&, PlatformXR::SessionMode, const PlatformXR::Device::FeatureList& /* granted */, const PlatformXR::Device::FeatureList& /* consentRequired */, const PlatformXR::Device::FeatureList& /* consentOptional */, CompletionHandler<void(std::optional<PlatformXR::Device::FeatureList>&&)>&&) final;
 #endif
 
 #if ENABLE(APPLE_PAY_AMS_UI)

Modified: trunk/Source/WebKit/WebProcess/XR/PlatformXRSystemProxy.cpp (286317 => 286318)


--- trunk/Source/WebKit/WebProcess/XR/PlatformXRSystemProxy.cpp	2021-11-30 20:40:10 UTC (rev 286317)
+++ trunk/Source/WebKit/WebProcess/XR/PlatformXRSystemProxy.cpp	2021-11-30 20:41:45 UTC (rev 286318)
@@ -34,6 +34,7 @@
 #include "WebPage.h"
 #include "WebProcess.h"
 #include "XRDeviceInfo.h"
+#include <WebCore/SecurityOrigin.h>
 #include <wtf/Vector.h>
 
 using namespace PlatformXR;
@@ -69,6 +70,11 @@
     });
 }
 
+void PlatformXRSystemProxy::requestPermissionOnSessionFeatures(const WebCore::SecurityOriginData& securityOriginData, PlatformXR::SessionMode mode, const PlatformXR::Device::FeatureList& granted, const PlatformXR::Device::FeatureList& consentRequired, const PlatformXR::Device::FeatureList& consentOptional, CompletionHandler<void(std::optional<PlatformXR::Device::FeatureList>&&)>&& completionHandler)
+{
+    m_page.sendWithAsyncReply(Messages::PlatformXRSystem::RequestPermissionOnSessionFeatures(securityOriginData, mode, granted, consentRequired, consentOptional), WTFMove(completionHandler));
+}
+
 void PlatformXRSystemProxy::initializeTrackingAndRendering()
 {
     m_page.send(Messages::PlatformXRSystem::InitializeTrackingAndRendering());

Modified: trunk/Source/WebKit/WebProcess/XR/PlatformXRSystemProxy.h (286317 => 286318)


--- trunk/Source/WebKit/WebProcess/XR/PlatformXRSystemProxy.h	2021-11-30 20:40:10 UTC (rev 286317)
+++ trunk/Source/WebKit/WebProcess/XR/PlatformXRSystemProxy.h	2021-11-30 20:41:45 UTC (rev 286318)
@@ -32,6 +32,10 @@
 #include "XRDeviceProxy.h"
 #include <WebCore/PlatformXR.h>
 
+namespace WebCore {
+struct SecurityOriginData;
+}
+
 namespace WebKit {
 
 class WebPage;
@@ -42,6 +46,7 @@
     virtual ~PlatformXRSystemProxy();
 
     void enumerateImmersiveXRDevices(CompletionHandler<void(const PlatformXR::Instance::DeviceList&)>&&);
+    void requestPermissionOnSessionFeatures(const WebCore::SecurityOriginData&, PlatformXR::SessionMode, const PlatformXR::Device::FeatureList& /* granted */, const PlatformXR::Device::FeatureList& /* consentRequired */, const PlatformXR::Device::FeatureList& /* consentOptional */, CompletionHandler<void(std::optional<PlatformXR::Device::FeatureList>&&)>&&);
     void initializeTrackingAndRendering();
     void shutDownTrackingAndRendering();
     void requestFrame(PlatformXR::Device::RequestFrameCallback&&);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to