[EME] Bug 26758 - Make the CDM responsible for preventing multiple MediaKeySession objects for the same persisted session data.
authorDavid Dorwin <ddorwin@google.com>
Mon, 15 Sep 2014 15:12:06 -0700
changeset 431 03408a291076
parent 430 1f049d683307
child 432 d4cd783f02b3
[EME] Bug 26758 - Make the CDM responsible for preventing multiple MediaKeySession objects for the same persisted session data.
encrypted-media/encrypted-media.html
encrypted-media/encrypted-media.xml
--- a/encrypted-media/encrypted-media.html	Mon Sep 15 15:11:52 2014 -0700
+++ b/encrypted-media/encrypted-media.html	Mon Sep 15 15:12:06 2014 -0700
@@ -587,7 +587,6 @@
           </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>Set the <code><a href="#dom-sessionid">sessionId</a></code> attribute to <var title="true">session id</var>.</p></li>
-          <li><p>Add an entry for the value of the <code><a href="#dom-sessionid">sessionId</a></code> attribute to <var title="true">media keys</var>'s <var title="true">list of active session IDs</var>.</p></li>
           <li><p>Let this object's <var title="true">callable</var> be true.</p></li>
           <li><p>Run the <a href="#algorithms-queue-message">Queue a "message" Event</a> algorithm on the <var title="true">session</var>, providing <var title="true">request</var> and <code>null</code>.</p></li>
           <li><p>Resolve <var>promise</var>.</p></li>
@@ -609,10 +608,6 @@
       <li>
 <p>Run the following steps asynchronously:</p>
         <ol>
-          <li>
-<p>If <var title="true">media keys</var>'s <var title="true">list of active session IDs</var> includes an entry for <var title="true">sessionId</var>, reject <var>promise</var> with a new <code><a href="http://www.w3.org/TR/dom/#exception-domexception">DOMException</a></code> whose name is <code><a href="#dfn-QuotaExceededError">"QuotaExceededError"</a></code>.</p>
-            <p class="non-normative">In other words, do not create a session if a non-closed session already exists for this <var title="true">sessionId</var>.</p>
-          </li>
           <li><p>Let <var title="true">expiration time</var> be <code>NaN</code>.</p></li>
           <li><p>Let <var title="true">request</var> be null.</p></li>
           <li><p>Let <var title="true">destination URL</var> be null.</p></li>
@@ -624,6 +619,10 @@
               <li><p>If there is no data stored for the <var title="true">sessionId</var> in the <var title="true">origin</var>, resolve <var>promise</var> with <code>false</code>.</p></li>
               <li><p>Let <var title="true">session data</var> be the data stored for the <var title="true">sessionId</var> in the <var title="true">origin</var>.
               This must not include data from other origin(s) or that is not associated with an origin.</p></li>
+              <li>
+<p>If there is an unclosed "<code><a href="#dom-sessiontypepersistent">persistent</a></code>" session in any <a href="http://www.w3.org/TR/dom/#document">Document</a> representing the <var title="true">session data</var>, reject <var>promise</var> with a new <code><a href="http://www.w3.org/TR/dom/#exception-domexception">DOMException</a></code> whose name is <code><a href="#dfn-QuotaExceededError">"QuotaExceededError"</a></code>.</p>
+                <p class="non-normative">In other words, do not create a session if a non-closed persistent session already exists for this <var title="true">sessionId</var> in any browsing context.</p>
+              </li>
               <li><p>Load the <var title="true">session data</var>.</p></li>
               <li><p>If the <var title="true">session data</var> indicates an expiration time for the session, let <var title="true">expiration time</var> be the expiration time in milliseconds since 01 January 1970 UTC.</p></li>
               <li>
@@ -637,7 +636,6 @@
           </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>Set the <code><a href="#dom-sessionid">sessionId</a></code> attribute to <var title="true">sessionId</var>.</p></li>
-          <li><p>Add an entry for the value of the <code><a href="#dom-sessionid">sessionId</a></code> attribute to <var title="true">media keys</var>'s <var title="true">list of active session IDs</var>.</p></li>
           <li><p>Let this object's <var title="true">callable</var> be true.</p></li>
           <li>
 <p>If the loaded session contains usable keys, run the <a href="#algorithms-keys-changed">Usable Keys Changed</a> algorithm on the <var title="true">session</var>.</p>
@@ -986,7 +984,6 @@
     <ol>
       <li><p>Let the <var title="true">session</var> be the associated <code><a href="#dom-mediakeysession">MediaKeySession</a></code> object.</p></li>
       <li><p>Let <var title="true">media keys</var> be the <code><a href="#dom-mediakeys">MediaKeys</a></code> object that created this object.</p></li>
-      <li><p>Remove the entry for the value of the <var title="true">session</var>'s <code><a href="#dom-sessionid">sessionId</a></code> attribute from <var title="true">media keys</var>'s <var title="true">list of active session IDs</var>.</p></li>
       <li><p>Let <var>promise</var> be the <code><a href="#dom-closed">closed</a></code> attribute of the <var title="true">session</var>.</p></li>
       <li><p>Resolve <var>promise</var>.</p></li>
     </ol>
@@ -1055,6 +1052,10 @@
       Specifically, the CDM should not store session data during the <code><a href="#dom-generaterequest">generateRequest()</a></code> algorithm.
       This ensures that the application is aware of the session and knows it needs to eventually remove it.
     </p>
+    <p>The CDM must ensure that data for a given session is only present in one active unclosed session in any <a href="http://www.w3.org/TR/dom/#document">Document</a>.
+      In other words, <code><a href="#dom-load">load()</a></code> must fail when there is already a <code><a href="#dom-mediakeysession">MediaKeySession</a></code> representing the session specified by <var title="true">sessionId</var>, either because the object that created it via <code><a href="#dom-generaterequest">generateRequest()</a></code> is still active or it has been loaded into another object via <code><a href="#dom-load">load()</a></code>.
+      A session may only be loaded again after the <a href="#algorithms-session-close">Session Close</a> algorithm has not been run on the object representing it.
+    </p>
     <p>An application that creates a "<code><a href="#dom-sessiontypepersistent">persistent</a></code>" session should later remove the stored data using <code><a href="#dom-remove">remove()</a></code>.
       The CDM may also remove sessions as appropriate, but applications should not rely on this.
     </p>
--- a/encrypted-media/encrypted-media.xml	Mon Sep 15 15:11:52 2014 -0700
+++ b/encrypted-media/encrypted-media.xml	Mon Sep 15 15:12:06 2014 -0700
@@ -560,7 +560,6 @@
           </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>Set the <coderef>sessionId</coderef> attribute to <var title="true">session id</var>.</p></li>
-          <li><p>Add an entry for the value of the <coderef>sessionId</coderef> attribute to <var title="true">media keys</var>'s <var title="true">list of active session IDs</var>.</p></li>
           <li><p>Let this object's <var title="true">callable</var> be true.</p></li>
           <li><p>Run the <a href="#algorithms-queue-message">Queue a "message" Event</a> algorithm on the <var title="true">session</var>, providing <var title="true">request</var> and <code>null</code>.</p></li>
           <li><p>Resolve <var>promise</var>.</p></li>
@@ -581,9 +580,6 @@
       <li><p>Let <var>promise</var> be a new promise.</p></li>
       <li><p>Run the following steps asynchronously:</p>
         <ol>
-          <li><p>If <var title="true">media keys</var>'s <var title="true">list of active session IDs</var> includes an entry for <var title="true">sessionId</var>, reject <var>promise</var> with a new <code><dom4ref name="exception-domexception">DOMException</dom4ref></code> whose name is <code><a href="#dfn-QuotaExceededError">"QuotaExceededError"</a></code>.</p>
-            <p class="non-normative">In other words, do not create a session if a non-closed session already exists for this <var title="true">sessionId</var>.</p>
-          </li>
           <li><p>Let <var title="true">expiration time</var> be <code>NaN</code>.</p></li>
           <li><p>Let <var title="true">request</var> be null.</p></li>
           <li><p>Let <var title="true">destination URL</var> be null.</p></li>
@@ -594,6 +590,9 @@
               <li><p>If there is no data stored for the <var title="true">sessionId</var> in the <var title="true">origin</var>, resolve <var>promise</var> with <code>false</code>.</p></li><!-- Per https://github.com/w3ctag/promises-guide#rejections-should-be-used-for-exceptional-situations. -->
               <li><p>Let <var title="true">session data</var> be the data stored for the <var title="true">sessionId</var> in the <var title="true">origin</var>.
               This must not include data from other origin(s) or that is not associated with an origin.</p></li>
+              <li><p>If there is an unclosed "<coderef prefix="sessiontype">persistent</coderef>" session in any <dom4ref name="document">Document</dom4ref> representing the <var title="true">session data</var>, reject <var>promise</var> with a new <code><dom4ref name="exception-domexception">DOMException</dom4ref></code> whose name is <code><a href="#dfn-QuotaExceededError">"QuotaExceededError"</a></code>.</p>
+                <p class="non-normative">In other words, do not create a session if a non-closed persistent session already exists for this <var title="true">sessionId</var> in any browsing context.</p>
+              </li>
               <li><p>Load the <var title="true">session data</var>.</p></li>
               <li><p>If the <var title="true">session data</var> indicates an expiration time for the session, let <var title="true">expiration time</var> be the expiration time in milliseconds since 01 January 1970 UTC.</p></li>
               <li><p>If the CDM needs to send a message:</p>
@@ -606,7 +605,6 @@
           </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>Set the <coderef>sessionId</coderef> attribute to <var title="true">sessionId</var>.</p></li>
-          <li><p>Add an entry for the value of the <coderef>sessionId</coderef> attribute to <var title="true">media keys</var>'s <var title="true">list of active session IDs</var>.</p></li>
           <li><p>Let this object's <var title="true">callable</var> be true.</p></li>
           <li><p>If the loaded session contains usable keys, run the <a href="#algorithms-keys-changed">Usable Keys Changed</a> algorithm on the <var title="true">session</var>.</p>
             <p>The algorithm may also be run later should additional processing be necessary to determine with certainty whether one or more keys is usable.</p>
@@ -926,7 +924,6 @@
     <ol>
       <li><p>Let the <var title="true">session</var> be the associated <coderef>MediaKeySession</coderef> object.</p></li>
       <li><p>Let <var title="true">media keys</var> be the <coderef>MediaKeys</coderef> object that created this object.</p></li>
-      <li><p>Remove the entry for the value of the <var title="true">session</var>'s <coderef>sessionId</coderef> attribute from <var title="true">media keys</var>'s <var title="true">list of active session IDs</var>.</p></li>
       <li><p>Let <var>promise</var> be the <coderef>closed</coderef> attribute of the <var title="true">session</var>.</p></li>
       <li><p>Resolve <var>promise</var>.</p></li>
     </ol>
@@ -995,6 +992,10 @@
       Specifically, the CDM should not store session data during the <methodref>generateRequest</methodref> algorithm.
       This ensures that the application is aware of the session and knows it needs to eventually remove it.
     </p>
+    <p>The CDM must ensure that data for a given session is only present in one active unclosed session in any <dom4ref name="document">Document</dom4ref>.
+      In other words, <methodref>load</methodref> must fail when there is already a <coderef>MediaKeySession</coderef> representing the session specified by <var title="true">sessionId</var>, either because the object that created it via <methodref>generateRequest</methodref> is still active or it has been loaded into another object via <methodref>load</methodref>.
+      A session may only be loaded again after the <a href="#algorithms-session-close">Session Close</a> algorithm has not been run on the object representing it.
+    </p>
     <p>An application that creates a "<coderef prefix="sessiontype">persistent</coderef>" session should later remove the stored data using <methodref>remove</methodref>.
       The CDM may also remove sessions as appropriate, but applications should not rely on this.
     </p>