0

Remove deprecated navigator.xr.supportsSession call

This call was replaced by isSessionSupported in the WebXR spec is Sept
of 2019. I think 5+ years should be enough of a deprecation period that
we can now remove the call safely.

Stats for the deprecated call say it's used by ~0.00004% of web pages.

Bug: 40874319
Change-Id: I1b8f6b2b3fbf21e1926fe6d03a39f70b30c4d879
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6227520
Reviewed-by: Sergio Villar <svillar@igalia.com>
Auto-Submit: Brandon Jones <bajones@chromium.org>
Reviewed-by: Rick Byers <rbyers@chromium.org>
Commit-Queue: Brandon Jones <bajones@chromium.org>
Reviewed-by: Alexander Cooper <alcooper@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1424807}
This commit is contained in:
Brandon Jones
2025-02-25 14:30:16 -08:00
committed by Chromium LUCI CQ
parent 06ac99f3db
commit 315c95485c
10 changed files with 65 additions and 183 deletions

@ -611,14 +611,5 @@
"kXMLHttpRequestSynchronousInNonWorkerOutsideBeforeUnload",
],
},
{
name: "XRSupportsSession",
message: "`supportsSession()` is deprecated. Please use `isSessionSupported()` and check the resolved boolean value instead.",
translation_note: "Warning displayed to developers that instead of using `supportsSession()`, which returns a promise that resolves if the XR session can be supported and rejects if not, they should use `isSessionSupported()` which will return a promise which resolves to a boolean indicating if the XR session can be supported or not, but may reject to throw an exception.",
web_features: [
"kXRSupportsSession",
],
milestone: 80,
},
],
}

@ -371,12 +371,10 @@ const char* XRSystem::CheckInlineSessionRequestAllowed(
XRSystem::PendingSupportsSessionQuery::PendingSupportsSessionQuery(
ScriptPromiseResolverBase* resolver,
device::mojom::blink::XRSessionMode session_mode,
bool throw_on_unsupported)
device::mojom::blink::XRSessionMode session_mode)
: resolver_(resolver),
mode_(session_mode),
trace_id_(base::trace_event::GetNextGlobalTraceId()),
throw_on_unsupported_(throw_on_unsupported) {
trace_id_(base::trace_event::GetNextGlobalTraceId()) {
TRACE_EVENT("xr", "PendingSupportsSessionQuery::PendingSupportsSessionQuery",
"session_mode", session_mode, perfetto::Flow::Global(trace_id_));
}
@ -391,18 +389,8 @@ void XRSystem::PendingSupportsSessionQuery::Resolve(
TRACE_EVENT("xr", "PendingSupportsSessionQuery::Resolve", "supported",
supported, perfetto::TerminatingFlow::Global(trace_id_));
if (throw_on_unsupported_) {
if (supported) {
resolver_->DowncastTo<IDLUndefined>()->Resolve();
} else {
DVLOG(2) << __func__ << ": session is unsupported - throwing exception";
RejectWithDOMException(DOMExceptionCode::kNotSupportedError,
kSessionNotSupported, exception_state);
}
} else {
static_cast<ScriptPromiseResolver<IDLBoolean>*>(resolver_.Get())
->Resolve(supported);
}
static_cast<ScriptPromiseResolver<IDLBoolean>*>(resolver_.Get())
->Resolve(supported);
}
void XRSystem::PendingSupportsSessionQuery::RejectWithDOMException(
@ -901,17 +889,6 @@ void XRSystem::SetFramesThrottled(const XRSession* session, bool throttled) {
}
}
ScriptPromise<IDLUndefined> XRSystem::supportsSession(
ScriptState* script_state,
const V8XRSessionMode& mode,
ExceptionState& exception_state) {
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver<IDLUndefined>>(
script_state, exception_state.GetContext());
auto promise = resolver->Promise();
InternalIsSessionSupported(resolver, mode, exception_state, true);
return promise;
}
ScriptPromise<IDLBoolean> XRSystem::isSessionSupported(
ScriptState* script_state,
const V8XRSessionMode& mode,
@ -919,7 +896,64 @@ ScriptPromise<IDLBoolean> XRSystem::isSessionSupported(
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver<IDLBoolean>>(
script_state, exception_state.GetContext());
auto promise = resolver->Promise();
InternalIsSessionSupported(resolver, mode, exception_state, false);
if (!GetExecutionContext()) {
// Reject if the context is inaccessible.
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
kNavigatorDetachedError);
return promise; // Promise will be rejected by generated bindings
}
DisableBackForwardCache();
device::mojom::blink::XRSessionMode session_mode =
V8EnumToSessionMode(mode.AsEnum());
PendingSupportsSessionQuery* query =
MakeGarbageCollected<PendingSupportsSessionQuery>(resolver, session_mode);
if (session_mode == device::mojom::blink::XRSessionMode::kImmersiveAr &&
!IsImmersiveArAllowed()) {
DVLOG(2) << __func__
<< ": Immersive AR session is only supported if WebXRARModule "
"feature is enabled by a runtime feature and web settings";
query->Resolve(false);
return promise;
}
if (session_mode == device::mojom::blink::XRSessionMode::kInline) {
// inline sessions are always supported.
query->Resolve(true);
return promise;
}
if (!GetExecutionContext()->IsFeatureEnabled(
network::mojom::PermissionsPolicyFeature::kWebXr,
ReportOptions::kReportOnFailure)) {
// Only allow the call to be made if the appropriate permissions policy is
// in place.
query->RejectWithSecurityError(kFeaturePolicyBlocked, &exception_state);
return promise;
}
// If TryEnsureService() doesn't set |service_|, then we don't have any WebXR
// hardware, so we need to reject as being unsupported.
TryEnsureService();
if (!service_.is_bound()) {
query->Resolve(false, &exception_state);
return promise;
}
device::mojom::blink::XRSessionOptionsPtr session_options =
device::mojom::blink::XRSessionOptions::New();
session_options->mode = query->mode();
session_options->trace_id = query->TraceId();
outstanding_support_queries_.insert(query);
service_->SupportsSession(
std::move(session_options),
WTF::BindOnce(&XRSystem::OnSupportsSessionReturned, WrapPersistent(this),
WrapPersistent(query)));
return promise;
}
@ -951,69 +985,6 @@ void XRSystem::AddWebXrInternalsMessage(const String& message) {
}
}
void XRSystem::InternalIsSessionSupported(ScriptPromiseResolverBase* resolver,
const V8XRSessionMode& mode,
ExceptionState& exception_state,
bool throw_on_unsupported) {
if (!GetExecutionContext()) {
// Reject if the context is inaccessible.
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
kNavigatorDetachedError);
return; // Promise will be rejected by generated bindings
}
DisableBackForwardCache();
device::mojom::blink::XRSessionMode session_mode =
V8EnumToSessionMode(mode.AsEnum());
PendingSupportsSessionQuery* query =
MakeGarbageCollected<PendingSupportsSessionQuery>(resolver, session_mode,
throw_on_unsupported);
if (session_mode == device::mojom::blink::XRSessionMode::kImmersiveAr &&
!IsImmersiveArAllowed()) {
DVLOG(2) << __func__
<< ": Immersive AR session is only supported if WebXRARModule "
"feature is enabled by a runtime feature and web settings";
query->Resolve(false);
return;
}
if (session_mode == device::mojom::blink::XRSessionMode::kInline) {
// inline sessions are always supported.
query->Resolve(true);
return;
}
if (!GetExecutionContext()->IsFeatureEnabled(
network::mojom::PermissionsPolicyFeature::kWebXr,
ReportOptions::kReportOnFailure)) {
// Only allow the call to be made if the appropriate permissions policy is
// in place.
query->RejectWithSecurityError(kFeaturePolicyBlocked, &exception_state);
return;
}
// If TryEnsureService() doesn't set |service_|, then we don't have any WebXR
// hardware, so we need to reject as being unsupported.
TryEnsureService();
if (!service_.is_bound()) {
query->Resolve(false, &exception_state);
return;
}
device::mojom::blink::XRSessionOptionsPtr session_options =
device::mojom::blink::XRSessionOptions::New();
session_options->mode = query->mode();
session_options->trace_id = query->TraceId();
outstanding_support_queries_.insert(query);
service_->SupportsSession(
std::move(session_options),
WTF::BindOnce(&XRSystem::OnSupportsSessionReturned, WrapPersistent(this),
WrapPersistent(query)));
}
void XRSystem::RequestSessionInternal(
device::mojom::blink::XRSessionMode session_mode,
PendingRequestSessionQuery* query,

@ -88,9 +88,6 @@ class XRSystem final : public EventTarget,
DEFINE_ATTRIBUTE_EVENT_LISTENER(devicechange, kDevicechange)
ScriptPromise<IDLUndefined> supportsSession(ScriptState*,
const V8XRSessionMode&,
ExceptionState& exception_state);
ScriptPromise<IDLBoolean> isSessionSupported(ScriptState*,
const V8XRSessionMode&,
ExceptionState& exception_state);
@ -314,8 +311,7 @@ class XRSystem final : public EventTarget,
: public GarbageCollected<PendingSupportsSessionQuery> {
public:
PendingSupportsSessionQuery(ScriptPromiseResolverBase*,
device::mojom::blink::XRSessionMode,
bool throw_on_unsupported);
device::mojom::blink::XRSessionMode);
PendingSupportsSessionQuery(const PendingSupportsSessionQuery&) = delete;
PendingSupportsSessionQuery& operator=(const PendingSupportsSessionQuery&) =
@ -352,8 +348,6 @@ class XRSystem final : public EventTarget,
void RejectWithTypeError(const String& message,
ExceptionState* exception_state);
bool ThrowOnUnsupported() const { return throw_on_unsupported_; }
device::mojom::blink::XRSessionMode mode() const;
uint64_t TraceId() const { return trace_id_; }
@ -366,20 +360,12 @@ class XRSystem final : public EventTarget,
// Used for trace calls in order to correlate this request across processes.
const uint64_t trace_id_;
// Only set when calling the deprecated supportsSession method.
const bool throw_on_unsupported_ = false;
};
// Helper, logs message to the console as well as DVLOGs.
void AddConsoleMessage(mojom::blink::ConsoleMessageLevel error_level,
const String& message);
void InternalIsSessionSupported(ScriptPromiseResolverBase*,
const V8XRSessionMode&,
ExceptionState& exception_state,
bool throw_on_unsupported);
const char* CheckInlineSessionRequestAllowed(
LocalFrame* frame,
const PendingRequestSessionQuery& query);

@ -9,7 +9,6 @@
RuntimeEnabled=WebXR
] interface XRSystem : EventTarget {
attribute EventHandler ondevicechange;
[CallWith=ScriptState, DeprecateAs=XRSupportsSession, RaisesException] Promise<undefined> supportsSession(XRSessionMode mode);
[CallWith=ScriptState, MeasureAs=XRIsSessionSupported, RaisesException] Promise<boolean> isSessionSupported(XRSessionMode mode);
[CallWith=ScriptState, MeasureAs=XRRequestSession, RaisesException] Promise<XRSession> requestSession(XRSessionMode mode, optional XRSessionInit options = {});
};

@ -11502,7 +11502,6 @@ interface XRSystem : EventTarget
method constructor
method isSessionSupported
method requestSession
method supportsSession
setter ondevicechange
interface XRTransientInputHitTestResult
attribute @@toStringTag

@ -12568,7 +12568,6 @@ interface XRSystem : EventTarget
method constructor
method isSessionSupported
method requestSession
method supportsSession
setter ondevicechange
interface XRTransientInputHitTestResult
attribute @@toStringTag

@ -13,9 +13,9 @@ promise_test((t) => {
var nav_xr = window.frames[0].navigator.xr;
const dom_exception = window.frames[0].DOMException;
document.getElementById("subframe").remove();
return promise_rejects_dom(t, "InvalidStateError", dom_exception, nav_xr.supportsSession('inline'))
return promise_rejects_dom(t, "InvalidStateError", dom_exception, nav_xr.isSessionSupported('inline'))
.then(() => promise_rejects_dom(t, "InvalidStateError", dom_exception, nav_xr.requestSession('inline')));
}, "Check that navigator.xr.supportsSession and navigator.xr.requestSession reject on a detached navigator.");
}, "Check that navigator.xr.isSessionSupported and navigator.xr.requestSession reject on a detached navigator.");
</script>
</body>

@ -1,18 +0,0 @@
<!DOCTYPE html>
<body>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/webxr/resources/webxr_util.js"></script>
<script src="/webxr/resources/webxr_test_constants.js"></script>
<script>
// This test is chromium specific as though supportsSession is removed from
// the spec it is still implemented, albeit as a deprecated method, in
// chromium. Keeping this test until such time as it is removed.
xr_promise_test(
"supportsSession resolves when immersive options supported",
() => {
return navigator.xr.test.simulateDeviceConnection(TRACKED_IMMERSIVE_DEVICE)
.then( (controller) => navigator.xr.supportsSession('immersive-vr'));
});
</script>
</body>

@ -1,24 +0,0 @@
<!DOCTYPE html>
<body>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/webxr/resources/webxr_util.js"></script>
<script src="/webxr/resources/webxr_test_constants.js"></script>
<script>
// This test is chromium specific as though supportsSession is removed from
// the spec it is still implemented, albeit as a deprecated method, in
// chromium. Keeping this test until such time as it is removed.
xr_promise_test(
"supportsSession rejects when options not supported",
(t) => {
return navigator.xr.test.simulateDeviceConnection(VALID_NON_IMMERSIVE_DEVICE)
.then( (controller) => {
return promise_rejects_dom(
t,
"NotSupportedError",
navigator.xr.supportsSession('immersive-vr')
);
});
});
</script>
</body>

@ -1,21 +0,0 @@
<!DOCTYPE html>
<body>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/webxr/resources/webxr_util.js"></script>
<script src="/webxr/resources/webxr_test_constants.js"></script>
<script>
// This test is chromium specific as, though supportsSession is removed from
// the spec it is still implemented, albeit as a deprecated method, in
// chromium. Keeping this test until such time as it is removed.
xr_promise_test(
"supportsSession resolves when inline options supported",
(t) => {
return navigator.xr.test.simulateDeviceConnection(TRACKED_IMMERSIVE_DEVICE)
.then( (controller) => {
// Inline sessions should be supported.
return navigator.xr.supportsSession('inline');
});
});
</script>
</body>