[EME] Make the createSession() and update() algorithms more similar.
authorDavid Dorwin <ddorwin@google.com>
Mon, 28 Oct 2013 17:19:54 -0700
changeset 182 7c4bb47218ce
parent 181 82a472ad7ef9
child 183 15e7e8f7eecd
[EME] Make the createSession() and update() algorithms more similar.

Also made other minor improvements in these algorithms.
encrypted-media/encrypted-media.html
encrypted-media/encrypted-media.xml
--- a/encrypted-media/encrypted-media.html	Mon Oct 28 16:23:25 2013 -0700
+++ b/encrypted-media/encrypted-media.html	Mon Oct 28 17:19:54 2013 -0700
@@ -371,51 +371,46 @@
 <p>Schedule a task to initialize the session, providing <var title="true">type</var>, <var title="true">initData</var>, and the new object.</p>
         <p>The user agent will asynchronously execute the following steps in the task:</p>
         <ol>
+          <li><p>Let <var title="true">request</var> be null.</p></li>
           <li><p>Let <var title="true">defaultURL</var> be null.</p></li>
-          <li><p>Let <var title="true">request</var> be null.</p></li>
           <li>
-<p>Use <var title="true">cdm</var> to process <var title="true">type</var> and <var title="true">initData</var>.</p>
+<p>Use <var title="true">cdm</var> to execute the following steps:</p>
             <ol>
-              <li><p>Determine whether a message exchange <span class="non-normative">(e.g. a license request)</span> is required.</p></li>
               <li>
-<p>Follow the steps for the first matching condition from the following list:</p>
-                <dl class="switch">
-                  <dt>If a message exchange is required</dt>
-                  <dd>
-                    <ol>
-                      <li>
-<p>Let <var title="true">request</var> be a request generated by the <a href="#cdm">CDM</a> using <var title="true">initData</var>.</p>
-                        <p>Note: <var title="true">cdm</var> must not use any stream-specific data, including <a href="http://www.w3.org/TR/html5/embedded-content-0.html#media-data">media data</a>, not provided via <var title="true">initData</var>.</p>
-                        <p class="non-normative"><var title="true">type</var> may be used to determine how to interpret <var title="true">initData</var>.</p>
-                        <p class="non-normative"><var title="true">request</var> may be a request for multiple keys, depending on the <var title="true"><a href="#key-system">keySystem</a></var> and/or <var title="true">initData</var>. This is transparent to the application.</p>                
-                      </li>
-                      <li><p>If <var title="true">initData</var> indicates a default URL relevant to <var title="true">keySystem</var>, let <var title="true">defaultURL</var> be that URL.</p></li> 
-                    </ol>
-                    </dd>
-                  <dt>Otherwise</dt>
-                  <dd>Continue.</dd>
-                </dl>
+<p>Process <var title="true">type</var> and <var title="true">initData</var>.</p>
+              <p class="non-normative">Note: <var title="true">type</var> may be used to determine how to interpret <var title="true">initData</var>.</p>
               </li>
               <li>
-<p><i>Error</i>: If any of the preceding processing steps failed</p>
-                  <ol>
-                    <li>
-<p>Create a new <code><a href="#dom-mediakeyerror">MediaKeyError</a></code> object with the following attributes:</p>
-                      <ul style="list-style-type:none"><li>
-                        <code><a href="#dom-code">code</a></code> = the appropriate <code><a href="#dom-mediakeyerror">MediaKeyError</a></code> code<br>
-                        <code><a href="#dom-systemcode">systemCode</a></code> = a Key System-specific value, if provided, and 0 otherwise
-                      </li></ul>
-                    </li>
-                    <li><p>Set the <code><a href="#dom-mediakeysession">MediaKeySession</a></code> object's <code><a href="#dom-error">error</a></code> attribute to the error object created in the previous step.</p></li>
-                    <li><p>Let the state of the session be <code><a href="#dom-stateerror">ERROR</a></code>.</p></li>
-                    <li><p><a href="http://www.w3.org/TR/html5/webappapis.html#queue-a-task">queue a task</a> to <a href="http://www.w3.org/TR/html5/webappapis.html#fire-a-simple-event">fire a simple event</a> named <code><a href="#dom-keyerror">keyerror</a></code> at the <code><a href="#dom-mediakeysession">MediaKeySession</a></code> object.</p></li>
-                    <li><p>Abort the task.</p></li>
-                  </ol>
+<p>If a message exchange <span class="non-normative">(e.g. a license request)</span> is required:</p>
+                <ol>
+                  <li>
+<p>Let <var title="true">request</var> be a request generated by the <a href="#cdm">CDM</a> using <var title="true">initData</var>.</p>
+                    <p><var title="true">cdm</var> must not use any stream-specific data, including <a href="http://www.w3.org/TR/html5/embedded-content-0.html#media-data">media data</a>, not provided via <var title="true">initData</var>.</p>
+                    <p class="non-normative">Note: <var title="true">request</var> may be a request for multiple keys, depending on the <var title="true"><a href="#key-system">keySystem</a></var> and/or <var title="true">initData</var>. This is transparent to the application.</p>                
+                  </li>
+                  <li><p>If <var title="true">initData</var> indicates a default URL relevant to <var title="true">keySystem</var>, let <var title="true">defaultURL</var> be that URL.</p></li> 
+                </ol>
               </li>
             </ol>
           </li>
           <li><p>Let the <code><a href="#dom-sessionid">sessionId</a></code> attribute be a unique <a href="#session-id">Session ID</a> string. <span class="non-normative">It may be obtained from <var title="true">cdm</var>.</span></p></li>
           <li>
+<p>If any of the preceding steps in the task failed, run the following steps:</p>
+              <ol>
+                <li>
+<p>Create a new <code><a href="#dom-mediakeyerror">MediaKeyError</a></code> object with the following attributes:</p>
+                  <ul style="list-style-type:none"><li>
+                    <code><a href="#dom-code">code</a></code> = the appropriate <code><a href="#dom-mediakeyerror">MediaKeyError</a></code> code<br>
+                    <code><a href="#dom-systemcode">systemCode</a></code> = a Key System-specific value, if provided, and 0 otherwise
+                  </li></ul>
+                </li>
+                <li><p>Set the <code><a href="#dom-mediakeysession">MediaKeySession</a></code> object's <code><a href="#dom-error">error</a></code> attribute to the error object created in the previous step.</p></li>
+                <li><p>Let the state of the session be <code><a href="#dom-stateerror">ERROR</a></code>.</p></li>
+                <li><p><a href="http://www.w3.org/TR/html5/webappapis.html#queue-a-task">queue a task</a> to <a href="http://www.w3.org/TR/html5/webappapis.html#fire-a-simple-event">fire a simple event</a> named <code><a href="#dom-keyerror">keyerror</a></code> at the <code><a href="#dom-mediakeysession">MediaKeySession</a></code> object.</p></li>
+                <li><p>Abort the task.</p></li>
+              </ol>
+          </li>
+          <li>
 <p>Follow the steps for the first matching condition from the following list:</p>
             <dl class="switch">
               <dt>If <var title="true">request</var> is not null</dt>
@@ -443,7 +438,6 @@
           </li>
         </ol>
       </li>
-      
       <li>Return the new object to the caller.</li>
     </ol>
 
@@ -488,18 +482,20 @@
         <ol>
           <li><p>Let <var title="true">cdm</var> be the <var title="true">cdm</var> loaded in the <a href="#dom-media-keys-constructor"><code>MediaKeys</code> constructor</a>.</p></li>
           <li><p>Let <var title="true">did store key</var> be false.</p></li>
-          <li><p>Let <var title="true">next message</var> be null.</p></li>
+          <li><p>Let <var title="true">request</var> be null.</p></li>
           <li>
-<p>Use <var title="true">cdm</var> to handle <var title="true">key</var>.</p>
-          <p class="non-normative">Note: For some <a href="#key-system">Key Systems</a>, <var title="true">key</var> may be a license or other structure containing multiple keys.</p>
+<p>Use <var title="true">cdm</var> to execute the following steps:</p>
             <ol>
-              <li><p>Process <var title="true">key</var>.</p></li>
+              <li>
+<p>Process <var title="true">key</var>.</p>
+              <p class="non-normative">Note: For some <a href="#key-system">Key Systems</a>, <var title="true">key</var> may be a license or other structure containing multiple keys.</p>
+              </li>
               <li>
 <p>For each <var title="true">individual key</var> in <var title="true">key</var>, store the <var title="true">individual key</var>.</p>
                 <ol>
                   <li><p>Let <var title="true">key ID</var> be the key ID associated with the <var title="true">individual key</var>.</p></li>
                   <li>
-<p>Store the <var title="true">individual key</var> by following the steps for the first matching condition from the following list:</p>  
+<p>Run the following to store the <var title="true">individual key</var>:</p>  
                     <ol>
                       <li><p>If a stored key already exists for <var title="true">key ID</var>, delete that key.</p></li>
                       <li><p>Store the <var title="true">individual key</var>, license, and/or license information indexed by <var title="true">key ID</var>. <span class="non-normative">The replacement algorithm is <a href="#key-system">Key System</a>-dependent.</span></p></li>
@@ -511,23 +507,14 @@
                   <li><p>Let <var title="true">did store key</var> be true.</p></li>
                 </ol>
               </li>
-              <li><p>If another message needs to be sent to the server, let <var title="true">next message</var> be that message.</p></li>
+              <li><p>If another message needs to be sent to the server, let <var title="true">request</var> be that message.</p></li>
             </ol>
           </li>
           <li>If <var title="true">did store key</var> is true and the <a href="#media-element">media element</a> is <a href="#waiting-for-a-key">waiting for a key</a>, <a href="http://www.w3.org/TR/html5/webappapis.html#queue-a-task">queue a task</a> to attempt to resume playback.
             <p class="non-normative">In other words, resume playback if the necessary key is provided.</p>
           </li>
           <li>
-<p>If <var title="true">next message</var> is not null, <a href="http://www.w3.org/TR/html5/webappapis.html#queue-a-task">queue a task</a> to <a href="http://www.w3.org/TR/html5/webappapis.html#fire-a-simple-event">fire a simple event</a> named <code><a href="#dom-keymessage">keymessage</a></code> at the <code><a href="#dom-mediakeysession">MediaKeySession</a></code> object.</p>
-             <p>The event is of type <code><a href="#dom-mediakeymessageevent">MediaKeyMessageEvent</a></code> and has:</p>
-             <ul style="list-style-type:none"><li>
-               <code><a href="#dom-message">message</a></code> = <var title="true">next message</var><br>
-               <code><a href="#dom-destinationurl">destinationURL</a></code> = null
-             </li></ul>
-          </li>
-          <li><p>If <var title="true">next message</var> is null, let the state of the session be <code><a href="#dom-ready">READY</a></code> and <a href="http://www.w3.org/TR/html5/webappapis.html#queue-a-task">queue a task</a> to <a href="http://www.w3.org/TR/html5/webappapis.html#fire-a-simple-event">fire a simple event</a> named <code><a href="#dom-keyready">keyready</a></code> at the <code><a href="#dom-mediakeysession">MediaKeySession</a></code> object.</p></li>
-          <li>
-<p><i>Error</i>: If any of the preceding steps in the task failed</p>
+<p>If any of the preceding steps in the task failed, run the following steps:</p>
               <ol>
                 <li>
 <p>Create a new <code><a href="#dom-mediakeyerror">MediaKeyError</a></code> object with the following attributes:</p>
@@ -542,17 +529,36 @@
                 <li><p>Abort the task.</p></li>
               </ol>
           </li>
+          <li>
+<p>Follow the steps for the first matching condition from the following list:</p>
+            <dl class="switch">
+              <dt>If <var title="true">request</var> is not null</dt>
+              <dd>
+                <ol>
+                  <li><p>Let the state of the session be <code><a href="#dom-pending">PENDING</a></code>.</p></li>
+                  <li>
+                    <p><a href="http://www.w3.org/TR/html5/webappapis.html#queue-a-task">queue a task</a> to <a href="http://www.w3.org/TR/html5/webappapis.html#fire-a-simple-event">fire a simple event</a> named <code><a href="#dom-keymessage">keymessage</a></code> at the <code><a href="#dom-mediakeysession">MediaKeySession</a></code> object.</p>
+                    <p>The event is of type <code><a href="#dom-mediakeymessageevent">MediaKeyMessageEvent</a></code> and has:</p>
+                    <ul style="list-style-type:none"><li>
+                      <code><a href="#dom-message">message</a></code> = <var title="true">request</var><br>
+                      <code><a href="#dom-destinationurl">destinationURL</a></code> = null
+                    </li></ul>
+                  </li>
+                </ol>
+              </dd>
+              <dt>Otherwise</dt>
+              <dd>
+                <ol>
+                  <li><p>Let the state of the session be <code><a href="#dom-ready">READY</a></code>.</p></li>
+                  <li><p><a href="http://www.w3.org/TR/html5/webappapis.html#queue-a-task">queue a task</a> to <a href="http://www.w3.org/TR/html5/webappapis.html#fire-a-simple-event">fire a simple event</a> named <code><a href="#dom-keyready">keyready</a></code> at the <code><a href="#dom-mediakeysession">MediaKeySession</a></code> object.</p></li>
+                </ol>
+              </dd>
+            </dl>
+          </li>
       </ol>
       </li>
     </ol>
 
-    <p>The key acquisition process <em>may</em> involve the web page handling <code><a href="#dom-keymessage">keymessage</a></code> events, sending the message to a Key System-specific service, and calling <code><a href="#dom-update">update</a></code> with the response message.
-    <code><a href="#dom-update">update</a></code> calls may generate <code><a href="#dom-keymessage">keymessage</a></code> events.
-    During the process, the web page may wish to cancel the acquisition process.
-    <span class="non-normative">For example, if the page cannot contact the license service because of network issues it may wish to fallback to an alternative key system.</span>
-    The page calls <code><a href="#dom-close">close()</a></code> to cancel the a key acquisition session.
-    </p>
-
     <p>The <dfn id="dom-close"><code>close()</code></dfn> method causes the key acquisition session to close and all keys to be released. It must run the following steps:</p>
 
      <ol>
--- a/encrypted-media/encrypted-media.xml	Mon Oct 28 16:23:25 2013 -0700
+++ b/encrypted-media/encrypted-media.xml	Mon Oct 28 17:19:54 2013 -0700
@@ -365,45 +365,39 @@
       <li><p>Schedule a task to initialize the session, providing <var title="true">type</var>, <var title="true">initData</var>, and the new object.</p>
         <p>The user agent will asynchronously execute the following steps in the task:</p>
         <ol>
+          <li><p>Let <var title="true">request</var> be null.</p></li>
           <li><p>Let <var title="true">defaultURL</var> be null.</p></li>
-          <li><p>Let <var title="true">request</var> be null.</p></li>
-          <li><p>Use <var title="true">cdm</var> to process <var title="true">type</var> and <var title="true">initData</var>.</p>
+          <li><p>Use <var title="true">cdm</var> to execute the following steps:</p>
             <ol>
-              <li><p>Determine whether a message exchange <span class="non-normative">(e.g. a license request)</span> is required.</p></li>
-              <li><p>Follow the steps for the first matching condition from the following list:</p>
-                <dl class="switch">
-                  <dt>If a message exchange is required</dt>
-                  <dd>
-                    <ol>
-                      <li><p>Let <var title="true">request</var> be a request generated by the <a href="#cdm">CDM</a> using <var title="true">initData</var>.</p>
-                        <p>Note: <var title="true">cdm</var> must not use any stream-specific data, including <videoanchor name="media-data">media data</videoanchor>, not provided via <var title="true">initData</var>.</p>
-                        <p class="non-normative"><var title="true">type</var> may be used to determine how to interpret <var title="true">initData</var>.</p>
-                        <p class="non-normative"><var title="true">request</var> may be a request for multiple keys, depending on the <var title="true"><a href="#key-system">keySystem</a></var> and/or <var title="true">initData</var>. This is transparent to the application.</p>                
-                      </li>
-                      <li><p>If <var title="true">initData</var> indicates a default URL relevant to <var title="true">keySystem</var>, let <var title="true">defaultURL</var> be that URL.</p></li> 
-                    </ol>
-                    </dd>
-                  <dt>Otherwise</dt>
-                  <dd>Continue.</dd>
-                </dl>
+              <li><p>Process <var title="true">type</var> and <var title="true">initData</var>.</p>
+              <p class="non-normative">Note: <var title="true">type</var> may be used to determine how to interpret <var title="true">initData</var>.</p>
               </li>
-              <li><p><i>Error</i>: If any of the preceding processing steps failed</p>
-                  <ol>
-                    <li><p>Create a new <coderef>MediaKeyError</coderef> object with the following attributes:</p>
-                      <ul style="list-style-type:none"><li>
-                        <coderef>code</coderef> = the appropriate <coderef>MediaKeyError</coderef> code<br></br>
-                        <coderef>systemCode</coderef> = a Key System-specific value, if provided, and 0 otherwise
-                      </li></ul>
-                    </li>
-                    <li><p>Set the <coderef>MediaKeySession</coderef> object's <coderef>error</coderef> attribute to the error object created in the previous step.</p></li>
-                    <li><p>Let the state of the session be <coderef prefix="state">ERROR</coderef>.</p></li>
-                    <li><p><queue-a-task/> to <fire-a-simple-event/> named <coderef>keyerror</coderef> at the <coderef>MediaKeySession</coderef> object.</p></li>
-                    <li><p>Abort the task.</p></li>
-                  </ol>
+              <li><p>If a message exchange <span class="non-normative">(e.g. a license request)</span> is required:</p>
+                <ol>
+                  <li><p>Let <var title="true">request</var> be a request generated by the <a href="#cdm">CDM</a> using <var title="true">initData</var>.</p>
+                    <p><var title="true">cdm</var> must not use any stream-specific data, including <videoanchor name="media-data">media data</videoanchor>, not provided via <var title="true">initData</var>.</p>
+                    <p class="non-normative">Note: <var title="true">request</var> may be a request for multiple keys, depending on the <var title="true"><a href="#key-system">keySystem</a></var> and/or <var title="true">initData</var>. This is transparent to the application.</p>                
+                  </li>
+                  <li><p>If <var title="true">initData</var> indicates a default URL relevant to <var title="true">keySystem</var>, let <var title="true">defaultURL</var> be that URL.</p></li> 
+                </ol>
               </li>
             </ol>
           </li>
           <li><p>Let the <coderef>sessionId</coderef> attribute be a unique <a href="#session-id">Session ID</a> string. <span class="non-normative">It may be obtained from <var title="true">cdm</var>.</span></p></li>
+          <li><p>If any of the preceding steps in the task failed, run the following steps:</p>
+              <ol>
+                <li><p>Create a new <coderef>MediaKeyError</coderef> object with the following attributes:</p>
+                  <ul style="list-style-type:none"><li>
+                    <coderef>code</coderef> = the appropriate <coderef>MediaKeyError</coderef> code<br></br>
+                    <coderef>systemCode</coderef> = a Key System-specific value, if provided, and 0 otherwise
+                  </li></ul>
+                </li>
+                <li><p>Set the <coderef>MediaKeySession</coderef> object's <coderef>error</coderef> attribute to the error object created in the previous step.</p></li>
+                <li><p>Let the state of the session be <coderef prefix="state">ERROR</coderef>.</p></li>
+                <li><p><queue-a-task/> to <fire-a-simple-event/> named <coderef>keyerror</coderef> at the <coderef>MediaKeySession</coderef> object.</p></li>
+                <li><p>Abort the task.</p></li>
+              </ol>
+          </li>
           <li><p>Follow the steps for the first matching condition from the following list:</p>
             <dl class="switch">
               <dt>If <var title="true">request</var> is not null</dt>
@@ -431,7 +425,6 @@
           </li>
         </ol>
       </li>
-      
       <li>Return the new object to the caller.</li>
     </ol>
 
@@ -475,15 +468,16 @@
         <ol>
           <li><p>Let <var title="true">cdm</var> be the <var title="true">cdm</var> loaded in the <a href="#dom-media-keys-constructor"><code>MediaKeys</code> constructor</a>.</p></li>
           <li><p>Let <var title="true">did store key</var> be false.</p></li>
-          <li><p>Let <var title="true">next message</var> be null.</p></li>
-          <li><p>Use <var title="true">cdm</var> to handle <var title="true">key</var>.</p>
-          <p class="non-normative">Note: For some <a href="#key-system">Key Systems</a>, <var title="true">key</var> may be a license or other structure containing multiple keys.</p>
+          <li><p>Let <var title="true">request</var> be null.</p></li>
+          <li><p>Use <var title="true">cdm</var> to execute the following steps:</p>
             <ol>
-              <li><p>Process <var title="true">key</var>.</p></li>
+              <li><p>Process <var title="true">key</var>.</p>
+              <p class="non-normative">Note: For some <a href="#key-system">Key Systems</a>, <var title="true">key</var> may be a license or other structure containing multiple keys.</p>
+              </li>
               <li><p>For each <var title="true">individual key</var> in <var title="true">key</var>, store the <var title="true">individual key</var>.</p>
                 <ol>
                   <li><p>Let <var title="true">key ID</var> be the key ID associated with the <var title="true">individual key</var>.</p></li>
-                  <li><p>Store the <var title="true">individual key</var> by following the steps for the first matching condition from the following list:</p>  
+                  <li><p>Run the following to store the <var title="true">individual key</var>:</p>  
                     <ol>
                       <li><p>If a stored key already exists for <var title="true">key ID</var>, delete that key.</p></li>
                       <li><p>Store the <var title="true">individual key</var>, license, and/or license information indexed by <var title="true">key ID</var>. <span class="non-normative">The replacement algorithm is <a href="#key-system">Key System</a>-dependent.</span></p></li>
@@ -495,21 +489,13 @@
                   <li><p>Let <var title="true">did store key</var> be true.</p></li>
                 </ol>
               </li>
-              <li><p>If another message needs to be sent to the server, let <var title="true">next message</var> be that message.</p></li>
+              <li><p>If another message needs to be sent to the server, let <var title="true">request</var> be that message.</p></li>
             </ol>
           </li>
           <li>If <var title="true">did store key</var> is true and the <a href="#media-element">media element</a> is <a href="#waiting-for-a-key">waiting for a key</a>, <queue-a-task/> to attempt to resume playback.
             <p class="non-normative">In other words, resume playback if the necessary key is provided.</p>
           </li>
-          <li><p>If <var title="true">next message</var> is not null, <queue-a-task/> to <fire-a-simple-event/> named <coderef>keymessage</coderef> at the <coderef>MediaKeySession</coderef> object.</p>
-             <p>The event is of type <coderef>MediaKeyMessageEvent</coderef> and has:</p>
-             <ul style="list-style-type:none"><li>
-               <coderef>message</coderef> = <var title="true">next message</var><br></br>
-               <coderef>destinationURL</coderef> = null
-             </li></ul>
-          </li>
-          <li><p>If <var title="true">next message</var> is null, let the state of the session be <coderef>READY</coderef> and <queue-a-task/> to <fire-a-simple-event/> named <coderef>keyready</coderef> at the <coderef>MediaKeySession</coderef> object.</p></li>
-          <li><p><i>Error</i>: If any of the preceding steps in the task failed</p>
+          <li><p>If any of the preceding steps in the task failed, run the following steps:</p>
               <ol>
                 <li><p>Create a new <coderef>MediaKeyError</coderef> object with the following attributes:</p>
                   <ul style="list-style-type:none"><li>
@@ -523,17 +509,35 @@
                 <li><p>Abort the task.</p></li>
               </ol>
           </li>
+          <li><p>Follow the steps for the first matching condition from the following list:</p>
+            <dl class="switch">
+              <dt>If <var title="true">request</var> is not null</dt>
+              <dd>
+                <ol>
+                  <li><p>Let the state of the session be <coderef>PENDING</coderef>.</p></li>
+                  <li>
+                    <p><queue-a-task/> to <fire-a-simple-event/> named <coderef>keymessage</coderef> at the <coderef>MediaKeySession</coderef> object.</p>
+                    <p>The event is of type <coderef>MediaKeyMessageEvent</coderef> and has:</p>
+                    <ul style="list-style-type:none"><li>
+                      <coderef>message</coderef> = <var title="true">request</var><br></br>
+                      <coderef>destinationURL</coderef> = null
+                    </li></ul>
+                  </li>
+                </ol>
+              </dd>
+              <dt>Otherwise</dt>
+              <dd>
+                <ol>
+                  <li><p>Let the state of the session be <coderef>READY</coderef>.</p></li>
+                  <li><p><queue-a-task/> to <fire-a-simple-event/> named <coderef>keyready</coderef> at the <coderef>MediaKeySession</coderef> object.</p></li>
+                </ol>
+              </dd>
+            </dl>
+          </li>
       </ol>
       </li>
     </ol>
 
-    <p>The key acquisition process <em>may</em> involve the web page handling <coderef>keymessage</coderef> events, sending the message to a Key System-specific service, and calling <coderef>update</coderef> with the response message.
-    <coderef>update</coderef> calls may generate <coderef>keymessage</coderef> events.
-    During the process, the web page may wish to cancel the acquisition process.
-    <span class="non-normative">For example, if the page cannot contact the license service because of network issues it may wish to fallback to an alternative key system.</span>
-    The page calls <methodref>close</methodref> to cancel the a key acquisition session.
-    </p>
-
     <p>The <methoddfn name="close">close()</methoddfn> method causes the key acquisition session to close and all keys to be released. It must run the following steps:</p>
 
      <ol>