Files
sousa-gecko/testing/web-platform/tests/media-capabilities/decodingInfoEncryptedMedia.https.html
T
Sangbaek Park 0d504401db Bug 2029073 [wpt PR 58961] - Media Capabilities: add encryptionScheme to decodingInfo, a=testonly
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
2026-04-17 08:37:33 +00:00

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>