<!doctype html>
<html>
  <head>
    <meta charset=utf-8>
    <title>Encrypted Media Extensions: persistent-license, retrieve and destroy, drm</title>
    <link rel="help" href="https://w3c.github.io/encrypted-media/">

    <!-- Helper scripts for Encrypted Media Extensions tests  -->
    <script src=/encrypted-media/util/utils.js></script>
    <script src=/encrypted-media/util/fetch.js></script>
    <script src=/encrypted-media/util/utf8.js></script>
    <script src=/encrypted-media/util/testmediasource.js></script>

    <!-- Message handler for DRM keysystem -->
    <script src=/encrypted-media/util/drm-messagehandler.js></script>

  </head>
  <body>
    <div id='log'></div>

    <div id='video'>
      <video id="videoelement" width="200px"></video>
    </div>

    <script>
    // Wait for a message from the main window with details of our task
    window.addEventListener('message', function(event) {

        var config = event.data.config,
            configuration = {   initDataTypes: [config.initDataType],
                                audioCapabilities: [{contentType: config.audioType}],
                                videoCapabilities: [{contentType: config.videoType}],
                                sessionTypes: ['persistent-license']},
            assertions = [];

        var _mediaKeys,
            _mediaKeySession;

        config.video = document.getElementById('videoelement');
        config.messagehandler = (new MessageHandler(config.keysystem, config.content, 'persistent-license')).messagehandler;

        function onComplete() {
            window.opener.postMessage(assertions, '*');
        }

        function onFailure(error) {
            assertions.push({actual: false, expected: true, message: error.toString()});
            onComplete();
        }

        function onMessage( messageevent )
        {
            assertions.push({expected: true, actual: messageevent instanceof window.MediaKeyMessageEvent, message: "event is of correct class"});
            assertions.push({expected: 'message', actual: messageevent.type, message: "event type is message"});
            assertions.push({expected: 'license-release', actual: messageevent.messageType, message: "message type is license-release"});

            config.messagehandler(messageevent.messageType, messageevent.message)
            .then( function(response) {
                return messageevent.target.update(response);
            }).catch(onFailure);
        }

        function onTimeupdate(event) {
            if (config.video.currentTime > (config.duration || 1)) {
                config.video.pause();
                config.video.removeAttribute('src');
                config.video.load();
                _mediaKeySession.remove();
            }
        }

        function onClosed() {
            // Try and reload and check this fails
            var mediaKeySession = _mediaKeys.createSession('persistent-license');
            mediaKeySession.load(event.data.sessionId ).then( function(success) {
                assertions.push({expected: false, actual: success, message: "Load of removed session should fail"});
                onComplete();
            }).catch(onFailure);
        }

        navigator.requestMediaKeySystemAccess(config.keysystem, [configuration] )
        .then(function(access) {
            return access.createMediaKeys();
        }).then(function(mediaKeys) {
            _mediaKeys = mediaKeys;
            return config.video.setMediaKeys(mediaKeys);
        }).then(function() {
            config.video.addEventListener('timeupdate', onTimeupdate, true);
            _mediaKeySession = _mediaKeys.createSession('persistent-license');
            _mediaKeySession.addEventListener('message', onMessage);
            _mediaKeySession.closed.then(onClosed);
            return _mediaKeySession.load(event.data.sessionId);
        }).then(function(success) {
            assertions.push({actual: success, expected: true, message: "Expect load session to succeed"});
            if (!success) throw new DOMException();
            return testmediasource(config);
        }).then(function(source) {
            config.video.src = URL.createObjectURL(source);
            config.video.play();
        })
        .catch(onFailure);
    } );


    </script>
  </body>
</html>
