dom/media/test/test_eme_persistent_sessions.html
author JW Wang <jwwang@mozilla.com>
Fri, 09 Jan 2015 01:46:00 +0100
changeset 250181 00ac75ab182f
parent 249684 30e19d1edbf2
child 250187 4bcb6239d04b
permissions -rw-r--r--
Bug 1081251 - register error handlers for all media elements in EME mochitests. r=cpearce a=lmandel

<!DOCTYPE HTML>
<html>
<head>
  <title>Test Encrypted Media Extensions</title>
  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
  <script type="text/javascript" src="manifest.js"></script>
  <script type="text/javascript" src="eme.js"></script>
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
var manager = new MediaTestManager;

function UsableKeyIdsMatch(usableKeyIds, expectedKeyIds) {
  var hexKeyIds = usableKeyIds.map(function(keyId) {
    return Base64ToHex(window.btoa(ArrayBufferToString(keyId)));
  }).sort();
  var expected = Object.keys(expectedKeyIds).sort();
  if (expected.length != hexKeyIds.length) {
    return false;
  }
  for (var i = 0; i < hexKeyIds.length; i++) {
    if (hexKeyIds[i] != expected[i]){
      return false;
    }
  }
  return true;
}

function AwaitAllKeysUsable(session, keys, token) {
  return new Promise(function(resolve, reject) {
    function check() {
      session.getUsableKeyIds().then(function(usableKeyIds) {
        var u = UsableKeyIdsMatch(usableKeyIds, keys);
        if (UsableKeyIdsMatch(usableKeyIds, keys)) {
          session.removeEventListener("keyschange", check);
          resolve();
        }
      }, bail(token + " failed to get usableKeyIds"));
    }
    session.addEventListener("keyschange", check);
    check(); // in case all keys are already usable
  });
}

function AwaitAllKeysNotUsable(session, token) {
  return new Promise(function(resolve, reject) {
    function check() {
      session.getUsableKeyIds().then(function(usableKeyIds) {
        if (usableKeyIds.length == 0) {
          session.removeEventListener("keyschange", check);
          resolve();
        }
      }, bail(token + " failed to get usableKeyIds"));
    }
    session.addEventListener("keyschange", check);
    check(); // in case all keys are already removed
  });
}

function startTest(test, token)
{
  manager.started(token);

  var recreatedSession; // will have remove() called on it.

  var keySystemAccess;

  var v = SetupEME(test, token,
    {
      onsessionupdated: function(session) {
        Log(token, "Session created");
        var sessionId;
        initialSession = session;

        // Once the session has loaded and has all its keys usable, close
        // all sessions without calling remove() on them.
        AwaitAllKeysUsable(session, test.keys, token)
        .then(function() {
          sessionId = session.sessionId;
          Log(token, "Closing session with id=" + sessionId);
          return session.close();
        })

        // Once the session is closed, reload the MediaKeys and reload the session
        .then(function() {
          return navigator.requestMediaKeySystemAccess(KEYSYSTEM_TYPE);
        })

        .then(function(requestedKeySystemAccess) {
          keySystemAccess = requestedKeySystemAccess;
          return keySystemAccess.createMediaKeys();
        })

        .then(function(mediaKeys) {
          Log(token, "re-created MediaKeys object ok");
          recreatedSession = mediaKeys.createSession("persistent");
          Log(token, "Created recreatedSession, loading sessionId=" + sessionId);
          return recreatedSession.load(sessionId);
        })

        .then(function(suceeded) {
          if (suceeded) {
            return Promise.resolve();
          } else {
            return Promise.reject("Fail to load recreatedSession, sessionId=" + sessionId);
          }
        })

        .then(function() {
          return AwaitAllKeysUsable(recreatedSession, test.keys, token);
        })

        .then(function() {
          Log(token, "re-loaded persistent session, all keys still usable");
          return Promise.all([AwaitAllKeysNotUsable(recreatedSession, token), recreatedSession.remove()]);
        })

        .then(function() {
          Log(token, "removed session, all keys unusable.");
          // Attempt to recreate the session, the attempt should fail.
          return keySystemAccess.createMediaKeys();
        })

        .then(function(mediaKeys) {
          Log(token, "re-re-created MediaKeys object ok");
          // Trying to load the removed persistent session should fail.
          return mediaKeys.createSession("persistent").load(sessionId);
        })

        .then(function(suceeded) {
          is(suceeded, false, token + " we expect the third session creation to fail, as the session should have been removed.");
          manager.finished(token);
        })

        .catch(function(reason) {
          // Catch rejections if any.
          ok(false, token + " rejected, reason=" + reason);
          manager.finished(token);
        });

      },
      sessionType: "persistent",
    }
  );

  LoadTest(test, v, token);
}

function beginTest() {
  manager.runTests(gEMETests, startTest);
}

var prefs = [
  [ "media.mediasource.enabled", true ],
  [ "media.mediasource.mp4.enabled", true ],
];

if (/Linux/.test(navigator.userAgent) ||
    !document.createElement('video').canPlayType("video/mp4")) {
  // XXX remove once we have mp4 PlatformDecoderModules on all platforms.
  prefs.push([ "media.fragmented-mp4.exposed", true ]);
  prefs.push([ "media.fragmented-mp4.use-blank-decoder", true ]);
}

SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({ "set" : prefs }, beginTest);
</script>
</pre>
</body>
</html>