Title: [292449] trunk
Revision
292449
Author
[email protected]
Date
2022-04-05 22:30:07 -0700 (Tue, 05 Apr 2022)

Log Message

[WebXR] Add a new enum type to represent session features
https://bugs.webkit.org/show_bug.cgi?id=238837

Patch by Ada Chan <[email protected]> on 2022-04-05
Reviewed by Dean Jackson.

Source/WebCore:

Test: http/wpt/webxr/xrDevice_requestSession_hand_tracking_feature.https.html

Add a new enum type, PlatformXR::SessionFeature, to represent session features.
It includes the ReferenceSpaceTypes and the hand-tracking feature for now.

Fix the algorithm to resolve the requested features to recognize hand-tracking
as a feature that requires explicit consent.

* Modules/webxr/WebXRSession.cpp:
(WebCore::WebXRSession::referenceSpaceIsSupported const):
Convert the XRReferenceSpaceType to PlatformXR::SessionFeature first before
checking against the feature list.
* Modules/webxr/WebXRSystem.cpp:
(WebCore::WebXRSystem::inlineSessionRequestIsAllowedForGlobalObject const):
Use PlatformXR::parseSessionFeatureDescriptor() to parse the feature string.
(WebCore::featureRequiresExplicitConsent):
Returns true for the hand tracking feature.
(WebCore::WebXRSystem::isFeatureSupported const):
Check whether the device supports the feature. For hand-tracking, make sure
the hand input module setting is enabled.
(WebCore::WebXRSystem::resolveRequestedFeatures const):
Update the string conversion between JS and WTF::String now that features cannot
be parsed as XRReferenceSpaceType enum. If the feature requires explicit consent
and it's not already in the granted list, add it to consentRequired or consentOptional
depending on whether it's specified as required.
(WebCore::WebXRSystem::resolveFeaturePermissions const):
If a feature is required but not given a clear signal of user intent, the session
should not be created.
(WebCore::WebXRSystem::DummyInlineDevice::DummyInlineDevice):
Updated to use PlatformXR::SessionFeature.
* Modules/webxr/WebXRSystem.h:
* platform/xr/PlatformXR.h:
(PlatformXR::sessionFeatureFromReferenceSpaceType):
(PlatformXR::parseSessionFeatureDescriptor):
Parse feature string to return PlatformXR::SessionFeature.
(PlatformXR::sessionFeatureDescriptor):
Return feature string from PlatformXR::SessionFeature.
(PlatformXR::Device::supports const):
Read from the m_supportedFeaturesMap.
(PlatformXR::Device::setSupportedFeatures):
Write to the m_supportedFeaturesMap.
(PlatformXR::Device::supportedFeatures const):
Read from the m_supportedFeaturesMap.
* platform/xr/openxr/PlatformXROpenXR.cpp:
(PlatformXR::OpenXRDevice::collectSupportedFeatures const):
Updated to use PlatformXR::SessionFeature.
* testing/WebXRTest.cpp:
(WebCore::WebXRTest::simulateDeviceConnection):
Updated to parse feature string to PlatformXR::SessionFeature.

Source/WebKit:

Add a new _WKXRSessionFeatureFlags entry for hand-tracking.

* Scripts/webkit/messages.py:
(types_that_cannot_be_forward_declared):
(headers_for_type):
* Shared/XR/XRDeviceProxy.cpp:
(WebKit::XRDeviceProxy::XRDeviceProxy):
* UIProcess/API/Cocoa/WKUIDelegatePrivate.h:
* UIProcess/Cocoa/UIDelegate.mm:
(WebKit::toWKXRSessionFeatureFlags):
(WebKit::toPlatformXRFeatures):
* UIProcess/XR/PlatformXRSystem.cpp:
(WebKit::PlatformXRSystem::requestPermissionOnSessionFeatures):
* UIProcess/XR/PlatformXRSystem.h:
* UIProcess/XR/PlatformXRSystem.messages.in:

LayoutTests:

Test listing "hand-tracking" as an optional feature while the device does not
support it allows the session to be created.
Test listing "hand-tracking" as a required feature while the device does not
support it would not create the session.

* http/wpt/webxr/resources/webxr_test_constants_single_view.js:
* http/wpt/webxr/xrDevice_requestSession_hand_tracking_feature.https-expected.txt: Added.
* http/wpt/webxr/xrDevice_requestSession_hand_tracking_feature.https.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (292448 => 292449)


--- trunk/LayoutTests/ChangeLog	2022-04-06 04:07:25 UTC (rev 292448)
+++ trunk/LayoutTests/ChangeLog	2022-04-06 05:30:07 UTC (rev 292449)
@@ -1,3 +1,19 @@
+2022-04-05  Ada Chan  <[email protected]>
+
+        [WebXR] Add a new enum type to represent session features
+        https://bugs.webkit.org/show_bug.cgi?id=238837
+
+        Reviewed by Dean Jackson.
+
+        Test listing "hand-tracking" as an optional feature while the device does not
+        support it allows the session to be created.
+        Test listing "hand-tracking" as a required feature while the device does not
+        support it would not create the session.
+
+        * http/wpt/webxr/resources/webxr_test_constants_single_view.js:
+        * http/wpt/webxr/xrDevice_requestSession_hand_tracking_feature.https-expected.txt: Added.
+        * http/wpt/webxr/xrDevice_requestSession_hand_tracking_feature.https.html: Added.
+
 2022-04-05  Matt Woodrow  <[email protected]>
 
         Support transitions/animations on grid-template-columns|rows

Modified: trunk/LayoutTests/http/wpt/webxr/resources/webxr_test_constants_single_view.js (292448 => 292449)


--- trunk/LayoutTests/http/wpt/webxr/resources/webxr_test_constants_single_view.js	2022-04-06 04:07:25 UTC (rev 292448)
+++ trunk/LayoutTests/http/wpt/webxr/resources/webxr_test_constants_single_view.js	2022-04-06 05:30:07 UTC (rev 292449)
@@ -134,8 +134,22 @@
   'light-estimation',
   'anchors',
   'depth-sensing',
+  'hand-tracking',
 ];
 
+const ALL_FEATURES_NO_HAND_TRACKING = [
+  'viewer',
+  'local',
+  'local-floor',
+  'bounded-floor',
+  'unbounded',
+  'hit-test',
+  'dom-overlay',
+  'light-estimation',
+  'anchors',
+  'depth-sensing',
+];
+
 const TRACKED_IMMERSIVE_DEVICE = {
     supportsImmersive: true,
     supportedModes: [ "inline", "immersive-vr"],
@@ -146,6 +160,16 @@
     interactionMode: "world-space"
 };
 
+const TRACKED_IMMERSIVE_DEVICE_NO_HAND_TRACKING = {
+    supportsImmersive: true,
+    supportedModes: [ "inline", "immersive-vr"],
+    views: VALID_VIEWS,
+    viewerOrigin: IDENTITY_TRANSFORM,
+    supportedFeatures: ALL_FEATURES_NO_HAND_TRACKING,
+    environmentBlendMode: "opaque",
+    interactionMode: "world-space"
+};
+
 const IMMERSIVE_AR_DEVICE = {
   supportsImmersive: true,
   supportedModes: [ "inline", "immersive-ar"],

Added: trunk/LayoutTests/http/wpt/webxr/xrDevice_requestSession_hand_tracking_feature.https-expected.txt (0 => 292449)


--- trunk/LayoutTests/http/wpt/webxr/xrDevice_requestSession_hand_tracking_feature.https-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/webxr/xrDevice_requestSession_hand_tracking_feature.https-expected.txt	2022-04-06 05:30:07 UTC (rev 292449)
@@ -0,0 +1,5 @@
+
+PASS Tests requestSession should succeed when device does not support hand-tracking and hand-tracking is an optional feature - webgl
+PASS Tests requestSession should succeed when device does not support hand-tracking and hand-tracking is an optional feature - webgl2
+PASS Tests requestSession should fail when device does not support hand-tracking and hand-tracking is a required feature
+

Added: trunk/LayoutTests/http/wpt/webxr/xrDevice_requestSession_hand_tracking_feature.https.html (0 => 292449)


--- trunk/LayoutTests/http/wpt/webxr/xrDevice_requestSession_hand_tracking_feature.https.html	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/webxr/xrDevice_requestSession_hand_tracking_feature.https.html	2022-04-06 05:30:07 UTC (rev 292449)
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<body>
+  <script src=""
+  <script src=""
+  <script src=""
+  <script src=""
+  <script>
+    xr_session_promise_test(
+      "Tests requestSession should succeed when device does not support hand-tracking and hand-tracking is an optional feature",
+      (session) => {
+        assert_not_equals(session, null);
+      }, TRACKED_IMMERSIVE_DEVICE_NO_HAND_TRACKING, 'immersive-vr', { optionalFeatures: ["hand-tracking"] });
+
+    xr_promise_test(
+      "Tests requestSession should fail when device does not support hand-tracking and hand-tracking is a required feature",
+      (t) => {
+        return navigator.xr.test.simulateDeviceConnection(TRACKED_IMMERSIVE_DEVICE_NO_HAND_TRACKING)
+          .then((controller) => new Promise((resolve) => {
+            navigator.xr.test.simulateUserActivation(() => {
+              resolve(promise_rejects_dom(
+                t, "NotSupportedError",
+                navigator.xr.requestSession('immersive-vr', { requiredFeatures: ["hand-tracking"] })));
+              });
+          }));
+      });
+  </script>
+</body>

Modified: trunk/Source/WebCore/ChangeLog (292448 => 292449)


--- trunk/Source/WebCore/ChangeLog	2022-04-06 04:07:25 UTC (rev 292448)
+++ trunk/Source/WebCore/ChangeLog	2022-04-06 05:30:07 UTC (rev 292449)
@@ -1,3 +1,60 @@
+2022-04-05  Ada Chan  <[email protected]>
+
+        [WebXR] Add a new enum type to represent session features
+        https://bugs.webkit.org/show_bug.cgi?id=238837
+
+        Reviewed by Dean Jackson.
+
+        Test: http/wpt/webxr/xrDevice_requestSession_hand_tracking_feature.https.html
+
+        Add a new enum type, PlatformXR::SessionFeature, to represent session features.
+        It includes the ReferenceSpaceTypes and the hand-tracking feature for now.
+
+        Fix the algorithm to resolve the requested features to recognize hand-tracking
+        as a feature that requires explicit consent.
+
+        * Modules/webxr/WebXRSession.cpp:
+        (WebCore::WebXRSession::referenceSpaceIsSupported const):
+        Convert the XRReferenceSpaceType to PlatformXR::SessionFeature first before
+        checking against the feature list.
+        * Modules/webxr/WebXRSystem.cpp:
+        (WebCore::WebXRSystem::inlineSessionRequestIsAllowedForGlobalObject const):
+        Use PlatformXR::parseSessionFeatureDescriptor() to parse the feature string.
+        (WebCore::featureRequiresExplicitConsent):
+        Returns true for the hand tracking feature.
+        (WebCore::WebXRSystem::isFeatureSupported const):
+        Check whether the device supports the feature. For hand-tracking, make sure
+        the hand input module setting is enabled.
+        (WebCore::WebXRSystem::resolveRequestedFeatures const):
+        Update the string conversion between JS and WTF::String now that features cannot
+        be parsed as XRReferenceSpaceType enum. If the feature requires explicit consent
+        and it's not already in the granted list, add it to consentRequired or consentOptional
+        depending on whether it's specified as required.
+        (WebCore::WebXRSystem::resolveFeaturePermissions const):
+        If a feature is required but not given a clear signal of user intent, the session
+        should not be created.
+        (WebCore::WebXRSystem::DummyInlineDevice::DummyInlineDevice):
+        Updated to use PlatformXR::SessionFeature.
+        * Modules/webxr/WebXRSystem.h:
+        * platform/xr/PlatformXR.h:
+        (PlatformXR::sessionFeatureFromReferenceSpaceType):
+        (PlatformXR::parseSessionFeatureDescriptor):
+        Parse feature string to return PlatformXR::SessionFeature.
+        (PlatformXR::sessionFeatureDescriptor):
+        Return feature string from PlatformXR::SessionFeature.
+        (PlatformXR::Device::supports const):
+        Read from the m_supportedFeaturesMap.
+        (PlatformXR::Device::setSupportedFeatures):
+        Write to the m_supportedFeaturesMap.
+        (PlatformXR::Device::supportedFeatures const):
+        Read from the m_supportedFeaturesMap.
+        * platform/xr/openxr/PlatformXROpenXR.cpp:
+        (PlatformXR::OpenXRDevice::collectSupportedFeatures const):
+        Updated to use PlatformXR::SessionFeature.
+        * testing/WebXRTest.cpp:
+        (WebCore::WebXRTest::simulateDeviceConnection):
+        Updated to parse feature string to PlatformXR::SessionFeature.
+
 2022-04-05  Andres Gonzalez  <[email protected]>
 
         Eliminate delays for processing live regions and modal notifications.

Modified: trunk/Source/WebCore/Modules/webxr/WebXRSession.cpp (292448 => 292449)


--- trunk/Source/WebCore/Modules/webxr/WebXRSession.cpp	2022-04-06 04:07:25 UTC (rev 292448)
+++ trunk/Source/WebCore/Modules/webxr/WebXRSession.cpp	2022-04-06 05:30:07 UTC (rev 292449)
@@ -166,7 +166,7 @@
 bool WebXRSession::referenceSpaceIsSupported(XRReferenceSpaceType type) const
 {
     // 1. If type is not contained in session’s XR device's list of enabled features for mode return false.
-    if (!m_requestedFeatures.contains(type))
+    if (!m_requestedFeatures.contains(sessionFeatureFromReferenceSpaceType(type)))
         return false;
 
     // 2. If type is viewer, return true.

Modified: trunk/Source/WebCore/Modules/webxr/WebXRSystem.cpp (292448 => 292449)


--- trunk/Source/WebCore/Modules/webxr/WebXRSystem.cpp	2022-04-06 04:07:25 UTC (rev 292448)
+++ trunk/Source/WebCore/Modules/webxr/WebXRSystem.cpp	2022-04-06 05:30:07 UTC (rev 292449)
@@ -47,7 +47,9 @@
 #include "WebXRSession.h"
 #include "XRReferenceSpaceType.h"
 #include "XRSessionInit.h"
+#include <_javascript_Core/JSCJSValue.h>
 #include <_javascript_Core/JSGlobalObject.h>
+#include <_javascript_Core/JSString.h>
 #include <wtf/IsoMallocInlines.h>
 #include <wtf/Scope.h>
 
@@ -222,8 +224,9 @@
         if (features.isEmpty())
             return true;
         if (features.size() == 1 && document.globalObject()) {
-            auto feature = parseEnumeration<XRReferenceSpaceType>(*document.globalObject(), features.first());
-            if (feature == XRReferenceSpaceType::Viewer)
+            auto featureString = features.first().toWTFString(document.globalObject());
+            auto sessionFeature = PlatformXR::parseSessionFeatureDescriptor(featureString);
+            if (sessionFeature && *sessionFeature == PlatformXR::SessionFeature::ReferenceSpaceTypeViewer)
                 return true;
         }
         return false;
@@ -250,6 +253,33 @@
     FeatureList requested;
 };
 
+static bool featureRequiresExplicitConsent(PlatformXR::SessionFeature feature)
+{
+#if ENABLE(WEBXR_HANDS)
+    if (feature == PlatformXR::SessionFeature::HandTracking)
+        return true;
+#else
+    UNUSED_PARAM(feature);
+#endif
+    return false;
+}
+
+bool WebXRSystem::isFeatureSupported(PlatformXR::SessionFeature feature, XRSessionMode mode, const PlatformXR::Device& device) const
+{
+    if (!device.supportedFeatures(mode).contains(feature))
+        return false;
+
+#if ENABLE(WEBXR_HANDS)
+    if (feature == PlatformXR::SessionFeature::HandTracking) {
+        auto scriptExecutionContext = this->scriptExecutionContext();
+        if (!scriptExecutionContext || !scriptExecutionContext->settingsValues().webXRHandInputModuleEnabled)
+            return false;
+    }
+#endif
+
+    return true;
+}
+
 #define RETURN_FALSE_OR_CONTINUE(mustReturn) { \
     if (mustReturn) {\
         return false; \
@@ -277,9 +307,9 @@
     //    with mode to the indicated feature list if it is not already present.
     // https://immersive-web.github.io/webxr/#default-features
     auto requiredFeaturesWithDefaultFeatures = init.requiredFeatures;
-    requiredFeaturesWithDefaultFeatures.append(convertEnumerationToJS(globalObject, XRReferenceSpaceType::Viewer));
+    requiredFeaturesWithDefaultFeatures.append(JSC::jsStringWithCache(globalObject.vm(), PlatformXR::sessionFeatureDescriptor(PlatformXR::SessionFeature::ReferenceSpaceTypeViewer)));
     if (mode == XRSessionMode::ImmersiveAr || mode == XRSessionMode::ImmersiveVr)
-        requiredFeaturesWithDefaultFeatures.append(convertEnumerationToJS(globalObject, XRReferenceSpaceType::Local));
+        requiredFeaturesWithDefaultFeatures.append(JSC::jsStringWithCache(globalObject.vm(), PlatformXR::sessionFeatureDescriptor(PlatformXR::SessionFeature::ReferenceSpaceTypeLocal)));
 
     // 7. For each feature in requiredFeatures|optionalFeatures perform the following steps:
     // 8. For each feature in optionalFeatures perform the following steps:
@@ -286,7 +316,7 @@
     // We're merging both loops in a single lambda. The only difference is that a failure on any required features
     // implies cancelling the whole process while failures in optional features are just skipped.
     enum class ParsingMode { Strict, Loose };
-    auto parseFeatures = [&device, &globalObject, mode, &resolvedFeatures] (const JSFeatureList& sessionFeatures, ParsingMode parsingMode) -> bool {
+    auto parseFeatures = [this, &device, &globalObject, mode, &resolvedFeatures] (const JSFeatureList& sessionFeatures, ParsingMode parsingMode) -> bool {
         bool returnOnFailure = parsingMode == ParsingMode::Strict;
         for (const auto& sessionFeature : sessionFeatures) {
             // 1. If the feature is null, continue to the next entry.
@@ -300,7 +330,8 @@
             //   2.1. Let s be the result of calling ? ToString(feature).
             //   2.2. If s is not a valid feature descriptor or is undefined, (return null|continue to next entry).
             //   2.3. Set feature to s.
-            auto feature = parseEnumeration<XRReferenceSpaceType>(globalObject, sessionFeature);
+            auto featureString = sessionFeature.toWTFString(&globalObject);
+            auto feature = PlatformXR::parseSessionFeatureDescriptor(featureString);
             if (!feature)
                 RETURN_FALSE_OR_CONTINUE(returnOnFailure);
 
@@ -315,12 +346,19 @@
 
             // 5. If session's XR device is not capable of supporting the functionality described by feature or the
             //    user agent has otherwise determined to reject the feature, (return null|continue to next entry).
-            if (!device->supportedFeatures(mode).contains(feature.value()))
+            if (!isFeatureSupported(feature.value(), mode, *device))
                 RETURN_FALSE_OR_CONTINUE(returnOnFailure);
 
             // 6. If the functionality described by feature requires explicit consent, append it to (consentRequired|consentOptional).
-            // 7. Else append feature to granted.
-            resolvedFeatures.granted.append(feature.value());
+            if (featureRequiresExplicitConsent(feature.value())) {
+                if (parsingMode == ParsingMode::Strict)
+                    resolvedFeatures.consentRequired.append(feature.value());
+                else
+                    resolvedFeatures.consentOptional.append(feature.value());
+            } else {
+                // 7. Else append feature to granted.
+                resolvedFeatures.granted.append(feature.value());
+            }
 
             // https://immersive-web.github.io/webxr/#requested-features
             // The combined list of feature descriptors given by the requiredFeatures and optionalFeatures are collectively considered the requested features for an XRSession.
@@ -377,12 +415,19 @@
     }
 
     // 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 {
+    document->page()->chrome().client().requestPermissionOnXRSessionFeatures(document->securityOrigin().data(), mode, resolvedFeatures->granted, resolvedFeatures->consentRequired, resolvedFeatures->consentOptional, [device, mode, consentRequired = WTFMove(resolvedFeatures->consentRequired), completionHandler = WTFMove(completionHandler)](std::optional<PlatformXR::Device::FeatureList>&& userGranted) mutable {
         if (!userGranted) {
             completionHandler(std::nullopt);
             return;
         }
 
+        for (auto featureRequiringConsent : consentRequired) {
+            if (!userGranted->contains(featureRequiringConsent)) {
+                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".
@@ -555,7 +600,7 @@
 WebXRSystem::DummyInlineDevice::DummyInlineDevice(ScriptExecutionContext& scriptExecutionContext)
     : ContextDestructionObserver(&scriptExecutionContext)
 {
-    setSupportedFeatures(XRSessionMode::Inline, { XRReferenceSpaceType::Viewer });
+    setSupportedFeatures(XRSessionMode::Inline, { PlatformXR::SessionFeature::ReferenceSpaceTypeViewer });
 }
 
 void WebXRSystem::DummyInlineDevice::requestFrame(PlatformXR::Device::RequestFrameCallback&& callback)

Modified: trunk/Source/WebCore/Modules/webxr/WebXRSystem.h (292448 => 292449)


--- trunk/Source/WebCore/Modules/webxr/WebXRSystem.h	2022-04-06 04:07:25 UTC (rev 292448)
+++ trunk/Source/WebCore/Modules/webxr/WebXRSystem.h	2022-04-06 05:30:07 UTC (rev 292449)
@@ -101,6 +101,7 @@
     bool immersiveSessionRequestIsAllowedForGlobalObject(DOMWindow&, Document&) const;
     bool inlineSessionRequestIsAllowedForGlobalObject(DOMWindow&, Document&, const XRSessionInit&) const;
 
+    bool isFeatureSupported(PlatformXR::SessionFeature, XRSessionMode, const PlatformXR::Device&) const;
     struct ResolvedRequestedFeatures;
     std::optional<ResolvedRequestedFeatures> resolveRequestedFeatures(XRSessionMode, const XRSessionInit&, PlatformXR::Device*, JSC::JSGlobalObject&) const;
     void resolveFeaturePermissions(XRSessionMode, const XRSessionInit&, PlatformXR::Device*, JSC::JSGlobalObject&, CompletionHandler<void(std::optional<FeatureList>&&)>&&) const;

Modified: trunk/Source/WebCore/platform/xr/PlatformXR.h (292448 => 292449)


--- trunk/Source/WebCore/platform/xr/PlatformXR.h	2022-04-06 04:07:25 UTC (rev 292448)
+++ trunk/Source/WebCore/platform/xr/PlatformXR.h	2022-04-06 05:30:07 UTC (rev 292449)
@@ -84,8 +84,84 @@
     Screen,
 };
 
+// https://immersive-web.github.io/webxr/#feature-descriptor
+enum class SessionFeature {
+    ReferenceSpaceTypeViewer,
+    ReferenceSpaceTypeLocal,
+    ReferenceSpaceTypeLocalFloor,
+    ReferenceSpaceTypeBoundedFloor,
+    ReferenceSpaceTypeUnbounded,
 #if ENABLE(WEBXR_HANDS)
+    HandTracking,
+#endif
+};
 
+inline SessionFeature sessionFeatureFromReferenceSpaceType(ReferenceSpaceType referenceSpaceType)
+{
+    switch (referenceSpaceType) {
+    case ReferenceSpaceType::Viewer:
+        return SessionFeature::ReferenceSpaceTypeViewer;
+    case ReferenceSpaceType::Local:
+        return SessionFeature::ReferenceSpaceTypeLocal;
+    case ReferenceSpaceType::LocalFloor:
+        return SessionFeature::ReferenceSpaceTypeLocalFloor;
+    case ReferenceSpaceType::BoundedFloor:
+        return SessionFeature::ReferenceSpaceTypeBoundedFloor;
+    case ReferenceSpaceType::Unbounded:
+        return SessionFeature::ReferenceSpaceTypeUnbounded;
+    }
+
+    ASSERT_NOT_REACHED();
+    return SessionFeature::ReferenceSpaceTypeViewer;
+}
+
+inline std::optional<SessionFeature> parseSessionFeatureDescriptor(const String& string)
+{
+    String feature = string.stripWhiteSpace().convertToASCIILowercase();
+
+    if (feature == "viewer"_s)
+        return SessionFeature::ReferenceSpaceTypeViewer;
+    if (feature == "local"_s)
+        return SessionFeature::ReferenceSpaceTypeLocal;
+    if (feature == "local-floor"_s)
+        return SessionFeature::ReferenceSpaceTypeLocalFloor;
+    if (feature == "bounded-floor"_s)
+        return SessionFeature::ReferenceSpaceTypeBoundedFloor;
+    if (feature == "unbounded"_s)
+        return SessionFeature::ReferenceSpaceTypeUnbounded;
+#if ENABLE(WEBXR_HANDS)
+    if (feature == "hand-tracking"_s)
+        return SessionFeature::HandTracking;
+#endif
+
+    return std::nullopt;
+}
+
+inline String sessionFeatureDescriptor(SessionFeature sessionFeature)
+{
+    switch (sessionFeature) {
+    case SessionFeature::ReferenceSpaceTypeViewer:
+        return "viewer"_s;
+    case SessionFeature::ReferenceSpaceTypeLocal:
+        return "local"_s;
+    case SessionFeature::ReferenceSpaceTypeLocalFloor:
+        return "local-floor"_s;
+    case SessionFeature::ReferenceSpaceTypeBoundedFloor:
+        return "bounded-floor"_s;
+    case SessionFeature::ReferenceSpaceTypeUnbounded:
+        return "unbounded"_s;
+#if ENABLE(WEBXR_HANDS)
+    case SessionFeature::HandTracking:
+        return "hand-tracking"_s;
+#endif
+    default:
+        ASSERT_NOT_REACHED();
+        return ""_s;
+    }
+}
+
+#if ENABLE(WEBXR_HANDS)
+
 enum class HandJoint : unsigned {
     Wrist,
     ThumbMetacarpal,
@@ -124,10 +200,10 @@
 public:
     virtual ~Device() = default;
 
-    using FeatureList = Vector<ReferenceSpaceType>;
-    bool supports(SessionMode mode) const { return m_enabledFeaturesMap.contains(mode); }
-    void setSupportedFeatures(SessionMode mode, const FeatureList& features) { m_enabledFeaturesMap.set(mode, features); }
-    FeatureList supportedFeatures(SessionMode mode) const { return m_enabledFeaturesMap.get(mode); }
+    using FeatureList = Vector<SessionFeature>;
+    bool supports(SessionMode mode) const { return m_supportedFeaturesMap.contains(mode); }
+    void setSupportedFeatures(SessionMode mode, const FeatureList& features) { m_supportedFeaturesMap.set(mode, features); }
+    FeatureList supportedFeatures(SessionMode mode) const { return m_supportedFeaturesMap.get(mode); }
     void setEnabledFeatures(SessionMode mode, const FeatureList& features) { m_enabledFeaturesMap.set(mode, features); }
     FeatureList enabledFeatures(SessionMode mode) const { return m_enabledFeaturesMap.get(mode); }
 
@@ -703,6 +779,20 @@
     >;
 };
 
+template<> struct EnumTraits<PlatformXR::SessionFeature> {
+    using values = EnumValues<
+        PlatformXR::SessionFeature,
+        PlatformXR::SessionFeature::ReferenceSpaceTypeViewer,
+        PlatformXR::SessionFeature::ReferenceSpaceTypeLocal,
+        PlatformXR::SessionFeature::ReferenceSpaceTypeLocalFloor,
+        PlatformXR::SessionFeature::ReferenceSpaceTypeBoundedFloor,
+        PlatformXR::SessionFeature::ReferenceSpaceTypeUnbounded
+#if ENABLE(WEBXR_HANDS)
+        , PlatformXR::SessionFeature::HandTracking
+#endif
+    >;
+};
+
 }
 
 #endif

Modified: trunk/Source/WebCore/platform/xr/openxr/PlatformXROpenXR.cpp (292448 => 292449)


--- trunk/Source/WebCore/platform/xr/openxr/PlatformXROpenXR.cpp	2022-04-06 04:07:25 UTC (rev 292448)
+++ trunk/Source/WebCore/platform/xr/openxr/PlatformXROpenXR.cpp	2022-04-06 05:30:07 UTC (rev 292449)
@@ -344,19 +344,19 @@
 
     // https://www.khronos.org/registry/OpenXR/specs/1.0/man/html/XrReferenceSpaceType.html
     // OpenXR runtimes must support Viewer and Local spaces.
-    features.append(ReferenceSpaceType::Viewer);
-    features.append(ReferenceSpaceType::Local);
+    features.append(PlatformXR::SessionFeature::ReferenceSpaceTypeViewer);
+    features.append(PlatformXR::SessionFeature::ReferenceSpaceTypeLocal);
 
     // Mark LocalFloor as supported regardless if XR_REFERENCE_SPACE_TYPE_STAGE is available.
     // The spec uses a estimated height if we don't provide a floor transform in frameData.
-    features.append(ReferenceSpaceType::LocalFloor);
+    features.append(PlatformXR::SessionFeature::ReferenceSpaceTypeLocalFloor);
 
     // Mark BoundedFloor as supported regardless if XR_REFERENCE_SPACE_TYPE_STAGE is available.
     // The spec allows reporting an empty array if xrGetReferenceSpaceBoundsRect fails.
-    features.append(ReferenceSpaceType::BoundedFloor);
+    features.append(PlatformXR::SessionFeature::ReferenceSpaceTypeBoundedFloor);
 
     if (m_extensions.isExtensionSupported(XR_MSFT_UNBOUNDED_REFERENCE_SPACE_EXTENSION_NAME))
-        features.append(ReferenceSpaceType::Unbounded);
+        features.append(PlatformXR::SessionFeature::ReferenceSpaceTypeUnbounded);
 
     return features;
 }

Modified: trunk/Source/WebCore/testing/WebXRTest.cpp (292448 => 292449)


--- trunk/Source/WebCore/testing/WebXRTest.cpp	2022-04-06 04:07:25 UTC (rev 292448)
+++ trunk/Source/WebCore/testing/WebXRTest.cpp	2022-04-06 05:30:07 UTC (rev 292449)
@@ -30,6 +30,7 @@
 
 #include "JSWebFakeXRDevice.h"
 #include "JSXRReferenceSpaceType.h"
+#include "PlatformXR.h"
 #include "UserGestureIndicator.h"
 #include "WebXRSystem.h"
 #include "XRSessionMode.h"
@@ -47,12 +48,13 @@
 
         device->setViews(init.views);
 
-        Vector<XRReferenceSpaceType> features;
+        PlatformXR::Device::FeatureList features;
         if (init.supportedFeatures) {
             if (auto* globalObject = context.globalObject()) {
                 for (auto& feature : init.supportedFeatures.value()) {
-                    if (auto referenceSpaceType = parseEnumeration<XRReferenceSpaceType>(*globalObject, feature))
-                        features.append(referenceSpaceType.value());
+                    auto featureString = feature.toWTFString(globalObject);
+                    if (auto sessionFeature = PlatformXR::parseSessionFeatureDescriptor(featureString))
+                        features.append(*sessionFeature);
                 }
             }
         }

Modified: trunk/Source/WebKit/ChangeLog (292448 => 292449)


--- trunk/Source/WebKit/ChangeLog	2022-04-06 04:07:25 UTC (rev 292448)
+++ trunk/Source/WebKit/ChangeLog	2022-04-06 05:30:07 UTC (rev 292449)
@@ -1,3 +1,26 @@
+2022-04-05  Ada Chan  <[email protected]>
+
+        [WebXR] Add a new enum type to represent session features
+        https://bugs.webkit.org/show_bug.cgi?id=238837
+
+        Reviewed by Dean Jackson.
+
+        Add a new _WKXRSessionFeatureFlags entry for hand-tracking.
+
+        * Scripts/webkit/messages.py:
+        (types_that_cannot_be_forward_declared):
+        (headers_for_type):
+        * Shared/XR/XRDeviceProxy.cpp:
+        (WebKit::XRDeviceProxy::XRDeviceProxy):
+        * UIProcess/API/Cocoa/WKUIDelegatePrivate.h:
+        * UIProcess/Cocoa/UIDelegate.mm:
+        (WebKit::toWKXRSessionFeatureFlags):
+        (WebKit::toPlatformXRFeatures):
+        * UIProcess/XR/PlatformXRSystem.cpp:
+        (WebKit::PlatformXRSystem::requestPermissionOnSessionFeatures):
+        * UIProcess/XR/PlatformXRSystem.h:
+        * UIProcess/XR/PlatformXRSystem.messages.in:
+
 2022-04-05  Wenson Hsieh  <[email protected]>
 
         [iOS] Update the context menu item glyph for visual look up

Modified: trunk/Source/WebKit/Scripts/webkit/messages.py (292448 => 292449)


--- trunk/Source/WebKit/Scripts/webkit/messages.py	2022-04-06 04:07:25 UTC (rev 292448)
+++ trunk/Source/WebKit/Scripts/webkit/messages.py	2022-04-06 05:30:07 UTC (rev 292449)
@@ -264,6 +264,7 @@
         'MachSendRight',
         'MediaTime',
         'PlatformXR::ReferenceSpaceType',
+        'PlatformXR::SessionFeature',
         'PlatformXR::SessionMode',
         'PlatformXR::VisibilityState',
         'String',
@@ -754,6 +755,7 @@
         'PAL::WebGPU::VertexStepMode': ['<pal/graphics/WebGPU/WebGPUVertexStepMode.h>'],
         'PlatformXR::Device::FrameData': ['<WebCore/PlatformXR.h>'],
         'PlatformXR::ReferenceSpaceType': ['<WebCore/PlatformXR.h>'],
+        'PlatformXR::SessionFeature': ['<WebCore/PlatformXR.h>'],
         'PlatformXR::SessionMode': ['<WebCore/PlatformXR.h>'],
         'PlatformXR::VisibilityState': ['<WebCore/PlatformXR.h>'],
         'Seconds': ['<wtf/Seconds.h>'],

Modified: trunk/Source/WebKit/Shared/XR/XRDeviceProxy.cpp (292448 => 292449)


--- trunk/Source/WebKit/Shared/XR/XRDeviceProxy.cpp	2022-04-06 04:07:25 UTC (rev 292448)
+++ trunk/Source/WebKit/Shared/XR/XRDeviceProxy.cpp	2022-04-06 05:30:07 UTC (rev 292449)
@@ -48,7 +48,7 @@
     m_supportsOrientationTracking = deviceInfo.supportsOrientationTracking;
     m_recommendedResolution = deviceInfo.recommendedResolution;
     if (!deviceInfo.features.isEmpty())
-        setEnabledFeatures(SessionMode::ImmersiveVr, deviceInfo.features);
+        setSupportedFeatures(SessionMode::ImmersiveVr, deviceInfo.features);
 }
 
 void XRDeviceProxy::sessionDidEnd()

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


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKUIDelegatePrivate.h	2022-04-06 04:07:25 UTC (rev 292448)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKUIDelegatePrivate.h	2022-04-06 05:30:07 UTC (rev 292449)
@@ -102,6 +102,7 @@
     _WKXRSessionFeatureFlagsReferenceSpaceTypeLocalFloor = 1 << 2,
     _WKXRSessionFeatureFlagsReferenceSpaceTypeBoundedFloor = 1 << 3,
     _WKXRSessionFeatureFlagsReferenceSpaceTypeUnbounded = 1 << 4,
+    _WKXRSessionFeatureFlagsHandTracking = 1 << 5,
 } WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
 
 typedef NS_ENUM(NSInteger, _WKModalContainerDecision) {

Modified: trunk/Source/WebKit/UIProcess/Cocoa/UIDelegate.mm (292448 => 292449)


--- trunk/Source/WebKit/UIProcess/Cocoa/UIDelegate.mm	2022-04-06 04:07:25 UTC (rev 292448)
+++ trunk/Source/WebKit/UIProcess/Cocoa/UIDelegate.mm	2022-04-06 05:30:07 UTC (rev 292449)
@@ -1854,19 +1854,23 @@
     }
 }
 
-static _WKXRSessionFeatureFlags toWKXRSessionFeatureFlags(PlatformXR::ReferenceSpaceType feature)
+static _WKXRSessionFeatureFlags toWKXRSessionFeatureFlags(PlatformXR::SessionFeature feature)
 {
     switch (feature) {
-    case PlatformXR::ReferenceSpaceType::Viewer:
+    case PlatformXR::SessionFeature::ReferenceSpaceTypeViewer:
         return _WKXRSessionFeatureFlagsReferenceSpaceTypeViewer;
-    case PlatformXR::ReferenceSpaceType::Local:
+    case PlatformXR::SessionFeature::ReferenceSpaceTypeLocal:
         return _WKXRSessionFeatureFlagsReferenceSpaceTypeLocal;
-    case PlatformXR::ReferenceSpaceType::LocalFloor:
+    case PlatformXR::SessionFeature::ReferenceSpaceTypeLocalFloor:
         return _WKXRSessionFeatureFlagsReferenceSpaceTypeLocalFloor;
-    case PlatformXR::ReferenceSpaceType::BoundedFloor:
+    case PlatformXR::SessionFeature::ReferenceSpaceTypeBoundedFloor:
         return _WKXRSessionFeatureFlagsReferenceSpaceTypeBoundedFloor;
-    case PlatformXR::ReferenceSpaceType::Unbounded:
+    case PlatformXR::SessionFeature::ReferenceSpaceTypeUnbounded:
         return _WKXRSessionFeatureFlagsReferenceSpaceTypeUnbounded;
+#if ENABLE(WEBXR_HANDS)
+    case PlatformXR::SessionFeature::HandTracking:
+        return _WKXRSessionFeatureFlagsHandTracking;
+#endif
     }
 }
 
@@ -1885,15 +1889,19 @@
 
     PlatformXR::Device::FeatureList features;
     if (featureFlags & _WKXRSessionFeatureFlagsReferenceSpaceTypeViewer)
-        features.append(PlatformXR::ReferenceSpaceType::Viewer);
+        features.append(PlatformXR::SessionFeature::ReferenceSpaceTypeViewer);
     if (featureFlags & _WKXRSessionFeatureFlagsReferenceSpaceTypeLocal)
-        features.append(PlatformXR::ReferenceSpaceType::Local);
+        features.append(PlatformXR::SessionFeature::ReferenceSpaceTypeLocal);
     if (featureFlags & _WKXRSessionFeatureFlagsReferenceSpaceTypeLocalFloor)
-        features.append(PlatformXR::ReferenceSpaceType::LocalFloor);
+        features.append(PlatformXR::SessionFeature::ReferenceSpaceTypeLocalFloor);
     if (featureFlags & _WKXRSessionFeatureFlagsReferenceSpaceTypeBoundedFloor)
-        features.append(PlatformXR::ReferenceSpaceType::BoundedFloor);
+        features.append(PlatformXR::SessionFeature::ReferenceSpaceTypeBoundedFloor);
     if (featureFlags & _WKXRSessionFeatureFlagsReferenceSpaceTypeUnbounded)
-        features.append(PlatformXR::ReferenceSpaceType::Unbounded);
+        features.append(PlatformXR::SessionFeature::ReferenceSpaceTypeUnbounded);
+#if ENABLE(WEBXR_HANDS)
+    if (featureFlags & _WKXRSessionFeatureFlagsHandTracking)
+        features.append(PlatformXR::SessionFeature::HandTracking);
+#endif
     return features;
 }
 

Modified: trunk/Source/WebKit/UIProcess/XR/PlatformXRSystem.cpp (292448 => 292449)


--- trunk/Source/WebKit/UIProcess/XR/PlatformXRSystem.cpp	2022-04-06 04:07:25 UTC (rev 292448)
+++ trunk/Source/WebKit/UIProcess/XR/PlatformXRSystem.cpp	2022-04-06 05:30:07 UTC (rev 292449)
@@ -73,7 +73,7 @@
     });
 }
 
-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)
+void PlatformXRSystem::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)
 {
     auto* xrCoordinator = PlatformXRSystem::xrCoordinator();
     if (!xrCoordinator) {

Modified: trunk/Source/WebKit/UIProcess/XR/PlatformXRSystem.h (292448 => 292449)


--- trunk/Source/WebKit/UIProcess/XR/PlatformXRSystem.h	2022-04-06 04:07:25 UTC (rev 292448)
+++ trunk/Source/WebKit/UIProcess/XR/PlatformXRSystem.h	2022-04-06 05:30:07 UTC (rev 292449)
@@ -63,7 +63,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 requestPermissionOnSessionFeatures(const WebCore::SecurityOriginData&, PlatformXR::SessionMode, const PlatformXR::Device::FeatureList&, const PlatformXR::Device::FeatureList&, const PlatformXR::Device::FeatureList&, 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 (292448 => 292449)


--- trunk/Source/WebKit/UIProcess/XR/PlatformXRSystem.messages.in	2022-04-06 04:07:25 UTC (rev 292448)
+++ trunk/Source/WebKit/UIProcess/XR/PlatformXRSystem.messages.in	2022-04-06 05:30:07 UTC (rev 292449)
@@ -27,7 +27,7 @@
 
 messages -> PlatformXRSystem NotRefCounted {
     EnumerateImmersiveXRDevices() -> (Vector<WebKit::XRDeviceInfo> devicesInfos)
-    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)
+    RequestPermissionOnSessionFeatures(struct WebCore::SecurityOriginData origin, PlatformXR::SessionMode mode, Vector<PlatformXR::SessionFeature> granted, Vector<PlatformXR::SessionFeature> consentRequired, Vector<PlatformXR::SessionFeature> consentOptional) -> (std::optional<Vector<PlatformXR::SessionFeature>> userGranted)
     InitializeTrackingAndRendering()
     ShutDownTrackingAndRendering()
     RequestFrame() -> (struct PlatformXR::Device::FrameData frameData)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to