Skip to content

Commit

Permalink
[WebXR] Resolve required/optional features per the spec
Browse files Browse the repository at this point in the history
This adds support to resolve required/optional features against device
capabilities as well as sets up the plumbing for appropriately tailored
consent.

A WPT test for lack of device support was also added, which required
updating the tests.

Bug:991605
Change-Id: Ibce6924492311544fd75ca36ed79aa855c943aad
  • Loading branch information
alcooper91 authored and chromium-wpt-export-bot committed Aug 19, 2019
1 parent f656b09 commit 82e17c6
Show file tree
Hide file tree
Showing 9 changed files with 136 additions and 10 deletions.
52 changes: 49 additions & 3 deletions resources/chromium/webxr-test.js
Expand Up @@ -116,7 +116,6 @@ class MockVRService {
if (index >= 0) {
this.runtimes_.splice(index, 1);
if (this.client_) {
console.error("Notifying client");
this.client_.onDeviceChanged();
}
}
Expand Down Expand Up @@ -153,7 +152,7 @@ class MockVRService {
// If there were no successful results, returns a null session.
return {
result: {
failureReason : device.mojom.RequestSessionResult.NO_RUNTIME_FOUND,
failureReason : device.mojom.RequestSessionError.NO_RUNTIME_FOUND,
$tag : 1
}
};
Expand Down Expand Up @@ -224,6 +223,9 @@ class MockRuntime {
this.setBoundsGeometry(fakeDeviceInit.boundsCoordinates);

this.setViews(fakeDeviceInit.views);

// Need to support webVR which doesn't have a notion of features
this.setFeatures(fakeDeviceInit.supportedFeatures || []);
}

// Test API methods.
Expand Down Expand Up @@ -421,6 +423,34 @@ class MockRuntime {
};
}

setFeatures(supportedFeatures) {
function convertFeatureToMojom(feature) {
switch (feature) {
case "viewer":
return device.mojom.XRSessionFeature.REF_SPACE_VIEWER;
case "local":
return device.mojom.XRSessionFeature.REF_SPACE_LOCAL;
case "local-floor":
return device.mojom.XRSessionFeature.REF_SPACE_LOCAL_FLOOR;
case "bounded-floor":
return device.mojom.XRSessionFeature.REF_SPACE_BOUNDED_FLOOR;
case "unbounded":
return device.mojom.XRSessionFeature.REF_SPACE_UNBOUNDED;
default:
return device.mojom.XRSessionFeature.INVALID;
}
}

this.supportedFeatures_ = [];

for (let i = 0; i < supportedFeatures.length; i++) {
let feature = convertFeatureToMojom(supportedFeatures[i]);
if (feature !== device.mojom.XRSessionFeature.INVALID) {
this.supportedFeatures_.push(feature);
}
}
}

// These methods are intended to be used by MockXRInputSource only.
addInputSource(source) {
let index = this.input_sources_.indexOf(source);
Expand Down Expand Up @@ -525,12 +555,28 @@ class MockRuntime {

let clientRequest = mojo.makeRequest(this.sessionClient_);

let enabled_features = [];
for(let i = 0; i < sessionOptions.requiredFeatures.length; i++) {
if (this.supportedFeatures_.indexOf(sessionOptions.requiredFeatures[i]) !== -1) {
enabled_features.push(sessionOptions.requiredFeatures[i]);
} else {
return Promise.resolve({session: null});
}
}

for (let i =0; i < sessionOptions.optionalFeatures.length; i++) {
if (this.supportedFeatures_.indexOf(sessionOptions.optionalFeatures[i]) !== -1) {
enabled_features.push(sessionOptions.optionalFeatures[i]);
}
}

return Promise.resolve({
session: {
submitFrameSink: submit_frame_sink,
dataProvider: dataProviderPtr,
clientRequest: clientRequest,
displayInfo: this.displayInfo_
displayInfo: this.displayInfo_,
enabledFeatures: enabled_features,
}
});
} else {
Expand Down
14 changes: 12 additions & 2 deletions webxr/resources/webxr_test_constants.js
Expand Up @@ -112,16 +112,26 @@ const NON_IMMERSIVE_VIEWS = [{
}
];

const ALL_FEATURES = [
"viewer",
"local",
"local-floor",
"bounded-floor",
"unbounded",
];

const TRACKED_IMMERSIVE_DEVICE = {
supportsImmersive: true,
views: VALID_VIEWS,
viewerOrigin: IDENTITY_TRANSFORM
viewerOrigin: IDENTITY_TRANSFORM,
supportedFeatures: ALL_FEATURES
};

const VALID_NON_IMMERSIVE_DEVICE = {
supportsImmersive: false,
views: NON_IMMERSIVE_VIEWS,
viewerOrigin: IDENTITY_TRANSFORM
viewerOrigin: IDENTITY_TRANSFORM,
supportedFeatures: ALL_FEATURES
};

const VALID_CONTROLLER = {
Expand Down
3 changes: 2 additions & 1 deletion webxr/xrBoundedReferenceSpace_updates.https.html
Expand Up @@ -14,7 +14,8 @@
supportsImmersive: true,
views: VALID_VIEWS,
viewerOrigin: IDENTITY_TRANSFORM,
floorOrigin: VALID_FLOOR_ORIGIN
floorOrigin: VALID_FLOOR_ORIGIN,
supportedFeatures: ALL_FEATURES
};

let testFunction = function(session, fakeDeviceController, t) {
Expand Down
3 changes: 2 additions & 1 deletion webxr/xrReferenceSpace_originOffset.https.html
Expand Up @@ -29,7 +29,8 @@
let fakeDeviceInitParams = {
supportsImmersive: true,
viewerOrigin: VALID_POSE_TRANSFORM,
views: VIEWS_WITH_OFFSET
views: VIEWS_WITH_OFFSET,
supportedFeatures: ALL_FEATURES
};

let testFunction =
Expand Down
1 change: 1 addition & 0 deletions webxr/xrReferenceSpace_originOffsetBounded.https.html
Expand Up @@ -37,6 +37,7 @@
views: VIEWS_WITH_OFFSET,
viewerOrigin: IDENTITY_TRANSFORM,
floorOrigin: FLOOR_TRANSFORM,
supportedFeatures: ALL_FEATURES,
boundsCoordinates: [
{ x: 1, z: -1.5 },
{ x: 1, z: 1.5 },
Expand Down
64 changes: 64 additions & 0 deletions webxr/xrSession_features_deviceSupport.https.html
@@ -0,0 +1,64 @@
<!DOCTYPE html>
<body>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src="resources/webxr_util.js"></script>
<script src="resources/webxr_test_constants.js"></script>
<canvas></canvas>
<script>

let testName =
"Immersive XRSession requests with no supported device should reject";

let fakeDeviceInitParams = {
supportsImmersive: true,
views: VALID_VIEWS,
viewerOrigin: IDENTITY_TRANSFORM,
supportedFeatures: [
"viewer",
"local",
"local-floor"]
};

xr_promise_test(testName,
(t) => {
function session_resolves(sessionMode, sessionInit) {
return navigator.xr.requestSession(sessionMode, sessionInit)
.then((session) => {
return session.end();
});
}

return navigator.xr.test.simulateDeviceConnection(fakeDeviceInitParams)
.then((controller) => new Promise((resolve, reject) => {
navigator.xr.test.simulateUserActivation(() => {
// Attempting to request required features that aren't supported by
// the device should reject.
promise_rejects(t, "NotSupportedError",
navigator.xr.requestSession("immersive-vr", {
requiredFeatures: ['bounded-floor']
}))
.then(() => {
// Attempting to request with an unsupported feature as optional
// should succeed
return session_resolves("immersive-vr", {
optionalFeatures: ['bounded-floor']
});
})
.then(() => {
// Attempting to request with supported features only should succeed.
return session_resolves("immersive-vr", {
requiredFeatures: ['local', 'local-floor']
})
.then(() => {
resolve();
}).catch((err) => {
reject(err);
});;
});
});
}));
});

</script>
</body>
Expand Up @@ -16,7 +16,8 @@

let fakeDeviceInitParams = {
supportsImmersive: true,
views: VALID_VIEWS
views: VALID_VIEWS,
supportedFeatures: ALL_FEATURES
};

// A valid pose matrix/transform for when we don't care about specific values
Expand Down
3 changes: 2 additions & 1 deletion webxr/xrView_match.https.html
Expand Up @@ -26,7 +26,8 @@
let fakeDeviceInitParams = {
supportsImmersive: true,
views: fakeViews,
viewerOrigin: IDENTITY_TRANSFORM
viewerOrigin: IDENTITY_TRANSFORM,
supportedFeatures: ALL_FEATURES
};

let testFunction = function(session, fakeDeviceController, t) {
Expand Down
3 changes: 2 additions & 1 deletion webxr/xrView_oneframeupdate.https.html
Expand Up @@ -27,7 +27,8 @@
let fakeDeviceInitParams = {
supportsImmersive: true,
views: fakeViews,
viewerOrigin: IDENTITY_TRANSFORM
viewerOrigin: IDENTITY_TRANSFORM,
supportedFeatures: ALL_FEATURES
};

let testFunction = function(session, fakeDeviceController, t) {
Expand Down

0 comments on commit 82e17c6

Please sign in to comment.