[EME] Bug 26575 - Make createSession() return a new MediaKeySession synchronously.
authorDavid Dorwin <ddorwin@google.com>
Tue, 26 Aug 2014 13:03:43 -0700
changeset 404 30e440862bc9
parent 403 4e31f7807448
child 405 4c40f901e80e
[EME] Bug 26575 - Make createSession() return a new MediaKeySession synchronously.
encrypted-media/encrypted-media.html
encrypted-media/encrypted-media.xml
--- a/encrypted-media/encrypted-media.html	Mon Aug 25 12:04:02 2014 -0700
+++ b/encrypted-media/encrypted-media.html	Tue Aug 26 13:03:43 2014 -0700
@@ -104,7 +104,7 @@
     <div class="head">
       <p><a href="http://www.w3.org/"><img src="https://www.w3.org/Icons/w3c_home" alt="W3C" width="72" height="48"></a></p>
       <h1>Encrypted Media Extensions</h1>
-      <h2 id="draft-date">W3C Editor's Draft 25 August 2014</h2>
+      <h2 id="draft-date">W3C Editor's Draft 26 August 2014</h2>
       <dl>
         <dt>This Version:</dt>
         <dd><a href="http://dvcs.w3.org/hg/html-media/raw-file/default/encrypted-media/encrypted-media.html">http://dvcs.w3.org/hg/html-media/raw-file/default/encrypted-media/encrypted-media.html</a></dd>
@@ -349,7 +349,7 @@
 interface <dfn id="dom-mediakeys">MediaKeys</dfn> {
   readonly attribute DOMString <a href="#dom-keysystem">keySystem</a>;
 
-  Promise&lt;<a href="#dom-mediakeysession">MediaKeySession</a>&gt; <a href="#dom-createsession">createSession</a>(optional <a href="#dom-sessiontype">SessionType</a> sessionType = "<a href="#dom-sessiontypetemporary">temporary</a>");
+  <a href="#dom-mediakeysession">MediaKeySession</a> <a href="#dom-createsession">createSession</a>(optional <a href="#dom-sessiontype">SessionType</a> sessionType = "<a href="#dom-sessiontypetemporary">temporary</a>");
   Promise&lt;void&gt; <a href="#dom-setservercertificate">setServerCertificate</a>((ArrayBuffer or ArrayBufferView) serverCertificate);
 
   static Promise&lt;<a href="#dom-mediakeys">MediaKeys</a>&gt; <a href="#dom-create">create</a>(DOMString <a href="#key-system">keySystem</a>);
@@ -468,31 +468,23 @@
 <div class="issue-title"><span>Issue 1</span></div>
 <p class=""><a href="https://www.w3.org/Bugs/Public/show_bug.cgi?id=26575">Bug 26575</a> - This method may be changed to return the MediaKeySession object synchronously.</p>
 </div>
-    <p>The <dfn id="dom-createsession"><code>createSession(sessionType)</code></dfn> method creates a new <code><a href="#dom-mediakeysession">MediaKeySession</a></code> object for the <var title="true">initData</var>. It must run the following steps:</p>
+    <p>The <dfn id="dom-createsession"><code>createSession(sessionType)</code></dfn> method returns a new <code><a href="#dom-mediakeysession">MediaKeySession</a></code> object. It must run the following steps:</p>
 
     <ol>
-      <li><p>If <var title="true">sessionType</var> is not supported by the <a href="#cdm">content decryption module</a> corresponding to the <code><a href="#dom-keysystem">keySystem</a></code>, return a promise rejected with a new <code><a href="http://www.w3.org/TR/dom/#exception-domexception">DOMException</a></code> whose name is <code><a href="#dfn-NotSupportedError">"NotSupportedError"</a></code>.</p></li>
-      <li><p>Let <var>promise</var> be a new promise.</p></li>
+      <li><p>If <var title="true">sessionType</var> is not supported by the <a href="#cdm">content decryption module</a> corresponding to the <code><a href="#dom-keysystem">keySystem</a></code>, throw a <code><a href="http://www.w3.org/TR/dom/#exception-domexception">DOMException</a></code> whose name is <code><a href="#dfn-NotSupportedError">"NotSupportedError"</a></code>.</p></li>
       <li>
-<p>Run the following steps asynchronously:</p>
-        <ol>
-          <li>
 <p>Let <var title="true">session</var> be a new <code><a href="#dom-mediakeysession">MediaKeySession</a></code> object, and initialize it as follows:</p>
-            <ol>
-              <li><p>Let the <code><a href="#dom-sessionid">sessionId</a></code> attribute be the empty string.</p></li>
-              <li><p>Let the <code><a href="#dom-expiration">expiration</a></code> attribute be <code>NaN</code>.</p></li>
-              <li><p>Let the <code><a href="#dom-closed">closed</a></code> attribute be a new promise.</p></li>
-              <li><p>Let the <var title="true">session type</var> be <var title="true">sessionType</var>.</p></li>
-              <li><p>Let <var title="true">uninitialized</var> be true.</p></li>
-              <li><p>Let <var title="true">callable</var> be false.</p></li>
-            </ol>
-          </li>
-          <li><p>If any of the preceding steps failed, reject <var>promise</var> with a new <code><a href="http://www.w3.org/TR/dom/#exception-domexception">DOMException</a></code> whose name is the appropriate <a href="#error-names">error name</a>.</p></li>
-          <li><p>Add an entry for the value of the <code><a href="#dom-sessionid">sessionId</a></code> attribute to the <var title="true">list of active session IDs</var> for this object.</p></li>
-          <li><p>Resolve <var>promise</var> with <var title="true">session</var>.</p></li>
+        <ol>
+          <li><p>Let the <code><a href="#dom-sessionid">sessionId</a></code> attribute be the empty string.</p></li>
+          <li><p>Let the <code><a href="#dom-expiration">expiration</a></code> attribute be <code>NaN</code>.</p></li>
+          <li><p>Let the <code><a href="#dom-closed">closed</a></code> attribute be a new promise.</p></li>
+          <li><p>Let the <var title="true">session type</var> be <var title="true">sessionType</var>.</p></li>
+          <li><p>Let <var title="true">uninitialized</var> be true.</p></li>
+          <li><p>Let <var title="true">callable</var> be false.</p></li>
         </ol>
       </li>
-      <li><p>Return <var>promise</var>.</p></li>
+      <li><p>Add an entry for the value of the <code><a href="#dom-sessionid">sessionId</a></code> attribute to the <var title="true">list of active session IDs</var> for this object.</p></li>
+      <li><p>Return <var title="true">session</var>.</p></li>
     </ol>
 
     <p id="server-certificate">The <dfn id="dom-setservercertificate"><code>setServerCertificate(serverCertificate)</code></dfn> method provides a server certificate to be used to encrypt messages to the license server. It must run the following steps:</p>
@@ -1593,10 +1585,7 @@
       promise.then(
         function(createdMediaKeys) {
           var initData = new Uint8Array([ ... ]);
-          return createdMediaKeys.<a href="#dom-createsession">createSession</a>();
-        }
-      ).then(
-        function(keySession) {
+          var keySession = createdMediaKeys.<a href="#dom-createsession">createSession</a>();
           keySession.addEventListener("<a href="#dom-eventmessage">message</a>", handleMessage, false);
           return keySession.<a href="#dom-generaterequest">generateRequest</a>("webm", initData);
         }
@@ -1683,12 +1672,9 @@
   }
 
   function makeNewRequest(mediaKeys, initDataType, initData) {
-    mediaKeys.<a href="#dom-createsession">createSession</a>().then(
-      function(keySession) {
-        keySession.addEventListener("<a href="#dom-eventmessage">message</a>", licenseRequestReady, false);
-        return keySession.<a href="#dom-generaterequest">generateRequest</a>(initDataType, initData);
-      }
-    ).catch(
+    var keySession = mediaKeys.<a href="#dom-createsession">createSession</a>();
+    keySession.addEventListener("<a href="#dom-eventmessage">message</a>", licenseRequestReady, false);
+    keySession.<a href="#dom-generaterequest">generateRequest</a>(initDataType, initData).catch(
       console.error.bind(console, "Unable to create or initialize key session")
     );
   }
@@ -1771,16 +1757,13 @@
 
   // This replaces the implementation in the previous example.
   function makeNewRequest(mediaKeys, initDataType, initData) {
-    mediaKeys.<a href="#dom-createsession">createSession</a>().then(
-      function(keySession) {
-        keySession.addEventListener("<a href="#dom-eventmessage">message</a>", handleMessage, false);
-        keySession.addEventListener("<a href="#dom-eventkeyschange">keyschange</a>", handleKeysChange, false);
-        keySession.<a href="#dom-closed">closed</a>.then(
-          console.log.bind(console, "Session closed")
-        );
-        return keySession.<a href="#dom-generaterequest">generateRequest</a>(initDataType, initData);
-      }
-    ).catch(
+    var keySession = mediaKeys.<a href="#dom-createsession">createSession</a>();
+    keySession.addEventListener("<a href="#dom-eventmessage">message</a>", handleMessage, false);
+    keySession.addEventListener("<a href="#dom-eventkeyschange">keyschange</a>", handleKeysChange, false);
+    keySession.<a href="#dom-closed">closed</a>.then(
+      console.log.bind(console, "Session closed")
+    );
+    keySession.<a href="#dom-generaterequest">generateRequest</a>(initDataType, initData).catch(
       console.error.bind(console, "Unable to create or initialize key session")
     );
   }
@@ -1859,36 +1842,33 @@
 
   // Called if the application does not have a stored sessionId for the media resource.
   function makeNewRequest(mediaKeys, initDataType, initData) {
-    mediaKeys.<a href="#dom-createsession">createSession</a>("persistent").then(
-      function(keySession) {
-        keySession.addEventListener("<a href="#dom-eventmessage">message</a>", handleMessage, false);
-        keySession.<a href="#dom-closed">closed</a>.then(
-          function() {
-            console.log("Session " + this.sessionId + " closed");
-          }.bind(keySession)        
-        );
-        // Store keySession.<a href="#dom-sessionid">sessionId</a> in the application.
-        return keySession.<a href="#dom-generaterequest">generateRequest</a>(initDataType, initData);
-      }
-    ).catch(
+    var keySession = mediaKeys.<a href="#dom-createsession">createSession</a>("persistent");
+    keySession.addEventListener("<a href="#dom-eventmessage">message</a>", handleMessage, false);
+    keySession.<a href="#dom-closed">closed</a>.then(
+      function() {
+        console.log("Session " + this.sessionId + " closed");
+      }.bind(keySession)        
+    );
+    // Store keySession.<a href="#dom-sessionid">sessionId</a> in the application.
+    keySession.<a href="#dom-generaterequest">generateRequest</a>(initDataType, initData).catch(
       console.error.bind(console, "Unable to create or initialize a persistable key session")
     );
   }
 
   // Called if the application has a stored sessionId for the media resource.
   function loadStoredSession(mediaKeys, sessionId) {
-    mediaKeys.<a href="#dom-createsession">createSession</a>("persistent").then(
-      function(keySession) {
-        if (!keySession) {
+    var keySession = mediaKeys.<a href="#dom-createsession">createSession</a>("persistent");
+    keySession.addEventListener("<a href="#dom-eventmessage">message</a>", handleMessage, false);
+    keySession.<a href="#dom-closed">closed</a>.then(
+      console.log.bind(console, "Session closed")
+    );
+    keySession.<a href="#dom-load">load</a>(sessionId).then(
+      function(loaded) {
+        if (!loaded) {
           console.error("No stored session with the ID " + sessionId + " was found.");
           // The application should remove its record of |sessionId|.
           return;
         }
-        keySession.addEventListener("<a href="#dom-eventmessage">message</a>", handleMessage, false);
-        keySession.<a href="#dom-closed">closed</a>.then(
-          console.log.bind(console, "Session closed")
-        );
-        return keySession.<a href="#dom-load">load</a>(sessionId);
       }
     ).catch(
       console.error.bind(console, "Unable to load or initialize the stored session with the ID " + sessionId)
--- a/encrypted-media/encrypted-media.xml	Mon Aug 25 12:04:02 2014 -0700
+++ b/encrypted-media/encrypted-media.xml	Tue Aug 26 13:03:43 2014 -0700
@@ -103,7 +103,7 @@
     <div class="head">
       <p><a href="http://www.w3.org/"><img src="https://www.w3.org/Icons/w3c_home" alt="W3C" width="72" height="48" /></a></p>
       <h1>Encrypted Media Extensions</h1>
-      <h2 id="draft-date">W3C Editor's Draft 25 August 2014</h2>
+      <h2 id="draft-date">W3C Editor's Draft 26 August 2014</h2>
       <dl>
         <dt>This Version:</dt>
         <dd><a href="http://dvcs.w3.org/hg/html-media/raw-file/default/encrypted-media/encrypted-media.html">http://dvcs.w3.org/hg/html-media/raw-file/default/encrypted-media/encrypted-media.html</a></dd>
@@ -346,7 +346,7 @@
 interface <precodedfn>MediaKeys</precodedfn> {
   readonly attribute DOMString <precoderef>keySystem</precoderef>;
 
-  Promise&lt;<precoderef>MediaKeySession</precoderef>&gt; <premethodref>createSession</premethodref>(optional <precoderef>SessionType</precoderef> sessionType = "<precoderef prefix="sessiontype">temporary</precoderef>");
+  <precoderef>MediaKeySession</precoderef> <premethodref>createSession</premethodref>(optional <precoderef>SessionType</precoderef> sessionType = "<precoderef prefix="sessiontype">temporary</precoderef>");
   Promise&lt;void&gt; <premethodref>setServerCertificate</premethodref>((ArrayBuffer or ArrayBufferView) serverCertificate);
 
   static Promise&lt;<precoderef>MediaKeys</precoderef>&gt; <premethodref>create</premethodref>(DOMString <a href="#key-system">keySystem</a>);
@@ -455,29 +455,22 @@
     <p>The <codedfn>keySystem</codedfn> attribute identifies the <a href="#key-system">Key System</a> being used.</p>
 
     <div class="issue"><div class="issue-title"><span>Issue 1</span></div><p class=""><a href="https://www.w3.org/Bugs/Public/show_bug.cgi?id=26575">Bug 26575</a> - This method may be changed to return the MediaKeySession object synchronously.</p></div>
-    <p>The <methoddfn name="createSession">createSession(<var title="true">sessionType</var>)</methoddfn> method creates a new <coderef>MediaKeySession</coderef> object for the <var title="true">initData</var>. It must run the following steps:</p>
+    <p>The <methoddfn name="createSession">createSession(<var title="true">sessionType</var>)</methoddfn> method returns a new <coderef>MediaKeySession</coderef> object. It must run the following steps:</p>
 
     <ol>
-      <li><p>If <var title="true">sessionType</var> is not supported by the <a href="#cdm">content decryption module</a> corresponding to the <coderef>keySystem</coderef>, return a promise rejected with a new <code><dom4ref name="exception-domexception">DOMException</dom4ref></code> whose name is <code><a href="#dfn-NotSupportedError">"NotSupportedError"</a></code>.</p></li>
-      <li><p>Let <var>promise</var> be a new promise.</p></li>
-      <li><p>Run the following steps asynchronously:</p>
+      <li><p>If <var title="true">sessionType</var> is not supported by the <a href="#cdm">content decryption module</a> corresponding to the <coderef>keySystem</coderef>, throw a <code><dom4ref name="exception-domexception">DOMException</dom4ref></code> whose name is <code><a href="#dfn-NotSupportedError">"NotSupportedError"</a></code>.</p></li>
+      <li><p>Let <var title="true">session</var> be a new <coderef>MediaKeySession</coderef> object, and initialize it as follows:</p>
         <ol>
-          <li><p>Let <var title="true">session</var> be a new <coderef>MediaKeySession</coderef> object, and initialize it as follows:</p>
-            <ol>
-              <li><p>Let the <coderef>sessionId</coderef> attribute be the empty string.</p></li>
-              <li><p>Let the <coderef>expiration</coderef> attribute be <code>NaN</code>.</p></li>
-              <li><p>Let the <coderef>closed</coderef> attribute be a new promise.</p></li>
-              <li><p>Let the <var title="true">session type</var> be <var title="true">sessionType</var>.</p></li>
-              <li><p>Let <var title="true">uninitialized</var> be true.</p></li>
-              <li><p>Let <var title="true">callable</var> be false.</p></li>
-            </ol>
-          </li>
-          <li><p>If any of the preceding steps failed, reject <var>promise</var> with a new <code><dom4ref name="exception-domexception">DOMException</dom4ref></code> whose name is the appropriate <a href="#error-names">error name</a>.</p></li>
-          <li><p>Add an entry for the value of the <coderef>sessionId</coderef> attribute to the <var title="true">list of active session IDs</var> for this object.</p></li>
-          <li><p>Resolve <var>promise</var> with <var title="true">session</var>.</p></li>
+          <li><p>Let the <coderef>sessionId</coderef> attribute be the empty string.</p></li>
+          <li><p>Let the <coderef>expiration</coderef> attribute be <code>NaN</code>.</p></li>
+          <li><p>Let the <coderef>closed</coderef> attribute be a new promise.</p></li>
+          <li><p>Let the <var title="true">session type</var> be <var title="true">sessionType</var>.</p></li>
+          <li><p>Let <var title="true">uninitialized</var> be true.</p></li>
+          <li><p>Let <var title="true">callable</var> be false.</p></li>
         </ol>
       </li>
-      <li><p>Return <var>promise</var>.</p></li>
+      <li><p>Add an entry for the value of the <coderef>sessionId</coderef> attribute to the <var title="true">list of active session IDs</var> for this object.</p></li>
+      <li><p>Return <var title="true">session</var>.</p></li>
     </ol>
 
     <p id="server-certificate">The <methoddfn name="setServerCertificate">setServerCertificate(<var title="true">serverCertificate</var>)</methoddfn> method provides a server certificate to be used to encrypt messages to the license server. It must run the following steps:</p>
@@ -1518,10 +1511,7 @@
       promise.then(
         function(createdMediaKeys) {
           var initData = new Uint8Array([ ... ]);
-          return createdMediaKeys.<premethodref>createSession</premethodref>();
-        }
-      ).then(
-        function(keySession) {
+          var keySession = createdMediaKeys.<premethodref>createSession</premethodref>();
           keySession.addEventListener("<precoderef prefix="event">message</precoderef>", handleMessage, false);
           return keySession.<premethodref>generateRequest</premethodref>("webm", initData);
         }
@@ -1608,12 +1598,9 @@
   }
 
   function makeNewRequest(mediaKeys, initDataType, initData) {
-    mediaKeys.<premethodref>createSession</premethodref>().then(
-      function(keySession) {
-        keySession.addEventListener("<precoderef prefix="event">message</precoderef>", licenseRequestReady, false);
-        return keySession.<premethodref>generateRequest</premethodref>(initDataType, initData);
-      }
-    ).catch(
+    var keySession = mediaKeys.<premethodref>createSession</premethodref>();
+    keySession.addEventListener("<precoderef prefix="event">message</precoderef>", licenseRequestReady, false);
+    keySession.<premethodref>generateRequest</premethodref>(initDataType, initData).catch(
       console.error.bind(console, "Unable to create or initialize key session")
     );
   }
@@ -1696,16 +1683,13 @@
 
   // This replaces the implementation in the previous example.
   function makeNewRequest(mediaKeys, initDataType, initData) {
-    mediaKeys.<premethodref>createSession</premethodref>().then(
-      function(keySession) {
-        keySession.addEventListener("<precoderef prefix="event">message</precoderef>", handleMessage, false);
-        keySession.addEventListener("<precoderef prefix="event">keyschange</precoderef>", handleKeysChange, false);
-        keySession.<precoderef>closed</precoderef>.then(
-          console.log.bind(console, "Session closed")
-        );
-        return keySession.<premethodref>generateRequest</premethodref>(initDataType, initData);
-      }
-    ).catch(
+    var keySession = mediaKeys.<premethodref>createSession</premethodref>();
+    keySession.addEventListener("<precoderef prefix="event">message</precoderef>", handleMessage, false);
+    keySession.addEventListener("<precoderef prefix="event">keyschange</precoderef>", handleKeysChange, false);
+    keySession.<precoderef>closed</precoderef>.then(
+      console.log.bind(console, "Session closed")
+    );
+    keySession.<premethodref>generateRequest</premethodref>(initDataType, initData).catch(
       console.error.bind(console, "Unable to create or initialize key session")
     );
   }
@@ -1786,36 +1770,33 @@
 
   // Called if the application does not have a stored sessionId for the media resource.
   function makeNewRequest(mediaKeys, initDataType, initData) {
-    mediaKeys.<premethodref>createSession</premethodref>("persistent").then(
-      function(keySession) {
-        keySession.addEventListener("<precoderef prefix="event">message</precoderef>", handleMessage, false);
-        keySession.<precoderef>closed</precoderef>.then(
-          function() {
-            console.log("Session " + this.sessionId + " closed");
-          }.bind(keySession)        
-        );
-        // Store keySession.<precoderef>sessionId</precoderef> in the application.
-        return keySession.<premethodref>generateRequest</premethodref>(initDataType, initData);
-      }
-    ).catch(
+    var keySession = mediaKeys.<premethodref>createSession</premethodref>("persistent");
+    keySession.addEventListener("<precoderef prefix="event">message</precoderef>", handleMessage, false);
+    keySession.<precoderef>closed</precoderef>.then(
+      function() {
+        console.log("Session " + this.sessionId + " closed");
+      }.bind(keySession)        
+    );
+    // Store keySession.<precoderef>sessionId</precoderef> in the application.
+    keySession.<premethodref>generateRequest</premethodref>(initDataType, initData).catch(
       console.error.bind(console, "Unable to create or initialize a persistable key session")
     );
   }
 
   // Called if the application has a stored sessionId for the media resource.
   function loadStoredSession(mediaKeys, sessionId) {
-    mediaKeys.<premethodref>createSession</premethodref>("persistent").then(
-      function(keySession) {
-        if (!keySession) {
+    var keySession = mediaKeys.<premethodref>createSession</premethodref>("persistent");
+    keySession.addEventListener("<precoderef prefix="event">message</precoderef>", handleMessage, false);
+    keySession.<precoderef>closed</precoderef>.then(
+      console.log.bind(console, "Session closed")
+    );
+    keySession.<premethodref>load</premethodref>(sessionId).then(
+      function(loaded) {
+        if (!loaded) {
           console.error("No stored session with the ID " + sessionId + " was found.");
           // The application should remove its record of |sessionId|.
           return;
         }
-        keySession.addEventListener("<precoderef prefix="event">message</precoderef>", handleMessage, false);
-        keySession.<precoderef>closed</precoderef>.then(
-          console.log.bind(console, "Session closed")
-        );
-        return keySession.<premethodref>load</premethodref>(sessionId);
       }
     ).catch(
       console.error.bind(console, "Unable to load or initialize the stored session with the ID " + sessionId)