feat(media): expose secure encrypted-media owner interfaces

This commit is contained in:
ldm0
2026-10-11 06:48:41 +08:00
committed by Donough Liu
parent 07c09b138e
commit 23c6bb5754
5 changed files with 68 additions and 0 deletions
@@ -120,6 +120,10 @@ const SECURE_CONTEXT_ONLY_INTERFACE_NAMES: &[&str] = &[
"ToolCancelEvent",
"WebTransportBidirectionalStream",
"WebTransportDatagramDuplexStream",
"MediaKeySession",
"MediaKeyStatusMap",
"MediaKeySystemAccess",
"MediaKeys",
"MediaDeviceInfo",
"InputDeviceInfo",
"DeviceMotionEvent",
@@ -1331,6 +1331,22 @@ const CONSTRUCTOR_SPECS_AFTER_STREAMS: &[ConstructorSpec] = &[
interface: web_api_interfaces::MediaRecorder::DESCRIPTOR,
kind: ConstructorKind::Shell { length: 1 },
},
ConstructorSpec {
interface: web_api_interfaces::MediaKeys::DESCRIPTOR,
kind: ConstructorKind::Illegal,
},
ConstructorSpec {
interface: web_api_interfaces::MediaKeySystemAccess::DESCRIPTOR,
kind: ConstructorKind::Illegal,
},
ConstructorSpec {
interface: web_api_interfaces::MediaKeyStatusMap::DESCRIPTOR,
kind: ConstructorKind::Illegal,
},
ConstructorSpec {
interface: web_api_interfaces::MediaKeySession::DESCRIPTOR,
kind: ConstructorKind::Illegal,
},
ConstructorSpec {
interface: web_api_interfaces::MediaError::DESCRIPTOR,
kind: ConstructorKind::MediaError,
@@ -0,0 +1,43 @@
use super::*;
#[test]
fn eme_owner_interface_exposure_interfaces_have_realm_local_constructors_and_exposure() {
for url in [
"https://interface-exposure.test/",
"http://interface-exposure.test/",
] {
let mut vm = new_storage_test_vm(url);
assert_eq!(vm.eval(r#"
(() => {
const assert = (ok, message) => { if (!ok) throw Error(message); };
const names = ["MediaKeySession", "MediaKeyStatusMap", "MediaKeySystemAccess", "MediaKeys"];
const parents = {"MediaKeySession": "EventTarget", "MediaKeyStatusMap": null, "MediaKeySystemAccess": null, "MediaKeys": null};
if (!document.documentElement) document.appendChild(document.createElement('html'));
if (!document.body) document.documentElement.appendChild(document.createElement('body'));
const child = document.createElement('iframe');
document.body.appendChild(child);
const other = child.contentWindow;
for (const realm of [window, other]) {
for (const name of names) {
if (!isSecureContext) {
assert(!(name in realm), name + ' unavailable outside secure contexts');
continue;
}
const C = realm[name];
assert(typeof C === 'function' && C.name === name && C.length === 0, name + ' constructor');
assert(C.prototype.constructor === C, name + ' prototype identity');
assert(Object.getPrototypeOf(C.prototype) === (parents[name] ? realm[parents[name]].prototype : realm.Object.prototype), name + ' prototype inheritance');
assert(realm[name] === C, name + ' stable lazy materialization');
for (const invoke of [() => C(), () => new C(), () => Reflect.construct(C, [], function Subclass() {})]) {
let error;
try { invoke(); } catch (caught) { error = caught; }
assert(error instanceof realm.TypeError, name + ' rejects construction in callee realm');
}
assert(C !== (realm === window ? other[name] : window[name]), name + ' distinct realm constructors');
}
}
return 'passed';
})()
"#).unwrap(), "passed", "{url}");
}
}
@@ -2151,6 +2151,7 @@ mod dom_elements;
mod dom_exception_proxy_identity;
mod dom_xhr;
mod element_click;
mod eme_owner_interface_exposure_interfaces;
mod encoded_video_chunk_shell;
mod event_receivers;
mod geometry_point_conversion_order;
@@ -306,6 +306,10 @@ interfaces! {
CanvasCaptureMediaStreamTrack: MediaStreamTrack;
MediaDevices: EventTarget;
MediaError;
MediaKeySession: EventTarget;
MediaKeyStatusMap;
MediaKeySystemAccess;
MediaKeys;
MediaList;
MediaQueryList: EventTarget;
MediaQueryListEvent: Event;