<!DOCTYPE html>
<html>
<head>
<title>Test Encryption Scheme</title>
<script src="encrypted-media-utils.js"></script>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
</head>
<body>
<script>
// Checks that calling navigator.requestMediaKeySystemAccess()
// with |configuration| selects a configuration where the first
// entry in audioCapabilities and videoCapabilities contains
// encryptionScheme of |expectedAudioScheme| or
// |expectedVideoScheme|, respectively. If |expectedAudioScheme| or
// |expectedVideoScheme| is undefined, then no corresponding
// capability should have been selected.
function expectSupport(configuration, expectedAudioScheme, expectedVideoScheme, testName) {
promise_test(async test => {
var access = await navigator.requestMediaKeySystemAccess('org.w3.clearkey', configuration);
var result = access.getConfiguration();
if (result.audioCapabilities.length > 0) {
assert_equals(result.audioCapabilities[0].encryptionScheme, expectedAudioScheme, 'audio scheme');
} else {
assert_equals(undefined, expectedAudioScheme, 'expected audio scheme missing');
}
if (result.videoCapabilities.length > 0) {
assert_equals(result.videoCapabilities[0].encryptionScheme, expectedVideoScheme, 'video scheme');
} else {
assert_equals(undefined, expectedVideoScheme, 'expected video scheme missing');
}
}, testName);
}
// Verifies that calling navigator.requestMediaKeySystemAccess()
// with |configuration| fails (due to no encryptionScheme being
// supported).
function expectFailure(configuration, testName) {
promise_test(async test => {
try {
await navigator.requestMediaKeySystemAccess('org.w3.clearkey', configuration);
assert_unreached('Unexpected requestMediaKeySystemAccess() success.');
} catch(error) {
// Error is what we want to happen.
}
}, testName);
}
// Creates an audioCapabilities sequence with one entry, including
// |encryption_scheme| if specified.
function getAudioCapabilities(encryptionScheme) {
var capability = [{contentType: 'audio/webm; codecs="opus"'}];
if (encryptionScheme !== undefined) {
capability[0].encryptionScheme = encryptionScheme;
}
return capability;
}
// Creates an videoCapabilities sequence with one entry, including
// |encryption_scheme| if specified.
function getVideoCapabilities(encryptionScheme) {
var capability = [{contentType: 'video/webm; codecs="vp8"'}];
if (encryptionScheme !== undefined) {
capability[0].encryptionScheme = encryptionScheme;
}
return capability;
}
// Takes a set of capabilities (passed as arguments) and combines
// them into a MediaKeySystemConfiguration dictionary. If multiple
// arguments define the same property, the last one overrides the
// previous entry.
function buildConfiguration() {
var configuration = { initDataTypes : [ 'webm' ] };
for (var i = 0; i < arguments.length; i++) {
for (var arg in arguments[i]) {
if (arg == 'audio') {
configuration['audioCapabilities'] =
getAudioCapabilities(arguments[i][arg]);
} else if (arg == 'video') {
configuration['videoCapabilities'] =
getVideoCapabilities(arguments[i][arg]);
}
}
}
return configuration;
}
// Test "cenc".
expectSupport([buildConfiguration({audio: 'cenc'})],
'cenc', undefined, 'Audio supports cenc');
expectSupport([buildConfiguration({video: 'cenc'})],
undefined, 'cenc', 'Video supports cenc');
expectSupport([buildConfiguration({audio: 'cenc'}, {video: 'cenc'})],
'cenc', 'cenc', 'Audio and Video supports cenc');
// Test "cbcs".
expectSupport([buildConfiguration({audio: 'cbcs'})],
'cbcs', undefined, 'Audio supports cbcs');
expectSupport([buildConfiguration({video: 'cbcs'})],
undefined, 'cbcs', 'Video supports cbcs');
expectSupport([buildConfiguration({audio: 'cbcs'}, {video: 'cbcs'})],
'cbcs', 'cbcs', 'Audio and Video supports cbcs');
// Test "cbcs-1-9".
expectSupport([buildConfiguration({audio: 'cbcs-1-9'})],
'cbcs-1-9', undefined, 'Audio supports cbcs-1-9');
expectSupport([buildConfiguration({video: 'cbcs-1-9'})],
undefined, 'cbcs-1-9', 'Video supports cbcs-1-9');
expectSupport([buildConfiguration({audio: 'cbcs-1-9'}, {video: 'cbcs-1-9'})],
'cbcs-1-9', 'cbcs-1-9', 'Audio and Video supports cbcs-1-9');
// Test "invalid", which should fail.
expectFailure([buildConfiguration({audio: 'invalid'})],
'Audio fails with invalid scheme');
expectFailure([buildConfiguration({video: 'invalid'})],
'Video fails with invalid scheme');
expectFailure([buildConfiguration({audio: 'invalid'}, {video: 'invalid'})],
'Audio and Video fails with invalid scheme');
expectFailure([buildConfiguration({audio: 'cenc'}, {video: 'invalid'})],
'Audio valid, Video invalid scheme');
expectFailure([buildConfiguration({audio: 'invalid'}, {video: 'cbcs'})],
'Audio invalid scheme, Video valid with cbcs');
expectFailure([buildConfiguration({audio: 'invalid'}, {video: 'cbcs-1-9'})],
'Audio invalid scheme, Video valid with cbcs-1-9');
// Test without encryptionScheme.
expectSupport([buildConfiguration({audio: null})],
null, undefined, 'Audio handles missing encryptionScheme');
expectSupport([buildConfiguration({video: null})],
undefined, null, 'Video handles missing encryptionScheme');
expectSupport([buildConfiguration({audio: null}, {video: null})],
null, null, 'Audio and Video handles missing encryptionScheme');
expectSupport([buildConfiguration({audio: 'cbcs'}, {video: null})],
'cbcs', null, 'Audio valid and Video missing');
expectSupport([buildConfiguration({audio: null}, {video: 'cbcs'})],
null, 'cbcs', 'Audio missing and Video valid');
// Test with "", which is invalid.
expectFailure([buildConfiguration({audio: ''})],
'Audio handles empty encryptionScheme');
expectFailure([buildConfiguration({video: ''})],
'Video handles empty encryptionScheme');
expectFailure([buildConfiguration({audio: ''}, {video: ''})],
'Audio and Video handles empty encryptionScheme');
expectFailure([buildConfiguration({audio: 'cbcs'}, {video: ''})],
'Audio valid and Video empty');
expectFailure([buildConfiguration({audio: ''}, {video: 'cbcs'})],
'Audio empty and Video valid');
// Test mixed combinations.
expectSupport([buildConfiguration({audio: 'cenc'}, {video: 'cbcs'})],
'cenc', 'cbcs', 'Audio supports cenc and Video supports cbcs');
expectSupport([buildConfiguration({audio: 'cenc'}, {video: 'cbcs-1-9'})],
'cenc', 'cbcs-1-9', 'Audio supports cenc and Video supports cbcs-1-9');
expectSupport([buildConfiguration({audio: 'cbcs'}, {video: 'cenc'})],
'cbcs', 'cenc', 'Audio supports cbcs and Video supports cenc');
expectSupport([buildConfiguration({audio: 'cbcs'}, {video: 'cbcs-1-9'})],
'cbcs', 'cbcs-1-9', 'Audio supports cbcs and Video supports cbcs-1-9');
expectSupport([buildConfiguration({audio: 'cbcs-1-9'}, {video: 'cenc'})],
'cbcs-1-9', 'cenc', 'Audio supports cbcs-1-9 and Video supports cenc');
expectSupport([buildConfiguration({audio: 'cbcs-1-9'}, {video: 'cbcs'})],
'cbcs-1-9', 'cbcs', 'Audio supports cbcs-1-9 and Video supports cbcs');
// Test multiple configurations.
expectSupport([buildConfiguration({audio: 'cenc'}),
buildConfiguration({audio: 'cbcs'})],
'cenc', undefined, 'Multiple audio entries supports cenc');
expectSupport([buildConfiguration({audio: 'cbcs'}),
buildConfiguration({audio: 'cenc'})],
'cbcs', undefined, 'Multiple audio entries supports cbcs');
expectSupport([buildConfiguration({video: 'cenc'}),
buildConfiguration({video: 'cbcs'})],
undefined, 'cenc', 'Multiple video entries supports cenc');
expectSupport([buildConfiguration({video: 'cbcs'}),
buildConfiguration({video: 'cenc'})],
undefined, 'cbcs', 'Multiple video entries supports cbcs');
// Test mixed multiple configurations.
expectSupport([buildConfiguration({audio: 'cenc'}),
buildConfiguration({video: 'cbcs'})],
'cenc', undefined, 'Mixed entries supports cenc');
expectSupport([buildConfiguration({video: 'cbcs'}),
buildConfiguration({audio: 'cenc'})],
undefined, 'cbcs', 'Mixed entries supports cbcs');
// Test invalid values.
expectFailure([buildConfiguration({audio: 3})],
'Audio fails with numeric scheme');
expectFailure([buildConfiguration({audio: [1, 2, 3]})],
'Audio fails with array scheme');
expectFailure([buildConfiguration({audio: {test: 'test'}})],
'Audio fails with object scheme');
</script>
</body>
</html>