tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

waiting-for-a-key.js (6843B)


      1 function runTest(config)
      2 {
      3    // For debugging timeouts, keep track of the number of the
      4    // various events received.
      5    var debugEncryptedEventFired = false;
      6    var debugWaitingForKeyEventFired = false;
      7    var debugTimeUpdateEventCount = 0;
      8    var debugMessage = '';
      9 
     10    // Set global option explicit_timeout to true and control
     11    // the timeout in the promise test below.
     12    setup({
     13        explicit_timeout: true
     14    });
     15 
     16    promise_test(function (test) {
     17        var video = config.video;
     18        var keysystem = config.keysystem;
     19        var configuration = {
     20            initDataTypes: [config.initDataType],
     21            audioCapabilities: [{
     22                contentType: config.audioType
     23            }],
     24            videoCapabilities: [{
     25                contentType: config.videoType
     26            }],
     27            sessionTypes: ['temporary']
     28        };
     29        var initData;
     30        var initDataType;
     31        var mediaKeySession;
     32        // As this code doesn't wait for the 'message' event for clearkey to avoid
     33        // race conditions with 'waitingforkey', specify the key ID and
     34        // key used by the encrypted content.
     35        var keyId = new Uint8Array(config.content.keys[0].kid);
     36        var rawKey = new Uint8Array(config.content.keys[0].key);
     37        // Use the message handler for non clearkey drm
     38        var handler = config.messageHandler || null;
     39 
     40        // Override timeout() to use custom message instead of default
     41        // message "Test timed out"
     42        test.timeout = function () {
     43            var message = 'timeout. message = ' + debugMessage
     44              + ', encrypted: ' + debugEncryptedEventFired
     45              + ', waitingforkey: ' + debugWaitingForKeyEventFired
     46              + ', timeupdate count: ' + debugTimeUpdateEventCount;
     47 
     48            this.timeout_id = null;
     49            this.set_status(this.TIMEOUT, message);
     50            this.phase = this.phases.HAS_RESULT;
     51            this.done();
     52        };
     53 
     54        return navigator.requestMediaKeySystemAccess(keysystem, [configuration]).then(function (access) {
     55            debugMessage = 'createMediaKeys()';
     56            return access.createMediaKeys();
     57        }).then(function (mediaKeys) {
     58              debugMessage = 'setMediaKeys()';
     59              return video.setMediaKeys(mediaKeys);
     60        }).then(function () {
     61            return testmediasource(config);
     62        }).then(function (source) {
     63            debugMessage = 'wait_for_encrypted_event()';
     64            mediaSource = source;
     65            video.src = URL.createObjectURL(mediaSource);
     66            video.play();
     67            return wait_for_encrypted_event(video);
     68        }).then(function (e) {
     69            // Received the 'encrypted' event(s), so keep a copy of
     70            // the initdata for use when creating the session later.
     71            initDataType = config.initData ? config.initDataType : e.initDataType;
     72            initData = config.initData || e.initData;
     73            // Wait until the video indicates that it needs a key to
     74            // continue.
     75            debugMessage = 'wait_for_waitingforkey_event()';
     76            return wait_for_waitingforkey_event(video);
     77        }).then(function () {
     78            // Make sure the video is NOT paused and not progressing
     79            // before a key is provided. This requires the video
     80            // to NOT have a clear lead.
     81            assert_false(video.paused);
     82            assert_less_than(video.currentTime, 0.2);
     83            // Create a session.
     84            mediaKeySession = video.mediaKeys.createSession('temporary');
     85            debugMessage = 'generateRequest()';
     86            return mediaKeySession.generateRequest(initDataType, initData);
     87        }).then(function () {
     88            // generateRequest() will cause a 'message' event to
     89            // occur specifying the keyId that is needed
     90            // Add the key needed to decrypt.
     91            return wait_for_message_event(mediaKeySession, handler);
     92        }).then(function () {
     93            // Video should start playing now that it can decrypt the
     94            // streams, so wait until a little bit of the video has
     95            // played.
     96            debugMessage = 'wait_for_timeupdate_event()';
     97            return wait_for_timeupdate_event(video);
     98        }).catch(function (error) {
     99            assert_unreached('Error: ' + error.name);
    100        });
    101 
    102        // Typical test duration is 6 seconds on release builds
    103        // (12 seconds on debug).
    104    }, 'Waiting for a key.');
    105 
    106    // Wait for an 'encrypted' event
    107    function wait_for_encrypted_event(video)
    108    {
    109        return new Promise(function (resolve) {
    110            video.addEventListener('encrypted', function listener(e) {
    111                assert_equals(e.target, video);
    112                assert_true(e instanceof window.MediaEncryptedEvent);
    113                assert_equals(e.type, 'encrypted');
    114                debugEncryptedEventFired = true;
    115                video.removeEventListener('encrypted', listener);
    116                resolve(e);
    117            });
    118        });
    119    };
    120 
    121    // Wait for a 'waitingforkey' event. Promise resolved when the
    122    // event is received.
    123    function wait_for_waitingforkey_event(video)
    124    {
    125        return new Promise(function (resolve) {
    126            video.addEventListener('waitingforkey', function listener(e) {
    127                assert_equals(e.target, video);
    128                assert_equals(e.type, 'waitingforkey');
    129                debugWaitingForKeyEventFired = true;
    130                video.removeEventListener('waitingforkey', listener);
    131                resolve(e);
    132            });
    133        });
    134    };
    135 
    136    // Wait for a 'timeupdate' event. Promise resolved if |video| has
    137    // played for more than 0.2 seconds.
    138    function wait_for_timeupdate_event(video)
    139    {
    140        return new Promise(function (resolve) {
    141            video.addEventListener('timeupdate', function listener(e) {
    142                assert_equals(e.target, video);
    143                ++debugTimeUpdateEventCount;
    144                if (video.currentTime < 0.2)
    145                    return;
    146                video.removeEventListener('timeupdate', listener);
    147                resolve(e);
    148            });
    149        });
    150    };
    151 
    152    // We need to wait for the message even if for non clearkey DRMs.
    153    function wait_for_message_event(mediaKeySession, handler)
    154    {
    155        return new Promise(function (resolve, reject) {
    156            mediaKeySession.addEventListener('message', function listener(e) {
    157                assert_equals(e.target, mediaKeySession);
    158                assert_equals(e.type, 'message');
    159                video.removeEventListener('message', listener);
    160                return handler(e.messageType, e.message).then(function (response) {
    161                    return e.target.update(response)
    162                }).then(resolve, reject);
    163            });
    164        });
    165    }
    166 }