<!doctype html>
<html>
  <head>
    <meta charset=utf-8>
    <title>Encrypted Media Extensions: Retrieve stored persistent-usage-record</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>

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

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

    <script>
    window.addEventListener( 'message', function( event ) {

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

            config.messagehandler = (new MessageHandler( config.keysystem, undefined, 'persistent-usage-record' ) ).messagehandler;

        function onFailure(error) {
            assertions.push( { actual: false, expected: true, message: error } );
            window.opener.postMessage({ testResult: assertions }, '*');
        }

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

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

        navigator.requestMediaKeySystemAccess(config.keysystem, [ configuration ] ).then(function(access) {
            return access.createMediaKeys();
        }).then(function(mediaKeys) {
            _mediaKeys = mediaKeys;
            return config.servercertificate ? _mediaKeys.setServerCertificate( config.servercertificate ) : true;
        }).then( function( success ) {
            _mediaKeySession = _mediaKeys.createSession( 'persistent-usage-record' );
            _mediaKeySession.addEventListener( 'message', onMessage );
            _mediaKeySession.closed.then( function() {
                window.opener.postMessage({ testResult: assertions }, '*');
            });
            return _mediaKeySession.load( event.data.sessionId );
        }).then(function( success ) {
            if ( !success ) {
                assertions.push( { actual: success, expected: true, message: "Error loading session" } );
                window.opener.postMessage({ testResult: assertions }, '*');
            }
        }).catch( onFailure );
    });
    </script>
  </body>
</html>
