Automatic update from web-platform-tests Media Capabilities: add encryptionScheme to decodingInfo Based on the W3C spec for mediaCapabilities.decodingInfo (https://www.w3.org/TR/media-capabilities/#is-encrypted-decode-supported:~:text=Set%20the%20encryptionScheme%20attribute%20to%20config.keySystemConfiguration.video.encryptionScheme) , we should take `keySystemConfiguration.encryptionScheme` into consideration. KeySystemTrackConfiguration had `robustness` field only. The following JS script query returned "Supported" previously on the device that doesn't support "CBCS" which is wrong. ``` async function checkMediaCapabilitiesDecodingInfoSupport() { try { const mediaConfig = { type: 'media-source', video: { contentType: 'video/mp4; codecs="avc1.4d401f"', width: 1920, height: 1080, bitrate: 1972240, framerate: 24, }, audio: { contentType: 'audio/mp4; codecs="mp4a.40.2"', channels: 2, bitrate: 133940, samplerate: 44100, spatialRendering: false, }, keySystemConfiguration: { keySystem: 'com.microsoft.playready.recommendation.3000', persistentState: 'required', distinctiveIdentifier: 'required', video: { robustness: "", encryptionScheme: "cbcs", } } }; const support = await navigator.mediaCapabilities.decodingInfo(mediaConfig); if (support.supported && support.keySystemAccess) { console.log('Supported'); } else { console.log('Not Supported'); } } catch (error) { console.error('Error:', error); } } checkMediaCapabilitiesDecodingInfoSupport(); ``` After adding the `encryptionScheme` field, the same script returns "Not Supported". Bug: 498284510 Change-Id: Idc1ae433ddd63d380bb02ecccfdbea9c985f5b3f Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7722637 Commit-Queue: Sangbaek Park <sangbaekpark@chromium.org> Reviewed-by: Dale Curtis <dalecurtis@chromium.org> Reviewed-by: Mike Taylor <miketaylr@chromium.org> Cr-Commit-Position: refs/heads/main@{#1609563} -- wpt-commits: 8ef18929f39e6be566440766f4e9277cca76b6d3 wpt-pr: 58961
304 lines
9.2 KiB
HTML
304 lines
9.2 KiB
HTML
<!DOCTYPE html>
|
|
<title>MediaCapabilities.decodingInfo for encrypted media</title>
|
|
<meta name="timeout" content="long">
|
|
<script src=/resources/testharness.js></script>
|
|
<script src="/resources/testharnessreport.js"></script>
|
|
<script>
|
|
|
|
// Minimal VideoConfiguration that will be allowed per spec. All optional
|
|
// properties are missing.
|
|
var minimalVideoConfiguration = {
|
|
contentType: 'video/webm; codecs="vp09.00.10.08"',
|
|
width: 800,
|
|
height: 600,
|
|
bitrate: 3000,
|
|
framerate: 24,
|
|
};
|
|
|
|
// Minimal AudioConfiguration that will be allowed per spec. All optional
|
|
// properties are missing.
|
|
var minimalAudioConfiguration = {
|
|
contentType: 'audio/webm; codecs="opus"',
|
|
};
|
|
|
|
// Minimal MediaCapabilitiesKeySystemConfiguration that will be allowed per
|
|
// spec. All optional properties are missing.
|
|
var minimalKeySystemConfiguration = {
|
|
keySystem: 'org.w3.clearkey',
|
|
};
|
|
|
|
// Config with bogus name not provided by any UA.
|
|
var bogusKeySystemConfiguration = {
|
|
keySystem: 'bogus',
|
|
};
|
|
|
|
promise_test(t => {
|
|
return navigator.mediaCapabilities.decodingInfo({
|
|
type: 'file',
|
|
video: minimalVideoConfiguration,
|
|
keySystemConfiguration: minimalKeySystemConfiguration,
|
|
});
|
|
}, "Test that decodingInfo accepts a stub key system configuration (w/video).");
|
|
|
|
promise_test(t => {
|
|
return navigator.mediaCapabilities.decodingInfo({
|
|
type: 'file',
|
|
audio: minimalAudioConfiguration,
|
|
keySystemConfiguration: minimalKeySystemConfiguration,
|
|
});
|
|
}, "Test that decodingInfo accepts a stub key system configuration (w/audio).");
|
|
|
|
promise_test(t => {
|
|
return navigator.mediaCapabilities.decodingInfo({
|
|
type: 'file',
|
|
video: minimalVideoConfiguration,
|
|
keySystemConfiguration: {
|
|
keySystem: 'org.w3.clearkey',
|
|
video: {
|
|
robustness: '',
|
|
},
|
|
},
|
|
});
|
|
}, "Test that decodingInfo accepts a key system configuration with video info.");
|
|
|
|
promise_test(t => {
|
|
return navigator.mediaCapabilities.decodingInfo({
|
|
type: 'file',
|
|
audio: minimalAudioConfiguration,
|
|
keySystemConfiguration: {
|
|
keySystem: 'org.w3.clearkey',
|
|
audio : {
|
|
robustness: '',
|
|
},
|
|
},
|
|
});
|
|
}, "Test that decodingInfo accepts a key system configuration with audio info.");
|
|
|
|
promise_test(t => {
|
|
return promise_rejects_js(t, TypeError, navigator.mediaCapabilities.decodingInfo({
|
|
type: 'file',
|
|
audio: minimalAudioConfiguration,
|
|
keySystemConfiguration: {
|
|
keySystem: 'org.w3.clearkey',
|
|
video: {
|
|
robustness: '',
|
|
},
|
|
},
|
|
}));
|
|
}, "Test that decodingInfo rejects if robustness and configuration do not match (1).");
|
|
|
|
promise_test(t => {
|
|
return promise_rejects_js(t, TypeError, navigator.mediaCapabilities.decodingInfo({
|
|
type: 'file',
|
|
video: minimalVideoConfiguration,
|
|
keySystemConfiguration: {
|
|
keySystem: 'org.w3.clearkey',
|
|
audio : {
|
|
robustness: '',
|
|
},
|
|
},
|
|
}));
|
|
}, "Test that decodingInfo rejects if robustness and configuration do not match (2).");
|
|
|
|
promise_test(t => {
|
|
return promise_rejects_js(t, TypeError, navigator.mediaCapabilities.decodingInfo({
|
|
type: 'file',
|
|
video: minimalVideoConfiguration,
|
|
keySystemConfiguration: {
|
|
keySystem: 'org.w3.clearkey',
|
|
audio : {
|
|
robustness: '',
|
|
},
|
|
video: {
|
|
robustness: '',
|
|
},
|
|
},
|
|
}));
|
|
}, "Test that decodingInfo rejects if robustness and configuration do not match (3).");
|
|
|
|
promise_test(t => {
|
|
return promise_rejects_js(t, TypeError, navigator.mediaCapabilities.decodingInfo({
|
|
type: 'file',
|
|
audio: minimalAudioConfiguration,
|
|
video: minimalVideoConfiguration,
|
|
keySystemConfiguration: {
|
|
keySystem: 'org.w3.clearkey',
|
|
audio : {
|
|
robustness: '',
|
|
},
|
|
video: {
|
|
robustness: '',
|
|
},
|
|
persistentState: "foobar",
|
|
},
|
|
}));
|
|
}, "Test that decodingInfo rejects if persistentState isn't valid.");
|
|
|
|
promise_test(t => {
|
|
return promise_rejects_js(t, TypeError, navigator.mediaCapabilities.decodingInfo({
|
|
type: 'file',
|
|
audio: minimalAudioConfiguration,
|
|
video: minimalVideoConfiguration,
|
|
keySystemConfiguration: {
|
|
keySystem: 'org.w3.clearkey',
|
|
audio : {
|
|
robustness: '',
|
|
},
|
|
video: {
|
|
robustness: '',
|
|
},
|
|
distinctiveIdentifier: "foobar",
|
|
},
|
|
}));
|
|
}, "Test that decodingInfo rejects if distinctiveIdentifier isn't valid.");
|
|
|
|
promise_test(t => {
|
|
return promise_rejects_js(t, TypeError, navigator.mediaCapabilities.decodingInfo({
|
|
type: 'file',
|
|
audio: minimalAudioConfiguration,
|
|
video: minimalVideoConfiguration,
|
|
keySystemConfiguration: {
|
|
keySystem: 'org.w3.clearkey',
|
|
audio : {
|
|
robustness: '',
|
|
},
|
|
video: {
|
|
robustness: '',
|
|
},
|
|
sessionTypes: "foobar",
|
|
},
|
|
}));
|
|
}, "Test that decodingInfo rejects if sessionTypes isn't a sequence.");
|
|
|
|
promise_test(t => {
|
|
return navigator.mediaCapabilities.decodingInfo({
|
|
type: 'file',
|
|
audio: minimalAudioConfiguration,
|
|
video: minimalVideoConfiguration,
|
|
keySystemConfiguration: {
|
|
keySystem: {},
|
|
initDataType: {},
|
|
audio : {
|
|
robustness: '',
|
|
},
|
|
video: {
|
|
robustness: '',
|
|
},
|
|
},
|
|
});
|
|
}, "Test that decodingInfo does not reject when properties are set to unexpected values.");
|
|
|
|
promise_test(t => {
|
|
return navigator.mediaCapabilities.decodingInfo({
|
|
type: 'file',
|
|
video: minimalVideoConfiguration,
|
|
audio: minimalAudioConfiguration,
|
|
keySystemConfiguration: minimalKeySystemConfiguration,
|
|
}).then(ability => {
|
|
assert_equals(typeof ability.supported, "boolean");
|
|
assert_equals(typeof ability.smooth, "boolean");
|
|
assert_equals(typeof ability.powerEfficient, "boolean");
|
|
assert_equals(typeof ability.keySystemAccess, "object");
|
|
});
|
|
}, "Test that decodingInfo returns a valid MediaCapabilitiesDecodingInfo objects with encrypted media");
|
|
|
|
promise_test(t => {
|
|
return navigator.mediaCapabilities.decodingInfo({
|
|
type: 'file',
|
|
video: minimalVideoConfiguration,
|
|
keySystemConfiguration: {
|
|
keySystem: 'foobar',
|
|
video: {
|
|
robustness: '',
|
|
},
|
|
}
|
|
}).then(ability => {
|
|
assert_false(ability.supported);
|
|
assert_false(ability.smooth);
|
|
assert_false(ability.powerEfficient);
|
|
assert_equals(ability.keySystemAccess, null);
|
|
});
|
|
}, "Test that random key systems are reported as non supported.");
|
|
|
|
// TODO(mlamouri): this test could be split in two tests for which codec support
|
|
// across browsers is widely compatible: one when all browsers wouldn't support
|
|
// and one where all browsers do support. The current approach is to check that
|
|
// the answer is consistent to the spec.
|
|
promise_test(t => {
|
|
return navigator.mediaCapabilities.decodingInfo({
|
|
type: 'file',
|
|
video: minimalVideoConfiguration,
|
|
audio: minimalAudioConfiguration,
|
|
keySystemConfiguration: minimalKeySystemConfiguration,
|
|
}).then(ability => {
|
|
if (ability.supported)
|
|
assert_not_equals(ability.keySystemAccess, null);
|
|
else
|
|
assert_equals(ability.keySystemAccess, null);
|
|
});
|
|
}, "Test that keySystemAccess is only null when not supported if keySystemConfiguration was used.");
|
|
|
|
promise_test(t => {
|
|
return navigator.mediaCapabilities.decodingInfo({
|
|
type: 'file',
|
|
video: minimalVideoConfiguration,
|
|
audio: minimalAudioConfiguration,
|
|
// Supply bogus config to reliably result in a null keySystemAccess.
|
|
keySystemConfiguration: bogusKeySystemConfiguration,
|
|
}).then(ability => {
|
|
assert_equals(ability.keySystemAccess, null);
|
|
assert_false(ability.supported);
|
|
});
|
|
}, "Test that supported=false when keySystemConfiguration is unsupported.");
|
|
|
|
promise_test(t => {
|
|
return promise_rejects_js(t, TypeError, navigator.mediaCapabilities.decodingInfo({
|
|
type: 'webrtc',
|
|
video: minimalVideoConfiguration,
|
|
keySystemConfiguration: minimalKeySystemConfiguration,
|
|
}));
|
|
}, "Test that decodingInfo with type webrtc rejects key system configuration.");
|
|
|
|
promise_test(async t => {
|
|
const config = {
|
|
type: 'file',
|
|
video: minimalVideoConfiguration,
|
|
audio: minimalAudioConfiguration,
|
|
keySystemConfiguration: {
|
|
keySystem: 'org.w3.clearkey',
|
|
video: {
|
|
robustness: '',
|
|
encryptionScheme: 'cenc' // <- New field being tested
|
|
}
|
|
}
|
|
};
|
|
|
|
const result = await navigator.mediaCapabilities.decodingInfo(config);
|
|
|
|
// As long as it resolves to an object with `supported` (even if false),
|
|
// the IDL parser correctly digested `encryptionScheme`.
|
|
assert_equals(typeof result.supported, 'boolean', "supported should be a boolean");
|
|
assert_equals(typeof result.smooth, 'boolean', "smooth should be a boolean");
|
|
assert_equals(typeof result.powerEfficient, 'boolean', "powerEfficient should be a boolean");
|
|
}, "decodingInfo() accepts KeySystemTrackConfiguration with encryptionScheme");
|
|
|
|
promise_test(async t => {
|
|
const config = {
|
|
type: 'file',
|
|
video: minimalVideoConfiguration,
|
|
audio: minimalAudioConfiguration,
|
|
keySystemConfiguration: {
|
|
keySystem: 'org.w3.clearkey',
|
|
video: {
|
|
robustness: '',
|
|
encryptionScheme: null // <- Explicitly testing nullable
|
|
}
|
|
}
|
|
};
|
|
|
|
const result = await navigator.mediaCapabilities.decodingInfo(config);
|
|
assert_equals(typeof result.supported, 'boolean');
|
|
}, "decodingInfo() accepts KeySystemTrackConfiguration with null encryptionScheme");
|
|
|
|
</script>
|