From 43a97878ce14b72f0981164f87f2e35e14151312 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 11:22:09 +0200 Subject: Adding upstream version 110.0.1. Signed-off-by: Daniel Baumann --- .../web-platform/tests/encrypted-media/META.yml | 6 + .../web-platform/tests/encrypted-media/README.md | 7 + .../clearkey-check-encryption-scheme.https.html | 32 ++ .../clearkey-check-initdata-type.https.html | 32 ++ .../clearkey-check-status-for-hdcp.https.html | 32 ++ ...clearkey-events-session-closed-event.https.html | 40 ++ .../encrypted-media/clearkey-events.https.html | 43 ++ ...ey-generate-request-disallowed-input.https.html | 31 ++ .../clearkey-invalid-license.https.html | 30 ++ ...earkey-keystatuses-multiple-sessions.https.html | 50 ++ .../clearkey-keystatuses.https.html | 49 ++ ...-playback-destroy-persistent-license.https.html | 51 +++ ...4-playback-persistent-license-events.https.html | 51 +++ ...rkey-mp4-playback-persistent-license.https.html | 51 +++ ...yback-persistent-usage-record-events.https.html | 51 +++ ...mp4-playback-persistent-usage-record.https.html | 51 +++ ...-retrieve-destroy-persistent-license.https.html | 52 +++ ...playback-retrieve-persistent-license.https.html | 52 +++ ...ack-retrieve-persistent-usage-record.https.html | 51 +++ ...-temporary-clear-encrypted-segmented.https.html | 59 +++ ...4-playback-temporary-clear-encrypted.https.html | 52 +++ ...ck-temporary-encrypted-clear-sources.https.html | 58 +++ ...4-playback-temporary-encrypted-clear.https.html | 52 +++ ...earkey-mp4-playback-temporary-events.https.html | 51 +++ ...orary-multikey-sequential-readyState.https.html | 54 +++ ...ayback-temporary-multikey-sequential.https.html | 53 +++ ...rkey-mp4-playback-temporary-multikey.https.html | 52 +++ ...-mp4-playback-temporary-multisession.https.html | 51 +++ ...ack-temporary-setMediaKeys-after-src.https.html | 51 +++ ...-temporary-setMediaKeys-after-update.https.html | 51 +++ ...k-temporary-setMediaKeys-immediately.https.html | 51 +++ ...k-temporary-setMediaKeys-onencrypted.https.html | 51 +++ ...ey-mp4-playback-temporary-two-videos.https.html | 54 +++ ...mp4-playback-temporary-waitingforkey.https.html | 51 +++ .../clearkey-mp4-playback-temporary.https.html | 51 +++ ...rkey-mp4-requestmediakeysystemaccess.https.html | 39 ++ ...key-mp4-reset-src-after-setmediakeys.https.html | 46 ++ ...p4-setmediakeys-again-after-playback.https.html | 52 +++ ...tmediakeys-again-after-resetting-src.https.html | 52 +++ ...earkey-mp4-setmediakeys-at-same-time.https.html | 42 ++ ...tiple-times-with-different-mediakeys.https.html | 48 ++ ...ltiple-times-with-the-same-mediakeys.https.html | 48 ++ ...mediakeys-to-multiple-video-elements.https.html | 46 ++ .../clearkey-mp4-setmediakeys.https.html | 40 ++ .../clearkey-mp4-syntax-mediakeys.https.html | 41 ++ .../clearkey-mp4-syntax-mediakeysession.https.html | 41 ++ ...rkey-mp4-syntax-mediakeysystemaccess.https.html | 41 ++ .../clearkey-mp4-unique-origin.https.html | 42 ++ ...clearkey-mp4-update-disallowed-input.https.html | 28 ++ .../clearkey-mp4-waiting-for-a-key.https.html | 51 +++ ...key-not-callable-after-createsession.https.html | 31 ++ .../clearkey-update-non-ascii-input.https.html | 36 ++ .../content/audio_aac-lc_128k_2keys_2sess.mp4 | Bin 0 -> 166614 bytes .../content/audio_aac-lc_128k_dashinit.mp4 | Bin 0 -> 85332 bytes .../content/audio_aac-lc_128k_enc_dashinit.mp4 | Bin 0 -> 90594 bytes .../encrypted-media/content/content-metadata.js | 274 +++++++++++ .../video_512x288_h264-360k_clear_dashinit.mp4 | Bin 0 -> 238401 bytes .../video_512x288_h264-360k_clear_enc_dashinit.mp4 | Bin 0 -> 241564 bytes .../content/video_512x288_h264-360k_dashinit.mp4 | Bin 0 -> 1425859 bytes .../video_512x288_h264-360k_enc_2keys_2sess.mp4 | Bin 0 -> 475456 bytes .../video_512x288_h264-360k_enc_clear_dashinit.mp4 | Bin 0 -> 241049 bytes .../video_512x288_h264-360k_enc_dashinit.mp4 | Bin 0 -> 241862 bytes .../video_512x288_h264-360k_multikey_dashinit.mp4 | Bin 0 -> 246574 bytes .../drm-check-encryption-scheme.https.html | 32 ++ .../drm-check-initdata-type.https.html | 32 ++ .../drm-check-status-for-hdcp.https.html | 32 ++ .../drm-events-session-closed-event.https.html | 39 ++ .../tests/encrypted-media/drm-events.https.html | 71 +++ .../encrypted-media/drm-expiration.https.html | 67 +++ ...rm-generate-request-disallowed-input.https.html | 31 ++ .../encrypted-media/drm-invalid-license.https.html | 31 ++ .../drm-keystatuses-multiple-sessions.https.html | 55 +++ .../encrypted-media/drm-keystatuses.https.html | 52 +++ .../encrypted-media/drm-mp4-onencrypted.https.html | 46 ++ ...-playback-destroy-persistent-license.https.html | 52 +++ ...4-playback-persistent-license-events.https.html | 52 +++ .../drm-mp4-playback-persistent-license.https.html | 52 +++ ...yback-persistent-usage-record-events.https.html | 53 +++ ...mp4-playback-persistent-usage-record.https.html | 53 +++ ...-retrieve-destroy-persistent-license.https.html | 54 +++ ...playback-retrieve-persistent-license.https.html | 53 +++ ...ack-retrieve-persistent-usage-record.https.html | 53 +++ ...4-playback-temporary-clear-encrypted.https.html | 53 +++ ...ck-temporary-encrypted-clear-sources.https.html | 58 +++ ...4-playback-temporary-encrypted-clear.https.html | 53 +++ .../drm-mp4-playback-temporary-events.https.html | 52 +++ .../drm-mp4-playback-temporary-expired.https.html | 52 +++ ...orary-multikey-sequential-readyState.https.html | 57 +++ ...ayback-temporary-multikey-sequential.https.html | 56 +++ .../drm-mp4-playback-temporary-multikey.https.html | 52 +++ ...-mp4-playback-temporary-multisession.https.html | 55 +++ ...-playback-temporary-playduration-keystatus.html | 52 +++ .../drm-mp4-playback-temporary-playduration.html | 52 +++ ...ack-temporary-setMediaKeys-after-src.https.html | 52 +++ ...-temporary-setMediaKeys-after-update.https.html | 52 +++ ...k-temporary-setMediaKeys-immediately.https.html | 52 +++ ...k-temporary-setMediaKeys-onencrypted.https.html | 52 +++ ...rm-mp4-playback-temporary-two-videos.https.html | 54 +++ ...mp4-playback-temporary-waitingforkey.https.html | 53 +++ .../drm-mp4-playback-temporary.https.html | 52 +++ .../drm-mp4-requestmediakeysystemaccess.https.html | 39 ++ ...drm-mp4-reset-src-after-setmediakeys.https.html | 45 ++ ...p4-setmediakeys-again-after-playback.https.html | 52 +++ ...tmediakeys-again-after-resetting-src.https.html | 52 +++ .../drm-mp4-setmediakeys-at-same-time.https.html | 44 ++ ...tiple-times-with-different-mediakeys.https.html | 50 ++ ...ltiple-times-with-the-same-mediakeys.https.html | 50 ++ ...mediakeys-to-multiple-video-elements.https.html | 48 ++ .../drm-mp4-setmediakeys.https.html | 40 ++ .../drm-mp4-syntax-mediakeys.https.html | 42 ++ .../drm-mp4-syntax-mediakeysession.https.html | 42 ++ .../drm-mp4-syntax-mediakeysystemaccess.https.html | 42 ++ .../drm-mp4-unique-origin.https.html | 43 ++ .../drm-mp4-waiting-for-a-key.https.html | 52 +++ ...drm-not-callable-after-createsession.https.html | 31 ++ .../drm-temporary-license-type.https.html | 71 +++ ...ted-media-default-feature-policy.https.sub.html | 20 + ...edia-supported-by-feature-policy.tentative.html | 11 + .../tests/encrypted-media/idlharness.https.html | 36 ++ .../encrypted-media/polyfill/cast-polyfill.js | 80 ++++ .../encrypted-media/polyfill/chrome-polyfill.js | 37 ++ .../encrypted-media/polyfill/clearkey-polyfill.js | 510 +++++++++++++++++++++ .../encrypted-media/polyfill/edge-keystatuses.js | 144 ++++++ .../polyfill/edge-persistent-usage-record.js | 193 ++++++++ .../encrypted-media/polyfill/firefox-polyfill.js | 23 + .../polyfill/make-polyfill-tests.py | 32 ++ ...earkey-retrieve-destroy-persistent-license.html | 105 +++++ .../clearkey-retrieve-persistent-license.html | 74 +++ .../drm-retrieve-destroy-persistent-license.html | 106 +++++ .../resources/drm-retrieve-persistent-license.html | 77 ++++ .../drm-retrieve-persistent-usage-record.html | 70 +++ .../retrieve-persistent-usage-record.html | 92 ++++ .../scripts/check-encryption-scheme.js | 46 ++ .../encrypted-media/scripts/check-initdata-type.js | 35 ++ .../scripts/check-status-for-hdcp.js | 26 ++ .../scripts/clearkey-update-non-ascii-input.js | 52 +++ .../scripts/events-session-closed-event.js | 52 +++ .../tests/encrypted-media/scripts/events.js | 59 +++ .../tests/encrypted-media/scripts/expiration.js | 43 ++ .../scripts/generate-request-disallowed-input.js | 72 +++ .../encrypted-media/scripts/invalid-license.js | 38 ++ .../scripts/keystatuses-multiple-sessions.js | 103 +++++ .../tests/encrypted-media/scripts/keystatuses.js | 165 +++++++ .../scripts/not-callable-after-createsession.js | 50 ++ .../tests/encrypted-media/scripts/onencrypted.js | 48 ++ .../scripts/playback-destroy-persistent-license.js | 95 ++++ .../scripts/playback-persistent-license-events.js | 158 +++++++ .../scripts/playback-persistent-license.js | 77 ++++ .../playback-persistent-usage-record-events.js | 109 +++++ .../scripts/playback-persistent-usage-record.js | 104 +++++ .../playback-retrieve-persistent-license.js | 115 +++++ .../playback-retrieve-persistent-usage-record.js | 114 +++++ ...-temporary-encrypted-clear-segmented-sources.js | 109 +++++ .../playback-temporary-encrypted-clear-sources.js | 109 +++++ .../scripts/playback-temporary-events.js | 131 ++++++ .../scripts/playback-temporary-expired.js | 95 ++++ .../playback-temporary-multikey-sequential.js | 122 +++++ .../scripts/playback-temporary-multisession.js | 76 +++ .../playback-temporary-playduration-keystatus.js | 78 ++++ .../scripts/playback-temporary-playduration.js | 80 ++++ .../scripts/playback-temporary-setMediaKeys.js | 105 +++++ .../scripts/playback-temporary-two-videos.js | 83 ++++ .../scripts/playback-temporary-waitingforkey.js | 71 +++ .../encrypted-media/scripts/playback-temporary.js | 82 ++++ .../scripts/requestmediakeysystemaccess.js | 341 ++++++++++++++ .../scripts/reset-src-after-setmediakeys.js | 61 +++ .../scripts/setmediakeys-again-after-playback.js | 79 ++++ .../setmediakeys-again-after-resetting-src.js | 79 ++++ .../scripts/setmediakeys-at-same-time.js | 59 +++ ...keys-multiple-times-with-different-mediakeys.js | 98 ++++ ...akeys-multiple-times-with-the-same-mediakeys.js | 46 ++ .../setmediakeys-to-multiple-video-elements.js | 54 +++ .../tests/encrypted-media/scripts/setmediakeys.js | 50 ++ .../encrypted-media/scripts/syntax-mediakeys.js | 184 ++++++++ .../scripts/syntax-mediakeysession.js | 452 ++++++++++++++++++ .../scripts/syntax-mediakeysystemaccess.js | 147 ++++++ .../scripts/temporary-license-type.js | 61 +++ .../tests/encrypted-media/scripts/unique-origin.js | 64 +++ .../scripts/update-disallowed-input.js | 43 ++ .../encrypted-media/scripts/waiting-for-a-key.js | 166 +++++++ .../util/clearkey-messagehandler.js | 64 +++ .../encrypted-media/util/drm-messagehandler.js | 265 +++++++++++ .../tests/encrypted-media/util/testmediasource.js | 49 ++ .../tests/encrypted-media/util/utf8.js | 2 + .../tests/encrypted-media/util/utils.js | 293 ++++++++++++ 185 files changed, 12183 insertions(+) create mode 100644 testing/web-platform/tests/encrypted-media/META.yml create mode 100644 testing/web-platform/tests/encrypted-media/README.md create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-check-encryption-scheme.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-check-initdata-type.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-check-status-for-hdcp.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-events-session-closed-event.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-events.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-generate-request-disallowed-input.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-invalid-license.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-keystatuses-multiple-sessions.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-keystatuses.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-destroy-persistent-license.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-persistent-license-events.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-persistent-license.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-persistent-usage-record-events.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-persistent-usage-record.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-retrieve-destroy-persistent-license.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-retrieve-persistent-license.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-retrieve-persistent-usage-record.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-clear-encrypted-segmented.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-clear-encrypted.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-encrypted-clear-sources.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-encrypted-clear.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-events.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-multikey-sequential-readyState.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-multikey-sequential.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-multikey.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-multisession.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-setMediaKeys-after-src.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-setMediaKeys-after-update.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-setMediaKeys-immediately.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-setMediaKeys-onencrypted.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-two-videos.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-waitingforkey.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-mp4-requestmediakeysystemaccess.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-mp4-reset-src-after-setmediakeys.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-mp4-setmediakeys-again-after-playback.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-mp4-setmediakeys-again-after-resetting-src.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-mp4-setmediakeys-at-same-time.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-mp4-setmediakeys-multiple-times-with-different-mediakeys.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-mp4-setmediakeys-multiple-times-with-the-same-mediakeys.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-mp4-setmediakeys-to-multiple-video-elements.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-mp4-setmediakeys.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-mp4-syntax-mediakeys.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-mp4-syntax-mediakeysession.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-mp4-syntax-mediakeysystemaccess.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-mp4-unique-origin.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-mp4-update-disallowed-input.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-mp4-waiting-for-a-key.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-not-callable-after-createsession.https.html create mode 100644 testing/web-platform/tests/encrypted-media/clearkey-update-non-ascii-input.https.html create mode 100644 testing/web-platform/tests/encrypted-media/content/audio_aac-lc_128k_2keys_2sess.mp4 create mode 100644 testing/web-platform/tests/encrypted-media/content/audio_aac-lc_128k_dashinit.mp4 create mode 100644 testing/web-platform/tests/encrypted-media/content/audio_aac-lc_128k_enc_dashinit.mp4 create mode 100644 testing/web-platform/tests/encrypted-media/content/content-metadata.js create mode 100644 testing/web-platform/tests/encrypted-media/content/video_512x288_h264-360k_clear_dashinit.mp4 create mode 100644 testing/web-platform/tests/encrypted-media/content/video_512x288_h264-360k_clear_enc_dashinit.mp4 create mode 100644 testing/web-platform/tests/encrypted-media/content/video_512x288_h264-360k_dashinit.mp4 create mode 100644 testing/web-platform/tests/encrypted-media/content/video_512x288_h264-360k_enc_2keys_2sess.mp4 create mode 100644 testing/web-platform/tests/encrypted-media/content/video_512x288_h264-360k_enc_clear_dashinit.mp4 create mode 100644 testing/web-platform/tests/encrypted-media/content/video_512x288_h264-360k_enc_dashinit.mp4 create mode 100644 testing/web-platform/tests/encrypted-media/content/video_512x288_h264-360k_multikey_dashinit.mp4 create mode 100644 testing/web-platform/tests/encrypted-media/drm-check-encryption-scheme.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-check-initdata-type.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-check-status-for-hdcp.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-events-session-closed-event.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-events.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-expiration.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-generate-request-disallowed-input.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-invalid-license.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-keystatuses-multiple-sessions.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-keystatuses.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-mp4-onencrypted.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-mp4-playback-destroy-persistent-license.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-mp4-playback-persistent-license-events.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-mp4-playback-persistent-license.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-mp4-playback-persistent-usage-record-events.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-mp4-playback-persistent-usage-record.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-mp4-playback-retrieve-destroy-persistent-license.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-mp4-playback-retrieve-persistent-license.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-mp4-playback-retrieve-persistent-usage-record.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-clear-encrypted.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-encrypted-clear-sources.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-encrypted-clear.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-events.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-expired.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-multikey-sequential-readyState.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-multikey-sequential.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-multikey.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-multisession.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-playduration-keystatus.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-playduration.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-setMediaKeys-after-src.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-setMediaKeys-after-update.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-setMediaKeys-immediately.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-setMediaKeys-onencrypted.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-two-videos.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-waitingforkey.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-mp4-requestmediakeysystemaccess.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-mp4-reset-src-after-setmediakeys.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-mp4-setmediakeys-again-after-playback.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-mp4-setmediakeys-again-after-resetting-src.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-mp4-setmediakeys-at-same-time.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-mp4-setmediakeys-multiple-times-with-different-mediakeys.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-mp4-setmediakeys-multiple-times-with-the-same-mediakeys.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-mp4-setmediakeys-to-multiple-video-elements.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-mp4-setmediakeys.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-mp4-syntax-mediakeys.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-mp4-syntax-mediakeysession.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-mp4-syntax-mediakeysystemaccess.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-mp4-unique-origin.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-mp4-waiting-for-a-key.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-not-callable-after-createsession.https.html create mode 100644 testing/web-platform/tests/encrypted-media/drm-temporary-license-type.https.html create mode 100644 testing/web-platform/tests/encrypted-media/encrypted-media-default-feature-policy.https.sub.html create mode 100644 testing/web-platform/tests/encrypted-media/encrypted-media-supported-by-feature-policy.tentative.html create mode 100644 testing/web-platform/tests/encrypted-media/idlharness.https.html create mode 100644 testing/web-platform/tests/encrypted-media/polyfill/cast-polyfill.js create mode 100644 testing/web-platform/tests/encrypted-media/polyfill/chrome-polyfill.js create mode 100644 testing/web-platform/tests/encrypted-media/polyfill/clearkey-polyfill.js create mode 100644 testing/web-platform/tests/encrypted-media/polyfill/edge-keystatuses.js create mode 100644 testing/web-platform/tests/encrypted-media/polyfill/edge-persistent-usage-record.js create mode 100644 testing/web-platform/tests/encrypted-media/polyfill/firefox-polyfill.js create mode 100644 testing/web-platform/tests/encrypted-media/polyfill/make-polyfill-tests.py create mode 100644 testing/web-platform/tests/encrypted-media/resources/clearkey-retrieve-destroy-persistent-license.html create mode 100644 testing/web-platform/tests/encrypted-media/resources/clearkey-retrieve-persistent-license.html create mode 100644 testing/web-platform/tests/encrypted-media/resources/drm-retrieve-destroy-persistent-license.html create mode 100644 testing/web-platform/tests/encrypted-media/resources/drm-retrieve-persistent-license.html create mode 100644 testing/web-platform/tests/encrypted-media/resources/drm-retrieve-persistent-usage-record.html create mode 100644 testing/web-platform/tests/encrypted-media/resources/retrieve-persistent-usage-record.html create mode 100644 testing/web-platform/tests/encrypted-media/scripts/check-encryption-scheme.js create mode 100644 testing/web-platform/tests/encrypted-media/scripts/check-initdata-type.js create mode 100644 testing/web-platform/tests/encrypted-media/scripts/check-status-for-hdcp.js create mode 100644 testing/web-platform/tests/encrypted-media/scripts/clearkey-update-non-ascii-input.js create mode 100644 testing/web-platform/tests/encrypted-media/scripts/events-session-closed-event.js create mode 100644 testing/web-platform/tests/encrypted-media/scripts/events.js create mode 100644 testing/web-platform/tests/encrypted-media/scripts/expiration.js create mode 100644 testing/web-platform/tests/encrypted-media/scripts/generate-request-disallowed-input.js create mode 100644 testing/web-platform/tests/encrypted-media/scripts/invalid-license.js create mode 100644 testing/web-platform/tests/encrypted-media/scripts/keystatuses-multiple-sessions.js create mode 100644 testing/web-platform/tests/encrypted-media/scripts/keystatuses.js create mode 100644 testing/web-platform/tests/encrypted-media/scripts/not-callable-after-createsession.js create mode 100644 testing/web-platform/tests/encrypted-media/scripts/onencrypted.js create mode 100644 testing/web-platform/tests/encrypted-media/scripts/playback-destroy-persistent-license.js create mode 100644 testing/web-platform/tests/encrypted-media/scripts/playback-persistent-license-events.js create mode 100644 testing/web-platform/tests/encrypted-media/scripts/playback-persistent-license.js create mode 100644 testing/web-platform/tests/encrypted-media/scripts/playback-persistent-usage-record-events.js create mode 100644 testing/web-platform/tests/encrypted-media/scripts/playback-persistent-usage-record.js create mode 100644 testing/web-platform/tests/encrypted-media/scripts/playback-retrieve-persistent-license.js create mode 100644 testing/web-platform/tests/encrypted-media/scripts/playback-retrieve-persistent-usage-record.js create mode 100644 testing/web-platform/tests/encrypted-media/scripts/playback-temporary-encrypted-clear-segmented-sources.js create mode 100644 testing/web-platform/tests/encrypted-media/scripts/playback-temporary-encrypted-clear-sources.js create mode 100644 testing/web-platform/tests/encrypted-media/scripts/playback-temporary-events.js create mode 100644 testing/web-platform/tests/encrypted-media/scripts/playback-temporary-expired.js create mode 100644 testing/web-platform/tests/encrypted-media/scripts/playback-temporary-multikey-sequential.js create mode 100644 testing/web-platform/tests/encrypted-media/scripts/playback-temporary-multisession.js create mode 100644 testing/web-platform/tests/encrypted-media/scripts/playback-temporary-playduration-keystatus.js create mode 100644 testing/web-platform/tests/encrypted-media/scripts/playback-temporary-playduration.js create mode 100644 testing/web-platform/tests/encrypted-media/scripts/playback-temporary-setMediaKeys.js create mode 100644 testing/web-platform/tests/encrypted-media/scripts/playback-temporary-two-videos.js create mode 100644 testing/web-platform/tests/encrypted-media/scripts/playback-temporary-waitingforkey.js create mode 100644 testing/web-platform/tests/encrypted-media/scripts/playback-temporary.js create mode 100644 testing/web-platform/tests/encrypted-media/scripts/requestmediakeysystemaccess.js create mode 100644 testing/web-platform/tests/encrypted-media/scripts/reset-src-after-setmediakeys.js create mode 100644 testing/web-platform/tests/encrypted-media/scripts/setmediakeys-again-after-playback.js create mode 100644 testing/web-platform/tests/encrypted-media/scripts/setmediakeys-again-after-resetting-src.js create mode 100644 testing/web-platform/tests/encrypted-media/scripts/setmediakeys-at-same-time.js create mode 100644 testing/web-platform/tests/encrypted-media/scripts/setmediakeys-multiple-times-with-different-mediakeys.js create mode 100644 testing/web-platform/tests/encrypted-media/scripts/setmediakeys-multiple-times-with-the-same-mediakeys.js create mode 100644 testing/web-platform/tests/encrypted-media/scripts/setmediakeys-to-multiple-video-elements.js create mode 100644 testing/web-platform/tests/encrypted-media/scripts/setmediakeys.js create mode 100644 testing/web-platform/tests/encrypted-media/scripts/syntax-mediakeys.js create mode 100644 testing/web-platform/tests/encrypted-media/scripts/syntax-mediakeysession.js create mode 100644 testing/web-platform/tests/encrypted-media/scripts/syntax-mediakeysystemaccess.js create mode 100644 testing/web-platform/tests/encrypted-media/scripts/temporary-license-type.js create mode 100644 testing/web-platform/tests/encrypted-media/scripts/unique-origin.js create mode 100644 testing/web-platform/tests/encrypted-media/scripts/update-disallowed-input.js create mode 100644 testing/web-platform/tests/encrypted-media/scripts/waiting-for-a-key.js create mode 100644 testing/web-platform/tests/encrypted-media/util/clearkey-messagehandler.js create mode 100644 testing/web-platform/tests/encrypted-media/util/drm-messagehandler.js create mode 100644 testing/web-platform/tests/encrypted-media/util/testmediasource.js create mode 100644 testing/web-platform/tests/encrypted-media/util/utf8.js create mode 100644 testing/web-platform/tests/encrypted-media/util/utils.js (limited to 'testing/web-platform/tests/encrypted-media') diff --git a/testing/web-platform/tests/encrypted-media/META.yml b/testing/web-platform/tests/encrypted-media/META.yml new file mode 100644 index 0000000000..b09e3b3c4e --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/META.yml @@ -0,0 +1,6 @@ +spec: https://w3c.github.io/encrypted-media/ +suggested_reviewers: + - cpearce + - joeyparrish + - jrummell-chromium + - jyavenard diff --git a/testing/web-platform/tests/encrypted-media/README.md b/testing/web-platform/tests/encrypted-media/README.md new file mode 100644 index 0000000000..932c9962d5 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/README.md @@ -0,0 +1,7 @@ +## Preparing to run tests +The following steps may be necessary when running test from a new server/origin for the first time. +* Some implementations and/or tests may require consent. + When running on such clients, manually run a test to trigger the consent request and choose to persist the consent. +* Some of the tests, such as *-retrieve-*, use pop-ups. + It may be necessary to run these tests manually and choose to always allow pop-ups on the origin. + Related test failures may appear as: "Cannot set property 'onload' of undefined" diff --git a/testing/web-platform/tests/encrypted-media/clearkey-check-encryption-scheme.https.html b/testing/web-platform/tests/encrypted-media/clearkey-check-encryption-scheme.https.html new file mode 100644 index 0000000000..eb580ea5f8 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-check-encryption-scheme.https.html @@ -0,0 +1,32 @@ + + + + + Encrypted Media Extensions: Check encryptionScheme with Clear Key + + + + + + + + + + + + + + + + + + +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/clearkey-check-initdata-type.https.html b/testing/web-platform/tests/encrypted-media/clearkey-check-initdata-type.https.html new file mode 100644 index 0000000000..00894338ae --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-check-initdata-type.https.html @@ -0,0 +1,32 @@ + + + + + Encrypted Media Extensions: Successful Playback, Temporary session with Clear Key, mp4 + + + + + + + + + + + + + + + + + + +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/clearkey-check-status-for-hdcp.https.html b/testing/web-platform/tests/encrypted-media/clearkey-check-status-for-hdcp.https.html new file mode 100644 index 0000000000..5ec3b26285 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-check-status-for-hdcp.https.html @@ -0,0 +1,32 @@ + + + + + Encrypted Media Extensions: Check HDCP status with Clear Key + + + + + + + + + + + + + + + + + + +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/clearkey-events-session-closed-event.https.html b/testing/web-platform/tests/encrypted-media/clearkey-events-session-closed-event.https.html new file mode 100644 index 0000000000..ddf3ecbbbf --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-events-session-closed-event.https.html @@ -0,0 +1,40 @@ + + + + + Encrypted Media Extensions - Test MediaKeySession closed event with Clear Key, mp4 + + + + + + + + + + + + + + + + + + +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/clearkey-events.https.html b/testing/web-platform/tests/encrypted-media/clearkey-events.https.html new file mode 100644 index 0000000000..7563eb33bd --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-events.https.html @@ -0,0 +1,43 @@ + + + + + Encrypted Media Extensions: Events with Clear Key + + + + + + + + + + + + + + + + + + + + + +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/clearkey-generate-request-disallowed-input.https.html b/testing/web-platform/tests/encrypted-media/clearkey-generate-request-disallowed-input.https.html new file mode 100644 index 0000000000..9f86d89b47 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-generate-request-disallowed-input.https.html @@ -0,0 +1,31 @@ + + + + + Encrypted Media Extensions: Test handling of invalid initData for generateRequest() + + + + + + + + + + + + + + + +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/clearkey-invalid-license.https.html b/testing/web-platform/tests/encrypted-media/clearkey-invalid-license.https.html new file mode 100644 index 0000000000..702f934d2d --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-invalid-license.https.html @@ -0,0 +1,30 @@ + + + + + Encrypted Media Extensions: Test handling of invalid Clear Key license + + + + + + + + + + + + + + + +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/clearkey-keystatuses-multiple-sessions.https.html b/testing/web-platform/tests/encrypted-media/clearkey-keystatuses-multiple-sessions.https.html new file mode 100644 index 0000000000..3dec1ad165 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-keystatuses-multiple-sessions.https.html @@ -0,0 +1,50 @@ + + + + + Encrypted Media Extensions: Verify MediaKeySession.keyStatuses with multiple sessions, Clear Key + + + + + + + + + + + + + + + + + + + + + + +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/clearkey-keystatuses.https.html b/testing/web-platform/tests/encrypted-media/clearkey-keystatuses.https.html new file mode 100644 index 0000000000..3acce4d436 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-keystatuses.https.html @@ -0,0 +1,49 @@ + + + + + Encrypted Media Extensions: Verify MediaKeySession.keyStatuses with multiple sessions, Clear Key + + + + + + + + + + + + + + + + + + + + + + +
+ + + + \ No newline at end of file diff --git a/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-destroy-persistent-license.https.html b/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-destroy-persistent-license.https.html new file mode 100644 index 0000000000..2fb1db4dcc --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-destroy-persistent-license.https.html @@ -0,0 +1,51 @@ + + + + + Encrypted Media Extensions: persistent-license, playback, destroy license with Clear Key, mp4 + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + \ No newline at end of file diff --git a/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-persistent-license-events.https.html b/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-persistent-license-events.https.html new file mode 100644 index 0000000000..66720946d4 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-persistent-license-events.https.html @@ -0,0 +1,51 @@ + + + + + Encrypted Media Extensions: Successful Playback, persistent-license session with Clear Key, mp4, event sequence + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + \ No newline at end of file diff --git a/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-persistent-license.https.html b/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-persistent-license.https.html new file mode 100644 index 0000000000..b65cf5337f --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-persistent-license.https.html @@ -0,0 +1,51 @@ + + + + + Encrypted Media Extensions: Successful Playback, persistent-license session with Clear Key, mp4 + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + \ No newline at end of file diff --git a/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-persistent-usage-record-events.https.html b/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-persistent-usage-record-events.https.html new file mode 100644 index 0000000000..11b3e8f15c --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-persistent-usage-record-events.https.html @@ -0,0 +1,51 @@ + + + + + Encrypted Media Extensions: Successful Playback, persistent-usage-record session with Clear Key, mp4, event sequence + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-persistent-usage-record.https.html b/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-persistent-usage-record.https.html new file mode 100644 index 0000000000..3f0d55e413 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-persistent-usage-record.https.html @@ -0,0 +1,51 @@ + + + + + Encrypted Media Extensions: Successful Playback, persistent-usage-record session with Clear Key, mp4, event sequence + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-retrieve-destroy-persistent-license.https.html b/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-retrieve-destroy-persistent-license.https.html new file mode 100644 index 0000000000..c8838d2b7d --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-retrieve-destroy-persistent-license.https.html @@ -0,0 +1,52 @@ + + + + + Encrypted Media Extensions: persistent-license, playback, retrieve, playback and destroy with Clear Key, mp4 + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + \ No newline at end of file diff --git a/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-retrieve-persistent-license.https.html b/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-retrieve-persistent-license.https.html new file mode 100644 index 0000000000..072b885d21 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-retrieve-persistent-license.https.html @@ -0,0 +1,52 @@ + + + + + Encrypted Media Extensions: persistent-license playback, retrieve and playback with Clear Key, mp4 + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + \ No newline at end of file diff --git a/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-retrieve-persistent-usage-record.https.html b/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-retrieve-persistent-usage-record.https.html new file mode 100644 index 0000000000..63e792c298 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-retrieve-persistent-usage-record.https.html @@ -0,0 +1,51 @@ + + + + + Encrypted Media Extensions: persistent-usage-record, playback and retrieve record in new window, Clear Key, mp4 + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-clear-encrypted-segmented.https.html b/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-clear-encrypted-segmented.https.html new file mode 100644 index 0000000000..e402688aac --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-clear-encrypted-segmented.https.html @@ -0,0 +1,59 @@ + + + + + Encrypted Media Extensions: Successful Playback, Temporary session with Clear Key, mp4, clear then encrypted using segmented media + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-clear-encrypted.https.html b/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-clear-encrypted.https.html new file mode 100644 index 0000000000..b8d7cf978e --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-clear-encrypted.https.html @@ -0,0 +1,52 @@ + + + + + Encrypted Media Extensions: Successful Playback, Temporary session with Clear Key, mp4, clear then encrypted + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-encrypted-clear-sources.https.html b/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-encrypted-clear-sources.https.html new file mode 100644 index 0000000000..73df333979 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-encrypted-clear-sources.https.html @@ -0,0 +1,58 @@ + + + + + + Encrypted Media Extensions: Successful Playback, alternate Encrypted and Clear playbacks, Temporary, mp4, Clear Key + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-encrypted-clear.https.html b/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-encrypted-clear.https.html new file mode 100644 index 0000000000..9ab8fd854c --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-encrypted-clear.https.html @@ -0,0 +1,52 @@ + + + + + Encrypted Media Extensions: Successful Playback, Temporary session with Clear Key, mp4, encrypted then clear + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-events.https.html b/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-events.https.html new file mode 100644 index 0000000000..be40082fa8 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-events.https.html @@ -0,0 +1,51 @@ + + + + + Encrypted Media Extensions: Successful playback, Temporary session with Clear Key, mp4, validating events + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-multikey-sequential-readyState.https.html b/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-multikey-sequential-readyState.https.html new file mode 100644 index 0000000000..ff5bb47639 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-multikey-sequential-readyState.https.html @@ -0,0 +1,54 @@ + + + + + + Encrypted Media Extensions: Successful Playback, Temporary session with Clear Key, mp4, multiple keys in sequence, check readyState + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-multikey-sequential.https.html b/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-multikey-sequential.https.html new file mode 100644 index 0000000000..a001e6a4d7 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-multikey-sequential.https.html @@ -0,0 +1,53 @@ + + + + + + Encrypted Media Extensions: Successful Playback, Temporary session with Clear Key, mp4, multiple keys in sequence + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-multikey.https.html b/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-multikey.https.html new file mode 100644 index 0000000000..b036a051a4 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-multikey.https.html @@ -0,0 +1,52 @@ + + + + + Encrypted Media Extensions: Successful Playback, Temporary session with Clear Key, mp4, multiple keys for audio/video + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-multisession.https.html b/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-multisession.https.html new file mode 100644 index 0000000000..b64befda17 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-multisession.https.html @@ -0,0 +1,51 @@ + + + + + Encrypted Media Extensions: Successful Playback, Temporary session with Clear Key, mp4, multiple keys in sequence + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-setMediaKeys-after-src.https.html b/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-setMediaKeys-after-src.https.html new file mode 100644 index 0000000000..209f08231b --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-setMediaKeys-after-src.https.html @@ -0,0 +1,51 @@ + + + + + Encrypted Media Extensions: Successful Playback, Temporary session with Clear Key, mp4 + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + \ No newline at end of file diff --git a/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-setMediaKeys-after-update.https.html b/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-setMediaKeys-after-update.https.html new file mode 100644 index 0000000000..1b1242ba39 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-setMediaKeys-after-update.https.html @@ -0,0 +1,51 @@ + + + + + Encrypted Media Extensions: Successful Playback, Temporary session with Clear Key, mp4 + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + \ No newline at end of file diff --git a/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-setMediaKeys-immediately.https.html b/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-setMediaKeys-immediately.https.html new file mode 100644 index 0000000000..2448484778 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-setMediaKeys-immediately.https.html @@ -0,0 +1,51 @@ + + + + + Encrypted Media Extensions: Successful Playback, Temporary session with Clear Key, mp4 + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-setMediaKeys-onencrypted.https.html b/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-setMediaKeys-onencrypted.https.html new file mode 100644 index 0000000000..b7a9ede97d --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-setMediaKeys-onencrypted.https.html @@ -0,0 +1,51 @@ + + + + + Encrypted Media Extensions: Successful Playback, Temporary session with Clear Key, mp4 + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + \ No newline at end of file diff --git a/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-two-videos.https.html b/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-two-videos.https.html new file mode 100644 index 0000000000..ea69fc41e7 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-two-videos.https.html @@ -0,0 +1,54 @@ + + + + + + Encrypted Media Extensions: Successful Playback, Temporary session with Clear Key, mp4, two videos + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-waitingforkey.https.html b/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-waitingforkey.https.html new file mode 100644 index 0000000000..443aec81b7 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary-waitingforkey.https.html @@ -0,0 +1,51 @@ + + + + + Encrypted Media Extensions: Successful Playback, Temporary session with Clear Key, mp4, play, wait for key, continue play + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + \ No newline at end of file diff --git a/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary.https.html b/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary.https.html new file mode 100644 index 0000000000..f6bff6992a --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-mp4-playback-temporary.https.html @@ -0,0 +1,51 @@ + + + + + Encrypted Media Extensions: Successful Playback, Temporary session with Clear Key, mp4 + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/clearkey-mp4-requestmediakeysystemaccess.https.html b/testing/web-platform/tests/encrypted-media/clearkey-mp4-requestmediakeysystemaccess.https.html new file mode 100644 index 0000000000..c768bc4c86 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-mp4-requestmediakeysystemaccess.https.html @@ -0,0 +1,39 @@ + + + + + + Encrypted Media Extensions: requestMediaKeySystemAccess tests, Clear Key + + + + + + + + + + + + + + + + + + + +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/clearkey-mp4-reset-src-after-setmediakeys.https.html b/testing/web-platform/tests/encrypted-media/clearkey-mp4-reset-src-after-setmediakeys.https.html new file mode 100644 index 0000000000..0acd27fbff --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-mp4-reset-src-after-setmediakeys.https.html @@ -0,0 +1,46 @@ + + + + + Encrypted Media Extensions - Reset MediaSource after setMediaKeys for Clear Key, mp4 + + + + + + + + + + + + + + + + + + + +
+
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/clearkey-mp4-setmediakeys-again-after-playback.https.html b/testing/web-platform/tests/encrypted-media/clearkey-mp4-setmediakeys-again-after-playback.https.html new file mode 100644 index 0000000000..b744182be2 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-mp4-setmediakeys-again-after-playback.https.html @@ -0,0 +1,52 @@ + + + + + Encrypted Media Extensions: setMediaKeys again after playback with Clear Key + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/clearkey-mp4-setmediakeys-again-after-resetting-src.https.html b/testing/web-platform/tests/encrypted-media/clearkey-mp4-setmediakeys-again-after-resetting-src.https.html new file mode 100644 index 0000000000..4700f5d2cc --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-mp4-setmediakeys-again-after-resetting-src.https.html @@ -0,0 +1,52 @@ + + + + + Encrypted Media Extensions: setMediaKeys again after resetting src attribute on video element with Clear Key + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/clearkey-mp4-setmediakeys-at-same-time.https.html b/testing/web-platform/tests/encrypted-media/clearkey-mp4-setmediakeys-at-same-time.https.html new file mode 100644 index 0000000000..860cb6cb22 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-mp4-setmediakeys-at-same-time.https.html @@ -0,0 +1,42 @@ + + + + + Encrypted Media Extensions: setMediaKeys multiple at same time with Clear Key + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/clearkey-mp4-setmediakeys-multiple-times-with-different-mediakeys.https.html b/testing/web-platform/tests/encrypted-media/clearkey-mp4-setmediakeys-multiple-times-with-different-mediakeys.https.html new file mode 100644 index 0000000000..088e3c2d7c --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-mp4-setmediakeys-multiple-times-with-different-mediakeys.https.html @@ -0,0 +1,48 @@ + + + + + Encrypted Media Extensions: setMediaKeys multiple times with different mediakeys with Clear Key + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/clearkey-mp4-setmediakeys-multiple-times-with-the-same-mediakeys.https.html b/testing/web-platform/tests/encrypted-media/clearkey-mp4-setmediakeys-multiple-times-with-the-same-mediakeys.https.html new file mode 100644 index 0000000000..a38d1305fe --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-mp4-setmediakeys-multiple-times-with-the-same-mediakeys.https.html @@ -0,0 +1,48 @@ + + + + + Encrypted Media Extensions: setMediaKeys multiple times with the same mediakeys with Clear Key + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/clearkey-mp4-setmediakeys-to-multiple-video-elements.https.html b/testing/web-platform/tests/encrypted-media/clearkey-mp4-setmediakeys-to-multiple-video-elements.https.html new file mode 100644 index 0000000000..de85169d61 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-mp4-setmediakeys-to-multiple-video-elements.https.html @@ -0,0 +1,46 @@ + + + + + Encrypted Media Extensions: setMediaKeys to multiple video elements with Clear Key + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/clearkey-mp4-setmediakeys.https.html b/testing/web-platform/tests/encrypted-media/clearkey-mp4-setmediakeys.https.html new file mode 100644 index 0000000000..ea04f95408 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-mp4-setmediakeys.https.html @@ -0,0 +1,40 @@ + + + + + Encrypted Media Extensions: setMediaKeys with Clear Key + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/clearkey-mp4-syntax-mediakeys.https.html b/testing/web-platform/tests/encrypted-media/clearkey-mp4-syntax-mediakeys.https.html new file mode 100644 index 0000000000..e76f509616 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-mp4-syntax-mediakeys.https.html @@ -0,0 +1,41 @@ + + + + + Encrypted Media Extensions - Test MediaKeys attribute, setServerCertificate and setServerCertificate exception syntax for Clear Key, mp4 + + + + + + + + + + + + + + + + + + +
+
+ +
+ + + diff --git a/testing/web-platform/tests/encrypted-media/clearkey-mp4-syntax-mediakeysession.https.html b/testing/web-platform/tests/encrypted-media/clearkey-mp4-syntax-mediakeysession.https.html new file mode 100644 index 0000000000..447560d74b --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-mp4-syntax-mediakeysession.https.html @@ -0,0 +1,41 @@ + + + + + Encrypted Media Extensions - Test MediaKeySession attribute and function syntax for Clear Key, mp4 + + + + + + + + + + + + + + + + + + +
+
+ +
+ + + diff --git a/testing/web-platform/tests/encrypted-media/clearkey-mp4-syntax-mediakeysystemaccess.https.html b/testing/web-platform/tests/encrypted-media/clearkey-mp4-syntax-mediakeysystemaccess.https.html new file mode 100644 index 0000000000..1991f588fe --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-mp4-syntax-mediakeysystemaccess.https.html @@ -0,0 +1,41 @@ + + + + + Encrypted Media Extensions - Test navigator.requestmediakeysystemaccess exception and MediaKeySystemAccess attribute syntax for Clear Key, mp4 + + + + + + + + + + + + + + + + + + +
+
+ +
+ + + diff --git a/testing/web-platform/tests/encrypted-media/clearkey-mp4-unique-origin.https.html b/testing/web-platform/tests/encrypted-media/clearkey-mp4-unique-origin.https.html new file mode 100644 index 0000000000..0823a9e882 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-mp4-unique-origin.https.html @@ -0,0 +1,42 @@ + + + + + Encrypted Media Extensions: Unique origin with Clear Key, mp4 + + + + + + + + + + + + + + + + + +
+
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/clearkey-mp4-update-disallowed-input.https.html b/testing/web-platform/tests/encrypted-media/clearkey-mp4-update-disallowed-input.https.html new file mode 100644 index 0000000000..e5061a7654 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-mp4-update-disallowed-input.https.html @@ -0,0 +1,28 @@ + + + + + Encrypted Media Extensions - Test handling of invalid responses for update() for Clear Key, mp4 + + + + + + + + + + + + + + +
+ + + diff --git a/testing/web-platform/tests/encrypted-media/clearkey-mp4-waiting-for-a-key.https.html b/testing/web-platform/tests/encrypted-media/clearkey-mp4-waiting-for-a-key.https.html new file mode 100644 index 0000000000..03f0787fcd --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-mp4-waiting-for-a-key.https.html @@ -0,0 +1,51 @@ + + + + + Encrypted Media Extensions - Waiting for a key for Clear Key, mp4 + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/clearkey-not-callable-after-createsession.https.html b/testing/web-platform/tests/encrypted-media/clearkey-not-callable-after-createsession.https.html new file mode 100644 index 0000000000..ca0622d9fc --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-not-callable-after-createsession.https.html @@ -0,0 +1,31 @@ + + + + + Encrypted Media Extensions: Test MediaKeySession not callable immediately after CreateSession(). + + + + + + + + + + + + + + + +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/clearkey-update-non-ascii-input.https.html b/testing/web-platform/tests/encrypted-media/clearkey-update-non-ascii-input.https.html new file mode 100644 index 0000000000..cc13472914 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/clearkey-update-non-ascii-input.https.html @@ -0,0 +1,36 @@ + + + + + Encrypted Media Extensions: Test Clear Key handling of non-ASCII responses for update() + + + + + + + + + + + + + + + + + + +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/content/audio_aac-lc_128k_2keys_2sess.mp4 b/testing/web-platform/tests/encrypted-media/content/audio_aac-lc_128k_2keys_2sess.mp4 new file mode 100644 index 0000000000..526998d6ac Binary files /dev/null and b/testing/web-platform/tests/encrypted-media/content/audio_aac-lc_128k_2keys_2sess.mp4 differ diff --git a/testing/web-platform/tests/encrypted-media/content/audio_aac-lc_128k_dashinit.mp4 b/testing/web-platform/tests/encrypted-media/content/audio_aac-lc_128k_dashinit.mp4 new file mode 100644 index 0000000000..4daf4d5633 Binary files /dev/null and b/testing/web-platform/tests/encrypted-media/content/audio_aac-lc_128k_dashinit.mp4 differ diff --git a/testing/web-platform/tests/encrypted-media/content/audio_aac-lc_128k_enc_dashinit.mp4 b/testing/web-platform/tests/encrypted-media/content/audio_aac-lc_128k_enc_dashinit.mp4 new file mode 100644 index 0000000000..77e869f808 Binary files /dev/null and b/testing/web-platform/tests/encrypted-media/content/audio_aac-lc_128k_enc_dashinit.mp4 differ diff --git a/testing/web-platform/tests/encrypted-media/content/content-metadata.js b/testing/web-platform/tests/encrypted-media/content/content-metadata.js new file mode 100644 index 0000000000..580cc2bdfe --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/content/content-metadata.js @@ -0,0 +1,274 @@ +content = addMemberListToObject( { + + 'mp4-clear' : { initDataType: 'cenc', + audio : { type: 'audio/mp4;codecs="mp4a.40.2"', + path: '/encrypted-media/content/audio_aac-lc_128k_dashinit.mp4' }, + video : { type: 'video/mp4;codecs="avc1.4d401e"', + path: '/encrypted-media/content/video_512x288_h264-360k_clear_dashinit.mp4' } + }, + + 'mp4-basic' : { assetId: 'mp4-basic', + initDataType: 'cenc', + audio : { type: 'audio/mp4;codecs="mp4a.40.2"', + path: '/encrypted-media/content/audio_aac-lc_128k_dashinit.mp4' }, + video : { type: 'video/mp4;codecs="avc1.4d401e"', + path: '/encrypted-media/content/video_512x288_h264-360k_enc_dashinit.mp4' }, + keys : [ { kid: [ 0xad, 0x13, 0xf9, 0xea, 0x2b, 0xe6, 0x98, 0xb8, 0x75, 0xf5, 0x04, 0xa8, 0xe3, 0xcc, 0xea, 0x64 ], + key: [ 0xbe, 0x7d, 0xf8, 0xa3, 0x66, 0x7a, 0x6a, 0x8f, 0xd5, 0x64, 0xd0, 0xed, 0x81, 0x33, 0x9a, 0x95 ], + initDataType: 'cenc', + initData: 'AAAAcXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAFEIARIQrRP56ivmmLh19QSo48zqZBoIY2FzdGxhYnMiKGV5SmhjM05sZEVsa0lqb2laVzFsTFhSbGMzUXRjMmx1WjJ4bEluMD0yB2RlZmF1bHQAAAMacHNzaAAAAACaBPB5mEBChquS5lvgiF+VAAAC+voCAAABAAEA8AI8AFcAUgBNAEgARQBBAEQARQBSACAAeABtAGwAbgBzAD0AIgBoAHQAdABwADoALwAvAHMAYwBoAGUAbQBhAHMALgBtAGkAYwByAG8AcwBvAGYAdAAuAGMAbwBtAC8ARABSAE0ALwAyADAAMAA3AC8AMAAzAC8AUABsAGEAeQBSAGUAYQBkAHkASABlAGEAZABlAHIAIgAgAHYAZQByAHMAaQBvAG4APQAiADQALgAwAC4AMAAuADAAIgA+ADwARABBAFQAQQA+ADwAUABSAE8AVABFAEMAVABJAE4ARgBPAD4APABLAEUAWQBMAEUATgA+ADEANgA8AC8ASwBFAFkATABFAE4APgA8AEEATABHAEkARAA+AEEARQBTAEMAVABSADwALwBBAEwARwBJAEQAPgA8AC8AUABSAE8AVABFAEMAVABJAE4ARgBPAD4APABLAEkARAA+ADYAdgBrAFQAcgBlAFkAcgB1AEoAaAAxADkAUQBTAG8ANAA4AHoAcQBaAEEAPQA9ADwALwBLAEkARAA+ADwAQwBIAEUAQwBLAFMAVQBNAD4AagBZAEYATgBmADAAeQBmADQAaQBzAD0APAAvAEMASABFAEMASwBTAFUATQA+ADwATABBAF8AVQBSAEwAPgBoAHQAdABwADoALwAvAHAAbABhAHkAcgBlAGEAZAB5AC4AZABpAHIAZQBjAHQAdABhAHAAcwAuAG4AZQB0AC8AcAByAC8AcwB2AGMALwByAGkAZwBoAHQAcwBtAGEAbgBhAGcAZQByAC4AYQBzAG0AeAA/AFAAbABhAHkAUgBpAGcAaAB0AD0AMQAmAGEAbQBwADsAVQBzAGUAUwBpAG0AcABsAGUATgBvAG4AUABlAHIAcwBpAHMAdABlAG4AdABMAGkAYwBlAG4AcwBlAD0AMQA8AC8ATABBAF8AVQBSAEwAPgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==' } ] + }, + + 'mp4-clear-encrypted' : { + assetId: 'mp4-basic', + initDataType: 'cenc', + audio : { type: 'audio/mp4;codecs="mp4a.40.2"', + path: '/encrypted-media/content/audio_aac-lc_128k_dashinit.mp4' }, + video : { type: 'video/mp4;codecs="avc1.4d401e"', + path: '/encrypted-media/content/video_512x288_h264-360k_clear_enc_dashinit.mp4' }, + keys : [ { kid: [ 0xad, 0x13, 0xf9, 0xea, 0x2b, 0xe6, 0x98, 0xb8, 0x75, 0xf5, 0x04, 0xa8, 0xe3, 0xcc, 0xea, 0x64 ], + key: [ 0xbe, 0x7d, 0xf8, 0xa3, 0x66, 0x7a, 0x6a, 0x8f, 0xd5, 0x64, 0xd0, 0xed, 0x81, 0x33, 0x9a, 0x95 ], + initDataType: 'cenc', + initData: 'AAAAcXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAFEIARIQrRP56ivmmLh19QSo48zqZBoIY2FzdGxhYnMiKGV5SmhjM05sZEVsa0lqb2laVzFsTFhSbGMzUXRjMmx1WjJ4bEluMD0yB2RlZmF1bHQAAAMacHNzaAAAAACaBPB5mEBChquS5lvgiF+VAAAC+voCAAABAAEA8AI8AFcAUgBNAEgARQBBAEQARQBSACAAeABtAGwAbgBzAD0AIgBoAHQAdABwADoALwAvAHMAYwBoAGUAbQBhAHMALgBtAGkAYwByAG8AcwBvAGYAdAAuAGMAbwBtAC8ARABSAE0ALwAyADAAMAA3AC8AMAAzAC8AUABsAGEAeQBSAGUAYQBkAHkASABlAGEAZABlAHIAIgAgAHYAZQByAHMAaQBvAG4APQAiADQALgAwAC4AMAAuADAAIgA+ADwARABBAFQAQQA+ADwAUABSAE8AVABFAEMAVABJAE4ARgBPAD4APABLAEUAWQBMAEUATgA+ADEANgA8AC8ASwBFAFkATABFAE4APgA8AEEATABHAEkARAA+AEEARQBTAEMAVABSADwALwBBAEwARwBJAEQAPgA8AC8AUABSAE8AVABFAEMAVABJAE4ARgBPAD4APABLAEkARAA+ADYAdgBrAFQAcgBlAFkAcgB1AEoAaAAxADkAUQBTAG8ANAA4AHoAcQBaAEEAPQA9ADwALwBLAEkARAA+ADwAQwBIAEUAQwBLAFMAVQBNAD4AagBZAEYATgBmADAAeQBmADQAaQBzAD0APAAvAEMASABFAEMASwBTAFUATQA+ADwATABBAF8AVQBSAEwAPgBoAHQAdABwADoALwAvAHAAbABhAHkAcgBlAGEAZAB5AC4AZABpAHIAZQBjAHQAdABhAHAAcwAuAG4AZQB0AC8AcAByAC8AcwB2AGMALwByAGkAZwBoAHQAcwBtAGEAbgBhAGcAZQByAC4AYQBzAG0AeAA/AFAAbABhAHkAUgBpAGcAaAB0AD0AMQAmAGEAbQBwADsAVQBzAGUAUwBpAG0AcABsAGUATgBvAG4AUABlAHIAcwBpAHMAdABlAG4AdABMAGkAYwBlAG4AcwBlAD0AMQA8AC8ATABBAF8AVQBSAEwAPgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==' } ] + }, + + 'mp4-encrypted-clear' : { + assetId: 'mp4-basic', + initDataType: 'cenc', + audio : { type: 'audio/mp4;codecs="mp4a.40.2"', + path: '/encrypted-media/content/audio_aac-lc_128k_dashinit.mp4' }, + video : { type: 'video/mp4;codecs="avc1.4d401e"', + path: '/encrypted-media/content/video_512x288_h264-360k_enc_clear_dashinit.mp4' }, + keys : [ { kid: [ 0xad, 0x13, 0xf9, 0xea, 0x2b, 0xe6, 0x98, 0xb8, 0x75, 0xf5, 0x04, 0xa8, 0xe3, 0xcc, 0xea, 0x64 ], + key: [ 0xbe, 0x7d, 0xf8, 0xa3, 0x66, 0x7a, 0x6a, 0x8f, 0xd5, 0x64, 0xd0, 0xed, 0x81, 0x33, 0x9a, 0x95 ], + initDataType: 'cenc', + initData: 'AAAAcXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAFEIARIQrRP56ivmmLh19QSo48zqZBoIY2FzdGxhYnMiKGV5SmhjM05sZEVsa0lqb2laVzFsTFhSbGMzUXRjMmx1WjJ4bEluMD0yB2RlZmF1bHQAAAMacHNzaAAAAACaBPB5mEBChquS5lvgiF+VAAAC+voCAAABAAEA8AI8AFcAUgBNAEgARQBBAEQARQBSACAAeABtAGwAbgBzAD0AIgBoAHQAdABwADoALwAvAHMAYwBoAGUAbQBhAHMALgBtAGkAYwByAG8AcwBvAGYAdAAuAGMAbwBtAC8ARABSAE0ALwAyADAAMAA3AC8AMAAzAC8AUABsAGEAeQBSAGUAYQBkAHkASABlAGEAZABlAHIAIgAgAHYAZQByAHMAaQBvAG4APQAiADQALgAwAC4AMAAuADAAIgA+ADwARABBAFQAQQA+ADwAUABSAE8AVABFAEMAVABJAE4ARgBPAD4APABLAEUAWQBMAEUATgA+ADEANgA8AC8ASwBFAFkATABFAE4APgA8AEEATABHAEkARAA+AEEARQBTAEMAVABSADwALwBBAEwARwBJAEQAPgA8AC8AUABSAE8AVABFAEMAVABJAE4ARgBPAD4APABLAEkARAA+ADYAdgBrAFQAcgBlAFkAcgB1AEoAaAAxADkAUQBTAG8ANAA4AHoAcQBaAEEAPQA9ADwALwBLAEkARAA+ADwAQwBIAEUAQwBLAFMAVQBNAD4AagBZAEYATgBmADAAeQBmADQAaQBzAD0APAAvAEMASABFAEMASwBTAFUATQA+ADwATABBAF8AVQBSAEwAPgBoAHQAdABwADoALwAvAHAAbABhAHkAcgBlAGEAZAB5AC4AZABpAHIAZQBjAHQAdABhAHAAcwAuAG4AZQB0AC8AcAByAC8AcwB2AGMALwByAGkAZwBoAHQAcwBtAGEAbgBhAGcAZQByAC4AYQBzAG0AeAA/AFAAbABhAHkAUgBpAGcAaAB0AD0AMQAmAGEAbQBwADsAVQBzAGUAUwBpAG0AcABsAGUATgBvAG4AUABlAHIAcwBpAHMAdABlAG4AdABMAGkAYwBlAG4AcwBlAD0AMQA8AC8ATABBAF8AVQBSAEwAPgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==' } ] + }, + + + 'mp4-av-multikey' : { + assetId: 'mp4-basic', + initDataType: 'cenc', + associatedInitData: true, // indicates that initData for one key causes other keys to be returned as well + audio: { type: 'audio/mp4;codecs="mp4a.40.2"', + path: '/encrypted-media/content/audio_aac-lc_128k_enc_dashinit.mp4' }, + video : { type: 'video/mp4;codecs="avc1.4d401e"', + path: '/encrypted-media/content/video_512x288_h264-360k_enc_dashinit.mp4' }, + keys : [ { kid: [ 0xad, 0x13, 0xf9, 0xea, 0x2b, 0xe6, 0x98, 0xb8, 0x75, 0xf5, 0x04, 0xa8, 0xe3, 0xcc, 0xea, 0x64 ], + key: [ 0xbe, 0x7d, 0xf8, 0xa3, 0x66, 0x7a, 0x6a, 0x8f, 0xd5, 0x64, 0xd0, 0xed, 0x81, 0x33, 0x9a, 0x95 ], + initDataType: 'cenc', + initData: 'AAAAcXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAFEIARIQrRP56ivmmLh19QSo48zqZBoIY2FzdGxhYnMiKGV5SmhjM05sZEVsa0lqb2laVzFsTFhSbGMzUXRjMmx1WjJ4bEluMD0yB2RlZmF1bHQAAAMacHNzaAAAAACaBPB5mEBChquS5lvgiF+VAAAC+voCAAABAAEA8AI8AFcAUgBNAEgARQBBAEQARQBSACAAeABtAGwAbgBzAD0AIgBoAHQAdABwADoALwAvAHMAYwBoAGUAbQBhAHMALgBtAGkAYwByAG8AcwBvAGYAdAAuAGMAbwBtAC8ARABSAE0ALwAyADAAMAA3AC8AMAAzAC8AUABsAGEAeQBSAGUAYQBkAHkASABlAGEAZABlAHIAIgAgAHYAZQByAHMAaQBvAG4APQAiADQALgAwAC4AMAAuADAAIgA+ADwARABBAFQAQQA+ADwAUABSAE8AVABFAEMAVABJAE4ARgBPAD4APABLAEUAWQBMAEUATgA+ADEANgA8AC8ASwBFAFkATABFAE4APgA8AEEATABHAEkARAA+AEEARQBTAEMAVABSADwALwBBAEwARwBJAEQAPgA8AC8AUABSAE8AVABFAEMAVABJAE4ARgBPAD4APABLAEkARAA+ADYAdgBrAFQAcgBlAFkAcgB1AEoAaAAxADkAUQBTAG8ANAA4AHoAcQBaAEEAPQA9ADwALwBLAEkARAA+ADwAQwBIAEUAQwBLAFMAVQBNAD4AagBZAEYATgBmADAAeQBmADQAaQBzAD0APAAvAEMASABFAEMASwBTAFUATQA+ADwATABBAF8AVQBSAEwAPgBoAHQAdABwADoALwAvAHAAbABhAHkAcgBlAGEAZAB5AC4AZABpAHIAZQBjAHQAdABhAHAAcwAuAG4AZQB0AC8AcAByAC8AcwB2AGMALwByAGkAZwBoAHQAcwBtAGEAbgBhAGcAZQByAC4AYQBzAG0AeAA/AFAAbABhAHkAUgBpAGcAaAB0AD0AMQAmAGEAbQBwADsAVQBzAGUAUwBpAG0AcABsAGUATgBvAG4AUABlAHIAcwBpAHMAdABlAG4AdABMAGkAYwBlAG4AcwBlAD0AMQA8AC8ATABBAF8AVQBSAEwAPgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==' }, + { kid: [ 0x55, 0x8e, 0xe5, 0x41, 0xb9, 0x0a, 0xb2, 0xf3, 0x95, 0x0d, 0x00, 0xad, 0xe3, 0x76, 0x0d, 0x45 ], + key: [ 0x91, 0x03, 0x92, 0x63, 0x01, 0x6d, 0xa6, 0x35, 0x77, 0x0d, 0x57, 0xdb, 0x92, 0xf9, 0x8b, 0xd0 ], + initDataType : 'cenc', + initData: 'AAAAcXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAFEIARIQVY7lQbkKsvOVDQCt43YNRRoIY2FzdGxhYnMiKGV5SmhjM05sZEVsa0lqb2laVzFsTFhSbGMzUXRjMmx1WjJ4bEluMD0yB2RlZmF1bHQAAAMacHNzaAAAAACaBPB5mEBChquS5lvgiF+VAAAC+voCAAABAAEA8AI8AFcAUgBNAEgARQBBAEQARQBSACAAeABtAGwAbgBzAD0AIgBoAHQAdABwADoALwAvAHMAYwBoAGUAbQBhAHMALgBtAGkAYwByAG8AcwBvAGYAdAAuAGMAbwBtAC8ARABSAE0ALwAyADAAMAA3AC8AMAAzAC8AUABsAGEAeQBSAGUAYQBkAHkASABlAGEAZABlAHIAIgAgAHYAZQByAHMAaQBvAG4APQAiADQALgAwAC4AMAAuADAAIgA+ADwARABBAFQAQQA+ADwAUABSAE8AVABFAEMAVABJAE4ARgBPAD4APABLAEUAWQBMAEUATgA+ADEANgA8AC8ASwBFAFkATABFAE4APgA8AEEATABHAEkARAA+AEEARQBTAEMAVABSADwALwBBAEwARwBJAEQAPgA8AC8AUABSAE8AVABFAEMAVABJAE4ARgBPAD4APABLAEkARAA+AFEAZQBXAE8AVgBRAHEANQA4ADcASwBWAEQAUQBDAHQANAAzAFkATgBSAFEAPQA9ADwALwBLAEkARAA+ADwAQwBIAEUAQwBLAFMAVQBNAD4AWQBpAE8ALwAxADYATABzADkANgBFAD0APAAvAEMASABFAEMASwBTAFUATQA+ADwATABBAF8AVQBSAEwAPgBoAHQAdABwADoALwAvAHAAbABhAHkAcgBlAGEAZAB5AC4AZABpAHIAZQBjAHQAdABhAHAAcwAuAG4AZQB0AC8AcAByAC8AcwB2AGMALwByAGkAZwBoAHQAcwBtAGEAbgBhAGcAZQByAC4AYQBzAG0AeAA/AFAAbABhAHkAUgBpAGcAaAB0AD0AMQAmAGEAbQBwADsAVQBzAGUAUwBpAG0AcABsAGUATgBvAG4AUABlAHIAcwBpAHMAdABlAG4AdABMAGkAYwBlAG4AcwBlAD0AMQA8AC8ATABBAF8AVQBSAEwAPgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==' } ] + }, + + 'mp4-multikey' : { assetId: 'mp4-multikey', + initDataType: 'cenc', + audio: { type: 'audio/mp4;codecs="mp4a.40.2"', + path: '/encrypted-media/content/audio_aac-lc_128k_2keys_2sess.mp4' }, + video: { type: 'video/mp4;codecs="avc1.4d401e"', + path: '/encrypted-media/content/video_512x288_h264-360k_enc_2keys_2sess.mp4' }, + keys: [ { kid: [ 0x13, 0xa7, 0x53, 0x06, 0xd1, 0x18, 0x91, 0x7b, 0x47, 0xa6, 0xc1, 0x83, 0x64, 0x42, 0x51, 0x6f ], + key: [ 0x8a, 0xaa, 0xd8, 0xc4, 0xdb, 0xde, 0xac, 0xcd, 0xad, 0x26, 0x76, 0xa1, 0xed, 0x38, 0x95, 0x2e ], + variantId: 'key1', + initDataType: 'cenc', + initData: 'AAAAjXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAG0IARIQE6dTBtEYkXtHpsGDZEJRbxoIY2FzdGxhYnMiRGV5SmhjM05sZEVsa0lqb2laVzFsTFhSbGMzUXRNbk5sYzNOcGIyNGlMQ0oyWVhKcFlXNTBTV1FpT2lKclpYa3hJbjA9MgdkZWZhdWx0AAADwnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAA6KiAwAAAQABAJgDPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBCAGwATwBuAEUAeABqAFIAZQA1AEYASABwAHMARwBEAFoARQBKAFIAYgB3AD0APQA8AC8ASwBJAEQAPgA8AEwAQQBfAFUAUgBMAD4AaAB0AHQAcABzADoALwAvAGwAaQBjAC4AcwB0AGEAZwBpAG4AZwAuAGQAcgBtAHQAbwBkAGEAeQAuAGMAbwBtAC8AbABpAGMAZQBuAHMAZQAtAHAAcgBvAHgAeQAtAGgAZQBhAGQAZQByAGEAdQB0AGgALwBkAHIAbQB0AG8AZABhAHkALwBSAGkAZwBoAHQAcwBNAGEAbgBhAGcAZQByAC4AYQBzAG0AeAA8AC8ATABBAF8AVQBSAEwAPgA8AEwAVQBJAF8AVQBSAEwAPgBoAHQAdABwAHMAOgAvAC8AbABpAGMALgBzAHQAYQBnAGkAbgBnAC4AZAByAG0AdABvAGQAYQB5AC4AYwBvAG0ALwBsAGkAYwBlAG4AcwBlAC0AcAByAG8AeAB5AC0AaABlAGEAZABlAHIAYQB1AHQAaAAvAGQAcgBtAHQAbwBkAGEAeQAvAFIAaQBnAGgAdABzAE0AYQBuAGEAZwBlAHIALgBhAHMAbQB4ADwALwBMAFUASQBfAFUAUgBMAD4APABDAEgARQBDAEsAUwBVAE0APgBJAEQAUgB0AFAAZwBVAEkALwBiAEkAPQA8AC8AQwBIAEUAQwBLAFMAVQBNAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA=' }, + { kid: [ 0xee, 0x73, 0x56, 0x4e, 0xc8, 0xa8, 0x90, 0xf0, 0x78, 0xef, 0x68, 0x71, 0xfa, 0x4b, 0xe1, 0x8b ], + key: [ 0xe4, 0x4f, 0xe1, 0x45, 0x7c, 0x5e, 0xbc, 0xd8, 0x3e, 0xad, 0xdc, 0xd6, 0x2c, 0xaf, 0x55, 0x18 ], + variantId: 'key2', + initDataType: 'cenc', + initData: 'AAAAjXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAG0IARIQ7nNWTsiokPB472hx+kvhixoIY2FzdGxhYnMiRGV5SmhjM05sZEVsa0lqb2laVzFsTFhSbGMzUXRNbk5sYzNOcGIyNGlMQ0oyWVhKcFlXNTBTV1FpT2lKclpYa3lJbjA9MgdkZWZhdWx0AAADwnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAA6KiAwAAAQABAJgDPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBUAGwAWgB6ADcAcQBqAEkAOABKAEIANAA3ADIAaAB4ACsAawB2AGgAaQB3AD0APQA8AC8ASwBJAEQAPgA8AEwAQQBfAFUAUgBMAD4AaAB0AHQAcABzADoALwAvAGwAaQBjAC4AcwB0AGEAZwBpAG4AZwAuAGQAcgBtAHQAbwBkAGEAeQAuAGMAbwBtAC8AbABpAGMAZQBuAHMAZQAtAHAAcgBvAHgAeQAtAGgAZQBhAGQAZQByAGEAdQB0AGgALwBkAHIAbQB0AG8AZABhAHkALwBSAGkAZwBoAHQAcwBNAGEAbgBhAGcAZQByAC4AYQBzAG0AeAA8AC8ATABBAF8AVQBSAEwAPgA8AEwAVQBJAF8AVQBSAEwAPgBoAHQAdABwAHMAOgAvAC8AbABpAGMALgBzAHQAYQBnAGkAbgBnAC4AZAByAG0AdABvAGQAYQB5AC4AYwBvAG0ALwBsAGkAYwBlAG4AcwBlAC0AcAByAG8AeAB5AC0AaABlAGEAZABlAHIAYQB1AHQAaAAvAGQAcgBtAHQAbwBkAGEAeQAvAFIAaQBnAGgAdABzAE0AYQBuAGEAZwBlAHIALgBhAHMAbQB4ADwALwBMAFUASQBfAFUAUgBMAD4APABDAEgARQBDAEsAUwBVAE0APgB4AEQASwBBAFkAMAB2AFoAaABVAFUAPQA8AC8AQwBIAEUAQwBLAFMAVQBNAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA=' } ] }, + + + 'mp4-multikey-sequential' : { assetId: 'mp4-multikey-sequential', + initDataType: 'cenc', + audio: { type: 'audio/mp4;codecs="mp4a.40.2"', + path: '/encrypted-media/content/audio_aac-lc_128k_dashinit.mp4' }, + video: { type: 'video/mp4;codecs="avc1.4d401e"', + path: '/encrypted-media/content/video_512x288_h264-360k_multikey_dashinit.mp4' }, + keys: [ { kid: [0x8a, 0x0d, 0x85, 0x45, 0x21, 0x05, 0xd4, 0x15, 0x35, 0x8f, 0xea, 0x8f, 0x68, 0xe6, 0xc1, 0x91], + key: [0x76, 0x6f, 0xab, 0xc1, 0x68, 0x3f, 0xf8, 0xef, 0x4e, 0x76, 0x00, 0x24, 0xc5, 0x23, 0x8f, 0x10], + variantId: 'key1', + initDataType: 'cenc', + initData: 'AAAAlXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAHUIARIQig2FRSEF1BU1j+qPaObBkRoIY2FzdGxhYnMiTGV5SmhjM05sZEVsa0lqb2liWEEwTFcxMWJIUnBhMlY1TFhObGNYVmxiblJwWVd3aUxDSjJZWEpwWVc1MFNXUWlPaUpyWlhreEluMD0yB2RlZmF1bHQAAANYcHNzaAAAAACaBPB5mEBChquS5lvgiF+VAAADODgDAAABAAEALgM8AFcAUgBNAEgARQBBAEQARQBSACAAeABtAGwAbgBzAD0AIgBoAHQAdABwADoALwAvAHMAYwBoAGUAbQBhAHMALgBtAGkAYwByAG8AcwBvAGYAdAAuAGMAbwBtAC8ARABSAE0ALwAyADAAMAA3AC8AMAAzAC8AUABsAGEAeQBSAGUAYQBkAHkASABlAGEAZABlAHIAIgAgAHYAZQByAHMAaQBvAG4APQAiADQALgAwAC4AMAAuADAAIgA+ADwARABBAFQAQQA+ADwAUABSAE8AVABFAEMAVABJAE4ARgBPAD4APABLAEUAWQBMAEUATgA+ADEANgA8AC8ASwBFAFkATABFAE4APgA8AEEATABHAEkARAA+AEEARQBTAEMAVABSADwALwBBAEwARwBJAEQAPgA8AC8AUABSAE8AVABFAEMAVABJAE4ARgBPAD4APABLAEkARAA+AFIAWQBVAE4AaQBnAFUAaABGAGQAUQAxAGoAKwBxAFAAYQBPAGIAQgBrAFEAPQA9ADwALwBLAEkARAA+ADwATABBAF8AVQBSAEwAPgBoAHQAdABwAHMAOgAvAC8AbABpAGMALgBzAHQAYQBnAGkAbgBnAC4AZAByAG0AdABvAGQAYQB5AC4AYwBvAG0ALwBsAGkAYwBlAG4AcwBlAC0AcAByAG8AeAB5AC0AaABlAGEAZABlAHIAYQB1AHQAaAAvAGQAcgBtAHQAbwBkAGEAeQAvAFIAaQBnAGgAdABzAE0AYQBuAGEAZwBlAHIALgBhAHMAbQB4ADwALwBMAEEAXwBVAFIATAA+ADwATABVAEkAXwBVAFIATAA+AGgAdAB0AHAAcwA6AC8ALwBwAGwAYQB5AHIAZQBhAGQAeQAtAHUAaQAuAGUAeABhAG0AcABsAGUALgBjAG8AbQA8AC8ATABVAEkAXwBVAFIATAA+ADwAQwBIAEUAQwBLAFMAVQBNAD4AcQBOAEkAZQBiAFQAWABzAG8AcgBnAD0APAAvAEMASABFAEMASwBTAFUATQA+ADwALwBEAEEAVABBAD4APAAvAFcAUgBNAEgARQBBAEQARQBSAD4A' }, + { kid: [0xfb, 0xb4, 0xb7, 0xf3, 0x4a, 0xbd, 0x31, 0x87, 0x34, 0x4b, 0xce, 0xc4, 0x5f, 0x96, 0x68, 0x88], + key: [0x26, 0x52, 0xc3, 0x1d, 0xf7, 0x92, 0xd1, 0x7b, 0x08, 0xa6, 0xfa, 0xd3, 0x7c, 0xb6, 0x25, 0x60], + variantId: 'key2', + initDataType: 'cenc', + initData: 'AAAAlXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAHUIARIQ+7S380q9MYc0S87EX5ZoiBoIY2FzdGxhYnMiTGV5SmhjM05sZEVsa0lqb2liWEEwTFcxMWJIUnBhMlY1TFhObGNYVmxiblJwWVd3aUxDSjJZWEpwWVc1MFNXUWlPaUpyWlhreUluMD0yB2RlZmF1bHQAAANYcHNzaAAAAACaBPB5mEBChquS5lvgiF+VAAADODgDAAABAAEALgM8AFcAUgBNAEgARQBBAEQARQBSACAAeABtAGwAbgBzAD0AIgBoAHQAdABwADoALwAvAHMAYwBoAGUAbQBhAHMALgBtAGkAYwByAG8AcwBvAGYAdAAuAGMAbwBtAC8ARABSAE0ALwAyADAAMAA3AC8AMAAzAC8AUABsAGEAeQBSAGUAYQBkAHkASABlAGEAZABlAHIAIgAgAHYAZQByAHMAaQBvAG4APQAiADQALgAwAC4AMAAuADAAIgA+ADwARABBAFQAQQA+ADwAUABSAE8AVABFAEMAVABJAE4ARgBPAD4APABLAEUAWQBMAEUATgA+ADEANgA8AC8ASwBFAFkATABFAE4APgA8AEEATABHAEkARAA+AEEARQBTAEMAVABSADwALwBBAEwARwBJAEQAPgA8AC8AUABSAE8AVABFAEMAVABJAE4ARgBPAD4APABLAEkARAA+ADgANwBlADAAKwA3ADEASwBoAHoARQAwAFMAOAA3AEUAWAA1AFoAbwBpAEEAPQA9ADwALwBLAEkARAA+ADwATABBAF8AVQBSAEwAPgBoAHQAdABwAHMAOgAvAC8AbABpAGMALgBzAHQAYQBnAGkAbgBnAC4AZAByAG0AdABvAGQAYQB5AC4AYwBvAG0ALwBsAGkAYwBlAG4AcwBlAC0AcAByAG8AeAB5AC0AaABlAGEAZABlAHIAYQB1AHQAaAAvAGQAcgBtAHQAbwBkAGEAeQAvAFIAaQBnAGgAdABzAE0AYQBuAGEAZwBlAHIALgBhAHMAbQB4ADwALwBMAEEAXwBVAFIATAA+ADwATABVAEkAXwBVAFIATAA+AGgAdAB0AHAAcwA6AC8ALwBwAGwAYQB5AHIAZQBhAGQAeQAtAHUAaQAuAGUAeABhAG0AcABsAGUALgBjAG8AbQA8AC8ATABVAEkAXwBVAFIATAA+ADwAQwBIAEUAQwBLAFMAVQBNAD4ARgB0AGkASQBoADYAUwBKAG0AcABZAD0APAAvAEMASABFAEMASwBTAFUATQA+ADwALwBEAEEAVABBAD4APAAvAFcAUgBNAEgARQBBAEQARQBSAD4A' } ] }, + + 'webm' : { audio : { type: 'audio/webm; codecs="opus"' }, + video : { type: 'video/webm; codecs="vp8"', + path: '/encrypted-media/content/test-encrypted.webm' }, + keys : [ { kid: [48,49,50,51,52,53,54,55,56,57,48,49,50,51,52,53], + key: [0xeb, 0xdd, 0x62, 0xf1, 0x68, 0x14, 0xd2, 0x7b, + 0x68, 0xef, 0x12, 0x2a, 0xfc, 0xe4, 0xae, 0x3c ] } ] + }, + 'webm-multikey' : + { audio : { type: 'audio/webm; codecs="opus"' }, + video : { type: 'video/webm; codecs="vp8"', + path: '/encrypted-media/content/test-encrypted-different-av-keys.webm' }, + keys : [ { kid: [48,49,50,51,52,53,54,55,56,57,48,49,50,51,52,53], + key: [ 0x7A, 0x7A, 0x62, 0xF1, 0x68, 0x14, 0xD2, 0x7B, + 0x68, 0xEF, 0x12, 0x2A, 0xFC, 0xE4, 0xAE, 0x0A ] }, + { kid: [49,50,51,52,53,54,55,56,57,48,49,50,51,52,53,54], + key: [ 0x30, 0x30, 0x62, 0xF1, 0x68, 0x14, 0xD2, 0x7B, + 0x68, 0xEF, 0x12, 0x2A, 0xFC, 0xE4, 0xAE, 0x0A ] } ] + }, +} ); + +function addMemberListToObject( o ) +{ + var items = [ ]; + for( var item in o ) + { + if ( !o.hasOwnProperty( item ) ) continue; + + o[item].name = item; + items.push( o[item] ); + } + + o._items = items; + + return o; +} + +function getInitData( contentitem, initDataType ) +{ + if (initDataType == 'webm') { + return new Uint8Array( contentitem.keys[ 0 ].kid ); // WebM initData supports only a single key + } + + if (initDataType == 'cenc') { + + var size = 36 + contentitem.keys.length * 16, + kids = contentitem.keys.map( function( k ) { return k.kid; } ); + + return new Uint8Array(Array.prototype.concat.call( [ + 0x00, 0x00, size / 256, size % 256, // size + 0x70, 0x73, 0x73, 0x68, // 'pssh' + 0x01, // version = 1 + 0x00, 0x00, 0x00, // flags + 0x10, 0x77, 0xEF, 0xEC, 0xC0, 0xB2, 0x4D, 0x02, // Common SystemID + 0xAC, 0xE3, 0x3C, 0x1E, 0x52, 0xE2, 0xFB, 0x4B, + 0x00, 0x00, 0x00, kids.length ], // key count ] + Array.prototype.concat.apply( [], kids ), + [ 0x00, 0x00, 0x00, 0x00 ]// datasize + )); + } + if (initDataType == 'keyids') { + + return toUtf8( { kids: contentitem.keys.map( function( k ) { return base64urlEncode( new Uint8Array( k.kid ) ); } ) } ); + } + throw 'initDataType ' + initDataType + ' not supported.'; +} + +function getSingleKeyInitData( kid, initDataType ) +{ + if (initDataType == 'webm') { + return new Uint8Array( kid ); + } + + if (initDataType == 'cenc') { + + var size = 52; + + return new Uint8Array(Array.prototype.concat.call( [ + 0x00, 0x00, size / 256, size % 256, // size + 0x70, 0x73, 0x73, 0x68, // 'pssh' + 0x01, // version = 1 + 0x00, 0x00, 0x00, // flags + 0x10, 0x77, 0xEF, 0xEC, 0xC0, 0xB2, 0x4D, 0x02, // Common SystemID + 0xAC, 0xE3, 0x3C, 0x1E, 0x52, 0xE2, 0xFB, 0x4B, + 0x00, 0x00, 0x00, 0x01 ], // key count ] + kid, + [ 0x00, 0x00, 0x00, 0x00 ]// datasize + )); + } + if (initDataType == 'keyids') { + + return toUtf8( { kids: [ base64urlEncode( new Uint8Array( kid ) ) ] } ); + } + throw 'initDataType ' + initDataType + ' not supported.'; +} + +function getMultikeyInitDatas( contentitem, initDataType ) +{ + return contentitem.keys.map( function( k ) { return getSingleKeyInitData( k.kid, initDataType ); } ); +} + +function getProprietaryInitDatas( contentitem ) +{ + var keysWithInitData = contentitem.keys.filter( function( k ) { return k.initData; } ); + return { initDataType: contentitem.initDataType, + initDatas : keysWithInitData.map( function( k ) { return k.initData; } ), + variantIds: keysWithInitData.map( function( k ) { return k.variantId; } ) + }; +} + +// Returns a promise that resolves to the following object +// { supported: boolean, // whether the content is supported at all +// content: , // the content item description +// initDataTypes: +// } +// +// Note: we test initData types one at a time since some versions of Edge don't support testing several at once +// +function isContentSupportedForInitDataTypes( keysystem, initDataTypes, contentitem ) +{ + return Promise.all( initDataTypes.map( function( initDataType ) { + var configuration = { initDataTypes : [ initDataType ], + audioCapabilities: [ { contentType: contentitem.audio.type } ], + videoCapabilities: [ { contentType: contentitem.video.type } ] + }; + return navigator.requestMediaKeySystemAccess( keysystem, [ configuration ] ).then( function( access ) { + return { supported: true, initDataType: access.getConfiguration().initDataTypes[ 0 ] }; + }, function() { + return { supported: false }; + } ); + } ) ).then( function( results ) { + + var initDataTypes = results.filter( function( result ) { return result.supported; } ) + .map( function( result ) { return result.initDataType; } ); + + return initDataTypes.length > 0 ? + { content: contentitem, supported: true, initDataTypes: initDataTypes } + : { content: contentitem, supported: false }; + } ); +} + +// Returns a promise that resolves to { content:, supported:, initDataTypes: } object +function isContentSupported( keysystem, contentitem ) +{ + return isContentSupportedForInitDataTypes( keysystem, [ 'cenc', 'webm', 'keyids' ], contentitem ); +} + +// Returns a Promise resolving to an array of supported content for the key system +function getSupportedContent( keysystem ) +{ + return Promise.all( content._items.map( isContentSupported.bind( null, keysystem ) ) ). + then( function( results ) + { + return results.filter( function( r ) { return r.supported; } ).map( function( r ) { return r.content; } ); + } ); +} + +// Returns a Promise resolving to an array of { content:, initDataType: } pairs for the key system +function getSupportedContentAndInitDataTypes( keysystem ) +{ + return Promise.all( content._items.map( isContentSupported.bind( null, keysystem ) ) ). + then( function( results ) + { + return results.filter( function( r ) { return r.supported; } ); + } ); +} + +// gets a configuration object for provided piece of content +function getSimpleConfigurationForContent( contentitem ) +{ + return { initDataTypes: [ 'keyids', 'webm', 'cenc' ], + audioCapabilities: [ { contentType: contentitem.audio.type } ], + videoCapabilities: [ { contentType: contentitem.video.type } ] }; +} diff --git a/testing/web-platform/tests/encrypted-media/content/video_512x288_h264-360k_clear_dashinit.mp4 b/testing/web-platform/tests/encrypted-media/content/video_512x288_h264-360k_clear_dashinit.mp4 new file mode 100644 index 0000000000..33ac63f6bf Binary files /dev/null and b/testing/web-platform/tests/encrypted-media/content/video_512x288_h264-360k_clear_dashinit.mp4 differ diff --git a/testing/web-platform/tests/encrypted-media/content/video_512x288_h264-360k_clear_enc_dashinit.mp4 b/testing/web-platform/tests/encrypted-media/content/video_512x288_h264-360k_clear_enc_dashinit.mp4 new file mode 100644 index 0000000000..dca23449af Binary files /dev/null and b/testing/web-platform/tests/encrypted-media/content/video_512x288_h264-360k_clear_enc_dashinit.mp4 differ diff --git a/testing/web-platform/tests/encrypted-media/content/video_512x288_h264-360k_dashinit.mp4 b/testing/web-platform/tests/encrypted-media/content/video_512x288_h264-360k_dashinit.mp4 new file mode 100644 index 0000000000..53a461e8ae Binary files /dev/null and b/testing/web-platform/tests/encrypted-media/content/video_512x288_h264-360k_dashinit.mp4 differ diff --git a/testing/web-platform/tests/encrypted-media/content/video_512x288_h264-360k_enc_2keys_2sess.mp4 b/testing/web-platform/tests/encrypted-media/content/video_512x288_h264-360k_enc_2keys_2sess.mp4 new file mode 100644 index 0000000000..f59284cfef Binary files /dev/null and b/testing/web-platform/tests/encrypted-media/content/video_512x288_h264-360k_enc_2keys_2sess.mp4 differ diff --git a/testing/web-platform/tests/encrypted-media/content/video_512x288_h264-360k_enc_clear_dashinit.mp4 b/testing/web-platform/tests/encrypted-media/content/video_512x288_h264-360k_enc_clear_dashinit.mp4 new file mode 100644 index 0000000000..d837ac6500 Binary files /dev/null and b/testing/web-platform/tests/encrypted-media/content/video_512x288_h264-360k_enc_clear_dashinit.mp4 differ diff --git a/testing/web-platform/tests/encrypted-media/content/video_512x288_h264-360k_enc_dashinit.mp4 b/testing/web-platform/tests/encrypted-media/content/video_512x288_h264-360k_enc_dashinit.mp4 new file mode 100644 index 0000000000..156a799a9d Binary files /dev/null and b/testing/web-platform/tests/encrypted-media/content/video_512x288_h264-360k_enc_dashinit.mp4 differ diff --git a/testing/web-platform/tests/encrypted-media/content/video_512x288_h264-360k_multikey_dashinit.mp4 b/testing/web-platform/tests/encrypted-media/content/video_512x288_h264-360k_multikey_dashinit.mp4 new file mode 100644 index 0000000000..659a61cdcf Binary files /dev/null and b/testing/web-platform/tests/encrypted-media/content/video_512x288_h264-360k_multikey_dashinit.mp4 differ diff --git a/testing/web-platform/tests/encrypted-media/drm-check-encryption-scheme.https.html b/testing/web-platform/tests/encrypted-media/drm-check-encryption-scheme.https.html new file mode 100644 index 0000000000..862591b1b8 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-check-encryption-scheme.https.html @@ -0,0 +1,32 @@ + + + + + Encrypted Media Extensions: Check encryptionScheme with DRM + + + + + + + + + + + + + + + + + + +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/drm-check-initdata-type.https.html b/testing/web-platform/tests/encrypted-media/drm-check-initdata-type.https.html new file mode 100644 index 0000000000..6b3324027b --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-check-initdata-type.https.html @@ -0,0 +1,32 @@ + + + + + Encrypted Media Extensions: Successful Playback, Temporary session with DRM, mp4 + + + + + + + + + + + + + + + + + + +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/drm-check-status-for-hdcp.https.html b/testing/web-platform/tests/encrypted-media/drm-check-status-for-hdcp.https.html new file mode 100644 index 0000000000..68c45be69b --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-check-status-for-hdcp.https.html @@ -0,0 +1,32 @@ + + + + + Encrypted Media Extensions: Check HDCP status with DRM + + + + + + + + + + + + + + + + + + +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/drm-events-session-closed-event.https.html b/testing/web-platform/tests/encrypted-media/drm-events-session-closed-event.https.html new file mode 100644 index 0000000000..425d17646c --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-events-session-closed-event.https.html @@ -0,0 +1,39 @@ + + + + + Encrypted Media Extensions - Test MediaKeySession closed event with DRM, mp4 + + + + + + + + + + + + + + + + + + +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/drm-events.https.html b/testing/web-platform/tests/encrypted-media/drm-events.https.html new file mode 100644 index 0000000000..5dd2ed774d --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-events.https.html @@ -0,0 +1,71 @@ + + + + + + Encrypted Media Extensions: Events with DRM + + + + + + + + + + + + + + + + + + + + + + +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/drm-expiration.https.html b/testing/web-platform/tests/encrypted-media/drm-expiration.https.html new file mode 100644 index 0000000000..7a9993af8d --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-expiration.https.html @@ -0,0 +1,67 @@ + + + + + + Encrypted Media Extensions: Expiration with DRM + + + + + + + + + + + + + + + + + + + + + + +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/drm-generate-request-disallowed-input.https.html b/testing/web-platform/tests/encrypted-media/drm-generate-request-disallowed-input.https.html new file mode 100644 index 0000000000..45f2bc6957 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-generate-request-disallowed-input.https.html @@ -0,0 +1,31 @@ + + + + + Encrypted Media Extensions: Test handling of invalid initData for generateRequest() + + + + + + + + + + + + + + + +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/drm-invalid-license.https.html b/testing/web-platform/tests/encrypted-media/drm-invalid-license.https.html new file mode 100644 index 0000000000..1443386038 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-invalid-license.https.html @@ -0,0 +1,31 @@ + + + + + Encrypted Media Extensions: Test handling of invalid DRM license + + + + + + + + + + + + + + + +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/drm-keystatuses-multiple-sessions.https.html b/testing/web-platform/tests/encrypted-media/drm-keystatuses-multiple-sessions.https.html new file mode 100644 index 0000000000..61b7c33bdc --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-keystatuses-multiple-sessions.https.html @@ -0,0 +1,55 @@ + + + + + + Encrypted Media Extensions: Successful Playback, Temporary session with DRM, mp4, multiple keys for audio/video + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/drm-keystatuses.https.html b/testing/web-platform/tests/encrypted-media/drm-keystatuses.https.html new file mode 100644 index 0000000000..3fc61a4f7f --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-keystatuses.https.html @@ -0,0 +1,52 @@ + + + + + + Encrypted Media Extensions: Verify MediaKeySession.keyStatuses with multiple sessions, DRM + + + + + + + + + + + + + + + + + + + + + + +
+ + + + \ No newline at end of file diff --git a/testing/web-platform/tests/encrypted-media/drm-mp4-onencrypted.https.html b/testing/web-platform/tests/encrypted-media/drm-mp4-onencrypted.https.html new file mode 100644 index 0000000000..8fc820ce26 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-mp4-onencrypted.https.html @@ -0,0 +1,46 @@ + + + + + Encrypted Media Extensions: Encrypted fired on encrypted media file with DRM, mp4 + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/drm-mp4-playback-destroy-persistent-license.https.html b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-destroy-persistent-license.https.html new file mode 100644 index 0000000000..bc3f5b189f --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-destroy-persistent-license.https.html @@ -0,0 +1,52 @@ + + + + + + Encrypted Media Extensions: Successful Playback, persistent-license session with DRM, mp4, destroy the license + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + \ No newline at end of file diff --git a/testing/web-platform/tests/encrypted-media/drm-mp4-playback-persistent-license-events.https.html b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-persistent-license-events.https.html new file mode 100644 index 0000000000..88660e88f4 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-persistent-license-events.https.html @@ -0,0 +1,52 @@ + + + + + + Encrypted Media Extensions: Successful Playback, persistent-license session with DRM, mp4, event sequence + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + \ No newline at end of file diff --git a/testing/web-platform/tests/encrypted-media/drm-mp4-playback-persistent-license.https.html b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-persistent-license.https.html new file mode 100644 index 0000000000..0c1f94b860 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-persistent-license.https.html @@ -0,0 +1,52 @@ + + + + + + Encrypted Media Extensions: Successful Playback, persistent-license session with DRM, mp4 + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + \ No newline at end of file diff --git a/testing/web-platform/tests/encrypted-media/drm-mp4-playback-persistent-usage-record-events.https.html b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-persistent-usage-record-events.https.html new file mode 100644 index 0000000000..5cbb8021b0 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-persistent-usage-record-events.https.html @@ -0,0 +1,53 @@ + + + + + + Encrypted Media Extensions: Successful Playback, persistent-usage-record session with DRM, mp4, event sequence + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/drm-mp4-playback-persistent-usage-record.https.html b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-persistent-usage-record.https.html new file mode 100644 index 0000000000..69876be989 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-persistent-usage-record.https.html @@ -0,0 +1,53 @@ + + + + + + Encrypted Media Extensions: Successful Playback, persistent-usage-record session with DRM, mp4 + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/drm-mp4-playback-retrieve-destroy-persistent-license.https.html b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-retrieve-destroy-persistent-license.https.html new file mode 100644 index 0000000000..9bba71f89a --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-retrieve-destroy-persistent-license.https.html @@ -0,0 +1,54 @@ + + + + + + Encrypted Media Extensions: Successful Playback, persistent-license session with DRM, mp4, retrieve license, playback and destroy the license + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/drm-mp4-playback-retrieve-persistent-license.https.html b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-retrieve-persistent-license.https.html new file mode 100644 index 0000000000..8429d1922d --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-retrieve-persistent-license.https.html @@ -0,0 +1,53 @@ + + + + + + Encrypted Media Extensions: Successful Playback, persistent-license session with DRM, mp4, retrieve the license, playback + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + \ No newline at end of file diff --git a/testing/web-platform/tests/encrypted-media/drm-mp4-playback-retrieve-persistent-usage-record.https.html b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-retrieve-persistent-usage-record.https.html new file mode 100644 index 0000000000..4059bff0cf --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-retrieve-persistent-usage-record.https.html @@ -0,0 +1,53 @@ + + + + + + Encrypted Media Extensions: persistent-usage-record, playback and retrieve record in new window, DRM, mp4 + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-clear-encrypted.https.html b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-clear-encrypted.https.html new file mode 100644 index 0000000000..6b6e1ce621 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-clear-encrypted.https.html @@ -0,0 +1,53 @@ + + + + + + Encrypted Media Extensions: Successful Playback, Temporary session with DRM, mp4, clear then encrypted + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-encrypted-clear-sources.https.html b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-encrypted-clear-sources.https.html new file mode 100644 index 0000000000..f4ad811df9 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-encrypted-clear-sources.https.html @@ -0,0 +1,58 @@ + + + + + + Encrypted Media Extensions: Successful Playback, alternate Encrypted and Clear playbacks, Temporary, mp4, DRM + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-encrypted-clear.https.html b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-encrypted-clear.https.html new file mode 100644 index 0000000000..f9cce58a90 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-encrypted-clear.https.html @@ -0,0 +1,53 @@ + + + + + + Encrypted Media Extensions: Successful Playback, Temporary session with DRM, mp4, encrypted then clear + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-events.https.html b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-events.https.html new file mode 100644 index 0000000000..c621de0520 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-events.https.html @@ -0,0 +1,52 @@ + + + + + + Encrypted Media Extensions: Successful playback, temporary session with DRM, mp4, validating events + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-expired.https.html b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-expired.https.html new file mode 100644 index 0000000000..4d9cc71ac7 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-expired.https.html @@ -0,0 +1,52 @@ + + + + + + Encrypted Media Extensions: Successful Playback, Temporary session with DRM, mp4, expired license + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-multikey-sequential-readyState.https.html b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-multikey-sequential-readyState.https.html new file mode 100644 index 0000000000..ec69118d69 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-multikey-sequential-readyState.https.html @@ -0,0 +1,57 @@ + + + + + + Encrypted Media Extensions: Successful Playback, Temporary session with DRM, mp4, multiple keys in sequence, check readyState + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-multikey-sequential.https.html b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-multikey-sequential.https.html new file mode 100644 index 0000000000..7f0c23f230 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-multikey-sequential.https.html @@ -0,0 +1,56 @@ + + + + + + Encrypted Media Extensions: Successful Playback, Temporary session with DRM, mp4, multiple keys in sequence + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-multikey.https.html b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-multikey.https.html new file mode 100644 index 0000000000..5be9bda028 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-multikey.https.html @@ -0,0 +1,52 @@ + + + + + + Encrypted Media Extensions: Successful playback, temporary session with DRM, mp4, multiple keys + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-multisession.https.html b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-multisession.https.html new file mode 100644 index 0000000000..e22e4f9350 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-multisession.https.html @@ -0,0 +1,55 @@ + + + + + + Encrypted Media Extensions: Verify MediaKeySession.keyStatuses with multiple sessions, DRM + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-playduration-keystatus.html b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-playduration-keystatus.html new file mode 100644 index 0000000000..46cf5c9184 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-playduration-keystatus.html @@ -0,0 +1,52 @@ + + + + + Encrypted Media Extensions: Successful Playback, Temporary session limited playduration, check keystatus, DRM, mp4 + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-playduration.html b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-playduration.html new file mode 100644 index 0000000000..173e0f0d59 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-playduration.html @@ -0,0 +1,52 @@ + + + + + Encrypted Media Extensions: Successful Playback, Temporary session limited playduration, DRM, mp4 + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-setMediaKeys-after-src.https.html b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-setMediaKeys-after-src.https.html new file mode 100644 index 0000000000..3560e0ab85 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-setMediaKeys-after-src.https.html @@ -0,0 +1,52 @@ + + + + + + Encrypted Media Extensions: Successful Playback, Temporary session with DRM, mp4 + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + \ No newline at end of file diff --git a/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-setMediaKeys-after-update.https.html b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-setMediaKeys-after-update.https.html new file mode 100644 index 0000000000..f225859dc5 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-setMediaKeys-after-update.https.html @@ -0,0 +1,52 @@ + + + + + + Encrypted Media Extensions: Successful Playback, Temporary session with DRM, mp4 + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + \ No newline at end of file diff --git a/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-setMediaKeys-immediately.https.html b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-setMediaKeys-immediately.https.html new file mode 100644 index 0000000000..2c198ef8fe --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-setMediaKeys-immediately.https.html @@ -0,0 +1,52 @@ + + + + + + Encrypted Media Extensions: Successful Playback, Temporary session with DRM, mp4 + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-setMediaKeys-onencrypted.https.html b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-setMediaKeys-onencrypted.https.html new file mode 100644 index 0000000000..d3efc80f61 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-setMediaKeys-onencrypted.https.html @@ -0,0 +1,52 @@ + + + + + + Encrypted Media Extensions: Successful Playback, Temporary session with DRM, mp4 + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + \ No newline at end of file diff --git a/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-two-videos.https.html b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-two-videos.https.html new file mode 100644 index 0000000000..cbd6c9c659 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-two-videos.https.html @@ -0,0 +1,54 @@ + + + + + + Encrypted Media Extensions: Successful Playback, Temporary session with DRM, mp4, two videos + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-waitingforkey.https.html b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-waitingforkey.https.html new file mode 100644 index 0000000000..edd5e37204 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary-waitingforkey.https.html @@ -0,0 +1,53 @@ + + + + + + Encrypted Media Extensions: Verify MediaKeySession.keyStatuses with multiple sessions, DRM + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + \ No newline at end of file diff --git a/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary.https.html b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary.https.html new file mode 100644 index 0000000000..b0ad0ef0c6 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-mp4-playback-temporary.https.html @@ -0,0 +1,52 @@ + + + + + + Encrypted Media Extensions: Successful Playback, Temporary session with DRM, mp4 + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/drm-mp4-requestmediakeysystemaccess.https.html b/testing/web-platform/tests/encrypted-media/drm-mp4-requestmediakeysystemaccess.https.html new file mode 100644 index 0000000000..ae0165f09e --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-mp4-requestmediakeysystemaccess.https.html @@ -0,0 +1,39 @@ + + + + + Encrypted Media Extensions: requestMediaKeySystemAccess tests, DRM + + + + + + + + + + + + + + + + + + + +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/drm-mp4-reset-src-after-setmediakeys.https.html b/testing/web-platform/tests/encrypted-media/drm-mp4-reset-src-after-setmediakeys.https.html new file mode 100644 index 0000000000..bbcefee8cf --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-mp4-reset-src-after-setmediakeys.https.html @@ -0,0 +1,45 @@ + + + + + Encrypted Media Extensions - Reset MediaSource after setMediaKeys for DRM, mp4 + + + + + + + + + + + + + + + + + + +
+
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/drm-mp4-setmediakeys-again-after-playback.https.html b/testing/web-platform/tests/encrypted-media/drm-mp4-setmediakeys-again-after-playback.https.html new file mode 100644 index 0000000000..a60b764772 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-mp4-setmediakeys-again-after-playback.https.html @@ -0,0 +1,52 @@ + + + + + + Encrypted Media Extensions: setMediaKeys again after playback with DRM + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/drm-mp4-setmediakeys-again-after-resetting-src.https.html b/testing/web-platform/tests/encrypted-media/drm-mp4-setmediakeys-again-after-resetting-src.https.html new file mode 100644 index 0000000000..bff89c0a44 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-mp4-setmediakeys-again-after-resetting-src.https.html @@ -0,0 +1,52 @@ + + + + + + Encrypted Media Extensions: setMediaKeys again after resetting src attribute on video element with DRM + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/drm-mp4-setmediakeys-at-same-time.https.html b/testing/web-platform/tests/encrypted-media/drm-mp4-setmediakeys-at-same-time.https.html new file mode 100644 index 0000000000..571d354353 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-mp4-setmediakeys-at-same-time.https.html @@ -0,0 +1,44 @@ + + + + + + Encrypted Media Extensions: setMediaKeys multiple at same time with DRM + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/drm-mp4-setmediakeys-multiple-times-with-different-mediakeys.https.html b/testing/web-platform/tests/encrypted-media/drm-mp4-setmediakeys-multiple-times-with-different-mediakeys.https.html new file mode 100644 index 0000000000..453ded031c --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-mp4-setmediakeys-multiple-times-with-different-mediakeys.https.html @@ -0,0 +1,50 @@ + + + + + + Encrypted Media Extensions: setMediaKeys multiple times with different mediakeys with DRM + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/drm-mp4-setmediakeys-multiple-times-with-the-same-mediakeys.https.html b/testing/web-platform/tests/encrypted-media/drm-mp4-setmediakeys-multiple-times-with-the-same-mediakeys.https.html new file mode 100644 index 0000000000..adf91b826a --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-mp4-setmediakeys-multiple-times-with-the-same-mediakeys.https.html @@ -0,0 +1,50 @@ + + + + + + Encrypted Media Extensions: setMediaKeys multiple times with the same mediakeys with DRM + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/drm-mp4-setmediakeys-to-multiple-video-elements.https.html b/testing/web-platform/tests/encrypted-media/drm-mp4-setmediakeys-to-multiple-video-elements.https.html new file mode 100644 index 0000000000..952815184a --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-mp4-setmediakeys-to-multiple-video-elements.https.html @@ -0,0 +1,48 @@ + + + + + + Encrypted Media Extensions: setMediaKeys to multiple video elements with DRM + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/drm-mp4-setmediakeys.https.html b/testing/web-platform/tests/encrypted-media/drm-mp4-setmediakeys.https.html new file mode 100644 index 0000000000..45318acaa5 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-mp4-setmediakeys.https.html @@ -0,0 +1,40 @@ + + + + + Encrypted Media Extensions: setMediaKeys with DRM + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/drm-mp4-syntax-mediakeys.https.html b/testing/web-platform/tests/encrypted-media/drm-mp4-syntax-mediakeys.https.html new file mode 100644 index 0000000000..22fa605f45 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-mp4-syntax-mediakeys.https.html @@ -0,0 +1,42 @@ + + + + + Encrypted Media Extensions - Test MediaKeys attribute, setServerCertificate and setServerCertificate exception syntax for DRM, mp4 + + + + + + + + + + + + + + + + + + +
+
+ +
+ + + diff --git a/testing/web-platform/tests/encrypted-media/drm-mp4-syntax-mediakeysession.https.html b/testing/web-platform/tests/encrypted-media/drm-mp4-syntax-mediakeysession.https.html new file mode 100644 index 0000000000..ea15884125 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-mp4-syntax-mediakeysession.https.html @@ -0,0 +1,42 @@ + + + + + Encrypted Media Extensions - Test MediaKeySession attribute and function syntax for DRM, mp4 + + + + + + + + + + + + + + + + + + +
+
+ +
+ + + diff --git a/testing/web-platform/tests/encrypted-media/drm-mp4-syntax-mediakeysystemaccess.https.html b/testing/web-platform/tests/encrypted-media/drm-mp4-syntax-mediakeysystemaccess.https.html new file mode 100644 index 0000000000..5714ed35e3 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-mp4-syntax-mediakeysystemaccess.https.html @@ -0,0 +1,42 @@ + + + + + Encrypted Media Extensions - Test navigator.requestmediakeysystemaccess exception and MediaKeySystemAccess attribute syntax for DRM, mp4 + + + + + + + + + + + + + + + + + + +
+
+ +
+ + + diff --git a/testing/web-platform/tests/encrypted-media/drm-mp4-unique-origin.https.html b/testing/web-platform/tests/encrypted-media/drm-mp4-unique-origin.https.html new file mode 100644 index 0000000000..3e13ab5a6c --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-mp4-unique-origin.https.html @@ -0,0 +1,43 @@ + + + + + Encrypted Media Extensions: Unique origin with DRM, mp4 + + + + + + + + + + + + + + + + + +
+
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/drm-mp4-waiting-for-a-key.https.html b/testing/web-platform/tests/encrypted-media/drm-mp4-waiting-for-a-key.https.html new file mode 100644 index 0000000000..dc5197b356 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-mp4-waiting-for-a-key.https.html @@ -0,0 +1,52 @@ + + + + + + Encrypted Media Extensions - Waiting for a key for DRM, mp4 + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/drm-not-callable-after-createsession.https.html b/testing/web-platform/tests/encrypted-media/drm-not-callable-after-createsession.https.html new file mode 100644 index 0000000000..c783a179a8 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-not-callable-after-createsession.https.html @@ -0,0 +1,31 @@ + + + + + Encrypted Media Extensions: Test MediaKeySession not callable immediately after CreateSession(), DRM. + + + + + + + + + + + + + + + +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/drm-temporary-license-type.https.html b/testing/web-platform/tests/encrypted-media/drm-temporary-license-type.https.html new file mode 100644 index 0000000000..90d84cc86b --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/drm-temporary-license-type.https.html @@ -0,0 +1,71 @@ + + + + + + Encrypted Media Extensions: Test that persistent license cannot be ingested into temporary session + + + + + + + + + + + + + + + + + + + + + + +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/encrypted-media-default-feature-policy.https.sub.html b/testing/web-platform/tests/encrypted-media/encrypted-media-default-feature-policy.https.sub.html new file mode 100644 index 0000000000..a5114262ad --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/encrypted-media-default-feature-policy.https.sub.html @@ -0,0 +1,20 @@ + + + + + + + + diff --git a/testing/web-platform/tests/encrypted-media/encrypted-media-supported-by-feature-policy.tentative.html b/testing/web-platform/tests/encrypted-media/encrypted-media-supported-by-feature-policy.tentative.html new file mode 100644 index 0000000000..5b2d2240c6 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/encrypted-media-supported-by-feature-policy.tentative.html @@ -0,0 +1,11 @@ + +Test that encrypted-media is advertised in the feature list + + + + + diff --git a/testing/web-platform/tests/encrypted-media/idlharness.https.html b/testing/web-platform/tests/encrypted-media/idlharness.https.html new file mode 100644 index 0000000000..18c8f89ea2 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/idlharness.https.html @@ -0,0 +1,36 @@ + + + + + Encrypted Media Extentions IDL test + + + + + + + + + +

Description

+

+ This test verifies that implementations of the Encrypted Media Extensions API match its WebIDL definition. +

+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/polyfill/cast-polyfill.js b/testing/web-platform/tests/encrypted-media/polyfill/cast-polyfill.js new file mode 100644 index 0000000000..576e0ad040 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/polyfill/cast-polyfill.js @@ -0,0 +1,80 @@ +(function() { + + if ( /CrKey\/[0-9]+\.[0-9a-z]+\.[0-9a-z]+/i.exec( navigator.userAgent ) ) { + + var castscript = document.createElement('script'); + castscript.type = 'text/javascript'; + castscript.src = 'https://www.gstatic.com/cast/sdk/libs/receiver/2.0.0/cast_receiver.js' + document.head.appendChild( castscript ); + + var _requestMediaKeySystemAccess = navigator.requestMediaKeySystemAccess.bind( navigator ), + _setMediaKeys = HTMLMediaElement.prototype.setMediaKeys, + _load = MediaKeySession.prototype.load; + + MediaKeySession.prototype.load = function load() + { + return _load.call( this ).then( function( success ) + { + return success ? this.remove() : false; + }.bind( this ) ); + }; + + function MediaKeys( mediaKeys ) + { + this._mediaKeys = mediaKeys; + } + + MediaKeys.prototype.setServerCertificate = function setServerCertificate( certificate ) + { + return this._mediaKeys.setServerCertificate( certificate ); + }; + + MediaKeys.prototype.createSession = function createSession( sessionType ) { + + if ( sessionType === 'persistent-usage-record' ) + { + return cast.receiver.eme.KeySession.createSession( this._mediaKeys, 'persistent-release-message' ); + } + + return this._mediaKeys.createSession( sessionType ); + }; + + function MediaKeySystemAccess( access ) + { + this._access = mediaKeySystemAccess; + } + + Object.defineProperty( MediaKeySystemAccess.prototype, 'keySystem', { get: function() { return this._access.keySystem; } } ); + + MediaKeySystemAccess.prototype.getConfiguration = function getConfiguration() { return this._access.getConfiguration(); }; + + MediaKeySystemAccess.prototype.createMediaKeys = function createMediaKeys() { + + return this._access.createMediaKey().then( function( mediaKeys ) { return new MediaKeys( mediaKeys ); } ); + + }; + + HTMLMediaElement.prototype.setMediaKeys = function setMediaKeys( mediaKeys ) + { + if ( mediaKeys instanceof MediaKeys ) + { + return _setMediaKeys.call( this, mediaKeys._mediaKeys ); + } + else + { + return _setMediaKeys.call( this, mediaKeys ); + } + }; + + navigator.requestMediaKeySystemAccess = function requestMediaKeySystemAccess( keysystem, supportedConfigurations ) { + + if ( keysystem !== 'com.chromecast.playready' ) + { + return _requestMediaKeySystemAccess( keysystem, supportedConfigurations ); + } + + return _requestMediaKeySystemAccess( keysystem, supportedConfigurations ) + .then( function( access ) { return new MediaKeySystemAccess( access ); } ); + }; + } +})(); \ No newline at end of file diff --git a/testing/web-platform/tests/encrypted-media/polyfill/chrome-polyfill.js b/testing/web-platform/tests/encrypted-media/polyfill/chrome-polyfill.js new file mode 100644 index 0000000000..2f11497cca --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/polyfill/chrome-polyfill.js @@ -0,0 +1,37 @@ +(function(){ + if( navigator.userAgent.toLowerCase().indexOf('edge') === -1 + && navigator.userAgent.toLowerCase().indexOf('chrome') > -1){ + + if ( ( /chrome\/([0-9]*)\./.exec( navigator.userAgent.toLowerCase() )[1] | 0 ) < 54 ) { + + // Work around https://bugs.chromium.org/p/chromium/issues/detail?id=622956 + // Chrome does not fire the empty keystatuschange event when a session is closed + var _mediaKeySessionClose = MediaKeySession.prototype.close; + var _mediaKeySessionKeyStatusesGetter = Object.getOwnPropertyDescriptor( MediaKeySession.prototype, 'keyStatuses' ).get; + var _emptyMediaKeyStatusMap = { size: 0, + has: function() { return false; }, + get: function() { return undefined; }, + entries:function() { return []; }, // this may not be correct, I think it should be some iterator thing + keys: function() { return []; }, + values: function() { return []; }, + forEach:function() { return; } }; + + MediaKeySession.prototype.close = function close() + { + this.__closed = true; + + setTimeout( function() { + this.dispatchEvent( new Event( 'keystatuseschange' ) ); + }.bind( this ), 0 ); + + return _mediaKeySessionClose.call( this ); + }; + + Object.defineProperty( MediaKeySession.prototype, 'keyStatuses', { get: function() { + + return this.__closed ? _emptyMediaKeyStatusMap : _mediaKeySessionKeyStatusesGetter.call( this ); + + } } ); + } + } +}()); diff --git a/testing/web-platform/tests/encrypted-media/polyfill/clearkey-polyfill.js b/testing/web-platform/tests/encrypted-media/polyfill/clearkey-polyfill.js new file mode 100644 index 0000000000..057ea3e030 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/polyfill/clearkey-polyfill.js @@ -0,0 +1,510 @@ +(function(){ + + // Save platform functions that will be modified + var _requestMediaKeySystemAccess = navigator.requestMediaKeySystemAccess.bind( navigator ), + _setMediaKeys = HTMLMediaElement.prototype.setMediaKeys; + + // Allow us to modify the target of Events + Object.defineProperties( Event.prototype, { + target: { get: function() { return this._target || this.currentTarget; }, + set: function( newtarget ) { this._target = newtarget; } } + } ); + + var EventTarget = function(){ + this.listeners = {}; + }; + + EventTarget.prototype.listeners = null; + + EventTarget.prototype.addEventListener = function(type, callback){ + if(!(type in this.listeners)) { + this.listeners[type] = []; + } + this.listeners[type].push(callback); + }; + + EventTarget.prototype.removeEventListener = function(type, callback){ + if(!(type in this.listeners)) { + return; + } + var stack = this.listeners[type]; + for(var i = 0, l = stack.length; i < l; i++){ + if(stack[i] === callback){ + stack.splice(i, 1); + return this.removeEventListener(type, callback); + } + } + }; + + EventTarget.prototype.dispatchEvent = function(event){ + if(!(event.type in this.listeners)) { + return; + } + var stack = this.listeners[event.type]; + event.target = this; + for(var i = 0, l = stack.length; i < l; i++) { + stack[i].call(this, event); + } + }; + + function MediaKeySystemAccessProxy( keysystem, access, configuration ) + { + this._keysystem = keysystem; + this._access = access; + this._configuration = configuration; + } + + Object.defineProperties( MediaKeySystemAccessProxy.prototype, { + keysystem: { get: function() { return this._keysystem; } } + }); + + MediaKeySystemAccessProxy.prototype.getConfiguration = function getConfiguration() + { + return this._configuration; + }; + + MediaKeySystemAccessProxy.prototype.createMediaKeys = function createMediaKeys() + { + return new Promise( function( resolve, reject ) { + + this._access.createMediaKeys() + .then( function( mediaKeys ) { resolve( new MediaKeysProxy( mediaKeys ) ); }) + .catch( function( error ) { reject( error ); } ); + + }.bind( this ) ); + }; + + function MediaKeysProxy( mediaKeys ) + { + this._mediaKeys = mediaKeys; + this._sessions = [ ]; + this._videoelement = undefined; + this._onTimeUpdateListener = MediaKeysProxy.prototype._onTimeUpdate.bind( this ); + } + + MediaKeysProxy.prototype._setVideoElement = function _setVideoElement( videoElement ) + { + if ( videoElement !== this._videoelement ) + { + if ( this._videoelement ) + { + this._videoelement.removeEventListener( 'timeupdate', this._onTimeUpdateListener ); + } + + this._videoelement = videoElement; + + if ( this._videoelement ) + { + this._videoelement.addEventListener( 'timeupdate', this._onTimeUpdateListener ); + } + } + }; + + MediaKeysProxy.prototype._onTimeUpdate = function( event ) + { + this._sessions.forEach( function( session ) { + + if ( session._sessionType === 'persistent-usage-record' ) + { + session._onTimeUpdate( event ); + } + + } ); + }; + + MediaKeysProxy.prototype._removeSession = function _removeSession( session ) + { + var index = this._sessions.indexOf( session ); + if ( index !== -1 ) this._sessions.splice( index, 1 ); + }; + + MediaKeysProxy.prototype.createSession = function createSession( sessionType ) + { + if ( !sessionType || sessionType === 'temporary' ) return this._mediaKeys.createSession(); + + var session = new MediaKeySessionProxy( this, sessionType ); + this._sessions.push( session ); + + return session; + }; + + MediaKeysProxy.prototype.setServerCertificate = function setServerCertificate( certificate ) + { + return this._mediaKeys.setServerCertificate( certificate ); + }; + + function MediaKeySessionProxy( mediaKeysProxy, sessionType ) + { + EventTarget.call( this ); + + this._mediaKeysProxy = mediaKeysProxy + this._sessionType = sessionType; + this._sessionId = ""; + + // MediaKeySessionProxy states + // 'created' - After initial creation + // 'loading' - Persistent license session waiting for key message to load stored keys + // 'active' - Normal active state - proxy all key messages + // 'removing' - Release message generated, waiting for ack + // 'closed' - Session closed + this._state = 'created'; + + this._closed = new Promise( function( resolve ) { this._resolveClosed = resolve; }.bind( this ) ); + } + + MediaKeySessionProxy.prototype = Object.create( EventTarget.prototype ); + + Object.defineProperties( MediaKeySessionProxy.prototype, { + + sessionId: { get: function() { return this._sessionId; } }, + expiration: { get: function() { return NaN; } }, + closed: { get: function() { return this._closed; } }, + keyStatuses:{ get: function() { return this._session.keyStatuses; } }, // TODO this will fail if examined too early + _kids: { get: function() { return this._keys.map( function( key ) { return key.kid; } ); } }, + }); + + MediaKeySessionProxy.prototype._createSession = function _createSession() + { + this._session = this._mediaKeysProxy._mediaKeys.createSession(); + + this._session.addEventListener( 'message', MediaKeySessionProxy.prototype._onMessage.bind( this ) ); + this._session.addEventListener( 'keystatuseschange', MediaKeySessionProxy.prototype._onKeyStatusesChange.bind( this ) ); + }; + + MediaKeySessionProxy.prototype._onMessage = function _onMessage( event ) + { + switch( this._state ) + { + case 'loading': + this._session.update( toUtf8( { keys: this._keys } ) ) + .then( function() { + this._state = 'active'; + this._loaded( true ); + }.bind(this)).catch( this._loadfailed ); + + break; + + case 'active': + this.dispatchEvent( event ); + break; + + default: + // Swallow the event + break; + } + }; + + MediaKeySessionProxy.prototype._onKeyStatusesChange = function _onKeyStatusesChange( event ) + { + switch( this._state ) + { + case 'active' : + case 'removing' : + this.dispatchEvent( event ); + break; + + default: + // Swallow the event + break; + } + }; + + MediaKeySessionProxy.prototype._onTimeUpdate = function _onTimeUpdate( event ) + { + if ( !this._firstTime ) this._firstTime = Date.now(); + this._latestTime = Date.now(); + this._store(); + }; + + MediaKeySessionProxy.prototype._queueMessage = function _queueMessage( messageType, message ) + { + setTimeout( function() { + + var messageAsArray = toUtf8( message ).buffer; + + this.dispatchEvent( new MediaKeyMessageEvent( 'message', { messageType: messageType, message: messageAsArray } ) ); + + }.bind( this ) ); + }; + + function _storageKey( sessionId ) + { + return sessionId; + } + + MediaKeySessionProxy.prototype._store = function _store() + { + var data; + + if ( this._sessionType === 'persistent-usage-record' ) + { + data = { kids: this._kids }; + if ( this._firstTime ) data.firstTime = this._firstTime; + if ( this._latestTime ) data.latestTime = this._latestTime; + } + else + { + data = { keys: this._keys }; + } + + window.localStorage.setItem( _storageKey( this._sessionId ), JSON.stringify( data ) ); + }; + + MediaKeySessionProxy.prototype._load = function _load( sessionId ) + { + var store = window.localStorage.getItem( _storageKey( sessionId ) ); + if ( store === null ) return false; + + var data; + try { data = JSON.parse( store ) } catch( error ) { + return false; + } + + if ( data.kids ) + { + this._sessionType = 'persistent-usage-record'; + this._keys = data.kids.map( function( kid ) { return { kid: kid }; } ); + if ( data.firstTime ) this._firstTime = data.firstTime; + if ( data.latestTime ) this._latestTime = data.latestTime; + } + else + { + this._sessionType = 'persistent-license'; + this._keys = data.keys; + } + + return true; + }; + + MediaKeySessionProxy.prototype._clear = function _clear() + { + window.localStorage.removeItem( _storageKey( this._sessionId ) ); + }; + + MediaKeySessionProxy.prototype.generateRequest = function generateRequest( initDataType, initData ) + { + if ( this._state !== 'created' ) return Promise.reject( new InvalidStateError() ); + + this._createSession(); + + this._state = 'active'; + + return this._session.generateRequest( initDataType, initData ) + .then( function() { + this._sessionId = Math.random().toString(36).slice(2); + }.bind( this ) ); + }; + + MediaKeySessionProxy.prototype.load = function load( sessionId ) + { + if ( this._state !== 'created' ) return Promise.reject( new InvalidStateError() ); + + return new Promise( function( resolve, reject ) { + + try + { + if ( !this._load( sessionId ) ) + { + resolve( false ); + + return; + } + + this._sessionId = sessionId; + + if ( this._sessionType === 'persistent-usage-record' ) + { + var msg = { kids: this._kids }; + if ( this._firstTime ) msg.firstTime = this._firstTime; + if ( this._latestTime ) msg.latestTime = this._latestTime; + + this._queueMessage( 'license-release', msg ); + + this._state = 'removing'; + + resolve( true ); + } + else + { + this._createSession(); + + this._state = 'loading'; + this._loaded = resolve; + this._loadfailed = reject; + + var initData = { kids: this._kids }; + + this._session.generateRequest( 'keyids', toUtf8( initData ) ); + } + } + catch( error ) + { + reject( error ); + } + }.bind( this ) ); + }; + + MediaKeySessionProxy.prototype.update = function update( response ) + { + return new Promise( function( resolve, reject ) { + + switch( this._state ) { + + case 'active' : + + var message = fromUtf8( response ); + + // JSON Web Key Set + this._keys = message.keys; + + this._store(); + + resolve( this._session.update( response ) ); + + break; + + case 'removing' : + + this._state = 'closed'; + + this._clear(); + + this._mediaKeysProxy._removeSession( this ); + + this._resolveClosed(); + + delete this._session; + + resolve(); + + break; + + default: + reject( new InvalidStateError() ); + } + + }.bind( this ) ); + }; + + MediaKeySessionProxy.prototype.close = function close() + { + if ( this._state === 'closed' ) return Promise.resolve(); + + this._state = 'closed'; + + this._mediaKeysProxy._removeSession( this ); + + this._resolveClosed(); + + var session = this._session; + if ( !session ) return Promise.resolve(); + + this._session = undefined; + + return session.close(); + }; + + MediaKeySessionProxy.prototype.remove = function remove() + { + if ( this._state !== 'active' || !this._session ) return Promise.reject( new DOMException('InvalidStateError('+this._state+')') ); + + this._state = 'removing'; + + this._mediaKeysProxy._removeSession( this ); + + return this._session.close() + .then( function() { + + var msg = { kids: this._kids }; + + if ( this._sessionType === 'persistent-usage-record' ) + { + if ( this._firstTime ) msg.firstTime = this._firstTime; + if ( this._latestTime ) msg.latestTime = this._latestTime; + } + + this._queueMessage( 'license-release', msg ); + + }.bind( this ) ) + }; + + HTMLMediaElement.prototype.setMediaKeys = function setMediaKeys( mediaKeys ) + { + if ( mediaKeys instanceof MediaKeysProxy ) + { + mediaKeys._setVideoElement( this ); + return _setMediaKeys.call( this, mediaKeys._mediaKeys ); + } + else + { + return _setMediaKeys.call( this, mediaKeys ); + } + }; + + navigator.requestMediaKeySystemAccess = function( keysystem, configurations ) + { + // First, see if this is supported by the platform + return new Promise( function( resolve, reject ) { + + _requestMediaKeySystemAccess( keysystem, configurations ) + .then( function( access ) { resolve( access ); } ) + .catch( function( error ) { + + if ( error instanceof TypeError ) reject( error ); + + if ( keysystem !== 'org.w3.clearkey' ) reject( error ); + + if ( !configurations.some( is_persistent_configuration ) ) reject( error ); + + // Shallow copy the configurations, swapping out the labels and omitting the sessiontypes + var configurations_copy = configurations.map( function( config, index ) { + + var config_copy = copy_configuration( config ); + config_copy.label = index.toString(); + return config_copy; + + } ); + + // And try again with these configurations + _requestMediaKeySystemAccess( keysystem, configurations_copy ) + .then( function( access ) { + + // Create the supported configuration based on the original request + var configuration = access.getConfiguration(), + original_configuration = configurations[ configuration.label ]; + + // If the original configuration did not need persistent session types, then we're done + if ( !is_persistent_configuration( original_configuration ) ) resolve( access ); + + // Create the configuration that we will return + var returned_configuration = copy_configuration( configuration ); + + if ( original_configuration.label ) + returned_configuration.label = original_configuration; + else + delete returned_configuration.label; + + returned_configuration.sessionTypes = original_configuration.sessionTypes; + + resolve( new MediaKeySystemAccessProxy( keysystem, access, returned_configuration ) ); + } ) + .catch( function( error ) { reject( error ); } ); + } ); + } ); + }; + + function is_persistent_configuration( configuration ) + { + return configuration.sessionTypes && + ( configuration.sessionTypes.indexOf( 'persistent-usage-record' ) !== -1 + || configuration.sessionTypes.indexOf( 'persistent-license' ) !== -1 ); + } + + function copy_configuration( src ) + { + var dst = {}; + [ 'label', 'initDataTypes', 'audioCapabilities', 'videoCapabilities', 'distinctiveIdenfifier', 'persistentState' ] + .forEach( function( item ) { if ( src[item] ) dst[item] = src[item]; } ); + return dst; + } +}()); diff --git a/testing/web-platform/tests/encrypted-media/polyfill/edge-keystatuses.js b/testing/web-platform/tests/encrypted-media/polyfill/edge-keystatuses.js new file mode 100644 index 0000000000..8861444591 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/polyfill/edge-keystatuses.js @@ -0,0 +1,144 @@ +(function() { + + // This polyfill fixes the following problems with Edge browser + // (1) Various maplike methods for keystatuses are not supported or suported incorrectly + // (2) Key Ids exposed in keystatuses are incorrect (byte swaps) + if ( navigator.userAgent.toLowerCase().indexOf('edge') > -1 ) { + /////////////////////////////////////////////////////////////////////////////////////////////// + // The following function is the core of this JS patch. The rest of this file is infrastructure + // required to enable this function + /////////////////////////////////////////////////////////////////////////////////////////////// + function _proxyKeyStatusesChange( event ) { + this._keyStatuses.clear(); + var keyStatuses = []; + this._session.keyStatuses.forEach( function( keyId, status ) { + var newKeyId = new Uint8Array( keyId ); + + function swap( arr, a, b ) { var t = arr[a]; arr[a] = arr[b]; arr[b] = t; } + swap( newKeyId, 0, 3 ); + swap( newKeyId, 1, 2 ); + swap( newKeyId, 4, 5 ); + swap( newKeyId, 6, 7 ); + + keyStatuses.push( { key: newKeyId, status: status, ord: arrayBufferAsString( newKeyId ) } ); + }); + + function lexicographical( a, b ) { return a < b ? -1 : a === b ? 0 : +1; } + function lexicographicalkey( a, b ) { return lexicographical( a.ord, b.ord ); } + + keyStatuses.sort( lexicographicalkey ).forEach( function( obj ) { + this._keyStatuses._set( obj.key, obj.status ); + }.bind( this ) ); + + this.dispatchEvent( event ); + }; + /////////////////////////////////////////////////////////////////////////////////////////////// + + // Override MediaKeys.createSession + var _mediaKeysCreateSession = MediaKeys.prototype.createSession; + MediaKeys.prototype.createSession = function ( sessionType ) { + return new MediaKeySession( _mediaKeysCreateSession.call( this, sessionType ) ); + }; + + // MediaKeySession proxy + function MediaKeySession( session ) { + EventTarget.call( this ); + this._session = session; + this._keyStatuses = new MediaKeyStatusMap(); + this._session.addEventListener("keystatuseschange",this._onKeyStatusesChange.bind(this)); + this._session.addEventListener("message",this.dispatchEvent.bind(this)); + } + + MediaKeySession.prototype = Object.create( EventTarget.prototype ); + + Object.defineProperties( MediaKeySession.prototype, { + sessionId: { get: function() { return this._session.sessionId; } }, + expiration: { get: function() { return this._session.expiration; } }, + closed: { get: function() { return this._session.closed; } }, + keyStatuses:{ get: function() { return this._keyStatuses; } } + }); + + [ "generateRequest", "load", "update", "remove", "close" ].forEach( function( fnname ) { + MediaKeySession.prototype[ fnname ] = function() { + return window.MediaKeySession.prototype[ fnname ].apply( this._session, arguments ); + } + } ); + + MediaKeySession.prototype._onKeyStatusesChange = _proxyKeyStatusesChange; + + // MediaKeyStatusMap proxy + // + // We need a proxy class to replace the broken MediaKeyStatusMap one. We cannot use a + // regular Map directly because we need get and has methods to compare by value not + // as references. + function MediaKeyStatusMap() { this._map = new Map(); } + + Object.defineProperties( MediaKeyStatusMap.prototype, { + size: { get: function() { return this._map.size; } }, + forEach: { get: function() { return function( f ) { return this._map.forEach( f ); } } }, + entries: { get: function() { return function() { return this._map.entries(); } } }, + values: { get: function() { return function() { return this._map.values(); } } }, + keys: { get: function() { return function() { return this._map.keys(); } } }, + clear: { get: function() { return function() { return this._map.clear(); } } } } ); + + MediaKeyStatusMap.prototype[ Symbol.iterator ] = function() { return this._map[ Symbol.iterator ]() }; + + MediaKeyStatusMap.prototype.has = function has( keyId ) { + for ( var k of this._map.keys() ) { if ( arrayBufferEqual( k, keyId ) ) return true; } + return false; + }; + + MediaKeyStatusMap.prototype.get = function get( keyId ) { + for ( var k of this._map.entries() ) { if ( arrayBufferEqual( k[ 0 ], keyId ) ) return k[ 1 ]; } + }; + + MediaKeyStatusMap.prototype._set = function _set( keyId, status ) { + this._map.set( new Uint8Array( keyId ), status ); + }; + + function arrayBufferEqual(buf1, buf2) + { + if (buf1.byteLength !== buf2.byteLength) return false; + var a1 = Array.from( new Int8Array(buf1) ), a2 = Array.from( new Int8Array(buf2) ); + return a1.every( function( x, i ) { return x === a2[i]; } ); + } + + // EventTarget + function EventTarget(){ + this.listeners = {}; + }; + + EventTarget.prototype.listeners = null; + + EventTarget.prototype.addEventListener = function(type, callback){ + if(!(type in this.listeners)) { + this.listeners[type] = []; + } + this.listeners[type].push(callback); + }; + + EventTarget.prototype.removeEventListener = function(type, callback){ + if(!(type in this.listeners)) { + return; + } + var stack = this.listeners[type]; + for(var i = 0, l = stack.length; i < l; i++){ + if(stack[i] === callback){ + stack.splice(i, 1); + return this.removeEventListener(type, callback); + } + } + }; + + EventTarget.prototype.dispatchEvent = function(event){ + if(!(event.type in this.listeners)) { + return; + } + var stack = this.listeners[event.type]; + event.target = this; + for(var i = 0, l = stack.length; i < l; i++) { + stack[i].call(this, event); + } + }; + } +})(); diff --git a/testing/web-platform/tests/encrypted-media/polyfill/edge-persistent-usage-record.js b/testing/web-platform/tests/encrypted-media/polyfill/edge-persistent-usage-record.js new file mode 100644 index 0000000000..7f86f0c058 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/polyfill/edge-persistent-usage-record.js @@ -0,0 +1,193 @@ +(function() { + + // This polyfill fixes the following problems with Edge browser + // (1) To retrieve a persisted usage record, you must use session type 'persistent-release-message' instead of 'persistent-usage-record' + // (2) To retrieve a persisted usage record, you must call remove() after calling load() + // (3) On providing a license release acknowledgement, the session does not automatically close as is should + // (4) Retrieval of the usage record at the end of an active session is not supported + + if ( navigator.userAgent.toLowerCase().indexOf('edge') > -1 ) { + + var _mediaKeySystemAccessCreateMediaKeys = MediaKeySystemAccess.prototype.createMediaKeys; + _mediaKeysCreateSession = MediaKeys.prototype.createSession; + + // MediaKeySession proxy + function MediaKeySession( mediaKeys, session ) + { + EventTarget.call( this ); + + this._mediaKeys = mediaKeys; + this._session = session; + this._sessionId = undefined; + this._removing = false; + + session.addEventListener( 'message', this.dispatchEvent.bind( this ) ); + session.addEventListener( 'keystatuseschange', this.dispatchEvent.bind( this ) ); + session.closed.then( function() { if ( !this._removing ) this._resolveClosed(); }.bind ( this ) ); + + this._closed = new Promise( function( resolve ) { this._resolveClosed = resolve; }.bind( this ) ); + } + + MediaKeySession.prototype = Object.create( EventTarget.prototype ); + + Object.defineProperties( MediaKeySession.prototype, { + sessionId: { get: function() { return this._sessionId ? this._sessionId : this._session.sessionId; } }, + expiration: { get: function() { return this._session.expiration; } }, + closed: { get: function() { return this._closed; } }, + keyStatuses:{ get: function() { return this._session.keyStatuses; } } + }); + + // load() + // + // Use a surrogate 'persistent-release-message' session to obtain the release message + // + MediaKeySession.prototype.load = function load( sessionId ) + { + if ( this.sessionId ) return Promise.reject( new DOMException('InvalidAccessError') ); + + this._surrogate = this._mediaKeys.createSession( 'persistent-release-message' ); + this._surrogate.addEventListener( 'message', this.dispatchEvent.bind( this ) ); + + return this._surrogate.load( sessionId ).then( function( success ) { + if (!success) return false; + + this._sessionId = sessionId; + this._removing = true; + this._session.close(); + + return this._surrogate.remove().then( function() { return true; } ); + }.bind( this ) ); + }; + + // remove() + // + // On an existing session, use a surrogate 'persistent-release-message' session to obtain the release message + // + MediaKeySession.prototype.remove = function remove() + { + if ( this._sessionId !== undefined ) return Promise.reject( new DOMException('InvalidAccessError') ); + if ( this.sessionId === undefined ) return Promise.reject( new DOMException('InvalidAccessError') ); + + this._surrogate = this._mediaKeys.createSession( 'persistent-release-message' ); + this._surrogate.addEventListener( 'message', this.dispatchEvent.bind( this ) ); + this._removing = true; + this._sessionId = this._session.sessionId; + + var self = this; + + return Promise.all( [ self._session.close(), self._session.closed ] ).then( function() { + return self._surrogate.load( self._sessionId ); + }).then( function( success ) { + if ( !success ) { + throw new DOMException('InvalidAccessError'); + } + + return self._surrogate.remove(); + }).then( function() { return true; } ); + } + + // update() + // + // For a normal session, pass through, otherwise update the surrogate and close the proxy + MediaKeySession.prototype.update = function update( message ) + { + if ( !this._removing ) return this._session.update( message ); + + return this._surrogate.update( message ).then( function() { + this._sessionId = undefined; + this._resolveClosed(); + }.bind( this ) ); + }; + + // close() - pass through + // + MediaKeySession.prototype.close = function close() + { + if ( !this._removing ) return this._session.close(); + this._resolveClosed(); + return Promise.resolve(); + }; + + // generateRequest() - pass through + // + MediaKeySession.prototype.generateRequest = function generateRequest( initDataType, initData ) + { + if ( this.sessionId ) Promise.reject( new DOMException('InvalidAccessError') ); + return this._session.generateRequest( initDataType, initData ); + }; + + // Wrap PlayReady persistent-usage-record sessions in our Proxy + MediaKeys.prototype.createSession = function createSession( sessionType ) { + + var session = _mediaKeysCreateSession.call( this, sessionType ); + if ( this._keySystem !== 'com.microsoft.playready' || sessionType !== 'persistent-usage-record' ) + { + return session; + } + + return new MediaKeySession( this, session ); + + }; + + // + // Annotation polyfills - annotate not otherwise available data + // + + // Annotate MediaKeys with the keysystem + MediaKeySystemAccess.prototype.createMediaKeys = function createMediaKeys() + { + return _mediaKeySystemAccessCreateMediaKeys.call( this ).then( function( mediaKeys ) { + mediaKeys._keySystem = this.keySystem; + return mediaKeys; + }.bind( this ) ); + }; + + // + // Utilities + // + + // Allow us to modify the target of Events + Object.defineProperties( Event.prototype, { + target: { get: function() { return this._target || this.currentTarget; }, + set: function( newtarget ) { this._target = newtarget; } } + } ); + + // Make an EventTarget base class + function EventTarget(){ + this.listeners = {}; + }; + + EventTarget.prototype.listeners = null; + + EventTarget.prototype.addEventListener = function(type, callback){ + if(!(type in this.listeners)) { + this.listeners[type] = []; + } + this.listeners[type].push(callback); + }; + + EventTarget.prototype.removeEventListener = function(type, callback){ + if(!(type in this.listeners)) { + return; + } + var stack = this.listeners[type]; + for(var i = 0, l = stack.length; i < l; i++){ + if(stack[i] === callback){ + stack.splice(i, 1); + return this.removeEventListener(type, callback); + } + } + }; + + EventTarget.prototype.dispatchEvent = function(event){ + if(!(event.type in this.listeners)) { + return; + } + var stack = this.listeners[event.type]; + event.target = this; + for(var i = 0, l = stack.length; i < l; i++) { + stack[i].call(this, event); + } + }; + } +})(); diff --git a/testing/web-platform/tests/encrypted-media/polyfill/firefox-polyfill.js b/testing/web-platform/tests/encrypted-media/polyfill/firefox-polyfill.js new file mode 100644 index 0000000000..ce241af362 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/polyfill/firefox-polyfill.js @@ -0,0 +1,23 @@ +(function(){ + if(navigator.userAgent.toLowerCase().indexOf('firefox') > -1){ + + // Work around https://bugzilla.mozilla.org/show_bug.cgi?id=1282142 + // Firefox does not correctly reject the Clear Key session types it does not support + var _requestMediaKeySystemAccess = navigator.requestMediaKeySystemAccess.bind( navigator ); + + navigator.requestMediaKeySystemAccess = function( keysystem, configurations ) + { + if ( keysystem !== 'org.w3.clearkey' ) return _requestMediaKeySystemAccess( keysystem, configurations ); + + var supported_configurations = configurations.filter( function( c ) { + + return !c.sessionTypes || ( c.sessionTypes.length === 1 && c.sessionTypes[ 0 ] === 'temporary' ); + + } ); + + if ( supported_configurations.length === 0 ) return Promise.reject( new DOMException( 'None of the requested configurations were supported.' ) ); + + return _requestMediaKeySystemAccess( keysystem, supported_configurations ); + } + } +}()); \ No newline at end of file diff --git a/testing/web-platform/tests/encrypted-media/polyfill/make-polyfill-tests.py b/testing/web-platform/tests/encrypted-media/polyfill/make-polyfill-tests.py new file mode 100644 index 0000000000..532037e2a3 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/polyfill/make-polyfill-tests.py @@ -0,0 +1,32 @@ +#!/usr/bin/python + +from __future__ import print_function + +import os, re, os.path, glob + +head = re.compile( r"^(\s*)", re.MULTILINE ) +runtest = re.compile( r"runTest\(\s*(\S.*?)\s*\)", re.DOTALL ) + +scripts = ''' + + + + + + ''' + +def process_file( infile, outfile ) : + with open( outfile, "w" ) as output : + with open( infile, "r" ) as input : + output.write( runtest.sub( r"runTest( \1, 'polyfill: ' )", head.sub( scripts + r"\1", input.read() ) ) ) + +if __name__ == '__main__' : + if (not os.getcwd().endswith('polyfill')) : + print("Please run from polyfill directory") + exit( 1 ) + + for infile in glob.glob( "../*.html" ) : + process_file( infile, os.path.basename( infile ) ) + + for infile in glob.glob( "../resources/*.html" ) : + process_file( infile, os.path.join( "resources", os.path.basename( infile ) ) ) diff --git a/testing/web-platform/tests/encrypted-media/resources/clearkey-retrieve-destroy-persistent-license.html b/testing/web-platform/tests/encrypted-media/resources/clearkey-retrieve-destroy-persistent-license.html new file mode 100644 index 0000000000..a5a63dbf63 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/resources/clearkey-retrieve-destroy-persistent-license.html @@ -0,0 +1,105 @@ + + + + + Encrypted Media Extensions: persistent-license, retrieve and destroy, ClearKey + + + + + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/resources/clearkey-retrieve-persistent-license.html b/testing/web-platform/tests/encrypted-media/resources/clearkey-retrieve-persistent-license.html new file mode 100644 index 0000000000..4716b42549 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/resources/clearkey-retrieve-persistent-license.html @@ -0,0 +1,74 @@ + + + + + Encrypted Media Extensions: persistent-license, retrieve and playback, ClearKey + + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/resources/drm-retrieve-destroy-persistent-license.html b/testing/web-platform/tests/encrypted-media/resources/drm-retrieve-destroy-persistent-license.html new file mode 100644 index 0000000000..6564d8e606 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/resources/drm-retrieve-destroy-persistent-license.html @@ -0,0 +1,106 @@ + + + + + Encrypted Media Extensions: persistent-license, retrieve and destroy, drm + + + + + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/resources/drm-retrieve-persistent-license.html b/testing/web-platform/tests/encrypted-media/resources/drm-retrieve-persistent-license.html new file mode 100644 index 0000000000..bf554248f4 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/resources/drm-retrieve-persistent-license.html @@ -0,0 +1,77 @@ + + + + + Encrypted Media Extensions: persistent-license, retrieve and playback, DRM + + + + + + + + +
+ +
+ +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/resources/drm-retrieve-persistent-usage-record.html b/testing/web-platform/tests/encrypted-media/resources/drm-retrieve-persistent-usage-record.html new file mode 100644 index 0000000000..d1b3e0c694 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/resources/drm-retrieve-persistent-usage-record.html @@ -0,0 +1,70 @@ + + + + + Encrypted Media Extensions: Retrieve stored persistent-usage-record + + + + + + + + + + + +
+ + + + diff --git a/testing/web-platform/tests/encrypted-media/resources/retrieve-persistent-usage-record.html b/testing/web-platform/tests/encrypted-media/resources/retrieve-persistent-usage-record.html new file mode 100644 index 0000000000..c09134b546 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/resources/retrieve-persistent-usage-record.html @@ -0,0 +1,92 @@ + + + + + Encrypted Media Extensions: Retrieve stored persistent-usage-record + + + + + + + + + + + +
+ + + + \ No newline at end of file diff --git a/testing/web-platform/tests/encrypted-media/scripts/check-encryption-scheme.js b/testing/web-platform/tests/encrypted-media/scripts/check-encryption-scheme.js new file mode 100644 index 0000000000..ffab4a3491 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/scripts/check-encryption-scheme.js @@ -0,0 +1,46 @@ +function runTest(config, qualifier) +{ + function checkEncryptionScheme(encryptionScheme) + { + var simpleConfig = getSimpleConfiguration(); + assert_greater_than(simpleConfig[0].audioCapabilities.length, 0); + simpleConfig[0].audioCapabilities.forEach(function(capability) { + capability.encryptionScheme = encryptionScheme; + }); + + return navigator.requestMediaKeySystemAccess(config.keysystem, simpleConfig) + .then( + function(access) { + var actualConfiguration = access.getConfiguration(); + for (let i = 0; i < actualConfiguration.audioCapabilities.length; i++) { + const capability = actualConfiguration.audioCapabilities[i]; + + // If "encryptionScheme" is not supported, fail. + if (!('encryptionScheme' in capability)) { + return Promise.reject('Not implemented'); + } + + // If "encryptionScheme" is supported, it should be returned. + assert_equals(capability.encryptionScheme, encryptionScheme); + } + return Promise.resolve('Supported'); + }, + function error() { + // CDM does not support "encryptionScheme". Test should still pass. + return Promise.resolve('Not supported'); + }); + } + + promise_test( + () => checkEncryptionScheme('cenc'), + testnamePrefix(qualifier, config.keysystem) + ' support for "cenc" encryption scheme.'); + + promise_test( + () => checkEncryptionScheme('cbcs'), + testnamePrefix(qualifier, config.keysystem) + ' support for "cbcs" encryption scheme.'); + + promise_test( + () => checkEncryptionScheme('cbcs-1-9'), + testnamePrefix(qualifier, config.keysystem) + + ' support for "cbcs-1-9" encryption scheme.'); +} diff --git a/testing/web-platform/tests/encrypted-media/scripts/check-initdata-type.js b/testing/web-platform/tests/encrypted-media/scripts/check-initdata-type.js new file mode 100644 index 0000000000..5c7cb6e4b9 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/scripts/check-initdata-type.js @@ -0,0 +1,35 @@ + function runTest( config, qualifier ) + { + function checkInitDataType(initDataType) + { + return isInitDataTypeSupported(initDataType).then(function(result) { + // If |initDataType| is not supported, simply succeed. + if (!result) + return Promise.resolve('Not supported'); + + return navigator.requestMediaKeySystemAccess( config.keysystem, getSimpleConfigurationForInitDataType(initDataType)) + .then(function(access) { + return access.createMediaKeys(); + }).then(function(mediaKeys) { + var mediaKeySession = mediaKeys.createSession(); + var initData = getInitData(initDataType); + return mediaKeySession.generateRequest(initDataType, initData); + }); + }); + } + + promise_test(function() + { + return checkInitDataType('webm'); + }, testnamePrefix( qualifier, config.keysystem ) + ' support for "webm".'); + + promise_test(function() + { + return checkInitDataType('cenc'); + }, testnamePrefix( qualifier, config.keysystem ) + ' support for "cenc".'); + + promise_test(function() + { + return checkInitDataType('keyids'); + }, testnamePrefix( qualifier, config.keysystem ) + ' support for "keyids".'); +} diff --git a/testing/web-platform/tests/encrypted-media/scripts/check-status-for-hdcp.js b/testing/web-platform/tests/encrypted-media/scripts/check-status-for-hdcp.js new file mode 100644 index 0000000000..ac30819695 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/scripts/check-status-for-hdcp.js @@ -0,0 +1,26 @@ +function runTest(config, qualifier) +{ + function checkStatusForMinHdcpVersionPolicy(hdcpVersion) + { + return navigator.requestMediaKeySystemAccess(config.keysystem, getSimpleConfiguration()) + .then(function(access) { + return access.createMediaKeys(); + }) + .then(function(mediaKeys) { + // As HDCP policy depends on the hardware running this test, + // don't bother checking the result returned as it may or + // may not be supported. This simply verifies that + // getStatusForPolicy() exists and doesn't blow up. + return mediaKeys.getStatusForPolicy({minHdcpVersion: hdcpVersion}); + }); + } + + promise_test( + () => checkStatusForMinHdcpVersionPolicy(''), + testnamePrefix(qualifier, config.keysystem) + + ' support for empty HDCP version.'); + + promise_test( + () => checkStatusForMinHdcpVersionPolicy('1.0'), + testnamePrefix(qualifier, config.keysystem) + ' support for HDCP 1.0.'); +} diff --git a/testing/web-platform/tests/encrypted-media/scripts/clearkey-update-non-ascii-input.js b/testing/web-platform/tests/encrypted-media/scripts/clearkey-update-non-ascii-input.js new file mode 100644 index 0000000000..7a5c073bfa --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/scripts/clearkey-update-non-ascii-input.js @@ -0,0 +1,52 @@ +// This test is only applicable to clearkey +function runTest(config, qualifier) +{ + var testname = testnamePrefix(qualifier, config.keysystem) + ' test handling of non-ASCII responses for update()'; + + var configuration = getSimpleConfigurationForContent(config.content); + + if (config.initDataType) { + configuration.initDataTypes = [config.initDataType]; + } + + promise_test(function (test) { + var initDataType; + var initData; + var mediaKeySession; + var messageEventFired = false; + + var p = navigator.requestMediaKeySystemAccess(config.keysystem, [configuration]).then(function (access) { + initDataType = access.getConfiguration().initDataTypes[0]; + initData = getInitData(config.content, initDataType); + return access.createMediaKeys(); + }).then(function (mediaKeys) { + mediaKeySession = mediaKeys.createSession(); + var eventWatcher = new EventWatcher(test, mediaKeySession, ['message']); + var promise = eventWatcher.wait_for('message'); + mediaKeySession.generateRequest(initDataType, initData); + return promise; + }).then(function (messageEvent) { + // |jwkSet| contains a non-ASCII character \uDC00. + var jwkSet = '{"keys":[{' + + '"kty":"oct",' + + '"k":"MDEyMzQ1Njc4OTAxMjM0NQ",' + + '"kid":"MDEyMzQ1Njc4O\uDC00TAxMjM0NQ"' + + '}]}'; + messageEventFired = true; + return messageEvent.target.update(stringToUint8Array(jwkSet)); + }).catch(function (error) { + // Ensure we reached the update() call we are trying to test. + if (!messageEventFired) { + assert_unreached( + `Failed to reach the update() call. Error: '${error.name}' '${error.message}'`); + } + + // Propagate the error on through. + throw error; + }); + + return promise_rejects_js( + test, TypeError, p, + 'update() should fail because the processed message has non-ASCII character.'); + }, testname); +} diff --git a/testing/web-platform/tests/encrypted-media/scripts/events-session-closed-event.js b/testing/web-platform/tests/encrypted-media/scripts/events-session-closed-event.js new file mode 100644 index 0000000000..44f683eac8 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/scripts/events-session-closed-event.js @@ -0,0 +1,52 @@ +function runTest(config, qualifier) +{ + var testname = testnamePrefix(qualifier, config.keysystem) + ' test MediaKeySession closed event.'; + + var configuration = { + initDataTypes: [config.initDataType], + audioCapabilities: [{ + contentType: config.audioType + }], + videoCapabilities: [{ + contentType: config.videoType + }], + sessionTypes: ['temporary'] + }; + + promise_test(function (test) { + var initDataType; + var initData; + var mediaKeySession; + + return navigator.requestMediaKeySystemAccess(config.keysystem, [configuration]).then(function (access) { + initDataType = access.getConfiguration().initDataTypes[0]; + return access.createMediaKeys(); + }).then(function (mediaKeys) { + mediaKeySession = mediaKeys.createSession(); + if(config.initData) { + initData = config.initData; + } else { + initData = stringToUint8Array(atob(config.content.keys[0].initData)); + } + return mediaKeySession.generateRequest(initDataType, initData); + }).then(function() { + // close() should result in the closed promise being + // fulfilled. + return mediaKeySession.close(); + }).then(function (result) { + assert_equals(result, undefined); + // Wait for the session to be closed. + return mediaKeySession.closed; + }).then(function (result) { + assert_equals(result, undefined); + // Now that the session is closed, verify that the + // closed attribute immediately returns a fulfilled + // promise. + return mediaKeySession.closed; + }).then(function (result) { + assert_equals(result, undefined); + }).catch(function(error) { + assert_unreached('Error: ' + error.name); + }); + }, testname); +} \ No newline at end of file diff --git a/testing/web-platform/tests/encrypted-media/scripts/events.js b/testing/web-platform/tests/encrypted-media/scripts/events.js new file mode 100644 index 0000000000..85c86ae78d --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/scripts/events.js @@ -0,0 +1,59 @@ +function runTest(config,qualifier) { + + var testname = testnamePrefix(qualifier, config.keysystem) + ', basic events'; + + var configuration = getSimpleConfigurationForContent(config.content); + + if (config.initDataType && config.initData) { + configuration.initDataTypes = [config.initDataType]; + } + + async_test(function(test) + { + var initDataType; + var initData; + var mediaKeySession; + + function onFailure(error) { + forceTestFailureFromPromise(test, error); + } + + function processMessage(event) + { + assert_true(event instanceof window.MediaKeyMessageEvent); + assert_equals(event.target, mediaKeySession); + assert_equals(event.type, 'message'); + assert_in_array(event.messageType,['license-request', 'individualization-request']); + + config.messagehandler( event.messageType, event.message ).then(function(response) { + waitForEventAndRunStep('keystatuseschange', mediaKeySession, test.step_func(processKeyStatusesChange), test); + return mediaKeySession.update( response ); + }).catch(onFailure); + } + + function processKeyStatusesChange(event) + { + assert_true(event instanceof Event); + assert_equals(event.target, mediaKeySession); + assert_equals(event.type, 'keystatuseschange'); + test.done(); + } + + navigator.requestMediaKeySystemAccess(config.keysystem,[configuration]).then(function(access) { + initDataType = access.getConfiguration().initDataTypes[0]; + + if (config.initDataType && config.initData) { + initData = config.initData; + } else { + initData = getInitData(config.content, initDataType); + } + + return access.createMediaKeys(); + }).then(test.step_func(function(mediaKeys) { + mediaKeySession = mediaKeys.createSession(); + waitForEventAndRunStep('message', mediaKeySession, test.step_func(processMessage), test); + return mediaKeySession.generateRequest(initDataType, initData); + })).catch(onFailure); + }, testname ); + +} diff --git a/testing/web-platform/tests/encrypted-media/scripts/expiration.js b/testing/web-platform/tests/encrypted-media/scripts/expiration.js new file mode 100644 index 0000000000..96b7fbfeef --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/scripts/expiration.js @@ -0,0 +1,43 @@ +function runTest(config,qualifier) { + + var testname = testnamePrefix(qualifier, config.keysystem) + ', expiration'; + + var configuration = getSimpleConfigurationForContent(config.content); + if (config.initDataType && config.initData) { + configuration.initDataTypes = [config.initDataType]; + } + + async_test(function(test) { + + var _mediaKeys, + _mediaKeySession; + + function onFailure(error) { + forceTestFailureFromPromise(test, error); + } + + function onMessage(event) { + assert_equals(event.target, _mediaKeySession); + assert_true(event instanceof window.MediaKeyMessageEvent); + assert_equals(event.type, 'message'); + + assert_in_array(event.messageType, [ 'license-request', 'individualization-request' ] ); + + config.messagehandler(event.messageType, event.message, {expiration: config.expiration}).then(function(response) { + return event.target.update(response); + }).then(test.step_func(function() { + assert_approx_equals(event.target.expiration, config.expiration, 4000, "expiration attribute should equal provided expiration time"); + test.done(); + })).catch(onFailure); + } + + navigator.requestMediaKeySystemAccess(config.keysystem, [configuration]).then(function(access) { + return access.createMediaKeys(); + }).then(function(mediaKeys) { + _mediaKeys = mediaKeys; + _mediaKeySession = _mediaKeys.createSession( 'temporary' ); + waitForEventAndRunStep('message', _mediaKeySession, onMessage, test); + return _mediaKeySession.generateRequest(config.initDataType, config.initData); + }).catch(onFailure); + }, testname); +} diff --git a/testing/web-platform/tests/encrypted-media/scripts/generate-request-disallowed-input.js b/testing/web-platform/tests/encrypted-media/scripts/generate-request-disallowed-input.js new file mode 100644 index 0000000000..9fd42ee85f --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/scripts/generate-request-disallowed-input.js @@ -0,0 +1,72 @@ +function runTest(config,qualifier) { + var tests = [ ], initData, keyId; + function push_test(keysystem, initDataType, initData, testname) { + tests.push({ keysystem: keysystem, initDataType: initDataType, initData: initData, testname: testname }); + } + + initData = new Uint8Array(70000); + push_test(config.keysystem, 'webm', initData, testnamePrefix( qualifier, config.keysystem ) + ', temporary, webm, initData longer than 64Kb characters'); + + initData = new Uint8Array(70000); + push_test(config.keysystem, 'cenc', initData, testnamePrefix( qualifier, config.keysystem ) + ', temporary, cenc, initData longer than 64Kb characters'); + + initData = new Uint8Array(70000); + push_test(config.keysystem, 'keyids', initData, testnamePrefix( qualifier, config.keysystem ) + ', temporary, keyids, initData longer than 64Kb characters'); + + // Invalid 'pssh' box as the size specified is larger than what + // is provided. + initData = new Uint8Array([ + 0x00, 0x00, 0xff, 0xff, // size = huge + 0x70, 0x73, 0x73, 0x68, // 'pssh' + 0x00, // version = 0 + 0x00, 0x00, 0x00, // flags + 0x10, 0x77, 0xEF, 0xEC, 0xC0, 0xB2, 0x4D, 0x02, // Common SystemID + 0xAC, 0xE3, 0x3C, 0x1E, 0x52, 0xE2, 0xFB, 0x4B, + 0x00, 0x00, 0x00, 0x00 // datasize + ]); + push_test(config.keysystem, 'cenc', initData, testnamePrefix( qualifier, config.keysystem ) + ', temporary, cenc, invalid initdata (invalid pssh)'); + + // Invalid data as type = 'psss'. + initData = new Uint8Array([ + 0x00, 0x00, 0x00, 0x00, // size = 0 + 0x70, 0x73, 0x73, 0x73, // 'psss' + 0x00, // version = 0 + 0x00, 0x00, 0x00, // flags + 0x10, 0x77, 0xEF, 0xEC, 0xC0, 0xB2, 0x4D, 0x02, // Common SystemID + 0xAC, 0xE3, 0x3C, 0x1E, 0x52, 0xE2, 0xFB, 0x4B, + 0x00, 0x00, 0x00, 0x00 // datasize + ]); + push_test(config.keysystem, 'cenc', initData, testnamePrefix( qualifier, config.keysystem ) + ', temporary, cenc, invalid initdata (not pssh)'); + + // Valid key ID size must be at least 1 character for keyids. + keyId = new Uint8Array(0); + initData = stringToUint8Array(createKeyIDs(keyId)); + push_test(config.keysystem, 'keyids', initData, testnamePrefix( qualifier, config.keysystem ) + ', temporary, keyids, invalid initdata (too short key ID)'); + + // Valid key ID size must be less than 512 characters for keyids. + keyId = new Uint8Array(600); + initData = stringToUint8Array(createKeyIDs(keyId)); + push_test(config.keysystem, 'keyids', initData, testnamePrefix( qualifier, config.keysystem ) + ', temporary, keyids, invalid initdata (too long key ID)'); + + Promise.all( tests.map(function(testspec) { + return isInitDataTypeSupported(testspec.keysystem,testspec.initDataType); + })).then(function(results) { + tests.filter(function(testspec, i) { return results[i]; } ).forEach(function(testspec) { + promise_test(function(test) { + // Create a "temporary" session for |keysystem| and call generateRequest() + // with the provided initData. generateRequest() should fail with an + // TypeError. Returns a promise that is resolved + // if the error occurred and rejected otherwise. + var p = navigator.requestMediaKeySystemAccess(testspec.keysystem, getSimpleConfigurationForInitDataType(testspec.initDataType)).then(function(access) { + return access.createMediaKeys(); + }).then(function(mediaKeys) { + var mediaKeySession = mediaKeys.createSession("temporary"); + return mediaKeySession.generateRequest(testspec.initDataType, testspec.initData); + }); + + return promise_rejects_js(test, TypeError, p, + "generateRequest() should fail"); + }, testspec.testname); + }); + }); +} diff --git a/testing/web-platform/tests/encrypted-media/scripts/invalid-license.js b/testing/web-platform/tests/encrypted-media/scripts/invalid-license.js new file mode 100644 index 0000000000..89d43769e5 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/scripts/invalid-license.js @@ -0,0 +1,38 @@ +function runTest(config) +{ + promise_test(function (test) { + var initDataType; + var initData; + var keySystem = config.keysystem; + var invalidLicense = new Uint8Array([0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77]); + var messageEventFired = false; + + var p = navigator.requestMediaKeySystemAccess(keySystem, getSimpleConfiguration()).then(function (access) { + initDataType = access.getConfiguration().initDataTypes[0]; + initData = getInitData(initDataType); + return access.createMediaKeys(); + }).then(function (mediaKeys) { + var keySession = mediaKeys.createSession(); + var eventWatcher = new EventWatcher(test, keySession, ['message']); + var promise = eventWatcher.wait_for('message'); + keySession.generateRequest(initDataType, initData); + return promise; + }).then(function (messageEvent) { + messageEventFired = true; + return messageEvent.target.update(invalidLicense); + }).catch(function (error) { + // Ensure we reached the update() call we are trying to test. + if (!messageEventFired) { + assert_unreached( + `Failed to reach the update() call. Error: '${error.name}' '${error.message}'`); + } + + // Propagate the error on through. + throw error; + }); + + return promise_rejects_js( + test, TypeError, p, + 'update() should fail because of an invalid license.'); + }, 'Update with invalid Clear Key license'); +} diff --git a/testing/web-platform/tests/encrypted-media/scripts/keystatuses-multiple-sessions.js b/testing/web-platform/tests/encrypted-media/scripts/keystatuses-multiple-sessions.js new file mode 100644 index 0000000000..e9bf10e886 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/scripts/keystatuses-multiple-sessions.js @@ -0,0 +1,103 @@ +function runTest(config,qualifier) +{ + var testname = testnamePrefix(qualifier, config.keysystem) + ', temporary, keystatuses, multiple sessions'; + + var configuration = getSimpleConfigurationForContent(config.content); + + if (config.initDataType && config.initData) configuration.initDataTypes = [config.initDataType]; + + async_test(function(test) + { + var mediaKeySession1; + var mediaKeySession2; + + // Even though key ids are uint8, using printable values so that + // they can be verified easily. + var key1 = new Uint8Array(config.content.keys[0].kid), + key2 = new Uint8Array(config.content.keys[1].kid), + variant1 = config.content.keys[0].variantId, + variant2 = config.content.keys[1].variantId; + + function onFailure(error) { + forceTestFailureFromPromise(test,error); + } + + function processMessage1(event) + { + // This should only be called for session1. + assert_equals(event.target, mediaKeySession1); + + // No keys added yet. + verifyKeyStatuses(mediaKeySession1.keyStatuses, {expected: [], unexpected: [key1, key2]}); + + // Add key1 to session1. + config.messagehandler(event.messageType, event.message, {variantId:variant1}).then(function(response) { + return event.target.update(response); + }).catch(onFailure); + + } + + function processKeyStatusesChange1(event) + { + // This should only be called for session1. + assert_equals(event.target, mediaKeySession1); + + // Check that keyStatuses contains the expected key1 only. + verifyKeyStatuses(mediaKeySession1.keyStatuses, {expected: [key1], unexpected: [key2]}); + + // Now trigger a message event on session2. + mediaKeySession2.generateRequest(config.initDataType, config.initData[1]).catch(onFailure); + } + + function processMessage2(event) + { + // This should only be called for session2. + assert_equals(event.target, mediaKeySession2); + + // session2 has no keys added yet. + verifyKeyStatuses(mediaKeySession2.keyStatuses, {expected: [], unexpected: [key1, key2]}); + + // session1 should still have 1 key. + verifyKeyStatuses(mediaKeySession1.keyStatuses, {expected: [key1], unexpected: [key2]}); + + // Add key2 to session2. + config.messagehandler(event.messageType, event.message, {variantId:variant2}).then(function(response) { + return event.target.update(response); + }).catch(onFailure); + } + + function processKeyStatusesChange2(event) + { + // This should only be called for session2. + assert_equals(event.target, mediaKeySession2); + + // Check that keyStatuses contains the expected key2 only. + verifyKeyStatuses(mediaKeySession2.keyStatuses, {expected: [key2], unexpected: [key1]}); + + // session1 should still have 1 key. + verifyKeyStatuses(mediaKeySession1.keyStatuses, {expected: [key1], unexpected: [key2]}); + + test.done(); + } + + navigator.requestMediaKeySystemAccess(config.keysystem, [configuration]).then(function(access) { + return access.createMediaKeys(); + }).then(function(mediaKeys) { + mediaKeySession1 = mediaKeys.createSession(); + mediaKeySession2 = mediaKeys.createSession(); + + // There should be no keys defined on either session. + verifyKeyStatuses(mediaKeySession1.keyStatuses, {expected: [], unexpected: [key1, key2]}); + verifyKeyStatuses(mediaKeySession2.keyStatuses, {expected: [], unexpected: [key1, key2]}); + + // Bind all the event handlers now. + waitForEventAndRunStep('message', mediaKeySession1, processMessage1, test); + waitForEventAndRunStep('message', mediaKeySession2, processMessage2, test); + waitForEventAndRunStep('keystatuseschange', mediaKeySession1, processKeyStatusesChange1, test); + waitForEventAndRunStep('keystatuseschange', mediaKeySession2, processKeyStatusesChange2, test); + + // Generate a request on session1. + return mediaKeySession1.generateRequest(config.initDataType, config.initData[0]); + }).catch(onFailure); + }, testname ); +} diff --git a/testing/web-platform/tests/encrypted-media/scripts/keystatuses.js b/testing/web-platform/tests/encrypted-media/scripts/keystatuses.js new file mode 100644 index 0000000000..8d33dd4210 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/scripts/keystatuses.js @@ -0,0 +1,165 @@ +function runTest(config,qualifier) +{ + var testname = testnamePrefix(qualifier, config.keysystem) + ', temporary, keystatuses'; + + var configuration = getSimpleConfigurationForContent(config.content); + + if (config.initDataType && config.initData) { + configuration.initDataTypes = [config.initDataType]; + } + + async_test(function(test) + { + var mediaKeySession; + var initDataType; + var initData; + var closed = false; + + // Even though key ids are uint8, using printable values so that + // they can be verified easily. + var key1 = new Uint8Array(config.content.keys[0].kid), + key2 = new Uint8Array(config.content.keys[1].kid), + key1String = arrayBufferAsString(key1), + key2String = arrayBufferAsString(key2); + + function onFailure(error) { + forceTestFailureFromPromise(test, error); + } + + function processMessage(event) + { + // No keys added yet. + assert_equals(mediaKeySession.keyStatuses.size, 0); + + waitForEventAndRunStep('keystatuseschange', mediaKeySession, processKeyStatusesChange, test); + + // Add keys to session + config.messagehandler(event.messageType, event.message).then(function(response) { + return event.target.update(response); + }).catch(onFailure); + } + + function checkKeyStatusFor2Keys() + { + // Two keys added, so both should show up in |keyStatuses|. + assert_equals(mediaKeySession.keyStatuses.size, 2); + + // Check |keyStatuses| for 2 entries. + var result = []; + for (let item of mediaKeySession.keyStatuses) { + result.push({ key: arrayBufferAsString(item[0]), value: item[1] }); + } + function lexicographical( a, b ) { return a < b ? -1 : a === b ? 0 : +1; } + function lexicographicalkey( a, b ) { return lexicographical( a.key, b.key ); } + var expected1 = [{ key: key1String, value: 'usable'}, { key: key2String, value: 'usable'}].sort( lexicographicalkey ); + var expected2 = [{ key: key1String, value: 'status-pending'}, { key: key2String, value: 'status-pending'}].sort( lexicographicalkey ); + assert_in_array( JSON.stringify(result), + [ JSON.stringify(expected1),JSON.stringify(expected2) ], + "keystatuses should have the two expected keys with keystatus 'usable' or 'status-pending'"); + + // |keyStatuses| must contain both keys. + result = []; + for (var key of mediaKeySession.keyStatuses.keys()) { + result.push(arrayBufferAsString(key)); + } + assert_array_equals(result, + [key1String, key2String].sort( lexicographical ), + "keyStatuses.keys() should return an iterable over the two expected keys"); + + // Both values in |mediaKeySession| should be 'usable' or 'status-pending'. + result = []; + for (var value of mediaKeySession.keyStatuses.values()) { + result.push(value); + } + + assert_equals( result.length, 2, "keyStatuses.values() should have two elements" ); + assert_equals( result[0], result[1], "the values in keyStatuses.values() should be equal" ); + assert_in_array( result[0], [ 'usable', 'status-pending' ] ); + + // Check |keyStatuses.entries()|. + result = []; + for (var entry of mediaKeySession.keyStatuses.entries()) { + result.push({ key: arrayBufferAsString(entry[0]), value: entry[1] }); + } + assert_in_array(JSON.stringify(result), + [ JSON.stringify(expected1), JSON.stringify(expected2) ], + "keyStatuses.entries() should return an iterable over the two expected keys, with keystatus 'usable' or 'status-pending'"); + + // forEach() should return both entries. + result = []; + mediaKeySession.keyStatuses.forEach(function(status, keyId) { + result.push({ key: arrayBufferAsString(keyId), value: status }); + }); + assert_in_array(JSON.stringify(result), + [ JSON.stringify(expected1), JSON.stringify(expected2) ], + "keyStatuses.forEach() should iterate over the two expected keys, with keystatus 'usable' or 'status-pending'"); + + // has() and get() should return the expected values. + assert_true(mediaKeySession.keyStatuses.has(key1), "keyStatuses should have key1"); + assert_true(mediaKeySession.keyStatuses.has(key2), "keyStatuses should have key2"); + assert_in_array(mediaKeySession.keyStatuses.get(key1), [ 'usable', 'status-pending' ], "key1 should have status 'usable' or 'status-pending'"); + assert_in_array(mediaKeySession.keyStatuses.get(key2), [ 'usable', 'status-pending' ], "key2 should have status 'usable' or 'status-pending'"); + + // Try some invalid keyIds. + var invalid1 = key1.subarray(0, key1.length - 1); + assert_false(mediaKeySession.keyStatuses.has(invalid1), "keystatuses should not have invalid key (1)"); + assert_equals(mediaKeySession.keyStatuses.get(invalid1), undefined, "keystatus value for invalid key should be undefined (1)"); + + var invalid2 = key1.subarray(1); + assert_false(mediaKeySession.keyStatuses.has(invalid2), "keystatuses should not have invalid key (2)"); + assert_equals(mediaKeySession.keyStatuses.get(invalid2), undefined, "keystatus value for invalid key should be undefined (2)"); + + var invalid3 = new Uint8Array(key1); + invalid3[0] += 1; + assert_false(mediaKeySession.keyStatuses.has(invalid3), "keystatuses should not have invalid key (3)"); + assert_equals(mediaKeySession.keyStatuses.get(invalid3), undefined, "keystatus value for invalid key should be undefined (3)"); + + var invalid4 = new Uint8Array(key1); + invalid4[invalid4.length - 1] -= 1; + assert_false(mediaKeySession.keyStatuses.has(invalid4), "keystatuses should not have invalid key (4)"); + assert_equals(mediaKeySession.keyStatuses.get(invalid4), undefined, "keystatus value for invalid key should be undefined (4)"); + + var invalid5 = new Uint8Array(key1.length + 1); + invalid5.set(key1, 1); // First element will be 0. + assert_false(mediaKeySession.keyStatuses.has(invalid5), "keystatuses should not have invalid key (5)"); + assert_equals(mediaKeySession.keyStatuses.get(invalid5), undefined, "keystatus value for invalid key should be undefined (5)"); + + var invalid6 = new Uint8Array(key1.length + 1); + invalid6.set(key1, 0); // Last element will be 0. + assert_false(mediaKeySession.keyStatuses.has(invalid6), "keystatuses should not have invalid key (6)"); + assert_equals(mediaKeySession.keyStatuses.get(invalid6), undefined, "keystatus value for invalid key should be undefined (6)"); + } + + function processKeyStatusesChange(event) + { + if (!closed) + { + // The first keystatuseschange (caused by update()) + // should include both keys. + checkKeyStatusFor2Keys(); + + mediaKeySession.close().catch(onFailure); + closed = true; + } + else + { + // The second keystatuseschange (caused by close()) + // should not have any keys. + assert_equals(mediaKeySession.keyStatuses.size, 0); + test.done(); + } + } + + navigator.requestMediaKeySystemAccess(config.keysystem, [configuration]).then(function(access) { + return access.createMediaKeys(); + }).then(test.step_func(function(mediaKeys) { + mediaKeySession = mediaKeys.createSession(); + + // There should be no keys defined yet. + //verifyKeyStatuses(mediaKeySession.keyStatuses, { expected: [], unexpected: [key1, key2] }); + + waitForEventAndRunStep('message', mediaKeySession, processMessage, test); + return mediaKeySession.generateRequest(config.initDataType, config.initData); + })).catch(onFailure); + }, testname ); +} diff --git a/testing/web-platform/tests/encrypted-media/scripts/not-callable-after-createsession.js b/testing/web-platform/tests/encrypted-media/scripts/not-callable-after-createsession.js new file mode 100644 index 0000000000..2642c71e0e --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/scripts/not-callable-after-createsession.js @@ -0,0 +1,50 @@ + function runTest(config,qualifier) { + // After creation, the MediaKeySession object is not + // callable, and we should get a InvalidStateError. + + promise_test(function() + { + return navigator.requestMediaKeySystemAccess(config.keysystem, getSimpleConfiguration()).then(function(access) { + return access.createMediaKeys(); + }).then(function(mediaKeys) { + var mediaKeySession = mediaKeys.createSession(); + + var arbitraryResponse = new Uint8Array([0x00, 0x11]); + return mediaKeySession.update(arbitraryResponse).then(function(result) { + assert_unreached('update() succeeded unexpectedly.'); + }).catch(function(error) { + assert_equals(error.name, 'InvalidStateError'); + }); + }); + }, testnamePrefix( qualifier, config.keysystem ) + ', temporary, update() immediately after createSession()'); + + promise_test(function() + { + return navigator.requestMediaKeySystemAccess(config.keysystem, getSimpleConfiguration()).then(function(access) { + return access.createMediaKeys(); + }).then(function(mediaKeys) { + var mediaKeySession = mediaKeys.createSession(); + + return mediaKeySession.close().then(function(result) { + assert_unreached('close() succeeded unexpectedly.'); + }).catch(function(error) { + assert_equals(error.name, 'InvalidStateError'); + }); + }); + }, testnamePrefix( qualifier, config.keysystem ) + ', temporary, close() immediately after createSession()'); + + promise_test(function() + { + return navigator.requestMediaKeySystemAccess(config.keysystem, getSimpleConfiguration()).then(function(access) { + return access.createMediaKeys(); + }).then(function(mediaKeys) { + var mediaKeySession = mediaKeys.createSession(); + + return mediaKeySession.remove().then(function(result) { + assert_unreached('remove() succeeded unexpectedly.'); + }).catch(function(error) { + assert_equals(error.name, 'InvalidStateError'); + }); + }); + }, testnamePrefix( qualifier, config.keysystem ) + ', temporary, remove() immediately after createSession()'); +} diff --git a/testing/web-platform/tests/encrypted-media/scripts/onencrypted.js b/testing/web-platform/tests/encrypted-media/scripts/onencrypted.js new file mode 100644 index 0000000000..acf0ffacc0 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/scripts/onencrypted.js @@ -0,0 +1,48 @@ +function runTest(config) { + var expectedInitData = []; + expectedInitData.push(stringToUint8Array(atob(config.keys[0].initData))); + expectedInitData.push(stringToUint8Array(atob(config.keys[1].initData))); + + // Will get 2 identical events, one for audio, one for video. + var expectedEvents = 2; + var currentData; + + async_test(function (test) { + var video = config.video, + mediaSource, + onEncrypted = function (event) { + currentData = new Uint8Array(event.initData); + assert_equals(event.target, config.video); + assert_true(event instanceof window.MediaEncryptedEvent); + assert_equals(event.type, 'encrypted'); + assert_equals(event.initDataType, 'cenc'); + // At this point we do not know if the event is related to audio or video. So check for both expected init data + assert_true(checkInitData(currentData, expectedInitData[0]) || checkInitData(currentData, expectedInitData[1])); + + if (--expectedEvents === 0) { + test.done(); + } + }; + + waitForEventAndRunStep('encrypted', video, onEncrypted, test); + testmediasource(config).then(function (source) { + mediaSource = source; + config.video.src = URL.createObjectURL(mediaSource); + return source.done; + }).then(function(){ + video.play(); + }); + }, 'encrypted fired on encrypted media file.'); +} + +function checkInitData(data, expectedData) { + if (data.length !== expectedData.length) { + return false; + } + for (var i = 0; i < data.length; i++) { + if (data[i] !== expectedData[i]) { + return false; + } + } + return true; +} diff --git a/testing/web-platform/tests/encrypted-media/scripts/playback-destroy-persistent-license.js b/testing/web-platform/tests/encrypted-media/scripts/playback-destroy-persistent-license.js new file mode 100644 index 0000000000..8a6cacedb4 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/scripts/playback-destroy-persistent-license.js @@ -0,0 +1,95 @@ +function runTest(config,qualifier) { + + var testname = testnamePrefix( qualifier, config.keysystem ) + + ', persistent-license, ' + + /video\/([^;]*)/.exec( config.videoType )[ 1 ] + + ', playback, destroy and acknowledge'; + + var configuration = { initDataTypes: [ config.initDataType ], + audioCapabilities: [ { contentType: config.audioType } ], + videoCapabilities: [ { contentType: config.videoType } ], + sessionTypes: [ 'persistent-license' ] }; + + async_test( function(test) { + + var _video = config.video, + _mediaKeys, + _mediaKeySession, + _mediaSource, + _sessionId, + _startedReleaseSequence = false; + + function onFailure(error) { + forceTestFailureFromPromise(test, error); + } + + function onMessage(event) { + assert_equals(event.target, _mediaKeySession); + assert_true(event instanceof window.MediaKeyMessageEvent); + assert_equals(event.type, 'message'); + + config.messagehandler(event.messageType, event.message).then(function(response) { + return _mediaKeySession.update(response); + }).catch(onFailure); + } + + function onEncrypted(event) { + assert_equals(event.target, _video); + assert_true(event instanceof window.MediaEncryptedEvent); + assert_equals(event.type, 'encrypted'); + + waitForEventAndRunStep('message', _mediaKeySession, onMessage, test); + _mediaKeySession.generateRequest( config.initData ? config.initDataType : event.initDataType, + config.initData || event.initData ).then( test.step_func(function() { + assert_not_equals( _mediaKeySession.sessionId, undefined, "SessionId should be defined" ); + _sessionId = _mediaKeySession.sessionId; + })).catch(onFailure); + } + + function onTimeupdate(event) { + if (_video.currentTime > ( config.duration || 1 ) && !_startedReleaseSequence) { + _video.removeEventListener('timeupdate', onTimeupdate); + _video.pause(); + _video.removeAttribute('src'); + _video.load(); + + _startedReleaseSequence = true; + _mediaKeySession.closed.then(onClosed); + _mediaKeySession.remove().catch(onFailure); + } + } + + function onPlaying(event) { + // Not using waitForEventAndRunStep() to avoid too many + // EVENT(onTimeUpdate) logs. + _video.addEventListener('timeupdate', onTimeupdate, true); + } + + function onClosed() { + // Try and reload and check this fails + var mediaKeySession = _mediaKeys.createSession( 'persistent-license' ); + mediaKeySession.load(_sessionId).then( test.step_func(function(success) { + assert_false( success, "Load of removed session shouold fail" ); + test.done(); + })).catch(onFailure); + } + + navigator.requestMediaKeySystemAccess(config.keysystem, [configuration]).then(function(access) { + return access.createMediaKeys(); + }).then(function(mediaKeys) { + _mediaKeys = mediaKeys; + return _video.setMediaKeys(_mediaKeys); + }).then(function() { + _mediaKeySession = _mediaKeys.createSession('persistent-license'); + waitForEventAndRunStep('encrypted', _video, onEncrypted, test); + waitForEventAndRunStep('playing', _video, onPlaying, test); + return testmediasource(config); + }).then(function(source) { + _mediaSource = source; + _video.src = URL.createObjectURL(_mediaSource); + return source.done; + }).then(function(){ + _video.play(); + }).catch(onFailure); + }, testname); +} diff --git a/testing/web-platform/tests/encrypted-media/scripts/playback-persistent-license-events.js b/testing/web-platform/tests/encrypted-media/scripts/playback-persistent-license-events.js new file mode 100644 index 0000000000..2d99f679f4 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/scripts/playback-persistent-license-events.js @@ -0,0 +1,158 @@ +function runTest(config,qualifier) { + + var testname = testnamePrefix(qualifier, config.keysystem) + + ', persistent-license, ' + + /video\/([^;]*)/.exec(config.videoType)[1] + + ', playback, check events'; + + var configuration = { initDataTypes: [ config.initDataType ], + audioCapabilities: [ { contentType: config.audioType } ], + videoCapabilities: [ { contentType: config.videoType } ], + sessionTypes: [ 'persistent-license' ] }; + + + async_test(function(test) { + var _video = config.video, + _mediaKeys, + _mediaKeySession, + _mediaSource, + _receivedTimeupdateEvent = false, + _startedReleaseSequence = false, + _events = [ ]; + + function recordEventFunc(eventType) { + return function() { _events.push(eventType); }; + } + + function recordEventFuncAndCheckExpirationForNaN(eventType) { + return function() { + _events.push(eventType); + assert_equals(_mediaKeySession.expiration, NaN); + }; + } + + function onFailure(error) { + forceTestFailureFromPromise(test, error); + } + + function onMessage(event) { + assert_equals( event.target, _mediaKeySession ); + assert_true( event instanceof window.MediaKeyMessageEvent ); + assert_equals( event.type, 'message'); + + if (!_startedReleaseSequence) { + assert_in_array(event.messageType, ['license-request', 'individualization-request']); + } else { + assert_equals(event.messageType, 'license-release'); + } + + if (event.messageType !== 'individualization-request') { + _events.push(event.messageType); + } + + config.messagehandler(event.messageType, event.message ).then(function(response) { + _events.push(event.messageType + '-response'); + return _mediaKeySession.update(response); + }).then(test.step_func(function() { + _events.push(event.messageType + '-response-resolved'); + if (event.messageType === 'license-release') { + test.step_timeout(function() { + checkEventSequence(_events, [ + 'generaterequest', + [ // potentially repeating + 'license-request', + 'license-request-response', + 'license-request-response-resolved' + ], + 'keystatuseschange-usablekey', + 'playing', + 'remove-resolved', + 'keystatuseschange-allkeysreleased', + 'license-release', + 'license-release-response', + 'closed-attribute-resolved', + 'license-release-response-resolved', + 'keystatuseschange-empty' + ]); + test.done(); + }, 100); + } + })).catch(onFailure); + } + + function onKeyStatusesChange(event) { + assert_equals(event.target, _mediaKeySession); + assert_true(event instanceof window.Event); + assert_equals(event.type, 'keystatuseschange'); + var hasKeys = false, + usableKey = false; // true if any key usable. + _mediaKeySession.keyStatuses.forEach(function(value, keyid) { + assert_in_array(value, ['usable', 'released']); + hasKeys = true; + usableKey = usableKey || (value === 'usable'); + }); + + if (!hasKeys) { + _events.push('keystatuseschange-empty'); + } else if (usableKey) { + _events.push('keystatuseschange-usablekey'); + } else { + _events.push('keystatuseschange-allkeysreleased'); + } + } + + function onEncrypted(event) { + assert_equals(event.target, _video); + assert_true(event instanceof window.MediaEncryptedEvent); + assert_equals(event.type, 'encrypted'); + + _mediaKeySession.generateRequest( config.initData ? config.initDataType : event.initDataType, + config.initData || event.initData ).then(recordEventFunc('generaterequest') + ).catch(onFailure); + } + + function onTimeupdate(event) { + if ( _video.currentTime > ( config.duration || 1 ) && !_receivedTimeupdateEvent ) { + _receivedTimeupdateEvent = true; + _video.pause(); + _video.removeAttribute('src'); + _video.load(); + + _startedReleaseSequence = true; + _mediaKeySession.remove() + .then(recordEventFuncAndCheckExpirationForNaN('remove-resolved')) + .catch(onFailure); + } + } + + function onPlaying(event) { + _events.push( 'playing' ); + } + + navigator.requestMediaKeySystemAccess(config.keysystem, [ configuration ]).then(function(access) { + return access.createMediaKeys(); + }).then(function(mediaKeys) { + _mediaKeys = mediaKeys; + return _video.setMediaKeys(_mediaKeys); + }).then(function() { + waitForEventAndRunStep('encrypted', _video, onEncrypted, test); + waitForEventAndRunStep('playing', _video, onPlaying, test); + // Not using waitForEventAndRunStep() to avoid too many + // EVENT(onTimeUpdate) logs. + _video.addEventListener('timeupdate', onTimeupdate, true); + _mediaKeySession = _mediaKeys.createSession( 'persistent-license' ); + waitForEventAndRunStep('keystatuseschange', _mediaKeySession, onKeyStatusesChange, test); + waitForEventAndRunStep('message', _mediaKeySession, onMessage, test); + _mediaKeySession.closed + .then(recordEventFuncAndCheckExpirationForNaN('closed-attribute-resolved')) + .catch(onFailure); + return testmediasource(config); + }).then(function(source) { + _mediaSource = source; + _video.src = URL.createObjectURL(_mediaSource); + return source.done; + }).then(function(){ + _video.play(); + }).catch(onFailure); + }, testname); +} diff --git a/testing/web-platform/tests/encrypted-media/scripts/playback-persistent-license.js b/testing/web-platform/tests/encrypted-media/scripts/playback-persistent-license.js new file mode 100644 index 0000000000..c7e56e3aea --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/scripts/playback-persistent-license.js @@ -0,0 +1,77 @@ +function runTest(config,qualifier) { + + var testname = testnamePrefix(qualifier, config.keysystem) + + ', persistent-license, ' + + /video\/([^;]*)/.exec(config.videoType)[1] + + 'playback'; + + var configuration = { initDataTypes: [ config.initDataType ], + audioCapabilities: [ { contentType: config.audioType } ], + videoCapabilities: [ { contentType: config.videoType } ], + sessionTypes: [ 'persistent-license' ] }; + + + async_test(function(test) { + var _video = config.video, + _mediaKeys, + _mediaKeySession, + _mediaSource; + + function onFailure(error) { + forceTestFailureFromPromise(test, error); + } + + function onMessage(event) { + assert_equals( event.target, _mediaKeySession ); + assert_true( event instanceof window.MediaKeyMessageEvent ); + assert_equals( event.type, 'message'); + + assert_in_array( event.messageType, [ 'license-request', 'individualization-request' ] ); + + config.messagehandler(event.messageType, event.message).then( function( response ) { + return _mediaKeySession.update(response) + }).catch(onFailure); + } + + function onEncrypted(event) { + assert_equals(event.target, _video); + assert_true(event instanceof window.MediaEncryptedEvent); + assert_equals(event.type, 'encrypted'); + + waitForEventAndRunStep('message', _mediaKeySession, onMessage, test); + _mediaKeySession.generateRequest( config.initData ? config.initDataType : event.initDataType, + config.initData || event.initData ).catch(onFailure); + } + + function onTimeupdate(event) { + if (_video.currentTime > (config.duration || 1)) { + _video.pause(); + test.done(); + } + } + + function onPlaying(event) { + // Not using waitForEventAndRunStep() to avoid too many + // EVENT(onTimeUpdate) logs. + _video.addEventListener('timeupdate', onTimeupdate, true); + } + + navigator.requestMediaKeySystemAccess(config.keysystem, [ configuration ]).then(function(access) { + return access.createMediaKeys(); + }).then(function(mediaKeys) { + _mediaKeys = mediaKeys; + return _video.setMediaKeys(_mediaKeys); + }).then(function() { + _mediaKeySession = _mediaKeys.createSession( 'persistent-license' ); + waitForEventAndRunStep('encrypted', _video, onEncrypted, test); + waitForEventAndRunStep('playing', _video, onPlaying, test); + return testmediasource(config); + }).then(function(source) { + _mediaSource = source; + _video.src = URL.createObjectURL(_mediaSource); + return source.done; + }).then(function(){ + _video.play(); + }).catch(onFailure); + }, testname); +} diff --git a/testing/web-platform/tests/encrypted-media/scripts/playback-persistent-usage-record-events.js b/testing/web-platform/tests/encrypted-media/scripts/playback-persistent-usage-record-events.js new file mode 100644 index 0000000000..e8e1e54790 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/scripts/playback-persistent-usage-record-events.js @@ -0,0 +1,109 @@ +function runTest(config,qualifier) { + + var testname = testnamePrefix(qualifier, config.keysystem) + + ', persistent-usage-record, ' + + /video\/([^;]*)/.exec(config.videoType)[1] + + ', playback, check events'; + + var configuration = { initDataTypes: [config.initDataType ], + audioCapabilities: [{contentType: config.audioType}], + videoCapabilities: [{contentType: config.videoType}], + sessionTypes: ['persistent-usage-record']}; + + + async_test(function(test) { + var _video = config.video, + _mediaKeys, + _mediaKeySession, + _sessionId, + _timeupdateEvent = false, + _events = [ ]; + + function recordEventFunc(eventType) { + return function() { _events.push(eventType); }; + } + + function onFailure(error) { + forceTestFailureFromPromise(test, error); + } + + function onMessage(event) { + assert_equals(event.target, _mediaKeySession); + assert_true(event instanceof window.MediaKeyMessageEvent); + assert_equals(event.type, 'message'); + + if (event.messageType !== 'individualization-request') { + _events.push(event.messageType); + } + + config.messagehandler(event.messageType, event.message).then(function(response) { + _events.push(event.messageType + '-response'); + return _mediaKeySession.update(response); + }).then(test.step_func(function() { + _events.push('update-resolved'); + if (event.messageType === 'license-release') { + checkEventSequence( _events, + ['encrypted','generaterequest-done', + ['license-request', 'license-request-response', 'update-resolved'], // potentially repeating + 'keystatuseschange', + 'playing', + 'remove-resolved', + 'keystatuseschange', + 'license-release', + 'license-release-response', + 'closed-attribute-resolved', + 'update-resolved' ]); + test.done(); + } + + if ( event.messageType === 'license-request' ) { + _video.setMediaKeys(_mediaKeys); + } + })).catch(onFailure); + } + + function onEncrypted(event) { + assert_equals(event.target, _video); + assert_true(event instanceof window.MediaEncryptedEvent); + _events.push(event.type); + _mediaKeySession.generateRequest( config.initDataType || event.initDataType, + config.initData || event.initData ).then( function() { + _events.push( 'generaterequest-done' ); + _sessionId = _mediaKeySession.sessionId; + }).catch(onFailure); + } + + function onTimeupdate(event) { + if (_video.currentTime > (config.duration || 1) && !_timeupdateEvent) { + _timeupdateEvent = true; + _video.pause(); + _mediaKeySession.remove().then(recordEventFunc('remove-resolved')).catch(onFailure); + } + } + + navigator.requestMediaKeySystemAccess(config.keysystem, [configuration]).then(function(access) { + return access.createMediaKeys(); + }).then(function(mediaKeys) { + _mediaKeys = mediaKeys; + waitForEventAndRunStep('encrypted', _video, onEncrypted, test); + waitForEventAndRunStep('playing', _video, recordEventFunc('playing'), test); + + // Not using waitForEventAndRunStep() to avoid too many + // EVENT(onTimeUpdate) logs. + _video.addEventListener('timeupdate', onTimeupdate, true); + + _mediaKeySession = _mediaKeys.createSession( 'persistent-usage-record' ); + waitForEventAndRunStep('message', _mediaKeySession, onMessage, test); + waitForEventAndRunStep('keystatuseschange', _mediaKeySession, recordEventFunc('keystatuseschange'), test); + _mediaKeySession.closed.then(recordEventFunc('closed-attribute-resolved')); + return config.servercertificate ? _mediaKeys.setServerCertificate(config.servercertificate) : true; + }).then(function( success ) { + return testmediasource(config); + }).then(function(source) { + _video.src = URL.createObjectURL(source); + return source.done; + }).then(function(){ + _video.play(); + }).catch(onFailure); + }, testname); +} diff --git a/testing/web-platform/tests/encrypted-media/scripts/playback-persistent-usage-record.js b/testing/web-platform/tests/encrypted-media/scripts/playback-persistent-usage-record.js new file mode 100644 index 0000000000..1772b4bd5f --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/scripts/playback-persistent-usage-record.js @@ -0,0 +1,104 @@ +function runTest(config,qualifier) { + + var testname = testnamePrefix(qualifier, config.keysystem) + + ', persistent-usage-record, ' + + /video\/([^;]*)/.exec(config.videoType)[1] + + 'playback'; + + var configuration = { initDataTypes: [ config.initDataType ], + audioCapabilities: [ { contentType: config.audioType } ], + videoCapabilities: [ { contentType: config.videoType } ], + sessionTypes: [ 'persistent-usage-record' ] }; + + + async_test(function(test) { + var _video = config.video, + _mediaKeys, + _mediaKeySession, + _mediaSource, + _releaseSequence = false; + + function onFailure(error) { + forceTestFailureFromPromise(test, error); + } + + function onMessage(event) { + assert_equals(event.target, _mediaKeySession); + // event instance verification failing on CastTV + // assert_true( event instanceof window.MediaKeyMessageEvent ); + assert_equals(event.type, 'message'); + + if (!_releaseSequence) + { + assert_in_array(event.messageType, ['license-request', 'individualization-request']); + } + else + { + assert_equals(event.messageType, 'license-release'); + } + + config.messagehandler(event.messageType, event.message).then(function(response) { + return _mediaKeySession.update(response); + }).then(function() { + if(event.messageType === 'license-request') { + return _video.setMediaKeys(_mediaKeys); + } else if(event.messageType === 'license-release') { + test.done(); + } + }).catch(onFailure); + } + + function onEncrypted(event) { + assert_equals(event.target, _video); + assert_true(event instanceof window.MediaEncryptedEvent); + assert_equals(event.type, 'encrypted'); + + waitForEventAndRunStep('message', _mediaKeySession, onMessage, test); + _mediaKeySession.generateRequest( config.initData ? config.initDataType : event.initDataType, + config.initData || event.initData ) + .catch(onFailure); + } + + function onClosed(event) { + _video.src = ""; + _video.setMediaKeys( null ); + } + + function onTimeupdate(event) { + if (_video.currentTime > ( config.duration || 1) && !_releaseSequence) { + _video.removeEventListener('timeupdate', onTimeupdate ); + _video.pause(); + _releaseSequence = true; + + _mediaKeySession.closed.then(test.step_func(onClosed)); + _mediaKeySession.remove().catch(onFailure); + + _video.removeEventListener('timeupdate', onTimeupdate); + } + } + + function onPlaying(event) { + // Not using waitForEventAndRunStep() to avoid too many + // EVENT(onTimeUpdate) logs. + _video.addEventListener('timeupdate', onTimeupdate, true); + } + + navigator.requestMediaKeySystemAccess(config.keysystem, [ configuration ]).then(function(access) { + return access.createMediaKeys(); + }).then(function(mediaKeys) { + _mediaKeys = mediaKeys; + _mediaKeySession = _mediaKeys.createSession('persistent-usage-record'); + waitForEventAndRunStep('encrypted', _video, onEncrypted, test); + waitForEventAndRunStep('playing', _video, onPlaying, test); + return config.servercertificate ? _mediaKeys.setServerCertificate(config.servercertificate) : true; + }).then(function(success) { + return testmediasource(config); + }).then(function(source) { + _mediaSource = source; + _video.src = URL.createObjectURL(_mediaSource); + return source.done; + }).then(function(){ + _video.play(); + }).catch(onFailure); + }, testname); +} diff --git a/testing/web-platform/tests/encrypted-media/scripts/playback-retrieve-persistent-license.js b/testing/web-platform/tests/encrypted-media/scripts/playback-retrieve-persistent-license.js new file mode 100644 index 0000000000..83cba34028 --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/scripts/playback-retrieve-persistent-license.js @@ -0,0 +1,115 @@ +function runTest(config,qualifier) { + + var testname = testnamePrefix(qualifier, config.keysystem) + + ', persistent-license, ' + + /video\/([^;]*)/.exec(config.videoType)[1] + + ', ' + config.testcase; + + var configuration = { initDataTypes: [ config.initDataType ], + audioCapabilities: [ { contentType: config.audioType } ], + videoCapabilities: [ { contentType: config.videoType } ], + sessionTypes: [ 'persistent-license' ] }; + + + async_test( function(test) { + var _video = config.video, + _mediaKeys, + _mediaKeySession, + _mediaSource, + _sessionId; + + function onFailure(error) { + forceTestFailureFromPromise(test, error); + } + + function onEncrypted(event) { + assert_equals(event.target, _video); + assert_true(event instanceof window.MediaEncryptedEvent); + assert_equals(event.type, 'encrypted'); + + waitForEventAndRunStep('message', _mediaKeySession, onMessage, test); + _mediaKeySession.generateRequest( config.initData ? config.initDataType : event.initDataType, + config.initData || event.initData ).then( function() { + _sessionId = _mediaKeySession.sessionId; + }).catch(onFailure); + } + + function onMessage(event) { + assert_equals(event.target, _mediaKeySession); + assert_true(event instanceof window.MediaKeyMessageEvent); + assert_equals(event.type, 'message'); + + assert_in_array(event.messageType, ['license-request', 'individualization-request']); + + config.messagehandler(event.messageType, event.message).then(function(response) { + return _mediaKeySession.update(response); + }).catch(onFailure); + } + + function onPlaying(event) { + // Not using waitForEventAndRunStep() to avoid too many + // EVENT(onTimeUpdate) logs. + _video.addEventListener('timeupdate', onTimeupdate); + } + + function onTimeupdate(event) { + if (_video.currentTime > (config.duration || 1)) { + _video.removeEventListener('timeupdate', onTimeupdate); + _video.pause(); + _video.removeAttribute('src'); + _video.load(); + + _mediaKeySession.closed + .then(test.step_func(onClosed)) + .catch(onFailure); + _mediaKeySession.close() + .catch(onFailure); + } + } + + function onClosed() { + // Open a new window in which we will attempt to play with the persisted license + var win = window.open(config.windowscript); + assert_not_equals(win, null, "Popup windows not allowed?"); + + // Lisen for an event from the new window containing its test assertions + window.addEventListener('message', test.step_func(function(messageEvent) { + if (messageEvent.data.testResult) { + messageEvent.data.testResult.forEach(test.step_func(function(assertion) { + assert_equals(assertion.actual, assertion.expected, assertion.message); + })); + + win.close(); + test.done(); + } + })); + + // Delete things which can't be cloned and posted over to the new window + delete config.video; + delete config.messagehandler; + + // Post the config and session id to the new window when it is ready + win.onload = function() { + win.postMessage({config: config, sessionId: _sessionId}, '*'); + } + } + + navigator.requestMediaKeySystemAccess(config.keysystem, [configuration]).then(function(access) { + return access.createMediaKeys(); + }).then(function(mediaKeys) { + _mediaKeys = mediaKeys; + return _video.setMediaKeys( mediaKeys ); + }).then(function() { + _mediaKeySession = _mediaKeys.createSession('persistent-license'); + waitForEventAndRunStep('encrypted', _video, onEncrypted, test); + waitForEventAndRunStep('playing', _video, onPlaying, test); + return testmediasource(config); + }).then(function(source) { + _mediaSource = source; + _video.src = URL.createObjectURL(_mediaSource); + return source.done; + }).then(function(){ + _video.play(); + }).catch(onFailure); + }, testname); +} diff --git a/testing/web-platform/tests/encrypted-media/scripts/playback-retrieve-persistent-usage-record.js b/testing/web-platform/tests/encrypted-media/scripts/playback-retrieve-persistent-usage-record.js new file mode 100644 index 0000000000..a04f97d2ca --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/scripts/playback-retrieve-persistent-usage-record.js @@ -0,0 +1,114 @@ +function runTest(config,qualifier) { + + var testname = testnamePrefix(qualifier, config.keysystem) + + ', persistent-usage-record, ' + + /video\/([^;]*)/.exec(config.videoType)[1] + + ', playback, retrieve in new window'; + + var configuration = { initDataTypes: [ config.initDataType ], + audioCapabilities: [ { contentType: config.audioType } ], + videoCapabilities: [ { contentType: config.videoType } ], + sessionTypes: [ 'persistent-usage-record' ] }; + + + async_test( function( test ) { + var _video = config.video, + _mediaKeys, + _mediaKeySession, + _mediaSource, + _sessionId, + _isClosing = false; + + function onFailure(error) { + forceTestFailureFromPromise(test, error); + } + + function onEncrypted(event) { + assert_equals(event.target, _video); + assert_true(event instanceof window.MediaEncryptedEvent); + assert_equals(event.type, 'encrypted'); + + waitForEventAndRunStep('message', _mediaKeySession, onMessage, test); + _mediaKeySession.generateRequest( config.initDataType || event.initDataType, + config.initData || event.initData ).then( function() { + _sessionId = _mediaKeySession.sessionId; + }).catch(onFailure); + } + + function onMessage(event) { + assert_equals(event.target, _mediaKeySession); + assert_true(event instanceof window.MediaKeyMessageEvent); + assert_equals(event.type, 'message'); + + assert_in_array( event.messageType,['license-request', 'individualization-request']); + + config.messagehandler( event.messageType, event.message ).then(function(response) { + return _mediaKeySession.update(response); + }).then(function() { + return _video.setMediaKeys(_mediaKeys); + }).catch(onFailure); + } + + function onPlaying(event) { + // Not using waitForEventAndRunStep() to avoid too many + // EVENT(onTimeUpdate) logs. + _video.addEventListener('timeupdate', onTimeupdate, true); + } + + function onTimeupdate(event) { + if (!_isClosing && _video.currentTime > (config.duration || 1)) { + _isClosing = true; + _video.removeEventListener('timeupdate', onTimeupdate); + _video.pause(); + _mediaKeySession.closed.then( test.step_func(onClosed)); + _mediaKeySession.close(); + } + } + + function onClosed(event) { + _video.src = ""; + _video.setMediaKeys( null ); + + var win = window.open(config.windowscript); + assert_not_equals(win, null, "Popup windows not allowed?"); + + window.addEventListener('message', test.step_func(function(event) { + if (event.data.testResult) { + event.data.testResult.forEach(test.step_func(function(assertion) { + assert_equals(assertion.actual, assertion.expected, assertion.message); + })); + + win.close(); + test.done(); + } + })); + + delete config.video; + delete config.messagehandler; + + win.onload = function() { + win.postMessage({ config: config, sessionId: _sessionId }, '*'); + } + } + + navigator.requestMediaKeySystemAccess(config.keysystem, [configuration]).then(function(access) { + return access.createMediaKeys(); + }).then(function(mediaKeys) { + _mediaKeys = mediaKeys; + return _video.setMediaKeys(mediaKeys); + }).then(function(){ + _mediaKeySession = _mediaKeys.createSession( 'persistent-usage-record' ); + waitForEventAndRunStep('encrypted', _video, onEncrypted, test); + waitForEventAndRunStep('playing', _video, onPlaying, test); + return config.servercertificate ? _mediaKeys.setServerCertificate(config.servercertificate) : true; + }).then(function(success) { + return testmediasource(config); + }).then(function(source) { + _mediaSource = source; + _video.src = URL.createObjectURL(_mediaSource); + return source.done; + }).then(function(){ + _video.play(); + }).catch(onFailure); + }, testname); +} diff --git a/testing/web-platform/tests/encrypted-media/scripts/playback-temporary-encrypted-clear-segmented-sources.js b/testing/web-platform/tests/encrypted-media/scripts/playback-temporary-encrypted-clear-segmented-sources.js new file mode 100644 index 0000000000..8f5af2cd6b --- /dev/null +++ b/testing/web-platform/tests/encrypted-media/scripts/playback-temporary-encrypted-clear-segmented-sources.js @@ -0,0 +1,109 @@ +function runTest(configEncrypted,configClear,qualifier) { + + var testname = testnamePrefix(qualifier, configEncrypted.keysystem) + + ', temporary, ' + + /video\/([^;]*)/.exec(configEncrypted.videoType)[1] + + ', playback, encrypted and clear sources in separate segments'; + + var configuration = { initDataTypes: [ configEncrypted.initDataType ], + audioCapabilities: [ { contentType: configEncrypted.audioType } ], + videoCapabilities: [ { contentType: configEncrypted.videoType } ], + sessionTypes: [ 'temporary' ] }; + + async_test(function(test) { + var didAppendEncrypted = false, + _video = configEncrypted.video, + _mediaKeys, + _mediaKeySession, + _mediaSource, + _sourceBuffer; + + function onFailure(error) { + forceTestFailureFromPromise(test, error); + } + + function onVideoError(event) { + var message = (_video.error || {}).message || 'Got unknown error from