summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/encrypted-media/Google/migrated_to_root_disabled/encrypted-media-waiting-for-a-key.html
blob: 2af37cfb9af79b5dc0ba4233e5f5b1fa4f9e3abe (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
<!DOCTYPE html>
<!-- Copyright © 2016 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
<html>
    <head>
        <title>Waiting for a key.</title>
        <script src="encrypted-media-utils.js"></script>
<!--
        Test has been migrated to the root directory and is being disabled here.
        <script src="/resources/testharness.js"></script>
        <script src="/resources/testharnessreport.js"></script>
-->
    </head>
    <body>
        <video id="testVideo"></video>
        <div id="log"></div>
        <script>
            // For debugging timeouts, keep track of the number of the
            // various events received.
            var debugEncryptedEventCount = 0;
            var debugWaitingForKeyEventCount = 0;
            var debugTimeUpdateEventCount = 0;
            var debugMessage = '';

            promise_test(function(test)
            {
                var video = document.getElementById('testVideo');
                var content = 'webm/test-encrypted.webm';
                var initData;
                var initDataType;
                var mediaKeySession;

                test.timeout = function()
                {
                    var message = 'timeout. message = ' + debugMessage
                                   + ', encrypted: ' + debugEncryptedEventCount
                                   + ', waitingforkey: ' + debugWaitingForKeyEventCount
                                   + ', timeupdate: ' + debugTimeUpdateEventCount;
                    test.force_timeout();
                    test.timeout_id = null;
                    test.set_status(2, message);
                    test.done();
                };

                // As this code doesn't wait for the 'message' event to avoid
                // race conditions with 'waitingforkey', specify the key ID and
                // key used by the encrypted content.
                var keyId = stringToUint8Array('0123456789012345');
                var rawKey = new Uint8Array([0xeb, 0xdd, 0x62, 0xf1, 0x68, 0x14, 0xd2, 0x7b,
                                             0x68, 0xef, 0x12, 0x2a, 0xfc, 0xe4, 0xae, 0x3c]);

                return navigator.requestMediaKeySystemAccess('org.w3.clearkey', getConfigurationForFile(content)).then(function(access) {
                    debugMessage = 'createMediaKeys()';
                    return access.createMediaKeys();
                }).then(function(mediaKeys) {
                    debugMessage = 'setMediaKeys()';
                    return video.setMediaKeys(mediaKeys);
                }).then(function() {
                    video.src = content;
                    video.play();
                    debugMessage = 'wait_for_encrypted_event()';
                    return wait_for_encrypted_event(video);
                }).then(function(e) {
                    // Received the 'encrypted' event(s), so keep a copy of
                    // the initdata for use when creating the session later.
                    initData = e.initData;
                    initDataType = e.initDataType;

                    // Wait until the video indicates that it needs a key to
                    // continue.
                    debugMessage = 'wait_for_waitingforkey_event()';
                    return wait_for_waitingforkey_event(video);
                }).then(function() {
                    // Make sure the video is NOT paused and not progressing
                    // before a key is provided. This requires the video
                    // to NOT have a clear lead.
                    assert_false(video.paused);
                    assert_equals(video.currentTime, 0);

                    // Create a session.
                    mediaKeySession = video.mediaKeys.createSession();
                    debugMessage = 'generateRequest()';
                    return mediaKeySession.generateRequest(initDataType, initData);
                }).then(function() {
                    // generateRequest() will cause a 'message' event to
                    // occur specifying the keyId that is needed, but we
                    // ignore it since we already know what keyId is needed.
                    // Add the key needed to decrypt.
                    var jwkSet = stringToUint8Array(createJWKSet(createJWK(keyId, rawKey)));
                    debugMessage = 'update()';
                    return mediaKeySession.update(jwkSet);
                }).then(function() {
                    // Video should start playing now that it can decrypt the
                    // streams, so wait until a little bit of the video has
                    // played.
                    debugMessage = 'wait_for_timeupdate_event()';
                    return wait_for_timeupdate_event(video);
                });

                // Typical test duration is 6 seconds on release builds
                // (12 seconds on debug). Since the test is timing out anyway,
                // make the duration 5 seconds so that the timeout function
                // is actually called (instead of simply aborting the test).
            }, 'Waiting for a key.', { timeout: 5000 });

            // Wait for a pair of 'encrypted' events. Promise resolved on
            // second event.
            function wait_for_encrypted_event(video)
            {
                var encryptedEventCount = 0;
                return new Promise(function(resolve) {
                    video.addEventListener('encrypted', function listener(e) {
                        assert_equals(e.target, video);
                        assert_true(e instanceof window.MediaEncryptedEvent);
                        assert_equals(e.type, 'encrypted');

                        // The same decryption key is used by both the audio
                        // and the video streams so wait for the second event
                        // to ensure we see both events.
                        ++debugEncryptedEventCount;
                        if (++encryptedEventCount != 2)
                            return;

                        video.removeEventListener('encrypted', listener);
                        resolve(e);
                    });
                });
            };

            // Wait for a 'waitingforkey' event. Promise resolved when the
            // event is received.
            function wait_for_waitingforkey_event(video)
            {
                var waitingForKeyEventCount = 0;
                return new Promise(function(resolve) {
                    video.addEventListener('waitingforkey', function listener(e) {
                        assert_equals(e.target, video);
                        assert_equals(e.type, 'waitingforkey');

                        ++debugWaitingForKeyEventCount;
                        ++waitingForKeyEventCount;
                        // TODO(jrummell): waitingforkey event should only
                        // occur once. http://crbug.com/461903
//                      assert_equals(waitingForKeyEventCount, 1, 'Multiple waitingforkey events');

                        video.removeEventListener('waitingforkey', listener);
                        resolve(e);
                    });
                });
            };

            // Wait for a 'timeupdate' event. Promise resolved if |video| has
            // played for more than 0.2 seconds.
            function wait_for_timeupdate_event(video)
            {
                return new Promise(function(resolve) {
                    video.addEventListener('timeupdate', function listener(e) {
                        assert_equals(e.target, video);
                        ++debugTimeUpdateEventCount;
                        if (video.currentTime < 0.2)
                            return;
                        video.removeEventListener('timeupdate', listener);
                        resolve(e);
                    });
                });
            };
        </script>
    </body>
</html>