<!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({ testResult: 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>
