From 51d4ad783ce96dd0ae25c930b27cdddd51e17a87 Mon Sep 17 00:00:00 2001 From: Mark Watson <watsonm@netflix.com> Date: Tue, 19 Sep 2017 12:10:36 -0700 Subject: [PATCH 1/4] Revert "Fix #353: Remove persistent-usage-record from the V1 spec (#354)" This reverts commit 0c72b4817a66c0350b49ba1e1f12d64287aa4efe. --- encrypted-media-respec.html | 249 ++++++++++++++++- encrypted-media.js | 8 + index.html | 524 +++++++++++++++++++++++++++--------- 3 files changed, 645 insertions(+), 136 deletions(-) diff --git a/encrypted-media-respec.html b/encrypted-media-respec.html index 4adf5a13..06e309bd 100644 --- a/encrypted-media-respec.html +++ b/encrypted-media-respec.html @@ -288,7 +288,7 @@ <h2>Definitions</h2> Known keys are exposed via the <a def-id="keyStatuses"></a> attribute. </p> - <p>Keys are considered known even after they become unusable, such as due to <a def-id="expiration-time">expiration</a> or if they are removed but a <a def-id="record-of-license-destruction"></a> is available. + <p>Keys are considered known even after they become unusable, such as due to <a def-id="expiration-time">expiration</a> or if they are removed but a <a def-id="record-of-license-destruction"></a> or <a def-id="record-of-key-usage"></a> is available. Keys only become unknown when they are explicitly removed from a session and any license release message is acknowledged. </p> @@ -1432,7 +1432,8 @@ <h2><dfn>MediaKeys</dfn> Interface</h2> <div><pre class="idl">enum MediaKeySessionType { "temporary", - "persistent-license" + "persistent-license", + "persistent-usage-record" };</pre> <p>The <dfn>MediaKeySessionType</dfn> enumeration is defined as follows:</p> <table class="simple" data-dfn-for="MediaKeySessionType" data-link-for="MediaKeySessionType"><tbody> @@ -1463,6 +1464,48 @@ <h2><dfn>MediaKeys</dfn> Interface</h2> See <a def-id="session-storage"></a>. </p> </td></tr> + <tr><td><dfn><code id="idl-def-MediaKeySessionType.persistent-usage-record">persistent-usage-record</code></dfn></td><td> + <p> + A session for which the license and key(s) are not persisted and for which a <a def-id="record-of-key-usage"></a> is persisted when + the keys available within the session are destroyed. + The <dfn id="record-of-key-usage">record of key usage</dfn> consists of: + </p> + <ul> + <li> + <p>A record of the <a def-id="key-id">key IDs</a> of all the key(s) that were at any time <a href="#known-key">known</a> to the session,</p> + </li> + <li> + <p> + <var>first decryption time</var> - The <dfn id="first-decryption-time">first decryption time</dfn>, defined as the time at which the session was first used to decrypt content, accurate to <var><a def-id="key-usage-accuracy"></a></var> and + </p> + </li> + <li> + <p> + <var>latest decryption time</var> - The <dfn id="latest-decryption-time">latest decryption time</dfn>, defined as the latest time at which the session was used to decrypt content, accurate to <var><a def-id="key-usage-accuracy"></a></var>. + </p> + </li> + </ul> + <p> + A <a def-id="message"></a> of type <a def-id="message-type-license-release"></a> containing the <a def-id="record-of-key-usage"></a> will be generated each time <a def-id="remove"></a> is called, until the record is acknowledged by a response passed to <a def-id="update"></a>. + </p> + <p> + The <dfn id="key-usage-accuracy"><var>key usage accuracy</var></dfn> is implementation-dependant but SHALL NOT be greater than 60 seconds. + </p> + <p class="note"> + Because the license and keys are not persisted, this record implicitly proves that the keys are no longer available in the session. + </p> + <p class="note"> + User agents MAY implement this mechanism by means other than persisting data on key destruction - for example by persisting data during playback which is later used + to infer the fact of key destruction - provided the observable behavior is compliant to this specification. + </p> + <p> + The session MUST be loadable via its <a def-id="session-id"></a> once <a def-id="update"></a> is called successfully. + The application is responsible for managing any such storage that may be generated by the CDM. + See <a def-id="session-storage"></a>. + Can only be created if the configuration associated with the <a>MediaKeySystemAccess</a> object that created this object has a <a def-id="option-persistentState"></a> value of <a def-id="requirement-required"></a>. + Support for this session type is OPTIONAL. + </p> + </td></tr> </tbody></table></div> <div><pre class="idl">[SecureContext] interface MediaKeys { @@ -1558,6 +1601,8 @@ <h4>Is persistent session type?</h4> <dd>Return <code>false</code>.</dd> <dt><a def-id="persistent-license-session"></a></dt> <dd>Return <code>true</code>.</dd> + <dt><a def-id="persistent-usage-record-session"></a></dt> + <dd>Return <code>true</code>.</dd> </dl> </li> </ol> @@ -1632,7 +1677,12 @@ <h2><dfn>MediaKeySession</dfn> Interface</h2> <!-- TODO: Replace and/or expand on this with an implementation of Issue #360. --> Applications that want to ensure a session is closed before taking some other action SHOULD call <a def-id="close"></a> and wait for the returned promise to be resolved. </p> - + <p> + If a <a>MediaKeySession</a> object becomes inaccessible to the page + and is not <a def-id="media-key-session-closed"></a>, the User Agent + MUST run the <a def-id="media-key-session-destroyed-algorithm"></a> algorithm before User Agent state + associated with the <a href="#key-session">session</a> is deleted. + </p> <p>For methods that return a promise, all errors are reported asynchronously by rejecting the returned Promise. This includes [[!WEBIDL]] type mapping errors.</p> <p>The following steps of an algorithm are always aborted when rejecting a promise.</p> @@ -1723,6 +1773,34 @@ <h2><dfn>MediaKeySession</dfn> Interface</h2> <dd> <p>Let <var>requested license type</var> be a persistable license.</p> </dd> + <dt><a def-id="persistent-usage-record-session"></a></dt> + <dd> + <ol> + <li> + <p>Initialize this object's <var>record of key usage</var> as follows.</p> + <ul> + <li> + <p> + Set the list of <a def-id="key-id">key IDs</a> <a href="#known-key">known</a> to the session to an empty list. + </p> + </li> + <li> + <p> + Set the <var>first decrypt time</var> to <code>null</code>. + </p> + </li> + <li> + <p> + Set the <var>latest decrypt time</var> to <code>null</code>. + </p> + </li> + </ul> + </li> + <li> + <p>Let <var>requested license type</var> be a non-persistable license that will persist a <a def-id="record-of-key-usage"></a>.</p> + </li> + </ol> + </dd> </dl> </li> @@ -1915,6 +1993,22 @@ <h2><dfn>MediaKeySession</dfn> Interface</h2> <dd>Process <var>sanitized response</var>, storing the license/key(s) and related session data contained in <var>sanitized response</var>. Such data MUST be stored such that only the <a def-id="origin"></a> of this object's <a def-id="document-concept"></a> can access it. </dd> + <dt>If <var>sessionType</var> is <a def-id="persistent-usage-record-session"></a> and <var>sanitized response</var> contains a non-persistable license</dt> + <dd> + <p>Run the following steps:</p> + <ol> + <li> + <p> + Process <var>sanitized response</var>, not storing any session data. + </p> + </li> + <li> + <p> + If processing <var>sanitized response</var> results in the addition of keys to the set of <a href="#known-key">known keys</a>, add the <a def-id="key-id">key IDs</a> of these keys to this object's <var>record of key usage</var>. + </p> + </li> + </ol> + </dd> <dt>Otherwise</dt> <dd><p>Reject <var>promise</var> with a newly created <a def-id="TypeError"></a>.</p></dd> </dl> @@ -1940,6 +2034,20 @@ <h2><dfn>MediaKeySession</dfn> Interface</h2> <li><p>Set <var>session closed</var> to true.</p></li> </ol> </dd> + <dt>If <var>sanitized response</var> contains a <a def-id="record-of-key-usage"></a> acknowledgement and <var>sessionType</var> is <a def-id="persistent-usage-record-session"></a></dt> + <dd> + <p>Run the following steps:</p> + <ol> + <li> + <p> + Close the <a href="#key-session">session</a> and clear <em>all</em> stored session data associated with this object, + including the <a def-id="sessionId"></a> and <a def-id="record-of-key-usage"></a>. + </p> + <p class="note">A subsequent call to <a def-id="load"></a> with the value of this object's <a def-id="sessionId"></a> would fail because there is no data stored for that session ID.</p> + </li> + <li><p>Set <var>session closed</var> to true.</p></li> + </ol> + </dd> <dt>Otherwise</dt> <dd>Process <var>sanitized response</var>, not storing any session data. <p class="note">For example, <var>sanitized response</var> may contain information that will be used to generate another <a def-id="message"></a> event. @@ -2091,6 +2199,19 @@ <h2><dfn>MediaKeySession</dfn> Interface</h2> </li> </ol> </dd> + <dt><a def-id="persistent-usage-record-session"></a></dt> + <dd> + <ol> + <li> + Store this object's <var>record of key usage</var>. + </li> + <li> + <p> + Let <var>message</var> be a message containing or reflecting this object's <var>record of key usage</var>. + </p> + </li> + </ol> + </dd> </dl> </li> </ol> @@ -2192,7 +2313,7 @@ <h2>Methods</h2> The time represented by the <a def-id="expiration"></a> attribute MUST be earlier than the current time. All other keys in the session MUST have this status. </td></tr><tr><td><dfn><code id="idl-def-MediaKeyStatus.released">released</code></dfn></td><td> - The key itself is no longer available to the CDM, but information about the key, such as a <a def-id="record-of-license-destruction"></a>, is available. + The key itself is no longer available to the CDM, but information about the key, such as a <a def-id="record-of-license-destruction"></a> or <a def-id="record-of-key-usage"></a>, is available. </td></tr><tr><td><dfn><code id="idl-def-MediaKeyStatus.output-restricted">output-restricted</code></dfn></td><td> There are output restrictions associated with the key that cannot currently be met. Media data decrypted with this key may be blocked from presentation, if necessary according to @@ -2228,7 +2349,7 @@ <h3><a>MediaKeyMessageEvent</a></h3> "individualization-request" };</pre> <p>The <dfn>MediaKeyMessageType</dfn> is defined as follows:</p> - <table class="simple" data-dfn-for="MediaKeyMessageType" data-link-for="MediaKeyMessageType"><tbody><tr><th colspan="2">Enumeration description</th></tr><tr><td><dfn><code id="idl-def-MediaKeyMessageType.license-request">license-request</code></dfn></td><td>The message contains a request for a new license.</td></tr><tr><td><dfn><code id="idl-def-MediaKeyMessageType.license-renewal">license-renewal</code></dfn></td><td>The message contains a request to renew an existing license.</td></tr><tr><td><dfn><code id="idl-def-MediaKeyMessageType.license-release">license-release</code></dfn></td><td>The message contains a <a def-id="record-of-license-destruction"></a>.</td></tr><tr><td><dfn><code id="idl-def-MediaKeyMessageType.individualization-request">individualization-request</code></dfn></td><td> + <table class="simple" data-dfn-for="MediaKeyMessageType" data-link-for="MediaKeyMessageType"><tbody><tr><th colspan="2">Enumeration description</th></tr><tr><td><dfn><code id="idl-def-MediaKeyMessageType.license-request">license-request</code></dfn></td><td>The message contains a request for a new license.</td></tr><tr><td><dfn><code id="idl-def-MediaKeyMessageType.license-renewal">license-renewal</code></dfn></td><td>The message contains a request to renew an existing license.</td></tr><tr><td><dfn><code id="idl-def-MediaKeyMessageType.license-release">license-release</code></dfn></td><td>The message contains a <a def-id="record-of-license-destruction"></a> or <a def-id="record-of-key-usage"></a>.</td></tr><tr><td><dfn><code id="idl-def-MediaKeyMessageType.individualization-request">individualization-request</code></dfn></td><td> The message contains a request for <a href="#app-assisted-individualization">App-Assisted Individualization</a> (or re-individualization).<br> As with all other messages, any identifiers in the message MUST be <a href="#per-origin-per-profile-identifiers">distinctive per origin and profile</a> and MUST NOT be <a def-id="distinctive-permanent-identifier-maybe-plural"></a>. </td></tr></tbody></table></div> @@ -2391,11 +2512,58 @@ <h4>Session Closed</h4> <li><p>If <var>promise</var> is resolved, abort these steps.</p></li> <!-- Handle the case that this algorithm is reached by a path other than close(). In all cases, the value is set before the algorithms below are run. --> <li><p>Set the <var>session</var>'s <var>closing or closed</var> value to true.</p></li> + <li> + <p> + If <var>session</var>'s <var>session type</var> is <a def-id="persistent-usage-record-session"></a>, execute the following steps: + </p> + <ol> + <li><p>Let <var>cdm</var> be the CDM instance represented by <var>session</var>'s <var>cdm instance</var> value.</p></li> + <li> + <p>Use <var>cdm</var> to store <var>session</var>'s <var>record of key usage</var>, if it exists.</p> + <div class="note"> + <p> + The <var>record of key usage</var> may not exist if no keys have been used in the session or if it has been deleted as + a result of the <a def-id="update"></a> method processing an acknowledgement of the <a def-id="record-of-key-usage"></a>. + </p> + <p> + Since it has no effects observable to the document, this step may be run asynchronously, including after the document has unloaded. + </p> + </div> + </li> + </ol> + + </li> <li><p>Run the <a def-id="update-key-statuses-algorithm"></a> algorithm on the <var>session</var>, providing an empty sequence.</p></li> <li><p>Run the <a def-id="update-expiration-algorithm"></a> algorithm on the <var>session</var>, providing <code>NaN</code>.</p></li> <li><p>Resolve <var>promise</var>.</p></li> </ol> </section> + <section id="media-key-session-destroyed"> + <h4>MediaKeySession Destroyed</h4> + <p> + The MediaKeySession Destroyed algorithm performs steps that are necessary when a <a>MediaKeySession</a> that is not <a def-id="media-key-session-closed"></a> is destroyed. + </p> + <p>The following steps are run in parallel to the main event loop:</p> + <ol> + <li><p>Let <var>session</var> be the associated <a>MediaKeySession</a> object.</p></li> + <li><p>Let <var>cdm</var> be the CDM instance represented by <var>session</var>'s <var>cdm instance</var> value.</p></li> + <li> + <p>Use <var>cdm</var> to execute the following steps:</p> + <ol> + <li><p>Close the <a href="#key-session">session</a> associated with <var>session</var>.</p></li> + <li> + <p> + If <var>session</var>'s <var>session type</var> is <a def-id="persistent-usage-record-session"></a>, + store <var>session</var>'s <var>record of key usage</var>, if it exists. + </p> + <p class="note"> + Since it has no effects observable to the document, this step may be run asynchronously, including after the document has unloaded. + </p> + </li> + </ol> + </li> + </ol> + </section> <section id="monitor-cdm"> <h4>Monitor for CDM State Changes</h4> <p> @@ -2536,14 +2704,14 @@ <h3>Session Storage and Persistence</h3> <p>This section provides an overview of session storage and persistence that complements the algorithms.</p> <p>The following requirements apply in addition to those in <a def-id="media-keys-storage"></a>.</p> <p>If the result of running the <a def-id="is-persistent-session-type-algorithm"></a> algorithm on this object's <var>session type</var> is <code>false</code>, the user agent and CDM MUST NOT persist a record of or data related to the session at any point. - This includes license(s), key(s), <a def-id="record-of-license-destruction-maybe-plural"></a>, and the <a def-id="session-id"></a>. + This includes license(s), key(s), <a def-id="record-of-license-destruction-maybe-plural"></a>, <a def-id="record-of-key-usage-maybe-plural"></a>, and the <a def-id="session-id"></a>. </p> <p>The remainder of this section applies to session types for which the <a def-id="is-persistent-session-type-algorithm"></a> algorithm returns <code>true</code>.</p> <p>The CDM SHOULD NOT store session data, including the Session ID, until <a def-id="update"></a> is called the first time. Specifically, the CDM SHOULD NOT store session data during the <a def-id="generateRequest"></a> algorithm. This ensures that the application is aware of the session and knows it needs to eventually remove it. </p> - <p><em>All</em> data associated with a session MUST be cleared when the session is cleared, such as in <a def-id="update"></a> when processing a <a def-id="record-of-license-destruction"></a> acknowledgement. + <p><em>All</em> data associated with a session MUST be cleared when the session is cleared, such as in <a def-id="update"></a> when processing a <a def-id="record-of-license-destruction"></a> acknowledgement or <a def-id="record-of-key-usage"></a> acknowledgement. See <a href="#persistent-state-requirements">Persistent Data</a>. </p> <p>The CDM MUST ensure that data for a given session is only present in one <a>MediaKeySession</a> object that is not @@ -2894,6 +3062,28 @@ <h4>Attempt to Decrypt</h4> <li><p>If the status of any of the <var>available keys</var> changed as the result of running the preceding step, <a def-id="queue-a-task"></a> to run the <a def-id="update-key-statuses-algorithm"></a> algorithm on each affected <var>session</var>, providing all <a def-id="key-id">key ID(s)</a> in the session along with the appropriate <a>MediaKeyStatus</a> value(s) for each.</p></li> <li><p>If <var>block key</var> is not null, run the following steps:</p> <ol> + <li> + <p>If <var>session</var>'s <var>session type</var> is <a def-id="persistent-usage-record-session"></a>, run the following steps:</p> + <ol> + <li> + <p>Let <var>usage</var> be <var>session</var>'s <var>record of key usage</var>.</p> + </li> + <li> + <p> + If the <var>first decrypt time</var> of <var>usage</var> is <code>null</code>, set the <var>first decrypt time</var> of <var>usage</var> to the current time, accurate to within <a def-id="key-usage-accuracy"></a>. + </p> + </li> + <li> + <p> + Set the <var>latest decrypt time</var> of <var>usage</var> to the current time, accurate to within <a def-id="key-usage-accuracy"></a>. + </p> + </li> + </ol> + <p class="note"> + Implementations MAY optimize the times at which this step is executed provided the recorded key usage times remain + accurate to within <var>key usage accuracy</var>. + </p> + </li> <li><p>Use the <var>cdm</var> to decrypt <var>block</var> using <var>block key</var>.</p></li> <li><p>Follow the steps for the first matching condition from the following list:</p> <dl class="switch"> @@ -3104,7 +3294,7 @@ <h3>Messages and Communication</h3> <section id="persistent-state-requirements"> <h3>Persistent Data</h3> <p> - Persistent Data includes all data stored by the CDM, or by the User Agent on behalf of the CDM, that exists after the destruction of the <a>MediaKeys</a> object. Specifically, it includes any identifiers (including <a def-id="distinctive-identifier-maybe-plural"></a>), licenses, keys, key IDs, or <a def-id="records-of-license-destruction"></a> stored by the CDM or by the User Agent on behalf of the CDM. + Persistent Data includes all data stored by the CDM, or by the User Agent on behalf of the CDM, that exists after the destruction of the <a>MediaKeys</a> object. Specifically, it includes any identifiers (including <a def-id="distinctive-identifier-maybe-plural"></a>), licenses, keys, key IDs, <a def-id="records-of-license-destruction"></a>, or <a def-id="records-of-key-usage"></a> stored by the CDM or by the User Agent on behalf of the CDM. </p> <section id="use-origin-specific-key-system-storage"> <h3>Use origin-specific and browsing profile-specific Key System storage</h3> @@ -3519,6 +3709,8 @@ <h4>Capabilities</h4> </ol> </li> <li><p>The <a def-id="persistent-license-session"></a> <a>MediaKeySessionType</a>: Implementations MAY support this type.</p></li> + <li><p>The <a def-id="persistent-usage-record-session"></a> <a>MediaKeySessionType</a>: Implementations MAY support this type.</p></li> + <li><p>The <a def-id="setServerCertificate"></a> method: Not supported.</p></li> <li><p>The <a def-id="setMediaKeys"></a> method: Implementations MAY support associating the <a>MediaKeys</a> object with more than one <a def-id="htmlmediaelement"></a>.</p></li> </ul> @@ -3559,6 +3751,12 @@ <h4>Behavior</h4> the <var>record of license destruction</var> is a JSON object encoded in UTF-8 as described in <a href="#clear-key-release-format">License Release Format</a>. </p> </li> + <li> + <p> + For sessions of type <a def-id="persistent-usage-record-session"></a>, in the <a def-id="remove"></a> and <a def-id="load"></a> algorithms, the <var>message</var> reflecting + the object's <var>record of key usage</var> is a JSON object encoded in UTF-8 as described in <a href="#clear-key-release-format">License Release Format</a>. + </p> + </li> <li> <p> The <a def-id="keyStatuses"></a> attribute method initially contains all key IDs that have been provided via <a def-id="update"></a>, with status <a def-id="status-usable"></a>. @@ -3650,12 +3848,23 @@ <h5>Example</h5> <h4>License Release Format</h4> <p>This section describes the format of the license release message to be provided via the <a def-id="message-event-message-attribute"></a> attribute of the <a def-id="message"></a> event.</p> <p> - The format is a JSON object. For sessions of type <a def-id="persistent-license-session"></a>, the object shall contain the following member: + The format is a JSON object. For sessions of type <a def-id="persistent-license-session"></a> and <a def-id="persistent-usage-record-session"></a>, + the object shall contain the following member: </p> <dl> <dt>"kids"</dt> <dd>An array of <a def-id="key-id">key IDs</a>. Each element of the array is the base64url encoding of the octet sequence containing the key ID value.</dd> </dl> + <p> + For sessions of type <a def-id="persistent-usage-record-session"></a> the object shall also contain the following members: + </p> + <dl> + <dt>"firstTime"</dt> + <dd>The <a def-id="first-decryption-time"></a> expressed as a number giving the time, in milliseconds since 01 January, 1970 UTC.</dd> + <dt>"latestTime"</dt> + <dd>The <a def-id="latest-decryption-time"></a> expressed as a number giving the time, in milliseconds since 01 January, 1970 UTC.</dd> + </dl> + <p>When contained in the ArrayBuffer <a def-id="message-event-message-attribute"></a> attribute of a <a>MediaKeyMessageEvent</a> object, the JSON string is encoded in UTF-8 as specified in the Encoding specification [[!ENCODING]]. Applications MAY decode the contents of the ArrayBuffer to a JSON string using the <a def-id="interface-textdecoder"></a> [[!ENCODING]]. </p> @@ -3669,6 +3878,20 @@ <h5>Example message reflecting a <a def-id="record-of-license-destruction"></a>< <pre class="example highlight">{ "kids": [ "LwVHf8JLtPrv2GUXFW2v_A", "0DdtU9od-Bh5L3xbv0Xf_A" ] } +</pre> + </section> + + <section id="clear-key-release-format-example-2" class="informative"> + <h5>Example message reflecting a <a def-id="record-of-key-usage"></a></h5> + <p> + The following example is a license release for a <a def-id="persistent-usage-record-session"></a> session that contained two keys. + (Line breaks are for readability only.) + </p> + <pre class="example highlight">{ + "kids": [ "LwVHf8JLtPrv2GUXFW2v_A", "0DdtU9od-Bh5L3xbv0Xf_A" ], + "firstTime" : 1430425323757, + "latestTime" : 1430425383757 +} </pre> </section> </section> @@ -3921,8 +4144,8 @@ <h4>Mitigations</h4> <h3>User Tracking</h3> <section class="informative"> <h4>Concerns</h4> - <p>A third-party host (or any entity, such as an advertiser, capable of getting content distributed to multiple sites) could use a <a def-id="distinctive-identifier"></a> or persistent data, including licenses, keys, key IDs, or - <a def-id="records-of-license-destruction"></a>, stored by or on behalf of the <a def-id="cdm"></a> to track a user across multiple sessions (including across <a def-id="origin">origins</a> and <a def-id="browsing-profile">browsing profiles</a>), building a profile of the user's activities or interests. Such tracking would undermine the privacy protections provided by the rest of the web platform and could, for example, enable highly-targeted advertising not otherwise possible. + <p>A third-party host (or any entity, such as an advertiser, capable of getting content distributed to multiple sites) could use a <a def-id="distinctive-identifier"></a> or persistent data, including licenses, keys, key IDs, <a def-id="records-of-license-destruction"></a>, or <a def-id="records-of-key-usage"></a>, stored by or on behalf of the <a def-id="cdm"></a> to track a user across multiple sessions (including across <a def-id="origin">origins</a> and <a def-id="browsing-profile">browsing profiles</a>), building a profile of the user's activities or interests. + Such tracking would undermine the privacy protections provided by the rest of the web platform and could, for example, enable highly-targeted advertising not otherwise possible. In conjunction with a site that is aware of the user's real identity (for example, a content provider or e-commerce site that requires authenticated credentials), this could allow oppressive groups to target individuals with greater accuracy than in a world with purely anonymous web usage. </p> @@ -3931,11 +4154,11 @@ <h4>Concerns</h4> <li><p><a def-id="distinctive-identifier-maybe-plural"></a></p></li> <li><p><a def-id="distinctive-permanent-identifier-maybe-plural"></a></p></li> <li><p>Origins visited (via stored or in-memory data, permissions, etc.)</p></li> - <li><p>Content viewed (via stored or in-memory licenses, keys, key IDs, <a def-id="records-of-license-destruction"></a>, etc.)</p></li> + <li><p>Content viewed (via stored or in-memory licenses, keys, key IDs, <a def-id="records-of-license-destruction"></a>, <a def-id="records-of-key-usage"></a>, etc.)</p></li> </ul> <p>This specification presents a specific concern because such information is commonly stored outside the user agent (and associated <a def-id="browsing-profile"></a> storage), often in the CDM.</p> - <p>Since the content of licenses and <a def-id="records-of-license-destruction"></a> are Key System-specific and since key IDs may contain any value, these data items could be abused to store user-identifying information.</p> + <p>Since the content of licenses, <a def-id="records-of-license-destruction"></a>, and <a def-id="records-of-key-usage"></a> are Key System-specific and since key IDs may contain any value, these data items could be abused to store user-identifying information.</p> <p>Key Systems may access or create persistent or semi-persistent identifier(s) for a device or user of a device. In some cases these identifiers may be bound to a specific device in a secure manner. diff --git a/encrypted-media.js b/encrypted-media.js index 0a646c49..793cd382 100644 --- a/encrypted-media.js +++ b/encrypted-media.js @@ -173,9 +173,14 @@ 'distinctive-identifiers': { func: term_helper, fragment: 'distinctive-identifier', link_text: 'Distinctive Identifiers' }, 'expiration-time': { func: term_helper, fragment: 'expiration-time', link_text: 'expiration time' }, 'browsing-profile': { func: term_helper, fragment: 'browsing-profile', link_text: 'browsing profile' }, + 'record-of-key-usage': { func: term_helper, fragment: 'record-of-key-usage', link_text: 'record of key usage' }, + 'records-of-key-usage': { func: term_helper, fragment: 'record-of-key-usage', link_text: 'records of key usage' }, + 'record-of-key-usage-maybe-plural': { func: term_helper, fragment: 'record-of-key-usage', link_text: 'record(s) of key usage' }, 'record-of-license-destruction': { func: term_helper, fragment: 'record-of-license-destruction', link_text: 'record of license destruction' }, 'records-of-license-destruction': { func: term_helper, fragment: 'record-of-license-destruction', link_text: 'records of license destruction' }, 'record-of-license-destruction-maybe-plural': { func: term_helper, fragment: 'record-of-license-destruction', link_text: 'record(s) of license destruction' }, + 'first-decryption-time': { func: term_helper, fragment: 'first-decryption-time', link_text: 'first decryption time' }, + 'latest-decryption-time': { func: term_helper, fragment: 'latest-decryption-time', link_text: 'latest decryption time' }, 'time': { func: term_helper, fragment: 'time', link_text: 'time' }, 'valid-media-mime-type': { func: term_helper, fragment: 'valid-media-mime-type', link_text: 'valid media MIME type' }, @@ -206,6 +211,8 @@ 'temporary-session': { func: idlref_helper, fragment: 'idl-def-MediaKeySessionType.temporary', link_text: '"temporary"', }, 'persistent-license-session': { func: idlref_helper, fragment: 'idl-def-MediaKeySessionType.persistent-license', link_text: '"persistent-license"', }, + 'persistent-usage-record-session': { func: idlref_helper, fragment: 'idl-def-MediaKeySessionType.persistent-usage-record', link_text: '"persistent-usage-record"', }, + 'key-usage-accuracy': { func: var_helper, fragment: 'key-usage-accuracy', link_text: 'key usage accuracy' }, 'is-persistent-session-type-algorithm': { func: term_helper, fragment: 'is-persistent-session-type', link_text: 'Is persistent session type?', }, 'cdm-unavailable-algorithm': { func: term_helper, fragment: 'cdm-unavailable', link_text: 'CDM Unavailable', }, @@ -247,6 +254,7 @@ 'update-expiration-algorithm': { func: term_helper, fragment: 'update-expiration', link_text: 'Update Expiration', }, 'resume-playback-algorithm': { func: term_helper, fragment: 'resume-playback', link_text: 'Attempt to Resume Playback If Necessary', }, 'wait-for-key-algorithm': { func: term_helper, fragment: 'wait-for-key', link_text: 'Wait for Key', }, + 'media-key-session-destroyed-algorithm' : { func: term_helper, fragment: 'media-key-session-destroyed', link_text: 'MediaKeySession destroyed', }, 'media-key-session-closed' : { func: term_helper, fragment: 'media-key-session-closed', link_text: 'closed', }, diff --git a/index.html b/index.html index 52c238c8..b973c3c2 100644 --- a/index.html +++ b/index.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html dir="ltr" lang="en"> +<html lang="en" dir="ltr"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> @@ -1198,6 +1198,26 @@ "0": {}, "length": 1 }], + "persistent-usage-record": [{ + "0": {}, + "length": 1 + }], + "record of key usage": [{ + "0": {}, + "length": 1 + }], + "first decryption time": [{ + "0": {}, + "length": 1 + }], + "latest decryption time": [{ + "0": {}, + "length": 1 + }], + "key usage accuracy": [{ + "0": {}, + "length": 1 + }], "createsession": [{ "0": {}, "length": 1 @@ -1723,8 +1743,8 @@ "publisher": "W3C" } }, - "publishISODate": "2017-09-14T00:00:00.000Z", - "generatedSubtitle": "Editor's Draft 14 September 2017" + "publishISODate": "2017-09-19T00:00:00.000Z", + "generatedSubtitle": "Editor's Draft 19 September 2017" } </script> <meta name="generator" content="ReSpec 16.2.2"> @@ -1734,11 +1754,11 @@ <body aria-busy="false" class="h-entry" id="respecDocument"> <div class="head" role="contentinfo" id="respecHeader"> <p> - <a class="logo" href="https://www.w3.org/"><img src="https://www.w3.org/StyleSheets/TR/2016/logos/W3C" alt="W3C" width="72" height="48"></a> + <a class="logo" href="https://www.w3.org/"><img width="72" height="48" src="https://www.w3.org/StyleSheets/TR/2016/logos/W3C" alt="W3C"></a> </p> <p></p> <h1 class="title p-name" id="title">Encrypted Media Extensions</h1> - <h2 id="w3c-editor's-draft-14-september-2017"><abbr title="World Wide Web Consortium">W3C</abbr> Editor's Draft <time class="dt-published" datetime="2017-09-14">14 September 2017</time></h2> + <h2 id="w3c-editor's-draft-19-september-2017"><abbr title="World Wide Web Consortium">W3C</abbr> Editor's Draft <time class="dt-published" datetime="2017-09-19">19 September 2017</time></h2> <dl> <dt>This version:</dt> <dd><a class="u-url" href="https://w3c.github.io/encrypted-media/">https://w3c.github.io/encrypted-media/</a></dd> @@ -1883,7 +1903,8 @@ <h2 class="introductory" id="table-of-contents">Table of Contents</h2> <li class="tocline"><a href="#update-key-statuses" class="tocxref"><span class="secno">6.4.2 </span>Update Key Statuses</a></li> <li class="tocline"><a href="#update-expiration" class="tocxref"><span class="secno">6.4.3 </span>Update Expiration</a></li> <li class="tocline"><a href="#session-closed" class="tocxref"><span class="secno">6.4.4 </span>Session Closed</a></li> - <li class="tocline"><a href="#monitor-cdm" class="tocxref"><span class="secno">6.4.5 </span>Monitor for CDM State Changes</a></li> + <li class="tocline"><a href="#media-key-session-destroyed" class="tocxref"><span class="secno">6.4.5 </span>MediaKeySession Destroyed</a></li> + <li class="tocline"><a href="#monitor-cdm" class="tocxref"><span class="secno">6.4.6 </span>Monitor for CDM State Changes</a></li> </ol> </li> <li class="tocline"><a href="#exceptions" class="tocxref"><span class="secno">6.5 </span>Exceptions</a></li> @@ -1978,6 +1999,7 @@ <h2 class="introductory" id="table-of-contents">Table of Contents</h2> <li class="tocline"><a href="#clear-key-release-format" class="tocxref"><span class="secno">9.1.5 </span>License Release Format</a> <ol class="toc"> <li class="tocline"><a href="#clear-key-release-format-example-1" class="tocxref"><span class="secno">9.1.5.1 </span>Example message reflecting a <span def-id="record-of-license-destruction" class="formerLink"></span></a></li> + <li class="tocline"><a href="#clear-key-release-format-example-2" class="tocxref"><span class="secno">9.1.5.2 </span>Example message reflecting a <span def-id="record-of-key-usage" class="formerLink"></span></a></li> </ol> </li> <li class="tocline"><a href="#clear-key-release-ack-format" class="tocxref"><span class="secno">9.1.6 </span>License Release Acknowledgement Format</a> @@ -2204,8 +2226,7 @@ <h2 id="x2.-definitions"><span class="secno">2. </span>Definitions</h2> <a href="#decryption-key">key</a> is usable or its value is known. Known keys are exposed via the <code><a href="#dom-mediakeysession-keystatuses">keyStatuses</a></code> attribute. </p> - <p>Keys are considered known even after they become unusable, such as due to <a href="#expiration-time">expiration</a> or if they are removed but a <a href="#record-of-license-destruction">record of license destruction</a> is available. Keys - only become unknown when they are explicitly removed from a session and any license release message is acknowledged. + <p>Keys are considered known even after they become unusable, such as due to <a href="#expiration-time">expiration</a> or if they are removed but a <a href="#record-of-license-destruction">record of license destruction</a> or <a href="#record-of-key-usage">record of key usage</a> is available. Keys only become unknown when they are explicitly removed from a session and any license release message is acknowledged. </p> <div class="note"> @@ -3827,7 +3848,8 @@ <h2 id="x5.-mediakeys-interface"><span class="secno">5. </span><dfn data-dfn-for <div> <pre class="def idl"><span class="idlEnum" id="idl-def-mediakeysessiontype" data-idl="" data-title="MediaKeySessionType">enum <span class="idlEnumID"><a data-lt="MediaKeySessionType" href="#dom-mediakeysessiontype" class="internalDFN" data-link-type="dfn" data-for=""><code>MediaKeySessionType</code></a></span> { <a href="#dom-mediakeysessiontype-temporary" class="idlEnumItem">"temporary"</a>, - <a href="#dom-mediakeysessiontype-persistent-license" class="idlEnumItem">"persistent-license"</a> + <a href="#dom-mediakeysessiontype-persistent-license" class="idlEnumItem">"persistent-license"</a>, + <a href="#dom-mediakeysessiontype-persistent-usage-record" class="idlEnumItem">"persistent-usage-record"</a> };</span></pre> </div> <p>The <dfn data-dfn-for="" data-dfn-type="dfn" id="dom-mediakeysessiontype" data-idl="" data-title="MediaKeySessionType"><code>MediaKeySessionType</code></dfn> enumeration is defined as follows:</p> @@ -3864,6 +3886,57 @@ <h2 id="x5.-mediakeys-interface"><span class="secno">5. </span><dfn data-dfn-for </p> </td> </tr> + <tr> + <td><dfn data-dfn-for="mediakeysessiontype" data-dfn-type="dfn" id="dom-mediakeysessiontype-persistent-usage-record" data-idl="" data-title="persistent-usage-record"><code id="idl-def-MediaKeySessionType.persistent-usage-record">persistent-usage-record</code></dfn></td> + <td> + <p> + A session for which the license and key(s) are not persisted and for which a <a href="#record-of-key-usage">record of key usage</a> is persisted when the keys available within the session are destroyed. The <dfn id="record-of-key-usage" + data-dfn-type="dfn">record of key usage</dfn> consists of: + </p> + <ul> + <li> + <p>A record of the <a href="#decryption-key-id">key IDs</a> of all the key(s) that were at any time <a href="#known-key">known</a> to the session,</p> + </li> + <li> + <p> + <var>first decryption time</var> - The <dfn id="first-decryption-time" data-dfn-type="dfn">first decryption time</dfn>, defined as the time at which the session was first used to decrypt content, accurate to <var><var><a href="#key-usage-accuracy">key usage accuracy</a></var></var> + and + </p> + </li> + <li> + <p> + <var>latest decryption time</var> - The <dfn id="latest-decryption-time" data-dfn-type="dfn">latest decryption time</dfn>, defined as the latest time at which the session was used to decrypt content, accurate to + <var><var><a href="#key-usage-accuracy">key usage accuracy</a></var></var>. + </p> + </li> + </ul> + <p> + A <code><a href="#dom-evt-message">message</a></code> of type <code><a href="#idl-def-MediaKeyMessageType.license-release">"license-release"</a></code> containing the <a href="#record-of-key-usage">record of key usage</a> will be generated each time <code><a href="#dom-mediakeysession-remove">remove()</a></code> is called, until the record is acknowledged by a response passed to <code><a href="#dom-mediakeysession-update">update()</a></code>. + </p> + <p> + The <dfn id="key-usage-accuracy" data-dfn-type="dfn"><var>key usage accuracy</var></dfn> is implementation-dependant but <em class="rfc2119" title="SHALL NOT">SHALL NOT</em> be greater than 60 seconds. + </p> + <div class="note"> + <div class="note-title marker" aria-level="3" role="heading" id="h-note54"><span>Note</span></div> + <p class=""> + Because the license and keys are not persisted, this record implicitly proves that the keys are no longer available in the session. + </p> + </div> + <div class="note"> + <div class="note-title marker" aria-level="3" role="heading" id="h-note55"><span>Note</span></div> + <p class=""> + User agents <em class="rfc2119" title="MAY">MAY</em> implement this mechanism by means other than persisting data on key destruction - for example by persisting data during playback which is later used to infer the + fact of key destruction - provided the observable behavior is compliant to this specification. + </p> + </div> + <p> + The session <em class="rfc2119" title="MUST">MUST</em> be loadable via its <a href="#session-id">Session ID</a> once <code><a href="#dom-mediakeysession-update">update()</a></code> is called successfully. The application + is responsible for managing any such storage that may be generated by the CDM. See <a href="#session-storage">Session Storage and Persistence</a>. Can only be created if the configuration associated with the <a href="#dom-mediakeysystemaccess" + class="internalDFN" data-link-type="dfn"><code>MediaKeySystemAccess</code></a> object that created this object has a <code><a href="#dom-mediakeysystemconfiguration-persistentstate">persistentState</a></code> value of <code><a href="#idl-def-MediaKeysRequirement.required">"required"</a></code>. + Support for this session type is <em class="rfc2119" title="OPTIONAL">OPTIONAL</em>. + </p> + </td> + </tr> </tbody> </table> </div> @@ -3912,7 +3985,7 @@ <h3 id="methods-1">Methods</h3> <p>If this object's <var>supported session types</var> value does not contain <var>sessionType</var>, <a href="https://heycam.github.io/webidl/#dfn-throw">throw</a> [<cite><a class="bibref" href="#bib-WEBIDL">WEBIDL</a></cite>] a <code><a href="#dfn-NotSupportedError">NotSupportedError</a></code>.</p> <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note54"><span>Note</span></div> + <div class="note-title marker" aria-level="4" role="heading" id="h-note56"><span>Note</span></div> <p class=""><var>sessionType</var> values for which the <a href="#is-persistent-session-type">Is persistent session type?</a> algorithm returns <code>true</code> will fail if this object's <var>persistent state allowed</var> value is <code>false</code>.</p> </div> @@ -3920,7 +3993,7 @@ <h3 id="methods-1">Methods</h3> <li> <p>If the implementation does not support <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> operations in the current state, <a href="https://heycam.github.io/webidl/#dfn-throw">throw</a> [<cite><a class="bibref" href="#bib-WEBIDL">WEBIDL</a></cite>] an <code><a href="#dfn-InvalidStateError">InvalidStateError</a></code>.</p> <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note55"><span>Note</span></div> + <div class="note-title marker" aria-level="4" role="heading" id="h-note57"><span>Note</span></div> <p class="">Some implementations are unable to execute <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> algorithms until this <a href="#dom-mediakeys" class="internalDFN" data-link-type="dfn"><code>MediaKeys</code></a> object is associated with a media element using <code><a href="#dom-htmlmediaelement-setmediakeys">setMediaKeys()</a></code>. This step enables applications to detect this uncommon behavior before attempting to perform such operations. @@ -3979,7 +4052,7 @@ <h3 id="methods-1">Methods</h3> <p id="server-certificate">Provides a server certificate to be used to encrypt messages to the license server.</p> <p>Key Systems that use such certificates <em class="rfc2119" title="MUST">MUST</em> also support requesting the certificate from the server via the <a href="#queue-message">Queue a "message" Event</a> algorithm.</p> <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note56"><span>Note</span></div> + <div class="note-title marker" aria-level="4" role="heading" id="h-note58"><span>Note</span></div> <p class="">This method allows an application to proactively provide a server certificate to implementations that support it to avoid the additional round trip should the CDM request it. It is intended as an optimization, and applications are not required to use it. </p> @@ -4030,7 +4103,7 @@ <h3 id="methods-1">Methods</h3> <li> <p>Let <var>sanitized certificate</var> be a validated and/or sanitized version of <var>certificate</var>.</p> <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note57"><span>Note</span></div> + <div class="note-title marker" aria-level="4" role="heading" id="h-note59"><span>Note</span></div> <p class="">The user agent should thoroughly validate the certificate before passing it to the CDM. This may include verifying values are within reasonable limits, stripping irrelevant data or fields, pre-parsing it, sanitizing it, and/or generating a fully sanitized version. The user agent should check that the length and values of fields are reasonable. Unknown fields should be rejected or removed. </p> @@ -4074,6 +4147,8 @@ <h4 id="x5.1.1-is-persistent-session-type?"><span class="secno">5.1.1 </span>Is <dd>Return <code>false</code>.</dd> <dt><code><a href="#idl-def-MediaKeySessionType.persistent-license">"persistent-license"</a></code></dt> <dd>Return <code>true</code>.</dd> + <dt><code><a href="#idl-def-MediaKeySessionType.persistent-usage-record">"persistent-usage-record"</a></code></dt> + <dd>Return <code>true</code>.</dd> </dl> </li> </ol> @@ -4133,7 +4208,7 @@ <h2 id="x6.-mediakeysession-interface"><span class="secno">6. </span><dfn data-d class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object that is no longer accessible <em class="rfc2119" title="SHALL NOT">SHALL NOT</em> receive further events and <em class="rfc2119" title="MAY">MAY</em> be destroyed. </p> <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note58"><span>Note</span></div> + <div class="note-title marker" aria-level="3" role="heading" id="h-note60"><span>Note</span></div> <p class=""> The above rule implies that the CDM instance must not be destroyed until all <a href="#dom-mediakeys" class="internalDFN" data-link-type="dfn"><code>MediaKeys</code></a> objects and all <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> objects associated with the CDM instance are destroyed. @@ -4144,11 +4219,11 @@ <h2 id="x6.-mediakeysession-interface"><span class="secno">6. </span><dfn data-d title="SHALL">SHALL</em> close the <a href="#key-session">key session</a> associated with the object. </p> <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note59"><span>Note</span></div> + <div class="note-title marker" aria-level="3" role="heading" id="h-note61"><span>Note</span></div> <p class="">Closing the key session results in the destruction of any license(s) and key(s) that have not been explicitly stored.</p> </div> <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note60"><span>Note</span></div> + <div class="note-title marker" aria-level="3" role="heading" id="h-note62"><span>Note</span></div> <p class=""> Exactly when the key session is closed is an implementation detail, and applications <em class="rfc2119" title="SHOULD NOT">SHOULD NOT</em> rely on specific timing. <!-- TODO: Replace and/or expand on this with an implementation of Issue #360. --> @@ -4156,7 +4231,10 @@ <h2 id="x6.-mediakeysession-interface"><span class="secno">6. </span><dfn data-d be resolved. </p> </div> - + <p> + If a <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object becomes inaccessible to the page and is not <a href="#media-key-session-closed">closed</a>, the User Agent + <em class="rfc2119" title="MUST">MUST</em> run the <a href="#media-key-session-destroyed">MediaKeySession destroyed</a> algorithm before User Agent state associated with the <a href="#key-session">session</a> is deleted. + </p> <p>For methods that return a promise, all errors are reported asynchronously by rejecting the returned Promise. This includes [<cite><a class="bibref" href="#bib-WEBIDL">WEBIDL</a></cite>] type mapping errors.</p> <p>The following steps of an algorithm are always aborted when rejecting a promise.</p> @@ -4187,7 +4265,7 @@ <h3 id="attributes-0">Attributes</h3> <dd> <p>The <a href="#expiration-time">expiration time</a> for all key(s) in the session, or <code>NaN</code> if no such time exists or if the license explicitly never expires, as determined by the CDM.</p> <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note61"><span>Note</span></div> + <div class="note-title marker" aria-level="4" role="heading" id="h-note63"><span>Note</span></div> <p class="">This value <em class="rfc2119" title="MAY">MAY</em> change during the session lifetime, such as when an action triggers the start of a window.</p> </div> </dd><dt><dfn data-dfn-for="mediakeysession" data-dfn-type="dfn" id="dom-mediakeysession-closed" data-idl="" data-title="closed"><code>closed</code></dfn> of type <span class="idlAttrType">Promise<void></span>, readonly </dt> @@ -4199,7 +4277,7 @@ <h3 id="attributes-0">Attributes</h3> unique key ID. </p> <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note62"><span>Note</span></div> + <div class="note-title marker" aria-level="4" role="heading" id="h-note64"><span>Note</span></div> <p class="">The map entries and their values may be updated whenever the event loop spins. The map <em class="rfc2119" title="MUST NOT">MUST NOT</em> ever be inconsistent or partially updated, but it may change between accesses if the event loop spins in between the accesses. Key IDs may be added as the result of a <code><a href="#dom-mediakeysession-load">load()</a></code> or <code><a href="#dom-mediakeysession-update">update()</a></code> call. Key IDs may be removed as the result of a <code><a href="#dom-mediakeysession-update">update()</a></code> call that removes knowledge of existing keys (or replaces the existing set of keys with a new set). Key IDs <em class="rfc2119" @@ -4207,7 +4285,7 @@ <h3 id="attributes-0">Attributes</h3> </p> </div> <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note63"><span>Note</span></div> + <div class="note-title marker" aria-level="4" role="heading" id="h-note65"><span>Note</span></div> <p class=""> Some older platforms may contain Key System implementations that do not expose key IDs, making it impossible to provide a compliant user agent implementation. To maximize interoperability, user agent implementations exposing such CDMs <em @@ -4341,7 +4419,7 @@ <h3 id="methods-2">Methods</h3> <dd> <p>Let <var>requested license type</var> be a temporary non-persistable license.</p> <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note64"><span>Note</span></div> + <div class="note-title marker" aria-level="4" role="heading" id="h-note66"><span>Note</span></div> <p class="">The returned license must not be persistable or require persisting information related to it.</p> </div> </dd> @@ -4349,6 +4427,34 @@ <h3 id="methods-2">Methods</h3> <dd> <p>Let <var>requested license type</var> be a persistable license.</p> </dd> + <dt><code><a href="#idl-def-MediaKeySessionType.persistent-usage-record">"persistent-usage-record"</a></code></dt> + <dd> + <ol> + <li> + <p>Initialize this object's <var>record of key usage</var> as follows.</p> + <ul> + <li> + <p> + Set the list of <a href="#decryption-key-id">key IDs</a> <a href="#known-key">known</a> to the session to an empty list. + </p> + </li> + <li> + <p> + Set the <var>first decrypt time</var> to <code>null</code>. + </p> + </li> + <li> + <p> + Set the <var>latest decrypt time</var> to <code>null</code>. + </p> + </li> + </ul> + </li> + <li> + <p>Let <var>requested license type</var> be a non-persistable license that will persist a <a href="#record-of-key-usage">record of key usage</a>.</p> + </li> + </ol> + </dd> </dl> </li> @@ -4420,7 +4526,7 @@ <h3 id="methods-2">Methods</h3> <li> <p>Resolve <var>promise</var>.</p> <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note65"><span>Note</span></div> + <div class="note-title marker" aria-level="4" role="heading" id="h-note67"><span>Note</span></div> <p class="">Since promise handlers are queued as microtasks, these will be executed ahead of any events queued by the preceding steps.</p> </div> </li> @@ -4491,7 +4597,7 @@ <h3 id="methods-2">Methods</h3> <li> <p>Let <var>sanitized session ID</var> be a validated and/or sanitized version of <var>sessionId</var>.</p> <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note66"><span>Note</span></div> + <div class="note-title marker" aria-level="4" role="heading" id="h-note68"><span>Note</span></div> <p class="">The user agent should thoroughly validate the sessionId value before passing it to the CDM. At a minimum, this should include checking that the length and value are reasonable (e.g., not longer than tens of characters and alphanumeric). </p> @@ -4503,7 +4609,7 @@ <h3 id="methods-2">Methods</h3> <li> <p>If there is a <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object that is not <a href="#media-key-session-closed">closed</a> in this object's <a href="https://www.w3.org/TR/dom/#concept-document">Document</a> whose <code><a href="#dom-mediakeysession-sessionid">sessionId</a></code> attribute is <var>sanitized session ID</var>, reject <var>promise</var> with a <code><a href="#dfn-QuotaExceededError">QuotaExceededError</a></code>.</p> <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note67"><span>Note</span></div> + <div class="note-title marker" aria-level="4" role="heading" id="h-note69"><span>Note</span></div> <p class="">In other words, do not create a session if a non-closed session, regardless of type, already exists for this <var>sanitized session ID</var> in this browsing context.</p> </div> </li> @@ -4538,7 +4644,7 @@ <h3 id="methods-2">Methods</h3> <li> <p>If there is a <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object that is not <a href="#media-key-session-closed">closed</a> in any <a href="https://www.w3.org/TR/dom/#concept-document">Document</a> and that represents the <var>session data</var>, reject <var>promise</var> with a <code><a href="#dfn-QuotaExceededError">QuotaExceededError</a></code>.</p> <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note68"><span>Note</span></div> + <div class="note-title marker" aria-level="4" role="heading" id="h-note70"><span>Note</span></div> <p class="">In other words, do not create a session if a non-closed persistent session already exists for this <var>sanitized session ID</var> in any browsing context.</p> </div> </li> @@ -4592,7 +4698,7 @@ <h3 id="methods-2">Methods</h3> <li> <p>Resolve <var>promise</var> with <code>true</code>.</p> <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note69"><span>Note</span></div> + <div class="note-title marker" aria-level="4" role="heading" id="h-note71"><span>Note</span></div> <p class="">Since promise handlers are queued as microtasks, these will be executed ahead of any events queued by the preceding steps.</p> </div> </li> @@ -4655,7 +4761,7 @@ <h3 id="methods-2">Methods</h3> <li> <p>Let <var>sanitized response</var> be a validated and/or sanitized version of <var>response copy</var>.</p> <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note70"><span>Note</span></div> + <div class="note-title marker" aria-level="4" role="heading" id="h-note72"><span>Note</span></div> <p class="">The user agent should thoroughly validate the response before passing it to the CDM. This may include verifying values are within reasonable limits, stripping irrelevant data or fields, pre-parsing it, sanitizing it, and/or generating a fully sanitized version. The user agent should check that the length and values of fields are reasonable. Unknown fields should be rejected or removed. </p> @@ -4688,7 +4794,7 @@ <h3 id="methods-2">Methods</h3> <dt>If <var>sanitized response</var> contains a license or key(s)</dt> <dd> <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note71"><span>Note</span></div> + <div class="note-title marker" aria-level="4" role="heading" id="h-note73"><span>Note</span></div> <p class="">This includes an initial license, an updated license, and a license renewal message.</p> </div> <p>Process <var>sanitized response</var>, following the stipulation for the first matching condition from the following list:</p> @@ -4699,6 +4805,22 @@ <h3 id="methods-2">Methods</h3> <dd>Process <var>sanitized response</var>, storing the license/key(s) and related session data contained in <var>sanitized response</var>. Such data <em class="rfc2119" title="MUST">MUST</em> be stored such that only the <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> of this object's <a href="https://www.w3.org/TR/dom/#concept-document">Document</a> can access it. </dd> + <dt>If <var>sessionType</var> is <code><a href="#idl-def-MediaKeySessionType.persistent-usage-record">"persistent-usage-record"</a></code> and <var>sanitized response</var> contains a non-persistable license</dt> + <dd> + <p>Run the following steps:</p> + <ol> + <li> + <p> + Process <var>sanitized response</var>, not storing any session data. + </p> + </li> + <li> + <p> + If processing <var>sanitized response</var> results in the addition of keys to the set of <a href="#known-key">known keys</a>, add the <a href="#decryption-key-id">key IDs</a> of these keys to this object's <var>record of key usage</var>. + </p> + </li> + </ol> + </dd> <dt>Otherwise</dt> <dd> <p>Reject <var>promise</var> with a newly created <code><a href="#dfn-TypeError">TypeError</a></code>.</p> @@ -4708,15 +4830,15 @@ <h3 id="methods-2">Methods</h3> <p>State information, including keys, for each session <em class="rfc2119" title="MUST">MUST</em> be stored in such a way that closing one session does not affect the observable state in other session(s), even if they contain overlapping key IDs.</p> <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note72"><span>Note</span></div> + <div class="note-title marker" aria-level="4" role="heading" id="h-note74"><span>Note</span></div> <p class="">When <var>sanitized response</var> contains key(s) and/or related data, <var>cdm</var> will likely store (in memory) the key and related data indexed by key ID.</p> </div> <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note73"><span>Note</span></div> + <div class="note-title marker" aria-level="4" role="heading" id="h-note75"><span>Note</span></div> <p class="">The replacement algorithm within a session is <a href="#key-system">Key System</a>-dependent.</p> </div> <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note74"><span>Note</span></div> + <div class="note-title marker" aria-level="4" role="heading" id="h-note76"><span>Note</span></div> <p class="">It is <em class="rfc2119" title="RECOMMENDED">RECOMMENDED</em> that CDM implementations support a standard and reasonably high minimum number of keys per <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object, including a standard replacement algorithm, and a standard and reasonably high minimum number of <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> objects. This enables a reasonable number of key rotation algorithms to be implemented across user agents and may @@ -4733,7 +4855,26 @@ <h3 id="methods-2">Methods</h3> Close the <a href="#key-session">key session</a> and clear <em>all</em> stored session data associated with this object, including the <code><a href="#dom-mediakeysession-sessionid">sessionId</a></code> and <a href="#record-of-license-destruction">record of license destruction</a>. </p> <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note75"><span>Note</span></div> + <div class="note-title marker" aria-level="4" role="heading" id="h-note77"><span>Note</span></div> + <p class="">A subsequent call to <code><a href="#dom-mediakeysession-load">load()</a></code> with the value of this object's <code><a href="#dom-mediakeysession-sessionid">sessionId</a></code> would + fail because there is no data stored for that session ID.</p> + </div> + </li> + <li> + <p>Set <var>session closed</var> to true.</p> + </li> + </ol> + </dd> + <dt>If <var>sanitized response</var> contains a <a href="#record-of-key-usage">record of key usage</a> acknowledgement and <var>sessionType</var> is <code><a href="#idl-def-MediaKeySessionType.persistent-usage-record">"persistent-usage-record"</a></code></dt> + <dd> + <p>Run the following steps:</p> + <ol> + <li> + <p> + Close the <a href="#key-session">session</a> and clear <em>all</em> stored session data associated with this object, including the <code><a href="#dom-mediakeysession-sessionid">sessionId</a></code> and <a href="#record-of-key-usage">record of key usage</a>. + </p> + <div class="note"> + <div class="note-title marker" aria-level="4" role="heading" id="h-note78"><span>Note</span></div> <p class="">A subsequent call to <code><a href="#dom-mediakeysession-load">load()</a></code> with the value of this object's <code><a href="#dom-mediakeysession-sessionid">sessionId</a></code> would fail because there is no data stored for that session ID.</p> </div> @@ -4746,7 +4887,7 @@ <h3 id="methods-2">Methods</h3> <dt>Otherwise</dt> <dd>Process <var>sanitized response</var>, not storing any session data. <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note76"><span>Note</span></div> + <div class="note-title marker" aria-level="4" role="heading" id="h-note79"><span>Note</span></div> <p class="">For example, <var>sanitized response</var> may contain information that will be used to generate another <code><a href="#dom-evt-message">message</a></code> event. In this case, there is no need to verify the contents against the <var>sessionType</var>. </p> @@ -4807,7 +4948,7 @@ <h3 id="methods-2">Methods</h3> <li> <p>Resolve <var>promise</var>.</p> <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note77"><span>Note</span></div> + <div class="note-title marker" aria-level="4" role="heading" id="h-note80"><span>Note</span></div> <p class="">Since promise handlers are queued as microtasks, these will be executed ahead of any events queued by the preceding steps.</p> </div> </li> @@ -4823,7 +4964,7 @@ <h3 id="methods-2">Methods</h3> <dd> <p>Indicates that the application no longer needs the session and the CDM should release any resources associated with the session and close it. Persisted data should not be released or cleared.</p> <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note78"><span>Note</span></div> + <div class="note-title marker" aria-level="4" role="heading" id="h-note81"><span>Note</span></div> <p class="">The returned promise is resolved when the request has been processed, and the <code><a href="#dom-mediakeysession-closed">closed</a></code> attribute promise is resolved when the session is closed.</p> </div> @@ -4853,7 +4994,7 @@ <h3 id="methods-2">Methods</h3> <li> <p>Use <var>cdm</var> to close the <a href="#key-session">key session</a> associated with this object.</p> <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note79"><span>Note</span></div> + <div class="note-title marker" aria-level="4" role="heading" id="h-note82"><span>Note</span></div> <p class="">Closing the key session results in the destruction of any license(s) and key(s) that have not been explicitly stored.</p> </div> </li> @@ -4866,7 +5007,7 @@ <h3 id="methods-2">Methods</h3> <li> <p>Resolve <var>promise</var>.</p> <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note80"><span>Note</span></div> + <div class="note-title marker" aria-level="4" role="heading" id="h-note83"><span>Note</span></div> <p class="">Since promise handlers are queued as microtasks, these will be executed ahead of any events queued by the preceding steps.</p> </div> </li> @@ -4924,7 +5065,7 @@ <h3 id="methods-2">Methods</h3> Destroy the license(s) and/or key(s) associated with the session. </p> <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note81"><span>Note</span></div> + <div class="note-title marker" aria-level="4" role="heading" id="h-note84"><span>Note</span></div> <p class=""> This implies destruction of the license(s) and/or keys(s) whether they are in memory, persistent store or both. </p> @@ -4957,6 +5098,19 @@ <h3 id="methods-2">Methods</h3> </li> </ol> </dd> + <dt><code><a href="#idl-def-MediaKeySessionType.persistent-usage-record">"persistent-usage-record"</a></code></dt> + <dd> + <ol> + <li> + Store this object's <var>record of key usage</var>. + </li> + <li> + <p> + Let <var>message</var> be a message containing or reflecting this object's <var>record of key usage</var>. + </p> + </li> + </ol> + </dd> </dl> </li> </ol> @@ -4986,7 +5140,7 @@ <h3 id="methods-2">Methods</h3> <li> <p>Resolve <var>promise</var>.</p> <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note82"><span>Note</span></div> + <div class="note-title marker" aria-level="4" role="heading" id="h-note85"><span>Note</span></div> <p class="">Since promise handlers are queued as microtasks, these will be executed ahead of any events queued by the preceding steps.</p> </div> </li> @@ -5008,7 +5162,7 @@ <h3 id="x6.1-mediakeystatusmap-interface"><span class="secno">6.1 </span><dfn da <p>The MediaKeyStatusMap object is a read-only map of <a href="#decryption-key-id">key IDs</a> to the current status of the associated key.</p> <p>A key's status is independent of whether the key is currently being used and of media data.</p> <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note83"><span>Note</span></div> + <div class="note-title marker" aria-level="4" role="heading" id="h-note86"><span>Note</span></div> <p class="">For example, if a key has output requirements that cannot currently be met, the key's status should be <code><a href="#idl-def-MediaKeyStatus.output-downscaled">"output-downscaled"</a></code> or <code><a href="#idl-def-MediaKeyStatus.output-restricted">"output-restricted"</a></code>, as appropriate, regardless of whether that key has been or is currently needed to decrypt media data.</p> </div> @@ -5130,7 +5284,8 @@ <h4 id="methods-3">Methods</h4> <tr> <td><dfn data-dfn-for="mediakeystatus" data-dfn-type="dfn" id="dom-mediakeystatus-released" data-idl="" data-title="released"><code id="idl-def-MediaKeyStatus.released">released</code></dfn></td> <td> - The key itself is no longer available to the CDM, but information about the key, such as a <a href="#record-of-license-destruction">record of license destruction</a>, is available. + The key itself is no longer available to the CDM, but information about the key, such as a <a href="#record-of-license-destruction">record of license destruction</a> or <a href="#record-of-key-usage">record of key usage</a>, + is available. </td> </tr> <tr> @@ -5195,7 +5350,7 @@ <h3 id="x6.2-mediakeymessageevent"><span class="secno">6.2 </span><a href="#dom- </tr> <tr> <td><dfn data-dfn-for="mediakeymessagetype" data-dfn-type="dfn" id="dom-mediakeymessagetype-license-release" data-idl="" data-title="license-release"><code id="idl-def-MediaKeyMessageType.license-release">license-release</code></dfn></td> - <td>The message contains a <a href="#record-of-license-destruction">record of license destruction</a>.</td> + <td>The message contains a <a href="#record-of-license-destruction">record of license destruction</a> or <a href="#record-of-key-usage">record of key usage</a>.</td> </tr> <tr> <td><dfn data-dfn-for="mediakeymessagetype" data-dfn-type="dfn" id="dom-mediakeymessagetype-individualization-request" data-idl="" data-title="individualization-request"><code id="idl-def-MediaKeyMessageType.individualization-request">individualization-request</code></dfn></td> @@ -5260,7 +5415,7 @@ <h4 id="attributes-2">Attributes</h4> URL. </p> <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note84"><span>Note</span></div> + <div class="note-title marker" aria-level="5" role="heading" id="h-note87"><span>Note</span></div> <p class="">This attribute allows an application to differentiate messages without parsing the message. It is intended to enable optional application and/or server optimizations, but applications are not required to use it. </p> </div> @@ -5362,7 +5517,7 @@ <h4 id="x6.4.2-update-key-statuses"><span class="secno">6.4.2 </span>Update Key <a href="#dom-mediakeystatus" class="internalDFN" data-link-type="dfn"><code>MediaKeyStatus</code></a> pairs. </p> <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note85"><span>Note</span></div> + <div class="note-title marker" aria-level="5" role="heading" id="h-note88"><span>Note</span></div> <p class="">The algorithm is always run in a task.</p> </div> <p>The following steps are run:</p> @@ -5395,7 +5550,7 @@ <h4 id="x6.4.2-update-key-statuses"><span class="secno">6.4.2 </span>Update Key </li> </ol> <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note86"><span>Note</span></div> + <div class="note-title marker" aria-level="5" role="heading" id="h-note89"><span>Note</span></div> <p class="">The effect of this steps is that the contents of <var>session</var>'s <code><a href="#dom-mediakeysession-keystatuses">keyStatuses</a></code> attribute are replaced without invalidating existing references to the attribute. This replacement is atomic from a script perspective. That is, script <em class="rfc2119" title="MUST NOT">MUST NOT</em> ever see a partially populated sequence. </p> @@ -5416,7 +5571,7 @@ <h4 id="x6.4.3-update-expiration"><span class="secno">6.4.3 </span>Update Expira a target <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object and the new expiration time, which may be <code>NaN</code>. </p> <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note87"><span>Note</span></div> + <div class="note-title marker" aria-level="5" role="heading" id="h-note90"><span>Note</span></div> <p class="">The algorithm is always run in a task.</p> </div> <p>The following steps are run:</p> @@ -5440,7 +5595,7 @@ <h4 id="x6.4.3-update-expiration"><span class="secno">6.4.3 </span>Update Expira <h4 id="x6.4.4-session-closed"><span class="secno">6.4.4 </span>Session Closed</h4> <p>The Session Closed algorithm updates the <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> state after a <a href="#key-session">key session</a> has been closed by the <a href="#cdm">CDM</a>.</p> <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note88"><span>Note</span></div> + <div class="note-title marker" aria-level="5" role="heading" id="h-note91"><span>Note</span></div> <p class="">The algorithm is always run in a task.</p> </div> <p> @@ -5448,7 +5603,7 @@ <h4 id="x6.4.4-session-closed"><span class="secno">6.4.4 </span>Session Closed</ class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> methods will fail and no further events will be queued for this object after this algorithm is run. </p> <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note89"><span>Note</span></div> + <div class="note-title marker" aria-level="5" role="heading" id="h-note92"><span>Note</span></div> <div class=""> <p> The CDM may close a session at any point, such as when the session is no longer needed or when system resources are lost. In that case, the <a href="#monitor-cdm">Monitor for CDM Changes</a> algorithm detects the change and @@ -5476,6 +5631,32 @@ <h4 id="x6.4.4-session-closed"><span class="secno">6.4.4 </span>Session Closed</ <li> <p>Set the <var>session</var>'s <var>closing or closed</var> value to true.</p> </li> + <li> + <p> + If <var>session</var>'s <var>session type</var> is <code><a href="#idl-def-MediaKeySessionType.persistent-usage-record">"persistent-usage-record"</a></code>, execute the following steps: + </p> + <ol> + <li> + <p>Let <var>cdm</var> be the CDM instance represented by <var>session</var>'s <var>cdm instance</var> value.</p> + </li> + <li> + <p>Use <var>cdm</var> to store <var>session</var>'s <var>record of key usage</var>, if it exists.</p> + <div class="note"> + <div class="note-title marker" aria-level="5" role="heading" id="h-note93"><span>Note</span></div> + <div class=""> + <p> + The <var>record of key usage</var> may not exist if no keys have been used in the session or if it has been deleted as a result of the <code><a href="#dom-mediakeysession-update">update()</a></code> method processing + an acknowledgement of the <a href="#record-of-key-usage">record of key usage</a>. + </p> + <p> + Since it has no effects observable to the document, this step may be run asynchronously, including after the document has unloaded. + </p> + </div> + </div> + </li> + </ol> + + </li> <li> <p>Run the <a href="#update-key-statuses">Update Key Statuses</a> algorithm on the <var>session</var>, providing an empty sequence.</p> </li> @@ -5487,18 +5668,53 @@ <h4 id="x6.4.4-session-closed"><span class="secno">6.4.4 </span>Session Closed</ </li> </ol> </section> + <section id="media-key-session-destroyed"> + <h4 id="x6.4.5-mediakeysession-destroyed"><span class="secno">6.4.5 </span>MediaKeySession Destroyed</h4> + <p> + The MediaKeySession Destroyed algorithm performs steps that are necessary when a <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> that is not <a href="#media-key-session-closed">closed</a> is destroyed. + </p> + <p>The following steps are run in parallel to the main event loop:</p> + <ol> + <li> + <p>Let <var>session</var> be the associated <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object.</p> + </li> + <li> + <p>Let <var>cdm</var> be the CDM instance represented by <var>session</var>'s <var>cdm instance</var> value.</p> + </li> + <li> + <p>Use <var>cdm</var> to execute the following steps:</p> + <ol> + <li> + <p>Close the <a href="#key-session">session</a> associated with <var>session</var>.</p> + </li> + <li> + <p> + If <var>session</var>'s <var>session type</var> is <code><a href="#idl-def-MediaKeySessionType.persistent-usage-record">"persistent-usage-record"</a></code>, store <var>session</var>'s <var>record of key usage</var>, + if it exists. + </p> + <div class="note"> + <div class="note-title marker" aria-level="5" role="heading" id="h-note94"><span>Note</span></div> + <p class=""> + Since it has no effects observable to the document, this step may be run asynchronously, including after the document has unloaded. + </p> + </div> + </li> + </ol> + </li> + </ol> + </section> <section id="monitor-cdm"> - <h4 id="x6.4.5-monitor-for-cdm-state-changes"><span class="secno">6.4.5 </span>Monitor for CDM State Changes</h4> + <h4 id="x6.4.6-monitor-for-cdm-state-changes"><span class="secno">6.4.6 </span>Monitor for CDM State Changes</h4> <p> The Monitor for CDM State Changes algorithm executes steps required when various aspects of CDM state change. </p> <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note90"><span>Note</span></div> + <div class="note-title marker" aria-level="5" role="heading" id="h-note95"><span>Note</span></div> <p class="">This algorithm only applies to CDM state changes that are not covered by other algorithms. For example, <code><a href="#dom-mediakeysession-update">update()</a></code> may result in messages, key status changes and/or expiration changes, but those are all handled within that algorithm.</p> </div> <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note91"><span>Note</span></div> + <div class="note-title marker" aria-level="5" role="heading" id="h-note96"><span>Note</span></div> <p class="">The algorithm is always run in parallel to the main event loop.</p> </div> <p> @@ -5624,14 +5840,15 @@ <h3 id="x6.5-exceptions"><span class="secno">6.5 </span>Exceptions</h3> <h3 id="x6.6-session-storage-and-persistence"><span class="secno">6.6 </span>Session Storage and Persistence</h3> <p>This section provides an overview of session storage and persistence that complements the algorithms.</p> <p>The following requirements apply in addition to those in <a href="#media-keys-storage">Storage and Persistence</a>.</p> - <p>If the result of running the <a href="#is-persistent-session-type">Is persistent session type?</a> algorithm on this object's <var>session type</var> is <code>false</code>, the user agent and CDM <em class="rfc2119" title="MUST NOT">MUST NOT</em> persist a record of or data related to the session at any point. This includes license(s), key(s), <a href="#record-of-license-destruction">record(s) of license destruction</a>, and the <a href="#session-id">Session ID</a>. + <p>If the result of running the <a href="#is-persistent-session-type">Is persistent session type?</a> algorithm on this object's <var>session type</var> is <code>false</code>, the user agent and CDM <em class="rfc2119" title="MUST NOT">MUST NOT</em> persist a record of or data related to the session at any point. This includes license(s), key(s), <a href="#record-of-license-destruction">record(s) of license destruction</a>, <a href="#record-of-key-usage">record(s) of key usage</a>, + and the <a href="#session-id">Session ID</a>. </p> <p>The remainder of this section applies to session types for which the <a href="#is-persistent-session-type">Is persistent session type?</a> algorithm returns <code>true</code>.</p> <p>The CDM <em class="rfc2119" title="SHOULD NOT">SHOULD NOT</em> store session data, including the Session ID, until <code><a href="#dom-mediakeysession-update">update()</a></code> is called the first time. Specifically, the CDM <em class="rfc2119" title="SHOULD NOT">SHOULD NOT</em> store session data during the <code><a href="#dom-mediakeysession-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><em>All</em> data associated with a session <em class="rfc2119" title="MUST">MUST</em> be cleared when the session is cleared, such as in <code><a href="#dom-mediakeysession-update">update()</a></code> when processing a <a href="#record-of-license-destruction">record of license destruction</a> acknowledgement. See <a href="#persistent-state-requirements">Persistent Data</a>. + <p><em>All</em> data associated with a session <em class="rfc2119" title="MUST">MUST</em> be cleared when the session is cleared, such as in <code><a href="#dom-mediakeysession-update">update()</a></code> when processing a <a href="#record-of-license-destruction">record of license destruction</a> acknowledgement or <a href="#record-of-key-usage">record of key usage</a> acknowledgement. See <a href="#persistent-state-requirements">Persistent Data</a>. </p> <p>The CDM <em class="rfc2119" title="MUST">MUST</em> ensure that data for a given session is only present in one <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object that is not <a href="#media-key-session-closed">closed</a> in any <a href="https://www.w3.org/TR/dom/#concept-document">Document</a>. In other words, <code><a href="#dom-mediakeysession-load">load()</a></code> <em class="rfc2119" title="MUST">MUST</em> fail when there is already a <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> representing the session specified by the <var>sessionId</var> parameter, either because the object that @@ -5679,7 +5896,7 @@ <h2 id="x7.-htmlmediaelement-extensions"><span class="secno">7. </span><dfn data <p>When the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#current-position">current playback position</a> is changed other than advancing in the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#direction-of-playback">direction of playback</a> as part of normal playback, the <var>encrypted block queue</var> value <em class="rfc2119" title="SHALL">SHALL</em> be empty, the <var>decryption blocked waiting for key</var> value <em class="rfc2119" title="SHALL">SHALL</em> be initialized to <code>false</code>, and the <var>playback blocked waiting for key</var> value <em class="rfc2119" title="SHALL">SHALL</em> be set to <code>false</code>.</p> <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note92"><span>Note</span></div> + <div class="note-title marker" aria-level="3" role="heading" id="h-note97"><span>Note</span></div> <p class=""> In other words, these values should be reset when, for example, <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#loading-the-media-resource">loading the media resource</a> or <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#seeking">seeking</a>. </p> @@ -5692,13 +5909,13 @@ <h2 id="x7.-htmlmediaelement-extensions"><span class="secno">7. </span><dfn data <p>When the user agent is ready to begin playback and has encountered an indication that the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a> may contain encrypted blocks during the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#resource-fetch-algorithm">resource fetch algorithm</a>, the user agent <em class="rfc2119" title="SHALL">SHALL</em> run the <a href="#media-may-contain-encrypted-blocks">Media Data May Contain Encrypted Blocks</a> algorithm.</p> <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note93"><span>Note</span></div> + <div class="note-title marker" aria-level="3" role="heading" id="h-note98"><span>Note</span></div> <p class=""> For some container formats, such indication is separate from <a href="#initialization-data">Initialization Data</a>. </p> </div> <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note94"><span>Note</span></div> + <div class="note-title marker" aria-level="3" role="heading" id="h-note99"><span>Note</span></div> <p class=""> The algorithm is to be run after parsing the relevant container data, including running the <a href="#initdata-encountered">Initialization Data Encountered</a> algorithm, but before decoding starts. </p> @@ -5708,7 +5925,7 @@ <h2 id="x7.-htmlmediaelement-extensions"><span class="secno">7. </span><dfn data <p>When the user agent encounters <a href="#initialization-data">Initialization Data</a> in the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a> during the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#resource-fetch-algorithm">resource fetch algorithm</a>, the user agent <em class="rfc2119" title="SHALL">SHALL</em> run the <a href="#initdata-encountered">Initialization Data Encountered</a> algorithm.</p> <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note95"><span>Note</span></div> + <div class="note-title marker" aria-level="3" role="heading" id="h-note100"><span>Note</span></div> <p class=""> Some container formats may support encrypted media data that does not contain <a href="#initialization-data">Initialization Data</a> and thus support media data that does not trigger this algorithm. </p> @@ -5718,7 +5935,7 @@ <h2 id="x7.-htmlmediaelement-extensions"><span class="secno">7. </span><dfn data <p>For each block of encrypted <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a> encountered during the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#resource-fetch-algorithm">resource fetch algorithm</a>, the user agent <em class="rfc2119" title="SHALL">SHALL</em> run the <a href="#encrypted-block-encountered">Encrypted Block Encountered</a> algorithm in the order the encrypted blocks were encountered.</p> <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note96"><span>Note</span></div> + <div class="note-title marker" aria-level="3" role="heading" id="h-note101"><span>Note</span></div> <p class="">The above step provides flexibility for user agent implementations to perform decryption at any time after an encrypted block is encountered before it is needed for playback.</p> </div> </li> @@ -5731,7 +5948,7 @@ <h2 id="x7.-htmlmediaelement-extensions"><span class="secno">7. </span><dfn data <li> <p>The user agent cannot provide data for the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#current-position">current playback position</a>.</p> <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note97"><span>Note</span></div> + <div class="note-title marker" aria-level="3" role="heading" id="h-note102"><span>Note</span></div> <p class="">For example, at the beginning of playback or after <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#seeking">seeking</a>.</p> </div> </li> @@ -5780,7 +5997,7 @@ <h3 id="methods-4">Methods</h3> <!-- </a> -->to use when decrypting media data during playback.</p> <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note98"><span>Note</span></div> + <div class="note-title marker" aria-level="4" role="heading" id="h-note103"><span>Note</span></div> <p class="">Support for clearing or replacing the associated <!-- Restore when https://github.com/w3c/respec/issues/893 is fixed. <a> -->MediaKeys <!-- </a> -->object during playback is a quality of implementation issue. In many cases it will result in a bad user experience or rejected promise.</p> @@ -5854,7 +6071,7 @@ <h3 id="methods-4">Methods</h3> <li> <p>If the association cannot currently be removed, let this object's <var>attaching media keys</var> value be false and reject <var>promise</var> with an <code><a href="#dfn-InvalidStateError">InvalidStateError</a></code>.</p> <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note99"><span>Note</span></div> + <div class="note-title marker" aria-level="4" role="heading" id="h-note104"><span>Note</span></div> <p class="">For example, some implementations may not allow removal during playback.</p> </div> </li> @@ -6015,7 +6232,7 @@ <h3 id="x7.2-event-summary"><span class="secno">7.2 </span>Event Summary</h3> <td>The user agent encounters <a href="#initialization-data">Initialization Data</a> in the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a>.</td> <td>The element's <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-readystate">readyState</a></code> is equal to or greater than <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-have_metadata">HAVE_METADATA</a></code>. <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note100"><span>Note</span></div> + <div class="note-title marker" aria-level="4" role="heading" id="h-note105"><span>Note</span></div> <p class="">It is possible that the element is playing or has played.</p> </div> </td> @@ -6050,7 +6267,7 @@ <h4 id="x7.3.1-media-data-may-contain-encrypted-blocks"><span class="secno">7.3. <li> <p>If the <var>media element</var>'s <code><a href="#dom-mediakeys">mediaKeys</a></code> attribute is null and the implementation requires specification of a <a href="#dom-mediakeys" class="internalDFN" data-link-type="dfn"><code>MediaKeys</code></a> object before decoding potentially-encrypted <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a>, run the following steps:</p> <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note101"><span>Note</span></div> + <div class="note-title marker" aria-level="5" role="heading" id="h-note106"><span>Note</span></div> <p class="">These steps may be reached when the application provides <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a> before calling <code><a href="#dom-htmlmediaelement-setmediakeys">setMediaKeys()</a></code> to provide a <a href="#dom-mediakeys" class="internalDFN" data-link-type="dfn"><code>MediaKeys</code></a> object. Selecting a <a href="#cdm">CDM</a> may affect the pipeline and/or decoders used, so some implementations may delay playback of media data that may contain encrypted blocks until a CDM is specified by passing a <a href="#dom-mediakeys" class="internalDFN" data-link-type="dfn"><code>MediaKeys</code></a> object to <code><a href="#dom-htmlmediaelement-setmediakeys">setMediaKeys()</a></code>. </p> @@ -6096,7 +6313,7 @@ <h4 id="x7.3.2-initialization-data-encountered"><span class="secno">7.3.2 </span </li> </ol> <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note102"><span>Note</span></div> + <div class="note-title marker" aria-level="5" role="heading" id="h-note107"><span>Note</span></div> <p class="">While the media element may allow loading of "Optionally-blockable Content" [<cite><a class="bibref" href="#bib-MIXED-CONTENT">MIXED-CONTENT</a></cite>], the user agent <em class="rfc2119" title="MUST NOT">MUST NOT</em> expose Initialization Data from such media data to the application.</p> </div> @@ -6113,11 +6330,11 @@ <h4 id="x7.3.2-initialization-data-encountered"><span class="secno">7.3.2 </span </li> </ul> <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note103"><span>Note</span></div> + <div class="note-title marker" aria-level="5" role="heading" id="h-note108"><span>Note</span></div> <p class=""><code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-readystate">readyState</a></code> is <em>not</em> changed and no algorithms are aborted. This event merely provides information.</p> </div> <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note104"><span>Note</span></div> + <div class="note-title marker" aria-level="5" role="heading" id="h-note109"><span>Note</span></div> <p class="">The <code><a href="#dom-mediaencryptedevent-initdata">initData</a></code> attribute will be null if the media data is <em>not</em> <a href="https://www.w3.org/TR/html51/browsers.html#same-origin">CORS-same-origin</a> or is <a href="#mixed-content">mixed content</a>. Applications may retrieve the Initialization Data from an alternate source. </p> @@ -6173,7 +6390,7 @@ <h4 id="x7.3.4-attempt-to-decrypt"><span class="secno">7.3.4 </span>Attempt to D <li> <p>If <var>cdm</var> is no longer usable for any reason, run the following steps:</p> <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note105"><span>Note</span></div> + <div class="note-title marker" aria-level="5" role="heading" id="h-note110"><span>Note</span></div> <p class="">These steps are intended to be run on unrecoverable failures of the CDM.</p> </div> <ol> @@ -6192,7 +6409,7 @@ <h4 id="x7.3.4-attempt-to-decrypt"><span class="secno">7.3.4 </span>Attempt to D <p>If there is at least one <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> created by the <var>media keys</var> that is not <a href="#media-key-session-closed">closed</a>, run the following steps:</p> <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note106"><span>Note</span></div> + <div class="note-title marker" aria-level="5" role="heading" id="h-note111"><span>Note</span></div> <p class="">This check ensures the <var>cdm</var> has finished loading and is a prerequisite for a matching key being available.</p> </div> <ol> @@ -6202,7 +6419,7 @@ <h4 id="x7.3.4-attempt-to-decrypt"><span class="secno">7.3.4 </span>Attempt to D <li> <p>Let the <var>block key ID</var> be the key ID of <var>block</var>.</p> <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note107"><span>Note</span></div> + <div class="note-title marker" aria-level="5" role="heading" id="h-note112"><span>Note</span></div> <p class="">The key ID is generally specified by the container.</p> </div> </li> @@ -6219,7 +6436,7 @@ <h4 id="x7.3.4-attempt-to-decrypt"><span class="secno">7.3.4 </span>Attempt to D <p>If any of the <var>available keys</var> corresponds to the <var>block key ID</var> and is <a href="#usable-for-decryption">usable for decryption</a>, let <var>session</var> be a <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object containing that key and let <var>block key</var> be that key.</p> <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note108"><span>Note</span></div> + <div class="note-title marker" aria-level="5" role="heading" id="h-note113"><span>Note</span></div> <p class="">If multiple sessions contain a key that is <a href="#usable-for-decryption">usable for decryption</a> for the <var>block key ID</var>, which session and key to use is <a href="#key-system">Key System</a>-dependent.</p> </div> </li> @@ -6229,6 +6446,30 @@ <h4 id="x7.3.4-attempt-to-decrypt"><span class="secno">7.3.4 </span>Attempt to D <li> <p>If <var>block key</var> is not null, run the following steps:</p> <ol> + <li> + <p>If <var>session</var>'s <var>session type</var> is <code><a href="#idl-def-MediaKeySessionType.persistent-usage-record">"persistent-usage-record"</a></code>, run the following steps:</p> + <ol> + <li> + <p>Let <var>usage</var> be <var>session</var>'s <var>record of key usage</var>.</p> + </li> + <li> + <p> + If the <var>first decrypt time</var> of <var>usage</var> is <code>null</code>, set the <var>first decrypt time</var> of <var>usage</var> to the current time, accurate to within <var><a href="#key-usage-accuracy">key usage accuracy</a></var>. + </p> + </li> + <li> + <p> + Set the <var>latest decrypt time</var> of <var>usage</var> to the current time, accurate to within <var><a href="#key-usage-accuracy">key usage accuracy</a></var>. + </p> + </li> + </ol> + <div class="note"> + <div class="note-title marker" aria-level="5" role="heading" id="h-note114"><span>Note</span></div> + <p class=""> + Implementations <em class="rfc2119" title="MAY">MAY</em> optimize the times at which this step is executed provided the recorded key usage times remain accurate to within <var>key usage accuracy</var>. + </p> + </div> + </li> <li> <p>Use the <var>cdm</var> to decrypt <var>block</var> using <var>block key</var>.</p> </li> @@ -6258,7 +6499,7 @@ <h4 id="x7.3.4-attempt-to-decrypt"><span class="secno">7.3.4 </span>Attempt to D <li> <p>Process the decrypted block as normal.</p> <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note109"><span>Note</span></div> + <div class="note-title marker" aria-level="5" role="heading" id="h-note115"><span>Note</span></div> <p class="">In other words, decode the block.</p> </div> </li> @@ -6270,13 +6511,13 @@ <h4 id="x7.3.4-attempt-to-decrypt"><span class="secno">7.3.4 </span>Attempt to D </dd> </dl> <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note110"><span>Note</span></div> + <div class="note-title marker" aria-level="5" role="heading" id="h-note116"><span>Note</span></div> <p class="">Not all decryption problems (e.g., using the wrong key) will result in a decryption failure. In such cases, no error is fired here but one may be fired during decode.</p> </div> </li> </ol> <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note111"><span>Note</span></div> + <div class="note-title marker" aria-level="5" role="heading" id="h-note117"><span>Note</span></div> <p class="">Otherwise, there is no key for the <var>block key ID</var> in any session so continue.</p> </div> </li> @@ -6289,11 +6530,11 @@ <h4 id="x7.3.4-attempt-to-decrypt"><span class="secno">7.3.4 </span>Attempt to D <li> <p>Set the <var>media element</var>'s <var>decryption blocked waiting for key</var> value to <code>true</code>.</p> <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note112"><span>Note</span></div> + <div class="note-title marker" aria-level="5" role="heading" id="h-note118"><span>Note</span></div> <p class="">This step is reached when there is no key that is <a href="#usable-for-decryption">usable for decryption</a> for <var>block</var>.</p> </div> <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note113"><span>Note</span></div> + <div class="note-title marker" aria-level="5" role="heading" id="h-note119"><span>Note</span></div> <div class=""> <p>Once the user agent has rendered the blocks preceding the block that cannot be decrypted (as much as it can, such as, all complete video frames), it will run the <a href="#wait-for-key">Wait for Key</a> algorithm.</p> <p>That algorithm is not run directly here in order to allow implementations to decrypt and decode media data ahead of the ahead of the current playback position without affecting the visible behavior.</p> @@ -6303,7 +6544,7 @@ <h4 id="x7.3.4-attempt-to-decrypt"><span class="secno">7.3.4 </span>Attempt to D </ol> <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note114"><span>Note</span></div> + <div class="note-title marker" aria-level="5" role="heading" id="h-note120"><span>Note</span></div> <div class=""> <p>For frame-based encryption, this may be implemented as follows when the media element attempts to decode a frame as part of the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#resource-fetch-algorithm">resource fetch algorithm</a>:</p> <ol> @@ -6347,7 +6588,7 @@ <h4 id="x7.3.5-wait-for-key"><span class="secno">7.3.5 </span>Wait for Key</h4> <li> <p>Set the <var>media element</var>'s <var>playback blocked waiting for key</var> value to <code>true</code>.</p> <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note115"><span>Note</span></div> + <div class="note-title marker" aria-level="5" role="heading" id="h-note121"><span>Note</span></div> <p class="">As a result of the above step, the media element will become a <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#blocked-media-element">blocked media element</a> if it wasn't already. In that case, the media element will stop playback.</p> </div> @@ -6365,7 +6606,7 @@ <h4 id="x7.3.5-wait-for-key"><span class="secno">7.3.5 </span>Wait for Key</h4> </dd> </dl> <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note116"><span>Note</span></div> + <div class="note-title marker" aria-level="5" role="heading" id="h-note122"><span>Note</span></div> <p class=""> In other words, if the video frame and audio data for the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#current-position">current playback position</a> have been decoded because they were unencrypted and/or successfully decrypted, set <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-readystate">readyState</a></code> to <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-have_current_data">HAVE_CURRENT_DATA</a></code>. @@ -6408,7 +6649,7 @@ <h4 id="x7.3.6-attempt-to-resume-playback-if-necessary"><span class="secno">7.3. <li> <p>Set the <var>media element</var>'s <var>playback blocked waiting for key</var> value to <code>false</code>.</p> <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note117"><span>Note</span></div> + <div class="note-title marker" aria-level="5" role="heading" id="h-note123"><span>Note</span></div> <p class="">As a result of the above step, the media element may no longer be a <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#blocked-media-element">blocked media element</a> and thus playback may resume.</p> </div> </li> @@ -6419,7 +6660,7 @@ <h4 id="x7.3.6-attempt-to-resume-playback-if-necessary"><span class="secno">7.3. <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-have_enough_data">HAVE_ENOUGH_DATA</a></code> as <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#ready-states">appropriate</a></code>. </p> <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note118"><span>Note</span></div> + <div class="note-title marker" aria-level="5" role="heading" id="h-note124"><span>Note</span></div> <div class=""> <p> States beyond <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-have_current_data">HAVE_CURRENT_DATA</a></code> and the <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#eventdef-media-canplaythrough">canplaythrough</a></code> event do not (or are unlikely to) consider key availability beyond the current key. @@ -6504,8 +6745,7 @@ <h3 id="x8.2-messages-and-communication"><span class="secno">8.2 </span>Messages <h3 id="x8.3-persistent-data"><span class="secno">8.3 </span>Persistent Data</h3> <p> Persistent Data includes all data stored by the CDM, or by the User Agent on behalf of the CDM, that exists after the destruction of the <a href="#dom-mediakeys" class="internalDFN" data-link-type="dfn"><code>MediaKeys</code></a> object. - Specifically, it includes any identifiers (including <a href="#distinctive-identifier">Distinctive Identifier(s)</a>), licenses, keys, key IDs, or <a href="#record-of-license-destruction">records of license destruction</a> stored by the - CDM or by the User Agent on behalf of the CDM. + Specifically, it includes any identifiers (including <a href="#distinctive-identifier">Distinctive Identifier(s)</a>), licenses, keys, key IDs, <a href="#record-of-license-destruction">records of license destruction</a>, or <a href="#record-of-key-usage">records of key usage</a> stored by the CDM or by the User Agent on behalf of the CDM. </p> <section id="use-origin-specific-key-system-storage"> <h4 id="x8.3.1-use-origin-specific-and-browsing-profile-specific-key-system-storage"><span class="secno">8.3.1 </span>Use origin-specific and browsing profile-specific Key System storage</h4> @@ -6632,7 +6872,7 @@ <h3 id="x8.5-identifiers"><span class="secno">8.5 </span>Identifiers</h3> defines requirements for avoiding or at least mitigating such concerns. The requirements for <a href="#exposed-value-requirements">Values Exposed to the Application</a> also apply to identifiers exposed to the application. </p> <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note119"><span>Note</span></div> + <div class="note-title marker" aria-level="4" role="heading" id="h-note125"><span>Note</span></div> <div class=""> <p>In summary:</p> <ul> @@ -6674,7 +6914,7 @@ <h4 id="x8.5.1-limit-or-avoid-use-of-distinctive-identifiers-and-permanent-ident <li> <p>Implementations <em class="rfc2119" title="SHOULD">SHOULD</em> avoid <a href="#uses-distinctive-identifiers-or-distinctive-permanent-identifiers">use of Distinctive Identifier(s) or Distinctive Permanent Identifier(s)</a>.</p> <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note120"><span>Note</span></div> + <div class="note-title marker" aria-level="5" role="heading" id="h-note126"><span>Note</span></div> <p class="">For example, use identifiers or other values that apply to a group of clients or devices rather than individual clients.</p> </div> </li> @@ -6682,7 +6922,7 @@ <h4 id="x8.5.1-limit-or-avoid-use-of-distinctive-identifiers-and-permanent-ident <p>Implementations <em class="rfc2119" title="SHOULD">SHOULD</em> only <a href="#uses-distinctive-identifiers-or-distinctive-permanent-identifiers">use Distinctive Identifier(s) or Distinctive Permanent Identifier(s)</a> when necessary to enforce the policies related to the specific CDM instance and session.</p> <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note121"><span>Note</span></div> + <div class="note-title marker" aria-level="5" role="heading" id="h-note127"><span>Note</span></div> <p class="">For example, <code><a href="#idl-def-MediaKeySessionType.temporary">"temporary"</a></code> and <code><a href="#idl-def-MediaKeySessionType.persistent-license">"persistent-license"</a></code> sessions may have different requirements.</p> </div> </li> @@ -6692,7 +6932,7 @@ <h4 id="x8.5.1-limit-or-avoid-use-of-distinctive-identifiers-and-permanent-ident the option to not use them. Implementations with such support <em class="rfc2119" title="SHOULD">SHOULD</em> expose the ability for the user to select this option. </p> <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note122"><span>Note</span></div> + <div class="note-title marker" aria-level="5" role="heading" id="h-note128"><span>Note</span></div> <div class=""> <p> When supported, applications can select for this mode using <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> = <code><a href="#idl-def-MediaKeysRequirement.not-allowed">"not-allowed"</a></code>. @@ -6715,7 +6955,7 @@ <h4 id="x8.5.2-encrypt-identifiers"><span class="secno">8.5.2 </span>Encrypt Ide when exposed outside the client. All other identifiers <em class="rfc2119" title="SHOULD">SHOULD</em> be encrypted at the message exchange level when exposed outside the client. The encryption <em class="rfc2119" title="MUST">MUST</em> ensure that any two instances of the identifier ciphertext are <a href="#associable-by-entity">associable</a> only by an entity in possession of the decryption key. </p> <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note123"><span>Note</span></div> + <div class="note-title marker" aria-level="5" role="heading" id="h-note129"><span>Note</span></div> <div class=""> <p>Identifiers may be exposed in the following ways:</p> <ul> @@ -6736,13 +6976,13 @@ <h4 id="x8.5.2-encrypt-identifiers"><span class="secno">8.5.2 </span>Encrypt Ide </p> <p>The server <em class="rfc2119" title="MUST NOT">MUST NOT</em> expose a <a href="#distinctive-identifier">Distinctive Identifier</a> to any entity other than the CDM that sent it.</p> <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note124"><span>Note</span></div> + <div class="note-title marker" aria-level="5" role="heading" id="h-note130"><span>Note</span></div> <p class="">Specifically, it should not be provided to the application or included unencrypted in messages to the CDM. This can be accomplished by encrypting the identifier or message with the identifier or such that it is only decryptable by that specific CDM. </p> </div> <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note125"><span>Note</span></div> + <div class="note-title marker" aria-level="5" role="heading" id="h-note131"><span>Note</span></div> <div class=""> <p>Among other things, this means that:</p> <ul> @@ -6766,7 +7006,7 @@ <h4 id="x8.5.3-use-per-origin-per-profile-identifiers"><span class="secno">8.5.3 All identifiers except <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifiers</a> <em class="rfc2119" title="MUST">MUST</em> be unique per <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> and <a href="#browsing-profile">browsing profile</a>. See <a href="#per-origin-per-profile-values" class="sec-ref"><span class="secno">8.4.1</span> <span class="sec-title">Use Per-Origin Per-Profile Values</span></a>. </p> <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note126"><span>Note</span></div> + <div class="note-title marker" aria-level="5" role="heading" id="h-note132"><span>Note</span></div> <div class=""> <p>This includes but is not limited to <a href="#distinctive-identifier">Distinctive Identifiers</a>.</p> <p><a href="#distinctive-permanent-identifier">Distinctive Permanent Identifiers</a> <em class="rfc2119" title="MUST NOT">MUST NOT</em> be exposed to the application or origin.</p> @@ -6780,7 +7020,7 @@ <h4 id="x8.5.4-use-non-associable-identifiers"><span class="secno">8.5.4 </span> All identifiers, including <a href="#distinctive-identifier">Distinctive Identifiers</a>, exposed by the implementation to applications, even in encrypted form, <em class="rfc2119" title="MUST">MUST</em> be <a href="#non-associable-by-application">non-associable by application(s)</a> across <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origins</a>, <a href="#browsing-profile">browsing profiles</a>, and <a href="#allow-identifiers-cleared">clearing of identifiers</a>. </p> <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note127"><span>Note</span></div> + <div class="note-title marker" aria-level="5" role="heading" id="h-note133"><span>Note</span></div> <p class=""> For all such identifiers, it <em class="rfc2119" title="MUST NOT">MUST NOT</em> be possible for one or more applications, including related license or other servers to achieve such correlation or association. </p> @@ -6814,7 +7054,7 @@ <h3 id="x8.6-individualization"><span class="secno">8.6 </span>Individualization those below. </p> <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note128"><span>Note</span></div> + <div class="note-title marker" aria-level="4" role="heading" id="h-note134"><span>Note</span></div> <p class=""> <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> controls whether <a href="#distinctive-identifier">Distinctive Identifiers</a> and <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifiers</a> may be <a href="#uses-distinctive-identifiers-or-distinctive-permanent-identifiers">used</a>, including for individualization. Specifically, such identifiers may only be <a href="#uses-distinctive-identifiers-or-distinctive-permanent-identifiers">used</a> when the value of the <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> member of the <a href="#dom-mediakeysystemaccess" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemAccess</code></a> used to create the <a href="#dom-mediakeys" class="internalDFN" data-link-type="dfn"><code>MediaKeys</code></a> object is <code><a href="#idl-def-MediaKeysRequirement.required">"required"</a></code>. </p> @@ -6828,7 +7068,7 @@ <h4 id="x8.6.1-direct-individualization"><span class="secno">8.6.1 </span>Direct specification. </p> <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note129"><span>Note</span></div> + <div class="note-title marker" aria-level="5" role="heading" id="h-note135"><span>Note</span></div> <p class="">For example, such a process may initialize a client device and/or obtain a <a href="#per-origin-per-profile-identifiers">per-origin</a> <a href="#allow-identifiers-cleared">clearable</a> identifier for <a href="#per-origin-per-profile-identifiers">a single browsing profile</a> by communicating with a pre-determined server hosted by the user agent or CDM vendor, possibly <a href="#uses-distinctive-permanent-identifiers">using Distinctive Permanent Identifier(s)</a> or other <a href="#permanent-identifier">Permanent Identifier(s)</a> from the client device. </p> </div> @@ -6886,7 +7126,7 @@ <h4 id="x8.6.2-app-assisted-individualization"><span class="secno">8.6.2 </span> <li> <p><em class="rfc2119" title="MUST">MUST</em> adhere to the <a href="#identifier-requirements">identifier requirements</a>.</p> <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note130"><span>Note</span></div> + <div class="note-title marker" aria-level="5" role="heading" id="h-note136"><span>Note</span></div> <p class="">This includes only using values that are <a href="#per-origin-per-profile-identifiers">unique per origin and profile</a> and <a href="#allow-identifiers-cleared">clearable</a> and <a href="#encrypt-identifiers">encrypting</a> them as required.</p> </div> </li> @@ -6909,7 +7149,7 @@ <h4 id="x8.6.2-app-assisted-individualization"><span class="secno">8.6.2 </span> <h3 id="x8.7-support-multiple-keys"><span class="secno">8.7 </span>Support Multiple Keys</h3> <p>Implementations <em class="rfc2119" title="MUST">MUST</em> support multiple keys in each <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object.</p> <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note131"><span>Note</span></div> + <div class="note-title marker" aria-level="4" role="heading" id="h-note137"><span>Note</span></div> <p class="">The mechanics of how multiple keys are supported is an implementation detail, but it <em class="rfc2119" title="MUST">MUST</em> be transparent to the application and the APIs defined in this specification.</p> </div> @@ -6923,7 +7163,7 @@ <h3 id="x8.8-initialization-data-type-support"><span class="secno">8.8 </span>In <h4 id="x8.8.1-licenses-generated-are-independent-of-content-type"><span class="secno">8.8.1 </span>Licenses Generated are Independent of Content Type</h4> <p>Implementations <em class="rfc2119" title="SHOULD">SHOULD</em> allow licenses generated with any <a href="#initialization-data-type">Initialization Data Type</a> they support to be used with any content type.</p> <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note132"><span>Note</span></div> + <div class="note-title marker" aria-level="5" role="heading" id="h-note138"><span>Note</span></div> <p class="">Otherwise, the <code><a href="#dom-navigator-requestmediakeysystemaccess">requestMediaKeySystemAccess()</a></code> algorithm might, for example, reject a <a href="#dom-mediakeysystemconfiguration" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemConfiguration</code></a> because one of the <code><a href="#dom-mediakeysystemconfiguration-initdatatypes">initDataTypes</a></code> is not supported with one of the <code><a href="#dom-mediakeysystemconfiguration-videocapabilities">videoCapabilities</a></code>.</p> </div> </section> @@ -6932,7 +7172,7 @@ <h4 id="x8.8.1-licenses-generated-are-independent-of-content-type"><span class=" <h4 id="x8.8.2-support-extraction-from-media-data"><span class="secno">8.8.2 </span>Support Extraction From Media Data</h4> <p>For any supported <a href="#initialization-data-type">Initialization Data Type</a> that may appear in a supported container, the user agents <em class="rfc2119" title="MUST">MUST</em> support <a href="#initdata-encountered">extracting</a> that type of <a href="#initialization-data">Initialization Data</a> from each such supported container.</p> <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note133"><span>Note</span></div> + <div class="note-title marker" aria-level="5" role="heading" id="h-note139"><span>Note</span></div> <p class="">In other words, indicating support for an <a href="#initialization-data-type">Initialization Data Type</a> implies both CDM support for generating license requests and, for container-specific types, user agent support for extracting it from the container. This does <strong>not</strong> mean that implementations must be able to parse <em>any</em> supported <a href="#initialization-data">Initialization Data</a> from <em>any</em> supported content type. </p> @@ -6959,7 +7199,7 @@ <h4 id="x8.9.2-interoperably-encrypted"><span class="secno">8.9.2 </span>Interop encryption" specification that allows the content to be decrypted in a fully specified and compatible way when a key or keys are provided. </p> <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note134"><span>Note</span></div> + <div class="note-title marker" aria-level="5" role="heading" id="h-note140"><span>Note</span></div> <p class=""> The Encrypted Media Extensions Stream Format and Initialization Data Format Registry [<cite><a class="bibref" href="#bib-EME-STREAM-REGISTRY">EME-STREAM-REGISTRY</a></cite>] provides references to such stream formats. </p> @@ -6972,7 +7212,7 @@ <h4 id="x8.9.3-unencrypted-in-band-support-content"><span class="secno">8.9.3 </ In-band support content, such as captions, described audio, and transcripts, <em class="rfc2119" title="SHOULD NOT">SHOULD NOT</em> be encrypted. </p> <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note135"><span>Note</span></div> + <div class="note-title marker" aria-level="5" role="heading" id="h-note141"><span>Note</span></div> <p class=""> Decryption of such tracks - especially such that they can be provided back the user agent - is not generally supported by implementations. Thus, encrypting such tracks would prevent them from being widely available for use with accessibility features in user agent implementations. @@ -6992,7 +7232,7 @@ <h4 id="x8.9.3-unencrypted-in-band-support-content"><span class="secno">8.9.3 </ <h2 id="x9.-common-key-systems"><span class="secno">9. </span>Common Key Systems</h2> <p>All user agents <em class="rfc2119" title="MUST">MUST</em> support the common key systems described in this section.</p> <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note136"><span>Note</span></div> + <div class="note-title marker" aria-level="3" role="heading" id="h-note142"><span>Note</span></div> <p class="">This ensures that there is a common baseline level of functionality that is guaranteed to be supported in all user agents, including those that are entirely open source. Thus, content providers that need only basic decryption can build simple applications that will work on all platforms without needing to work with any content protection providers. </p> @@ -7025,6 +7265,11 @@ <h4 id="x9.1.1-capabilities"><span class="secno">9.1.1 </span>Capabilities</h4> <p>The <code><a href="#idl-def-MediaKeySessionType.persistent-license">"persistent-license"</a></code> <a href="#dom-mediakeysessiontype" class="internalDFN" data-link-type="dfn"><code>MediaKeySessionType</code></a>: Implementations <em class="rfc2119" title="MAY">MAY</em> support this type.</p> </li> + <li> + <p>The <code><a href="#idl-def-MediaKeySessionType.persistent-usage-record">"persistent-usage-record"</a></code> <a href="#dom-mediakeysessiontype" class="internalDFN" data-link-type="dfn"><code>MediaKeySessionType</code></a>: Implementations + <em class="rfc2119" title="MAY">MAY</em> support this type.</p> + </li> + <li> <p>The <code><a href="#dom-mediakeys-setservercertificate">setServerCertificate()</a></code> method: Not supported.</p> </li> @@ -7078,6 +7323,11 @@ <h4 id="x9.1.2-behavior"><span class="secno">9.1.2 </span>Behavior</h4> For sessions of type <code><a href="#idl-def-MediaKeySessionType.persistent-license">"persistent-license"</a></code>, in the <code><a href="#dom-mediakeysession-remove">remove()</a></code> algorithm, the <var>message</var> reflecting the <var>record of license destruction</var> is a JSON object encoded in UTF-8 as described in <a href="#clear-key-release-format">License Release Format</a>. </p> </li> + <li> + <p> + For sessions of type <code><a href="#idl-def-MediaKeySessionType.persistent-usage-record">"persistent-usage-record"</a></code>, in the <code><a href="#dom-mediakeysession-remove">remove()</a></code> and <code><a href="#dom-mediakeysession-load">load()</a></code> algorithms, the <var>message</var> reflecting the object's <var>record of key usage</var> is a JSON object encoded in UTF-8 as described in <a href="#clear-key-release-format">License Release Format</a>. + </p> + </li> <li> <p> The <code><a href="#dom-mediakeysession-keystatuses">keyStatuses</a></code> attribute method initially contains all key IDs that have been provided via <code><a href="#dom-mediakeysession-update">update()</a></code>, with status @@ -7177,12 +7427,23 @@ <h5 id="x9.1.4.1-example"><span class="secno">9.1.4.1 </span>Example</h5> <h4 id="x9.1.5-license-release-format"><span class="secno">9.1.5 </span>License Release Format</h4> <p>This section describes the format of the license release message to be provided via the <code><a href="#dom-mediakeymessageevent-message">message</a></code> attribute of the <code><a href="#dom-evt-message">message</a></code> event.</p> <p> - The format is a JSON object. For sessions of type <code><a href="#idl-def-MediaKeySessionType.persistent-license">"persistent-license"</a></code>, the object shall contain the following member: + The format is a JSON object. For sessions of type <code><a href="#idl-def-MediaKeySessionType.persistent-license">"persistent-license"</a></code> and <code><a href="#idl-def-MediaKeySessionType.persistent-usage-record">"persistent-usage-record"</a></code>, + the object shall contain the following member: </p> <dl> <dt>"kids"</dt> <dd>An array of <a href="#decryption-key-id">key IDs</a>. Each element of the array is the base64url encoding of the octet sequence containing the key ID value.</dd> </dl> + <p> + For sessions of type <code><a href="#idl-def-MediaKeySessionType.persistent-usage-record">"persistent-usage-record"</a></code> the object shall also contain the following members: + </p> + <dl> + <dt>"firstTime"</dt> + <dd>The <a href="#first-decryption-time">first decryption time</a> expressed as a number giving the time, in milliseconds since 01 January, 1970 UTC.</dd> + <dt>"latestTime"</dt> + <dd>The <a href="#latest-decryption-time">latest decryption time</a> expressed as a number giving the time, in milliseconds since 01 January, 1970 UTC.</dd> + </dl> + <p>When contained in the ArrayBuffer <code><a href="#dom-mediakeymessageevent-message">message</a></code> attribute of a <a href="#dom-mediakeymessageevent" class="internalDFN" data-link-type="dfn"><code>MediaKeyMessageEvent</code></a> object, the JSON string is encoded in UTF-8 as specified in the Encoding specification [<cite><a class="bibref" href="#bib-ENCODING">ENCODING</a></cite>]. Applications <em class="rfc2119" title="MAY">MAY</em> decode the contents of the ArrayBuffer to a JSON string using the <a href="https://www.w3.org/TR/encoding/#interface-textdecoder">TextDecoder interface</a> [<cite><a class="bibref" href="#bib-ENCODING">ENCODING</a></cite>]. @@ -7198,6 +7459,22 @@ <h5 id="x9.1.5.1-example-message-reflecting-a"><span class="secno">9.1.5.1 </spa <div class="example-title marker"><span>Example 3</span></div> <pre class="highlight hljs json" aria-busy="false" aria-live="polite">{ <span class="hljs-attr">"kids"</span>: [ <span class="hljs-string">"LwVHf8JLtPrv2GUXFW2v_A"</span>, <span class="hljs-string">"0DdtU9od-Bh5L3xbv0Xf_A"</span> ] +}</pre> + </div> + </section> + + <section id="clear-key-release-format-example-2" class="informative"> + <h5 id="x9.1.5.2-example-message-reflecting-a"><span class="secno">9.1.5.2 </span>Example message reflecting a <a href="#record-of-key-usage">record of key usage</a></h5> + <p><em>This section is non-normative.</em></p> + <p> + The following example is a license release for a <code><a href="#idl-def-MediaKeySessionType.persistent-usage-record">"persistent-usage-record"</a></code> session that contained two keys. (Line breaks are for readability only.) + </p> + <div class="example"> + <div class="example-title marker"><span>Example 4</span></div> + <pre class="highlight hljs json" aria-busy="false" aria-live="polite">{ + <span class="hljs-attr">"kids"</span>: [ <span class="hljs-string">"LwVHf8JLtPrv2GUXFW2v_A"</span>, <span class="hljs-string">"0DdtU9od-Bh5L3xbv0Xf_A"</span> ], + <span class="hljs-attr">"firstTime"</span> : <span class="hljs-number">1430425323757</span>, + <span class="hljs-attr">"latestTime"</span> : <span class="hljs-number">1430425383757</span> }</pre> </div> </section> @@ -7222,7 +7499,7 @@ <h5 id="x9.1.6.1-example"><span class="secno">9.1.6.1 </span>Example</h5> <p><em>This section is non-normative.</em></p> <p>The following example is a license request for a temporary license for two key IDs. (Line breaks are for readability only.)</p> <div class="example"> - <div class="example-title marker"><span>Example 4</span></div> + <div class="example-title marker"><span>Example 5</span></div> <pre class="highlight hljs json" aria-busy="false" aria-live="polite">{ <span class="hljs-attr">"kids"</span>: [ @@ -7254,13 +7531,13 @@ <h3 id="x10.1-input-data-attacks-and-vulnerabilities"><span class="secno">10.1 < data passed to <code><a href="#dom-mediakeysession-update">update()</a></code>, licenses, key data, and all other data provided by the application as untrusted content and potential attack vectors. They <em class="rfc2119" title="MUST">MUST</em> use appropriate safeguards to mitigate any associated threats and take care to safely parse, decrypt, etc. such data. User Agents <em class="rfc2119" title="SHOULD">SHOULD</em> validate data before passing it to the CDM. </p> <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note137"><span>Note</span></div> + <div class="note-title marker" aria-level="4" role="heading" id="h-note143"><span>Note</span></div> <p class="">Such validation is especially important if the CDM does not run in the same (sandboxed) context as, for example, the DOM.</p> </div> <p>Implementations <em class="rfc2119" title="MUST NOT">MUST NOT</em> return active content or passive content that affects program control flow to the application.</p> <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note138"><span>Note</span></div> + <div class="note-title marker" aria-level="4" role="heading" id="h-note144"><span>Note</span></div> <p class="">For example, it is not safe to expose URLs or other information that may have come from media data, such as is the case for the <a href="#initialization-data">Initialization Data</a> passed to <code><a href="#dom-mediakeysession-generaterequest">generateRequest()</a></code>. Applications must determine the URLs to use. The <code><a href="#dom-mediakeymessageevent-messagetype">messageType</a></code> attribute of the <code><a href="#dom-evt-message">message</a></code> event can be used by the application to select among a set of URLs if applicable. @@ -7280,14 +7557,14 @@ <h3 id="x10.2-cdm-attacks-and-vulnerabilities"><span class="secno">10.2 </span>C including parsing of <a href="#input-data-security">all data</a>. </p> <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note139"><span>Note</span></div> + <div class="note-title marker" aria-level="4" role="heading" id="h-note145"><span>Note</span></div> <p class="">User agents should be especially diligent when using a CDM or underlying mechanism that is part of or provided by the client OS, platform and/or hardware.</p> </div> <p>If a user agent chooses to support a Key System implementation that cannot be sufficiently sandboxed or otherwise secured, the user agent <em class="rfc2119" title="SHOULD">SHOULD</em> <a href="#security-consent">ensure that users are fully informed and/or give explicit consent</a> before loading or invoking it. </p> <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note140"><span>Note</span></div> + <div class="note-title marker" aria-level="4" role="heading" id="h-note146"><span>Note</span></div> <p class="">Granting permissions to unauthenticated origins is equivalent to granting the permissions to any origin in the presence of a network attacker. See <a href="#persisted-consent-abuse">abuse of persisted consent</a>. </p> </div> @@ -7365,7 +7642,7 @@ <h4 id="x10.3.2-mitigations"><span class="secno">10.3.2 </span>Mitigations</h4> title="MUST">MUST</em> be per <a href="#browsing-profile">browsing profile</a>. </p> <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note141"><span>Note</span></div> + <div class="note-title marker" aria-level="5" role="heading" id="h-note147"><span>Note</span></div> <p class="">The restriction of the APIs defined in this specification to secure contexts ensures that a <a href="#network-attacks">network attacker</a> cannot exploit permissions granted to an unauthenticated origin. See <a href="#persisted-consent-abuse">abuse of persisted consent</a>. </p> </div> @@ -7409,7 +7686,7 @@ <h3 id="x10.5-cross-directory-attacks"><span class="secno">10.5 </span>Cross-Dir content. </p> <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note142"><span>Note</span></div> + <div class="note-title marker" aria-level="4" role="heading" id="h-note148"><span>Note</span></div> <p class="">Even if a path-restriction feature was made available by user agents, the usual DOM scripting security model would make it trivial to bypass this protection and access the data from any path.</p> </div> <p>Authors on shared hosts are therefore <em class="rfc2119" title="RECOMMENDED">RECOMMENDED</em> to avoid using the APIs defined in this specification because doing so compromises origin-based security and privacy mitigations in user agents.</p> @@ -7485,7 +7762,7 @@ <h4 id="x11.3.2-mitigations"><span class="secno">11.3.2 </span>Mitigations</h4> is exposed outside the client device or to the application, including, for example, in CDM messages. </p> <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note143"><span>Note</span></div> + <div class="note-title marker" aria-level="5" role="heading" id="h-note149"><span>Note</span></div> <div class=""> <p>The type of information covered by this requirement includes but is not limited to:</p> <ul> @@ -7524,10 +7801,10 @@ <h3 id="x11.4-user-tracking"><span class="secno">11.4 </span>User Tracking</h3> <h4 id="x11.4.1-concerns"><span class="secno">11.4.1 </span>Concerns</h4> <p><em>This section is non-normative.</em></p> <p>A third-party host (or any entity, such as an advertiser, capable of getting content distributed to multiple sites) could use a <a href="#distinctive-identifier">Distinctive Identifier</a> or persistent data, including licenses, keys, - key IDs, or - <a href="#record-of-license-destruction">records of license destruction</a>, stored by or on behalf of the <a href="#cdm">CDM</a> to track a user across multiple sessions (including across <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origins</a> and <a href="#browsing-profile">browsing profiles</a>), building a profile of the user's activities or interests. Such tracking would undermine the privacy protections provided by the rest of the web platform and could, for example, - enable highly-targeted advertising not otherwise possible. In conjunction with a site that is aware of the user's real identity (for example, a content provider or e-commerce site that requires authenticated credentials), this could - allow oppressive groups to target individuals with greater accuracy than in a world with purely anonymous web usage. + key IDs, <a href="#record-of-license-destruction">records of license destruction</a>, or <a href="#record-of-key-usage">records of key usage</a>, stored by or on behalf of the <a href="#cdm">CDM</a> to track a user across multiple + sessions (including across <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origins</a> and <a href="#browsing-profile">browsing profiles</a>), building a profile of the user's activities or interests. Such + tracking would undermine the privacy protections provided by the rest of the web platform and could, for example, enable highly-targeted advertising not otherwise possible. In conjunction with a site that is aware of the user's real + identity (for example, a content provider or e-commerce site that requires authenticated credentials), this could allow oppressive groups to target individuals with greater accuracy than in a world with purely anonymous web usage. </p> <p>User- or client-specific information that could be obtained via implementations of the APIs in this specification includes:</p> @@ -7542,12 +7819,13 @@ <h4 id="x11.4.1-concerns"><span class="secno">11.4.1 </span>Concerns</h4> <p>Origins visited (via stored or in-memory data, permissions, etc.)</p> </li> <li> - <p>Content viewed (via stored or in-memory licenses, keys, key IDs, <a href="#record-of-license-destruction">records of license destruction</a>, etc.)</p> + <p>Content viewed (via stored or in-memory licenses, keys, key IDs, <a href="#record-of-license-destruction">records of license destruction</a>, <a href="#record-of-key-usage">records of key usage</a>, etc.)</p> </li> </ul> <p>This specification presents a specific concern because such information is commonly stored outside the user agent (and associated <a href="#browsing-profile">browsing profile</a> storage), often in the CDM.</p> - <p>Since the content of licenses and <a href="#record-of-license-destruction">records of license destruction</a> are Key System-specific and since key IDs may contain any value, these data items could be abused to store user-identifying information.</p> + <p>Since the content of licenses, <a href="#record-of-license-destruction">records of license destruction</a>, and <a href="#record-of-key-usage">records of key usage</a> are Key System-specific and since key IDs may contain any value, these + data items could be abused to store user-identifying information.</p> <p>Key Systems may access or create persistent or semi-persistent identifier(s) for a device or user of a device. In some cases these identifiers may be bound to a specific device in a secure manner. If these identifiers are present in Key System messages, then devices and/or users may be tracked. If the mitigations below are not applied, this could include both tracking of users / devices over time and associating multiple users of a given device. @@ -7661,7 +7939,7 @@ <h4 id="x11.4.2-mitigations"><span class="secno">11.4.2 </span>Mitigations</h4> <p>User agents <em class="rfc2119" title="MAY">MAY</em>, possibly in a manner configured by the user, automatically delete <a href="#distinctive-identifier">Distinctive Identifiers</a> and/or other Key System data after a period of time.</p> <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note144"><span>Note</span></div> + <div class="note-title marker" aria-level="5" role="heading" id="h-note150"><span>Note</span></div> <div class=""> <p>For example, a user agent could be configured to store such data as session-only storage, deleting the data once the user had closed all the browsing contexts that could access it.</p> <p>This can restrict the ability of a site to track a user, as the site would then only be able to track the user across multiple sessions when the user authenticates with the site itself (e.g., by making a purchase or signing @@ -7688,7 +7966,7 @@ <h4 id="x11.4.2-mitigations"><span class="secno">11.4.2 </span>Mitigations</h4> title="MUST">MUST</em> be per <a href="#browsing-profile">browsing profile</a>. </p> <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note145"><span>Note</span></div> + <div class="note-title marker" aria-level="5" role="heading" id="h-note151"><span>Note</span></div> <p class="">The restriction of the APIs defined in this specification to secure contexts ensures that a <a href="#network-attacks">network attacker</a> cannot exploit permissions granted to an unauthenticated origin. See <a href="#persisted-consent-abuse">abuse of persisted consent</a>. </p> </div> @@ -7715,7 +7993,7 @@ <h4 id="x11.4.2-mitigations"><span class="secno">11.4.2 </span>Mitigations</h4> </dl> <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note146"><span>Note</span></div> + <div class="note-title marker" aria-level="5" role="heading" id="h-note152"><span>Note</span></div> <p class="">While these suggestions prevent trivial use of the APIs defined in this specification for user tracking, they do not block it altogether. Within a single origin, a site can continue to track the user during a session, and can then pass all this information to a third party along with any identifying information (names, credit card numbers, addresses) obtained by the site. If a third party cooperates with multiple sites to obtain such information, and if identifiers are not @@ -7823,7 +8101,7 @@ <h3 id="x13.1-source-and-key-known-at-page-load-(clear-key)"><span class="secno" <p class="exampledescription">In this simple example, the source file and <a href="#clear-key">clear-text license</a> are hard-coded in the page. Only one session will ever be created.</p> <div class="example"> - <div class="example-title marker"><span>Example 5</span></div> + <div class="example-title marker"><span>Example 6</span></div> <pre class="highlight hljs xml" aria-busy="false" aria-live="polite"><span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="javascript"> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">onLoad</span>(<span class="hljs-params"></span>) </span>{ <span class="hljs-keyword">var</span> video = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'video'</span>); @@ -7884,7 +8162,7 @@ <h3 id="x13.2-selecting-a-supported-key-system-and-using-initialization-data-fro </p> <div class="example"> - <div class="example-title marker"><span>Example 6</span></div> + <div class="example-title marker"><span>Example 7</span></div> <pre class="highlight hljs xml" aria-busy="false" aria-live="polite"><span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="javascript"> <span class="hljs-keyword">var</span> licenseUrl; <span class="hljs-keyword">var</span> serverCertificate; @@ -8025,7 +8303,7 @@ <h3 id="x13.3-create-mediakeys-before-loading-media"><span class="secno">13.3 </ </p> <div class="example"> - <div class="example-title marker"><span>Example 7</span></div> + <div class="example-title marker"><span>Example 8</span></div> <pre class="highlight hljs xml" aria-busy="false" aria-live="polite"><span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="javascript"> <span class="hljs-keyword">var</span> licenseUrl; <span class="hljs-keyword">var</span> serverCertificate; @@ -8065,7 +8343,7 @@ <h3 id="x13.4-using-all-events"><span class="secno">13.4 </span>Using All Events System might need to send a message.</p> <div class="example"> - <div class="example-title marker"><span>Example 8</span></div> + <div class="example-title marker"><span>Example 9</span></div> <pre class="highlight hljs xml" aria-busy="false" aria-live="polite"><span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="javascript"> <span class="hljs-keyword">var</span> licenseUrl; <span class="hljs-keyword">var</span> serverCertificate; @@ -8159,7 +8437,7 @@ <h3 id="x13.5-stored-license"><span class="secno">13.5 </span>Stored License</h3 <p class="exampledescription">This example requests a persistent license for future use and stores it. It also provides functions for later retrieving the license and for destroying it.</p> <div class="example"> - <div class="example-title marker"><span>Example 9</span></div> + <div class="example-title marker"><span>Example 10</span></div> <pre class="highlight hljs xml" aria-busy="false" aria-live="polite"><span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="javascript"> <span class="hljs-keyword">var</span> licenseUrl; <span class="hljs-keyword">var</span> serverCertificate; From ad062ffabd2ed7ad04ce3412a559db571840b2ec Mon Sep 17 00:00:00 2001 From: Mark Watson <watsonm@netflix.com> Date: Fri, 17 Nov 2017 08:41:17 -0800 Subject: [PATCH 2/4] Update editors --- encrypted-media-respec.html | 12 +- index.html | 13872 +++++++++++++++------------------- 2 files changed, 5978 insertions(+), 7906 deletions(-) diff --git a/encrypted-media-respec.html b/encrypted-media-respec.html index 06e309bd..81f8388a 100644 --- a/encrypted-media-respec.html +++ b/encrypted-media-respec.html @@ -48,12 +48,16 @@ // editors, add as many as you like // only "name" is required editors: [ - { name: "David Dorwin", w3cid: "52505", - company: "Google Inc.", companyURL: "https://www.google.com/" }, - { name: "Jerry Smith", w3cid: "60176", - company: "Microsoft Corporation", companyURL: "https://www.microsoft.com/" }, + + { name: "Mark Watson", url: "", w3cid: "46379", company: "Netflix Inc.", companyURL: "https://www.netflix.com/" }, + { name: "Jerry Smith", w3cid: "60176", + company: "Microsoft Corporation", companyURL: "https://www.microsoft.com/" }, + { name: "Joey Parrish", + company: "Google Inc.", companyURL: "https://www.google.com/" }, + { name: "David Dorwin", note: "Until September 2017", w3cid: "52505", + company: "Google Inc.", companyURL: "https://www.google.com/" }, { name: "Adrian Bateman", note: "Until May 2014", w3cid: "42763", company: "Microsoft Corporation", companyURL: "https://www.microsoft.com/" }, ], diff --git a/index.html b/index.html index b973c3c2..502461af 100644 --- a/index.html +++ b/index.html @@ -1,560 +1,514 @@ -<!DOCTYPE html> -<html lang="en" dir="ltr"> - -<head> - <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> - <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> - <style> - /* --- EXAMPLES --- */ - - div.example-title { - min-width: 7.5em; - color: #b9ab2d; - } - - div.example-title span { - text-transform: uppercase; - } - - aside.example, - div.example, - div.illegal-example { - padding: 0.5em; - margin: 1em 0; - position: relative; - clear: both; - } - - div.illegal-example { - color: red - } - - div.illegal-example p { - color: black - } - - aside.example, - div.example { - padding: .5em; - border-left-width: .5em; - border-left-style: solid; - border-color: #e0cb52; - background: #fcfaee; - } - - aside.example div.example { - border-left-width: .1em; - border-color: #999; - background: #fff; - } - - aside.example div.example div.example-title { - color: #999; - } - </style> - <style> - /* --- ISSUES/NOTES --- */ - - div.issue-title, - div.note-title, - div.ednote-title, - div.warning-title { - padding-right: 1em; - min-width: 7.5em; - color: #b9ab2d; - } - - div.issue-title { - color: #e05252; - } - - div.note-title, - div.ednote-title { - color: #2b2; - } - - div.warning-title { - color: #f22; - } - - div.issue-title span, - div.note-title span, - div.ednote-title span, - div.warning-title span { - text-transform: uppercase; - } - - div.note, - div.issue, - div.ednote, - div.warning { - margin-top: 1em; - margin-bottom: 1em; - } - - .note>p:first-child, - .ednote>p:first-child, - .issue>p:first-child, - .warning>p:first-child { - margin-top: 0 - } - - .issue, - .note, - .ednote, - .warning { - padding: .5em; - border-left-width: .5em; - border-left-style: solid; - } - - div.issue, - div.note, - div.ednote, - div.warning { - padding: 1em 1.2em 0.5em; - margin: 1em 0; - position: relative; - clear: both; - } - - span.note, - span.ednote, - span.issue, - span.warning { - padding: .1em .5em .15em; - } - - .issue { - border-color: #e05252; - background: #fbe9e9; - } - - .note, - .ednote { - border-color: #52e052; - background: #e9fbe9; - } - - .warning { - border-color: #f11; - border-width: .2em; - border-style: solid; - background: #fbe9e9; - } - - .warning-title:before { - content: "⚠"; - /*U+26A0 WARNING SIGN*/ - font-size: 3em; - float: left; - height: 100%; - padding-right: .3em; - vertical-align: top; - margin-top: -0.5em; - } - - li.task-list-item { - list-style: none; - } - - input.task-list-item-checkbox { - margin: 0 0.35em 0.25em -1.6em; - vertical-align: middle; - } - </style> - <style> - /* --- WEB IDL --- */ - - pre.idl { - padding: 1em; - } - - .respec-idl-separator { - padding: 0 0 0.4cm 0; - } - - .respec-idl-separator:last-child { - padding: 0; - } - - @media print { - pre.idl { - white-space: pre-wrap; - } - } - - pre.idl::before { - content: "WebIDL"; - display: block; - width: 150px; - background: #90b8de; - color: #fff; - font-family: sans-serif; - font-weight: bold; - margin: -1em 0 1em -1em; - height: 28px; - line-height: 28px; - } - - .idlType { - color: #ff4500; - font-weight: bold; - text-decoration: none; - } - /*.idlModule*/ - /*.idlModuleID*/ - /*.idlInterface*/ - - .idlInterfaceID, - .idlDictionaryID, - .idlCallbackID, - .idlEnumID { - font-weight: bold; - color: #005a9c; - } - - a.idlEnumItem { - color: #000; - border-bottom: 1px dotted #ccc; - text-decoration: none; - } - - .idlSuperclass { - font-style: italic; - color: #005a9c; - } - /*.idlAttribute*/ - - .idlAttrType, - .idlFieldType, - .idlMemberType { - color: #005a9c; - } - - .idlAttrName, - .idlFieldName, - .idlMemberName { - color: #ff4500; - } - - .idlAttrName a, - .idlFieldName a, - .idlMemberName a { - color: #ff4500; - border-bottom: 1px dotted #ff4500; - text-decoration: none; - } - /*.idlMethod*/ - - .idlMethType, - .idlCallbackType { - color: #005a9c; - } - - .idlMethName { - color: #ff4500; - } - - .idlMethName a { - color: #ff4500; - border-bottom: 1px dotted #ff4500; - text-decoration: none; - } - /*.idlCtor*/ - - .idlCtorName { - color: #ff4500; - } - - .idlCtorName a { - color: #ff4500; - border-bottom: 1px dotted #ff4500; - text-decoration: none; - } - /*.idlParam*/ - - .idlParamType { - color: #005a9c; - } - - .idlParamName, - .idlDefaultValue { - font-style: italic; - } - - .extAttr { - color: #666; - } - /*.idlSectionComment*/ - - .idlSectionComment { - color: gray; - } - /*.idlIterable*/ - - .idlIterableKeyType, - .idlIterableValueType { - color: #005a9c; - } - /*.idlMaplike*/ - - .idlMaplikeKeyType, - .idlMaplikeValueType { - color: #005a9c; - } - /*.idlConst*/ - - .idlConstType { - color: #005a9c; - } - - .idlConstName { - color: #ff4500; - } - - .idlConstName a { - color: #ff4500; - border-bottom: 1px dotted #ff4500; - text-decoration: none; - } - /*.idlException*/ - - .idlExceptionID { - font-weight: bold; - color: #c00; - } +<!DOCTYPE html><html lang="en" dir="ltr"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta name="generator" content="ReSpec 18.3.0"><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"><style>/* --- EXAMPLES --- */ +div.example-title { + min-width: 7.5em; + color: #b9ab2d; +} +div.example-title span { + text-transform: uppercase; +} +aside.example, div.example, div.illegal-example { + padding: 0.5em; + margin: 1em 0; + position: relative; + clear: both; +} +div.illegal-example { color: red } +div.illegal-example p { color: black } +aside.example, div.example { + padding: .5em; + border-left-width: .5em; + border-left-style: solid; + border-color: #e0cb52; + background: #fcfaee; +} + +aside.example div.example { + border-left-width: .1em; + border-color: #999; + background: #fff; +} +aside.example div.example div.example-title { + color: #999; +} +</style><style>/* --- ISSUES/NOTES --- */ +div.issue-title, div.note-title , div.ednote-title, div.warning-title { + padding-right: 1em; + min-width: 7.5em; + color: #b9ab2d; +} +div.issue-title { color: #e05252; } +div.note-title, div.ednote-title { color: #2b2; } +div.warning-title { color: #f22; } +div.issue-title span, div.note-title span, div.ednote-title span, div.warning-title span { + text-transform: uppercase; +} +div.note, div.issue, div.ednote, div.warning { + margin-top: 1em; + margin-bottom: 1em; +} +.note > p:first-child, .ednote > p:first-child, .issue > p:first-child, .warning > p:first-child { margin-top: 0 } +.issue, .note, .ednote, .warning { + padding: .5em; + border-left-width: .5em; + border-left-style: solid; +} +div.issue, div.note , div.ednote, div.warning { + padding: 1em 1.2em 0.5em; + margin: 1em 0; + position: relative; + clear: both; +} +span.note, span.ednote, span.issue, span.warning { padding: .1em .5em .15em; } + +.issue { + border-color: #e05252; + background: #fbe9e9; +} +.note, .ednote { + border-color: #52e052; + background: #e9fbe9; +} + +.warning { + border-color: #f11; + border-width: .2em; + border-style: solid; + background: #fbe9e9; +} + +.warning-title:before{ + content: "⚠"; /*U+26A0 WARNING SIGN*/ + font-size: 3em; + float: left; + height: 100%; + padding-right: .3em; + vertical-align: top; + margin-top: -0.5em; +} + +li.task-list-item { + list-style: none; +} + +input.task-list-item-checkbox { + margin: 0 0.35em 0.25em -1.6em; + vertical-align: middle; +} +</style><style>/* --- WEB IDL --- */ + +pre.idl { + padding: 1em; +} + +.respec-idl-separator { + padding: 0 0 0.4cm 0; +} + +.respec-idl-separator:last-child { + padding: 0; +} + +@media print { + pre.idl { + white-space: pre-wrap; + } +} - .idlTypedefID, - .idlTypedefType { - color: #005a9c; - } +pre.idl::before { + content: "WebIDL"; + display: block; + width: 150px; + background: #90b8de; + color: #fff; + font-family: sans-serif; + font-weight: bold; + margin: -1em 0 1em -1em; + height: 28px; + line-height: 28px; +} - .idlRaises, - .idlRaises a.idlType, - .idlRaises a.idlType code, - .excName a, - .excName a code { - color: #c00; - font-weight: normal; - } +.idlType { + color: #ff4500; + font-weight: bold; + text-decoration: none; +} - .excName a { - font-family: monospace; - } - .idlRaises a.idlType, - .excName a.idlType { - border-bottom: 1px dotted #c00; - } +/*.idlModule*/ - .excGetSetTrue, - .excGetSetFalse, - .prmNullTrue, - .prmNullFalse, - .prmOptTrue, - .prmOptFalse { - width: 45px; - text-align: center; - } - .excGetSetTrue, - .prmNullTrue, - .prmOptTrue { - color: #0c0; - } +/*.idlModuleID*/ - .excGetSetFalse, - .prmNullFalse, - .prmOptFalse { - color: #c00; - } - .idlImplements a { - font-weight: bold; - } +/*.idlInterface*/ - dl.attributes, - dl.methods, - dl.constants, - dl.constructors, - dl.fields, - dl.dictionary-members { - margin-left: 2em; - } +.idlInterfaceID, +.idlDictionaryID, +.idlCallbackID, +.idlEnumID { + font-weight: bold; + color: #005a9c; +} - .attributes dt, - .methods dt, - .constants dt, - .constructors dt, - .fields dt, - .dictionary-members dt { - font-weight: normal; - } +a.idlEnumItem { + color: #000; + border-bottom: 1px dotted #ccc; + text-decoration: none; +} - .attributes dt code, - .methods dt code, - .constants dt code, - .constructors dt code, - .fields dt code, - .dictionary-members dt code { - font-weight: bold; - color: #000; - font-family: monospace; - } +.idlSuperclass { + font-style: italic; + color: #005a9c; +} - .attributes dt code, - .fields dt code, - .dictionary-members dt code { - background: #ffffd2; - } - .attributes dt .idlAttrType code, - .fields dt .idlFieldType code, - .dictionary-members dt .idlMemberType code { - color: #005a9c; - background: transparent; - font-family: inherit; - font-weight: normal; - font-style: italic; - } +/*.idlAttribute*/ - .methods dt code { - background: #d9e6f8; - } +.idlAttrType, +.idlFieldType, +.idlMemberType { + color: #005a9c; +} - .constants dt code { - background: #ddffd2; - } +.idlAttrName, +.idlFieldName, +.idlMemberName { + color: #ff4500; +} - .constructors dt code { - background: #cfc; - } +.idlAttrName a, +.idlFieldName a, +.idlMemberName a { + color: #ff4500; + border-bottom: 1px dotted #ff4500; + text-decoration: none; +} - .attributes dd, - .methods dd, - .constants dd, - .constructors dd, - .fields dd, - .dictionary-members dd { - margin-bottom: 1em; - } - table.parameters, - table.exceptions { - border-spacing: 0; - border-collapse: collapse; - margin: 0.5em 0; - width: 100%; - } +/*.idlMethod*/ - table.parameters { - border-bottom: 1px solid #90b8de; - } +.idlMethType, +.idlCallbackType { + color: #005a9c; +} - table.exceptions { - border-bottom: 1px solid #deb890; - } +.idlMethName { + color: #ff4500; +} - .parameters th, - .exceptions th { - color: inherit; - padding: 3px 5px; - text-align: left; - font-weight: normal; - } +.idlMethName a { + color: #ff4500; + border-bottom: 1px dotted #ff4500; + text-decoration: none; +} - .parameters th { - color: #fff; - background: #005a9c; - } - .exceptions th { - background: #deb890; - } +/*.idlCtor*/ - .parameters td, - .exceptions td { - padding: 3px 10px; - border-top: 1px solid #ddd; - vertical-align: top; - } +.idlCtorName { + color: #ff4500; +} - .parameters tr:first-child td, - .exceptions tr:first-child td { - border-top: none; - } +.idlCtorName a { + color: #ff4500; + border-bottom: 1px dotted #ff4500; + text-decoration: none; +} - .parameters td.prmName, - .exceptions td.excName, - .exceptions td.excCodeName { - width: 100px; - } - .parameters td.prmType { - width: 120px; - } +/*.idlParam*/ - table.exceptions table { - border-spacing: 0; - border-collapse: collapse; - width: 100%; - } +.idlParamType { + color: #005a9c; +} - .respec-button-copy-paste:focus { - text-decoration: none; - border-color: #51a7e8; - outline: none; - box-shadow: 0 0 5px rgba(81, 167, 232, 0.5); - } +.idlParamName, +.idlDefaultValue { + font-style: italic; +} - .respec-button-copy-paste:focus:hover, - .respec-button-copy-paste.selected:focus { - border-color: #51a7e8; - } +.extAttr { + color: #666; +} - .respec-button-copy-paste:hover, - .respec-button-copy-paste:active, - .respec-button-copy-paste.zeroclipboard-is-hover, - .respec-button-copy-paste.zeroclipboard-is-active { - text-decoration: none; - background-color: #ddd; - background-image: linear-gradient(#eee, #ddd); - border-color: #ccc; - } - .respec-button-copy-paste:active, - .respec-button-copy-paste.selected, - .respec-button-copy-paste.zeroclipboard-is-active { - background-color: #dcdcdc; - background-image: none; - border-color: #b5b5b5; - box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15) - } +/*.idlSectionComment*/ - .respec-button-copy-paste.selected:hover { - background-color: #cfcfcf; - } +.idlSectionComment { + color: gray; +} - .respec-button-copy-paste:disabled, - .respec-button-copy-paste:disabled:hover, - .respec-button-copy-paste.disabled, - .respec-button-copy-paste.disabled:hover { - color: rgba(102, 102, 102, 0.5); - cursor: default; - background-color: rgba(229, 229, 229, 0.5); - background-image: none; - border-color: rgba(197, 197, 197, 0.5); - box-shadow: none; - } - </style> +/*.idlIterable*/ + +.idlIterableKeyType, +.idlIterableValueType { + color: #005a9c; +} + + +/*.idlMaplike*/ + +.idlMaplikeKeyType, +.idlMaplikeValueType { + color: #005a9c; +} + + +/*.idlConst*/ + +.idlConstType { + color: #005a9c; +} + +.idlConstName { + color: #ff4500; +} + +.idlConstName a { + color: #ff4500; + border-bottom: 1px dotted #ff4500; + text-decoration: none; +} + + +/*.idlException*/ + +.idlExceptionID { + font-weight: bold; + color: #c00; +} + +.idlTypedefID, +.idlTypedefType { + color: #005a9c; +} + +.idlRaises, +.idlRaises a.idlType, +.idlRaises a.idlType code, +.excName a, +.excName a code { + color: #c00; + font-weight: normal; +} + +.excName a { + font-family: monospace; +} + +.idlRaises a.idlType, +.excName a.idlType { + border-bottom: 1px dotted #c00; +} + +.excGetSetTrue, +.excGetSetFalse, +.prmNullTrue, +.prmNullFalse, +.prmOptTrue, +.prmOptFalse { + width: 45px; + text-align: center; +} + +.excGetSetTrue, +.prmNullTrue, +.prmOptTrue { + color: #0c0; +} + +.excGetSetFalse, +.prmNullFalse, +.prmOptFalse { + color: #c00; +} + +.idlImplements a { + font-weight: bold; +} + +dl.attributes, +dl.methods, +dl.constants, +dl.constructors, +dl.fields, +dl.dictionary-members { + margin-left: 2em; +} + +.attributes dt, +.methods dt, +.constants dt, +.constructors dt, +.fields dt, +.dictionary-members dt { + font-weight: normal; +} + +.attributes dt code, +.methods dt code, +.constants dt code, +.constructors dt code, +.fields dt code, +.dictionary-members dt code { + font-weight: bold; + color: #000; + font-family: monospace; +} + +.attributes dt code, +.fields dt code, +.dictionary-members dt code { + background: #ffffd2; +} + +.attributes dt .idlAttrType code, +.fields dt .idlFieldType code, +.dictionary-members dt .idlMemberType code { + color: #005a9c; + background: transparent; + font-family: inherit; + font-weight: normal; + font-style: italic; +} + +.methods dt code { + background: #d9e6f8; +} + +.constants dt code { + background: #ddffd2; +} + +.constructors dt code { + background: #cfc; +} + +.attributes dd, +.methods dd, +.constants dd, +.constructors dd, +.fields dd, +.dictionary-members dd { + margin-bottom: 1em; +} + +table.parameters, +table.exceptions { + border-spacing: 0; + border-collapse: collapse; + margin: 0.5em 0; + width: 100%; +} + +table.parameters { + border-bottom: 1px solid #90b8de; +} + +table.exceptions { + border-bottom: 1px solid #deb890; +} + +.parameters th, +.exceptions th { + color: inherit; + padding: 3px 5px; + text-align: left; + font-weight: normal; +} + +.parameters th { + color: #fff; + background: #005a9c; +} + +.exceptions th { + background: #deb890; +} + +.parameters td, +.exceptions td { + padding: 3px 10px; + border-top: 1px solid #ddd; + vertical-align: top; +} + +.parameters tr:first-child td, +.exceptions tr:first-child td { + border-top: none; +} + +.parameters td.prmName, +.exceptions td.excName, +.exceptions td.excCodeName { + width: 100px; +} + +.parameters td.prmType { + width: 120px; +} + +table.exceptions table { + border-spacing: 0; + border-collapse: collapse; + width: 100%; +} + +.respec-button-copy-paste:focus { + text-decoration: none; + border-color: #51a7e8; + outline: none; + box-shadow: 0 0 5px rgba(81, 167, 232, 0.5); +} + +.respec-button-copy-paste:focus:hover, +.respec-button-copy-paste.selected:focus { + border-color: #51a7e8; +} + +.respec-button-copy-paste:hover, +.respec-button-copy-paste:active, +.respec-button-copy-paste.zeroclipboard-is-hover, +.respec-button-copy-paste.zeroclipboard-is-active { + text-decoration: none; + background-color: #ddd; + background-image: linear-gradient(#eee, #ddd); + border-color: #ccc; +} + +.respec-button-copy-paste:active, +.respec-button-copy-paste.selected, +.respec-button-copy-paste.zeroclipboard-is-active { + background-color: #dcdcdc; + background-image: none; + border-color: #b5b5b5; + box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15) +} + +.respec-button-copy-paste.selected:hover { + background-color: #cfcfcf; +} + +.respec-button-copy-paste:disabled, +.respec-button-copy-paste:disabled:hover, +.respec-button-copy-paste.disabled, +.respec-button-copy-paste.disabled:hover { + color: rgba(102, 102, 102, 0.5); + cursor: default; + background-color: rgba(229, 229, 229, 0.5); + background-image: none; + border-color: rgba(197, 197, 197, 0.5); + box-shadow: none; +} +</style> + <title>Encrypted Media Extensions</title> - - - - - + + + + + <!-- script to register bugs --> <!-- Disabled unless/until it supports GitHub issues. <script src="https://w3c.github.io/webcomponents/assets/scripts/bug-assist.js"></script> @@ -563,7546 +517,5711 @@ --> <link rel="stylesheet" href="eme.css"> - <style id="respec-mainstyle"> - /***************************************************************** + <style id="respec-mainstyle">/***************************************************************** * ReSpec 3 CSS * Robin Berjon - http://berjon.com/ *****************************************************************/ - /* Override code highlighter background */ - - .hljs { - background: transparent !important; - } - /* --- INLINES --- */ - - em.rfc2119 { - text-transform: lowercase; - font-style: normal; - color: #900; - } - - h1 abbr, - h2 abbr, - h3 abbr, - h4 abbr, - h5 abbr, - h6 abbr, - a abbr { - border: none; - } - - dfn { - font-weight: bold; - } - - a.internalDFN { - color: inherit; - border-bottom: 1px solid #99c; - text-decoration: none; - } - - a.externalDFN { - color: inherit; - border-bottom: 1px dotted #ccc; - text-decoration: none; - } - - a.bibref { - text-decoration: none; - } - - cite .bibref { - font-style: normal; - } - - code { - color: #c83500; - } - - th code { - color: inherit; - } - /* --- TOC --- */ - - .toc a, - .tof a { - text-decoration: none; - } - - a .secno, - a .figno { - color: #000; - } - - ul.tof, - ol.tof { - list-style: none outside none; - } - - .caption { - margin-top: 0.5em; - font-style: italic; - } - /* --- TABLE --- */ - - table.simple { - border-spacing: 0; - border-collapse: collapse; - border-bottom: 3px solid #005a9c; - } - - .simple th { - background: #005a9c; - color: #fff; - padding: 3px 5px; - text-align: left; - } - - .simple th[scope="row"] { - background: inherit; - color: inherit; - border-top: 1px solid #ddd; - } - - .simple td { - padding: 3px 10px; - border-top: 1px solid #ddd; - } - - .simple tr:nth-child(even) { - background: #f0f6ff; - } - /* --- DL --- */ - - .section dd>p:first-child { - margin-top: 0; - } - - .section dd>p:last-child { - margin-bottom: 0; - } - - .section dd { - margin-bottom: 1em; - } - - .section dl.attrs dd, - .section dl.eldef dd { - margin-bottom: 0; - } - - #issue-summary>ul, - .respec-dfn-list { - column-count: 2; - } - - #issue-summary li, - .respec-dfn-list li { - list-style: none; - } - - details.respec-tests-details { - margin-left: 1em; - display: inline-block; - vertical-align: top; - } - details.respec-tests-details>* { - padding-right: 2em; - } - - details.respec-tests-details[open] { - z-index: 999999; - position: absolute; - border: thin solid #cad3e2; - border-radius: .3em; - background-color: white; - padding-bottom: .5em; - } - - details.respec-tests-details[open]>summary { - border-bottom: thin solid #cad3e2; - padding-left: 1em; - margin-bottom: 1em; - line-height: 2em; - } - - details.respec-tests-details>ul { - width: 100%; - margin-top: -0.3em; - } - - details.respec-tests-details>li { - padding-left: 1em; - } - - @media print { - .removeOnSave { - display: none; - } - } - </style> - <style> - /* +/* Override code highlighter background */ +.hljs { + background: transparent !important; +} + +/* --- INLINES --- */ +h1 abbr, +h2 abbr, +h3 abbr, +h4 abbr, +h5 abbr, +h6 abbr, +a abbr { + border: none; +} + +dfn { + font-weight: bold; +} + +a.internalDFN { + color: inherit; + border-bottom: 1px solid #99c; + text-decoration: none; +} + +a.externalDFN { + color: inherit; + border-bottom: 1px dotted #ccc; + text-decoration: none; +} + +a.bibref { + text-decoration: none; +} + +cite .bibref { + font-style: normal; +} + +code { + color: #c83500; +} + +th code { + color: inherit; +} + +/* --- TOC --- */ + +.toc a, +.tof a { + text-decoration: none; +} + +a .secno, +a .figno { + color: #000; +} + +ul.tof, +ol.tof { + list-style: none outside none; +} + +.caption { + margin-top: 0.5em; + font-style: italic; +} + +/* --- TABLE --- */ + +table.simple { + border-spacing: 0; + border-collapse: collapse; + border-bottom: 3px solid #005a9c; +} + +.simple th { + background: #005a9c; + color: #fff; + padding: 3px 5px; + text-align: left; +} + +.simple th[scope="row"] { + background: inherit; + color: inherit; + border-top: 1px solid #ddd; +} + +.simple td { + padding: 3px 10px; + border-top: 1px solid #ddd; +} + +.simple tr:nth-child(even) { + background: #f0f6ff; +} + +/* --- DL --- */ + +.section dd > p:first-child { + margin-top: 0; +} + +.section dd > p:last-child { + margin-bottom: 0; +} + +.section dd { + margin-bottom: 1em; +} + +.section dl.attrs dd, +.section dl.eldef dd { + margin-bottom: 0; +} + +#issue-summary > ul, +.respec-dfn-list { + column-count: 2; +} + +#issue-summary li, +.respec-dfn-list li { + list-style: none; +} + +details.respec-tests-details { + margin-left: 1em; + display: inline-block; + vertical-align: top; +} + +details.respec-tests-details > * { + padding-right: 2em; +} + +details.respec-tests-details[open] { + z-index: 999999; + position: absolute; + border: thin solid #cad3e2; + border-radius: .3em; + background-color: white; + padding-bottom: .5em; +} + +details.respec-tests-details[open] > summary { + border-bottom: thin solid #cad3e2; + padding-left: 1em; + margin-bottom: 1em; + line-height: 2em; +} + +details.respec-tests-details > ul { + width: 100%; + margin-top: -0.3em; +} + +details.respec-tests-details > li { + padding-left: 1em; +} + +@media print { + .removeOnSave { + display: none; + } +} +</style><style>/* github.com style (c) Vasily Polovnyov <vast@whiteants.net> */ - .hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - color: #333; - background: #f8f8f8; - } - - .hljs-comment, - .hljs-quote { - color: #998; - font-style: italic; - } - - .hljs-keyword, - .hljs-selector-tag, - .hljs-subst { - color: #333; - font-weight: bold; - } - - .hljs-number, - .hljs-literal, - .hljs-variable, - .hljs-template-variable, - .hljs-tag .hljs-attr { - color: #008080; - } - - .hljs-string, - .hljs-doctag { - color: #d14; - } - - .hljs-title, - .hljs-section, - .hljs-selector-id { - color: #900; - font-weight: bold; - } - - .hljs-subst { - font-weight: normal; - } - - .hljs-type, - .hljs-class .hljs-title { - color: #458; - font-weight: bold; - } - - .hljs-tag, - .hljs-name, - .hljs-attribute { - color: #000080; - font-weight: normal; - } - - .hljs-regexp, - .hljs-link { - color: #009926; - } - - .hljs-symbol, - .hljs-bullet { - color: #990073; - } - - .hljs-built_in, - .hljs-builtin-name { - color: #0086b3; - } - - .hljs-meta { - color: #999; - font-weight: bold; - } - - .hljs-deletion { - background: #fdd; - } - - .hljs-addition { - background: #dfd; - } - - .hljs-emphasis { - font-style: italic; - } - - .hljs-strong { - font-weight: bold; - } - </style> - <link rel="stylesheet" href="https://www.w3.org/StyleSheets/TR/2016/W3C-ED"> - <link rel="canonical" href="https://www.w3.org/TR/encrypted-media/"> - <script id="initialUserConfig" type="application/json"> +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + color: #333; + background: #f8f8f8; +} + +.hljs-comment, +.hljs-quote { + color: #998; + font-style: italic; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-subst { + color: #333; + font-weight: bold; +} + +.hljs-number, +.hljs-literal, +.hljs-variable, +.hljs-template-variable, +.hljs-tag .hljs-attr { + color: #008080; +} + +.hljs-string, +.hljs-doctag { + color: #d14; +} + +.hljs-title, +.hljs-section, +.hljs-selector-id { + color: #900; + font-weight: bold; +} + +.hljs-subst { + font-weight: normal; +} + +.hljs-type, +.hljs-class .hljs-title { + color: #458; + font-weight: bold; +} + +.hljs-tag, +.hljs-name, +.hljs-attribute { + color: #000080; + font-weight: normal; +} + +.hljs-regexp, +.hljs-link { + color: #009926; +} + +.hljs-symbol, +.hljs-bullet { + color: #990073; +} + +.hljs-built_in, +.hljs-builtin-name { + color: #0086b3; +} + +.hljs-meta { + color: #999; + font-weight: bold; +} + +.hljs-deletion { + background: #fdd; +} + +.hljs-addition { + background: #dfd; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} +</style><link rel="stylesheet" href="https://www.w3.org/StyleSheets/TR/2016/W3C-ED"><link rel="canonical" href="https://www.w3.org/TR/encrypted-media/"><script id="initialUserConfig" type="application/json">{ + "specStatus": "ED", + "implementationReportURI": "https://w3c.github.io/test-results/encrypted-media/all.html", + "shortName": "encrypted-media", + "license": "w3c-software-doc", + "useExperimentalStyles": true, + "edDraftURI": "https://w3c.github.io/encrypted-media/", + "editors": [ + { + "name": "Mark Watson", + "url": "", + "w3cid": "46379", + "company": "Netflix Inc.", + "companyURL": "https://www.netflix.com/" + }, + { + "name": "Jerry Smith", + "w3cid": "60176", + "company": "Microsoft Corporation", + "companyURL": "https://www.microsoft.com/" + }, + { + "name": "Joey Parrish", + "company": "Google Inc.", + "companyURL": "https://www.google.com/" + }, + { + "name": "David Dorwin", + "note": "Until September 2017", + "w3cid": "52505", + "company": "Google Inc.", + "companyURL": "https://www.google.com/" + }, + { + "name": "Adrian Bateman", + "note": "Until May 2014", + "w3cid": "42763", + "company": "Microsoft Corporation", + "companyURL": "https://www.microsoft.com/" + } + ], + "emeDefGroupName": "encrypted-media", + "emeContributors": [ + "Aaron Colwell", + "Alex Russell", + "Anne van Kesteren", + "Bob Lund", + "Boris Zbarsky", + "Chris Pearce", + "David Singer", + "Domenic Denicola", + "Frank Galligan", + "Glenn Adams", + "Henri Sivonen", + "Jer Noble", + "Joe Steele", + "Joey Parrish", + "John Simmons", + "Mark Vickers", + "Pavel Pergamenshchik", + "Philip Jägenstedt", + "Pierre Lemieux", + "Robert O'Callahan", + "Ryan Sleevi", + "Steve Heffernan", + "Steven Robertson", + "Thomás Inskip", + "Travis Leithead", + "Xiaohan Wang" + ], + "otherLinks": [ + { + "key": "Repository", + "data": [ + { + "value": "We are on GitHub.", + "href": "https://github.com/w3c/encrypted-media/" + }, { - "specStatus": "ED", - "implementationReportURI": "https://w3c.github.io/test-results/encrypted-media/all.html", - "shortName": "encrypted-media", - "license": "w3c-software-doc", - "useExperimentalStyles": true, - "edDraftURI": "https://w3c.github.io/encrypted-media/", - "editors": [{ - "name": "David Dorwin", - "w3cid": "52505", - "company": "Google Inc.", - "companyURL": "https://www.google.com/" - }, - { - "name": "Jerry Smith", - "w3cid": "60176", - "company": "Microsoft Corporation", - "companyURL": "https://www.microsoft.com/" - }, - { - "name": "Mark Watson", - "url": "", - "w3cid": "46379", - "company": "Netflix Inc.", - "companyURL": "https://www.netflix.com/" - }, - { - "name": "Adrian Bateman", - "note": "Until May 2014", - "w3cid": "42763", - "company": "Microsoft Corporation", - "companyURL": "https://www.microsoft.com/" - } - ], - "emeDefGroupName": "encrypted-media", - "emeContributors": [ - "Aaron Colwell", - "Alex Russell", - "Anne van Kesteren", - "Bob Lund", - "Boris Zbarsky", - "Chris Pearce", - "David Singer", - "Domenic Denicola", - "Frank Galligan", - "Glenn Adams", - "Henri Sivonen", - "Jer Noble", - "Joe Steele", - "Joey Parrish", - "John Simmons", - "Mark Vickers", - "Pavel Pergamenshchik", - "Philip Jägenstedt", - "Pierre Lemieux", - "Robert O'Callahan", - "Ryan Sleevi", - "Steve Heffernan", - "Steven Robertson", - "Thomás Inskip", - "Travis Leithead", - "Xiaohan Wang" - ], - "otherLinks": [{ - "key": "Repository", - "data": [{ - "value": "We are on GitHub.", - "href": "https://github.com/w3c/encrypted-media/" - }, - { - "value": "File a bug.", - "href": "https://github.com/w3c/encrypted-media/issues" - }, - { - "value": "Commit history.", - "href": "https://github.com/w3c/encrypted-media/commits/gh-pages/encrypted-media-respec.html" - } - ] - }], - "emeUnusedGroupNameExcludeList": [ - "eme-references-from-registry" - ], - "wg": "HTML Media Extensions Working Group", - "wgURI": "https://www.w3.org/html/wg/", - "wgPublicList": "public-html-media", - "wgPatentURI": "https://www.w3.org/2004/01/pp-impl/40318/status", - "noIDLIn": true, - "scheme": "https", - "preProcess": [ - null - ], - "definitionMap": { - "initialization data type": [{ - "0": {}, - "length": 1 - }], - "associable": [{ - "0": {}, - "length": 1 - }], - "non-associable": [{ - "0": {}, - "length": 1 - }], - "associable by an entity": [{ - "0": {}, - "length": 1 - }], - "non-associable by an entity": [{ - "0": {}, - "length": 1 - }], - "non-associable by the application": [{ - "0": {}, - "length": 1 - }], - "associable by the application": [{ - "0": {}, - "length": 1 - }], - "permanent identifier": [{ - "0": {}, - "length": 1 - }], - "distinctive permanent identifier": [{ - "0": {}, - "length": 1 - }], - "uses distinctive identifier(s)": [{ - "0": {}, - "length": 1 - }], - "uses distinctive permanent identifier(s)": [{ - "0": {}, - "length": 1 - }], - "uses distinctive identifier(s) or distinctive permanent identifier(s)": [{ - "0": {}, - "length": 1 - }], - "navigator": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "requestmediakeysystemaccess": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "mediakeysrequirement": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "required": [{ - "0": {}, - "length": 1 - }], - "optional": [{ - "0": {}, - "length": 1 - }], - "not-allowed": [{ - "0": {}, - "length": 1 - }], - "mediakeysystemconfiguration": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "label": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "initdatatypes": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "audiocapabilities": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "videocapabilities": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "distinctiveidentifier": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "persistentstate": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "sessiontypes": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "mediakeysystemmediacapability": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "contenttype": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "robustness": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "mediakeysystemaccess": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "keysystem": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "getconfiguration": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "createmediakeys": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "mediakeys": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "mediakeysessiontype": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "temporary": [{ - "0": {}, - "length": 1 - }], - "persistent-license": [{ - "0": {}, - "length": 1 - }], - "record of license destruction": [{ - "0": {}, - "length": 1 - }], - "persistent-usage-record": [{ - "0": {}, - "length": 1 - }], - "record of key usage": [{ - "0": {}, - "length": 1 - }], - "first decryption time": [{ - "0": {}, - "length": 1 - }], - "latest decryption time": [{ - "0": {}, - "length": 1 - }], - "key usage accuracy": [{ - "0": {}, - "length": 1 - }], - "createsession": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "setservercertificate": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "mediakeysession": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "closed": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "sessionid": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "expiration": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "keystatuses": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "onkeystatuseschange": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "onmessage": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "generaterequest": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "load": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "update": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "close": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "remove": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "mediakeystatusmap": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "size": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "has": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "get": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "iterable": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "mediakeystatus": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "usable": [{ - "0": {}, - "length": 1 - }], - "expired": [{ - "0": {}, - "length": 1 - }], - "released": [{ - "0": {}, - "length": 1 - }], - "output-restricted": [{ - "0": {}, - "length": 1 - }], - "output-downscaled": [{ - "0": {}, - "length": 1 - }], - "status-pending": [{ - "0": {}, - "length": 1 - }], - "internal-error": [{ - "0": {}, - "length": 1 - }], - "mediakeymessagetype": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "license-request": [{ - "0": {}, - "length": 1 - }], - "license-renewal": [{ - "0": {}, - "length": 1 - }], - "license-release": [{ - "0": {}, - "length": 1 - }], - "individualization-request": [{ - "0": {}, - "length": 1 - }], - "mediakeymessageevent": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "messagetype": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "message": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "mediakeymessageeventinit": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "typeerror": [{ - "0": {}, - "length": 1 - }], - "notsupportederror": [{ - "0": {}, - "length": 1 - }], - "invalidstateerror": [{ - "0": {}, - "length": 1 - }], - "quotaexceedederror": [{ - "0": {}, - "length": 1 - }], - "htmlmediaelement": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "onencrypted": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "onwaitingforkey": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "setmediakeys": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "mediaencryptedevent": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "initdatatype": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "initdata": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "mediaencryptedeventinit": [{ - "0": {}, - "length": 1 - }, - { - "0": {}, - "length": 1 - } - ], - "requestmediakeysystemaccess()": [{ - "0": {}, - "length": 1 - }], - "getconfiguration()": [{ - "0": {}, - "length": 1 - }], - "createmediakeys()": [{ - "0": {}, - "length": 1 - }], - "createsession()": [{ - "0": {}, - "length": 1 - }], - "setservercertificate()": [{ - "0": {}, - "length": 1 - }], - "generaterequest()": [{ - "0": {}, - "length": 1 - }], - "load()": [{ - "0": {}, - "length": 1 - }], - "update()": [{ - "0": {}, - "length": 1 - }], - "close()": [{ - "0": {}, - "length": 1 - }], - "remove()": [{ - "0": {}, - "length": 1 - }], - "has()": [{ - "0": {}, - "length": 1 - }], - "get()": [{ - "0": {}, - "length": 1 - }], - "setmediakeys()": [{ - "0": {}, - "length": 1 - }] - }, - "postProcess": [ - null - ], - "localBiblio": { - "EME-INITDATA-REGISTRY": { - "title": "Encrypted Media Extensions Initialization Data Format Registry", - "href": "format-registry/initdata/index.html", - "authors": [ - "David Dorwin", - "Adrian Bateman", - "Mark Watson" - ], - "publisher": "W3C" - }, - "EME-INITDATA-CENC": { - "title": "\"cenc\" Initialization Data Format", - "href": "format-registry/initdata/cenc.html", - "authors": [ - "David Dorwin", - "Adrian Bateman", - "Mark Watson", - "Jerry Smith" - ], - "publisher": "W3C" - }, - "EME-INITDATA-WEBM": { - "title": "\"webm\" Initialization Data Format", - "href": "format-registry/initdata/webm.html", - "authors": [ - "David Dorwin", - "Adrian Bateman", - "Mark Watson", - "Jerry Smith" - ], - "publisher": "W3C" - }, - "EME-INITDATA-KEYIDS": { - "title": "\"keyids\" Initialization Data Format", - "href": "format-registry/initdata/keyids.html", - "authors": [ - "David Dorwin", - "Adrian Bateman", - "Mark Watson", - "Jerry Smith" - ], - "publisher": "W3C" - }, - "EME-STREAM-REGISTRY": { - "title": "Encrypted Media Extensions Stream Format Registry", - "href": "format-registry/stream/index.html", - "authors": [ - "David Dorwin", - "Adrian Bateman", - "Mark Watson" - ], - "publisher": "W3C" - }, - "EME-STREAM-MP4": { - "title": "ISO Common Encryption ('cenc') Protection Scheme for ISO Base Media File Format Stream Format", - "href": "format-registry/stream/mp4.html", - "authors": [ - "David Dorwin", - "Adrian Bateman", - "Mark Watson", - "Jerry Smith" - ], - "publisher": "W3C" - }, - "EME-STREAM-WEBM": { - "title": "WebM Stream Format", - "href": "format-registry/stream/webm.html", - "authors": [ - "David Dorwin", - "Adrian Bateman", - "Mark Watson" - ], - "publisher": "W3C" - } - }, - "publishISODate": "2017-09-19T00:00:00.000Z", - "generatedSubtitle": "Editor's Draft 19 September 2017" + "value": "File a bug.", + "href": "https://github.com/w3c/encrypted-media/issues" + }, + { + "value": "Commit history.", + "href": "https://github.com/w3c/encrypted-media/commits/gh-pages/encrypted-media-respec.html" } - </script> - <meta name="generator" content="ReSpec 16.2.2"> - <meta name="description" content="This proposal extends HTMLMediaElement [HTML51] providing APIs to control playback of encrypted content."> -</head> - -<body aria-busy="false" class="h-entry" id="respecDocument"> - <div class="head" role="contentinfo" id="respecHeader"> - <p> - <a class="logo" href="https://www.w3.org/"><img width="72" height="48" src="https://www.w3.org/StyleSheets/TR/2016/logos/W3C" alt="W3C"></a> - </p> - <p></p> - <h1 class="title p-name" id="title">Encrypted Media Extensions</h1> - <h2 id="w3c-editor's-draft-19-september-2017"><abbr title="World Wide Web Consortium">W3C</abbr> Editor's Draft <time class="dt-published" datetime="2017-09-19">19 September 2017</time></h2> - <dl> - <dt>This version:</dt> - <dd><a class="u-url" href="https://w3c.github.io/encrypted-media/">https://w3c.github.io/encrypted-media/</a></dd> - <dt>Latest published version:</dt> - <dd><a href="https://www.w3.org/TR/encrypted-media/">https://www.w3.org/TR/encrypted-media/</a></dd> - <dt>Latest editor's draft:</dt> - <dd><a href="https://w3c.github.io/encrypted-media/">https://w3c.github.io/encrypted-media/</a></dd> - <dt>Implementation report:</dt> - <dd><a href="https://w3c.github.io/test-results/encrypted-media/all.html">https://w3c.github.io/test-results/encrypted-media/all.html</a></dd> - <dt>Editors:</dt> - <dd class="p-author h-card vcard" data-editor-id="52505"><span class="p-name fn">David Dorwin</span>, <a class="p-org org h-org h-card" href="https://www.google.com/">Google Inc.</a></dd> - <dd class="p-author h-card vcard" data-editor-id="60176"><span class="p-name fn">Jerry Smith</span>, <a class="p-org org h-org h-card" href="https://www.microsoft.com/">Microsoft Corporation</a></dd> - <dd class="p-author h-card vcard" data-editor-id="46379"><span class="p-name fn">Mark Watson</span>, <a class="p-org org h-org h-card" href="https://www.netflix.com/">Netflix Inc.</a></dd> - <dd class="p-author h-card vcard" data-editor-id="42763"><span class="p-name fn">Adrian Bateman</span>, <a class="p-org org h-org h-card" href="https://www.microsoft.com/">Microsoft Corporation</a> (Until May 2014)</dd> - - <dt>Repository:</dt> - <dd> - <a href="https://github.com/w3c/encrypted-media/"> - We are on GitHub. - </a> - </dd> - <dd> - <a href="https://github.com/w3c/encrypted-media/issues"> - File a bug. - </a> - </dd> - <dd> - <a href="https://github.com/w3c/encrypted-media/commits/gh-pages/encrypted-media-respec.html"> - Commit history. - </a> - </dd> - </dl> - <p class="copyright"> - <a href="https://www.w3.org/Consortium/Legal/ipr-notice#Copyright">Copyright</a> © 2017 - - <a href="https://www.w3.org/"><abbr title="World Wide Web Consortium">W3C</abbr></a><sup>®</sup> (<a href="https://www.csail.mit.edu/"><abbr title="Massachusetts Institute of Technology">MIT</abbr></a>, - <a href="https://www.ercim.eu/"><abbr title="European Research Consortium for Informatics and Mathematics">ERCIM</abbr></a>, - <a href="https://www.keio.ac.jp/">Keio</a>, <a href="http://ev.buaa.edu.cn/">Beihang</a>). - <abbr title="World Wide Web Consortium">W3C</abbr> <a href="https://www.w3.org/Consortium/Legal/ipr-notice#Legal_Disclaimer">liability</a>, - <a href="https://www.w3.org/Consortium/Legal/ipr-notice#W3C_Trademarks">trademark</a> and - <a rel="license" href="https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document">permissive document license</a> rules apply. - </p> - <hr title="Separator for header"> - </div> - - <section id="abstract" class="introductory"> - <h2 id="abstract-0">Abstract</h2> - <p>This proposal extends <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#htmlmediaelement-htmlmediaelement">HTMLMediaElement</a></code> [<cite><a class="bibref" href="#bib-HTML51">HTML51</a></cite>] providing APIs to control - playback of encrypted content.</p> - <p>The API supports use cases ranging from simple clear key decryption to high value video (given an appropriate user agent implementation). License/key exchange is controlled by the application, facilitating the development of robust playback applications - supporting a range of content decryption and protection technologies.</p> - <p>This specification does not define a content protection or Digital Rights Management system. Rather, it defines a common API that may be used to discover, select and interact with such systems as well as with simpler content encryption systems. - Implementation of Digital Rights Management is not required for compliance with this specification: only the Clear Key system is required to be implemented as a common baseline.</p> - <p>The common API supports a simple set of content encryption capabilities, leaving application functions such as authentication and authorization to page authors. This is achieved by requiring content protection system-specific messaging to be mediated - by the page rather than assuming out-of-band communication between the encryption system and a license or other server.</p> + ] + } + ], + "emeUnusedGroupNameExcludeList": [ + "eme-references-from-registry" + ], + "wg": "HTML Media Extensions Working Group", + "wgURI": "https://www.w3.org/html/wg/", + "wgPublicList": "public-html-media", + "wgPatentURI": "https://www.w3.org/2004/01/pp-impl/40318/status", + "noIDLIn": true, + "scheme": "https", + "preProcess": [ + null + ], + "definitionMap": { + "initialization data type": [ + { + "0": {}, + "length": 1 + } + ], + "associable": [ + { + "0": {}, + "length": 1 + } + ], + "non-associable": [ + { + "0": {}, + "length": 1 + } + ], + "associable by an entity": [ + { + "0": {}, + "length": 1 + } + ], + "non-associable by an entity": [ + { + "0": {}, + "length": 1 + } + ], + "non-associable by the application": [ + { + "0": {}, + "length": 1 + } + ], + "associable by the application": [ + { + "0": {}, + "length": 1 + } + ], + "permanent identifier": [ + { + "0": {}, + "length": 1 + } + ], + "distinctive permanent identifier": [ + { + "0": {}, + "length": 1 + } + ], + "uses distinctive identifier(s)": [ + { + "0": {}, + "length": 1 + } + ], + "uses distinctive permanent identifier(s)": [ + { + "0": {}, + "length": 1 + } + ], + "uses distinctive identifier(s) or distinctive permanent identifier(s)": [ + { + "0": {}, + "length": 1 + } + ], + "navigator": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "requestmediakeysystemaccess": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "mediakeysrequirement": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "required": [ + { + "0": {}, + "length": 1 + } + ], + "optional": [ + { + "0": {}, + "length": 1 + } + ], + "not-allowed": [ + { + "0": {}, + "length": 1 + } + ], + "mediakeysystemconfiguration": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "label": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "initdatatypes": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "audiocapabilities": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "videocapabilities": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "distinctiveidentifier": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "persistentstate": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "sessiontypes": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "mediakeysystemmediacapability": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "contenttype": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "robustness": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "mediakeysystemaccess": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "keysystem": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "getconfiguration": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "createmediakeys": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "mediakeys": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "mediakeysessiontype": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "temporary": [ + { + "0": {}, + "length": 1 + } + ], + "persistent-license": [ + { + "0": {}, + "length": 1 + } + ], + "record of license destruction": [ + { + "0": {}, + "length": 1 + } + ], + "persistent-usage-record": [ + { + "0": {}, + "length": 1 + } + ], + "record of key usage": [ + { + "0": {}, + "length": 1 + } + ], + "first decryption time": [ + { + "0": {}, + "length": 1 + } + ], + "latest decryption time": [ + { + "0": {}, + "length": 1 + } + ], + "key usage accuracy": [ + { + "0": {}, + "length": 1 + } + ], + "createsession": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "setservercertificate": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "mediakeysession": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "closed": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "sessionid": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "expiration": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "keystatuses": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "onkeystatuseschange": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "onmessage": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "generaterequest": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "load": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "update": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "close": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "remove": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "mediakeystatusmap": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "size": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "has": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "get": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "iterable": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "mediakeystatus": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "usable": [ + { + "0": {}, + "length": 1 + } + ], + "expired": [ + { + "0": {}, + "length": 1 + } + ], + "released": [ + { + "0": {}, + "length": 1 + } + ], + "output-restricted": [ + { + "0": {}, + "length": 1 + } + ], + "output-downscaled": [ + { + "0": {}, + "length": 1 + } + ], + "status-pending": [ + { + "0": {}, + "length": 1 + } + ], + "internal-error": [ + { + "0": {}, + "length": 1 + } + ], + "mediakeymessagetype": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "license-request": [ + { + "0": {}, + "length": 1 + } + ], + "license-renewal": [ + { + "0": {}, + "length": 1 + } + ], + "license-release": [ + { + "0": {}, + "length": 1 + } + ], + "individualization-request": [ + { + "0": {}, + "length": 1 + } + ], + "mediakeymessageevent": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "messagetype": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "message": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "mediakeymessageeventinit": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "typeerror": [ + { + "0": {}, + "length": 1 + } + ], + "notsupportederror": [ + { + "0": {}, + "length": 1 + } + ], + "invalidstateerror": [ + { + "0": {}, + "length": 1 + } + ], + "quotaexceedederror": [ + { + "0": {}, + "length": 1 + } + ], + "htmlmediaelement": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "onencrypted": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "onwaitingforkey": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "setmediakeys": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "mediaencryptedevent": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "initdatatype": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "initdata": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "mediaencryptedeventinit": [ + { + "0": {}, + "length": 1 + }, + { + "0": {}, + "length": 1 + } + ], + "requestmediakeysystemaccess()": [ + { + "0": {}, + "length": 1 + } + ], + "getconfiguration()": [ + { + "0": {}, + "length": 1 + } + ], + "createmediakeys()": [ + { + "0": {}, + "length": 1 + } + ], + "createsession()": [ + { + "0": {}, + "length": 1 + } + ], + "setservercertificate()": [ + { + "0": {}, + "length": 1 + } + ], + "generaterequest()": [ + { + "0": {}, + "length": 1 + } + ], + "load()": [ + { + "0": {}, + "length": 1 + } + ], + "update()": [ + { + "0": {}, + "length": 1 + } + ], + "close()": [ + { + "0": {}, + "length": 1 + } + ], + "remove()": [ + { + "0": {}, + "length": 1 + } + ], + "has()": [ + { + "0": {}, + "length": 1 + } + ], + "get()": [ + { + "0": {}, + "length": 1 + } + ], + "setmediakeys()": [ + { + "0": {}, + "length": 1 + } + ] + }, + "postProcess": [ + null + ], + "localBiblio": { + "EME-INITDATA-REGISTRY": { + "title": "Encrypted Media Extensions Initialization Data Format Registry", + "href": "format-registry/initdata/index.html", + "authors": [ + "David Dorwin", + "Adrian Bateman", + "Mark Watson" + ], + "publisher": "W3C" + }, + "EME-INITDATA-CENC": { + "title": "\"cenc\" Initialization Data Format", + "href": "format-registry/initdata/cenc.html", + "authors": [ + "David Dorwin", + "Adrian Bateman", + "Mark Watson", + "Jerry Smith" + ], + "publisher": "W3C" + }, + "EME-INITDATA-WEBM": { + "title": "\"webm\" Initialization Data Format", + "href": "format-registry/initdata/webm.html", + "authors": [ + "David Dorwin", + "Adrian Bateman", + "Mark Watson", + "Jerry Smith" + ], + "publisher": "W3C" + }, + "EME-INITDATA-KEYIDS": { + "title": "\"keyids\" Initialization Data Format", + "href": "format-registry/initdata/keyids.html", + "authors": [ + "David Dorwin", + "Adrian Bateman", + "Mark Watson", + "Jerry Smith" + ], + "publisher": "W3C" + }, + "EME-STREAM-REGISTRY": { + "title": "Encrypted Media Extensions Stream Format Registry", + "href": "format-registry/stream/index.html", + "authors": [ + "David Dorwin", + "Adrian Bateman", + "Mark Watson" + ], + "publisher": "W3C" + }, + "EME-STREAM-MP4": { + "title": "ISO Common Encryption ('cenc') Protection Scheme for ISO Base Media File Format Stream Format", + "href": "format-registry/stream/mp4.html", + "authors": [ + "David Dorwin", + "Adrian Bateman", + "Mark Watson", + "Jerry Smith" + ], + "publisher": "W3C" + }, + "EME-STREAM-WEBM": { + "title": "WebM Stream Format", + "href": "format-registry/stream/webm.html", + "authors": [ + "David Dorwin", + "Adrian Bateman", + "Mark Watson" + ], + "publisher": "W3C" + } + }, + "publishISODate": "2017-11-17T00:00:00.000Z", + "generatedSubtitle": "Editor's Draft 17 November 2017" +}</script><meta name="description" content="This proposal extends HTMLMediaElement [HTML51] providing APIs to control playback of encrypted content."></head> + <body aria-busy="false" class="h-entry"><div class="head"> + <p> + <a class="logo" href="https://www.w3.org/"><img width="72" height="48" src="https://www.w3.org/StyleSheets/TR/2016/logos/W3C" alt="W3C"></a> + </p> + <p><!--_hyper: -1132959517;--></p> + <h1 class="title p-name" id="title">Encrypted Media Extensions</h1> + <h2 id="w3c-editor-s-draft-17-november-2017"><abbr title="World Wide Web Consortium">W3C</abbr> Editor's Draft <time class="dt-published" datetime="2017-11-17">17 November 2017</time></h2> + <dl> + <dt>This version:</dt> + <dd><a class="u-url" href="https://w3c.github.io/encrypted-media/">https://w3c.github.io/encrypted-media/</a></dd> + <dt>Latest published version:</dt> + <dd><a href="https://www.w3.org/TR/encrypted-media/">https://www.w3.org/TR/encrypted-media/</a></dd> + <dt>Latest editor's draft:</dt> + <dd><a href="https://w3c.github.io/encrypted-media/">https://w3c.github.io/encrypted-media/</a></dd> + <dt>Implementation report:</dt> + <dd><a href="https://w3c.github.io/test-results/encrypted-media/all.html">https://w3c.github.io/test-results/encrypted-media/all.html</a></dd> + <dt>Editors:</dt> + <dd class="p-author h-card vcard" data-editor-id="46379"><span class="p-name fn">Mark Watson</span>, <a class="p-org org h-org h-card" href="https://www.netflix.com/">Netflix Inc.</a></dd> +<dd class="p-author h-card vcard" data-editor-id="60176"><span class="p-name fn">Jerry Smith</span>, <a class="p-org org h-org h-card" href="https://www.microsoft.com/">Microsoft Corporation</a></dd> +<dd class="p-author h-card vcard" data-editor-id="60176"><span class="p-name fn">Joey Parrish</span>, <a class="p-org org h-org h-card" href="https://www.google.com/">Google Inc.</a></dd> +<dd class="p-author h-card vcard" data-editor-id="52505"><span class="p-name fn">David Dorwin</span>, <a class="p-org org h-org h-card" href="https://www.google.com/">Google Inc.</a> (Until September 2017)</dd> +<dd class="p-author h-card vcard" data-editor-id="42763"><span class="p-name fn">Adrian Bateman</span>, <a class="p-org org h-org h-card" href="https://www.microsoft.com/">Microsoft Corporation</a> (Until May 2014)</dd> + + <dt>Repository:</dt> + <dd> + <a href="https://github.com/w3c/encrypted-media/"> + We are on GitHub. + </a> + </dd> + <dd> + <a href="https://github.com/w3c/encrypted-media/issues"> + File a bug. + </a> + </dd> + <dd> + <a href="https://github.com/w3c/encrypted-media/commits/gh-pages/encrypted-media-respec.html"> + Commit history. + </a> + </dd> + </dl> + <p class="copyright"> + <a href="https://www.w3.org/Consortium/Legal/ipr-notice#Copyright">Copyright</a> © + 2017 + + <a href="https://www.w3.org/"><abbr title="World Wide Web Consortium">W3C</abbr></a><sup>®</sup> + (<a href="https://www.csail.mit.edu/"><abbr title="Massachusetts Institute of Technology">MIT</abbr></a>, + <a href="https://www.ercim.eu/"><abbr title="European Research Consortium for Informatics and Mathematics">ERCIM</abbr></a>, + <a href="https://www.keio.ac.jp/">Keio</a>, <a href="http://ev.buaa.edu.cn/">Beihang</a>). + <abbr title="World Wide Web Consortium">W3C</abbr> <a href="https://www.w3.org/Consortium/Legal/ipr-notice#Legal_Disclaimer">liability</a>, + <a href="https://www.w3.org/Consortium/Legal/ipr-notice#W3C_Trademarks">trademark</a> and + <a rel="license" href="https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document">permissive document license</a> + rules apply. + </p> + <hr title="Separator for header"> +</div> + + <section id="abstract" class="introductory"><h2 id="abstract-0">Abstract</h2> + <p>This proposal extends <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#htmlmediaelement-htmlmediaelement">HTMLMediaElement</a></code> [<cite><a class="bibref" href="#bib-HTML51">HTML51</a></cite>] providing APIs to control playback of encrypted content.</p> + <p>The API supports use cases ranging from simple clear key decryption to high value video (given an appropriate user agent implementation). + License/key exchange is controlled by the application, facilitating the development of robust playback applications supporting a range of content decryption and protection technologies.</p> + <p>This specification does not define a content protection or Digital Rights Management system. Rather, it defines a common API that may be used to discover, select and interact with + such systems as well as with simpler content encryption systems. Implementation of Digital Rights Management is not required for compliance with this specification: only the + Clear Key system is required to be implemented as a common baseline.</p> + <p>The common API supports a simple set of content encryption capabilities, leaving application functions such as authentication and authorization to page authors. This is achieved by + requiring content protection system-specific messaging to be mediated by the page rather than assuming out-of-band communication between the encryption system and a license + or other server.</p> </section> - <section id="sotd" class="introductory"> - <h2 id="status-of-this-document">Status of This Document</h2> - <p> - <em>This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current <abbr title="World Wide Web Consortium">W3C</abbr> publications and the latest revision of this technical report can be found in the <a href="https://www.w3.org/TR/"><abbr title="World Wide Web Consortium">W3C</abbr> technical reports index</a> at https://www.w3.org/TR/.</em> - </p> - - + <section id="sotd" class="introductory"><h2 id="status-of-this-document">Status of This Document</h2> + <p> + <em>This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current <abbr title="World Wide Web Consortium">W3C</abbr> publications and the latest revision of this technical report can be found in the <a href="https://www.w3.org/TR/"><abbr title="World Wide Web Consortium">W3C</abbr> technical reports index</a> at https://www.w3.org/TR/.</em> + </p> + + <p> - This document was published by the <a href="https://www.w3.org/html/wg/">HTML Media Extensions Working Group</a> as an Editor's Draft. Comments regarding this document are welcome. Please send them to - <a href="mailto:public-html-media@w3.org">public-html-media@w3.org</a> (<a href="mailto:public-html-media-request@w3.org?subject=subscribe">subscribe</a>, + This document was published by the <a href="https://www.w3.org/html/wg/">HTML Media Extensions Working Group</a> as an Editor's Draft. + Comments regarding this document are welcome. Please send them to + <a href="mailto:public-html-media@w3.org">public-html-media@w3.org</a> + (<a href="mailto:public-html-media-request@w3.org?subject=subscribe">subscribe</a>, <a href="https://lists.w3.org/Archives/Public/public-html-media/">archives</a>). </p> - <p> - Please see the Working Group's <a href="https://w3c.github.io/test-results/encrypted-media/all.html">implementation + <p> + Please see the Working Group's <a href="https://w3c.github.io/test-results/encrypted-media/all.html">implementation report</a>. - </p> - <p> - Publication as an Editor's Draft does not imply endorsement by the <abbr title="World Wide Web Consortium">W3C</abbr> Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate - to cite this document as other than work in progress. - </p> + </p> + <p> + Publication as an Editor's Draft does not imply endorsement by the <abbr title="World Wide Web Consortium">W3C</abbr> + Membership. This is a draft document and may be updated, replaced or obsoleted by other + documents at any time. It is inappropriate to cite this document as other than work in + progress. + </p> <p> - This document was produced by a group operating under the - <a href="https://www.w3.org/Consortium/Patent-Policy-20040205/">5 February 2004 <abbr title="World Wide Web Consortium">W3C</abbr> Patent - Policy</a>. - <abbr title="World Wide Web Consortium">W3C</abbr> maintains a <a href="https://www.w3.org/2004/01/pp-impl/40318/status" rel="disclosure">public list of any patent - disclosures</a> made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains - <a href="https://www.w3.org/Consortium/Patent-Policy-20040205/#def-essential">Essential + This document was produced by + a group + operating under the + <a href="https://www.w3.org/Consortium/Patent-Policy/"><abbr title="World Wide Web Consortium">W3C</abbr> Patent Policy</a>. + <abbr title="World Wide Web Consortium">W3C</abbr> maintains a <a href="https://www.w3.org/2004/01/pp-impl/40318/status" rel="disclosure">public list of any patent + disclosures</a> + made in connection with the deliverables of + the group; that page also includes + instructions for disclosing a patent. An individual who has actual knowledge of a patent + which the individual believes contains + <a href="https://www.w3.org/Consortium/Patent-Policy/#def-essential">Essential Claim(s)</a> must disclose the information in accordance with - <a href="https://www.w3.org/Consortium/Patent-Policy-20040205/#sec-Disclosure">section + <a href="https://www.w3.org/Consortium/Patent-Policy/#sec-Disclosure">section 6 of the <abbr title="World Wide Web Consortium">W3C</abbr> Patent Policy</a>. </p> - <p>This document is governed by the <a id="w3c_process_revision" href="https://www.w3.org/2017/Process-20170301/">1 March 2017 <abbr title="World Wide Web Consortium">W3C</abbr> Process Document</a>. - </p> + <p>This document is governed by the <a id="w3c_process_revision" href="https://www.w3.org/2017/Process-20170301/">1 March 2017 <abbr title="World Wide Web Consortium">W3C</abbr> Process Document</a>. + </p> + +</section><nav id="toc"><h2 class="introductory" id="table-of-contents">Table of Contents</h2><ol class="toc"><li class="tocline"><a href="#introduction" class="tocxref"><span class="secno">1. </span>Introduction</a></li><li class="tocline"><a href="#definitions" class="tocxref"><span class="secno">2. </span>Definitions</a></li><li class="tocline"><a href="#obtaining-access-to-key-systems" class="tocxref"><span class="secno">3. </span>Obtaining Access to Key Systems</a><ol class="toc"><li class="tocline"><a href="#navigator-extension-requestmediakeysystemaccess" class="tocxref"><span class="secno">3.1 </span><span data-dfn-type="dfn" data-idl="" data-title="Navigator" data-dfn-for=""><code>Navigator</code></span> Extension: <code>requestMediaKeySystemAccess()</code></a><ol class="toc"><li class="tocline"><a href="#algorithms" class="tocxref"><span class="secno">3.1.1 </span>Algorithms</a><ol class="toc"><li class="tocline"><a href="#get-supported-configuration" class="tocxref"><span class="secno">3.1.1.1 </span>Get Supported Configuration</a></li><li class="tocline"><a href="#get-supported-configuration-and-consent" class="tocxref"><span class="secno">3.1.1.2 </span>Get Supported Configuration and Consent</a></li><li class="tocline"><a href="#get-supported-capabilities-for-audio-video-type" class="tocxref"><span class="secno">3.1.1.3 </span>Get Supported Capabilities for Audio/Video Type</a></li><li class="tocline"><a href="#get-consent-status" class="tocxref"><span class="secno">3.1.1.4 </span>Get Consent Status</a></li></ol></li></ol></li><li class="tocline"><a href="#mediakeysystemconfiguration-dictionary" class="tocxref"><span class="secno">3.2 </span><span class="formerLink" data-link-type="dfn"><code>MediaKeySystemConfiguration</code></span> dictionary</a></li><li class="tocline"><a href="#mediakeysystemmediacapability-dictionary" class="tocxref"><span class="secno">3.3 </span><span data-dfn-type="dfn" data-idl="" data-title="MediaKeySystemMediaCapability" data-dfn-for=""><code>MediaKeySystemMediaCapability</code></span> dictionary</a></li></ol></li><li class="tocline"><a href="#mediakeysystemaccess-interface" class="tocxref"><span class="secno">4. </span><span data-dfn-type="dfn" data-idl="" data-title="MediaKeySystemAccess" data-dfn-for=""><code>MediaKeySystemAccess</code></span> Interface</a></li><li class="tocline"><a href="#mediakeys-interface" class="tocxref"><span class="secno">5. </span><span data-dfn-type="dfn">MediaKeys</span> Interface</a><ol class="toc"><li class="tocline"><a href="#algorithms-0" class="tocxref"><span class="secno">5.1 </span>Algorithms</a><ol class="toc"><li class="tocline"><a href="#is-persistent-session-type" class="tocxref"><span class="secno">5.1.1 </span>Is persistent session type?</a></li><li class="tocline"><a href="#cdm-unavailable" class="tocxref"><span class="secno">5.1.2 </span>CDM Unavailable</a></li></ol></li><li class="tocline"><a href="#media-keys-storage" class="tocxref"><span class="secno">5.2 </span>Storage and Persistence</a></li></ol></li><li class="tocline"><a href="#mediakeysession-interface" class="tocxref"><span class="secno">6. </span><span data-dfn-type="dfn" data-idl="" data-title="MediaKeySession" data-dfn-for=""><code>MediaKeySession</code></span> Interface</a><ol class="toc"><li class="tocline"><a href="#mediakeystatusmap-interface" class="tocxref"><span class="secno">6.1 </span><span data-dfn-type="dfn" data-idl="" data-title="MediaKeyStatusMap" data-dfn-for=""><code>MediaKeyStatusMap</code></span> Interface</a></li><li class="tocline"><a href="#mediakeymessageevent" class="tocxref"><span class="secno">6.2 </span><span class="formerLink" data-link-type="dfn"><code>MediaKeyMessageEvent</code></span></a><ol class="toc"><li class="tocline"><a href="#mediakeymessageeventinit" class="tocxref"><span class="secno">6.2.1 </span><span data-dfn-type="dfn" data-idl="" data-title="MediaKeyMessageEventInit" data-dfn-for=""><code>MediaKeyMessageEventInit</code></span></a></li></ol></li><li class="tocline"><a href="#mediakeysession-events" class="tocxref"><span class="secno">6.3 </span>Event Summary</a></li><li class="tocline"><a href="#mediakeysession-algorithms" class="tocxref"><span class="secno">6.4 </span>Algorithms</a><ol class="toc"><li class="tocline"><a href="#queue-message" class="tocxref"><span class="secno">6.4.1 </span>Queue a "message" Event</a></li><li class="tocline"><a href="#update-key-statuses" class="tocxref"><span class="secno">6.4.2 </span>Update Key Statuses</a></li><li class="tocline"><a href="#update-expiration" class="tocxref"><span class="secno">6.4.3 </span>Update Expiration</a></li><li class="tocline"><a href="#session-closed" class="tocxref"><span class="secno">6.4.4 </span>Session Closed</a></li><li class="tocline"><a href="#media-key-session-destroyed" class="tocxref"><span class="secno">6.4.5 </span>MediaKeySession Destroyed</a></li><li class="tocline"><a href="#monitor-cdm" class="tocxref"><span class="secno">6.4.6 </span>Monitor for CDM State Changes</a></li></ol></li><li class="tocline"><a href="#exceptions" class="tocxref"><span class="secno">6.5 </span>Exceptions</a></li><li class="tocline"><a href="#session-storage" class="tocxref"><span class="secno">6.6 </span>Session Storage and Persistence</a></li></ol></li><li class="tocline"><a href="#htmlmediaelement-extensions" class="tocxref"><span class="secno">7. </span><span data-dfn-type="dfn" data-idl="" data-title="HTMLMediaElement" data-dfn-for=""><code>HTMLMediaElement</code></span> Extensions</a><ol class="toc"><li class="tocline"><a href="#mediaencryptedevent" class="tocxref"><span class="secno">7.1 </span><span class="formerLink" data-link-type="dfn"><code>MediaEncryptedEvent</code></span></a><ol class="toc"><li class="tocline"><a href="#mediaencryptedeventinit" class="tocxref"><span class="secno">7.1.1 </span><span data-dfn-type="dfn" data-idl="" data-title="MediaEncryptedEventInit" data-dfn-for=""><code>MediaEncryptedEventInit</code></span></a></li></ol></li><li class="tocline"><a href="#htmlmediaelement-events" class="tocxref"><span class="secno">7.2 </span>Event Summary</a></li><li class="tocline"><a href="#htmlmediaelement-algorithms" class="tocxref"><span class="secno">7.3 </span>Algorithms</a><ol class="toc"><li class="tocline"><a href="#media-may-contain-encrypted-blocks" class="tocxref"><span class="secno">7.3.1 </span>Media Data May Contain Encrypted Blocks</a></li><li class="tocline"><a href="#initdata-encountered" class="tocxref"><span class="secno">7.3.2 </span>Initialization Data Encountered</a></li><li class="tocline"><a href="#encrypted-block-encountered" class="tocxref"><span class="secno">7.3.3 </span>Encrypted Block Encountered</a></li><li class="tocline"><a href="#attempt-to-decrypt" class="tocxref"><span class="secno">7.3.4 </span>Attempt to Decrypt</a></li><li class="tocline"><a href="#wait-for-key" class="tocxref"><span class="secno">7.3.5 </span>Wait for Key</a></li><li class="tocline"><a href="#resume-playback" class="tocxref"><span class="secno">7.3.6 </span>Attempt to Resume Playback If Necessary</a></li></ol></li><li class="tocline"><a href="#media-element-restrictions" class="tocxref"><span class="secno">7.4 </span>Media Element Restrictions</a></li></ol></li><li class="tocline"><a href="#implementation-requirements" class="tocxref"><span class="secno">8. </span>Implementation Requirements</a><ol class="toc"><li class="tocline"><a href="#cdm-constraint-requirements" class="tocxref"><span class="secno">8.1 </span>CDM Constraints</a></li><li class="tocline"><a href="#messaging-requirements" class="tocxref"><span class="secno">8.2 </span>Messages and Communication</a></li><li class="tocline"><a href="#persistent-state-requirements" class="tocxref"><span class="secno">8.3 </span>Persistent Data</a><ol class="toc"><li class="tocline"><a href="#use-origin-specific-key-system-storage" class="tocxref"><span class="secno">8.3.1 </span>Use origin-specific and browsing profile-specific Key System storage</a></li><li class="tocline"><a href="#allow-persistent-data-cleared" class="tocxref"><span class="secno">8.3.2 </span>Allow Persistent Data to Be Cleared</a></li><li class="tocline"><a href="#encrypt-or-obfuscate-persistent-data" class="tocxref"><span class="secno">8.3.3 </span>Encrypt or obfuscate Persistent Data</a></li></ol></li><li class="tocline"><a href="#exposed-value-requirements" class="tocxref"><span class="secno">8.4 </span>Values Exposed to the Application</a><ol class="toc"><li class="tocline"><a href="#per-origin-per-profile-values" class="tocxref"><span class="secno">8.4.1 </span>Use Per-Origin Per-Profile Values</a></li><li class="tocline"><a href="#allow-values-to-be-cleared" class="tocxref"><span class="secno">8.4.2 </span>Allow Values to Be Cleared</a></li></ol></li><li class="tocline"><a href="#identifier-requirements" class="tocxref"><span class="secno">8.5 </span>Identifiers</a><ol class="toc"><li class="tocline"><a href="#limit-or-avoid-use-of-distinctive-identifiers-and-permanent-identifiers" class="tocxref"><span class="secno">8.5.1 </span>Limit or Avoid use of Distinctive Identifiers and Permanent Identifiers</a></li><li class="tocline"><a href="#encrypt-identifiers" class="tocxref"><span class="secno">8.5.2 </span>Encrypt Identifiers</a></li><li class="tocline"><a href="#per-origin-per-profile-identifiers" class="tocxref"><span class="secno">8.5.3 </span>Use Per-Origin Per-Profile Identifiers</a></li><li class="tocline"><a href="#non-associable-identifiers" class="tocxref"><span class="secno">8.5.4 </span>Use Non-Associable Identifiers</a></li><li class="tocline"><a href="#allow-identifiers-cleared" class="tocxref"><span class="secno">8.5.5 </span>Allow Identifiers to Be Cleared</a></li></ol></li><li class="tocline"><a href="#individualization" class="tocxref"><span class="secno">8.6 </span>Individualization</a><ol class="toc"><li class="tocline"><a href="#direct-individualization" class="tocxref"><span class="secno">8.6.1 </span>Direct Individualization</a></li><li class="tocline"><a href="#app-assisted-individualization" class="tocxref"><span class="secno">8.6.2 </span>App-Assisted Individualization</a></li></ol></li><li class="tocline"><a href="#support-multiple-keys" class="tocxref"><span class="secno">8.7 </span>Support Multiple Keys</a></li><li class="tocline"><a href="#initialization-data-type-support-requirements" class="tocxref"><span class="secno">8.8 </span>Initialization Data Type Support</a><ol class="toc"><li class="tocline"><a href="#licenses-generated-are-independent-of-content-type" class="tocxref"><span class="secno">8.8.1 </span>Licenses Generated are Independent of Content Type</a></li><li class="tocline"><a href="#support-extraction-from-media-data" class="tocxref"><span class="secno">8.8.2 </span>Support Extraction From Media Data</a></li></ol></li><li class="tocline"><a href="#media-requirements" class="tocxref"><span class="secno">8.9 </span>Supported Media</a><ol class="toc"><li class="tocline"><a href="#unencrypted-container" class="tocxref"><span class="secno">8.9.1 </span>Unencrypted Container</a></li><li class="tocline"><a href="#interoperably-encrypted" class="tocxref"><span class="secno">8.9.2 </span>Interoperably Encrypted</a></li><li class="tocline"><a href="#unencrypted-in-band-support-content" class="tocxref"><span class="secno">8.9.3 </span>Unencrypted In-band Support Content</a></li></ol></li></ol></li><li class="tocline"><a href="#common-key-systems" class="tocxref"><span class="secno">9. </span>Common Key Systems</a><ol class="toc"><li class="tocline"><a href="#clear-key" class="tocxref"><span class="secno">9.1 </span>Clear Key</a><ol class="toc"><li class="tocline"><a href="#clear-key-capabilities" class="tocxref"><span class="secno">9.1.1 </span>Capabilities</a></li><li class="tocline"><a href="#clear-key-behavior" class="tocxref"><span class="secno">9.1.2 </span>Behavior</a></li><li class="tocline"><a href="#clear-key-request-format" class="tocxref"><span class="secno">9.1.3 </span>License Request Format</a><ol class="toc"><li class="tocline"><a href="#clear-key-request-format-example" class="tocxref"><span class="secno">9.1.3.1 </span>Example</a></li></ol></li><li class="tocline"><a href="#clear-key-license-format" class="tocxref"><span class="secno">9.1.4 </span>License Format</a><ol class="toc"><li class="tocline"><a href="#clear-key-license-format-example" class="tocxref"><span class="secno">9.1.4.1 </span>Example</a></li></ol></li><li class="tocline"><a href="#clear-key-release-format" class="tocxref"><span class="secno">9.1.5 </span>License Release Format</a><ol class="toc"><li class="tocline"><a href="#clear-key-release-format-example-1" class="tocxref"><span class="secno">9.1.5.1 </span>Example message reflecting a <span def-id="record-of-license-destruction" class="formerLink"></span></a></li><li class="tocline"><a href="#clear-key-release-format-example-2" class="tocxref"><span class="secno">9.1.5.2 </span>Example message reflecting a <span def-id="record-of-key-usage" class="formerLink"></span></a></li></ol></li><li class="tocline"><a href="#clear-key-release-ack-format" class="tocxref"><span class="secno">9.1.6 </span>License Release Acknowledgement Format</a><ol class="toc"><li class="tocline"><a href="#clear-key-release-ack-format-example" class="tocxref"><span class="secno">9.1.6.1 </span>Example</a></li></ol></li><li class="tocline"><a href="#using-base64url" class="tocxref"><span class="secno">9.1.7 </span>Using base64url</a></li></ol></li></ol></li><li class="tocline"><a href="#security" class="tocxref"><span class="secno">10. </span>Security</a><ol class="toc"><li class="tocline"><a href="#input-data-security" class="tocxref"><span class="secno">10.1 </span>Input Data Attacks and Vulnerabilities</a></li><li class="tocline"><a href="#cdm-security" class="tocxref"><span class="secno">10.2 </span>CDM Attacks and Vulnerabilities</a></li><li class="tocline"><a href="#network-attacks" class="tocxref"><span class="secno">10.3 </span>Network Attacks</a><ol class="toc"><li class="tocline"><a href="#potential-attacks" class="tocxref"><span class="secno">10.3.1 </span>Potential Attacks</a></li><li class="tocline"><a href="#mitigations" class="tocxref"><span class="secno">10.3.2 </span>Mitigations</a></li></ol></li><li class="tocline"><a href="#iframe-attacks" class="tocxref"><span class="secno">10.4 </span><code>iframe</code> Attacks</a><ol class="toc"><li class="tocline"><a href="#potential-attacks-0" class="tocxref"><span class="secno">10.4.1 </span>Potential Attacks</a></li><li class="tocline"><a href="#mitigations-0" class="tocxref"><span class="secno">10.4.2 </span>Mitigations</a></li></ol></li><li class="tocline"><a href="#cross-directory-attacks" class="tocxref"><span class="secno">10.5 </span>Cross-Directory Attacks</a></li></ol></li><li class="tocline"><a href="#privacy" class="tocxref"><span class="secno">11. </span>Privacy</a><ol class="toc"><li class="tocline"><a href="#privacy-disclosure" class="tocxref"><span class="secno">11.1 </span>Information Disclosed by EME and Key Systems</a></li><li class="tocline"><a href="#privacy-fingerprinting" class="tocxref"><span class="secno">11.2 </span>Fingerprinting</a></li><li class="tocline"><a href="#privacy-leakage" class="tocxref"><span class="secno">11.3 </span>Information Leakage</a><ol class="toc"><li class="tocline"><a href="#concerns" class="tocxref"><span class="secno">11.3.1 </span>Concerns</a></li><li class="tocline"><a href="#mitigations-1" class="tocxref"><span class="secno">11.3.2 </span>Mitigations</a></li></ol></li><li class="tocline"><a href="#user-tracking" class="tocxref"><span class="secno">11.4 </span>User Tracking</a><ol class="toc"><li class="tocline"><a href="#concerns-0" class="tocxref"><span class="secno">11.4.1 </span>Concerns</a></li><li class="tocline"><a href="#mitigations-2" class="tocxref"><span class="secno">11.4.2 </span>Mitigations</a></li></ol></li><li class="tocline"><a href="#privacy-storedinfo" class="tocxref"><span class="secno">11.5 </span>Information Stored on User Devices</a><ol class="toc"><li class="tocline"><a href="#concerns-1" class="tocxref"><span class="secno">11.5.1 </span>Concerns</a></li><li class="tocline"><a href="#mitigations-3" class="tocxref"><span class="secno">11.5.2 </span>Mitigations</a></li></ol></li><li class="tocline"><a href="#incomplete-clearing" class="tocxref"><span class="secno">11.6 </span>Incomplete Clearing of Data</a><ol class="toc"><li class="tocline"><a href="#concerns-2" class="tocxref"><span class="secno">11.6.1 </span>Concerns</a></li><li class="tocline"><a href="#mitigations-4" class="tocxref"><span class="secno">11.6.2 </span>Mitigations</a></li></ol></li><li class="tocline"><a href="#private-browsing" class="tocxref"><span class="secno">11.7 </span>Private Browsing Modes</a></li><li class="tocline"><a href="#privacy-secureorigin" class="tocxref"><span class="secno">11.8 </span>Secure Origin and Transport</a></li></ol></li><li class="tocline"><a href="#conformance" class="tocxref"><span class="secno">12. </span>Conformance</a></li><li class="tocline"><a href="#examples" class="tocxref"><span class="secno">13. </span>Examples</a><ol class="toc"><li class="tocline"><a href="#example-source-and-key-known" class="tocxref"><span class="secno">13.1 </span>Source and Key Known at Page Load (Clear Key)</a></li><li class="tocline"><a href="#example-selecting-key-system" class="tocxref"><span class="secno">13.2 </span>Selecting a Supported Key System and Using Initialization Data from the "encrypted" Event</a></li><li class="tocline"><a href="#example-mediakeys-before-source" class="tocxref"><span class="secno">13.3 </span>Create MediaKeys Before Loading Media</a></li><li class="tocline"><a href="#example-using-all-events" class="tocxref"><span class="secno">13.4 </span>Using All Events</a></li><li class="tocline"><a href="#example-stored-license" class="tocxref"><span class="secno">13.5 </span>Stored License</a></li></ol></li><li class="tocline"><a href="#acknowledgements" class="tocxref"><span class="secno">14. </span>Acknowledgments</a></li><li class="tocline"><a href="#references" class="tocxref"><span class="secno">A. </span>References</a><ol class="toc"><li class="tocline"><a href="#normative-references" class="tocxref"><span class="secno">A.1 </span>Normative references</a></li><li class="tocline"><a href="#informative-references" class="tocxref"><span class="secno">A.2 </span>Informative references</a></li></ol></li></ol></nav> + <section id="introduction" class="informative"> + <!--OddPage--><h2 id="x1-introduction"><span class="secno">1. </span>Introduction</h2><p><em>This section is non-normative.</em></p> + <p> + This specification enables script to select content protection mechanisms, control license/key exchange, and + execute custom license management algorithms. + It supports a wide range of use cases without requiring client-side modifications in each user agent for each use case. + This enables content providers to develop a single application solution for all devices. + </p> + <p> + Supported content is encrypted per container-specific "common encryption" specifications, enabling use across key systems. + Supported content has an unencrypted container, enabling metadata to be provided to the application and maintaining compatibility with other <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#htmlmediaelement-htmlmediaelement">HTMLMediaElement</a></code> features. + </p> + <p> + Implementers should pay attention to the mitigations for the security and privacy threats and concerns described in this specification. + In particular, the specification requirements for security and privacy cannot be met without knowledge of the security and privacy properties of the <a href="#key-system">Key System</a> and its implementation(s). + <a href="#implementation-requirements" class="sec-ref"><span class="secno">8.</span> <span class="sec-title">Implementation Requirements</span></a> contains security and privacy provisions related to the integration and use of underlying <a href="#key-system">Key System</a> implementations. + <a href="#security" class="sec-ref"><span class="secno">10.</span> <span class="sec-title">Security</span></a> focuses on external threats, such as input data or network attacks. + <a href="#privacy" class="sec-ref"><span class="secno">11.</span> <span class="sec-title">Privacy</span></a> focuses on the handling of user-specific information and providing users with adequate control over their own privacy. + </p> + <div class="note"><div role="heading" class="note-title marker" id="h-note" aria-level="3"><span>Note</span></div><p class=""> + While this specification is independent of the source of the media data, authors should be aware that many implementations only support decrypting media data provided via Media Source Extensions [<cite><a class="bibref" href="#bib-MEDIA-SOURCE">MEDIA-SOURCE</a></cite>]. + </p></div> + <p> + A generic stack implemented using the API is shown below. + This diagram shows an example flow; other combinations of API calls and events are possible. + </p> + <img src="stack_overview.svg" alt="A generic stack implemented using the proposed APIs" height="700"> </section> - <nav id="toc"> - <h2 class="introductory" id="table-of-contents">Table of Contents</h2> - <ol class="toc" role="directory"> - <li class="tocline"><a href="#introduction" class="tocxref"><span class="secno">1. </span>Introduction</a></li> - <li class="tocline"><a href="#definitions" class="tocxref"><span class="secno">2. </span>Definitions</a></li> - <li class="tocline"><a href="#obtaining-access-to-key-systems" class="tocxref"><span class="secno">3. </span>Obtaining Access to Key Systems</a> - <ol class="toc"> - <li class="tocline"><a href="#navigator-extension:-requestmediakeysystemaccess()" class="tocxref"><span class="secno">3.1 </span><span data-dfn-for="" data-dfn-type="dfn" data-idl="" data-title="Navigator"><code>Navigator</code></span> Extension: <code>requestMediaKeySystemAccess()</code></a> - <ol - class="toc"> - <li class="tocline"><a href="#algorithms" class="tocxref"><span class="secno">3.1.1 </span>Algorithms</a> - <ol class="toc"> - <li class="tocline"><a href="#get-supported-configuration" class="tocxref"><span class="secno">3.1.1.1 </span>Get Supported Configuration</a></li> - <li class="tocline"><a href="#get-supported-configuration-and-consent" class="tocxref"><span class="secno">3.1.1.2 </span>Get Supported Configuration and Consent</a></li> - <li class="tocline"><a href="#get-supported-capabilities-for-audio/video-type" class="tocxref"><span class="secno">3.1.1.3 </span>Get Supported Capabilities for Audio/Video Type</a></li> - <li class="tocline"><a href="#get-consent-status" class="tocxref"><span class="secno">3.1.1.4 </span>Get Consent Status</a></li> - </ol> - </li> - </ol> - </li> - <li class="tocline"><a href="#mediakeysystemconfiguration-dictionary" class="tocxref"><span class="secno">3.2 </span><span class="formerLink" data-link-type="dfn"><code>MediaKeySystemConfiguration</code></span> dictionary</a></li> - <li class="tocline"><a href="#mediakeysystemmediacapability-dictionary" class="tocxref"><span class="secno">3.3 </span><span data-dfn-for="" data-dfn-type="dfn" data-idl="" data-title="MediaKeySystemMediaCapability"><code>MediaKeySystemMediaCapability</code></span> dictionary</a></li> - </ol> - </li> - <li class="tocline"><a href="#mediakeysystemaccess-interface" class="tocxref"><span class="secno">4. </span><span data-dfn-for="" data-dfn-type="dfn" data-idl="" data-title="MediaKeySystemAccess"><code>MediaKeySystemAccess</code></span> Interface</a></li> - <li class="tocline"><a href="#mediakeys-interface" class="tocxref"><span class="secno">5. </span><span data-dfn-for="" data-dfn-type="dfn" data-idl="" data-title="MediaKeys"><code>MediaKeys</code></span> Interface</a> - <ol class="toc"> - <li class="tocline"><a href="#algorithms-0" class="tocxref"><span class="secno">5.1 </span>Algorithms</a> - <ol class="toc"> - <li class="tocline"><a href="#is-persistent-session-type" class="tocxref"><span class="secno">5.1.1 </span>Is persistent session type?</a></li> - <li class="tocline"><a href="#cdm-unavailable" class="tocxref"><span class="secno">5.1.2 </span>CDM Unavailable</a></li> - </ol> - </li> - <li class="tocline"><a href="#media-keys-storage" class="tocxref"><span class="secno">5.2 </span>Storage and Persistence</a></li> - </ol> - </li> - <li class="tocline"><a href="#mediakeysession-interface" class="tocxref"><span class="secno">6. </span><span data-dfn-for="" data-dfn-type="dfn" data-idl="" data-title="MediaKeySession"><code>MediaKeySession</code></span> Interface</a> - <ol class="toc"> - <li class="tocline"><a href="#mediakeystatusmap-interface" class="tocxref"><span class="secno">6.1 </span><span data-dfn-for="" data-dfn-type="dfn" data-idl="" data-title="MediaKeyStatusMap"><code>MediaKeyStatusMap</code></span> Interface</a></li> - <li class="tocline"><a href="#mediakeymessageevent" class="tocxref"><span class="secno">6.2 </span><span class="formerLink" data-link-type="dfn"><code>MediaKeyMessageEvent</code></span></a> - <ol class="toc"> - <li class="tocline"><a href="#mediakeymessageeventinit" class="tocxref"><span class="secno">6.2.1 </span><span data-dfn-for="" data-dfn-type="dfn" data-idl="" data-title="MediaKeyMessageEventInit"><code>MediaKeyMessageEventInit</code></span></a></li> - </ol> - </li> - <li class="tocline"><a href="#mediakeysession-events" class="tocxref"><span class="secno">6.3 </span>Event Summary</a></li> - <li class="tocline"><a href="#mediakeysession-algorithms" class="tocxref"><span class="secno">6.4 </span>Algorithms</a> - <ol class="toc"> - <li class="tocline"><a href="#queue-message" class="tocxref"><span class="secno">6.4.1 </span>Queue a "message" Event</a></li> - <li class="tocline"><a href="#update-key-statuses" class="tocxref"><span class="secno">6.4.2 </span>Update Key Statuses</a></li> - <li class="tocline"><a href="#update-expiration" class="tocxref"><span class="secno">6.4.3 </span>Update Expiration</a></li> - <li class="tocline"><a href="#session-closed" class="tocxref"><span class="secno">6.4.4 </span>Session Closed</a></li> - <li class="tocline"><a href="#media-key-session-destroyed" class="tocxref"><span class="secno">6.4.5 </span>MediaKeySession Destroyed</a></li> - <li class="tocline"><a href="#monitor-cdm" class="tocxref"><span class="secno">6.4.6 </span>Monitor for CDM State Changes</a></li> - </ol> - </li> - <li class="tocline"><a href="#exceptions" class="tocxref"><span class="secno">6.5 </span>Exceptions</a></li> - <li class="tocline"><a href="#session-storage" class="tocxref"><span class="secno">6.6 </span>Session Storage and Persistence</a></li> - </ol> - </li> - <li class="tocline"><a href="#htmlmediaelement-extensions" class="tocxref"><span class="secno">7. </span><span data-dfn-for="" data-dfn-type="dfn" data-idl="" data-title="HTMLMediaElement"><code>HTMLMediaElement</code></span> Extensions</a> - <ol class="toc"> - <li class="tocline"><a href="#mediaencryptedevent" class="tocxref"><span class="secno">7.1 </span><span class="formerLink" data-link-type="dfn"><code>MediaEncryptedEvent</code></span></a> - <ol class="toc"> - <li class="tocline"><a href="#mediaencryptedeventinit" class="tocxref"><span class="secno">7.1.1 </span><span data-dfn-for="" data-dfn-type="dfn" data-idl="" data-title="MediaEncryptedEventInit"><code>MediaEncryptedEventInit</code></span></a></li> - </ol> - </li> - <li class="tocline"><a href="#htmlmediaelement-events" class="tocxref"><span class="secno">7.2 </span>Event Summary</a></li> - <li class="tocline"><a href="#htmlmediaelement-algorithms" class="tocxref"><span class="secno">7.3 </span>Algorithms</a> - <ol class="toc"> - <li class="tocline"><a href="#media-may-contain-encrypted-blocks" class="tocxref"><span class="secno">7.3.1 </span>Media Data May Contain Encrypted Blocks</a></li> - <li class="tocline"><a href="#initdata-encountered" class="tocxref"><span class="secno">7.3.2 </span>Initialization Data Encountered</a></li> - <li class="tocline"><a href="#encrypted-block-encountered" class="tocxref"><span class="secno">7.3.3 </span>Encrypted Block Encountered</a></li> - <li class="tocline"><a href="#attempt-to-decrypt" class="tocxref"><span class="secno">7.3.4 </span>Attempt to Decrypt</a></li> - <li class="tocline"><a href="#wait-for-key" class="tocxref"><span class="secno">7.3.5 </span>Wait for Key</a></li> - <li class="tocline"><a href="#resume-playback" class="tocxref"><span class="secno">7.3.6 </span>Attempt to Resume Playback If Necessary</a></li> - </ol> - </li> - <li class="tocline"><a href="#media-element-restrictions" class="tocxref"><span class="secno">7.4 </span>Media Element Restrictions</a></li> - </ol> - </li> - <li class="tocline"><a href="#implementation-requirements" class="tocxref"><span class="secno">8. </span>Implementation Requirements</a> - <ol class="toc"> - <li class="tocline"><a href="#cdm-constraint-requirements" class="tocxref"><span class="secno">8.1 </span>CDM Constraints</a></li> - <li class="tocline"><a href="#messaging-requirements" class="tocxref"><span class="secno">8.2 </span>Messages and Communication</a></li> - <li class="tocline"><a href="#persistent-state-requirements" class="tocxref"><span class="secno">8.3 </span>Persistent Data</a> - <ol class="toc"> - <li class="tocline"><a href="#use-origin-specific-key-system-storage" class="tocxref"><span class="secno">8.3.1 </span>Use origin-specific and browsing profile-specific Key System storage</a></li> - <li class="tocline"><a href="#allow-persistent-data-cleared" class="tocxref"><span class="secno">8.3.2 </span>Allow Persistent Data to Be Cleared</a></li> - <li class="tocline"><a href="#encrypt-or-obfuscate-persistent-data" class="tocxref"><span class="secno">8.3.3 </span>Encrypt or obfuscate Persistent Data</a></li> - </ol> - </li> - <li class="tocline"><a href="#exposed-value-requirements" class="tocxref"><span class="secno">8.4 </span>Values Exposed to the Application</a> - <ol class="toc"> - <li class="tocline"><a href="#per-origin-per-profile-values" class="tocxref"><span class="secno">8.4.1 </span>Use Per-Origin Per-Profile Values</a></li> - <li class="tocline"><a href="#allow-values-to-be-cleared" class="tocxref"><span class="secno">8.4.2 </span>Allow Values to Be Cleared</a></li> - </ol> - </li> - <li class="tocline"><a href="#identifier-requirements" class="tocxref"><span class="secno">8.5 </span>Identifiers</a> - <ol class="toc"> - <li class="tocline"><a href="#limit-or-avoid-use-of-distinctive-identifiers-and-permanent-identifiers" class="tocxref"><span class="secno">8.5.1 </span>Limit or Avoid use of Distinctive Identifiers and Permanent Identifiers</a></li> - <li class="tocline"><a href="#encrypt-identifiers" class="tocxref"><span class="secno">8.5.2 </span>Encrypt Identifiers</a></li> - <li class="tocline"><a href="#per-origin-per-profile-identifiers" class="tocxref"><span class="secno">8.5.3 </span>Use Per-Origin Per-Profile Identifiers</a></li> - <li class="tocline"><a href="#non-associable-identifiers" class="tocxref"><span class="secno">8.5.4 </span>Use Non-Associable Identifiers</a></li> - <li class="tocline"><a href="#allow-identifiers-cleared" class="tocxref"><span class="secno">8.5.5 </span>Allow Identifiers to Be Cleared</a></li> - </ol> - </li> - <li class="tocline"><a href="#individualization" class="tocxref"><span class="secno">8.6 </span>Individualization</a> - <ol class="toc"> - <li class="tocline"><a href="#direct-individualization" class="tocxref"><span class="secno">8.6.1 </span>Direct Individualization</a></li> - <li class="tocline"><a href="#app-assisted-individualization" class="tocxref"><span class="secno">8.6.2 </span>App-Assisted Individualization</a></li> - </ol> - </li> - <li class="tocline"><a href="#support-multiple-keys" class="tocxref"><span class="secno">8.7 </span>Support Multiple Keys</a></li> - <li class="tocline"><a href="#initialization-data-type-support-requirements" class="tocxref"><span class="secno">8.8 </span>Initialization Data Type Support</a> - <ol class="toc"> - <li class="tocline"><a href="#licenses-generated-are-independent-of-content-type" class="tocxref"><span class="secno">8.8.1 </span>Licenses Generated are Independent of Content Type</a></li> - <li class="tocline"><a href="#support-extraction-from-media-data" class="tocxref"><span class="secno">8.8.2 </span>Support Extraction From Media Data</a></li> - </ol> - </li> - <li class="tocline"><a href="#media-requirements" class="tocxref"><span class="secno">8.9 </span>Supported Media</a> - <ol class="toc"> - <li class="tocline"><a href="#unencrypted-container" class="tocxref"><span class="secno">8.9.1 </span>Unencrypted Container</a></li> - <li class="tocline"><a href="#interoperably-encrypted" class="tocxref"><span class="secno">8.9.2 </span>Interoperably Encrypted</a></li> - <li class="tocline"><a href="#unencrypted-in-band-support-content" class="tocxref"><span class="secno">8.9.3 </span>Unencrypted In-band Support Content</a></li> - </ol> - </li> - </ol> - </li> - <li class="tocline"><a href="#common-key-systems" class="tocxref"><span class="secno">9. </span>Common Key Systems</a> - <ol class="toc"> - <li class="tocline"><a href="#clear-key" class="tocxref"><span class="secno">9.1 </span>Clear Key</a> - <ol class="toc"> - <li class="tocline"><a href="#clear-key-capabilities" class="tocxref"><span class="secno">9.1.1 </span>Capabilities</a></li> - <li class="tocline"><a href="#clear-key-behavior" class="tocxref"><span class="secno">9.1.2 </span>Behavior</a></li> - <li class="tocline"><a href="#clear-key-request-format" class="tocxref"><span class="secno">9.1.3 </span>License Request Format</a> - <ol class="toc"> - <li class="tocline"><a href="#clear-key-request-format-example" class="tocxref"><span class="secno">9.1.3.1 </span>Example</a></li> - </ol> - </li> - <li class="tocline"><a href="#clear-key-license-format" class="tocxref"><span class="secno">9.1.4 </span>License Format</a> - <ol class="toc"> - <li class="tocline"><a href="#clear-key-license-format-example" class="tocxref"><span class="secno">9.1.4.1 </span>Example</a></li> - </ol> - </li> - <li class="tocline"><a href="#clear-key-release-format" class="tocxref"><span class="secno">9.1.5 </span>License Release Format</a> - <ol class="toc"> - <li class="tocline"><a href="#clear-key-release-format-example-1" class="tocxref"><span class="secno">9.1.5.1 </span>Example message reflecting a <span def-id="record-of-license-destruction" class="formerLink"></span></a></li> - <li class="tocline"><a href="#clear-key-release-format-example-2" class="tocxref"><span class="secno">9.1.5.2 </span>Example message reflecting a <span def-id="record-of-key-usage" class="formerLink"></span></a></li> - </ol> - </li> - <li class="tocline"><a href="#clear-key-release-ack-format" class="tocxref"><span class="secno">9.1.6 </span>License Release Acknowledgement Format</a> - <ol class="toc"> - <li class="tocline"><a href="#clear-key-release-ack-format-example" class="tocxref"><span class="secno">9.1.6.1 </span>Example</a></li> - </ol> - </li> - <li class="tocline"><a href="#using-base64url" class="tocxref"><span class="secno">9.1.7 </span>Using base64url</a></li> - </ol> - </li> - </ol> - </li> - <li class="tocline"><a href="#security" class="tocxref"><span class="secno">10. </span>Security</a> - <ol class="toc"> - <li class="tocline"><a href="#input-data-security" class="tocxref"><span class="secno">10.1 </span>Input Data Attacks and Vulnerabilities</a></li> - <li class="tocline"><a href="#cdm-security" class="tocxref"><span class="secno">10.2 </span>CDM Attacks and Vulnerabilities</a></li> - <li class="tocline"><a href="#network-attacks" class="tocxref"><span class="secno">10.3 </span>Network Attacks</a> - <ol class="toc"> - <li class="tocline"><a href="#potential-attacks" class="tocxref"><span class="secno">10.3.1 </span>Potential Attacks</a></li> - <li class="tocline"><a href="#mitigations" class="tocxref"><span class="secno">10.3.2 </span>Mitigations</a></li> - </ol> - </li> - <li class="tocline"><a href="#iframe-attacks" class="tocxref"><span class="secno">10.4 </span><code>iframe</code> Attacks</a> - <ol class="toc"> - <li class="tocline"><a href="#potential-attacks-0" class="tocxref"><span class="secno">10.4.1 </span>Potential Attacks</a></li> - <li class="tocline"><a href="#mitigations-0" class="tocxref"><span class="secno">10.4.2 </span>Mitigations</a></li> - </ol> - </li> - <li class="tocline"><a href="#cross-directory-attacks" class="tocxref"><span class="secno">10.5 </span>Cross-Directory Attacks</a></li> - </ol> - </li> - <li class="tocline"><a href="#privacy" class="tocxref"><span class="secno">11. </span>Privacy</a> - <ol class="toc"> - <li class="tocline"><a href="#privacy-disclosure" class="tocxref"><span class="secno">11.1 </span>Information Disclosed by EME and Key Systems</a></li> - <li class="tocline"><a href="#privacy-fingerprinting" class="tocxref"><span class="secno">11.2 </span>Fingerprinting</a></li> - <li class="tocline"><a href="#privacy-leakage" class="tocxref"><span class="secno">11.3 </span>Information Leakage</a> - <ol class="toc"> - <li class="tocline"><a href="#concerns" class="tocxref"><span class="secno">11.3.1 </span>Concerns</a></li> - <li class="tocline"><a href="#mitigations-1" class="tocxref"><span class="secno">11.3.2 </span>Mitigations</a></li> - </ol> - </li> - <li class="tocline"><a href="#user-tracking" class="tocxref"><span class="secno">11.4 </span>User Tracking</a> - <ol class="toc"> - <li class="tocline"><a href="#concerns-0" class="tocxref"><span class="secno">11.4.1 </span>Concerns</a></li> - <li class="tocline"><a href="#mitigations-2" class="tocxref"><span class="secno">11.4.2 </span>Mitigations</a></li> - </ol> - </li> - <li class="tocline"><a href="#privacy-storedinfo" class="tocxref"><span class="secno">11.5 </span>Information Stored on User Devices</a> - <ol class="toc"> - <li class="tocline"><a href="#concerns-1" class="tocxref"><span class="secno">11.5.1 </span>Concerns</a></li> - <li class="tocline"><a href="#mitigations-3" class="tocxref"><span class="secno">11.5.2 </span>Mitigations</a></li> - </ol> - </li> - <li class="tocline"><a href="#incomplete-clearing" class="tocxref"><span class="secno">11.6 </span>Incomplete Clearing of Data</a> - <ol class="toc"> - <li class="tocline"><a href="#concerns-2" class="tocxref"><span class="secno">11.6.1 </span>Concerns</a></li> - <li class="tocline"><a href="#mitigations-4" class="tocxref"><span class="secno">11.6.2 </span>Mitigations</a></li> - </ol> - </li> - <li class="tocline"><a href="#private-browsing" class="tocxref"><span class="secno">11.7 </span>Private Browsing Modes</a></li> - <li class="tocline"><a href="#privacy-secureorigin" class="tocxref"><span class="secno">11.8 </span>Secure Origin and Transport</a></li> - </ol> - </li> - <li class="tocline"><a href="#conformance" class="tocxref"><span class="secno">12. </span>Conformance</a></li> - <li class="tocline"><a href="#examples" class="tocxref"><span class="secno">13. </span>Examples</a> - <ol class="toc"> - <li class="tocline"><a href="#example-source-and-key-known" class="tocxref"><span class="secno">13.1 </span>Source and Key Known at Page Load (Clear Key)</a></li> - <li class="tocline"><a href="#example-selecting-key-system" class="tocxref"><span class="secno">13.2 </span>Selecting a Supported Key System and Using Initialization Data from the "encrypted" Event</a></li> - <li class="tocline"><a href="#example-mediakeys-before-source" class="tocxref"><span class="secno">13.3 </span>Create MediaKeys Before Loading Media</a></li> - <li class="tocline"><a href="#example-using-all-events" class="tocxref"><span class="secno">13.4 </span>Using All Events</a></li> - <li class="tocline"><a href="#example-stored-license" class="tocxref"><span class="secno">13.5 </span>Stored License</a></li> - </ol> - </li> - <li class="tocline"><a href="#acknowledgements" class="tocxref"><span class="secno">14. </span>Acknowledgments</a></li> - <li class="tocline"><a href="#references" class="tocxref"><span class="secno">A. </span>References</a> - <ol class="toc"> - <li class="tocline"><a href="#normative-references" class="tocxref"><span class="secno">A.1 </span>Normative references</a></li> - <li class="tocline"><a href="#informative-references" class="tocxref"><span class="secno">A.2 </span>Informative references</a></li> - </ol> - </li> - </ol> - </nav> - - <section id="introduction" class="informative"> - <!--OddPage--> - <h2 id="x1.-introduction"><span class="secno">1. </span>Introduction</h2> - <p><em>This section is non-normative.</em></p> - <p> - This specification enables script to select content protection mechanisms, control license/key exchange, and execute custom license management algorithms. It supports a wide range of use cases without requiring client-side modifications in each user agent - for each use case. This enables content providers to develop a single application solution for all devices. - </p> - <p> - Supported content is encrypted per container-specific "common encryption" specifications, enabling use across key systems. Supported content has an unencrypted container, enabling metadata to be provided to the application and maintaining compatibility - with other <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#htmlmediaelement-htmlmediaelement">HTMLMediaElement</a></code> features. - </p> - <p> - Implementers should pay attention to the mitigations for the security and privacy threats and concerns described in this specification. In particular, the specification requirements for security and privacy cannot be met without knowledge of the security - and privacy properties of the <a href="#key-system">Key System</a> and its implementation(s). - <a href="#implementation-requirements" class="sec-ref"><span class="secno">8.</span> <span class="sec-title">Implementation Requirements</span></a> contains security and privacy provisions related to the integration and use of underlying - <a - href="#key-system">Key System</a> implementations. - <a href="#security" class="sec-ref"><span class="secno">10.</span> <span class="sec-title">Security</span></a> focuses on external threats, such as input data or network attacks. - <a href="#privacy" class="sec-ref"><span class="secno">11.</span> <span class="sec-title">Privacy</span></a> focuses on the handling of user-specific information and providing users with adequate control over their own privacy. - </p> - <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note1"><span>Note</span></div> - <p class=""> - While this specification is independent of the source of the media data, authors should be aware that many implementations only support decrypting media data provided via Media Source Extensions [<cite><a class="bibref" href="#bib-MEDIA-SOURCE">MEDIA-SOURCE</a></cite>]. - </p> - </div> - <p> - A generic stack implemented using the API is shown below. This diagram shows an example flow; other combinations of API calls and events are possible. - </p> - <img src="stack_overview.svg" alt="A generic stack implemented using the proposed APIs" height="700"> - </section> - - <section id="definitions"> - <!--OddPage--> - <h2 id="x2.-definitions"><span class="secno">2. </span>Definitions</h2> - - <dl> - <dt id="cdm">Content Decryption Module (CDM)</dt> - <dd> - <p>Content Decryption Module (CDM) is the client component that provides the functionality, including decryption, for one or more <a href="#key-system">Key Systems</a>.</p> - <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note2"><span>Note</span></div> - <p class=""> - Implementations may or may not separate the implementations of CDMs or treat them as separate from the user agent. This is transparent to the API and application. - </p> - </div> - </dd> - - <dt id="key-system">Key System</dt> - <dd> - <p>A Key System is a generic term for a decryption mechanism and/or content protection provider. Key System strings provide unique identification of a Key System. They are used by the user agent to select a <a href="#cdm">CDM</a> and identify - the source of a key-related event. User agents <em class="rfc2119" title="MUST">MUST</em> support the <a href="#common-key-systems">Common Key Systems</a>. User agents <em class="rfc2119" title="MAY">MAY</em> also provide additional - CDMs with corresponding Key System strings. - </p> - - <p>A Key System string is always a reverse domain name. Key System strings are compared using case-sensitive matching. It is <em class="rfc2119" title="RECOMMENDED">RECOMMENDED</em> that CDMs use simple lower-case ASCII key system strings.</p> - <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note3"><span>Note</span></div> - <p class="">For example, "com.example.somesystem".</p> - </div> - - <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note4"><span>Note</span></div> - <p class=""> - Within a given system ("somesystem" in the example), subsystems may be defined as determined by the key system provider. For example, "com.example.somesystem.1" and "com.example.somesystem.1_5". Key System providers should keep in mind that these will - be used for comparison and discovery, so they should be easy to compare and the structure should remain reasonably simple. - </p> - </div> - </dd> - - <dt id="key-session">Key Session</dt> - <dd> - <p>A Key Session, or simply Session, provides a context for message exchange with the <a href="#cdm">CDM</a> as a result of which key(s) are made available to the CDM. Sessions are embodied as <a href="#dom-mediakeysession" class="internalDFN" - data-link-type="dfn"><code>MediaKeySession</code></a> objects. Each Key session is associated with a single instance of <a href="#initialization-data">Initialization Data</a> provided in the <code><a href="#dom-mediakeysession-generaterequest">generateRequest()</a></code> call. - </p> - <p>Each Key Session is associated with a single <a href="#dom-mediakeys" class="internalDFN" data-link-type="dfn"><code>MediaKeys</code></a> object, and only media element(s) associated with that <a href="#dom-mediakeys" class="internalDFN" - data-link-type="dfn"><code>MediaKeys</code></a> object may access key(s) associated with the session. Other <a href="#dom-mediakeys" class="internalDFN" data-link-type="dfn"><code>MediaKeys</code></a> objects, CDM instances, and media - elements <em class="rfc2119" title="MUST NOT">MUST NOT</em> access the key session or use its key(s). Key sessions and the keys they contain are no longer <a href="#usable-for-decryption">usable for decryption</a> once the session - has been closed, including when the <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object is destroyed. - </p> - <p> - All license(s) and key(s) associated with a Key Session which have not been explicitly stored <em class="rfc2119" title="MUST">MUST</em> be destroyed when the Key Session is closed. - </p> - <p><a href="#decryption-key-id">Key IDs</a> <em class="rfc2119" title="MUST">MUST</em> be unique within a session.</p> - </dd> - - <dt id="session-id">Session ID</dt> - <dd> - <p>A Session ID is a unique string identifier generated by the <a href="#cdm">CDM</a> that can be used by the application to identify <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> objects.</p> - - <p>A new Session ID is generated each time the user agent and CDM successfully create a new session.</p> - - <p>Each Session ID <em class="rfc2119" title="SHALL">SHALL</em> be unique within the browsing context in which it was created. For session types for which the <a href="#is-persistent-session-type">Is persistent session type?</a> algorithm - returns <code>true</code>, Session IDs <em class="rfc2119" title="MUST">MUST</em> be unique within the <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> over time, including across browsing sessions. - </p> - - <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note5"><span>Note</span></div> - <p class="">The underlying content protection protocol does not necessarily need to support Session IDs.</p> - </div> - </dd> - - <dt id="decryption-key">Key</dt> - <dd> - <p>Unless otherwise stated, key refers to a decryption key that can be used to decrypt blocks within <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a>. Each such key is uniquely identified by - a <a href="#decryption-key-id">key ID</a>. A key is associated with the <a href="#key-session">session</a> used to provide it to the <a href="#cdm">CDM</a>. (The same key may be present in multiple sessions.) Such keys <em class="rfc2119" - title="MUST">MUST</em> only be provided to the CDM via an <code><a href="#dom-mediakeysession-update">update()</a></code> call. (They may later be loaded by <code><a href="#dom-mediakeysession-load">load()</a></code> as part of the - stored session data.) - </p> - - <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note6"><span>Note</span></div> - <p class="">Authors <em class="rfc2119" title="SHOULD">SHOULD</em> encrypt each set of stream(s) that requires enforcement of a meaningfully different policy with a distinct key (and key ID). For example, if policies may differ between two video - resolutions, stream(s) containing one resolution should not be encrypted with the key used to encrypt stream(s) containing the other resolution. When encrypted, audio streams <em class="rfc2119" title="SHOULD NOT">SHOULD NOT</em> use the same key as any video stream. This is the only way to ensure enforcement and compatibility across clients. - </p> - </div> - </dd> - - <dt id="usable-for-decryption">Usable For Decryption</dt> - <dd> - <p>A key is considered usable for decryption if the CDM is certain the key is currently usable to decrypt one or more blocks of <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a>.</p> - <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note7"><span>Note</span></div> - <p class="">For example, a key is not usable for decryption if its license has expired. Even if its license has not expired, a key is not usable for decryption if other conditions (e.g., output protection) for its use are not currently satisfied.</p> - </div> - </dd> - - <dt id="decryption-key-id">Key ID</dt> - <dd> - <p>A <a href="#decryption-key">key</a> is associated with a key ID that is a sequence of octets and which uniquely identifies the key. The container specifies the ID of the key that can decrypt a block or set of blocks within the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a>. - <a href="#initialization-data">Initialization Data</a> <em class="rfc2119" title="MAY">MAY</em> contain key ID(s) to identify the keys that are needed to decrypt the media data. However, there is no requirement that Initialization - Data contain any or all key IDs used in the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a> or <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-resource">media resource</a>. - <a href="#license">Licenses</a> provided to the <a href="#cdm">CDM</a> associate each key with a key ID so the CDM can select the appropriate key when decrypting an encrypted block of media data. - </p> - </dd> - - <dt id="known-key">Known Key</dt> - <dd> - <p>A key is considered to be known to a session if the <a href="#cdm">CDM</a>'s implementation of the session contains any information - specifically the <a href="#decryption-key-id">key ID</a> - about it, regardless of whether the actual - <a href="#decryption-key">key</a> is usable or its value is known. Known keys are exposed via the <code><a href="#dom-mediakeysession-keystatuses">keyStatuses</a></code> attribute. - </p> - - <p>Keys are considered known even after they become unusable, such as due to <a href="#expiration-time">expiration</a> or if they are removed but a <a href="#record-of-license-destruction">record of license destruction</a> or <a href="#record-of-key-usage">record of key usage</a> is available. Keys only become unknown when they are explicitly removed from a session and any license release message is acknowledged. - </p> - - <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note8"><span>Note</span></div> - <p class="">For example, a key could become unknown if an <code><a href="#dom-mediakeysession-update">update()</a></code> call provides a new license that does not include the key and includes instructions to replace the license(s) that previously - contained the key.</p> - </div> - </dd> - - <dt id="license">License</dt> - <dd> - <p>A license is key system-specific state information that includes one or more <a href="#decryption-key">key(s)</a> - each associated with a <a href="#decryption-key-id">key ID</a> - and potentially other information about key usage.</p> - </dd> - - <dt id="initialization-data">Initialization Data</dt> - <dd> - <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note9"><span>Note</span></div> - <p class=""> - <a href="#key-system">Key Systems</a> usually require a block of initialization data containing information about the stream to be decrypted before they can construct a license request message. This block could be a simple key - or content ID or a more complex structure containing such information. It <em class="rfc2119" title="SHOULD">SHOULD</em> always allow unique identification of the <a href="#decryption-key">key(s)</a> needed to decrypt the content. - This initialization information <em class="rfc2119" title="MAY">MAY</em> be obtained in some application-specific way or provided with the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a>. - </p> - </div> - - <p> - Initialization Data is a generic term for container-specific data that is used by a <a href="#cdm">CDM</a> to generate a license request. - </p> - - <p> - The format of the initialization data depends upon the type of container, and containers <em class="rfc2119" title="MAY">MAY</em> support more than one format of initialization data. The <dfn id="initialization-data-type" data-dfn-type="dfn">Initialization Data Type</dfn> is a string that indicates the format of the accompanying Initialization Data. Initialization Data Type strings are always matched case-sensitively. It is - <em class="rfc2119" title="RECOMMENDED">RECOMMENDED</em> that Initialization Data Type strings are lower-case ASCII strings. - </p> - - <p> - The Encrypted Media Extensions Stream Format and Initialization Data Format Registry [<cite><a class="bibref" href="#bib-EME-INITDATA-REGISTRY">EME-INITDATA-REGISTRY</a></cite>] provides the mapping from <a href="#initialization-data-type">Initialization Data Type</a> string to the specification for each format. - </p> - - <p> - When the user agent encounters Initialization Data in the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a>, it provides that Initialization Data to the application in the <code><a href="#dom-mediaencryptedevent-initdata">initData</a></code> attribute of the <code><a href="#dom-evt-encrypted">encrypted</a></code> event. The user agent <em class="rfc2119" title="MUST NOT">MUST NOT</em> store the Initialization Data or use its <em>content</em> at the time it is encountered. - The application provides Initialization Data to the CDM via <code><a href="#dom-mediakeysession-generaterequest">generateRequest()</a></code>. The user agent <em class="rfc2119" title="MUST NOT">MUST NOT</em> provide Initialization - Data to the CDM by other means. - </p> - - <p>Initialization Data <em class="rfc2119" title="MUST">MUST</em> be a fixed value for a given set of stream(s) or <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a>. It <em class="rfc2119" title="MUST">MUST</em> only contain information related to the keys required to play a given set of stream(s) or <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a>. It <em class="rfc2119" title="MUST NOT">MUST NOT</em> contain application data, client-specific data, user-specific data, or executable code. - </p> - - <p>Initialization Data <em class="rfc2119" title="SHOULD NOT">SHOULD NOT</em> contain Key System-specific data or values. Implementations <em class="rfc2119" title="MUST">MUST</em> support the common formats defined in [<cite><a class="bibref" href="#bib-EME-INITDATA-REGISTRY">EME-INITDATA-REGISTRY</a></cite>] - for each <a href="#initialization-data-type">Initialization Data Type</a> they support. - </p> - <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note10"><span>Note</span></div> - <p class=""> - Use of proprietary formats/contents is discouraged, and supporting or using <em>only</em> proprietary formats is strongly discouraged. Proprietary formats should only be used with pre-existing content or on pre-existing client - devices that do not support the common formats. - </p> - </div> - </dd> - - <dt>Associable Values</dt> - <dd> - <p> - Two or more identifiers or other values are said to be <dfn id="associable" data-dfn-type="dfn">associable</dfn> if they are identical <em>or</em> it is possible - with a reasonable amount of time and effort - to correlate or associate - them. Otherwise, the values are <dfn id="non-associable" data-dfn-type="dfn">non-associable</dfn>. - </p> - <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note11"><span>Note</span></div> - <div class=""> - <p>For example, values created in the following ways are <a href="#associable">associable</a>:</p> - <ul> - <li> - <p>Using a trivially-reversible hash function.</p> - </li> - <li> - <p>Sharing a prefix or other subset</p> - </li> - <li> - <p>Replacing random value N with N+10</p> - </li> - <li> - <p>XORing the origin with a fixed value (because it is trivially reversible)</p> - </li> - </ul> - <p>In contrast, two values that are completely unrelated or cryptographically distinct, such as via a cryptographically strong non-reversible hash function, are <a href="#non-associable">non-associable</a>.</p> - </div> - </div> - <p>Two or more identifiers or other values are said to be <dfn id="associable-by-entity" data-dfn-type="dfn">associable by an entity</dfn> if it is possible - with a reasonable amount of time and effort - for the referenced entity or set - of entities to correlate or associate them without participation of additional entity(ies). Otherwise, the values are <dfn id="non-associable-by-entity" data-dfn-type="dfn">non-associable by an entity</dfn>. - </p> - <p>Two or more identifiers or other values are said to be <dfn id="non-associable-by-application" data-dfn-type="dfn">non-associable by the application</dfn> if they are <a href="#non-associable-by-entity">non-associable by an entity</a> where the entity is set that includes the application, all other applications, and other entities such as servers that they use or with which they communicate. Otherwise, the values would be considered <dfn id="associable-by-application" - data-dfn-type="dfn">associable by the application</dfn>, which is forbidden. - </p> - </dd> - - <dt id="distinctive-value">Distinctive Value</dt> - <dd> - <p> - A Distinctive Value is a value, piece of data, implication of the possession of a piece of data, or an observable behavior or timing that is <em>not</em> shared across a large population of users or client devices. A Distinctive Value - may be in memory or persisted. - </p> - <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note12"><span>Note</span></div> - <div class=""> - <p>Examples of Distinctive Values include but are not limited to:</p> - <ul> - <li> - <p><a href="#distinctive-identifier">Distinctive Identifiers</a></p> - </li> - <li> - <p><a href="#distinctive-permanent-identifier">Distinctive Permanent Identifiers</a></p> - </li> - <li> - <p>Other identifiers</p> - </li> - <li> - <p><a href="#session-id">Session IDs</a></p> - </li> - <li> - <p><a href="#license">Licenses</a></p> - </li> - <li> - <p>Other session data</p> - </li> - </ul> - </div> - </div> - <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note13"><span>Note</span></div> - <p class="">While a Distinctive Value is typically unique to a user or client device, a value does not need to be strictly unique to be distinctive. For example, a value shared among a small number of users could still be distinctive. - </p> - </div> - </dd> - - <dt>Permanent Identifiers</dt> - <dd> - <p> - A <dfn id="permanent-identifier" data-dfn-type="dfn">Permanent Identifier</dfn> is a value, piece of data, implication of the possession of a piece of data, or an observable behavior or timing that is indelible in some way or otherwise - non-trivial for the user to remove, reset, or change. This, includes but is not limited to: - </p> - <ul> - <li> - <p>A hardware or hardware-based identifier</p> - </li> - <li> - <p>A value provisioned in the hardware device in the factory</p> - </li> - <li> - <p>A value associated with or derived from the operating system installation instance</p> - </li> - <li> - <p>A value associated with or derived from the user agent installation instance</p> - </li> - <li> - <p>A value associated with or derived from the <a href="#cdm">CDM</a> or other software component</p> - </li> - <li> - <p>A value in a configuration file or similar semi-permanent data, even if generated on the client</p> - </li> - <li> - <p>Client or other user account values</p> - </li> - </ul> - - <p> - A <dfn id="distinctive-permanent-identifier" data-dfn-type="dfn">Distinctive Permanent Identifier</dfn> is a <a href="#permanent-identifier">Permanent Identifier</a> that is <a href="#distinctive-value">distinctive</a>. - </p> - <p> - When exposed outside the client, Distinctive Permanent Identifiers and values derived from or otherwise related to them <em class="rfc2119" title="MUST">MUST</em> be <a href="#encrypt-identifiers">encrypted</a>. Distinctive Permanent - Identifiers <em class="rfc2119" title="MUST NOT">MUST NOT</em> ever be exposed to the application, even in encrypted form. - </p> - <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note14"><span>Note</span></div> - <p class="">While a Distinctive Permanent Identifier is typically unique to a user or client device, a Distinctive Permanent Identifier does not need to be strictly unique to be distinctive. For example, a Distinctive Permanent Identifier shared - among a small number of users could still be distinctive. - </p> - </div> - <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note15"><span>Note</span></div> - <p class=""> - A Distinctive Permanent Identifier is <em>not</em> a <a href="#distinctive-identifier">Distinctive Identifier</a> because it is not derived or generated (within the scope of this specification). - </p> - </div> - <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note16"><span>Note</span></div> - <p class=""> - <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> controls whether Distinctive Permanent Identifiers may be used. Specifically, Distinctive Permanent Identifiers may only be - used when the value of the <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> member of the <a href="#dom-mediakeysystemaccess" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemAccess</code></a> used to create the <a href="#dom-mediakeys" class="internalDFN" data-link-type="dfn"><code>MediaKeys</code></a> object is <code><a href="#idl-def-MediaKeysRequirement.required">"required"</a></code>. - </p> - </div> - </dd> - - <dt id="distinctive-identifier">Distinctive Identifier</dt> - <dd> - <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note17"><span>Note</span></div> - <div class=""> - <p> - A Distinctive Identifier is a value, including in opaque or encrypted form, for which it is possible for any entity external to the client to correlate or associate values beyond what a user may expect on the web platform (e.g., cookies and other site - data). For example, values that are <a href="#associable-by-entity">associable by an entity other than the application</a> across a) <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origins</a>, - b) <a href="#browsing-profile">browsing profiles</a>, or c) browsing sessions even after the user has attempted to protect his or her privacy by clearing browsing data or values for which it is not easy for a user to break - such association. In particular, a value is a Distinctive Identifier if it is possible for a <a href="#associable-by-entity">central server, such as an individualization server, to associate</a> values across origins, such - as because the <a href="#individualization">individualization</a> requests contained a common value, or because values provided in individualization requests are <a href="#associable-by-entity">associable by such server</a> even after attempts to clear browsing data. Possible causes of this include use of <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifier(s)</a> in the individualization process. - </p> - <p> - Distinctive Identifiers exposed to the application, even in encrypted form, <em class="rfc2119" title="MUST">MUST</em> adhere to the <a href="#identifier-requirements">identifier requirements</a>, including being <a href="#encrypt-identifiers">encrypted</a>, - <a href="#per-origin-per-profile-identifiers">unique per origin and profile</a>, and <a href="#allow-identifiers-cleared">clearable</a>. - </p> - <p> - While the instantiation or use of a Distinctive Identifier is triggered by the application's use of the APIs defined in this specification, the identifier need not be provided to the application to trigger conditions related to Distinctive Identifiers. - (The <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifier(s)</a> <em class="rfc2119" title="MUST NOT">MUST NOT</em> ever be provided to the application, even in opaque or - encrypted form.) - </p> - </div> - </div> - <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note18"><span>Note</span></div> - <p class=""> - <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> controls whether Distinctive Identifiers may be used. Specifically, Distinctive Identifiers may only be used when the value - of the <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> member of the <a href="#dom-mediakeysystemaccess" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemAccess</code></a> used to create the <a href="#dom-mediakeys" class="internalDFN" data-link-type="dfn"><code>MediaKeys</code></a> object is <code><a href="#idl-def-MediaKeysRequirement.required">"required"</a></code>. - </p> - </div> - <p>A Distinctive Identifier is a value, piece of data, implication of the possession of a piece of data, or an observable behavior or timing for which all of the following criteria hold:</p> - <ul> - <li> - <p>It is <a href="#distinctive-value">distinctive</a>.</p> - <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note19"><span>Note</span></div> - <p class="">While a Distinctive Identifier is typically unique to a user or client device, an identifier does not need to be strictly unique to be distinctive. For example, an identifier shared among a small number of users could still - be distinctive. - </p> - </div> - </li> - <li> - <p>It, information about it, or values derived from or otherwise related to it are exposed, even in encrypted form, outside the client. This includes but is not limited to providing it to the application and/or license, <a href="#individualization">individualization</a>, - or other server. - </p> - </li> - <li> - <p>It has one or more the following properties:</p> - <ul> - <li> - <p>It is derived from one or more <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifier(s)</a>.</p> - </li> - <li> - <p>The generation, <a href="#individualization">individualization</a>, provisioning or other process that produced the value involved, used, provided, derived from, or similarly involved one or more <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifier(s)</a> or another Distinctive Identifier.</p> - </li> - <li> - <p>It is <a href="#allow-identifiers-cleared">clearable</a> but not <a href="#allow-persistent-data-cleared-with-cookies">along with cookies and other site data</a>.</p> - <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note20"><span>Note</span></div> - <p class="">For example, via some mechanism external to the user agent, such as an OS-level mechanism.</p> - </div> - </li> - </ul> - <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note21"><span>Note</span></div> - <div class=""> - <p>Other properties of concern that are normatively prohibited for values exposed to the application include:</p> - <ul> - <li> - <p>It is a <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifier</a>.</p> - </li> - <li> - <p>It is <em>not</em> <a href="#allow-identifiers-cleared">clearable</a>.</p> - </li> - <li> - <p>Value(s) created after <a href="#allow-identifiers-cleared">clearing identifier(s)</a> may be <a href="#associable-by-application">associable by the application</a> with previous value(s).</p> - </li> - <li> - <p>Values may not be <a href="#per-origin-per-profile-identifiers">unique per origin and profile</a>.</p> - </li> - <li> - <p>Values for different origins may be <a href="#associable-by-application">associable by the application</a>.</p> - </li> - </ul> - <p>Examples of such normatively prohibited values include but is not limited to:</p> - <ul> - <li> - <p>A single hardware-based value used for all origins.</p> - </li> - <li> - <p>A single random based value used for all origins.</p> - </li> - <li> - <p>A single value obtained from an <a href="#individualization">individualization</a> process that is used for all origins.</p> - </li> - <li> - <p>Values that include all or part of any of the above values.</p> - </li> - <li> - <p>A single value that is used for multiple but not all origins.</p> - </li> - <li> - <p>A single value that is used for all origins on a domain. (Identifiers must be per-<a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a>.)</p> - </li> - <li> - <p>A pre-provisioned origin-specific value.</p> - </li> - <li> - <p>Values generated by trivially-reversible means, which are thus <a href="#associable-by-application">associable by the application</a>, regardless of whether generated on the client or involving an a <a href="#individualization">individualization</a> process. For example, XORing or otherwise integrating (part of) the origin with a fixed value.</p> - </li> - </ul> - </div> - </div> - </li> - </ul> - - <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note22"><span>Note</span></div> - <p class=""> - While Distinctive Identifier are usually <a href="#associable-by-entity">associable by the entity that generated them</a> they <em class="rfc2119" title="MUST">MUST</em> be <a href="#non-associable-by-application">non-associable by applications</a>. - In other words, such correlation or association is only possible by the entity, such as an <a href="#individualization">individualization</a> server, that originally generated the Distinctive Identifier values. Entities with access - to the <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifier(s)</a> <em class="rfc2119" title="MUST NOT">MUST NOT</em> expose this capability to applications, as this would make resulting Distinctive Identifiers - <a href="#associable-by-application">associable by the application</a>, and <em class="rfc2119" title="SHOULD">SHOULD</em> take care to avoid exposing such correlation to other entities or third parties. - </p> - </div> - - <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note23"><span>Note</span></div> - <div class=""> - <p>Examples of Distinctive Identifiers include but are not limited to:</p> - <ul> - <li> - <p>A series of bytes that is included in key requests, different from the series of bytes included by other client devices, and based on or was acquired directly or indirectly using a <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifier</a>.</p> - </li> - <li> - <p>A public key included in key requests that is different from the public keys included in the requests by other client devices and is based on or was acquired directly or indirectly using a <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifier</a>.</p> - </li> - <li> - <p>Demonstration of possession of a private key (e.g., by signing some data) that other client devices do not have and is based on or was acquired directly or indirectly using a <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifier</a>.</p> - </li> - <li> - <p>An identifier for such a key.</p> - </li> - <li> - <p>Such a value used to derive another value that is exposed even though the first value is not directly exposed.</p> - </li> - <li> - <p>A value derived from another Distinctive Identifier.</p> - </li> - <li> - <p>A random value that was reported to a (e.g., <a href="#individualization">individualization</a>) server along with a <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifier</a> or provided by such a - server after providing a <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifier</a>.</p> - </li> - <li> - <p>A value derived from a unique value provisioned in the hardware device in the factory.</p> - </li> - <li> - <p>A value derived from a unique hardware value (e.g., MAC address or serial number) or software value (e.g., operating system installation instance or operating system user account name) in the hardware device in the factory.</p> - </li> - <li> - <p>A value derived from a unique value embedded in the CDM binary or other file used by the CDM.</p> - </li> - </ul> - <p>Examples of things that are <em>not</em> Distinctive Identifiers:</p> - <ul> - <li> - <p>A public key shared among all copies of a given CDM version if the installed base is large.</p> - </li> - <li> - <p>A nonce or ephemeral key that is unique but used in only one session.</p> - </li> - <li> - <p>A value that is not exposed, even in derived or similar ways, outside the client, including via <a href="#individualization">individualization</a> or similar.</p> - </li> - <li> - <p>Device-unique keys used in attestations between, for example, the video pipeline and the CDM when the CDM does not let these attestations further flow to the application and instead makes a new attestation on its own using - a key that does not constitute a Distinctive Identifier.</p> - </li> - <li> - <p>A value that is fully cleared/clearable along with browsing data, such as cookies, after which it will be replaced by a value that is <a href="#non-associable">non-associable</a> (not just <a href="#non-associable-by-application">non-associable by applications</a>), - even by a central server such as an <a href="#individualization">individualization</a> server, AND one or more of the following:</p> - <ul> - <li> - <p>No <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifier</a> or Distinctive Identifier was involved in the generation of the value.</p> - </li> - <li> - <p>It is a random value generated <em>without</em> inputs from the system.</p> - </li> - <li> - <p>It is a value provided by a server without the use of or knowledge of another Distinctive Identifier.</p> - </li> - </ul> - </li> - </ul> - </div> - </div> - </dd> - - <dt>Use of Distinctive Identifiers and Distinctive Permanent Identifiers</dt> - <dd> - <p> - An implementation, configuration, instance, or object <dfn id="uses-distinctive-identifiers" data-dfn-type="dfn">uses Distinctive Identifier(s)</dfn> if, at any time during its lifetime or the lifetime of related such entities, it - exposes, even in encrypted form, one or more <a href="#distinctive-identifier">Distinctive Identifier(s)</a>, information about them, or values derived from or otherwise related to them outside the client. This includes but is not - limited to providing such a value to the application and/or license, <a href="#individualization">individualization</a>, or other server. - </p> - <p> - An implementation, configuration, instance, or object <dfn id="uses-distinctive-permanent-identifiers" data-dfn-type="dfn">uses Distinctive Permanent Identifier(s)</dfn> if, at any time during its lifetime or the lifetime of related - such entities, it exposes, even in encrypted form, one or more <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifier(s)</a>, information about them, or values derived from or otherwise related to them outside - the client. This includes but is not limited to providing such a value to an <a href="#individualization">individualization</a> server. Such values <em class="rfc2119" title="MUST NOT">MUST NOT</em> be provided to the application. - </p> - <p> - An implementation, configuration, instance, or object <dfn id="uses-distinctive-identifiers-or-distinctive-permanent-identifiers" data-dfn-type="dfn">uses Distinctive Identifier(s) or Distinctive Permanent Identifier(s)</dfn> if it - <a href="#uses-distinctive-identifiers">uses Distinctive Identifier(s)</a> and/or <a href="#uses-distinctive-permanent-identifiers">uses Distinctive Permanent Identifier(s)</a>. - </p> - <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note24"><span>Note</span></div> - <p class=""> - <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> controls whether <a href="#distinctive-identifier">Distinctive Identifiers</a> and <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifiers</a> may be used. Specifically, such identifiers may only be used when the value of the <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> member of the <a href="#dom-mediakeysystemaccess" - class="internalDFN" data-link-type="dfn"><code>MediaKeySystemAccess</code></a> used to create the <a href="#dom-mediakeys" class="internalDFN" data-link-type="dfn"><code>MediaKeys</code></a> object is <code><a href="#idl-def-MediaKeysRequirement.required">"required"</a></code>. - </p> - </div> - </dd> - - <dt id="cross-origin">Cross Origin Limitations</dt> - <dd> - <p>During playback, embedded media data is exposed to script in the embedding <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a>. In order for the API to provide <a href="#initialization-data">Initialization Data</a> in the <code><a href="#dom-evt-encrypted">encrypted</a></code> event, <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a> <em class="rfc2119" title="MUST">MUST</em> be <a href="https://www.w3.org/TR/html51/browsers.html#same-origin">CORS-same-origin</a> with the embedding page. If <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a> is cross-origin with the embedding document, authors <em class="rfc2119" title="SHOULD">SHOULD</em> use the - <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#element-attrdef-media-crossorigin">crossorigin</a></code> attribute on the <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#htmlmediaelement-htmlmediaelement">HTMLMediaElement</a></code> and CORS headers on the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a> response to make it <a href="https://www.w3.org/TR/html51/browsers.html#same-origin">CORS-same-origin</a>. - </p> - </dd> - - <dt id="mixed-content">Mixed Content Limitations</dt> - <dd> - <p>During playback, embedded media data is exposed to script in the embedding <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a>. In order for the API to provide <a href="#initialization-data">Initialization Data</a> in the <code><a href="#dom-evt-encrypted">encrypted</a></code> event, <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a> <em class="rfc2119" title="MUST NOT">MUST NOT</em> be Mixed Content - [<cite><a class="bibref" href="#bib-MIXED-CONTENT">MIXED-CONTENT</a></cite>]. - </p> - </dd> - - <dt id="time">Time</dt> - <dd> - <p>Time <em class="rfc2119" title="MUST">MUST</em> be equivalent to that represented in <a class="external" href="https://tc39.github.io/ecma262/#sec-time-values-and-time-range">ECMAScript <span class="estype">Time Values and Time Range</span></a> [<cite><a class="bibref" href="#bib-ECMA-262">ECMA-262</a></cite>]. - </p> - <p>Time will equal <code>NaN</code> if no such time exists or if the time is indeterminate. It should never have the value <code>Infinity</code>. - </p> - <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note25"><span>Note</span></div> - <p class=""> - Time generally represents an instant in time with millisecond accuracy; however, that alone is not a sufficient definition. The defined Time Values and Time Range reference adds other important requirements. - </p> - </div> - </dd> - - <dt id="expiration-time">Expiration Time</dt> - <dd> - <p> - The <a href="#time">time</a> after which key(s) will no longer be <a href="#usable-for-decryption">usable for decryption</a>. - </p> - </dd> - - <dt id="browsing-profile">Browsing Profile</dt> - <dd> - <p> - A User Agent on a given machine may support execution in a variety of different contexts or modes or temporary states that are expected to behave independently with respect to application-visible state and data. In particular, all stored data is expected - to be independent. In this specification we refer to such independent contexts or modes as "Browsing Profiles". - </p> - <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note26"><span>Note</span></div> - <p class=""> - Examples of such independent contexts include if the user agent is running in different operating system user accounts or if the user agent provides the capability to define multiple independent profiles for a single account. - </p> - </div> - </dd> - <dt id="valid-media-mime-type">Valid Media MIME Type</dt> - <dd> - <p> - A valid media MIME type is a media <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#mime-types">MIME type</a> that is also a <a href="https://www.w3.org/TR/html51/infrastructure.html#valid-mime-type">valid MIME type</a> [<cite><a class="bibref" href="#bib-HTML51">HTML51</a></cite>]. When a MIME type includes parameters, such as `"codecs"` [<cite><a class="bibref" href="#bib-RFC6381">RFC6381</a></cite>], such parameters <em class="rfc2119" title="MUST">MUST</em> also be valid per the relevant specification. - </p> - <p> - When used with the features defined in this specification, MIME type strings <em class="rfc2119" title="SHOULD">SHOULD</em> explicitly specify codecs and codec constraints (e.g., per [<cite><a class="bibref" href="#bib-RFC6381">RFC6381</a></cite>]) - unless these are normatively implied by the container. - </p> - </dd> - </dl> - </section> - - - <section id="obtaining-access-to-key-systems"> - <!--OddPage--> - <h2 id="x3.-obtaining-access-to-key-systems"><span class="secno">3. </span>Obtaining Access to Key Systems</h2> - <p>This section defines the mechanism for obtaining access to a key system. The inclusion of capabilities in the request also enables feature detection. - </p> - <p>The steps of an algorithm are always aborted when rejecting a promise.</p> - - <section id="navigator-extension:-requestmediakeysystemaccess()"> - <h3 id="x3.1-navigator-extension:-requestmediakeysystemaccess()"><span class="secno">3.1 </span><dfn data-dfn-for="" data-dfn-type="dfn" id="dom-navigator" data-idl="" data-title="Navigator"><code>Navigator</code></dfn> Extension: <code>requestMediaKeySystemAccess()</code></h3> - - <div> - <div> - <pre class="def idl"><span class="idlInterface" id="idl-def-navigator-partial-1" data-idl="" data-title="Navigator">partial interface <span class="idlInterfaceID"><a data-lt="Navigator" href="#dom-navigator" class="internalDFN" data-link-type="dfn" data-for=""><code>Navigator</code></a></span> { -<span class="idlMethod" id="idl-def-navigator-requestmediakeysystemaccess(keysystem,supportedconfigurations)" data-idl="" data-title="requestMediaKeySystemAccess" data-dfn-for="navigator"> [<span class="extAttr"><span class="extAttrName"><a href="https://heycam.github.io/webidl/#SecureContext">SecureContext</a></span></span>] <span class="idlMethType"><a href="https://heycam.github.io/webidl/#idl-promise">Promise</a><<a href="#dom-mediakeysystemaccess" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemAccess</code></a>></span> <span class="idlMethName"><a data-lt="requestMediaKeySystemAccess" href="#dom-navigator-requestmediakeysystemaccess" class="internalDFN" data-link-type="dfn" data-for="Navigator"><code>requestMediaKeySystemAccess</code></a></span>(<span class="idlParam"><span class="idlParamType"><a href="https://heycam.github.io/webidl/#idl-DOMString">DOMString</a></span> <span class="idlParamName">keySystem</span></span>, - <span class="idlParam"><span class="idlParamType"><a href="https://heycam.github.io/webidl/#idl-sequence">sequence</a><<a href="#dom-mediakeysystemconfiguration" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemConfiguration</code></a>></span> <span class="idlParamName">supportedConfigurations</span></span>);</span> -};</span></pre> - </div> - <section> - <h4 id="methods">Methods</h4> - <dl class="methods" data-dfn-for="Navigator" data-link-for="Navigator"><dt><dfn data-dfn-for="navigator" data-dfn-type="dfn" id="dom-navigator-requestmediakeysystemaccess" data-idl="" data-title="requestMediaKeySystemAccess" data-lt="requestmediakeysystemaccess()|requestMediaKeySystemAccess"><code id="requestMediaKeySystemAccess">requestMediaKeySystemAccess</code></dfn></dt> - <dd> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note27"><span>Note</span></div> - <p class="">Calling this method may have <em>user-visible effects</em>, including requests for user consent. This method should only be called when the author intends to create and use a <a href="#dom-mediakeys" class="internalDFN" - data-link-type="dfn"><code>MediaKeys</code></a> object with the provided configuration. - </p> - </div> - <p>Requests access to the specified <a href="#key-system">Key System</a>. When <code>supportedConfigurations</code> is specified, the configuration specified by at least one of its elements must be supported. The resulting - <a - href="#dom-mediakeysystemaccess" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemAccess</code></a> will correspond to the first such element. - </p> - <p>Any permission checks or user interaction, such as a prompt for consent, <em class="rfc2119" title="MUST">MUST</em> be performed before resolving the promise.</p> - <p>If the <code>keySystem</code> is not supported or not allowed (in at least one of the <code>supportedConfigurations</code>, if specified), the promise is rejected. Otherwise, it is resolved with a new <a href="#dom-mediakeysystemaccess" - class="internalDFN" data-link-type="dfn"><code>MediaKeySystemAccess</code></a> object. - </p> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note28"><span>Note</span></div> - <div class=""> - <p>This method is only exposed to <a href="https://www.w3.org/TR/secure-contexts/#secure-context">secure contexts</a> [<cite><a class="bibref" href="#bib-SECURE-CONTEXTS">SECURE-CONTEXTS</a></cite>] as indicated by the - <code>[SecureContext]</code> IDL attribute.</p> - <p> - Requiring Secure Contexts is <em>not</em> a replacement for other security- and privacy-related requirements and recommendations. Implementations <em class="rfc2119" title="MUST">MUST</em> meet all related requirements - and <em class="rfc2119" title="SHOULD">SHOULD</em> follow related recommendations such that the risks on in an secure context would be similar. - </p> - </div> - </div> - - - - - <table class="parameters"> - <tbody> - <tr> - <th>Parameter</th> - <th>Type</th> - <th>Nullable</th> - <th>Optional</th> - <th>Description</th> - </tr> - <tr> - <td class="prmName">keySystem</td> - <td class="prmType"><code>DOMString</code></td> - <td class="prmNullFalse"><span role="img" aria-label="False">✘</span></td> - <td class="prmOptFalse"><span role="img" aria-label="False">✘</span></td> - <td class="prmDesc"> - The <a href="#key-system">Key System</a> for which access is being requested. - </td> - </tr> - <tr> - <td class="prmName">supportedConfigurations</td> - <td class="prmType"><code>sequence<MediaKeySystemConfiguration></code></td> - <td class="prmNullFalse"><span role="img" aria-label="False">✘</span></td> - <td class="prmOptFalse"><span role="img" aria-label="False">✘</span></td> - <td class="prmDesc"> - A sequence of <a href="#dom-mediakeysystemconfiguration" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemConfiguration</code></a> configurations to try in order. The first element with a satisfiable - configuration will be used. - </td> - </tr> - </tbody> - </table> - <div><em>Return type: </em><code>Promise<MediaKeySystemAccess></code></div> - <p>When this method is invoked, the user agent must run the following steps:</p> - <ol class="method-algorithm"> - <!-- TODO: Convert all parameters to use <code>. --> - <li> - <p>If <var>keySystem</var> is the empty string, return a promise rejected with a newly created <code><a href="#dfn-TypeError">TypeError</a></code>.</p> - </li> - <li> - <p>If <var>supportedConfigurations</var> is empty, return a promise rejected with a newly created <code><a href="#dfn-TypeError">TypeError</a></code>.</p> - </li> - <li> - <p>Let <var>document</var> be the calling context's <a href="https://www.w3.org/TR/dom/#concept-document">Document</a>.</p> - </li> - <li> - <p>Let <var>origin</var> be the <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> of <var>document</var>.</p> - </li> - <li> - <p>Let <var>promise</var> be a new promise.</p> - </li> - <li> - <p>Run the following steps in parallel:</p> - <ol> - <li> - <p>If <var>keySystem</var> is not one of the <a href="#key-system">Key Systems</a> supported by the user agent, reject <var>promise</var> with a <code><a href="#dfn-NotSupportedError">NotSupportedError</a></code>. - String comparison is case-sensitive.</p> - </li> - <li> - <p>Let <var>implementation</var> be the implementation of <var>keySystem</var>.</p> - </li> - <li> - <p>For each value in <code>supportedConfigurations</code>:</p> - <ol> - <li> - <p>Let <var>candidate configuration</var> be the value.</p> - </li> - <li> - <p>Let <var>supported configuration</var> be the result of executing the <a href="#get-supported-configuration">Get Supported Configuration</a> algorithm on <var>implementation</var>, <var>candidate configuration</var>, - and <var>origin</var>.</p> - </li> - <li> - <p>If <var>supported configuration</var> is not <code>NotSupported</code>, run the following steps:</p> - <ol> - <li> - <p>Let <var>access</var> be a new <a href="#dom-mediakeysystemaccess" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemAccess</code></a> object, and initialize it as follows:</p> - <ol> - <li> - <p>Set the <code><a href="#dom-mediakeysystemaccess-keysystem">keySystem</a></code> attribute to <var>keySystem</var>.</p> - </li> - <li> - <p>Let the <var>configuration</var> value be <var>supported configuration</var>.</p> - </li> - <li> - <p>Let the <var>cdm implementation</var> value be <var>implementation</var>.</p> - </li> - </ol> - </li> - <li> - <p>Resolve <var>promise</var> with <var>access</var> and abort the parallel steps of this algorithm.</p> - </li> - </ol> - </li> - </ol> - </li> - <li> - <p>Reject <var>promise</var> with a <code><a href="#dfn-NotSupportedError">NotSupportedError</a></code>.</p> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note29"><span>Note</span></div> - <p class=""><code>keySystem</code> was not supported/allowed or none of the configurations in <code>supportedConfigurations</code> were supported/allowed.</p> - </div> - </li> - </ol> - </li> - <li> - <p>Return <var>promise</var>.</p> - </li> - </ol> - </dd> - </dl> - </section> - </div> - - <section id="algorithms"> - <h4 id="x3.1.1-algorithms"><span class="secno">3.1.1 </span>Algorithms</h4> - - <section id="get-supported-configuration"> - <h5 id="x3.1.1.1-get-supported-configuration"><span class="secno">3.1.1.1 </span>Get Supported Configuration</h5> - <p>Given a <a href="#key-system">Key Systems</a> implementation <var>implementation</var>, <a href="#dom-mediakeysystemconfiguration" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemConfiguration</code></a> <var>candidate configuration</var>, - and <var>origin</var>, this algorithm returns a supported configuration or <code>NotSupported</code> as appropriate.</p> - <div class="note"> - <div class="note-title marker" aria-level="6" role="heading" id="h-note30"><span>Note</span></div> - <p class="">Unrecognized dictionary members in <var>candidate configuration</var> are ignored per [<cite><a class="bibref" href="#bib-WEBIDL">WEBIDL</a></cite>] and will never reach this algorithm. Thus, they cannot be considered as part of - the configuration. - </p> - </div> - <div class="note"> - <div class="note-title marker" aria-level="6" role="heading" id="h-note31"><span>Note</span></div> - <div class=""> - <p> - For certain configurations, it may be required to obtain user consent or inform the user. User Agents have some flexibility to determine whether consent is required for a specific configuration and whether such consent may also apply to other configurations. - For example, consent to one configuration may also imply consent for less powerful, more restricted configurations. Equally, a denial of consent for one configuration may imply denial of consent for more powerful, less - restricted configurations. - </p> - <p> - Supported configurations, including supported audio and video codecs, may depend on availability of optional capabilities such as - <a href="#distinctive-identifier">Distinctive Identifier(s)</a> and persistent state. The following algorithm iteratively tries to find a configuration that is both supported and has user consent (or does not need consent). - </p> - <p> - User Agents should reuse earlier consent responses, when appropriate, at least for the duration of the <code><a href="#dom-navigator-requestmediakeysystemaccess">requestMediaKeySystemAccess()</a></code> algorithm in order - to avoid repeated requests to the user for similar configurations. - </p> - <p> - The variable <var>restrictions</var> in the steps below represents the configurations for which consent has been denied during the execution of this algorithm or based on persisted consent information for the origin. It - is used to determine whether user consent for a candidate configuration or accumulated configuration has been denied. Consent is denied for a accumulated configuration if every derived configuration has already been denied. - Internal representation of <var>restrictions</var> is implementation-specific. - </p> - </div> - </div> - <ol> - <li> - <p>Let <var>supported configuration</var> be <code>ConsentDenied</code>.</p> - </li> - <li> - <p>Initialize <var>restrictions</var> to indicate that no configurations have had user consent denied.</p> - </li> - <li> - <p>Repeat the following step while <var>supported configuration</var> is <code>ConsentDenied</code>:</p> - <ol> - <li> - <p> - Let <var>supported configuration</var> and, if provided, <var>restrictions</var> be the result of executing the - <a href="#get-supported-configuration-and-consent">Get Supported Configuration and Consent</a> algorithm with <var>implementation</var>, <var>candidate configuration</var>, <var>restrictions</var> and <var>origin</var>. - </p> - </li> - </ol> - </li> - <li> - <p>Return <var>supported configuration</var>.</p> - </li> - </ol> - </section> - <section id="get-supported-configuration-and-consent"> - <h5 id="x3.1.1.2-get-supported-configuration-and-consent"><span class="secno">3.1.1.2 </span>Get Supported Configuration and Consent</h5> - <p>Given a <a href="#key-system">Key Systems</a> implementation <var>implementation</var>, <a href="#dom-mediakeysystemconfiguration" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemConfiguration</code></a> <var>candidate configuration</var>, - <var>restrictions</var> and <var>origin</var>, this algorithm returns a supported configuration, <code>NotSupported</code>, or <code>ConsentDenied</code> as appropriate and, in the <code>ConsentDenied</code> case, <var>restrictions</var>. - </p> - <ol> - <li> - <p>Let <var>accumulated configuration</var> be a new <a href="#dom-mediakeysystemconfiguration" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemConfiguration</code></a> dictionary.</p> - </li> - - <li> - <p> - Set the <code><a href="#dom-mediakeysystemconfiguration-label">label</a></code> member of <var>accumulated configuration</var> to equal the <code><a href="#dom-mediakeysystemconfiguration-label">label</a></code> member - of <var>candidate configuration</var>. - </p> - </li> - - <li> - <p>If the <code><a href="#dom-mediakeysystemconfiguration-initdatatypes">initDataTypes</a></code> member of <var>candidate configuration</var> is non-empty, run the following steps:</p> - <ol> - <li> - <p>Let <var>supported types</var> be an empty sequence of DOMStrings.</p> - </li> - <li> - <p>For each value in <var>candidate configuration</var>'s <code><a href="#dom-mediakeysystemconfiguration-initdatatypes">initDataTypes</a></code> member:</p> - <ol> - <li> - <p>Let <var>initDataType</var> be the value.</p> - </li> - <li> - <p>If the <var>implementation</var> supports generating requests based on <var>initDataType</var>, add <var>initDataType</var> to <var>supported types</var>. String comparison is case-sensitive. The empty string - is never supported. - </p> - <div class="note"> - <div class="note-title marker" aria-level="6" role="heading" id="h-note32"><span>Note</span></div> - <p class="">The <var>initDataType</var> <em class="rfc2119" title="MUST">MUST</em> be supported independent of content types in order to avoid unexpectedly rejecting the configuration in later steps. Support for <var>initDataType</var> includes both license generation and, when appropriate, extraction from media data. See <a href="#initialization-data-type-support-requirements">Initialization Data Type Support requirements</a>. - </p> - </div> - </li> - </ol> - </li> - <li> - <p>If <var>supported types</var> is empty, return <code>NotSupported</code>.</p> - </li> - <li> - <p>Set the <code><a href="#dom-mediakeysystemconfiguration-initdatatypes">initDataTypes</a></code> member of <var>accumulated configuration</var> to <var>supported types</var>.</p> - </li> - </ol> - </li> - - <!-- Table of results for MediaKeysRequirement members based on implementation capabilities: - || Implementation Capabilities | - Input Value || Only Supported | Only Not Supported | Both | - =========================================================================================== - "required" || "required" | Return null | "required" | - "optional" || "required" | "not-allowed" | Depends on combination | - "not-allowed" || Return null | "not-allowed" | "not-allowed" | - --> - <li> - <p> - Let <var>distinctive identifier requirement</var> be the value of <var>candidate configuration</var>'s <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> member. - </p> - </li> - <li> - <p> - If <var>distinctive identifier requirement</var> is <code><a href="#idl-def-MediaKeysRequirement.optional">"optional"</a></code> and - <a href="#distinctive-identifier">Distinctive Identifiers</a> are not allowed according to <var>restrictions</var>, set <var>distinctive identifier requirement</var> to <code><a href="#idl-def-MediaKeysRequirement.not-allowed">"not-allowed"</a></code>. - </p> - </li> - <li> - <p>Follow the steps for <var>distinctive identifier requirement</var> from the following list:</p> - <dl class="switch"> - <dt><code><a href="#idl-def-MediaKeysRequirement.required">"required"</a></code></dt> - <dd> - <p>If the <var>implementation</var> does not support <a href="#uses-distinctive-identifiers">use of Distinctive Identifier(s)</a> in combination with <var>accumulated configuration</var> and <var>restrictions</var>, return - <code>NotSupported</code>.</p> - <!-- TODO: Find a better descriptive model for this than "combination." - See the first three comment threads starting with https://github.com/w3c/encrypted-media/pull/165#discussion_r63112757. --> - </dd> - <dt><code><a href="#idl-def-MediaKeysRequirement.optional">"optional"</a></code></dt> - <dd> - <p>Continue with the following steps.</p> - </dd> - <dt><code><a href="#idl-def-MediaKeysRequirement.not-allowed">"not-allowed"</a></code></dt> - <dd> - <p>If the <var>implementation</var> requires <a href="#uses-distinctive-identifiers-or-distinctive-permanent-identifiers">use Distinctive Identifier(s) or Distinctive Permanent Identifier(s)</a> in combination with <var>accumulated configuration</var> and <var>restrictions</var>, return <code>NotSupported</code>.</p> - </dd> - </dl> - <div class="note"> - <div class="note-title marker" aria-level="6" role="heading" id="h-note33"><span>Note</span></div> - <div class=""> - <p> - The combination of <var>accumulated configuration</var> and <var>restrictions</var> means all the possible configurations that include everything in <var>accumulated configuration</var> and that are not denied according - to <var>restrictions</var>. - </p> - <p> - A feature is supported by an implementation with this combination if the implementation supports at least one of the configurations in the combination with the feature. - </p> - <p> - A feature is required by an implementtion with this combination if all configurations in the combination that are suported by the implementation include the feature. - </p> - </div> - </div> - </li> - <li> - <p> - Set the <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> member of <var>accumulated configuration</var> to equal <var>distinctive identifier requirement</var>. - </p> - </li> - <li> - <p> - Let <var>persistent state requirement</var> be equal to the value of <var>candidate configuration</var>'s <code><a href="#dom-mediakeysystemconfiguration-persistentstate">persistentState</a></code> member. - </p> - </li> - <li> - <p> - If <var>persistent state requirement</var> is <code><a href="#idl-def-MediaKeysRequirement.optional">"optional"</a></code> and persisting state is not allowed according to - <var>restrictions</var>, set <var>persistent state requirement</var> to <code><a href="#idl-def-MediaKeysRequirement.not-allowed">"not-allowed"</a></code>. - </p> - </li> - <li> - <p>Follow the steps for <var>persistent state requirement</var> from the following list:</p> - <dl class="switch"> - <dt><code><a href="#idl-def-MediaKeysRequirement.required">"required"</a></code></dt> - <dd> - <p>If the <var>implementation</var> does not support persisting state in combination with <var>accumulated configuration</var> and <var>restrictions</var>, return <code>NotSupported</code>.</p> - </dd> - <dt><code><a href="#idl-def-MediaKeysRequirement.optional">"optional"</a></code></dt> - <dd> - <p> - Continue with the following steps. - </p> - </dd> - <dt><code><a href="#idl-def-MediaKeysRequirement.not-allowed">"not-allowed"</a></code></dt> - <dd> - <p>If the <var>implementation</var> requires persisting state in combination with <var>accumulated configuration</var> and <var>restrictions</var>, return <code>NotSupported</code>.</p> - </dd> - </dl> - </li> - <li> - <p> - Set the <code><a href="#dom-mediakeysystemconfiguration-persistentstate">persistentState</a></code> member of <var>accumulated configuration</var> to equal the value of <var>persistent state requirement</var>. - </p> - </li> - <li> - <p>Follow the steps for the first matching condition from the following list:</p> - <dl class="switch"> - <dt>If the <code><a href="#dom-mediakeysystemconfiguration-sessiontypes">sessionTypes</a></code> member is <a href="https://heycam.github.io/webidl/#dfn-present">present</a> [<cite><a class="bibref" href="#bib-WEBIDL">WEBIDL</a></cite>] in <var>candidate configuration</var></dt> - <dd> - <p>Let <var>session types</var> be <var>candidate configuration</var>'s <code><a href="#dom-mediakeysystemconfiguration-sessiontypes">sessionTypes</a></code> member.</p> - </dd> - <dt>Otherwise</dt> - <dd> - <p>Let <var>session types</var> be <code>[ <code><a href="#idl-def-MediaKeySessionType.temporary">"temporary"</a></code> ]</code>.</p> - </dd> - </dl> - </li> - <li> - <p>For each value in <var>session types</var>:</p> - <ol> - <li> - <p>Let <var>session type</var> be the value.</p> - </li> - <li> - <p> - If <var>accumulated configuration</var>'s <code><a href="#dom-mediakeysystemconfiguration-persistentstate">persistentState</a></code> value is <code><a href="#idl-def-MediaKeysRequirement.not-allowed">"not-allowed"</a></code> and the <a href="#is-persistent-session-type">Is persistent session type?</a> algorithm returns <code>true</code> for <var>session type</var> return <code>NotSupported</code>. - </p> - </li> - <li> - <p>If the <var>implementation</var> does not support <var>session type</var> in combination with <var>accumulated configuration</var> and <var>restrictions</var> for other reasons, return <code>NotSupported</code>.</p> - </li> - <li> - <p>If <var>accumulated configuration</var>'s <code><a href="#dom-mediakeysystemconfiguration-persistentstate">persistentState</a></code> value is <code><a href="#idl-def-MediaKeysRequirement.optional">"optional"</a></code> and the result of running the <a href="#is-persistent-session-type">Is persistent session type?</a> algorithm on <var>session type</var> is <code>true</code>, change <var>accumulated configuration</var>'s <code><a href="#dom-mediakeysystemconfiguration-persistentstate">persistentState</a></code> value to <code><a href="#idl-def-MediaKeysRequirement.required">"required"</a></code>.</p> - </li> - </ol> - </li> - <li> - <p>Set the <code><a href="#dom-mediakeysystemconfiguration-sessiontypes">sessionTypes</a></code> member of <var>accumulated configuration</var> to <var>session types</var>.</p> - </li> - - <li> - <p> - If the <code><a href="#dom-mediakeysystemconfiguration-videocapabilities">videoCapabilities</a></code> and <code><a href="#dom-mediakeysystemconfiguration-audiocapabilities">audioCapabilities</a></code> members in <var>candidate configuration</var> are both empty, return <code>NotSupported</code>. - </p> - </li> - - <li> - <dl class="switch"> - <dt>If the <code><a href="#dom-mediakeysystemconfiguration-videocapabilities">videoCapabilities</a></code> member in <var>candidate configuration</var> is non-empty:</dt> - <dd> - <ol> - <li> - <p>Let <var>video capabilities</var> be the result of executing the <a href="#get-supported-capabilities-for-audio-video-type">Get Supported Capabilities for Audio/Video Type</a> algorithm on Video, <var>candidate configuration</var>'s - <code><a href="#dom-mediakeysystemconfiguration-videocapabilities">videoCapabilities</a></code> member, <var>accumulated configuration</var>, and <var>restrictions</var>.</p> - </li> - <li> - <p>If <var>video capabilities</var> is <code>null</code>, return <code>NotSupported</code>.</p> - </li> - <!-- Video capabilities were specified, but none were supported. --> - <li> - <p>Set the <code><a href="#dom-mediakeysystemconfiguration-videocapabilities">videoCapabilities</a></code> member of <var>accumulated configuration</var> to <var>video capabilities</var>.</p> - </li> - </ol> - </dd> - <dt>Otherwise:</dt> - <dd> - <p>Set the <code><a href="#dom-mediakeysystemconfiguration-videocapabilities">videoCapabilities</a></code> member of <var>accumulated configuration</var> to an empty sequence.</p> - </dd> - </dl> - </li> - - <li> - <dl class="switch"> - <dt>If the <code><a href="#dom-mediakeysystemconfiguration-audiocapabilities">audioCapabilities</a></code> member in <var>candidate configuration</var> is non-empty:</dt> - <dd> - <ol> - <li> - <p>Let <var>audio capabilities</var> be the result of executing the <a href="#get-supported-capabilities-for-audio-video-type">Get Supported Capabilities for Audio/Video Type</a> algorithm on Audio, <var>candidate configuration</var>'s - <code><a href="#dom-mediakeysystemconfiguration-audiocapabilities">audioCapabilities</a></code> member, <var>accumulated configuration</var>, and <var>restrictions</var>.</p> - </li> - <li> - <p>If <var>audio capabilities</var> is <code>null</code>, return <code>NotSupported</code>.</p> - </li> - <!-- Audio capabilities were specified, but none were supported. --> - <li> - <p>Set the <code><a href="#dom-mediakeysystemconfiguration-audiocapabilities">audioCapabilities</a></code> member of <var>accumulated configuration</var> to <var>audio capabilities</var>.</p> - </li> - </ol> - </dd> - <dt>Otherwise:</dt> - <dd> - <p>Set the <code><a href="#dom-mediakeysystemconfiguration-audiocapabilities">audioCapabilities</a></code> member of <var>accumulated configuration</var> to an empty sequence.</p> - </dd> - </dl> - </li> - - <!-- Replace "optional" values in the combined configuration before checking permissions and for the value exposed by MediaKeySystemAccess. --> - <li> - <p>If <var>accumulated configuration</var>'s <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> value is <code><a href="#idl-def-MediaKeysRequirement.optional">"optional"</a></code>, - follow the steps for the first matching condition from the following list:</p> - <dl class="switch"> - <dt>If the <var>implementation</var> requires <a href="#uses-distinctive-identifiers-or-distinctive-permanent-identifiers">use Distinctive Identifier(s) or Distinctive Permanent Identifier(s)</a> for any of the combinations in <var>accumulated configuration</var></dt> - <dd> - <p>Change <var>accumulated configuration</var>'s <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> value to <code><a href="#idl-def-MediaKeysRequirement.required">"required"</a></code>.</p> - </dd> - <dt>Otherwise</dt> - <dd> - <p>Change <var>accumulated configuration</var>'s <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> value to <code><a href="#idl-def-MediaKeysRequirement.not-allowed">"not-allowed"</a></code>.</p> - </dd> - </dl> - </li> - - <li> - <p>If <var>accumulated configuration</var>'s <code><a href="#dom-mediakeysystemconfiguration-persistentstate">persistentState</a></code> value is <code><a href="#idl-def-MediaKeysRequirement.optional">"optional"</a></code>, follow - the steps for the first matching condition from the following list:</p> - <dl class="switch"> - <dt>If the <var>implementation</var> requires persisting state for any of the combinations in <var>accumulated configuration</var></dt> - <dd> - <p>Change <var>accumulated configuration</var>'s <code><a href="#dom-mediakeysystemconfiguration-persistentstate">persistentState</a></code> value to <code><a href="#idl-def-MediaKeysRequirement.required">"required"</a></code>.</p> - </dd> - <dt>Otherwise</dt> - <dd> - <p>Change <var>accumulated configuration</var>'s <code><a href="#dom-mediakeysystemconfiguration-persistentstate">persistentState</a></code> value to <code><a href="#idl-def-MediaKeysRequirement.not-allowed">"not-allowed"</a></code>.</p> - </dd> - </dl> - </li> - - <li> - <p>If <var>implementation</var> in the configuration specified by the combination of the values in <var>accumulated configuration</var> is not supported or not allowed in the <var>origin</var>, return <code>NotSupported</code>.</p> - <div class="note"> - <div class="note-title marker" aria-level="6" role="heading" id="h-note34"><span>Note</span></div> - <p class="">In this step, "supported" includes the implementation being available for use when this algorithm returns, not just user agent support for such an implementation.</p> - </div> - </li> - - <li> - <p> - If <var>accumulated configuration</var>'s <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> value is <code><a href="#idl-def-MediaKeysRequirement.required">"required"</a></code> and the <a href="#distinctive-identifier">Distinctive Identifier(s)</a> associated with <var>accumulated configuration</var> are not <a href="#per-origin-per-profile-identifiers">unique per origin and profile</a> and - <a href="#allow-identifiers-cleared">clearable</a>: - </p> - <ol> - <li> - <p> - Update <var>restrictions</var> to reflect that all configurations described by <var>accumulated configuration</var> do not have user consent. - </p> - </li> - <li> - <p>Return <code>ConsentDenied</code> and <var>restrictions</var>.</p> - </li> - </ol> - <div class="note"> - <div class="note-title marker" aria-level="6" role="heading" id="h-note35"><span>Note</span></div> - <div class=""> - <p> - The "unique per origin and profile" and "clearable" conditions cannot be false in a compliant implementation because implementations <em class="rfc2119" title="MUST">MUST</em> <a href="#per-origin-per-profile-identifiers">use per-origin per-profile identifiers</a> and <a href="#allow-identifiers-cleared">allow the user to clear identifier</a>. - </p> - </div> - </div> - </li> - <li> - <p> - Let <var>consent status</var> and <var>updated restrictions</var> be the result of running the <a href="#get-consent-status">Get Consent Status</a> algorithm on <var>accumulated configuration</var>, <var>restrictions</var> and <var>origin</var> and follow the steps for the value of <var>consent status</var> from the following list: - </p> - - <dl class="switch"> - <dt><code>ConsentDenied</code>:</dt> - <dd> - <p> - Return <code>ConsentDenied</code> and <var>updated restrictions</var>. - </p> - </dd><dt><code>InformUser</code>:</dt> - <dd> - <p> - Inform the user that <var>accumulated configuration</var> is in use in the <var>origin</var> including, specifically, the information that <a href="#distinctive-identifier">Distinctive Identifier(s)</a> and/or - <a - href="#distinctive-permanent-identifier">Distinctive Permanent Identifier(s)</a> as appropriate will be used if the <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> member of <var>accumulated configuration</var> is <code><a href="#idl-def-MediaKeysRequirement.required">"required"</a></code>. Continue to the next step. - </p> - </dd> - <dt><code>Allowed</code>:</dt> - <dd> - <p> - Continue to the next step. - </p> - </dd> - </dl> - </li> - - <li> - <p>Return <var>accumulated configuration</var>.</p> - </li> - </ol> - </section> - - <section id="get-supported-capabilities-for-audio/video-type"> - <h5 id="x3.1.1.3-get-supported-capabilities-for-audio/video-type"><span class="secno">3.1.1.3 </span>Get Supported Capabilities for Audio/Video Type</h5> - <p>Given an <var>audio/video type</var>, <a href="#dom-mediakeysystemmediacapability" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemMediaCapability</code></a> sequence <var>requested media capabilities</var>, <a href="#dom-mediakeysystemconfiguration" - class="internalDFN" data-link-type="dfn"><code>MediaKeySystemConfiguration</code></a> <var>accumulated configuration</var>, and <var>restrictions</var>, this algorithm returns a sequence of supported <a href="#dom-mediakeysystemmediacapability" - class="internalDFN" data-link-type="dfn"><code>MediaKeySystemMediaCapability</code></a> values for this audio/video type or <code>null</code> as appropriate.</p> - <ol> - <li> - <p>Let <var>local accumulated configuration</var> be a local copy of <var>accumulated configuration</var>.</p> - </li> - <li> - <p>Let <var>supported media capabilities</var> be an empty sequence of <a href="#dom-mediakeysystemmediacapability" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemMediaCapability</code></a> dictionaries.</p> - </li> - <li> - <p>For each <var>requested media capability</var> in <var>requested media capabilities</var>:</p> - <ol> - <li> - <p>Let <var>content type</var> be <var>requested media capability</var>'s <code><a href="#dom-mediakeysystemmediacapability-contenttype">contentType</a></code> member.</p> - </li> - <li> - <p>Let <var>robustness</var> be <var>requested media capability</var>'s <code><a href="#dom-mediakeysystemmediacapability-robustness">robustness</a></code> member.</p> - </li> - <li> - <p>If <var>content type</var> is the empty string, return <code>null</code>.</p> - </li> - <!-- Invalid input. --> - <li> - <p>If <var>content type</var> is not a <a href="#valid-media-mime-type">valid media MIME type</a> or is unrecognized, continue to the next iteration.</p> - </li> - <li> - <p>Let <var>container</var> be the container type specified by <var>content type</var>.</p> - </li> - <li> - <p>If the user agent does not support <var>container</var>, continue to the next iteration. The case-sensitivity of string comparisons is determined by the appropriate RFC.</p> - <div class="note"> - <div class="note-title marker" aria-level="6" role="heading" id="h-note36"><span>Note</span></div> - <p class="">Per RFC 6838 [<cite><a class="bibref" href="#bib-RFC6838">RFC6838</a></cite>], "Both top-level type and subtype names are case-insensitive."</p> - </div> - </li> - <li> - <p>Let <var>parameters</var> be the RFC 6381 [<cite><a class="bibref" href="#bib-RFC6381">RFC6381</a></cite>] parameters, if any, specified by <var>content type</var>.</p> - </li> - <li> - <p>If the user agent does not recognize one or more <var>parameters</var>, continue to the next iteration.</p> - </li> - <li> - <p>Let <var>media types</var> be the set of codecs and codec constraints specified by <var>parameters</var>. The case-sensitivity of string comparisons is determined by the appropriate RFC or other specification.</p> - <div class="note"> - <div class="note-title marker" aria-level="6" role="heading" id="h-note37"><span>Note</span></div> - <p class="">Case-sensitive string comparison is <em class="rfc2119" title="RECOMMENDED">RECOMMENDED</em> because RFC 6381 [<cite><a class="bibref" href="#bib-RFC6381">RFC6381</a></cite>] says, "Values are case sensitive" for - some formats.</p> - </div> - </li> - <li> - <p> - If <var>media types</var> is empty: - </p> - <dl class="switch"> - <dt>If <var>container</var> normatively implies a specific set of codecs and codec constraints:</dt> - <dd> - <p> - Let <var>parameters</var> be that set. - </p> - </dd> - <dt>Otherwise:</dt> - <dd> - <p> - Continue to the next iteration. - </p> - </dd> - </dl> - </li> - <li> - <p>If <var>content type</var> is not strictly a <var>audio/video type</var>, continue to the next iteration.</p> - <div class="note"> - <div class="note-title marker" aria-level="6" role="heading" id="h-note38"><span>Note</span></div> - <p class="">For example, if <var>audio/video type</var> is Video and the top-level type is not "video" or <var>media types</var> contains non-video codecs.</p> - </div> - </li> - <li> - <p>If <var>robustness</var> is not the empty string and contains an unrecognized value or a value not supported by <var>implementation</var>, continue to the next iteration. String comparison is case-sensitive.</p> - </li> - <li> - <p>If the user agent and <var>implementation</var> definitely support playback of encrypted <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a> for the combination of <var>container</var>, - <var>media types</var>, <var>robustness</var> and <var>local accumulated configuration</var> in combination with <var>restrictions</var>:</p> - <div class="note"> - <div class="note-title marker" aria-level="6" role="heading" id="h-note39"><span>Note</span></div> - <p class=""><var>requested media capability</var> (content type and robustness) must be supported when used together with all previously added requested media capabilities.</p> - </div> - <ol> - <li> - <p> - Add <var>requested media capability</var> to <var>supported media capabilities</var>. - </p> - <div class="note"> - <div class="note-title marker" aria-level="6" role="heading" id="h-note40"><span>Note</span></div> - <p class=""> - This step ensures that the values of the members of entries in <var>supported media capabilities</var> are exactly the strings supplied in - <var>requested media capability</var> without modification by the User Agent. - </p> - </div> - </li> - <li> - <dl class="switch"> - <dt>If <var>audio/video type</var> is Video:</dt> - <dd> - <p> - Add <var>requested media capability</var> to the <code><a href="#dom-mediakeysystemconfiguration-videocapabilities">videoCapabilities</a></code> member of <var>local accumulated configuration</var>. - </p> - </dd> - <dt>If <var>audio/video type</var> is Audio:</dt> - <dd> - <p> - Add <var>requested media capability</var> to the <code><a href="#dom-mediakeysystemconfiguration-audiocapabilities">audioCapabilities</a></code> member of <var>local accumulated configuration</var>. - </p> - </dd> - </dl> - <div class="note"> - <div class="note-title marker" aria-level="6" role="heading" id="h-note41"><span>Note</span></div> - <p class=""> - This step ensures that configurations are always checked with configurations from previous iterations, including from previous calls to this algorithm. Otherwise, only configurations from previous calls to this algorithm would be checked in subsequent - calls. - </p> - </div> - </li> - </ol> - </li> - </ol> - </li> - <li> - <p>If <var>supported media capabilities</var> is empty, return <code>null</code>.</p> - <div class="note"> - <div class="note-title marker" aria-level="6" role="heading" id="h-note42"><span>Note</span></div> - <p class="">None of the <a href="#dom-mediakeysystemmediacapability" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemMediaCapability</code></a> elements in <var>requested media capabilities</var> is supported in combination - with <var>accumulated configuration</var>.</p> - </div> - </li> - <li> - <p>Return <var>supported media capabilities</var>.</p> - </li> - </ol> - </section> - - <section id="get-consent-status"> - <h5 id="x3.1.1.4-get-consent-status"><span class="secno">3.1.1.4 </span>Get Consent Status</h5> - <p> - Given an <var>accumulated configuration</var>, <var>restrictions</var> and <var>origin</var>, this algorithm returns the consent status for - <var>accumulated configuration</var> and <var>origin</var> as one of <code>ConsentDenied</code>, <code>InformUser</code> or <code>Allowed</code>, together with an updated value for <var>restrictions</var> in the <code>ConsentDenied</code> case. - </p> - <div class="note"> - <div class="note-title marker" aria-level="6" role="heading" id="h-note43"><span>Note</span></div> - <div class=""> - <p> - Consent status for <var>accumulated configuration</var> depends at least on the value of the <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> member of - <var>accumulated configuration</var>. - </p> - <p> - Previous consent for <var>accumulated configuration</var> with <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> set to <code><a href="#idl-def-MediaKeysRequirement.not-allowed">"not-allowed"</a></code> does not imply consent for the same configuration with <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> set to <code><a href="#idl-def-MediaKeysRequirement.optional">"optional"</a></code> or <code><a href="#idl-def-MediaKeysRequirement.required">"required"</a></code>. - </p> - </div> - </div> - <ol> - <li> - <p> - If there is persisted denial for <var>origin</var> indicating that <var>accumulated configuration</var> is not allowed, run the following steps: - </p> - <ol> - <li> - <p>Update <var>restrictions</var> to reflect the configurations for which consent has been denied.</p> - </li> - <li> - <p>Return <code>ConsentDenied</code> and <var>restrictions</var>.</p> - </li> - </ol> - </li> - <li> - <p> - If there is persisted consent for <var>origin</var> indicating <var>accumulated configuration</var> is allowed, return <code>Allowed</code>. - </p> - </li> - <li> - <p> - If any of the following are true: - </p> - <ul> - <li> - <p> - The <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> member of <var>accumulated configuration</var> is not - <code><a href="#idl-def-MediaKeysRequirement.not-allowed">"not-allowed"</a></code> and the combination of the User Agent, <var>implementation</var> and <var>accumulated configuration</var> does not follow all the - recommendations of - <a href="#allow-persistent-data-cleared">Allow Persistent Data to Be Cleared</a> with respect to - <a href="#distinctive-identifier">Distinctive Identifier(s)</a>. - </p> - </li> - <li> - <p> - The user agent requires explicit user consent for the <var>accumulated configuration</var> for other reasons. - </p> - <div class="note"> - <div class="note-title marker" aria-level="6" role="heading" id="h-note44"><span>Note</span></div> - <p class=""> - Another reason for requiring explicit user consent may be due to the security properties of the CDM implementation. - </p> - </div> - </li> - </ul> - <p>then run the following steps:</p> - <ol> - <li> - <p> - Request user consent to use <var>accumulated configuration</var> in the <var>origin</var> and wait for the user response. - </p> - <p> - The consent <em class="rfc2119" title="MUST">MUST</em> include consent to use a <a href="#distinctive-identifier">Distinctive Identifier(s)</a> and/or <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifier(s)</a> as appropriate if - <var>accumulated configuration</var>'s <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> member is <code><a href="#idl-def-MediaKeysRequirement.required">"required"</a></code>. - </p> - <div class="note"> - <div class="note-title marker" aria-level="6" role="heading" id="h-note45"><span>Note</span></div> - <div class=""> - - <p>User consent to use <var>accumulated configuration</var> is specific to the <var>origin</var> and may be limited to configurations sharing certain properties with <var>accumulated configuration</var>.</p> - </div> - </div> - </li> - <li> - <p> - If consent was denied, run the following steps: - </p> - <ol> - <li> - <p>Update <var>restrictions</var> to reflect the configurations for which consent was denied.</p> - </li> - <li> - <p>Return <code>ConsentDenied</code> and <var>restrictions</var>.</p> - </li> - </ol> - </li> - </ol> - </li> - <li> - <p> - If the <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> member of <var>accumulated configuration</var> is not - <code><a href="#idl-def-MediaKeysRequirement.not-allowed">"not-allowed"</a></code>, return <code>InformUser</code>. - </p> - </li> - <li> - <p> - If the user agent requires informing the user for the <var>accumulated configuration</var> for other reasons, return <code>InformUser</code>. - </p> - </li> - <li> - <p>Return <code>Allowed</code>.</p> - </li> - </ol> - </section> - </section> - </section> - - <section id="mediakeysystemconfiguration-dictionary"> - <h3 id="x3.2-mediakeysystemconfiguration-dictionary"><span class="secno">3.2 </span><a href="#dom-mediakeysystemconfiguration" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemConfiguration</code></a> dictionary</h3> - - <div> - <div> - <pre class="def idl"><span class="idlEnum" id="idl-def-mediakeysrequirement" data-idl="" data-title="MediaKeysRequirement">enum <span class="idlEnumID"><a data-lt="MediaKeysRequirement" href="#dom-mediakeysrequirement" class="internalDFN" data-link-type="dfn" data-for=""><code>MediaKeysRequirement</code></a></span> { - <a href="#dom-mediakeysrequirement-required" class="idlEnumItem">"required"</a>, - <a href="#dom-mediakeysrequirement-optional" class="idlEnumItem">"optional"</a>, - <a href="#dom-mediakeysrequirement-not-allowed" class="idlEnumItem">"not-allowed"</a> -};</span></pre> - </div> - <p> - The <dfn data-dfn-for="" data-dfn-type="dfn" id="dom-mediakeysrequirement" data-idl="" data-title="MediaKeysRequirement"><code>MediaKeysRequirement</code></dfn> enumeration is defined as follows: - </p> - <table class="simple" data-dfn-for="MediaKeysRequirement" data-link-for="MediaKeysRequirement"> - <tbody> - <tr> - <th colspan="2">Enumeration description</th> - </tr> - <tr> - <td><dfn data-dfn-for="mediakeysrequirement" data-dfn-type="dfn" id="dom-mediakeysrequirement-required" data-idl="" data-title="required"><code id="idl-def-MediaKeysRequirement.required">required</code></dfn></td> - <td> - <dl> - <dt>When used in a call to <code><a href="#dom-navigator-requestmediakeysystemaccess">requestMediaKeySystemAccess()</a></code></dt> - <dd>The returned object <em class="rfc2119" title="MUST">MUST</em> support this feature.</dd> - <dt>When returned by a <a href="#dom-mediakeysystemaccess" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemAccess</code></a> object</dt> - <dd>CDM instances created by the object <em class="rfc2119" title="MAY">MAY</em> use this feature.</dd> - </dl> - </td> - </tr> - <tr> - <td><dfn data-dfn-for="mediakeysrequirement" data-dfn-type="dfn" id="dom-mediakeysrequirement-optional" data-idl="" data-title="optional"><code id="idl-def-MediaKeysRequirement.optional">optional</code></dfn></td> - <td> - <dl> - <dt>When used in a call to <code><a href="#dom-navigator-requestmediakeysystemaccess">requestMediaKeySystemAccess()</a></code></dt> - <dd>The returned object <em class="rfc2119" title="MAY">MAY</em> support and use this feature.</dd> - <dt>When returned by a <a href="#dom-mediakeysystemaccess" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemAccess</code></a> object</dt> - <dd>This value cannot and <em class="rfc2119" title="MUST NOT">MUST NOT</em> be present in such an object.</dd> - </dl> - </td> - </tr> - <tr> - <td><dfn data-dfn-for="mediakeysrequirement" data-dfn-type="dfn" id="dom-mediakeysrequirement-not-allowed" data-idl="" data-title="not-allowed"><code id="idl-def-MediaKeysRequirement.not-allowed">not-allowed</code></dfn></td> - <td> - <dl> - <dt>When used in a call to <code><a href="#dom-navigator-requestmediakeysystemaccess">requestMediaKeySystemAccess()</a></code></dt> - <dd>The returned object <em class="rfc2119" title="MUST">MUST</em> function without using this feature and <em class="rfc2119" title="MUST NOT">MUST NOT</em> use it at any time.</dd> - <dt>When returned by a <a href="#dom-mediakeysystemaccess" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemAccess</code></a> object</dt> - <dd>CDM instances created by the object <em class="rfc2119" title="MUST NOT">MUST NOT</em> use this feature.</dd> - </dl> - </td> - </tr> - </tbody> - </table> - </div> - - <div> - <div> - <pre class="def idl"><span class="idlDictionary" id="idl-def-mediakeysystemconfiguration" data-idl="" data-title="MediaKeySystemConfiguration">dictionary <span class="idlDictionaryID"><a data-lt="MediaKeySystemConfiguration" href="#dom-mediakeysystemconfiguration" class="internalDFN" data-link-type="dfn" data-for=""><code>MediaKeySystemConfiguration</code></a></span> { -<span class="idlMember" id="idl-def-mediakeysystemconfiguration-label" data-idl="" data-title="label" data-dfn-for="mediakeysystemconfiguration"> <span class="idlMemberType"><a href="https://heycam.github.io/webidl/#idl-DOMString">DOMString</a></span> <span class="idlMemberName"><a data-lt="label" href="#dom-mediakeysystemconfiguration-label" class="internalDFN" data-link-type="dfn" data-for="MediaKeySystemConfiguration"><code>label</code></a></span> = <span class="idlMemberValue">""</span>;</span> -<span class="idlMember" id="idl-def-mediakeysystemconfiguration-initdatatypes" data-idl="" data-title="initDataTypes" data-dfn-for="mediakeysystemconfiguration"> <span class="idlMemberType"><a href="https://heycam.github.io/webidl/#idl-sequence">sequence</a><<a href="https://heycam.github.io/webidl/#idl-DOMString">DOMString</a>></span> <span class="idlMemberName"><a data-lt="initDataTypes" href="#dom-mediakeysystemconfiguration-initdatatypes" class="internalDFN" data-link-type="dfn" data-for="MediaKeySystemConfiguration"><code>initDataTypes</code></a></span> = <span class="idlMemberValue">[]</span>;</span> -<span class="idlMember" id="idl-def-mediakeysystemconfiguration-audiocapabilities" data-idl="" data-title="audioCapabilities" data-dfn-for="mediakeysystemconfiguration"> <span class="idlMemberType"><a href="https://heycam.github.io/webidl/#idl-sequence">sequence</a><<a href="#dom-mediakeysystemmediacapability" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemMediaCapability</code></a>></span> <span class="idlMemberName"><a data-lt="audioCapabilities" href="#dom-mediakeysystemconfiguration-audiocapabilities" class="internalDFN" data-link-type="dfn" data-for="MediaKeySystemConfiguration"><code>audioCapabilities</code></a></span> = <span class="idlMemberValue">[]</span>;</span> -<span class="idlMember" id="idl-def-mediakeysystemconfiguration-videocapabilities" data-idl="" data-title="videoCapabilities" data-dfn-for="mediakeysystemconfiguration"> <span class="idlMemberType"><a href="https://heycam.github.io/webidl/#idl-sequence">sequence</a><<a href="#dom-mediakeysystemmediacapability" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemMediaCapability</code></a>></span> <span class="idlMemberName"><a data-lt="videoCapabilities" href="#dom-mediakeysystemconfiguration-videocapabilities" class="internalDFN" data-link-type="dfn" data-for="MediaKeySystemConfiguration"><code>videoCapabilities</code></a></span> = <span class="idlMemberValue">[]</span>;</span> -<span class="idlMember" id="idl-def-mediakeysystemconfiguration-distinctiveidentifier" data-idl="" data-title="distinctiveIdentifier" data-dfn-for="mediakeysystemconfiguration"> <span class="idlMemberType"><a href="#dom-mediakeysrequirement" class="internalDFN" data-link-type="dfn"><code>MediaKeysRequirement</code></a></span> <span class="idlMemberName"><a data-lt="distinctiveIdentifier" href="#dom-mediakeysystemconfiguration-distinctiveidentifier" class="internalDFN" data-link-type="dfn" data-for="MediaKeySystemConfiguration"><code>distinctiveIdentifier</code></a></span> = <span class="idlMemberValue">"optional"</span>;</span> -<span class="idlMember" id="idl-def-mediakeysystemconfiguration-persistentstate" data-idl="" data-title="persistentState" data-dfn-for="mediakeysystemconfiguration"> <span class="idlMemberType"><a href="#dom-mediakeysrequirement" class="internalDFN" data-link-type="dfn"><code>MediaKeysRequirement</code></a></span> <span class="idlMemberName"><a data-lt="persistentState" href="#dom-mediakeysystemconfiguration-persistentstate" class="internalDFN" data-link-type="dfn" data-for="MediaKeySystemConfiguration"><code>persistentState</code></a></span> = <span class="idlMemberValue">"optional"</span>;</span> -<span class="idlMember" id="idl-def-mediakeysystemconfiguration-sessiontypes" data-idl="" data-title="sessionTypes" data-dfn-for="mediakeysystemconfiguration"> <span class="idlMemberType"><a href="https://heycam.github.io/webidl/#idl-sequence">sequence</a><<a href="https://heycam.github.io/webidl/#idl-DOMString">DOMString</a>></span> <span class="idlMemberName"><a data-lt="sessionTypes" href="#dom-mediakeysystemconfiguration-sessiontypes" class="internalDFN" data-link-type="dfn" data-for="MediaKeySystemConfiguration"><code>sessionTypes</code></a></span>;</span> -};</span></pre> - </div> - <p> - The dictionary <dfn data-dfn-for="" data-dfn-type="dfn" id="dom-mediakeysystemconfiguration" data-idl="" data-title="MediaKeySystemConfiguration"><code>MediaKeySystemConfiguration</code></dfn> contains the following members: - </p> - <dl class="dictionary-members" data-dfn-for="MediaKeySystemConfiguration" data-link-for="MediaKeySystemConfiguration"><dt><dfn data-dfn-for="mediakeysystemconfiguration" data-dfn-type="dfn" id="dom-mediakeysystemconfiguration-label" data-idl="" data-title="label"><code>label</code></dfn> of type <span class="idlMemberType">DOMString</span>, defaulting to <code>""</code></dt> - <dd> - An optional label that will be preserved in the <a href="#dom-mediakeysystemconfiguration" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemConfiguration</code></a> returned from the <code><a href="#dom-mediakeysystemaccess-getconfiguration">getConfiguration()</a></code> method of <a href="#dom-mediakeysystemaccess" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemAccess</code></a>. - </dd><dt><dfn data-dfn-for="mediakeysystemconfiguration" data-dfn-type="dfn" id="dom-mediakeysystemconfiguration-initdatatypes" data-idl="" data-title="initDataTypes"><code>initDataTypes</code></dfn> of type <span class="idlMemberType">sequence<DOMString></span>, defaulting to <code>[]</code></dt> - <dd> - A list of supported <a href="#initialization-data-type">Initialization Data Type</a> names. The <a href="#initialization-data-type">Initialization Data Type</a> capability of this object is considered supported if the list is empty - or contains one or more values that are supported with all other members (as determined by the algorithm). Values in the sequence <em class="rfc2119" title="MUST">MUST</em> not be the empty string. - </dd><dt><dfn data-dfn-for="mediakeysystemconfiguration" data-dfn-type="dfn" id="dom-mediakeysystemconfiguration-audiocapabilities" data-idl="" data-title="audioCapabilities"><code>audioCapabilities</code></dfn> of type <span class="idlMemberType">sequence<<a href="#dom-mediakeysystemmediacapability" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemMediaCapability</code></a>></span>, defaulting to <code>[]</code></dt> - <dd> - A list of supported audio type and capability pairs. The audio capability of this object is considered supported if the list is empty or contains one or more values that are supported with all other members (as determined by the algorithm). When there - is a conflict between values, the earlier value will be selected. An empty list indicates that no audio capabilities are supported. In this case, the <code><a href="#dom-mediakeysystemconfiguration-videocapabilities">videoCapabilities</a></code> element must not be empty. - </dd><dt><dfn data-dfn-for="mediakeysystemconfiguration" data-dfn-type="dfn" id="dom-mediakeysystemconfiguration-videocapabilities" data-idl="" data-title="videoCapabilities"><code>videoCapabilities</code></dfn> of type <span class="idlMemberType">sequence<<a href="#dom-mediakeysystemmediacapability" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemMediaCapability</code></a>></span>, defaulting to <code>[]</code></dt> - <dd> - A list of supported video type and capability pairs. The video capability of this object is considered supported if the list is empty or contains one or more values that are supported with all other members (as determined by the algorithm). When there - is a conflict between values, the earlier value will be selected. An empty list indicates that no video capabilities are supported. In this case, the <code><a href="#dom-mediakeysystemconfiguration-audiocapabilities">audioCapabilities</a></code> element must not be empty. - </dd><dt><dfn data-dfn-for="mediakeysystemconfiguration" data-dfn-type="dfn" id="dom-mediakeysystemconfiguration-distinctiveidentifier" data-idl="" data-title="distinctiveIdentifier"><code>distinctiveIdentifier</code></dfn> of type <span class="idlMemberType"><a href="#dom-mediakeysrequirement" class="internalDFN" data-link-type="dfn"><code>MediaKeysRequirement</code></a></span>, defaulting to <code>"optional"</code></dt> - <dd> - Whether use of a <a href="#distinctive-identifier">Distinctive Identifier(s)</a> is required. - <p>When this member is <code><a href="#idl-def-MediaKeysRequirement.not-allowed">"not-allowed"</a></code>, the implementation <em class="rfc2119" title="MUST NOT">MUST NOT</em> <a href="#uses-distinctive-identifiers-or-distinctive-permanent-identifiers">use Distinctive Identifier(s) or Distinctive Permanent Identifier(s)</a> for any operations associated with any object created from this configuration. - </p> - </dd><dt><dfn data-dfn-for="mediakeysystemconfiguration" data-dfn-type="dfn" id="dom-mediakeysystemconfiguration-persistentstate" data-idl="" data-title="persistentState"><code>persistentState</code></dfn> of type <span class="idlMemberType"><a href="#dom-mediakeysrequirement" class="internalDFN" data-link-type="dfn"><code>MediaKeysRequirement</code></a></span>, defaulting to <code>"optional"</code></dt> - <dd> - Whether the ability to persist state is required. This includes session data and any other type of state. - <p>The CDM <em class="rfc2119" title="MUST NOT">MUST NOT</em> persist any state related to the application or <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> of this object's <a href="https://www.w3.org/TR/dom/#concept-document">Document</a> when this member is <code><a href="#idl-def-MediaKeysRequirement.not-allowed">"not-allowed"</a></code>.</p> - <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note46"><span>Note</span></div> - <p class="">For the purposes of this member, persistent state does not include persistent unique identifiers (<a href="#distinctive-identifier">Distinctive Identifiers</a>) controlled by the <a href="#key-system">Key System</a> implementation. - <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> independently reflects this requirement.</p> - </div> - <p>Only <code><a href="#idl-def-MediaKeySessionType.temporary">"temporary"</a></code> sessions may be created when persistent state is not supported.</p> - <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note47"><span>Note</span></div> - <p class="">For <code><a href="#idl-def-MediaKeySessionType.temporary">"temporary"</a></code> sessions, the need and ability to store state is <a href="#key-system">Key System</a> implementation-specific and may vary by feature used.</p> - </div> - <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note48"><span>Note</span></div> - <p class="">Applications intending to create non-<code><a href="#idl-def-MediaKeySessionType.temporary">"temporary"</a></code> sessions, should set this member to <code><a href="#idl-def-MediaKeysRequirement.required">"required"</a></code> when calling <code><a href="#dom-navigator-requestmediakeysystemaccess">requestMediaKeySystemAccess()</a></code>.</p> - </div> - </dd><dt><dfn data-dfn-for="mediakeysystemconfiguration" data-dfn-type="dfn" id="dom-mediakeysystemconfiguration-sessiontypes" data-idl="" data-title="sessionTypes"><code>sessionTypes</code></dfn> of type <span class="idlMemberType">sequence<DOMString></span></dt> - <dd> - A list of <a href="#dom-mediakeysessiontype" class="internalDFN" data-link-type="dfn"><code>MediaKeySessionType</code></a>s that must be supported. All values must be supported. - <p>If this member is <a href="https://heycam.github.io/webidl/#dfn-present">not present</a> [<cite><a class="bibref" href="#bib-WEBIDL">WEBIDL</a></cite>] when the dictionary is passed to <code><a href="#dom-navigator-requestmediakeysystemaccess">requestMediaKeySystemAccess()</a></code>, - the dictionary will be treated as if this member is set to <code>[ <code><a href="#idl-def-MediaKeySessionType.temporary">"temporary"</a></code> ]</code>.</p> - </dd> - </dl> - - <p>Implementations <em class="rfc2119" title="SHOULD NOT">SHOULD NOT</em> add members to this dictionary. Should member(s) be added, they <em class="rfc2119" title="MUST">MUST</em> be of type <a href="#dom-mediakeysrequirement" class="internalDFN" - data-link-type="dfn"><code>MediaKeysRequirement</code></a>, and it is <em class="rfc2119" title="RECOMMENDED">RECOMMENDED</em> that they have default values of <code><a href="#idl-def-MediaKeysRequirement.optional">"optional"</a></code> to support the widest range of application and client combinations. - </p> - <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note49"><span>Note</span></div> - <p class="">Dictionary members not recognized by a user agent implementation are ignored per [<cite><a class="bibref" href="#bib-WEBIDL">WEBIDL</a></cite>] and will not be considered in the <code><a href="#dom-navigator-requestmediakeysystemaccess">requestMediaKeySystemAccess()</a></code> algorithm. Should an application use non-standard dictionary member(s), it <em class="rfc2119" title="MUST NOT">MUST NOT</em> rely on user agent implementations rejecting a configuration that includes such dictionary members. - </p> - </div> - <p>This dictionary <em class="rfc2119" title="MUST NOT">MUST NOT</em> be used to pass state or data to the CDM.</p> - - </div> - </section> - - <section id="mediakeysystemmediacapability-dictionary"> - <h3 id="x3.3-mediakeysystemmediacapability-dictionary"><span class="secno">3.3 </span><dfn data-dfn-for="" data-dfn-type="dfn" id="dom-mediakeysystemmediacapability" data-idl="" data-title="MediaKeySystemMediaCapability"><code>MediaKeySystemMediaCapability</code></dfn> dictionary</h3> - <div> - <div> - <pre class="def idl"><span class="idlDictionary" id="idl-def-mediakeysystemmediacapability" data-idl="" data-title="MediaKeySystemMediaCapability">dictionary <span class="idlDictionaryID"><a data-lt="MediaKeySystemMediaCapability" href="#dom-mediakeysystemmediacapability" class="internalDFN" data-link-type="dfn" data-for=""><code>MediaKeySystemMediaCapability</code></a></span> { -<span class="idlMember" id="idl-def-mediakeysystemmediacapability-contenttype" data-idl="" data-title="contentType" data-dfn-for="mediakeysystemmediacapability"> <span class="idlMemberType"><a href="https://heycam.github.io/webidl/#idl-DOMString">DOMString</a></span> <span class="idlMemberName"><a data-lt="contentType" href="#dom-mediakeysystemmediacapability-contenttype" class="internalDFN" data-link-type="dfn" data-for="MediaKeySystemMediaCapability"><code>contentType</code></a></span> = <span class="idlMemberValue">""</span>;</span> -<span class="idlMember" id="idl-def-mediakeysystemmediacapability-robustness" data-idl="" data-title="robustness" data-dfn-for="mediakeysystemmediacapability"> <span class="idlMemberType"><a href="https://heycam.github.io/webidl/#idl-DOMString">DOMString</a></span> <span class="idlMemberName"><a data-lt="robustness" href="#dom-mediakeysystemmediacapability-robustness" class="internalDFN" data-link-type="dfn" data-for="MediaKeySystemMediaCapability"><code>robustness</code></a></span> = <span class="idlMemberValue">""</span>;</span> -};</span></pre> - </div> - <section> - <h4 id="dictionary-mediakeysystemmediacapability-members">Dictionary <a class="idlType internalDFN" href="#dom-mediakeysystemmediacapability" data-link-type="dfn"><code>MediaKeySystemMediaCapability</code></a> Members</h4> - <dl class="dictionary-members" data-dfn-for="MediaKeySystemMediaCapability" - data-link-for="MediaKeySystemMediaCapability"><dt><dfn data-dfn-for="mediakeysystemmediacapability" data-dfn-type="dfn" id="dom-mediakeysystemmediacapability-contenttype" data-idl="" data-title="contentType"><code>contentType</code></dfn> of type <span class="idlMemberType">DOMString</span>, defaulting to <code>""</code></dt> - <dd> - <p> - The type of the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-resource">media resource</a>. Its value must be a <a href="#valid-media-mime-type">valid media MIME type</a>. The empty string - is invalid. - </p> - </dd><dt><dfn data-dfn-for="mediakeysystemmediacapability" data-dfn-type="dfn" id="dom-mediakeysystemmediacapability-robustness" data-idl="" data-title="robustness"><code>robustness</code></dfn> of type <span class="idlMemberType">DOMString</span>, defaulting to <code>""</code></dt> - <dd> - <p> - The robustness level associated with the content type. The empty string indicates that any ability to decrypt and decode the content type is acceptable. - </p> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note50"><span>Note</span></div> - <div class=""> - <p> - Implementations <em class="rfc2119" title="MUST">MUST</em> configure the CDM to support at least the robustness levels specified in the configuration of the MediaKeySystemAccess object used to create the MediaKeys - object. Exact configuration of the CDM is implementation-specific, and implementations <em class="rfc2119" title="MAY">MAY</em> configure the CDM to use the highest robustness level in the configuration even if - a higher robustness level is available. If only the empty string is specified, implementations <em class="rfc2119" title="MAY">MAY</em> be configured to use the lowest robustness level the implementation supports. - </p> - <p> - Applications <em class="rfc2119" title="SHOULD">SHOULD</em> specify the robustness level(s) they require to avoid unexpected client incompatibilities. - </p> - </div> - </div> - </dd> - </dl> - </section> - </div> - - <p>In order for the capability represented by this object to be considered supported, <code><a href="#dom-mediakeysystemmediacapability-contenttype">contentType</a></code> <em class="rfc2119" title="MUST NOT">MUST NOT</em> be the empty string - and its entire value, including all codecs, <em class="rfc2119" title="MUST">MUST</em> be supported with <code><a href="#dom-mediakeysystemmediacapability-robustness">robustness</a></code>.</p> - <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note51"><span>Note</span></div> - <p class="">If any of a set of codecs is acceptable, use a separate instances of this dictionary for each codec.</p> - </div> - </section> - </section> - - - <section id="mediakeysystemaccess-interface"> - <!--OddPage--> - <h2 id="x4.-mediakeysystemaccess-interface"><span class="secno">4. </span><dfn data-dfn-for="" data-dfn-type="dfn" id="dom-mediakeysystemaccess" data-idl="" data-title="MediaKeySystemAccess"><code>MediaKeySystemAccess</code></dfn> Interface</h2> - <p>The MediaKeySystemAccess object provides access to a <a href="#key-system">Key System</a>.</p> - - <div> - <div> - <pre class="def idl"><span class="idlInterface" id="idl-def-mediakeysystemaccess" data-idl="" data-title="MediaKeySystemAccess">[<span class="extAttr"><span class="extAttrName"><a href="https://heycam.github.io/webidl/#SecureContext">SecureContext</a></span></span>] -interface <span class="idlInterfaceID"><a data-lt="MediaKeySystemAccess" href="#dom-mediakeysystemaccess" class="internalDFN" data-link-type="dfn" data-for=""><code>MediaKeySystemAccess</code></a></span> { -<span class="idlAttribute" id="idl-def-mediakeysystemaccess-keysystem" data-idl="" data-title="keySystem" data-dfn-for="mediakeysystemaccess"> readonly attribute <span class="idlAttrType"><a href="https://heycam.github.io/webidl/#idl-DOMString">DOMString</a></span> <span class="idlAttrName"><a data-lt="keySystem" href="#dom-mediakeysystemaccess-keysystem" class="internalDFN" data-link-type="dfn" data-for="MediaKeySystemAccess"><code>keySystem</code></a></span>;</span> -<span class="idlMethod" id="idl-def-mediakeysystemaccess-getconfiguration()" data-idl="" data-title="getConfiguration" data-dfn-for="mediakeysystemaccess"> <span class="idlMethType"><a href="#dom-mediakeysystemconfiguration" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemConfiguration</code></a></span> <span class="idlMethName"><a data-lt="getConfiguration" href="#dom-mediakeysystemaccess-getconfiguration" class="internalDFN" data-link-type="dfn" data-for="MediaKeySystemAccess"><code>getConfiguration</code></a></span>();</span> -<span class="idlMethod" id="idl-def-mediakeysystemaccess-createmediakeys()" data-idl="" data-title="createMediaKeys" data-dfn-for="mediakeysystemaccess"> <span class="idlMethType"><a href="https://heycam.github.io/webidl/#idl-promise">Promise</a><<a href="#dom-mediakeys" class="internalDFN" data-link-type="dfn"><code>MediaKeys</code></a>></span> <span class="idlMethName"><a data-lt="createMediaKeys" href="#dom-mediakeysystemaccess-createmediakeys" class="internalDFN" data-link-type="dfn" data-for="MediaKeySystemAccess"><code>createMediaKeys</code></a></span>();</span> -};</span></pre> - </div> - <section> - <h3 id="attributes">Attributes</h3> - <dl class="attributes" data-dfn-for="MediaKeySystemAccess" data-link-for="MediaKeySystemAccess"><dt><dfn data-dfn-for="mediakeysystemaccess" data-dfn-type="dfn" id="dom-mediakeysystemaccess-keysystem" data-idl="" data-title="keySystem"><code>keySystem</code></dfn> of type <span class="idlAttrType">DOMString</span>, readonly </dt> - <dd> - Identifies the <a href="#key-system">Key System</a> being used. - </dd> - </dl> - </section> - <section> - <h3 id="methods-0">Methods</h3> - <dl class="methods" data-dfn-for="MediaKeySystemAccess" data-link-for="MediaKeySystemAccess"><dt><dfn data-dfn-for="mediakeysystemaccess" data-dfn-type="dfn" id="dom-mediakeysystemaccess-getconfiguration" data-idl="" data-title="getConfiguration" data-lt="getconfiguration()|getConfiguration"><code id="getConfiguration">getConfiguration</code></dfn></dt> - <dd> - <p>Returns the supported combination of configuration options selected by the <code><a href="#dom-navigator-requestmediakeysystemaccess">requestMediaKeySystemAccess()</a></code> algorithm. - </p> - <p>The returned object is a non-strict subset (plus any implied defaults) of the first satisfiable <a href="#dom-mediakeysystemconfiguration" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemConfiguration</code></a> configuration - passed to the <code><a href="#dom-navigator-requestmediakeysystemaccess">requestMediaKeySystemAccess()</a></code> call that returned the promise that was resolved with this object. It does not contain values capabilities not - specified in that single configuration (other than implied defaults) and thus may not reflect all capabilities of the <a href="#key-system">Key System</a> implementation. All values in the configuration may be used in any combination. - Members of type <a href="#dom-mediakeysrequirement" class="internalDFN" data-link-type="dfn"><code>MediaKeysRequirement</code></a> reflect whether the capability is required for any combination. They will not have the value - <code><a href="#idl-def-MediaKeysRequirement.optional">"optional"</a></code>. - </p> - - - <div><em>No parameters.</em></div> - <div><em>Return type: </em><code>MediaKeySystemConfiguration</code></div> - <p>When this method is invoked, the user agent must run the following steps:</p> - <ol class="method-algorithm"> - <li> - <p> - Return this object's <var>configuration</var> value. - </p> - <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note52"><span>Note</span></div> - <p class=""> - This results in a new object being created and initialized from <var>configuration</var> each time this method is called. - </p> - </div> - </li> - </ol> - </dd><dt><dfn data-dfn-for="mediakeysystemaccess" data-dfn-type="dfn" id="dom-mediakeysystemaccess-createmediakeys" data-idl="" data-title="createMediaKeys" data-lt="createmediakeys()|createMediaKeys"><code id="createMediaKeys">createMediaKeys</code></dfn></dt> - <dd> - <p>Creates a new <a href="#dom-mediakeys" class="internalDFN" data-link-type="dfn"><code>MediaKeys</code></a> object for <var>keySystem</var>.</p> - - - <div><em>No parameters.</em></div> - <div><em>Return type: </em><code>Promise<MediaKeys></code></div> - <p>When this method is invoked, the user agent must run the following steps:</p> - <ol class="method-algorithm"> - <li> - <p>Let <var>promise</var> be a new promise.</p> - </li> - <li> - <p>Run the following steps in parallel:</p> - <ol> - <li> - <p>Let <var>configuration</var> be the value of this object's <var>configuration</var> value.</p> - </li> - <li> - <p> - Let <var>use distinctive identifier</var> be <code>true</code> if the value of <var>configuration</var>'s <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> member is <code><a href="#idl-def-MediaKeysRequirement.required">"required"</a></code> and <code>false</code> otherwise. - </p> - </li> - <li> - <p> - Let <var>persistent state allowed</var> be <code>true</code> if the value of <var>configuration</var>'s <code><a href="#dom-mediakeysystemconfiguration-persistentstate">persistentState</a></code> member is <code><a href="#idl-def-MediaKeysRequirement.required">"required"</a></code> and <code>false</code> otherwise. - </p> - <p> - </p> - </li> - <li> - <p>Load and initialize the <a href="#key-system">Key System</a> implementation represented by this object's <var>cdm implementation</var> value if necessary.</p> - </li> - <li> - <p>Let <var>instance</var> be a new instance of the <a href="#key-system">Key System</a> implementation represented by this object's <var>cdm implementation</var> value.</p> - </li> - <li> - <p>Initialize <var>instance</var> to enable, disable and/or select <a href="#key-system">Key System</a> features using <var>configuration</var>.</p> - </li> - <li> - <p>If <var>use distinctive identifier</var> is <code>false</code>, prevent <var>instance</var> from <a href="#uses-distinctive-identifiers-or-distinctive-permanent-identifiers">using Distinctive Identifier(s) and Distinctive Permanent Identifier(s)</a>.</p> - </li> - <li> - <p>If <var>persistent state allowed</var> is <code>false</code>, prevent <var>instance</var> from persisting any state related to the application or <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> of this object's <a href="https://www.w3.org/TR/dom/#concept-document">Document</a>.</p> - </li> - <li> - <p>If any of the preceding steps failed, reject <var>promise</var> with a new <code><a href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code> whose name is the appropriate <a href="#error-names">error name</a>.</p> - </li> - <li> - <p>Let <var>media keys</var> be a new <a href="#dom-mediakeys" class="internalDFN" data-link-type="dfn"><code>MediaKeys</code></a> object, and initialize it as follows:</p> - <ol> - <li> - <p>Let the <var>use distinctive identifier</var> value be <var>use distinctive identifier</var>.</p> - </li> - <li> - <p>Let the <var>persistent state allowed</var> value be <var>persistent state allowed</var>.</p> - </li> - <li> - <p>Let the <var>supported session types</var> value be be the value of <var>configuration</var>'s <code><a href="#dom-mediakeysystemconfiguration-sessiontypes">sessionTypes</a></code> member.</p> - </li> - <li> - <p>Let the <var>cdm implementation</var> value be this object's <var>cdm implementation</var> value.</p> - </li> - <li> - <p>Let the <var>cdm instance</var> value be <var>instance</var>.</p> - </li> - </ol> - </li> - <li> - <p>Resolve <var>promise</var> with <var>media keys</var>.</p> - </li> - </ol> - </li> - <li> - <p>Return <var>promise</var>.</p> - </li> - </ol> - </dd> - </dl> - </section> - </div> - </section> - - - <section id="mediakeys-interface"> - <!--OddPage--> - <h2 id="x5.-mediakeys-interface"><span class="secno">5. </span><dfn data-dfn-for="" data-dfn-type="dfn" id="dom-mediakeys" data-idl="" data-title="MediaKeys"><code>MediaKeys</code></dfn> Interface</h2> - <p>The MediaKeys object represents a set of keys that an associated HTMLMediaElement can use for decryption of <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a> during playback. It also represents a - <a href="#cdm">CDM</a> instance. - </p> - <p>A <a href="#dom-mediakeys" class="internalDFN" data-link-type="dfn"><code>MediaKeys</code></a> object may be destroyed by the user agent when it is no longer accessible</p> - <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note53"><span>Note</span></div> - <p class="">For example, when there are no script references and no attached media element.</p> - </div> - <p>For methods that return a promise, all errors are reported asynchronously by rejecting the returned Promise. This includes [<cite><a class="bibref" href="#bib-WEBIDL">WEBIDL</a></cite>] type mapping errors.</p> - <p>The steps of an algorithm are always aborted when rejecting a promise.</p> - - <div> - <div> - <pre class="def idl"><span class="idlEnum" id="idl-def-mediakeysessiontype" data-idl="" data-title="MediaKeySessionType">enum <span class="idlEnumID"><a data-lt="MediaKeySessionType" href="#dom-mediakeysessiontype" class="internalDFN" data-link-type="dfn" data-for=""><code>MediaKeySessionType</code></a></span> { - <a href="#dom-mediakeysessiontype-temporary" class="idlEnumItem">"temporary"</a>, - <a href="#dom-mediakeysessiontype-persistent-license" class="idlEnumItem">"persistent-license"</a>, - <a href="#dom-mediakeysessiontype-persistent-usage-record" class="idlEnumItem">"persistent-usage-record"</a> -};</span></pre> - </div> - <p>The <dfn data-dfn-for="" data-dfn-type="dfn" id="dom-mediakeysessiontype" data-idl="" data-title="MediaKeySessionType"><code>MediaKeySessionType</code></dfn> enumeration is defined as follows:</p> - <table class="simple" data-dfn-for="MediaKeySessionType" data-link-for="MediaKeySessionType"> - <tbody> - <tr> - <th colspan="2">Enumeration description</th> - </tr> - <tr> - <td><dfn data-dfn-for="mediakeysessiontype" data-dfn-type="dfn" id="dom-mediakeysessiontype-temporary" data-idl="" data-title="temporary"><code id="idl-def-MediaKeySessionType.temporary">temporary</code></dfn></td> - <td> - <p> - A session for which the license, key(s) and record of or data related to the session are not persisted. - </p> - <p> - The application need not worry about managing such storage. Support for this session type is <em class="rfc2119" title="REQUIRED">REQUIRED</em>. - </p> - </td> - </tr> - <tr> - <td><dfn data-dfn-for="mediakeysessiontype" data-dfn-type="dfn" id="dom-mediakeysessiontype-persistent-license" data-idl="" data-title="persistent-license"><code id="idl-def-MediaKeySessionType.persistent-license">persistent-license</code></dfn></td> - <td> - <p> - A session for which the license (and potentially other data related to the session) will be persisted. A <a href="#record-of-license-destruction">record of license destruction</a> <em class="rfc2119" title="SHALL">SHALL</em> be persisted when the license and key(s) it contains are destroyed. The <dfn id="record-of-license-destruction" data-dfn-type="dfn">record of license destruction</dfn> is a <a href="#key-system">Key System</a>-specific - attestation that the license and key(s) it contains are no longer usable by the client. Support for this session type is <em class="rfc2119" title="OPTIONAL">OPTIONAL</em>. - </p> - <p> - Sessions of this type can only be created if the configuration associated with the <a href="#dom-mediakeysystemaccess" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemAccess</code></a> object that created this - object has a <code><a href="#dom-mediakeysystemconfiguration-persistentstate">persistentState</a></code> value of <code><a href="#idl-def-MediaKeysRequirement.required">"required"</a></code>. The session <em class="rfc2119" - title="MUST">MUST</em> be loadable via its <a href="#session-id">Session ID</a> once <code><a href="#dom-mediakeysession-update">update()</a></code> is called successfully. A <code><a href="#dom-evt-message">message</a></code> of type <code><a href="#idl-def-MediaKeyMessageType.license-release">"license-release"</a></code> containing the <a href="#record-of-license-destruction">record of license destruction</a> will be generated when <code><a href="#dom-mediakeysession-remove">remove()</a></code> is called until the record is acknowledged by a response passed to <code><a href="#dom-mediakeysession-update">update()</a></code>. - </p> - <p> - The application is responsible for ensuring that data persisted for such sessions is removed when the application no longer needs it. See <a href="#session-storage">Session Storage and Persistence</a>. - </p> - </td> - </tr> - <tr> - <td><dfn data-dfn-for="mediakeysessiontype" data-dfn-type="dfn" id="dom-mediakeysessiontype-persistent-usage-record" data-idl="" data-title="persistent-usage-record"><code id="idl-def-MediaKeySessionType.persistent-usage-record">persistent-usage-record</code></dfn></td> - <td> - <p> - A session for which the license and key(s) are not persisted and for which a <a href="#record-of-key-usage">record of key usage</a> is persisted when the keys available within the session are destroyed. The <dfn id="record-of-key-usage" - data-dfn-type="dfn">record of key usage</dfn> consists of: - </p> - <ul> - <li> - <p>A record of the <a href="#decryption-key-id">key IDs</a> of all the key(s) that were at any time <a href="#known-key">known</a> to the session,</p> - </li> - <li> - <p> - <var>first decryption time</var> - The <dfn id="first-decryption-time" data-dfn-type="dfn">first decryption time</dfn>, defined as the time at which the session was first used to decrypt content, accurate to <var><var><a href="#key-usage-accuracy">key usage accuracy</a></var></var> - and - </p> - </li> - <li> - <p> - <var>latest decryption time</var> - The <dfn id="latest-decryption-time" data-dfn-type="dfn">latest decryption time</dfn>, defined as the latest time at which the session was used to decrypt content, accurate to - <var><var><a href="#key-usage-accuracy">key usage accuracy</a></var></var>. - </p> - </li> - </ul> - <p> - A <code><a href="#dom-evt-message">message</a></code> of type <code><a href="#idl-def-MediaKeyMessageType.license-release">"license-release"</a></code> containing the <a href="#record-of-key-usage">record of key usage</a> will be generated each time <code><a href="#dom-mediakeysession-remove">remove()</a></code> is called, until the record is acknowledged by a response passed to <code><a href="#dom-mediakeysession-update">update()</a></code>. - </p> - <p> - The <dfn id="key-usage-accuracy" data-dfn-type="dfn"><var>key usage accuracy</var></dfn> is implementation-dependant but <em class="rfc2119" title="SHALL NOT">SHALL NOT</em> be greater than 60 seconds. - </p> - <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note54"><span>Note</span></div> - <p class=""> - Because the license and keys are not persisted, this record implicitly proves that the keys are no longer available in the session. - </p> - </div> - <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note55"><span>Note</span></div> - <p class=""> - User agents <em class="rfc2119" title="MAY">MAY</em> implement this mechanism by means other than persisting data on key destruction - for example by persisting data during playback which is later used to infer the - fact of key destruction - provided the observable behavior is compliant to this specification. - </p> - </div> - <p> - The session <em class="rfc2119" title="MUST">MUST</em> be loadable via its <a href="#session-id">Session ID</a> once <code><a href="#dom-mediakeysession-update">update()</a></code> is called successfully. The application - is responsible for managing any such storage that may be generated by the CDM. See <a href="#session-storage">Session Storage and Persistence</a>. Can only be created if the configuration associated with the <a href="#dom-mediakeysystemaccess" - class="internalDFN" data-link-type="dfn"><code>MediaKeySystemAccess</code></a> object that created this object has a <code><a href="#dom-mediakeysystemconfiguration-persistentstate">persistentState</a></code> value of <code><a href="#idl-def-MediaKeysRequirement.required">"required"</a></code>. - Support for this session type is <em class="rfc2119" title="OPTIONAL">OPTIONAL</em>. - </p> - </td> - </tr> - </tbody> - </table> - </div> - - <div> - <div> - <pre class="def idl"><span class="idlInterface" id="idl-def-mediakeys" data-idl="" data-title="MediaKeys">[<span class="extAttr"><span class="extAttrName"><a href="https://heycam.github.io/webidl/#SecureContext">SecureContext</a></span></span>] -interface <span class="idlInterfaceID"><a data-lt="MediaKeys" href="#dom-mediakeys" class="internalDFN" data-link-type="dfn" data-for=""><code>MediaKeys</code></a></span> { -<span class="idlMethod" id="idl-def-mediakeys-createsession(sessiontype)" data-idl="" data-title="createSession" data-dfn-for="mediakeys"> <span class="idlMethType"><a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a></span> <span class="idlMethName"><a data-lt="createSession" href="#dom-mediakeys-createsession" class="internalDFN" data-link-type="dfn" data-for="MediaKeys"><code>createSession</code></a></span>(<span class="idlParam">optional <span class="idlParamType"><a href="#dom-mediakeysessiontype" class="internalDFN" data-link-type="dfn"><code>MediaKeySessionType</code></a></span> <span class="idlParamName">sessionType</span> = <span class="idlDefaultValue">"temporary"</span></span>);</span> -<span class="idlMethod" id="idl-def-mediakeys-setservercertificate(servercertificate)" data-idl="" data-title="setServerCertificate" data-dfn-for="mediakeys"> <span class="idlMethType"><a href="https://heycam.github.io/webidl/#idl-promise">Promise</a><<a href="https://heycam.github.io/webidl/#idl-boolean">boolean</a>></span> <span class="idlMethName"><a data-lt="setServerCertificate" href="#dom-mediakeys-setservercertificate" class="internalDFN" data-link-type="dfn" data-for="MediaKeys"><code>setServerCertificate</code></a></span>(<span class="idlParam"><span class="idlParamType">BufferSource</span> <span class="idlParamName">serverCertificate</span></span>);</span> -};</span></pre> - </div> - <section> - <h3 id="methods-1">Methods</h3> - <dl class="methods" data-dfn-for="MediaKeys" data-link-for="MediaKeys"><dt><dfn data-dfn-for="mediakeys" data-dfn-type="dfn" id="dom-mediakeys-createsession" data-idl="" data-title="createSession" data-lt="createsession()|createSession"><code id="createSession">createSession</code></dfn></dt> - <dd> - <p>Returns a new <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object.</p> - - - - - <table class="parameters"> - <tbody> - <tr> - <th>Parameter</th> - <th>Type</th> - <th>Nullable</th> - <th>Optional</th> - <th>Description</th> - </tr> - <tr> - <td class="prmName">sessionType</td> - <td class="prmType"><code>MediaKeySessionType = "temporary"</code></td> - <td class="prmNullFalse"><span role="img" aria-label="False">✘</span></td> - <td class="prmOptTrue"><span role="img" aria-label="True">✔</span></td> - <td class="prmDesc"> - The type of session to create. The session type affects the behavior of the returned object. - </td> - </tr> - </tbody> - </table> - <div><em>Return type: </em><code>MediaKeySession</code></div> - <p>When this method is invoked, the user agent must run the following steps:</p> - <ol class="method-algorithm"> - <li> - <p>If this object's <var>supported session types</var> value does not contain <var>sessionType</var>, <a href="https://heycam.github.io/webidl/#dfn-throw">throw</a> [<cite><a class="bibref" href="#bib-WEBIDL">WEBIDL</a></cite>] - a <code><a href="#dfn-NotSupportedError">NotSupportedError</a></code>.</p> - <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note56"><span>Note</span></div> - <p class=""><var>sessionType</var> values for which the <a href="#is-persistent-session-type">Is persistent session type?</a> algorithm returns <code>true</code> will fail if this object's <var>persistent state allowed</var> value - is <code>false</code>.</p> - </div> - </li> - <li> - <p>If the implementation does not support <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> operations in the current state, <a href="https://heycam.github.io/webidl/#dfn-throw">throw</a> [<cite><a class="bibref" href="#bib-WEBIDL">WEBIDL</a></cite>] an <code><a href="#dfn-InvalidStateError">InvalidStateError</a></code>.</p> - <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note57"><span>Note</span></div> - <p class="">Some implementations are unable to execute <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> algorithms until this <a href="#dom-mediakeys" class="internalDFN" - data-link-type="dfn"><code>MediaKeys</code></a> object is associated with a media element using <code><a href="#dom-htmlmediaelement-setmediakeys">setMediaKeys()</a></code>. This step enables applications to detect - this uncommon behavior before attempting to perform such operations. - </p> - </div> - </li> - <li> - <p>Let <var>session</var> be a new <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object, and initialize it as follows:</p> - <ol> - <li> - <p>Let the <code><a href="#dom-mediakeysession-sessionid">sessionId</a></code> attribute be the empty string.</p> - </li> - <li> - <p>Let the <code><a href="#dom-mediakeysession-expiration">expiration</a></code> attribute be <code>NaN</code>.</p> - </li> - <li> - <p>Let the <code><a href="#dom-mediakeysession-closed">closed</a></code> attribute be a new promise.</p> - </li> - <li> - <p>Let <var>key status</var> be a new empty <a href="#dom-mediakeystatusmap" class="internalDFN" data-link-type="dfn"><code>MediaKeyStatusMap</code></a> object, and initialize it as follows:</p> - <ol> - <li> - <p>Let the <code><a href="#dom-mediakeystatusmap-size">size</a></code> attribute be 0.</p> - </li> - </ol> - </li> - <li> - <p>Let the <var>session type</var> value be <var>sessionType</var>.</p> - </li> - <li> - <p>Let the <var>uninitialized</var> value be true.</p> - </li> - <li> - <p>Let the <var>callable</var> value be false.</p> - </li> - <li> - <p>Let the <var>closing or closed</var> value be false.</p> - </li> - <li> - <p>Let the <var>use distinctive identifier</var> value be this object's <var>use distinctive identifier</var> value.</p> - </li> - <li> - <p>Let the <var>cdm implementation</var> value be this object's <var>cdm implementation</var>.</p> - </li> - <li> - <p>Let the <var>cdm instance</var> value be this object's <var>cdm instance</var>.</p> - </li> - </ol> - </li> - <li> - <p>Return <var>session</var>.</p> - </li> - </ol> - </dd><dt><dfn data-dfn-for="mediakeys" data-dfn-type="dfn" id="dom-mediakeys-setservercertificate" data-idl="" data-title="setServerCertificate" data-lt="setservercertificate()|setServerCertificate"><code id="setServerCertificate">setServerCertificate</code></dfn></dt> - <dd> - <p id="server-certificate">Provides a server certificate to be used to encrypt messages to the license server.</p> - <p>Key Systems that use such certificates <em class="rfc2119" title="MUST">MUST</em> also support requesting the certificate from the server via the <a href="#queue-message">Queue a "message" Event</a> algorithm.</p> - <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note58"><span>Note</span></div> - <p class="">This method allows an application to proactively provide a server certificate to implementations that support it to avoid the additional round trip should the CDM request it. It is intended as an optimization, and applications - are not required to use it. - </p> - </div> - - - - - <table class="parameters"> - <tbody> - <tr> - <th>Parameter</th> - <th>Type</th> - <th>Nullable</th> - <th>Optional</th> - <th>Description</th> - </tr> - <tr> - <td class="prmName">serverCertificate</td> - <td class="prmType"><code>BufferSource</code></td> - <td class="prmNullFalse"><span role="img" aria-label="False">✘</span></td> - <td class="prmOptFalse"><span role="img" aria-label="False">✘</span></td> - <td class="prmDesc"> - The server certificate. The contents are <a href="#key-system">Key System</a>-specific. It <em class="rfc2119" title="MUST NOT">MUST NOT</em> contain executable code. - </td> - </tr> - </tbody> - </table> - <div><em>Return type: </em><code>Promise<boolean></code></div> - <p>When this method is invoked, the user agent must run the following steps:</p> - <ol class="method-algorithm"> - <li> - <p>If the <a href="#key-system">Key System</a> implementation represented by this object's <var>cdm implementation</var> value does not support server certificates, return a promise resolved with <code>false</code>.</p> - </li> - <li> - <p>If <var>serverCertificate</var> is an empty array, return a promise rejected with a new a newly created <code><a href="#dfn-TypeError">TypeError</a></code>.</p> - </li> - <li> - <p>Let <var>certificate</var> be a copy of the contents of the <var>serverCertificate</var> parameter.</p> - </li> - <li> - <p>Let <var>promise</var> be a new promise.</p> - </li> - <li> - <p>Run the following steps in parallel:</p> - <ol> - <li> - <p>Let <var>sanitized certificate</var> be a validated and/or sanitized version of <var>certificate</var>.</p> - <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note59"><span>Note</span></div> - <p class="">The user agent should thoroughly validate the certificate before passing it to the CDM. This may include verifying values are within reasonable limits, stripping irrelevant data or fields, pre-parsing it, sanitizing - it, and/or generating a fully sanitized version. The user agent should check that the length and values of fields are reasonable. Unknown fields should be rejected or removed. - </p> - </div> - </li> - <li> - <p>Use this object's <var>cdm instance</var> to process <var>sanitized certificate</var>.</p> - </li> - <li> - <p>If the preceding step failed, resolve <var>promise</var> with a new <code><a href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code> whose name is the appropriate <a href="#error-names">error name</a>.</p> - </li> - <li> - <p>Resolve <var>promise</var> with <code>true</code>.</p> - </li> - </ol> - </li> - <li> - <p>Return <var>promise</var>.</p> - </li> - </ol> - </dd> - </dl> - </section> - </div> - - <section id="algorithms-0"> - <h3 id="x5.1-algorithms"><span class="secno">5.1 </span>Algorithms</h3> - <section id="is-persistent-session-type"> - <h4 id="x5.1.1-is-persistent-session-type?"><span class="secno">5.1.1 </span>Is persistent session type?</h4> - <p>The Is persistent session type? algorithm is run to determine whether the specified session type supports persistence of any kind. Requests to run this algorithm include a <a href="#dom-mediakeysessiontype" class="internalDFN" data-link-type="dfn"><code>MediaKeySessionType</code></a> value. - </p> - <p>The following steps are run:</p> - <ol> - <li> - <p>Let the <var>session type</var> be the specified <a href="#dom-mediakeysessiontype" class="internalDFN" data-link-type="dfn"><code>MediaKeySessionType</code></a> value.</p> - </li> - <li> - <p>Follow the steps for the value of <var>session type</var> from the following list:</p> - <dl class="switch"> - <dt><code><a href="#idl-def-MediaKeySessionType.temporary">"temporary"</a></code></dt> - <dd>Return <code>false</code>.</dd> - <dt><code><a href="#idl-def-MediaKeySessionType.persistent-license">"persistent-license"</a></code></dt> - <dd>Return <code>true</code>.</dd> - <dt><code><a href="#idl-def-MediaKeySessionType.persistent-usage-record">"persistent-usage-record"</a></code></dt> - <dd>Return <code>true</code>.</dd> - </dl> - </li> - </ol> - </section> - - <section id="cdm-unavailable"> - <h4 id="x5.1.2-cdm-unavailable"><span class="secno">5.1.2 </span>CDM Unavailable</h4> - <p> - The CDM unavailable algorithm is run to close all <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> objects associated with a <a href="#dom-mediakeys" class="internalDFN" data-link-type="dfn"><code>MediaKeys</code></a> object, <var>media keys</var> when the CDM instance becomes unavailable. - </p> - <p>The following step is run:</p> - <ol> - <li> - <p>For each <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> created by the <var>media keys</var> that is not <a href="#media-key-session-closed">closed</a>, <a href="https://www.w3.org/TR/html51/webappapis.html#queuing">queue a task</a> to run the <a href="#session-closed">Session Closed</a> algorithm on the session.</p> - </li> - </ol> - </section> - </section> - <section id="media-keys-storage"> - <h3 id="x5.2-storage-and-persistence"><span class="secno">5.2 </span>Storage and Persistence</h3> - <p>This section describes general requirements related to storage and persistence.</p> - - <p> - If a <a href="#dom-mediakeys" class="internalDFN" data-link-type="dfn"><code>MediaKeys</code></a> object's <var>persistent state allowed</var> value is <code>false</code> then the object's <var>cdm instance</var> - <em class="rfc2119" title="SHALL NOT">SHALL NOT</em> persist state or access previously persisted state as a result of operations on this object or any sessions that it creates. - </p> + <section id="definitions"> + <!--OddPage--><h2 id="x2-definitions"><span class="secno">2. </span>Definitions</h2> + + <dl> + <dt id="cdm">Content Decryption Module (CDM)</dt> + <dd> + <p>Content Decryption Module (CDM) is the client component that provides the functionality, including decryption, for one or more <a href="#key-system">Key Systems</a>.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-0" aria-level="3"><span>Note</span></div><p class=""> + Implementations may or may not separate the implementations of CDMs or treat them as separate from the user agent. + This is transparent to the API and application. + </p></div> + </dd> + + <dt id="key-system">Key System</dt> + <dd> + <p>A Key System is a generic term for a decryption mechanism and/or content protection provider. + Key System strings provide unique identification of a Key System. + They are used by the user agent to select a <a href="#cdm">CDM</a> and identify the source of a key-related event. + User agents <em class="rfc2119" title="MUST">MUST</em> support the <a href="#common-key-systems">Common Key Systems</a>. + User agents <em class="rfc2119" title="MAY">MAY</em> also provide additional CDMs with corresponding Key System strings. + </p> + + <p>A Key System string is always a reverse domain name. + Key System strings are compared using case-sensitive matching. It is <em class="rfc2119" title="RECOMMENDED">RECOMMENDED</em> that CDMs use simple lower-case ASCII key system strings.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-1" aria-level="3"><span>Note</span></div><p class="">For example, "com.example.somesystem".</p></div> + + <div class="note"><div role="heading" class="note-title marker" id="h-note-2" aria-level="3"><span>Note</span></div><p class=""> + Within a given system ("somesystem" in the example), subsystems may be defined as determined by the key system provider. + For example, "com.example.somesystem.1" and "com.example.somesystem.1_5". + Key System providers should keep in mind that these will be used for comparison and discovery, so they should be easy to compare and the structure should remain reasonably simple. + </p></div> + </dd> + + <dt id="key-session">Key Session</dt> + <dd> + <p>A Key Session, or simply Session, provides a context for message exchange with the <a href="#cdm">CDM</a> as a result of which key(s) are made available to the CDM. + Sessions are embodied as <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> objects. + Each Key session is associated with a single instance of <a href="#initialization-data">Initialization Data</a> provided in the <code><a href="#dom-mediakeysession-generaterequest">generateRequest()</a></code> call. + </p> + <p>Each Key Session is associated with a single <a href="#dfn-mediakeys" class="internalDFN" data-link-type="dfn">MediaKeys</a> object, and only media element(s) associated with that <a href="#dfn-mediakeys" class="internalDFN" data-link-type="dfn">MediaKeys</a> object may access key(s) associated with the session. + Other <a href="#dfn-mediakeys" class="internalDFN" data-link-type="dfn">MediaKeys</a> objects, CDM instances, and media elements <em class="rfc2119" title="MUST NOT">MUST NOT</em> access the key session or use its key(s). + Key sessions and the keys they contain are no longer <a href="#usable-for-decryption">usable for decryption</a> once the session has been closed, including when the <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object is destroyed. + </p> + <p> + All license(s) and key(s) associated with a Key Session which have not been explicitly stored <em class="rfc2119" title="MUST">MUST</em> be destroyed when the Key Session is closed. + </p> + <p><a href="#decryption-key-id">Key IDs</a> <em class="rfc2119" title="MUST">MUST</em> be unique within a session.</p> + </dd> + + <dt id="session-id">Session ID</dt> + <dd> + <p>A Session ID is a unique string identifier generated by the <a href="#cdm">CDM</a> that can be used by the application to identify <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> objects.</p> + + <p>A new Session ID is generated each time the user agent and CDM successfully create a new session.</p> + + <p>Each Session ID <em class="rfc2119" title="SHALL">SHALL</em> be unique within the browsing context in which it was created. + For session types for which the <a href="#is-persistent-session-type">Is persistent session type?</a> algorithm returns <code>true</code>, Session IDs <em class="rfc2119" title="MUST">MUST</em> be unique within the <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> over time, including across browsing sessions. + </p> + + <div class="note"><div role="heading" class="note-title marker" id="h-note-3" aria-level="3"><span>Note</span></div><p class="">The underlying content protection protocol does not necessarily need to support Session IDs.</p></div> + </dd> + + <dt id="decryption-key">Key</dt> + <dd> + <p>Unless otherwise stated, key refers to a decryption key that can be used to decrypt blocks within <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a>. + Each such key is uniquely identified by a <a href="#decryption-key-id">key ID</a>. + A key is associated with the <a href="#key-session">session</a> used to provide it to the <a href="#cdm">CDM</a>. (The same key may be present in multiple sessions.) + Such keys <em class="rfc2119" title="MUST">MUST</em> only be provided to the CDM via an <code><a href="#dom-mediakeysession-update">update()</a></code> call. (They may later be loaded by <code><a href="#dom-mediakeysession-load">load()</a></code> as part of the stored session data.) + </p> + + <div class="note"><div role="heading" class="note-title marker" id="h-note-4" aria-level="3"><span>Note</span></div><p class="">Authors <em class="rfc2119" title="SHOULD">SHOULD</em> encrypt each set of stream(s) that requires enforcement of a meaningfully different policy with a distinct key (and key ID). + For example, if policies may differ between two video resolutions, stream(s) containing one resolution should not be encrypted with the key used to encrypt stream(s) containing the other resolution. + When encrypted, audio streams <em class="rfc2119" title="SHOULD NOT">SHOULD NOT</em> use the same key as any video stream. + This is the only way to ensure enforcement and compatibility across clients. + </p></div> + </dd> + + <dt id="usable-for-decryption">Usable For Decryption</dt> + <dd> + <p>A key is considered usable for decryption if the CDM is certain the key is currently usable to decrypt one or more blocks of <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a>.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-5" aria-level="3"><span>Note</span></div><p class="">For example, a key is not usable for decryption if its license has expired. Even if its license has not expired, a key is not usable for decryption if other conditions (e.g., output protection) for its use are not currently satisfied.</p></div> + </dd> + + <dt id="decryption-key-id">Key ID</dt> + <dd> + <p>A <a href="#decryption-key">key</a> is associated with a key ID that is a sequence of octets and which uniquely identifies the key. + The container specifies the ID of the key that can decrypt a block or set of blocks within the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a>. + <a href="#initialization-data">Initialization Data</a> <em class="rfc2119" title="MAY">MAY</em> contain key ID(s) to identify the keys that are needed to decrypt the media data. + However, there is no requirement that Initialization Data contain any or all key IDs used in the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a> or <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-resource">media resource</a>. + <a href="#license">Licenses</a> provided to the <a href="#cdm">CDM</a> associate each key with a key ID so the CDM can select the appropriate key when decrypting an encrypted block of media data. + </p> + </dd> + + <dt id="known-key">Known Key</dt> + <dd> + <p>A key is considered to be known to a session if the <a href="#cdm">CDM</a>'s implementation of the session contains any information - specifically the <a href="#decryption-key-id">key ID</a> - about it, regardless of whether the actual <a href="#decryption-key">key</a> is usable or its value is known. + Known keys are exposed via the <code><a href="#dom-mediakeysession-keystatuses">keyStatuses</a></code> attribute. + </p> + + <p>Keys are considered known even after they become unusable, such as due to <a href="#expiration-time">expiration</a> or if they are removed but a <a href="#record-of-license-destruction">record of license destruction</a> or <a href="#record-of-key-usage">record of key usage</a> is available. + Keys only become unknown when they are explicitly removed from a session and any license release message is acknowledged. + </p> + + <div class="note"><div role="heading" class="note-title marker" id="h-note-6" aria-level="3"><span>Note</span></div><p class="">For example, a key could become unknown if an <code><a href="#dom-mediakeysession-update">update()</a></code> call provides a new license that does not include the key and includes instructions to replace the license(s) that previously contained the key.</p></div> + </dd> + + <dt id="license">License</dt> + <dd> + <p>A license is key system-specific state information that includes one or more <a href="#decryption-key">key(s)</a> - each associated with a <a href="#decryption-key-id">key ID</a> - and potentially other information about key usage.</p> + </dd> + + <dt id="initialization-data">Initialization Data</dt> + <dd> + <div class="note"><div role="heading" class="note-title marker" id="h-note-7" aria-level="3"><span>Note</span></div><p class=""> + <a href="#key-system">Key Systems</a> usually require a block of initialization data containing information about the stream to be decrypted before they can construct a license request message. + This block could be a simple key or content ID or a more complex structure containing such information. + It <em class="rfc2119" title="SHOULD">SHOULD</em> always allow unique identification of the <a href="#decryption-key">key(s)</a> needed to decrypt the content. + This initialization information <em class="rfc2119" title="MAY">MAY</em> be obtained in some application-specific way or provided with the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a>. + </p></div> + + <p> + Initialization Data is a generic term for container-specific data that is used by a <a href="#cdm">CDM</a> to generate a license request. + </p> + + <p> + The format of the initialization data depends upon the type of container, and containers <em class="rfc2119" title="MAY">MAY</em> support more than one format + of initialization data. The <dfn id="initialization-data-type" data-dfn-type="dfn">Initialization Data Type</dfn> is a string that indicates the + format of the accompanying Initialization Data. Initialization Data Type strings are always matched case-sensitively. It is + <em class="rfc2119" title="RECOMMENDED">RECOMMENDED</em> that Initialization Data Type strings are lower-case ASCII strings. + </p> + + <p> + The Encrypted Media Extensions Stream Format and Initialization Data Format Registry [<cite><a class="bibref" href="#bib-EME-INITDATA-REGISTRY">EME-INITDATA-REGISTRY</a></cite>] + provides the mapping from <a href="#initialization-data-type">Initialization Data Type</a> string to the specification for each format. + </p> + + <p> + When the user agent encounters Initialization Data in the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a>, it provides that Initialization Data to the application in the <code><a href="#dom-mediaencryptedevent-initdata">initData</a></code> attribute of the <code><a href="#dom-evt-encrypted">encrypted</a></code> event. + The user agent <em class="rfc2119" title="MUST NOT">MUST NOT</em> store the Initialization Data or use its <em>content</em> at the time it is encountered. + The application provides Initialization Data to the CDM via <code><a href="#dom-mediakeysession-generaterequest">generateRequest()</a></code>. + The user agent <em class="rfc2119" title="MUST NOT">MUST NOT</em> provide Initialization Data to the CDM by other means. + </p> + + <p>Initialization Data <em class="rfc2119" title="MUST">MUST</em> be a fixed value for a given set of stream(s) or <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a>. + It <em class="rfc2119" title="MUST">MUST</em> only contain information related to the keys required to play a given set of stream(s) or <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a>. + It <em class="rfc2119" title="MUST NOT">MUST NOT</em> contain application data, client-specific data, user-specific data, or executable code. + </p> + + <p>Initialization Data <em class="rfc2119" title="SHOULD NOT">SHOULD NOT</em> contain Key System-specific data or values. + Implementations <em class="rfc2119" title="MUST">MUST</em> support the common formats defined in [<cite><a class="bibref" href="#bib-EME-INITDATA-REGISTRY">EME-INITDATA-REGISTRY</a></cite>] for each <a href="#initialization-data-type">Initialization Data Type</a> they support. + </p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-8" aria-level="3"><span>Note</span></div><p class=""> + Use of proprietary formats/contents is discouraged, and supporting or using <em>only</em> proprietary formats is strongly discouraged. + Proprietary formats should only be used with pre-existing content or on pre-existing client devices that do not support the common formats. + </p></div> + </dd> + + <dt>Associable Values</dt> + <dd> + <p> + Two or more identifiers or other values are said to be <dfn id="associable" data-dfn-type="dfn">associable</dfn> if they are identical <em>or</em> it is possible - with a reasonable amount of time and effort - to correlate or associate them. + Otherwise, the values are <dfn id="non-associable" data-dfn-type="dfn">non-associable</dfn>. + </p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-9" aria-level="3"><span>Note</span></div><div class=""> + <p>For example, values created in the following ways are <a href="#associable">associable</a>:</p> + <ul> + <li><p>Using a trivially-reversible hash function.</p></li> + <li><p>Sharing a prefix or other subset</p></li> + <li><p>Replacing random value N with N+10</p></li> + <li><p>XORing the origin with a fixed value (because it is trivially reversible)</p></li> + </ul> + <p>In contrast, two values that are completely unrelated or cryptographically distinct, such as via a cryptographically strong non-reversible hash function, are <a href="#non-associable">non-associable</a>.</p> + </div></div> + <p>Two or more identifiers or other values are said to be <dfn id="associable-by-entity" data-dfn-type="dfn">associable by an entity</dfn> if it is possible - with a reasonable amount of time and effort - for the referenced entity or set of entities to correlate or associate them without participation of additional entity(ies). + Otherwise, the values are <dfn id="non-associable-by-entity" data-dfn-type="dfn">non-associable by an entity</dfn>. + </p> + <p>Two or more identifiers or other values are said to be <dfn id="non-associable-by-application" data-dfn-type="dfn">non-associable by the application</dfn> if they are <a href="#non-associable-by-entity">non-associable by an entity</a> + where the entity is set that includes the application, all other applications, and other entities such as servers that they use or with which they communicate. + Otherwise, the values would be considered <dfn id="associable-by-application" data-dfn-type="dfn">associable by the application</dfn>, which is forbidden. + </p> + </dd> + + <dt id="distinctive-value">Distinctive Value</dt> + <dd> + <p> + A Distinctive Value is a value, piece of data, implication of the possession of a piece of data, or an observable behavior or timing that is <em>not</em> shared across a large population of users or client devices. + A Distinctive Value may be in memory or persisted. + </p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-10" aria-level="3"><span>Note</span></div><div class=""> + <p>Examples of Distinctive Values include but are not limited to:</p> + <ul> + <li><p><a href="#distinctive-identifier">Distinctive Identifiers</a></p></li> + <li><p><a href="#distinctive-permanent-identifier">Distinctive Permanent Identifiers</a></p></li> + <li><p>Other identifiers</p></li> + <li><p><a href="#session-id">Session IDs</a></p></li> + <li><p><a href="#license">Licenses</a></p></li> + <li><p>Other session data</p></li> + </ul> + </div></div> + <div class="note"><div role="heading" class="note-title marker" id="h-note-11" aria-level="3"><span>Note</span></div><p class="">While a Distinctive Value is typically unique to a user or client device, a value does not need to be strictly unique to be distinctive. + For example, a value shared among a small number of users could still be distinctive. + </p></div> + </dd> + + <dt>Permanent Identifiers</dt> + <dd> + <p> + A <dfn id="permanent-identifier" data-dfn-type="dfn">Permanent Identifier</dfn> is a value, piece of data, implication of the possession of a piece of data, or an observable behavior or timing that is indelible in some way or otherwise non-trivial for the user to remove, reset, or change. + This, includes but is not limited to: + </p> + <ul> + <li><p>A hardware or hardware-based identifier</p></li> + <li><p>A value provisioned in the hardware device in the factory</p></li> + <li><p>A value associated with or derived from the operating system installation instance</p></li> + <li><p>A value associated with or derived from the user agent installation instance</p></li> + <li><p>A value associated with or derived from the <a href="#cdm">CDM</a> or other software component</p></li> + <li><p>A value in a configuration file or similar semi-permanent data, even if generated on the client</p></li> + <li><p>Client or other user account values</p></li> + </ul> + + <p> + A <dfn id="distinctive-permanent-identifier" data-dfn-type="dfn">Distinctive Permanent Identifier</dfn> is a <a href="#permanent-identifier">Permanent Identifier</a> that is <a href="#distinctive-value">distinctive</a>. + </p> + <p> + When exposed outside the client, Distinctive Permanent Identifiers and values derived from or otherwise related to them <em class="rfc2119" title="MUST">MUST</em> be <a href="#encrypt-identifiers">encrypted</a>. + Distinctive Permanent Identifiers <em class="rfc2119" title="MUST NOT">MUST NOT</em> ever be exposed to the application, even in encrypted form. + </p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-12" aria-level="3"><span>Note</span></div><p class="">While a Distinctive Permanent Identifier is typically unique to a user or client device, a Distinctive Permanent Identifier does not need to be strictly unique to be distinctive. + For example, a Distinctive Permanent Identifier shared among a small number of users could still be distinctive. + </p></div> + <div class="note"><div role="heading" class="note-title marker" id="h-note-13" aria-level="3"><span>Note</span></div><p class=""> + A Distinctive Permanent Identifier is <em>not</em> a <a href="#distinctive-identifier">Distinctive Identifier</a> because it is not derived or generated (within the scope of this specification). + </p></div> + <div class="note"><div role="heading" class="note-title marker" id="h-note-14" aria-level="3"><span>Note</span></div><p class=""> + <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> controls whether Distinctive Permanent Identifiers may be used. + Specifically, Distinctive Permanent Identifiers may only be used when the value of the <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> member of the <a href="#dom-mediakeysystemaccess" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemAccess</code></a> used to create the <a href="#dfn-mediakeys" class="internalDFN" data-link-type="dfn">MediaKeys</a> object is <code><a href="#idl-def-MediaKeysRequirement.required">"required"</a></code>. + </p></div> + </dd> + + <dt id="distinctive-identifier">Distinctive Identifier</dt> + <dd> + <div class="note"><div role="heading" class="note-title marker" id="h-note-15" aria-level="3"><span>Note</span></div><div class=""> <p> - If a <a href="#dom-mediakeys" class="internalDFN" data-link-type="dfn"><code>MediaKeys</code></a> object's <var>persistent state allowed</var> value is <code>true</code> then the object's <var>cdm instance</var> - <em class="rfc2119" title="MAY">MAY</em> persist state or access previously persisted state as a result of operations on this object or any sessions that it creates. - </p> - - <p>Persisted data <em class="rfc2119" title="MUST">MUST</em> always be stored such that only the <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> of this object's <a href="https://www.w3.org/TR/dom/#concept-document">Document</a> can access it. In addition, the data <em class="rfc2119" title="MUST">MUST</em> only be accessible by the current <a href="#browsing-profile">browsing profile</a>; other browsing profiles, user agents, and applications <em class="rfc2119" - title="MUST NOT">MUST NOT</em> be able to access the stored data. See <a href="#privacy-storedinfo">Information Stored on User Devices</a>. - </p> - - <p>See <a href="#security" class="sec-ref"><span class="secno">10.</span> <span class="sec-title">Security</span></a> and <a href="#privacy" class="sec-ref"><span class="secno">11.</span> <span class="sec-title">Privacy</span></a> for additional - considerations when supporting persistent storage.</p> - - </section> - </section> - - - <section id="mediakeysession-interface"> - <!--OddPage--> - <h2 id="x6.-mediakeysession-interface"><span class="secno">6. </span><dfn data-dfn-for="" data-dfn-type="dfn" id="dom-mediakeysession" data-idl="" data-title="MediaKeySession"><code>MediaKeySession</code></dfn> Interface</h2> - <p>The MediaKeySession object represents a <a href="#key-session">key session</a>.</p> - <p> - A <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object is <dfn id="media-key-session-closed" data-dfn-type="dfn">closed</dfn> if and only if the object's <code><a href="#dom-mediakeysession-closed">closed</a></code> attribute has been resolved. - </p> - <p> - The User Agent <em class="rfc2119" title="SHALL">SHALL</em> execute the <a href="#monitor-cdm">Monitor for CDM Changes</a> algorithm continuously for each <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object that is not <a href="#media-key-session-closed">closed</a>. The <a href="#monitor-cdm">Monitor for CDM Changes</a> algorithm <em class="rfc2119" title="MUST">MUST</em> be run in parallel to the main event loop but not in parallel to - other procedures defined in this specification that are also defined to be run in parallel. - </p> - <p> - A <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object <em class="rfc2119" title="SHALL NOT">SHALL NOT</em> be destroyed and <em class="rfc2119" title="SHALL">SHALL</em> continue to - receive events if it is not <a href="#media-key-session-closed">closed</a> and the <a href="#dom-mediakeys" class="internalDFN" data-link-type="dfn"><code>MediaKeys</code></a> object that created it remains accessible. Otherwise, a <a href="#dom-mediakeysession" - class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object that is no longer accessible <em class="rfc2119" title="SHALL NOT">SHALL NOT</em> receive further events and <em class="rfc2119" title="MAY">MAY</em> be destroyed. - </p> - <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note60"><span>Note</span></div> - <p class=""> - The above rule implies that the CDM instance must not be destroyed until all <a href="#dom-mediakeys" class="internalDFN" data-link-type="dfn"><code>MediaKeys</code></a> objects and all <a href="#dom-mediakeysession" class="internalDFN" - data-link-type="dfn"><code>MediaKeySession</code></a> objects associated with the CDM instance are destroyed. + A Distinctive Identifier is a value, including in opaque or encrypted form, for which it is possible for any entity external to the client to correlate or associate values beyond what a user may expect on the web platform (e.g., cookies and other site data). + For example, values that are <a href="#associable-by-entity">associable by an entity other than the application</a> across + a) <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origins</a>, + b) <a href="#browsing-profile">browsing profiles</a>, + or c) browsing sessions even after the user has attempted to protect his or her privacy by clearing browsing data + or values for which it is not easy for a user to break such association. + In particular, a value is a Distinctive Identifier if it is possible for a <a href="#associable-by-entity">central server, such as an individualization server, to associate</a> values across origins, such as because the <a href="#individualization">individualization</a> requests contained a common value, or because values provided in individualization requests are <a href="#associable-by-entity">associable by such server</a> even after attempts to clear browsing data. + Possible causes of this include use of <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifier(s)</a> in the individualization process. </p> - </div> - <p> - If a <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object is not <a href="#media-key-session-closed">closed</a> when it becomes inaccessible to the page, the CDM <em class="rfc2119" - title="SHALL">SHALL</em> close the <a href="#key-session">key session</a> associated with the object. - </p> - <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note61"><span>Note</span></div> - <p class="">Closing the key session results in the destruction of any license(s) and key(s) that have not been explicitly stored.</p> - </div> - <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note62"><span>Note</span></div> - <p class=""> - Exactly when the key session is closed is an implementation detail, and applications <em class="rfc2119" title="SHOULD NOT">SHOULD NOT</em> rely on specific timing. - <!-- TODO: Replace and/or expand on this with an implementation of Issue #360. --> - Applications that want to ensure a session is closed before taking some other action <em class="rfc2119" title="SHOULD">SHOULD</em> call <code><a href="#dom-mediakeysession-close">close()</a></code> and wait for the returned promise to - be resolved. + <p> + Distinctive Identifiers exposed to the application, even in encrypted form, <em class="rfc2119" title="MUST">MUST</em> adhere to the <a href="#identifier-requirements">identifier requirements</a>, + including being <a href="#encrypt-identifiers">encrypted</a>, <a href="#per-origin-per-profile-identifiers">unique per origin and profile</a>, and <a href="#allow-identifiers-cleared">clearable</a>. </p> - </div> - <p> - If a <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object becomes inaccessible to the page and is not <a href="#media-key-session-closed">closed</a>, the User Agent - <em class="rfc2119" title="MUST">MUST</em> run the <a href="#media-key-session-destroyed">MediaKeySession destroyed</a> algorithm before User Agent state associated with the <a href="#key-session">session</a> is deleted. - </p> - <p>For methods that return a promise, all errors are reported asynchronously by rejecting the returned Promise. This includes [<cite><a class="bibref" href="#bib-WEBIDL">WEBIDL</a></cite>] type mapping errors.</p> - <p>The following steps of an algorithm are always aborted when rejecting a promise.</p> - - <div> - <div> - <pre class="def idl"><span class="idlInterface" id="idl-def-mediakeysession" data-idl="" data-title="MediaKeySession">[<span class="extAttr"><span class="extAttrName"><a href="https://heycam.github.io/webidl/#SecureContext">SecureContext</a></span></span>] -interface <span class="idlInterfaceID"><a data-lt="MediaKeySession" href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn" data-for=""><code>MediaKeySession</code></a></span> : <span class="idlSuperclass">EventTarget</span> { -<span class="idlAttribute" id="idl-def-mediakeysession-sessionid" data-idl="" data-title="sessionId" data-dfn-for="mediakeysession"> readonly attribute <span class="idlAttrType"><a href="https://heycam.github.io/webidl/#idl-DOMString">DOMString</a></span> <span class="idlAttrName"><a data-lt="sessionId" href="#dom-mediakeysession-sessionid" class="internalDFN" data-link-type="dfn" data-for="MediaKeySession"><code>sessionId</code></a></span>;</span> -<span class="idlAttribute" id="idl-def-mediakeysession-expiration" data-idl="" data-title="expiration" data-dfn-for="mediakeysession"> readonly attribute <span class="idlAttrType"><a href="https://heycam.github.io/webidl/#idl-unrestricted-double">unrestricted double</a></span> <span class="idlAttrName"><a data-lt="expiration" href="#dom-mediakeysession-expiration" class="internalDFN" data-link-type="dfn" data-for="MediaKeySession"><code>expiration</code></a></span>;</span> -<span class="idlAttribute" id="idl-def-mediakeysession-closed" data-idl="" data-title="closed" data-dfn-for="mediakeysession"> readonly attribute <span class="idlAttrType"><a href="https://heycam.github.io/webidl/#idl-promise">Promise</a><void></span> <span class="idlAttrName"><a data-lt="closed" href="#dom-mediakeysession-closed" class="internalDFN" data-link-type="dfn" data-for="MediaKeySession"><code>closed</code></a></span>;</span> -<span class="idlAttribute" id="idl-def-mediakeysession-keystatuses" data-idl="" data-title="keyStatuses" data-dfn-for="mediakeysession"> readonly attribute <span class="idlAttrType"><a href="#dom-mediakeystatusmap" class="internalDFN" data-link-type="dfn"><code>MediaKeyStatusMap</code></a></span> <span class="idlAttrName"><a data-lt="keyStatuses" href="#dom-mediakeysession-keystatuses" class="internalDFN" data-link-type="dfn" data-for="MediaKeySession"><code>keyStatuses</code></a></span>;</span> -<span class="idlAttribute" id="idl-def-mediakeysession-onkeystatuseschange" data-idl="" data-title="onkeystatuseschange" data-dfn-for="mediakeysession"> attribute <span class="idlAttrType"><a href="https://html.spec.whatwg.org/multipage/#eventhandler">EventHandler</a></span> <span class="idlAttrName"><a data-lt="onkeystatuseschange" href="#dom-mediakeysession-onkeystatuseschange" class="internalDFN" data-link-type="dfn" data-for="MediaKeySession"><code>onkeystatuseschange</code></a></span>;</span> -<span class="idlAttribute" id="idl-def-mediakeysession-onmessage" data-idl="" data-title="onmessage" data-dfn-for="mediakeysession"> attribute <span class="idlAttrType"><a href="https://html.spec.whatwg.org/multipage/#eventhandler">EventHandler</a></span> <span class="idlAttrName"><a data-lt="onmessage" href="#dom-mediakeysession-onmessage" class="internalDFN" data-link-type="dfn" data-for="MediaKeySession"><code>onmessage</code></a></span>;</span> -<span class="idlMethod" id="idl-def-mediakeysession-generaterequest(initdatatype,initdata)" data-idl="" data-title="generateRequest" data-dfn-for="mediakeysession"> <span class="idlMethType"><a href="https://heycam.github.io/webidl/#idl-promise">Promise</a><void></span> <span class="idlMethName"><a data-lt="generateRequest" href="#dom-mediakeysession-generaterequest" class="internalDFN" data-link-type="dfn" data-for="MediaKeySession"><code>generateRequest</code></a></span>(<span class="idlParam"><span class="idlParamType"><a href="https://heycam.github.io/webidl/#idl-DOMString">DOMString</a></span> <span class="idlParamName">initDataType</span></span>, - <span class="idlParam"><span class="idlParamType">BufferSource</span> <span class="idlParamName">initData</span></span>);</span> -<span class="idlMethod" id="idl-def-mediakeysession-load(sessionid)" data-idl="" data-title="load" data-dfn-for="mediakeysession"> <span class="idlMethType"><a href="https://heycam.github.io/webidl/#idl-promise">Promise</a><<a href="https://heycam.github.io/webidl/#idl-boolean">boolean</a>></span> <span class="idlMethName"><a data-lt="load" href="#dom-mediakeysession-load" class="internalDFN" data-link-type="dfn" data-for="MediaKeySession"><code>load</code></a></span>(<span class="idlParam"><span class="idlParamType"><a href="https://heycam.github.io/webidl/#idl-DOMString">DOMString</a></span> <span class="idlParamName">sessionId</span></span>);</span> -<span class="idlMethod" id="idl-def-mediakeysession-update(response)" data-idl="" data-title="update" data-dfn-for="mediakeysession"> <span class="idlMethType"><a href="https://heycam.github.io/webidl/#idl-promise">Promise</a><void></span> <span class="idlMethName"><a data-lt="update" href="#dom-mediakeysession-update" class="internalDFN" data-link-type="dfn" data-for="MediaKeySession"><code>update</code></a></span>(<span class="idlParam"><span class="idlParamType">BufferSource</span> <span class="idlParamName">response</span></span>);</span> -<span class="idlMethod" id="idl-def-mediakeysession-close()" data-idl="" data-title="close" data-dfn-for="mediakeysession"> <span class="idlMethType"><a href="https://heycam.github.io/webidl/#idl-promise">Promise</a><void></span> <span class="idlMethName"><a data-lt="close" href="#dom-mediakeysession-close" class="internalDFN" data-link-type="dfn" data-for="MediaKeySession"><code>close</code></a></span>();</span> -<span class="idlMethod" id="idl-def-mediakeysession-remove()" data-idl="" data-title="remove" data-dfn-for="mediakeysession"> <span class="idlMethType"><a href="https://heycam.github.io/webidl/#idl-promise">Promise</a><void></span> <span class="idlMethName"><a data-lt="remove" href="#dom-mediakeysession-remove" class="internalDFN" data-link-type="dfn" data-for="MediaKeySession"><code>remove</code></a></span>();</span> -};</span></pre> - </div> - <section> - <h3 id="attributes-0">Attributes</h3> - <dl class="attributes" data-dfn-for="MediaKeySession" data-link-for="MediaKeySession"><dt><dfn data-dfn-for="mediakeysession" data-dfn-type="dfn" id="dom-mediakeysession-sessionid" data-idl="" data-title="sessionId"><code>sessionId</code></dfn> of type <span class="idlAttrType">DOMString</span>, readonly </dt> - <dd> - <p>The <a href="#session-id">Session ID</a> for this object and the associated key(s) or license(s).</p> - </dd><dt><dfn data-dfn-for="mediakeysession" data-dfn-type="dfn" id="dom-mediakeysession-expiration" data-idl="" data-title="expiration"><code>expiration</code></dfn> of type <span class="idlAttrType">unrestricted double</span>, readonly </dt> - <dd> - <p>The <a href="#expiration-time">expiration time</a> for all key(s) in the session, or <code>NaN</code> if no such time exists or if the license explicitly never expires, as determined by the CDM.</p> - <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note63"><span>Note</span></div> - <p class="">This value <em class="rfc2119" title="MAY">MAY</em> change during the session lifetime, such as when an action triggers the start of a window.</p> - </div> - </dd><dt><dfn data-dfn-for="mediakeysession" data-dfn-type="dfn" id="dom-mediakeysession-closed" data-idl="" data-title="closed"><code>closed</code></dfn> of type <span class="idlAttrType">Promise<void></span>, readonly </dt> - <dd> - <p>Signals when the object becomes <a href="#media-key-session-closed">closed</a> as a result of the <a href="#session-closed">Session Closed</a> algorithm being run. This promise can only be fulfilled and is never rejected.</p> - </dd><dt><dfn data-dfn-for="mediakeysession" data-dfn-type="dfn" id="dom-mediakeysession-keystatuses" data-idl="" data-title="keyStatuses"><code>keyStatuses</code></dfn> of type <span class="idlAttrType"><a href="#dom-mediakeystatusmap" class="internalDFN" data-link-type="dfn"><code>MediaKeyStatusMap</code></a></span>, readonly </dt> - <dd> - <p>A reference to a read-only map of <a href="#decryption-key-id">key IDs</a> <a href="#known-key">known</a> to the session to the current status of the associated key. Each entry <em class="rfc2119" title="MUST">MUST</em> have a - unique key ID. - </p> - <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note64"><span>Note</span></div> - <p class="">The map entries and their values may be updated whenever the event loop spins. The map <em class="rfc2119" title="MUST NOT">MUST NOT</em> ever be inconsistent or partially updated, but it may change between accesses if the - event loop spins in between the accesses. Key IDs may be added as the result of a <code><a href="#dom-mediakeysession-load">load()</a></code> or <code><a href="#dom-mediakeysession-update">update()</a></code> call. Key - IDs may be removed as the result of a <code><a href="#dom-mediakeysession-update">update()</a></code> call that removes knowledge of existing keys (or replaces the existing set of keys with a new set). Key IDs <em class="rfc2119" - title="MUST NOT">MUST NOT</em> be removed because they became unusable, such as due to expiration. Instead, such keys <em class="rfc2119" title="MUST">MUST</em> be given an appropriate status, such as <code><a href="#idl-def-MediaKeyStatus.expired">"expired"</a></code>. - </p> - </div> - <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note65"><span>Note</span></div> - <p class=""> - Some older platforms may contain Key System implementations that do not expose key IDs, making it impossible to provide a compliant user agent implementation. To maximize interoperability, user agent implementations exposing such CDMs - <em - class="rfc2119" title="SHOULD">SHOULD</em> implement this member as follows: Whenever a non-empty list is appropriate, such as when the <a href="#key-session">key session</a> represented by this object may contain <a href="#decryption-key">key(s)</a>, - populate the map with a single pair containing the one-byte key ID <code>0</code> and the <a href="#dom-mediakeystatus" class="internalDFN" data-link-type="dfn"><code>MediaKeyStatus</code></a> most appropriate for the - aggregated status of this object. - </p> - </div> - </dd><dt><dfn data-dfn-for="mediakeysession" data-dfn-type="dfn" id="dom-mediakeysession-onkeystatuseschange" data-idl="" data-title="onkeystatuseschange"><code>onkeystatuseschange</code></dfn> of type <span class="idlAttrType">EventHandler</span></dt> - <dd> - <p>Event handler for the <code><a href="#dom-evt-keystatuseschange">keystatuseschange</a></code> event.</p> - </dd><dt><dfn data-dfn-for="mediakeysession" data-dfn-type="dfn" id="dom-mediakeysession-onmessage" data-idl="" data-title="onmessage"><code>onmessage</code></dfn> of type <span class="idlAttrType">EventHandler</span></dt> - <dd> - <p>Event handler for the <code><a href="#dom-evt-message">message</a></code> event.</p> - </dd> - </dl> - </section> - <section> - <h3 id="methods-2">Methods</h3> - <dl class="methods" data-dfn-for="MediaKeySession" data-link-for="MediaKeySession"><dt><dfn data-dfn-for="mediakeysession" data-dfn-type="dfn" id="dom-mediakeysession-generaterequest" data-idl="" data-title="generateRequest" data-lt="generaterequest()|generateRequest"><code id="generateRequest">generateRequest</code></dfn></dt> - <dd> - <p>Generates a license request based on the <var>initData</var>. A <code><a href="#dom-evt-message">message</a></code> of type <code><a href="#idl-def-MediaKeyMessageType.license-request">"license-request"</a></code> or <code><a href="#idl-def-MediaKeyMessageType.individualization-request">"individualization-request"</a></code> will always be queued if the algorithm succeeds and the promise is resolved. - </p> + <p> + While the instantiation or use of a Distinctive Identifier is triggered by the application's use of the APIs defined in this specification, the identifier need not be provided to the application to trigger conditions related to Distinctive Identifiers. + (The <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifier(s)</a> <em class="rfc2119" title="MUST NOT">MUST NOT</em> ever be provided to the application, even in opaque or encrypted form.) + </p> + </div></div> + <div class="note"><div role="heading" class="note-title marker" id="h-note-16" aria-level="3"><span>Note</span></div><p class=""> + <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> controls whether Distinctive Identifiers may be used. + Specifically, Distinctive Identifiers may only be used when the value of the <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> member of the <a href="#dom-mediakeysystemaccess" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemAccess</code></a> used to create the <a href="#dfn-mediakeys" class="internalDFN" data-link-type="dfn">MediaKeys</a> object is <code><a href="#idl-def-MediaKeysRequirement.required">"required"</a></code>. + </p></div> + <p>A Distinctive Identifier is a value, piece of data, implication of the possession of a piece of data, or an observable behavior or timing for which all of the following criteria hold:</p> + <ul> + <li> + <p>It is <a href="#distinctive-value">distinctive</a>.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-17" aria-level="3"><span>Note</span></div><p class="">While a Distinctive Identifier is typically unique to a user or client device, an identifier does not need to be strictly unique to be distinctive. + For example, an identifier shared among a small number of users could still be distinctive. + </p></div> + </li> + <li> + <p>It, information about it, or values derived from or otherwise related to it are exposed, even in encrypted form, outside the client. + This includes but is not limited to providing it to the application and/or license, <a href="#individualization">individualization</a>, or other server. + </p> + </li> + <li><p>It has one or more the following properties:</p> + <ul> + <li><p>It is derived from one or more <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifier(s)</a>.</p></li> + <li><p>The generation, <a href="#individualization">individualization</a>, provisioning or other process that produced the value involved, used, provided, derived from, or similarly involved one or more <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifier(s)</a> or another Distinctive Identifier.</p></li> + <li> + <p>It is <a href="#allow-identifiers-cleared">clearable</a> but not <a href="#allow-persistent-data-cleared-with-cookies">along with cookies and other site data</a>.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-18" aria-level="3"><span>Note</span></div><p class="">For example, via some mechanism external to the user agent, such as an OS-level mechanism.</p></div> + </li> + </ul> + <div class="note"><div role="heading" class="note-title marker" id="h-note-19" aria-level="3"><span>Note</span></div><div class=""> + <p>Other properties of concern that are normatively prohibited for values exposed to the application include:</p> + <ul> + <li><p>It is a <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifier</a>.</p></li> + <li><p>It is <em>not</em> <a href="#allow-identifiers-cleared">clearable</a>.</p></li> + <li><p>Value(s) created after <a href="#allow-identifiers-cleared">clearing identifier(s)</a> may be <a href="#associable-by-application">associable by the application</a> with previous value(s).</p></li> + <li><p>Values may not be <a href="#per-origin-per-profile-identifiers">unique per origin and profile</a>.</p></li> + <li><p>Values for different origins may be <a href="#associable-by-application">associable by the application</a>.</p></li> + </ul> + <p>Examples of such normatively prohibited values include but is not limited to:</p> + <ul> + <li><p>A single hardware-based value used for all origins.</p></li> + <li><p>A single random based value used for all origins.</p></li> + <li><p>A single value obtained from an <a href="#individualization">individualization</a> process that is used for all origins.</p></li> + <li><p>Values that include all or part of any of the above values.</p></li> + <li><p>A single value that is used for multiple but not all origins.</p></li> + <li><p>A single value that is used for all origins on a domain. (Identifiers must be per-<a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a>.)</p></li> + <li><p>A pre-provisioned origin-specific value.</p></li> + <li><p>Values generated by trivially-reversible means, which are thus <a href="#associable-by-application">associable by the application</a>, regardless of whether generated on the client or involving an a <a href="#individualization">individualization</a> process. For example, XORing or otherwise integrating (part of) the origin with a fixed value.</p></li> + </ul> + </div></div> + </li> + </ul> + <div class="note"><div role="heading" class="note-title marker" id="h-note-20" aria-level="3"><span>Note</span></div><p class=""> + While Distinctive Identifier are usually <a href="#associable-by-entity">associable by the entity that generated them</a> they <em class="rfc2119" title="MUST">MUST</em> be <a href="#non-associable-by-application">non-associable by applications</a>. + In other words, such correlation or association is only possible by the entity, such as an <a href="#individualization">individualization</a> server, that originally generated the Distinctive Identifier values. + Entities with access to the <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifier(s)</a> <em class="rfc2119" title="MUST NOT">MUST NOT</em> expose this capability to applications, as this would make resulting Distinctive Identifiers <a href="#associable-by-application">associable by the application</a>, and <em class="rfc2119" title="SHOULD">SHOULD</em> take care to avoid exposing such correlation to other entities or third parties. + </p></div> + <div class="note"><div role="heading" class="note-title marker" id="h-note-21" aria-level="3"><span>Note</span></div><div class=""> + <p>Examples of Distinctive Identifiers include but are not limited to:</p> + <ul> + <li><p>A series of bytes that is included in key requests, different from the series of bytes included by other client devices, and based on or was acquired directly or indirectly using a <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifier</a>.</p></li> + <li><p>A public key included in key requests that is different from the public keys included in the requests by other client devices and is based on or was acquired directly or indirectly using a <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifier</a>.</p></li> + <li><p>Demonstration of possession of a private key (e.g., by signing some data) that other client devices do not have and is based on or was acquired directly or indirectly using a <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifier</a>.</p></li> + <li><p>An identifier for such a key.</p></li> + <li><p>Such a value used to derive another value that is exposed even though the first value is not directly exposed.</p></li> + <li><p>A value derived from another Distinctive Identifier.</p></li> + <li><p>A random value that was reported to a (e.g., <a href="#individualization">individualization</a>) server along with a <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifier</a> or provided by such a server after providing a <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifier</a>.</p></li> + <li><p>A value derived from a unique value provisioned in the hardware device in the factory.</p></li> + <li><p>A value derived from a unique hardware value (e.g., MAC address or serial number) or software value (e.g., operating system installation instance or operating system user account name) in the hardware device in the factory.</p></li> + <li><p>A value derived from a unique value embedded in the CDM binary or other file used by the CDM.</p></li> + </ul> + <p>Examples of things that are <em>not</em> Distinctive Identifiers:</p> + <ul> + <li><p>A public key shared among all copies of a given CDM version if the installed base is large.</p></li> + <li><p>A nonce or ephemeral key that is unique but used in only one session.</p></li> + <li><p>A value that is not exposed, even in derived or similar ways, outside the client, including via <a href="#individualization">individualization</a> or similar.</p></li> + <li><p>Device-unique keys used in attestations between, for example, the video pipeline and the CDM when the CDM does not let these attestations further flow to the application and instead makes a new attestation on its own using a key that does not constitute a Distinctive Identifier.</p></li> + <li> + <p>A value that is fully cleared/clearable along with browsing data, such as cookies, after which it will be replaced by a value that is <a href="#non-associable">non-associable</a> (not just <a href="#non-associable-by-application">non-associable by applications</a>), even by a central server such as an <a href="#individualization">individualization</a> server, AND one or more of the following:</p> + <ul> + <li><p>No <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifier</a> or Distinctive Identifier was involved in the generation of the value.</p></li> + <li><p>It is a random value generated <em>without</em> inputs from the system.</p></li> + <li><p>It is a value provided by a server without the use of or knowledge of another Distinctive Identifier.</p></li> + </ul> + </li> + </ul> + </div></div> + </dd> + + <dt>Use of Distinctive Identifiers and Distinctive Permanent Identifiers</dt> + <dd> + <p> + An implementation, configuration, instance, or object <dfn id="uses-distinctive-identifiers" data-dfn-type="dfn">uses Distinctive Identifier(s)</dfn> if, at any time during its lifetime or the lifetime of related such entities, + it exposes, even in encrypted form, one or more <a href="#distinctive-identifier">Distinctive Identifier(s)</a>, information about them, or values derived from or otherwise related to them outside the client. + This includes but is not limited to providing such a value to the application and/or license, <a href="#individualization">individualization</a>, or other server. + </p> + <p> + An implementation, configuration, instance, or object <dfn id="uses-distinctive-permanent-identifiers" data-dfn-type="dfn">uses Distinctive Permanent Identifier(s)</dfn> if, at any time during its lifetime or the lifetime of related such entities, + it exposes, even in encrypted form, one or more <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifier(s)</a>, information about them, or values derived from or otherwise related to them outside the client. + This includes but is not limited to providing such a value to an <a href="#individualization">individualization</a> server. + Such values <em class="rfc2119" title="MUST NOT">MUST NOT</em> be provided to the application. + </p> + <p> + An implementation, configuration, instance, or object <dfn id="uses-distinctive-identifiers-or-distinctive-permanent-identifiers" data-dfn-type="dfn">uses Distinctive Identifier(s) or Distinctive Permanent Identifier(s)</dfn> if it + <a href="#uses-distinctive-identifiers">uses Distinctive Identifier(s)</a> and/or <a href="#uses-distinctive-permanent-identifiers">uses Distinctive Permanent Identifier(s)</a>. + </p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-22" aria-level="3"><span>Note</span></div><p class=""> + <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> controls whether <a href="#distinctive-identifier">Distinctive Identifiers</a> and <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifiers</a> may be used. + Specifically, such identifiers may only be used when the value of the <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> member of the <a href="#dom-mediakeysystemaccess" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemAccess</code></a> used to create the <a href="#dfn-mediakeys" class="internalDFN" data-link-type="dfn">MediaKeys</a> object is <code><a href="#idl-def-MediaKeysRequirement.required">"required"</a></code>. + </p></div> + </dd> + + <dt id="cross-origin">Cross Origin Limitations</dt> + <dd> + <p>During playback, embedded media data is exposed to script in the embedding <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a>. + In order for the API to provide <a href="#initialization-data">Initialization Data</a> in the <code><a href="#dom-evt-encrypted">encrypted</a></code> event, <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a> <em class="rfc2119" title="MUST">MUST</em> be <a href="https://www.w3.org/TR/html51/browsers.html#same-origin">CORS-same-origin</a> with the embedding page. + If <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a> is cross-origin with the embedding document, authors <em class="rfc2119" title="SHOULD">SHOULD</em> use the <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#element-attrdef-media-crossorigin">crossorigin</a></code> attribute + on the <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#htmlmediaelement-htmlmediaelement">HTMLMediaElement</a></code> and CORS headers on the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a> response to make it <a href="https://www.w3.org/TR/html51/browsers.html#same-origin">CORS-same-origin</a>. + </p> + </dd> + + <dt id="mixed-content">Mixed Content Limitations</dt> + <dd> + <p>During playback, embedded media data is exposed to script in the embedding <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a>. + In order for the API to provide <a href="#initialization-data">Initialization Data</a> in the <code><a href="#dom-evt-encrypted">encrypted</a></code> event, <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a> <em class="rfc2119" title="MUST NOT">MUST NOT</em> be Mixed Content [<cite><a class="bibref" href="#bib-MIXED-CONTENT">MIXED-CONTENT</a></cite>]. + </p> + </dd> + + <dt id="time">Time</dt> + <dd> + <p>Time <em class="rfc2119" title="MUST">MUST</em> be equivalent to that represented in <a class="external" href="https://tc39.github.io/ecma262/#sec-time-values-and-time-range">ECMAScript <span class="estype">Time Values and Time Range</span></a> [<cite><a class="bibref" href="#bib-ECMA-262">ECMA-262</a></cite>]. + </p> + <p>Time will equal <code>NaN</code> if no such time exists or if the time is indeterminate. It should never have the value <code>Infinity</code>. + </p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-23" aria-level="3"><span>Note</span></div><p class=""> + Time generally represents an instant in time with millisecond accuracy; however, that alone is not a sufficient definition. The defined Time Values and Time Range reference adds other important requirements. + </p></div> + </dd> + + <dt id="expiration-time">Expiration Time</dt> + <dd> + <p> + The <a href="#time">time</a> after which key(s) will no longer be <a href="#usable-for-decryption">usable for decryption</a>. + </p> + </dd> + + <dt id="browsing-profile">Browsing Profile</dt> + <dd> + <p> + A User Agent on a given machine may support execution in a variety of different contexts or modes or temporary states that are expected to behave independently + with respect to application-visible state and data. + In particular, all stored data is expected to be independent. In this specification we refer to such independent contexts or modes as "Browsing Profiles". + </p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-24" aria-level="3"><span>Note</span></div><p class=""> + Examples of such independent contexts include if the user agent is running in different operating system user accounts or if the user agent provides the capability to define + multiple independent profiles for a single account. + </p></div> + </dd> + <dt id="valid-media-mime-type">Valid Media MIME Type</dt> + <dd> + <p> + A valid media MIME type is a media <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#mime-types">MIME type</a> that is also a <a href="https://www.w3.org/TR/html51/infrastructure.html#valid-mime-type">valid MIME type</a> [<cite><a class="bibref" href="#bib-HTML51">HTML51</a></cite>]. + When a MIME type includes parameters, such as `"codecs"` [<cite><a class="bibref" href="#bib-RFC6381">RFC6381</a></cite>], such parameters <em class="rfc2119" title="MUST">MUST</em> also be valid per the relevant specification. + </p> + <p> + When used with the features defined in this specification, MIME type strings <em class="rfc2119" title="SHOULD">SHOULD</em> explicitly specify codecs and codec constraints (e.g., per [<cite><a class="bibref" href="#bib-RFC6381">RFC6381</a></cite>]) unless these are normatively implied by the container. + </p> + </dd> + </dl> + </section> - <table class="parameters"> - <tbody> - <tr> - <th>Parameter</th> - <th>Type</th> - <th>Nullable</th> - <th>Optional</th> - <th>Description</th> - </tr> - <tr> - <td class="prmName">initDataType</td> - <td class="prmType"><code>DOMString</code></td> - <td class="prmNullFalse"><span role="img" aria-label="False">✘</span></td> - <td class="prmOptFalse"><span role="img" aria-label="False">✘</span></td> - <td class="prmDesc"> - The <a href="#initialization-data-type">Initialization Data Type</a> of the <var>initData</var>. - </td> - </tr> - <tr> - <td class="prmName">initData</td> - <td class="prmType"><code>BufferSource</code></td> - <td class="prmNullFalse"><span role="img" aria-label="False">✘</span></td> - <td class="prmOptFalse"><span role="img" aria-label="False">✘</span></td> - <td class="prmDesc"> - <a href="#initialization-data">Initialization Data</a> - </td> - </tr> - </tbody> - </table> - <div><em>Return type: </em><code>Promise<void></code></div> - <p>When this method is invoked, the user agent must run the following steps:</p> - <ol class="method-algorithm"> - <li> - <p>If this object's <var>closing or closed</var> value is true, return a promise rejected with an <code><a href="#dfn-InvalidStateError">InvalidStateError</a></code>.</p> - </li> - <li> - <p>If this object's <var>uninitialized</var> value is false, return a promise rejected with an <code><a href="#dfn-InvalidStateError">InvalidStateError</a></code>.</p> - </li> - <li> - <p>Let this object's <var>uninitialized</var> value be false.</p> - </li> - <!-- For simplicity and consistency, this object cannot be reused after any failure. --> - <li> - <p>If <var>initDataType</var> is the empty string, return a promise rejected with a newly created <code><a href="#dfn-TypeError">TypeError</a></code>.</p> - </li> - <li> - <p>If <var>initData</var> is an empty array, return a promise rejected with a newly created <code><a href="#dfn-TypeError">TypeError</a></code>.</p> - </li> - <li> - <p>If the <a href="#key-system">Key System</a> implementation represented by this object's <var>cdm implementation</var> value does not support <var>initDataType</var> as an <a href="#initialization-data-type">Initialization Data Type</a>, - return a promise rejected with a <code><a href="#dfn-NotSupportedError">NotSupportedError</a></code>. String comparison is case-sensitive.</p> - </li> - <li> - <p>Let <var>init data</var> be a copy of the contents of the <var>initData</var> parameter.</p> - </li> - <li> - <p>Let <var>session type</var> be this object's <var>session type</var>.</p> - </li> - <li> - <p>Let <var>promise</var> be a new promise.</p> - </li> - <li> - <p>Run the following steps in parallel:</p> - <ol> - <li> - <p>If the <var>init data</var> is not valid for <var>initDataType</var>, reject <var>promise</var> with a newly created <code><a href="#dfn-TypeError">TypeError</a></code>.</p> - </li> - <li> - <p>Let <var>sanitized init data</var> be a validated and sanitized version of <var>init data</var>.</p> - <p>The user agent <em class="rfc2119" title="MUST">MUST</em> thoroughly validate the <a href="#initialization-data">Initialization Data</a> before passing it to the CDM. This includes verifying that the length and - values of fields are reasonable, verifying that values are within reasonable limits, and stripping irrelevant, unsupported, or unknown data or fields. It is <em class="rfc2119" title="RECOMMENDED">RECOMMENDED</em> that user agents pre-parse, sanitize, and/or generate a fully sanitized version of the <a href="#initialization-data">Initialization Data</a>. If the <a href="#initialization-data">Initialization Data</a> format - specified by <var>initDataType</var> supports multiple entries, the user agent <em class="rfc2119" title="SHOULD">SHOULD</em> remove entries that are not needed by the CDM. The user agent <em class="rfc2119" - title="MUST NOT">MUST NOT</em> re-order entries within the <a href="#initialization-data">Initialization Data</a>. - </p> - </li> - <li> - <p>If the preceding step failed, reject <var>promise</var> with a newly created <code><a href="#dfn-TypeError">TypeError</a></code>.</p> - </li> - <li> - <p>If <var>sanitized init data</var> is empty, reject <var>promise</var> with a <code><a href="#dfn-NotSupportedError">NotSupportedError</a></code>.</p> - </li> - <li> - <p>Let <var>session id</var> be the empty string.</p> - </li> - <li> - <p>Let <var>message</var> be null.</p> - </li> - <li> - <p>Let <var>message type</var> be null.</p> - </li> - <li> - <p>Let <var>cdm</var> be the CDM instance represented by this object's <var>cdm instance</var> value.</p> - </li> - <li> - <p>Use the <var>cdm</var> to execute the following steps:</p> - <ol> - <li> - <p>If the <var>sanitized init data</var> is not supported by the <var>cdm</var>, reject <var>promise</var> with a <code><a href="#dfn-NotSupportedError">NotSupportedError</a></code>.</p> - </li> - <li> - <p>Follow the steps for the value of <var>session type</var> from the following list:</p> - <dl class="switch"> - <dt><code><a href="#idl-def-MediaKeySessionType.temporary">"temporary"</a></code></dt> - <dd> - <p>Let <var>requested license type</var> be a temporary non-persistable license.</p> - <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note66"><span>Note</span></div> - <p class="">The returned license must not be persistable or require persisting information related to it.</p> - </div> - </dd> - <dt><code><a href="#idl-def-MediaKeySessionType.persistent-license">"persistent-license"</a></code></dt> - <dd> - <p>Let <var>requested license type</var> be a persistable license.</p> - </dd> - <dt><code><a href="#idl-def-MediaKeySessionType.persistent-usage-record">"persistent-usage-record"</a></code></dt> - <dd> - <ol> - <li> - <p>Initialize this object's <var>record of key usage</var> as follows.</p> - <ul> - <li> - <p> - Set the list of <a href="#decryption-key-id">key IDs</a> <a href="#known-key">known</a> to the session to an empty list. - </p> - </li> - <li> - <p> - Set the <var>first decrypt time</var> to <code>null</code>. - </p> - </li> - <li> - <p> - Set the <var>latest decrypt time</var> to <code>null</code>. - </p> - </li> - </ul> - </li> - <li> - <p>Let <var>requested license type</var> be a non-persistable license that will persist a <a href="#record-of-key-usage">record of key usage</a>.</p> - </li> - </ol> - </dd> - </dl> - </li> - - <li> - <p>Let <var>session id</var> be a unique <a href="#session-id">Session ID</a> string.</p> - <p>If the result of running the <a href="#is-persistent-session-type">Is persistent session type?</a> algorithm on <var>session type</var> is <code>true</code>, the ID <em class="rfc2119" title="MUST">MUST</em> be unique within the <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> of this object's <a href="https://www.w3.org/TR/dom/#concept-document">Document</a> over time, - including across Documents and browsing sessions.</p> - </li> - <li> - <dl class="switch"> - <dt>If a license request for the <var>requested license type</var> can be generated based on the <var>sanitized init data</var>:</dt> - <dd> - <ol> - <li> - <p> - Let <var>message</var> be a license request for the <var>requested license type</var> generated based on the <var>sanitized init data</var> interpreted per <var>initDataType</var>. - </p> - <p> - The <var>cdm</var> <em class="rfc2119" title="MUST NOT">MUST NOT</em> use any stream-specific data, including <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a>, - not provided via the - <var>sanitized init data</var>. - </p> - <p>The <var>cdm</var> <em class="rfc2119" title="SHOULD NOT">SHOULD NOT</em> store session data, including the session ID, at this point. See <a href="#session-storage">Session Storage and Persistence</a>.</p> - </li> - <li> - <p> - Let <var>message type</var> be <code><a href="#idl-def-MediaKeyMessageType.license-request">"license-request"</a></code>. - </p> - </li> - </ol> - </dd> - <dt>Otherwise:</dt> - <dd> - <ol> - <li> - <p> - Let <var>message</var> be the request that needs to be processed before a license request request for the <var>requested license type</var> can be generated based on the <var>sanitized init data</var>. - </p> - <p> - In a subsequent call to <code><a href="#dom-mediakeysession-update">update()</a></code> the CDM <em class="rfc2119" title="MUST">MUST</em> generate a license request for the <var>requested license type</var> based on the <var>sanitized init data</var>, which is interpreted per <var>initDataType</var>. - </p> - </li> - <li> - <p> - Let <var>message type</var> reflect the type of <var>message</var>, either <code><a href="#idl-def-MediaKeyMessageType.license-request">"license-request"</a></code> or <code><a href="#idl-def-MediaKeyMessageType.individualization-request">"individualization-request"</a></code>. - </p> - </li> - </ol> - </dd> - </dl> - </li> - </ol> - </li> - <li> - <p><a href="https://www.w3.org/TR/html51/webappapis.html#queuing">Queue a task</a> to run the following steps:</p> - <ol> - <li> - <p>If any of the preceding steps failed, reject <var>promise</var> with a new <code><a href="https://heycam.github.io/webidl/#dfn-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-mediakeysession-sessionid">sessionId</a></code> attribute to <var>session id</var>.</p> - </li> - <li> - <p>Set this object's <var>callable</var> value to true.</p> - </li> - <li> - <p>Run the <a href="#queue-message">Queue a "message" Event</a> algorithm on the <var>session</var>, providing <var>message type</var> and <var>message</var>.</p> - </li> - <li> - <p>Resolve <var>promise</var>.</p> - <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note67"><span>Note</span></div> - <p class="">Since promise handlers are queued as microtasks, these will be executed ahead of any events queued by the preceding steps.</p> - </div> - </li> - </ol> - </li> - </ol> - </li> - <li> - <p>Return <var>promise</var>.</p> - </li> - </ol> - </dd><dt><dfn data-dfn-for="mediakeysession" data-dfn-type="dfn" id="dom-mediakeysession-load" data-idl="" data-title="load" data-lt="load()|load"><code id="load">load</code></dfn></dt> - <dd> - <p>Loads the data stored for the specified session into this object.</p> - - - - - <table class="parameters"> - <tbody> - <tr> - <th>Parameter</th> - <th>Type</th> - <th>Nullable</th> - <th>Optional</th> - <th>Description</th> - </tr> - <tr> - <td class="prmName">sessionId</td> - <td class="prmType"><code>DOMString</code></td> - <td class="prmNullFalse"><span role="img" aria-label="False">✘</span></td> - <td class="prmOptFalse"><span role="img" aria-label="False">✘</span></td> - <td class="prmDesc"> - The <a href="#session-id">Session ID</a> of the session to load. - </td> - </tr> - </tbody> - </table> - <div><em>Return type: </em><code>Promise<boolean></code></div> - <p>When this method is invoked, the user agent must run the following steps:</p> - <ol class="method-algorithm"> - <li> - <p>If this object's <var>closing or closed</var> value is true, return a promise rejected with an <code><a href="#dfn-InvalidStateError">InvalidStateError</a></code>.</p> - </li> - <li> - <p>If this object's <var>uninitialized</var> value is false, return a promise rejected with an <code><a href="#dfn-InvalidStateError">InvalidStateError</a></code>.</p> - </li> - <li> - <p>Let this object's <var>uninitialized</var> value be false.</p> - </li> - <!-- For simplicity and consistency, this object cannot be reused after any failure. --> - <li> - <p>If <var>sessionId</var> is the empty string, return a promise rejected with a newly created <code><a href="#dfn-TypeError">TypeError</a></code>.</p> - </li> - <li> - <p>If the result of running the <a href="#is-persistent-session-type">Is persistent session type?</a> algorithm on this object's <var>session type</var> is <code>false</code>, return a promise rejected with a newly created - <code><a href="#dfn-TypeError">TypeError</a></code>.</p> - </li> - <li> - <p>Let <var>origin</var> be the <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> of this object's <a href="https://www.w3.org/TR/dom/#concept-document">Document</a>.</p> - </li> - <li> - <p>Let <var>promise</var> be a new promise.</p> - </li> - <li> - <p>Run the following steps in parallel:</p> - <ol> - <li> - <p>Let <var>sanitized session ID</var> be a validated and/or sanitized version of <var>sessionId</var>.</p> - <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note68"><span>Note</span></div> - <p class="">The user agent should thoroughly validate the sessionId value before passing it to the CDM. At a minimum, this should include checking that the length and value are reasonable (e.g., not longer than tens of - characters and alphanumeric). - </p> - </div> - </li> - <li> - <p>If the preceding step failed, or if <var>sanitized session ID</var> is empty, reject <var>promise</var> with a newly created <code><a href="#dfn-TypeError">TypeError</a></code>.</p> - </li> - <li> - <p>If there is a <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object that is not <a href="#media-key-session-closed">closed</a> in this object's <a href="https://www.w3.org/TR/dom/#concept-document">Document</a> whose <code><a href="#dom-mediakeysession-sessionid">sessionId</a></code> attribute is <var>sanitized session ID</var>, reject <var>promise</var> with a <code><a href="#dfn-QuotaExceededError">QuotaExceededError</a></code>.</p> - <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note69"><span>Note</span></div> - <p class="">In other words, do not create a session if a non-closed session, regardless of type, already exists for this <var>sanitized session ID</var> in this browsing context.</p> - </div> - </li> - <li> - <p>Let <var>expiration time</var> be <code>NaN</code>.</p> - </li> - <li> - <p>Let <var>message</var> be null.</p> - </li> - <li> - <p>Let <var>message type</var> be null.</p> - </li> - <li> - <p>Let <var>cdm</var> be the CDM instance represented by this object's <var>cdm instance</var> value.</p> - </li> - <li> - <p>Use the <var>cdm</var> to execute the following steps:</p> - <ol> - <li> - <p>If there is no data stored for the <var>sanitized session ID</var> in the <var>origin</var>, resolve <var>promise</var> with <code>false</code> and abort these steps. - <!-- Per https://github.com/w3ctag/promises-guide#rejections-should-be-used-for-exceptional-situations. --> - </p> - </li> - <li> - <p>If the stored session's <var>session type</var> is not the same as the current <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> <var>session type</var>, - reject <var>promise</var> with a newly created <code><a href="#dfn-TypeError">TypeError</a></code>.</p> - </li> - <li> - <p>Let <var>session data</var> be the data stored for the <var>sanitized session ID</var> in the <var>origin</var>. This <em class="rfc2119" title="MUST NOT">MUST NOT</em> include data from other origin(s) - or that is not associated with an origin.</p> - </li> - <li> - <p>If there is a <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object that is not <a href="#media-key-session-closed">closed</a> in any <a href="https://www.w3.org/TR/dom/#concept-document">Document</a> and that represents the <var>session data</var>, reject <var>promise</var> with a <code><a href="#dfn-QuotaExceededError">QuotaExceededError</a></code>.</p> - <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note70"><span>Note</span></div> - <p class="">In other words, do not create a session if a non-closed persistent session already exists for this <var>sanitized session ID</var> in any browsing context.</p> - </div> - </li> - <li> - <p>Load the <var>session data</var>.</p> - </li> - <li> - <p>If the <var>session data</var> indicates an <a href="#expiration-time">expiration time</a> for the session, let <var>expiration time</var> be that expiration time.</p> - </li> - <li> - <p>If a message needs to be sent, execute the following steps:</p> - <ol> - <li> - <p>Let <var>message</var> be a message generated based on the <var>session data</var>.</p> - </li> - <li> - <p>Let <var>message type</var> be the appropriate <a href="#dom-mediakeymessagetype" class="internalDFN" data-link-type="dfn"><code>MediaKeyMessageType</code></a> for the message.</p> - </li> - </ol> - </li> - </ol> - </li> - <li> - <p><a href="https://www.w3.org/TR/html51/webappapis.html#queuing">Queue a task</a> to run the following steps:</p> - <ol> - <li> - <p>If any of the preceding steps failed, reject <var>promise</var> with a the appropriate <a href="#error-names">error name</a>.</p> - </li> - <li> - <p>Set the <code><a href="#dom-mediakeysession-sessionid">sessionId</a></code> attribute to <var>sanitized session ID</var>.</p> - </li> - <li> - <p>Set this object's <var>callable</var> value to true.</p> - </li> - <li> - <p> - If the loaded session contains information about any keys (there are <a href="#known-key">known keys</a>), run the <a href="#update-key-statuses">Update Key Statuses</a> algorithm on the <var>session</var>, - providing each key's <a href="#decryption-key-id">key ID</a> along with the appropriate <a href="#dom-mediakeystatus" class="internalDFN" data-link-type="dfn"><code>MediaKeyStatus</code></a>. - </p> - <p>Should additional processing be necessary to determine with certainty the status of a key, use <code><a href="#idl-def-MediaKeyStatus.status-pending">"status-pending"</a></code>. Once the additional processing - for one or more keys has completed, run the <a href="#update-key-statuses">Update Key Statuses</a> algorithm again with the actual status(es). - </p> - </li> - <li> - <p>Run the <a href="#update-expiration">Update Expiration</a> algorithm on the <var>session</var>, providing <var>expiration time</var>.</p> - </li> - <li> - <p>If <var>message</var> is not null, run the <a href="#queue-message">Queue a "message" Event</a> algorithm on the <var>session</var>, providing <var>message type</var> and <var>message</var>.</p> - </li> - - <li> - <p>Resolve <var>promise</var> with <code>true</code>.</p> - <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note71"><span>Note</span></div> - <p class="">Since promise handlers are queued as microtasks, these will be executed ahead of any events queued by the preceding steps.</p> - </div> - </li> - </ol> - </li> - </ol> - </li> - <li> - <p>Return <var>promise</var>.</p> - </li> - </ol> - </dd><dt><dfn data-dfn-for="mediakeysession" data-dfn-type="dfn" id="dom-mediakeysession-update" data-idl="" data-title="update" data-lt="update()|update"><code id="update">update</code></dfn></dt> - <dd> - <p>Provides messages, including licenses, to the CDM.</p> - - - - - <table class="parameters"> - <tbody> - <tr> - <th>Parameter</th> - <th>Type</th> - <th>Nullable</th> - <th>Optional</th> - <th>Description</th> - </tr> - <tr> - <td class="prmName">response</td> - <td class="prmType"><code>BufferSource</code></td> - <td class="prmNullFalse"><span role="img" aria-label="False">✘</span></td> - <td class="prmOptFalse"><span role="img" aria-label="False">✘</span></td> - <td class="prmDesc"> - A message to be provided to the CDM. The contents are <a href="#key-system">Key System</a>-specific. It <em class="rfc2119" title="MUST NOT">MUST NOT</em> contain executable code. - </td> - </tr> - </tbody> - </table> - <div><em>Return type: </em><code>Promise<void></code></div> - <p>When this method is invoked, the user agent must run the following steps:</p> - <ol class="method-algorithm"> - <li> - <p>If this object's <var>closing or closed</var> value is true, return a promise rejected with an <code><a href="#dfn-InvalidStateError">InvalidStateError</a></code>.</p> - </li> - <li> - <p>If this object's <var>callable</var> value is false, return a promise rejected with an <code><a href="#dfn-InvalidStateError">InvalidStateError</a></code>.</p> - </li> - <li> - <p>If <var>response</var> is an empty array, return a promise rejected with a newly created <code><a href="#dfn-TypeError">TypeError</a></code>.</p> - </li> - <li> - <p>Let <var>response copy</var> be a copy of the contents of the <var>response</var> parameter.</p> - </li> - <li> - <p>Let <var>promise</var> be a new promise.</p> - </li> - <li> - <p>Run the following steps in parallel:</p> - <ol> - <li> - <p>Let <var>sanitized response</var> be a validated and/or sanitized version of <var>response copy</var>.</p> - <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note72"><span>Note</span></div> - <p class="">The user agent should thoroughly validate the response before passing it to the CDM. This may include verifying values are within reasonable limits, stripping irrelevant data or fields, pre-parsing it, sanitizing - it, and/or generating a fully sanitized version. The user agent should check that the length and values of fields are reasonable. Unknown fields should be rejected or removed. - </p> - </div> - </li> - <li> - <p>If the preceding step failed, or if <var>sanitized response</var> is empty, reject <var>promise</var> with a newly created <code><a href="#dfn-TypeError">TypeError</a></code>.</p> - </li> - <li> - <p>Let <var>message</var> be null.</p> - </li> - <li> - <p>Let <var>message type</var> be null.</p> - </li> - <li> - <p>Let <var>session closed</var> be false.</p> - </li> - <li> - <p>Let <var>cdm</var> be the CDM instance represented by this object's <var>cdm instance</var> value.</p> - </li> - <li> - <p>Use the <var>cdm</var> to execute the following steps:</p> - <ol> - <li> - <p>If the format of <var>sanitized response</var> is invalid in any way, reject <var>promise</var> with a newly created <code><a href="#dfn-TypeError">TypeError</a></code>.</p> - </li> - <li> - <p>Process <var>sanitized response</var>, following the stipulation for the first matching condition from the following list:</p> - <dl class="switch"> - <dt>If <var>sanitized response</var> contains a license or key(s)</dt> - <dd> - <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note73"><span>Note</span></div> - <p class="">This includes an initial license, an updated license, and a license renewal message.</p> - </div> - <p>Process <var>sanitized response</var>, following the stipulation for the first matching condition from the following list:</p> - <dl class="switch"> - <dt>If <var>sessionType</var> is <code><a href="#idl-def-MediaKeySessionType.temporary">"temporary"</a></code> and <var>sanitized response</var> does not specify that session data, including any license, key(s), or similar session data it contains, should be stored</dt> - <dd>Process <var>sanitized response</var>, not storing any session data.</dd> - <dt>If <var>sessionType</var> is <code><a href="#idl-def-MediaKeySessionType.persistent-license">"persistent-license"</a></code> and <var>sanitized response</var> contains a persistable license</dt> - <dd>Process <var>sanitized response</var>, storing the license/key(s) and related session data contained in <var>sanitized response</var>. Such data <em class="rfc2119" title="MUST">MUST</em> be - stored such that only the <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> of this object's <a href="https://www.w3.org/TR/dom/#concept-document">Document</a> can access it. - </dd> - <dt>If <var>sessionType</var> is <code><a href="#idl-def-MediaKeySessionType.persistent-usage-record">"persistent-usage-record"</a></code> and <var>sanitized response</var> contains a non-persistable license</dt> - <dd> - <p>Run the following steps:</p> - <ol> - <li> - <p> - Process <var>sanitized response</var>, not storing any session data. - </p> - </li> - <li> - <p> - If processing <var>sanitized response</var> results in the addition of keys to the set of <a href="#known-key">known keys</a>, add the <a href="#decryption-key-id">key IDs</a> of these keys to this object's <var>record of key usage</var>. - </p> - </li> - </ol> - </dd> - <dt>Otherwise</dt> - <dd> - <p>Reject <var>promise</var> with a newly created <code><a href="#dfn-TypeError">TypeError</a></code>.</p> - </dd> - </dl> - <p>See also <a href="#session-storage">Session Storage and Persistence</a>.</p> - <p>State information, including keys, for each session <em class="rfc2119" title="MUST">MUST</em> be stored in such a way that closing one session does not affect the observable state in other session(s), - even if they contain overlapping key IDs.</p> - <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note74"><span>Note</span></div> - <p class="">When <var>sanitized response</var> contains key(s) and/or related data, <var>cdm</var> will likely store (in memory) the key and related data indexed by key ID.</p> - </div> - <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note75"><span>Note</span></div> - <p class="">The replacement algorithm within a session is <a href="#key-system">Key System</a>-dependent.</p> - </div> - <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note76"><span>Note</span></div> - <p class="">It is <em class="rfc2119" title="RECOMMENDED">RECOMMENDED</em> that CDM implementations support a standard and reasonably high minimum number of keys per <a href="#dom-mediakeysession" class="internalDFN" - data-link-type="dfn"><code>MediaKeySession</code></a> object, including a standard replacement algorithm, and a standard and reasonably high minimum number of <a href="#dom-mediakeysession" - class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> objects. This enables a reasonable number of key rotation algorithms to be implemented across user agents and may - reduce the likelihood of playback interruptions in use cases that involve various streams in the same element (e.g., adaptive streams, various audio and video tracks) using different keys. - </p> - </div> - </dd> - <dt>If <var>sanitized response</var> contains a <a href="#record-of-license-destruction">record of license destruction</a> acknowledgement and <var>sessionType</var> is <code><a href="#idl-def-MediaKeySessionType.persistent-license">"persistent-license"</a></code></dt> - <dd> - <p>Run the following steps:</p> - <ol> - <li> - <p> - Close the <a href="#key-session">key session</a> and clear <em>all</em> stored session data associated with this object, including the <code><a href="#dom-mediakeysession-sessionid">sessionId</a></code> and <a href="#record-of-license-destruction">record of license destruction</a>. - </p> - <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note77"><span>Note</span></div> - <p class="">A subsequent call to <code><a href="#dom-mediakeysession-load">load()</a></code> with the value of this object's <code><a href="#dom-mediakeysession-sessionid">sessionId</a></code> would - fail because there is no data stored for that session ID.</p> - </div> - </li> - <li> - <p>Set <var>session closed</var> to true.</p> - </li> - </ol> - </dd> - <dt>If <var>sanitized response</var> contains a <a href="#record-of-key-usage">record of key usage</a> acknowledgement and <var>sessionType</var> is <code><a href="#idl-def-MediaKeySessionType.persistent-usage-record">"persistent-usage-record"</a></code></dt> - <dd> - <p>Run the following steps:</p> - <ol> - <li> - <p> - Close the <a href="#key-session">session</a> and clear <em>all</em> stored session data associated with this object, including the <code><a href="#dom-mediakeysession-sessionid">sessionId</a></code> and <a href="#record-of-key-usage">record of key usage</a>. - </p> - <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note78"><span>Note</span></div> - <p class="">A subsequent call to <code><a href="#dom-mediakeysession-load">load()</a></code> with the value of this object's <code><a href="#dom-mediakeysession-sessionid">sessionId</a></code> would - fail because there is no data stored for that session ID.</p> - </div> - </li> - <li> - <p>Set <var>session closed</var> to true.</p> - </li> - </ol> - </dd> - <dt>Otherwise</dt> - <dd>Process <var>sanitized response</var>, not storing any session data. - <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note79"><span>Note</span></div> - <p class="">For example, <var>sanitized response</var> may contain information that will be used to generate another <code><a href="#dom-evt-message">message</a></code> event. In this case, there is no need - to verify the contents against the <var>sessionType</var>. - </p> - </div> - </dd> - </dl> - </li> - <li> - <p>If a message needs to be sent, execute the following steps:</p> - <ol> - <li> - <p>Let <var>message</var> be that message.</p> - </li> - <li> - <p>Let <var>message type</var> be the appropriate <a href="#dom-mediakeymessagetype" class="internalDFN" data-link-type="dfn"><code>MediaKeyMessageType</code></a> for the message.</p> - </li> - </ol> - </li> - </ol> - </li> - <li> - <p><a href="https://www.w3.org/TR/html51/webappapis.html#queuing">Queue a task</a> to run the following steps:</p> - <ol> - <li> - <dl class="switch"> - <dt>If <var>session closed</var> is true:</dt> - <dd> - <p>Run the <a href="#session-closed">Session Closed</a> algorithm on this object.</p> - </dd> - <dt>Otherwise:</dt> - <dd> - <p>Run the following steps:</p> - <ol> - <li> - <p> - If the set of keys <a href="#known-key">known</a> to the CDM for this object changed or the status of any key(s) changed, run the <a href="#update-key-statuses">Update Key Statuses</a> algorithm on the <var>session</var>, providing each known key's <a href="#decryption-key-id">key ID</a> along with the appropriate <a href="#dom-mediakeystatus" class="internalDFN" data-link-type="dfn"><code>MediaKeyStatus</code></a>. - </p> - <p> - Should additional processing be necessary to determine with certainty the status of a key, use <code><a href="#idl-def-MediaKeyStatus.status-pending">"status-pending"</a></code>. Once - the additional processing for one or more keys has completed, run the <a href="#update-key-statuses">Update Key Statuses</a> algorithm again with the actual status(es). - </p> - </li> - <li> - <p>If the <a href="#expiration-time">expiration time</a> for the session changed, run the <a href="#update-expiration">Update Expiration</a> algorithm on the <var>session</var>, providing the - new expiration time.</p> - </li> - <li> - <p>If any of the preceding steps failed, reject <var>promise</var> with a new <code><a href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code> whose name is the appropriate - <a href="#error-names">error name</a>.</p> - </li> - <li> - <p>If <var>message</var> is not null, run the <a href="#queue-message">Queue a "message" Event</a> algorithm on the <var>session</var>, providing <var>message type</var> and <var>message</var>.</p> - </li> - </ol> - </dd> - </dl> - </li> - <li> - <p>Resolve <var>promise</var>.</p> - <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note80"><span>Note</span></div> - <p class="">Since promise handlers are queued as microtasks, these will be executed ahead of any events queued by the preceding steps.</p> - </div> - </li> - </ol> - </li> - </ol> - </li> - <li> - <p>Return <var>promise</var>.</p> - </li> - </ol> - </dd><dt><dfn data-dfn-for="mediakeysession" data-dfn-type="dfn" id="dom-mediakeysession-close" data-idl="" data-title="close" data-lt="close()|close"><code id="close">close</code></dfn></dt> - <dd> - <p>Indicates that the application no longer needs the session and the CDM should release any resources associated with the session and close it. Persisted data should not be released or cleared.</p> - <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note81"><span>Note</span></div> - <p class="">The returned promise is resolved when the request has been processed, and the <code><a href="#dom-mediakeysession-closed">closed</a></code> attribute promise is resolved when the session is closed.</p> - </div> - - - <div><em>No parameters.</em></div> - <div><em>Return type: </em><code>Promise<void></code></div> - <p>When this method is invoked, the user agent must run the following steps:</p> - <ol class="method-algorithm"> - <li> - <p>If this object's <var>closing or closed</var> value is true, return a resolved promise.</p> - </li> - <li> - <p>If this object's <var>callable</var> value is false, return a promise rejected with an <code><a href="#dfn-InvalidStateError">InvalidStateError</a></code>.</p> - </li> - <li> - <p>Let <var>promise</var> be a new promise.</p> - </li> - <li> - <p>Set this object's <var>closing or closed</var> value to true.</p> - </li> - <li> - <p>Run the following steps in parallel:</p> - <ol> - <li> - <p>Let <var>cdm</var> be the CDM instance represented by this object's <var>cdm instance</var> value.</p> - </li> - <li> - <p>Use <var>cdm</var> to close the <a href="#key-session">key session</a> associated with this object.</p> - <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note82"><span>Note</span></div> - <p class="">Closing the key session results in the destruction of any license(s) and key(s) that have not been explicitly stored.</p> - </div> - </li> - <li> - <p><a href="https://www.w3.org/TR/html51/webappapis.html#queuing">Queue a task</a> to run the following steps:</p> - <ol> - <li> - <p>Run the <a href="#session-closed">Session Closed</a> algorithm on this object.</p> - </li> - <li> - <p>Resolve <var>promise</var>.</p> - <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note83"><span>Note</span></div> - <p class="">Since promise handlers are queued as microtasks, these will be executed ahead of any events queued by the preceding steps.</p> - </div> - </li> - </ol> - </li> - </ol> - </li> - <li> - <p>Return <var>promise</var>.</p> - </li> - </ol> - </dd><dt><dfn data-dfn-for="mediakeysession" data-dfn-type="dfn" id="dom-mediakeysession-remove" data-idl="" data-title="remove" data-lt="remove()|remove"><code id="remove">remove</code></dfn></dt> - <dd> - <p> - Removes all license(s) and key(s) associated with the session. For <a href="#is-persistent-session-type">persistent session types</a>, other session data will be cleared as defined for each session type once a release message - acknowledgment is processed by <code><a href="#dom-mediakeysession-update">update()</a></code>. - </p> + <section id="obtaining-access-to-key-systems"> + <!--OddPage--><h2 id="x3-obtaining-access-to-key-systems"><span class="secno">3. </span>Obtaining Access to Key Systems</h2> + <p>This section defines the mechanism for obtaining access to a key system. + The inclusion of capabilities in the request also enables feature detection. + </p> + <p>The steps of an algorithm are always aborted when rejecting a promise.</p> + <section id="navigator-extension-requestmediakeysystemaccess"> + <h3 id="x3-1-navigator-extension-requestmediakeysystemaccess"><span class="secno">3.1 </span><dfn data-dfn-type="dfn" id="dom-navigator" data-idl="" data-title="Navigator" data-dfn-for=""><code>Navigator</code></dfn> Extension: <code>requestMediaKeySystemAccess()</code></h3> - <div><em>No parameters.</em></div> - <div><em>Return type: </em><code>Promise<void></code></div> - <p>When this method is invoked, the user agent must run the following steps:</p> - <ol class="method-algorithm"> - <li> - <p>If this object's <var>closing or closed</var> value is true, return a promise rejected with an <code><a href="#dfn-InvalidStateError">InvalidStateError</a></code>.</p> - </li> - <li> - <p>If this object's <var>callable</var> value is false, return a promise rejected with an <code><a href="#dfn-InvalidStateError">InvalidStateError</a></code>.</p> - </li> - <li> - <p>Let <var>promise</var> be a new promise.</p> - </li> - <li> - <p>Run the following steps in parallel:</p> - <ol> - <li> - <p>Let <var>cdm</var> be the CDM instance represented by this object's <var>cdm instance</var> value.</p> - </li> - <li> - <p>Let <var>message</var> be null.</p> - </li> - <li> - <p>Let <var>message type</var> be null.</p> - </li> - <li> - <p>Use the <var>cdm</var> to execute the following steps:</p> - <ol> - <li> - <p> - If any license(s) and/or key(s) are associated with the session: - </p> - <ol> - <li> - <p> - Destroy the license(s) and/or key(s) associated with the session. - </p> - <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note84"><span>Note</span></div> - <p class=""> - This implies destruction of the license(s) and/or keys(s) whether they are in memory, persistent store or both. - </p> - </div> - </li> - <li> - <p>Follow the steps for the value of this object's <var>session type</var> from the following list:</p> - <dl class="switch"> - <dt><code><a href="#idl-def-MediaKeySessionType.temporary">"temporary"</a></code></dt> - <dd> - <p>Continue with the following steps.</p> - </dd> - <dt><code><a href="#idl-def-MediaKeySessionType.persistent-license">"persistent-license"</a></code></dt> - <dd> - <ol> - <li> - <p> - Let <var>record of license destruction</var> be a <a href="#record-of-license-destruction">record of license destruction</a> for the license represented by this object. - </p> - </li> - <li> - <p> - Store the <var>record of license destruction</var>. - </p> - </li> - <li> - <p> - Let <var>message</var> be a message containing or reflecting the <var>record of license destruction</var>. - </p> - </li> - </ol> - </dd> - <dt><code><a href="#idl-def-MediaKeySessionType.persistent-usage-record">"persistent-usage-record"</a></code></dt> - <dd> - <ol> - <li> - Store this object's <var>record of key usage</var>. - </li> - <li> - <p> - Let <var>message</var> be a message containing or reflecting this object's <var>record of key usage</var>. - </p> - </li> - </ol> - </dd> - </dl> - </li> - </ol> - </li> - </ol> - </li> - <li> - <p><a href="https://www.w3.org/TR/html51/webappapis.html#queuing">Queue a task</a> to run the following steps:</p> - <ol> - <li> - <p> - Run the <a href="#update-key-statuses">Update Key Statuses</a> algorithm on the <var>session</var>, providing all <a href="#decryption-key-id">key ID(s)</a> in the session along with the <code><a href="#idl-def-MediaKeyStatus.released">"released"</a></code> <a href="#dom-mediakeystatus" class="internalDFN" data-link-type="dfn"><code>MediaKeyStatus</code></a> value for each. - </p> - </li> - <li> - <p>Run the <a href="#update-expiration">Update Expiration</a> algorithm on the <var>session</var>, providing <code>NaN</code>.</p> - </li> - <li> - <p>If any of the preceding steps failed, reject <var>promise</var> with a new <code><a href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code> whose name is the appropriate <a href="#error-names">error name</a>.</p> - </li> - <li> - <p>Let <var>message type</var> be <code><a href="#idl-def-MediaKeyMessageType.license-release">"license-release"</a></code>.</p> - </li> - <li> - <p>If <var>message</var> is not <code>null</code>, run the <a href="#queue-message">Queue a "message" Event</a> algorithm on the <var>session</var>, providing <var>message type</var> and <var>message</var>.</p> - </li> - <li> - <p>Resolve <var>promise</var>.</p> - <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note85"><span>Note</span></div> - <p class="">Since promise handlers are queued as microtasks, these will be executed ahead of any events queued by the preceding steps.</p> - </div> - </li> - </ol> - </li> - </ol> - </li> - <li> - <p>Return <var>promise</var>.</p> - </li> + <div><div><pre class="def idl"><span class="idlInterface" id="idl-def-navigator-partial-1" data-idl="" data-title="Navigator">partial interface <span class="idlInterfaceID"><a data-no-default="" data-link-for="" data-lt="" href="#dom-navigator" class="internalDFN" data-link-type="dfn"><code>Navigator</code></a></span> { +<span class="idlMethod" id="idl-def-navigator-requestmediakeysystemaccess-keysystem-supportedconfigurations" data-idl="" data-title="requestMediaKeySystemAccess" data-dfn-for="navigator"> [<span class="extAttr"><span class="extAttrName"><a href="https://heycam.github.io/webidl/#SecureContext">SecureContext</a></span></span>] <span class="idlMethType"><a href="https://heycam.github.io/webidl/#idl-promise">Promise</a><<a href="#dom-mediakeysystemaccess" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemAccess</code></a>></span> <span class="idlMethName"><a data-no-default="" data-link-for="navigator" data-lt="requestMediaKeySystemAccess|requestmediakeysystemaccess()" href="#dom-navigator-requestmediakeysystemaccess" class="internalDFN" data-link-type="dfn"><code>requestMediaKeySystemAccess</code></a></span>(<span class="idlParam"><span class="idlParamType"><a href="https://heycam.github.io/webidl/#idl-DOMString">DOMString</a></span> <span class="idlParamName">keySystem</span></span>, + <span class="idlParam"><span class="idlParamType"><a href="https://heycam.github.io/webidl/#idl-sequence">sequence</a><<a href="#dom-mediakeysystemconfiguration" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemConfiguration</code></a>></span> <span class="idlParamName">supportedConfigurations</span></span>);</span> +};</span></pre></div><section><h4 id="methods">Methods</h4><dl class="methods" data-dfn-for="Navigator" data-link-for="Navigator"><dt><dfn data-dfn-for="navigator" data-dfn-type="dfn" id="dom-navigator-requestmediakeysystemaccess" data-idl="" data-title="requestMediaKeySystemAccess" data-lt="requestMediaKeySystemAccess|requestmediakeysystemaccess()"><code id="requestMediaKeySystemAccess">requestMediaKeySystemAccess</code></dfn></dt><dd> + <div class="note"><div role="heading" class="note-title marker" id="h-note-25" aria-level="5"><span>Note</span></div><p class="">Calling this method may have <em>user-visible effects</em>, including requests for user consent. + This method should only be called when the author intends to create and use a <a href="#dfn-mediakeys" class="internalDFN" data-link-type="dfn">MediaKeys</a> object with the provided configuration. + </p></div> + <p>Requests access to the specified <a href="#key-system">Key System</a>. + When <code>supportedConfigurations</code> is specified, the configuration specified by at least one of its elements must be supported. + The resulting <a href="#dom-mediakeysystemaccess" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemAccess</code></a> will correspond to the first such element. + </p> + <p>Any permission checks or user interaction, such as a prompt for consent, <em class="rfc2119" title="MUST">MUST</em> be performed before resolving the promise.</p> + <p>If the <code>keySystem</code> is not supported or not allowed (in at least one of the <code>supportedConfigurations</code>, if specified), the promise is rejected. + Otherwise, it is resolved with a new <a href="#dom-mediakeysystemaccess" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemAccess</code></a> object. + </p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-26" aria-level="5"><span>Note</span></div><div class=""> + <p>This method is only exposed to <a href="https://www.w3.org/TR/secure-contexts/#secure-context">secure contexts</a> [<cite><a class="bibref" href="#bib-SECURE-CONTEXTS">SECURE-CONTEXTS</a></cite>] as indicated by the <code>[SecureContext]</code> IDL attribute.</p> + <p> + Requiring Secure Contexts is <em>not</em> a replacement for other security- and privacy-related requirements and recommendations. + Implementations <em class="rfc2119" title="MUST">MUST</em> meet all related requirements and <em class="rfc2119" title="SHOULD">SHOULD</em> follow related recommendations such that the risks on in an secure context would be similar. + </p> + </div></div> + + + + + <table class="parameters"><tbody><tr><th>Parameter</th><th>Type</th><th>Nullable</th><th>Optional</th><th>Description</th></tr><tr><td class="prmName">keySystem</td><td class="prmType"><code>DOMString</code></td><td class="prmNullFalse"><span role="img" aria-label="False">✘</span></td><td class="prmOptFalse"><span role="img" aria-label="False">✘</span></td><td class="prmDesc"> + The <a href="#key-system">Key System</a> for which access is being requested. + </td></tr><tr><td class="prmName">supportedConfigurations</td><td class="prmType"><code>sequence<MediaKeySystemConfiguration></code></td><td class="prmNullFalse"><span role="img" aria-label="False">✘</span></td><td class="prmOptFalse"><span role="img" aria-label="False">✘</span></td><td class="prmDesc"> + A sequence of <a href="#dom-mediakeysystemconfiguration" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemConfiguration</code></a> configurations to try in order. + The first element with a satisfiable configuration will be used. + </td></tr></tbody></table><div><em>Return type: </em><code>Promise<MediaKeySystemAccess></code></div><p>When this method is invoked, the user agent must run the following steps:</p><ol class="method-algorithm"> + <!-- TODO: Convert all parameters to use <code>. --> + <li><p>If <var>keySystem</var> is the empty string, return a promise rejected with a newly created <code><a href="#dfn-TypeError">TypeError</a></code>.</p></li> + <li><p>If <var>supportedConfigurations</var> is empty, return a promise rejected with a newly created <code><a href="#dfn-TypeError">TypeError</a></code>.</p></li> + <li><p>Let <var>document</var> be the calling context's <a href="https://www.w3.org/TR/dom/#concept-document">Document</a>.</p></li> + <li><p>Let <var>origin</var> be the <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> of <var>document</var>.</p></li> + <li><p>Let <var>promise</var> be a new promise.</p></li> + <li><p>Run the following steps in parallel:</p> + <ol> + <li><p>If <var>keySystem</var> is not one of the <a href="#key-system">Key Systems</a> supported by the user agent, reject <var>promise</var> with a <code><a href="#dfn-NotSupportedError">NotSupportedError</a></code>. String comparison is case-sensitive.</p></li> + <li><p>Let <var>implementation</var> be the implementation of <var>keySystem</var>.</p></li> + <li><p>For each value in <code>supportedConfigurations</code>:</p> + <ol> + <li><p>Let <var>candidate configuration</var> be the value.</p></li> + <li><p>Let <var>supported configuration</var> be the result of executing the <a href="#get-supported-configuration">Get Supported Configuration</a> algorithm on <var>implementation</var>, <var>candidate configuration</var>, and <var>origin</var>.</p></li> + <li><p>If <var>supported configuration</var> is not <code>NotSupported</code>, run the following steps:</p> + <ol> + <li> + <p>Let <var>access</var> be a new <a href="#dom-mediakeysystemaccess" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemAccess</code></a> object, and initialize it as follows:</p> + <ol> + <li><p>Set the <code><a href="#dom-mediakeysystemaccess-keysystem">keySystem</a></code> attribute to <var>keySystem</var>.</p></li> + <li><p>Let the <var>configuration</var> value be <var>supported configuration</var>.</p></li> + <li><p>Let the <var>cdm implementation</var> value be <var>implementation</var>.</p></li> + </ol> + </li> + <li><p>Resolve <var>promise</var> with <var>access</var> and abort the parallel steps of this algorithm.</p></li> </ol> - </dd> - </dl> - </section> - </div> - - <section id="mediakeystatusmap-interface"> - <h3 id="x6.1-mediakeystatusmap-interface"><span class="secno">6.1 </span><dfn data-dfn-for="" data-dfn-type="dfn" id="dom-mediakeystatusmap" data-idl="" data-title="MediaKeyStatusMap"><code>MediaKeyStatusMap</code></dfn> Interface</h3> - <p>The MediaKeyStatusMap object is a read-only map of <a href="#decryption-key-id">key IDs</a> to the current status of the associated key.</p> - <p>A key's status is independent of whether the key is currently being used and of media data.</p> - <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note86"><span>Note</span></div> - <p class="">For example, if a key has output requirements that cannot currently be met, the key's status should be <code><a href="#idl-def-MediaKeyStatus.output-downscaled">"output-downscaled"</a></code> or <code><a href="#idl-def-MediaKeyStatus.output-restricted">"output-restricted"</a></code>, - as appropriate, regardless of whether that key has been or is currently needed to decrypt media data.</p> - </div> - <div> - <div> - <pre class="def idl"><span class="idlInterface" id="idl-def-mediakeystatusmap" data-idl="" data-title="MediaKeyStatusMap">[<span class="extAttr"><span class="extAttrName"><a href="https://heycam.github.io/webidl/#SecureContext">SecureContext</a></span></span>] -interface <span class="idlInterfaceID"><a data-lt="MediaKeyStatusMap" href="#dom-mediakeystatusmap" class="internalDFN" data-link-type="dfn" data-for=""><code>MediaKeyStatusMap</code></a></span> { -<span class="idlIterable" id="idl-def-mediakeystatusmap-iterable" data-idl="" data-title="iterable" data-dfn-for="mediakeystatusmap"> <a data-lt="iterable|undefined" data-lt-nodefault="" href="#dom-mediakeystatusmap-iterable" class="internalDFN" data-link-type="dfn" data-for="MediaKeyStatusMap"><code>iterable</code></a><BufferSource, <a href="#dom-mediakeystatus" class="internalDFN" data-link-type="dfn"><code>MediaKeyStatus</code></a>>;</span> -<span class="idlAttribute" id="idl-def-mediakeystatusmap-size" data-idl="" data-title="size" data-dfn-for="mediakeystatusmap"> readonly attribute <span class="idlAttrType"><a href="https://heycam.github.io/webidl/#idl-unsigned-long">unsigned long</a></span> <span class="idlAttrName"><a data-lt="size" href="#dom-mediakeystatusmap-size" class="internalDFN" data-link-type="dfn" data-for="MediaKeyStatusMap"><code>size</code></a></span>;</span> -<span class="idlMethod" id="idl-def-mediakeystatusmap-has(keyid)" data-idl="" data-title="has" data-dfn-for="mediakeystatusmap"> <span class="idlMethType"><a href="https://heycam.github.io/webidl/#idl-boolean">boolean</a></span> <span class="idlMethName"><a data-lt="has" href="#dom-mediakeystatusmap-has" class="internalDFN" data-link-type="dfn" data-for="MediaKeyStatusMap"><code>has</code></a></span>(<span class="idlParam"><span class="idlParamType">BufferSource</span> <span class="idlParamName">keyId</span></span>);</span> -<span class="idlMethod" id="idl-def-mediakeystatusmap-get(keyid)" data-idl="" data-title="get" data-dfn-for="mediakeystatusmap"> <span class="idlMethType"><a href="https://heycam.github.io/webidl/#idl-any">any</a></span> <span class="idlMethName"><a data-lt="get" href="#dom-mediakeystatusmap-get" class="internalDFN" data-link-type="dfn" data-for="MediaKeyStatusMap"><code>get</code></a></span>(<span class="idlParam"><span class="idlParamType">BufferSource</span> <span class="idlParamName">keyId</span></span>);</span> -};</span></pre> - </div> - <section> - <h4 id="attributes-1">Attributes</h4> - <dl class="attributes" data-dfn-for="MediaKeyStatusMap" data-link-for="MediaKeyStatusMap"><dt><dfn data-dfn-for="mediakeystatusmap" data-dfn-type="dfn" id="dom-mediakeystatusmap-size" data-idl="" data-title="size"><code>size</code></dfn> of type <span class="idlAttrType">unsigned long</span>, readonly </dt> - <dd> - <p>The number of <a href="#known-key">known keys.</a></p> - </dd> - </dl> - </section> - - <section> - <h4 id="methods-3">Methods</h4> - <dl class="methods" data-dfn-for="MediaKeyStatusMap" data-link-for="MediaKeyStatusMap"> - <dt><dfn data-dfn-for="mediakeystatusmap" data-dfn-type="dfn" id="dom-mediakeystatusmap-has" data-idl="" data-title="has" data-lt="has()|has"><code id="has">has</code></dfn></dt> - <dd> - <p>Returns <code>true</code> if the status of the key identified by <var>keyId</var> is known.</p> - - <table class="parameters"> - <tbody> - <tr> - <th>Parameter</th> - <th>Type</th> - <th>Nullable</th> - <th>Optional</th> - <th>Description</th> - </tr> - <tr> - <td class="prmName">keyId</td> - <td class="prmType"><code>BufferSource</code></td> - <td class="prmNullFalse"><span role="img" aria-label="False">✘</span></td> - <td class="prmOptFalse"><span role="img" aria-label="False">✘</span></td> - <td class="prmDesc">The <a href="#decryption-key-id">key ID</a> of the key.</td> - </tr> - </tbody> - </table> - <div><em>Return type: </em><code>boolean</code></div> - </dd> - <dt><dfn data-dfn-for="mediakeystatusmap" data-dfn-type="dfn" id="dom-mediakeystatusmap-get" data-idl="" data-title="get" data-lt="get()|get"><code id="get">get</code></dfn></dt> - <dd> - <p>Returns the <a href="#dom-mediakeystatus" class="internalDFN" data-link-type="dfn"><code>MediaKeyStatus</code></a> of the key identified by <var>keyId</var> or <code>undefined</code> if the status of the key identified by <var>keyId</var> is not known.</p> - - <table class="parameters"> - <tbody> - <tr> - <th>Parameter</th> - <th>Type</th> - <th>Nullable</th> - <th>Optional</th> - <th>Description</th> - </tr> - <tr> - <td class="prmName">keyId</td> - <td class="prmType"><code>BufferSource</code></td> - <td class="prmNullFalse"><span role="img" aria-label="False">✘</span></td> - <td class="prmOptFalse"><span role="img" aria-label="False">✘</span></td> - <td class="prmDesc">The <a href="#decryption-key-id">key ID</a> of the key.</td> - </tr> - </tbody> - </table> - <div><em>Return type: </em><code>any</code></div> - </dd> - </dl> - <p> - This interface has <code>entries</code>, <code>keys</code>, <code>values</code>, <code>forEach</code> and <code>@@iterator</code> methods brought by <dfn data-dfn-for="mediakeystatusmap" data-link-for="MediaKeyStatusMap" data-dfn-type="dfn" - id="dom-mediakeystatusmap-iterable" data-idl="" data-title="iterable"><code>iterable</code></dfn> (see WebIDL, <a href="https://www.w3.org/TR/WebIDL-1/#idl-iterable">3.2.7 Iterable declarations</a>). - </p> + </li> + </ol> + </li> + <li><p>Reject <var>promise</var> with a <code><a href="#dfn-NotSupportedError">NotSupportedError</a></code>.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-27" aria-level="5"><span>Note</span></div><p class=""><code>keySystem</code> was not supported/allowed or none of the configurations in <code>supportedConfigurations</code> were supported/allowed.</p></div> + </li> + </ol> + </li> + <li><p>Return <var>promise</var>.</p></li> + </ol></dd></dl></section></div> + + <section id="algorithms"> + <h4 id="x3-1-1-algorithms"><span class="secno">3.1.1 </span>Algorithms</h4> + + <section id="get-supported-configuration"> + <h5 id="x3-1-1-1-get-supported-configuration"><span class="secno">3.1.1.1 </span>Get Supported Configuration</h5> + <p>Given a <a href="#key-system">Key Systems</a> implementation <var>implementation</var>, <a href="#dom-mediakeysystemconfiguration" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemConfiguration</code></a> <var>candidate configuration</var>, and <var>origin</var>, this algorithm returns a supported configuration or <code>NotSupported</code> as appropriate.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-28" aria-level="6"><span>Note</span></div><p class="">Unrecognized dictionary members in <var>candidate configuration</var> are ignored per [<cite><a class="bibref" href="#bib-WEBIDL">WEBIDL</a></cite>] and will never reach this algorithm. Thus, they cannot be considered as part of the configuration. + </p></div> + <div class="note"><div role="heading" class="note-title marker" id="h-note-29" aria-level="6"><span>Note</span></div><div class=""> + <p> + For certain configurations, it may be required to obtain user consent or inform the user. User Agents have some flexibility to determine + whether consent is required for a specific configuration and whether such consent may also apply to other configurations. For example, + consent to one configuration may also imply consent for less powerful, more restricted configurations. Equally, a denial of consent for + one configuration may imply denial of consent for more powerful, less restricted configurations. + </p> + <p> + Supported configurations, including supported audio and video codecs, may depend on availability of optional capabilities such as + <a href="#distinctive-identifier">Distinctive Identifier(s)</a> and persistent state. The following algorithm iteratively tries to find a configuration + that is both supported and has user consent (or does not need consent). + </p> + <p> + User Agents should reuse earlier consent responses, when appropriate, at least for the duration of the <code><a href="#dom-navigator-requestmediakeysystemaccess">requestMediaKeySystemAccess()</a></code> + algorithm in order to avoid repeated requests to the user for similar configurations. + </p> + <p> + The variable <var>restrictions</var> in the steps below represents the configurations for which consent has been denied during the + execution of this algorithm or based on persisted consent information for the origin. It is used to determine + whether user consent for a candidate configuration or accumulated configuration has been denied. Consent is denied for a accumulated configuration + if every derived configuration has already been denied. Internal representation of <var>restrictions</var> is implementation-specific. + </p> + </div></div> + <ol> + <li> + <p>Let <var>supported configuration</var> be <code>ConsentDenied</code>.</p> + </li> + <li> + <p>Initialize <var>restrictions</var> to indicate that no configurations have had user consent denied.</p> + </li> + <li> + <p>Repeat the following step while <var>supported configuration</var> is <code>ConsentDenied</code>:</p> + <ol> + <li> <p> - The value pairs to iterate over are a snapshot of the set of pairs formed from the <a href="#decryption-key-id">key ID</a> and associated <a href="#dom-mediakeystatus" class="internalDFN" data-link-type="dfn"><code>MediaKeyStatus</code></a> value for all <a href="#known-key">known keys</a>, sorted by <a href="#decryption-key-id">key ID</a>. Key IDs are compared as follows: For key IDs <var>A</var> of length <var>m</var> and <var>B</var> of length <var>n</var>, assigned - such that <var>m</var> <= <var>n</var>, let <var>A</var> < <var>B</var> if and only if the <var>m</var> octets of <var>A</var> are less in lexicographical order than the first <var>m</var> octets of <var>B</var> or those - octets are equal and <var>m</var> < <var>n</var>. + Let <var>supported configuration</var> and, if provided, <var>restrictions</var> be the result of executing the + <a href="#get-supported-configuration-and-consent">Get Supported Configuration and Consent</a> algorithm + with <var>implementation</var>, <var>candidate configuration</var>, <var>restrictions</var> and <var>origin</var>. </p> - </section> - </div> + </li> + </ol> + </li> + <li> + <p>Return <var>supported configuration</var>.</p> + </li> + </ol> + </section> + <section id="get-supported-configuration-and-consent"> + <h5 id="x3-1-1-2-get-supported-configuration-and-consent"><span class="secno">3.1.1.2 </span>Get Supported Configuration and Consent</h5> + <p>Given a <a href="#key-system">Key Systems</a> implementation <var>implementation</var>, <a href="#dom-mediakeysystemconfiguration" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemConfiguration</code></a> <var>candidate configuration</var>, + <var>restrictions</var> and <var>origin</var>, this algorithm returns a supported configuration, <code>NotSupported</code>, or <code>ConsentDenied</code> as appropriate and, in the <code>ConsentDenied</code> case, <var>restrictions</var>. + </p> + <ol> + <li><p>Let <var>accumulated configuration</var> be a new <a href="#dom-mediakeysystemconfiguration" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemConfiguration</code></a> dictionary.</p></li> - <div> - <div> - <pre class="def idl"><span class="idlEnum" id="idl-def-mediakeystatus" data-idl="" data-title="MediaKeyStatus">enum <span class="idlEnumID"><a data-lt="MediaKeyStatus" href="#dom-mediakeystatus" class="internalDFN" data-link-type="dfn" data-for=""><code>MediaKeyStatus</code></a></span> { - <a href="#dom-mediakeystatus-usable" class="idlEnumItem">"usable"</a>, - <a href="#dom-mediakeystatus-expired" class="idlEnumItem">"expired"</a>, - <a href="#dom-mediakeystatus-released" class="idlEnumItem">"released"</a>, - <a href="#dom-mediakeystatus-output-restricted" class="idlEnumItem">"output-restricted"</a>, - <a href="#dom-mediakeystatus-output-downscaled" class="idlEnumItem">"output-downscaled"</a>, - <a href="#dom-mediakeystatus-status-pending" class="idlEnumItem">"status-pending"</a>, - <a href="#dom-mediakeystatus-internal-error" class="idlEnumItem">"internal-error"</a> -};</span></pre> - </div> - <p>The <dfn data-dfn-for="" data-dfn-type="dfn" id="dom-mediakeystatus" data-idl="" data-title="MediaKeyStatus"><code>MediaKeyStatus</code></dfn> enumeration is defined as follows: + <li> + <p> + Set the <code><a href="#dom-mediakeysystemconfiguration-label">label</a></code> member of <var>accumulated configuration</var> to equal the <code><a href="#dom-mediakeysystemconfiguration-label">label</a></code> member of <var>candidate configuration</var>. </p> - <table class="simple" data-dfn-for="MediaKeyStatus" data-link-for="MediaKeyStatus"> - <tbody> - <tr> - <th colspan="2">Enumeration description</th> - </tr> - <tr> - <td><dfn data-dfn-for="mediakeystatus" data-dfn-type="dfn" id="dom-mediakeystatus-usable" data-idl="" data-title="usable"><code id="idl-def-MediaKeyStatus.usable">usable</code></dfn></td> - <td> - The CDM is certain the key is currently <a href="#usable-for-decryption">usable for decryption</a>.<br> Keys that <em>may not</em> currently be <a href="#usable-for-decryption">usable for decryption</a> <em class="rfc2119" - title="MUST NOT">MUST NOT</em> have this status. - </td> - </tr> - <tr> - <td><dfn data-dfn-for="mediakeystatus" data-dfn-type="dfn" id="dom-mediakeystatus-expired" data-idl="" data-title="expired"><code id="idl-def-MediaKeyStatus.expired">expired</code></dfn></td> - <td> - The key is no longer <a href="#usable-for-decryption">usable for decryption</a> because its <a href="#expiration-time">expiration time</a> has passed.<br> The time represented by the <code><a href="#dom-mediakeysession-expiration">expiration</a></code> attribute <em class="rfc2119" title="MUST">MUST</em> be earlier than the current time. All other keys in the session <em class="rfc2119" title="MUST">MUST</em> have this status. - </td> - </tr> - <tr> - <td><dfn data-dfn-for="mediakeystatus" data-dfn-type="dfn" id="dom-mediakeystatus-released" data-idl="" data-title="released"><code id="idl-def-MediaKeyStatus.released">released</code></dfn></td> - <td> - The key itself is no longer available to the CDM, but information about the key, such as a <a href="#record-of-license-destruction">record of license destruction</a> or <a href="#record-of-key-usage">record of key usage</a>, - is available. - </td> - </tr> - <tr> - <td><dfn data-dfn-for="mediakeystatus" data-dfn-type="dfn" id="dom-mediakeystatus-output-restricted" data-idl="" data-title="output-restricted"><code id="idl-def-MediaKeyStatus.output-restricted">output-restricted</code></dfn></td> - <td> - There are output restrictions associated with the key that cannot currently be met. Media data decrypted with this key may be blocked from presentation, if necessary according to the output restrictions. The application should avoid using streams that - will trigger the output restrictions associated with the key. - </td> - </tr> - <tr> - <td><dfn data-dfn-for="mediakeystatus" data-dfn-type="dfn" id="dom-mediakeystatus-output-downscaled" data-idl="" data-title="output-downscaled"><code id="idl-def-MediaKeyStatus.output-downscaled">output-downscaled</code></dfn></td> - <td> - There are output restrictions associated with the key that cannot currently be met. Media data decrypted with this key may be presented at a lower quality (e.g., resolution), if necessary according to the output restrictions. The application should avoid - using streams that will trigger the output restrictions associated with the key.<br> Support for downscaling is <em class="rfc2119" title="OPTIONAL">OPTIONAL</em>. Applications <em class="rfc2119" - title="SHOULD NOT">SHOULD NOT</em> rely on downscaling to ensure uninterrupted playback when output requirements cannot be met. - </td> - </tr> - <tr> - <td><dfn data-dfn-for="mediakeystatus" data-dfn-type="dfn" id="dom-mediakeystatus-status-pending" data-idl="" data-title="status-pending"><code id="idl-def-MediaKeyStatus.status-pending">status-pending</code></dfn></td> - <td> - The status of the key is not yet known and is being determined. The status will be updated with the actual status when it has been determined. - </td> - </tr> - <tr> - <td><dfn data-dfn-for="mediakeystatus" data-dfn-type="dfn" id="dom-mediakeystatus-internal-error" data-idl="" data-title="internal-error"><code id="idl-def-MediaKeyStatus.internal-error">internal-error</code></dfn></td> - <td> - The key is not currently <a href="#usable-for-decryption">usable for decryption</a> because of an error in the CDM unrelated to the other values. This value is not actionable by the application. - </td> - </tr> - </tbody> - </table> - </div> - </section> + </li> - <section id="mediakeymessageevent"> - <h3 id="x6.2-mediakeymessageevent"><span class="secno">6.2 </span><a href="#dom-mediakeymessageevent" class="internalDFN" data-link-type="dfn"><code>MediaKeyMessageEvent</code></a></h3> - <p>The MediaKeyMessageEvent object is used for the <code><a href="#dom-evt-message">message</a></code> event.</p> - <p>Events are constructed as defined in <a href="https://www.w3.org/TR/dom/#constructing-events">Constructing events</a> [<cite><a class="bibref" href="#bib-DOM">DOM</a></cite>].</p> - - <div> - <div> - <pre class="def idl"><span class="idlEnum" id="idl-def-mediakeymessagetype" data-idl="" data-title="MediaKeyMessageType">enum <span class="idlEnumID"><a data-lt="MediaKeyMessageType" href="#dom-mediakeymessagetype" class="internalDFN" data-link-type="dfn" data-for=""><code>MediaKeyMessageType</code></a></span> { - <a href="#dom-mediakeymessagetype-license-request" class="idlEnumItem">"license-request"</a>, - <a href="#dom-mediakeymessagetype-license-renewal" class="idlEnumItem">"license-renewal"</a>, - <a href="#dom-mediakeymessagetype-license-release" class="idlEnumItem">"license-release"</a>, - <a href="#dom-mediakeymessagetype-individualization-request" class="idlEnumItem">"individualization-request"</a> -};</span></pre> - </div> - <p>The <dfn data-dfn-for="" data-dfn-type="dfn" id="dom-mediakeymessagetype" data-idl="" data-title="MediaKeyMessageType"><code>MediaKeyMessageType</code></dfn> is defined as follows:</p> - <table class="simple" data-dfn-for="MediaKeyMessageType" data-link-for="MediaKeyMessageType"> - <tbody> - <tr> - <th colspan="2">Enumeration description</th> - </tr> - <tr> - <td><dfn data-dfn-for="mediakeymessagetype" data-dfn-type="dfn" id="dom-mediakeymessagetype-license-request" data-idl="" data-title="license-request"><code id="idl-def-MediaKeyMessageType.license-request">license-request</code></dfn></td> - <td>The message contains a request for a new license.</td> - </tr> - <tr> - <td><dfn data-dfn-for="mediakeymessagetype" data-dfn-type="dfn" id="dom-mediakeymessagetype-license-renewal" data-idl="" data-title="license-renewal"><code id="idl-def-MediaKeyMessageType.license-renewal">license-renewal</code></dfn></td> - <td>The message contains a request to renew an existing license.</td> - </tr> - <tr> - <td><dfn data-dfn-for="mediakeymessagetype" data-dfn-type="dfn" id="dom-mediakeymessagetype-license-release" data-idl="" data-title="license-release"><code id="idl-def-MediaKeyMessageType.license-release">license-release</code></dfn></td> - <td>The message contains a <a href="#record-of-license-destruction">record of license destruction</a> or <a href="#record-of-key-usage">record of key usage</a>.</td> - </tr> - <tr> - <td><dfn data-dfn-for="mediakeymessagetype" data-dfn-type="dfn" id="dom-mediakeymessagetype-individualization-request" data-idl="" data-title="individualization-request"><code id="idl-def-MediaKeyMessageType.individualization-request">individualization-request</code></dfn></td> - <td> - The message contains a request for <a href="#app-assisted-individualization">App-Assisted Individualization</a> (or re-individualization).<br> As with all other messages, any identifiers in the message <em class="rfc2119" - title="MUST">MUST</em> be <a href="#per-origin-per-profile-identifiers">distinctive per origin and profile</a> and <em class="rfc2119" title="MUST NOT">MUST NOT</em> be <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifier(s)</a>. - </td> - </tr> - </tbody> - </table> - </div> - - <div> - <div> - <pre class="def idl"><span class="idlInterface" id="idl-def-mediakeymessageevent" data-idl="" data-title="MediaKeyMessageEvent">[<span class="extAttr"><span class="extAttrName"><a href="https://heycam.github.io/webidl/#SecureContext">SecureContext</a></span></span>, - <span class="idlCtor"><span class="extAttrName"><a href="https://heycam.github.io/webidl/#Constructor">Constructor</a></span>(<span class="idlParam"><span class="idlParamType"><a href="https://heycam.github.io/webidl/#idl-DOMString">DOMString</a></span> <span class="idlParamName">type</span></span>, <span class="idlParam"><span class="idlParamType"><a href="#dom-mediakeymessageeventinit" class="internalDFN" data-link-type="dfn"><code>MediaKeyMessageEventInit</code></a></span> <span class="idlParamName">eventInitDict</span></span>)</span>] -interface <span class="idlInterfaceID"><a data-lt="MediaKeyMessageEvent" href="#dom-mediakeymessageevent" class="internalDFN" data-link-type="dfn" data-for=""><code>MediaKeyMessageEvent</code></a></span> : <span class="idlSuperclass">Event</span> { -<span class="idlAttribute" id="idl-def-mediakeymessageevent-messagetype" data-idl="" data-title="messageType" data-dfn-for="mediakeymessageevent"> readonly attribute <span class="idlAttrType"><a href="#dom-mediakeymessagetype" class="internalDFN" data-link-type="dfn"><code>MediaKeyMessageType</code></a></span> <span class="idlAttrName"><a data-lt="messageType" href="#dom-mediakeymessageevent-messagetype" class="internalDFN" data-link-type="dfn" data-for="MediaKeyMessageEvent"><code>messageType</code></a></span>;</span> -<span class="idlAttribute" id="idl-def-mediakeymessageevent-message" data-idl="" data-title="message" data-dfn-for="mediakeymessageevent"> readonly attribute <span class="idlAttrType"><a href="https://heycam.github.io/webidl/#idl-ArrayBuffer">ArrayBuffer</a></span> <span class="idlAttrName"><a data-lt="message" href="#dom-mediakeymessageevent-message" class="internalDFN" data-link-type="dfn" data-for="MediaKeyMessageEvent"><code>message</code></a></span>;</span> -};</span></pre> - </div> - <section> - <h4 id="constructors">Constructors</h4> - <dl class="constructors" data-dfn-for="MediaKeyMessageEvent" data-link-for="MediaKeyMessageEvent"><dt><dfn data-dfn-for="" data-dfn-type="dfn" id="dom-mediakeymessageevent" data-idl="" data-title="MediaKeyMessageEvent"><code>MediaKeyMessageEvent</code></dfn></dt> - <dd> - - <table class="parameters"> - <tbody> - <tr> - <th>Parameter</th> - <th>Type</th> - <th>Nullable</th> - <th>Optional</th> - <th>Description</th> - </tr> - <tr> - <td class="prmName">type</td> - <td class="prmType"><code>DOMString</code></td> - <td class="prmNullFalse"><span role="img" aria-label="False">✘</span></td> - <td class="prmOptFalse"><span role="img" aria-label="False">✘</span></td> - <td class="prmDesc"></td> - </tr> - <tr> - <td class="prmName">eventInitDict</td> - <td class="prmType"><code>MediaKeyMessageEventInit</code></td> - <td class="prmNullFalse"><span role="img" aria-label="False">✘</span></td> - <td class="prmOptTrue"><span role="img" aria-label="True">✔</span></td> - <td class="prmDesc"></td> - </tr> - </tbody> - </table> - </dd> - </dl> - </section> - <section> - <h4 id="attributes-2">Attributes</h4> - <dl class="attributes" data-dfn-for="MediaKeyMessageEvent" data-link-for="MediaKeyMessageEvent"><dt><dfn data-dfn-for="mediakeymessageevent" data-dfn-type="dfn" id="dom-mediakeymessageevent-messagetype" data-idl="" data-title="messageType"><code>messageType</code></dfn> of type <span class="idlAttrType"><a href="#dom-mediakeymessagetype" class="internalDFN" data-link-type="dfn"><code>MediaKeyMessageType</code></a></span>, readonly </dt> - <dd> - The type of the message. - <p>Implementations <em class="rfc2119" title="MUST NOT">MUST NOT</em> require applications to handle message types. Implementations <em class="rfc2119" title="MUST">MUST</em> support applications that do not differentiate messages - and <em class="rfc2119" title="MUST NOT">MUST NOT</em> require that applications handle message types. Specifically, Key Systems <em class="rfc2119" title="MUST">MUST</em> support passing all types of messages to a single - URL. - </p> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note87"><span>Note</span></div> - <p class="">This attribute allows an application to differentiate messages without parsing the message. It is intended to enable optional application and/or server optimizations, but applications are not required to use it. - </p> - </div> - </dd><dt><dfn data-dfn-for="mediakeymessageevent" data-dfn-type="dfn" id="dom-mediakeymessageevent-message" data-idl="" data-title="message"><code>message</code></dfn> of type <span class="idlAttrType">ArrayBuffer</span>, readonly </dt> - <dd> - The message from the CDM. Messages are Key System-specific. - </dd> - </dl> - </section> - </div> - - <section id="mediakeymessageeventinit"> - <h4 id="x6.2.1-mediakeymessageeventinit"><span class="secno">6.2.1 </span><dfn data-dfn-for="" data-dfn-type="dfn" id="dom-mediakeymessageeventinit" data-idl="" data-title="MediaKeyMessageEventInit"><code>MediaKeyMessageEventInit</code></dfn></h4> - <div> - <div> - <pre class="def idl"><span class="idlDictionary" id="idl-def-mediakeymessageeventinit" data-idl="" data-title="MediaKeyMessageEventInit">dictionary <span class="idlDictionaryID"><a data-lt="MediaKeyMessageEventInit" href="#dom-mediakeymessageeventinit" class="internalDFN" data-link-type="dfn" data-for=""><code>MediaKeyMessageEventInit</code></a></span> : <span class="idlSuperclass">EventInit</span> { -<span class="idlMember" id="idl-def-mediakeymessageeventinit-messagetype" data-idl="" data-title="messageType" data-dfn-for="mediakeymessageeventinit"> required <span class="idlMemberType"><a href="#dom-mediakeymessagetype" class="internalDFN" data-link-type="dfn"><code>MediaKeyMessageType</code></a></span> <span class="idlMemberName"><a data-lt="messageType" href="#dom-mediakeymessageeventinit-messagetype" class="internalDFN" data-link-type="dfn" data-for="MediaKeyMessageEventInit"><code>messageType</code></a></span>;</span> -<span class="idlMember" id="idl-def-mediakeymessageeventinit-message" data-idl="" data-title="message" data-dfn-for="mediakeymessageeventinit"> required <span class="idlMemberType"><a href="https://heycam.github.io/webidl/#idl-ArrayBuffer">ArrayBuffer</a></span> <span class="idlMemberName"><a data-lt="message" href="#dom-mediakeymessageeventinit-message" class="internalDFN" data-link-type="dfn" data-for="MediaKeyMessageEventInit"><code>message</code></a></span>;</span> -};</span></pre> - </div> - <section> - <h5 id="dictionary-mediakeymessageeventinit-members">Dictionary <a class="idlType internalDFN" href="#dom-mediakeymessageeventinit" data-link-type="dfn"><code>MediaKeyMessageEventInit</code></a> Members</h5> - <dl class="dictionary-members" data-dfn-for="MediaKeyMessageEventInit" data-link-for="MediaKeyMessageEventInit"><dt><dfn data-dfn-for="mediakeymessageeventinit" data-dfn-type="dfn" id="dom-mediakeymessageeventinit-messagetype" data-idl="" data-title="messageType"><code>messageType</code></dfn> of type <span class="idlMemberType"><a href="#dom-mediakeymessagetype" class="internalDFN" data-link-type="dfn"><code>MediaKeyMessageType</code></a></span></dt> - <dd> - The type of the message. - </dd><dt><dfn data-dfn-for="mediakeymessageeventinit" data-dfn-type="dfn" id="dom-mediakeymessageeventinit-message" data-idl="" data-title="message"><code>message</code></dfn> of type <span class="idlMemberType">ArrayBuffer</span></dt> - <dd> - The message. - </dd> - </dl> - </section> - </div> - </section> - </section> - - <section id="mediakeysession-events" class="informative"> - <h3 id="x6.3-event-summary"><span class="secno">6.3 </span>Event Summary</h3> - <p><em>This section is non-normative.</em></p> - - <table class="old-table"> - <thead> - <tr> - <th>Event name</th> - <th>Interface</th> - <th>Dispatched when...</th> - </tr> - </thead> - <tbody> - <tr> - <td><dfn id="dom-evt-keystatuseschange"><code>keystatuseschange</code></dfn></td> - <td><code><a href="https://www.w3.org/TR/dom/#event">Event</a></code></td> - <td>There has been a change in the keys in the session or their status.</td> - </tr> - <tr> - <td><dfn id="dom-evt-message"><code>message</code></dfn></td> - <td><a href="#dom-mediakeymessageevent" class="internalDFN" data-link-type="dfn"><code>MediaKeyMessageEvent</code></a></td> - <td>The CDM has generated a message for the session.</td> - </tr> - </tbody> - </table> - </section> - - <section id="mediakeysession-algorithms"> - <h3 id="x6.4-algorithms"><span class="secno">6.4 </span>Algorithms</h3> + <li><p>If the <code><a href="#dom-mediakeysystemconfiguration-initdatatypes">initDataTypes</a></code> member of <var>candidate configuration</var> is non-empty, run the following steps:</p> + <ol> + <li><p>Let <var>supported types</var> be an empty sequence of DOMStrings.</p></li> + <li><p>For each value in <var>candidate configuration</var>'s <code><a href="#dom-mediakeysystemconfiguration-initdatatypes">initDataTypes</a></code> member:</p> + <ol> + <li><p>Let <var>initDataType</var> be the value.</p></li> + <li> + <p>If the <var>implementation</var> supports generating requests based on <var>initDataType</var>, add <var>initDataType</var> to <var>supported types</var>. + String comparison is case-sensitive. + The empty string is never supported. + </p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-30" aria-level="6"><span>Note</span></div><p class="">The <var>initDataType</var> <em class="rfc2119" title="MUST">MUST</em> be supported independent of content types in order to avoid unexpectedly rejecting the configuration in later steps. + Support for <var>initDataType</var> includes both license generation and, when appropriate, extraction from media data. + See <a href="#initialization-data-type-support-requirements">Initialization Data Type Support requirements</a>. + </p></div> + </li> + </ol> + </li> + <li><p>If <var>supported types</var> is empty, return <code>NotSupported</code>.</p></li> + <li><p>Set the <code><a href="#dom-mediakeysystemconfiguration-initdatatypes">initDataTypes</a></code> member of <var>accumulated configuration</var> to <var>supported types</var>.</p></li> + </ol> + </li> - <section id="queue-message"> - <h4 id="x6.4.1-queue-a-"message"-event"><span class="secno">6.4.1 </span>Queue a "message" Event</h4> - <p>The Queue a "message" Event algorithm queues a message event to a <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object. Requests to run this algorithm include a target <a href="#dom-mediakeysession" - class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object, a <var>message type</var>, and a <var>message</var>. + <!-- Table of results for MediaKeysRequirement members based on implementation capabilities: + || Implementation Capabilities | + Input Value || Only Supported | Only Not Supported | Both | + =========================================================================================== + "required" || "required" | Return null | "required" | + "optional" || "required" | "not-allowed" | Depends on combination | + "not-allowed" || Return null | "not-allowed" | "not-allowed" | + --> + <li> + <p> + Let <var>distinctive identifier requirement</var> be the value of <var>candidate configuration</var>'s <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> member. </p> + </li> + <li> <p> - <var>message</var> <em class="rfc2119" title="MUST NOT">MUST NOT</em> contain <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifier(s)</a>, even in an encrypted form. - <var>message</var> <em class="rfc2119" title="MUST NOT">MUST NOT</em> contain <a href="#distinctive-identifier">Distinctive Identifier(s)</a>, even in an encrypted form, if the <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object's <var>use distinctive identifier</var> value is false. + If <var>distinctive identifier requirement</var> is <code><a href="#idl-def-MediaKeysRequirement.optional">"optional"</a></code> and + <a href="#distinctive-identifier">Distinctive Identifiers</a> are not allowed according to <var>restrictions</var>, set <var>distinctive identifier requirement</var> + to <code><a href="#idl-def-MediaKeysRequirement.not-allowed">"not-allowed"</a></code>. </p> - <p>The following steps are run:</p> - <ol> - <li> - <p>Let the <var>session</var> be the specified <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object.</p> - </li> - <li> - <p><a href="https://www.w3.org/TR/html51/webappapis.html#queuing">Queue a task</a> to create an event named <code><a href="#dom-evt-message">message</a></code> that does not bubble and is not cancellable using the <a href="#dom-mediakeymessageevent" - class="internalDFN" data-link-type="dfn"><code>MediaKeyMessageEvent</code></a> interface with its <var>type</var> attribute set to <code>message</code> and its <var>isTrusted</var> attribute initialized to <code>true</code>, - and dispatch it at the <var>session</var>.</p> - <p>The event interface <a href="#dom-mediakeymessageevent" class="internalDFN" data-link-type="dfn"><code>MediaKeyMessageEvent</code></a> has:</p> - <ul style="list-style-type:none"> - <li> - <code><a href="#dom-mediakeymessageevent-messagetype">messageType</a></code> = the specified <var>message type</var><br><br> - <code><a href="#dom-mediakeymessageevent-message">message</a></code> = the specified <var>message</var> - </li> - </ul> - </li> - </ol> - </section> - - <section id="update-key-statuses"> - <h4 id="x6.4.2-update-key-statuses"><span class="secno">6.4.2 </span>Update Key Statuses</h4> - <p>The Update Key Statuses algorithm updates the set of <a href="#known-key">known</a> keys for a <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> or the status of one or more of the - keys. Requests to run this algorithm include a target <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object and a sequence of <a href="#decryption-key-id">key ID</a> and associated - <a href="#dom-mediakeystatus" class="internalDFN" data-link-type="dfn"><code>MediaKeyStatus</code></a> pairs. + </li> + <li> + <p>Follow the steps for <var>distinctive identifier requirement</var> from the following list:</p> + <dl class="switch"> + <dt><code><a href="#idl-def-MediaKeysRequirement.required">"required"</a></code></dt> + <dd> + <p>If the <var>implementation</var> does not support <a href="#uses-distinctive-identifiers">use of Distinctive Identifier(s)</a> in combination with <var>accumulated configuration</var> and <var>restrictions</var>, return <code>NotSupported</code>.</p> + <!-- TODO: Find a better descriptive model for this than "combination." + See the first three comment threads starting with https://github.com/w3c/encrypted-media/pull/165#discussion_r63112757. --> + </dd> + <dt><code><a href="#idl-def-MediaKeysRequirement.optional">"optional"</a></code></dt> + <dd> + <p>Continue with the following steps.</p> + </dd> + <dt><code><a href="#idl-def-MediaKeysRequirement.not-allowed">"not-allowed"</a></code></dt> + <dd> + <p>If the <var>implementation</var> requires <a href="#uses-distinctive-identifiers-or-distinctive-permanent-identifiers">use Distinctive Identifier(s) or Distinctive Permanent Identifier(s)</a> in combination with <var>accumulated configuration</var> and <var>restrictions</var>, return <code>NotSupported</code>.</p> + </dd> + </dl> + <div class="note"><div role="heading" class="note-title marker" id="h-note-31" aria-level="6"><span>Note</span></div><div class=""> + <p> + The combination of <var>accumulated configuration</var> and <var>restrictions</var> means all the possible configurations that + include everything in <var>accumulated configuration</var> and that are not denied according to <var>restrictions</var>. + </p> + <p> + A feature is supported by an implementation with this combination if the implementation supports at least one of the configurations + in the combination with the feature. + </p> + <p> + A feature is required by an implementtion with this combination if all configurations in the combination that are suported by the implementation + include the feature. + </p> + </div></div> + </li> + <li> + <p> + Set the <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> member of <var>accumulated configuration</var> to equal <var>distinctive identifier requirement</var>. </p> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note88"><span>Note</span></div> - <p class="">The algorithm is always run in a task.</p> - </div> - <p>The following steps are run:</p> + </li> + <li> + <p> + Let <var>persistent state requirement</var> be equal to the value of <var>candidate configuration</var>'s <code><a href="#dom-mediakeysystemconfiguration-persistentstate">persistentState</a></code> member. + </p> + </li> + <li> + <p> + If <var>persistent state requirement</var> is <code><a href="#idl-def-MediaKeysRequirement.optional">"optional"</a></code> and persisting state is not allowed according to + <var>restrictions</var>, set <var>persistent state requirement</var> to <code><a href="#idl-def-MediaKeysRequirement.not-allowed">"not-allowed"</a></code>. + </p> + </li> + <li><p>Follow the steps for <var>persistent state requirement</var> from the following list:</p> + <dl class="switch"> + <dt><code><a href="#idl-def-MediaKeysRequirement.required">"required"</a></code></dt> + <dd> + <p>If the <var>implementation</var> does not support persisting state in combination with <var>accumulated configuration</var> and <var>restrictions</var>, return <code>NotSupported</code>.</p> + </dd> + <dt><code><a href="#idl-def-MediaKeysRequirement.optional">"optional"</a></code></dt> + <dd> + <p> + Continue with the following steps. + </p> + </dd> + <dt><code><a href="#idl-def-MediaKeysRequirement.not-allowed">"not-allowed"</a></code></dt> + <dd> + <p>If the <var>implementation</var> requires persisting state in combination with <var>accumulated configuration</var> and <var>restrictions</var>, return <code>NotSupported</code>.</p> + </dd> + </dl> + </li> + <li> + <p> + Set the <code><a href="#dom-mediakeysystemconfiguration-persistentstate">persistentState</a></code> member of <var>accumulated configuration</var> to equal the value of <var>persistent state requirement</var>. + </p> + </li> + <li><p>Follow the steps for the first matching condition from the following list:</p> + <dl class="switch"> + <dt>If the <code><a href="#dom-mediakeysystemconfiguration-sessiontypes">sessionTypes</a></code> member is <a href="https://heycam.github.io/webidl/#dfn-present">present</a> [<cite><a class="bibref" href="#bib-WEBIDL">WEBIDL</a></cite>] in <var>candidate configuration</var></dt> + <dd> + <p>Let <var>session types</var> be <var>candidate configuration</var>'s <code><a href="#dom-mediakeysystemconfiguration-sessiontypes">sessionTypes</a></code> member.</p> + </dd> + <dt>Otherwise</dt> + <dd> + <p>Let <var>session types</var> be <code>[ <code><a href="#idl-def-MediaKeySessionType.temporary">"temporary"</a></code> ]</code>.</p> + </dd> + </dl> + </li> + <li><p>For each value in <var>session types</var>:</p> <ol> - <li> - <p>Let the <var>session</var> be the associated <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object.</p> - </li> - <li> - <p>Let the <var>input statuses</var> be the sequence of pairs key ID and associated <a href="#dom-mediakeystatus" class="internalDFN" data-link-type="dfn"><code>MediaKeyStatus</code></a> pairs.</p> - </li> - <li> - <p>Let the <var>statuses</var> be <var>session</var>'s <code><a href="#dom-mediakeysession-keystatuses">keyStatuses</a></code> attribute.</p> - </li> - <li> - <p>Run the following steps to replace the contents of <var>statuses</var>:</p> - <ol> - <li> - <p>Empty <var>statuses</var>.</p> - </li> - <li> - <p>For each pair in <var>input statuses</var>.</p> - <ol> - <li> - <p>Let <var>pair</var> be the pair.</p> - </li> - <li> - <p>Insert an entry for <var>pair</var>'s key ID into <var>statuses</var> with the value of <var>pair</var>'s <a href="#dom-mediakeystatus" class="internalDFN" data-link-type="dfn"><code>MediaKeyStatus</code></a> value.</p> - </li> - </ol> - </li> - </ol> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note89"><span>Note</span></div> - <p class="">The effect of this steps is that the contents of <var>session</var>'s <code><a href="#dom-mediakeysession-keystatuses">keyStatuses</a></code> attribute are replaced without invalidating existing references to the attribute. - This replacement is atomic from a script perspective. That is, script <em class="rfc2119" title="MUST NOT">MUST NOT</em> ever see a partially populated sequence. - </p> - </div> - </li> - <li> - <p><a href="https://www.w3.org/TR/html51/webappapis.html#queuing">Queue a task</a> to <a href="https://www.w3.org/TR/html51/webappapis.html#firing-a-simple-event-named-e">fire a simple event</a> named <code><a href="#dom-evt-keystatuseschange">keystatuseschange</a></code> at the <var>session</var>.</p> - </li> - <li> - <p><a href="https://www.w3.org/TR/html51/webappapis.html#queuing">Queue a task</a> to run the <a href="#resume-playback">Attempt to Resume Playback If Necessary</a> algorithm on each of the media element(s) whose <code><a href="#dom-mediakeys">mediaKeys</a></code> attribute is the MediaKeys object that created the <var>session</var>.</p> - </li> + <li><p>Let <var>session type</var> be the value.</p></li> + <li> + <p> + If <var>accumulated configuration</var>'s <code><a href="#dom-mediakeysystemconfiguration-persistentstate">persistentState</a></code> value is <code><a href="#idl-def-MediaKeysRequirement.not-allowed">"not-allowed"</a></code> and the <a href="#is-persistent-session-type">Is persistent session type?</a> algorithm returns <code>true</code> for <var>session type</var> return <code>NotSupported</code>. + </p> + </li> + <li> + <p>If the <var>implementation</var> does not support <var>session type</var> in combination with <var>accumulated configuration</var> and <var>restrictions</var> for other reasons, return <code>NotSupported</code>.</p> + </li> + <li><p>If <var>accumulated configuration</var>'s <code><a href="#dom-mediakeysystemconfiguration-persistentstate">persistentState</a></code> value is <code><a href="#idl-def-MediaKeysRequirement.optional">"optional"</a></code> and the result of running the <a href="#is-persistent-session-type">Is persistent session type?</a> algorithm on <var>session type</var> is <code>true</code>, change <var>accumulated configuration</var>'s <code><a href="#dom-mediakeysystemconfiguration-persistentstate">persistentState</a></code> value to <code><a href="#idl-def-MediaKeysRequirement.required">"required"</a></code>.</p></li> </ol> - </section> + </li> + <li><p>Set the <code><a href="#dom-mediakeysystemconfiguration-sessiontypes">sessionTypes</a></code> member of <var>accumulated configuration</var> to <var>session types</var>.</p></li> + + <li> + <p> + If the <code><a href="#dom-mediakeysystemconfiguration-videocapabilities">videoCapabilities</a></code> and <code><a href="#dom-mediakeysystemconfiguration-audiocapabilities">audioCapabilities</a></code> members in <var>candidate configuration</var> + are both empty, return <code>NotSupported</code>. + </p> + </li> + + <li> + <dl class="switch"> + <dt>If the <code><a href="#dom-mediakeysystemconfiguration-videocapabilities">videoCapabilities</a></code> member in <var>candidate configuration</var> is non-empty:</dt> + <dd> + <ol> + <li><p>Let <var>video capabilities</var> be the result of executing the <a href="#get-supported-capabilities-for-audio-video-type">Get Supported Capabilities for Audio/Video Type</a> algorithm on Video, <var>candidate configuration</var>'s <code><a href="#dom-mediakeysystemconfiguration-videocapabilities">videoCapabilities</a></code> member, <var>accumulated configuration</var>, and <var>restrictions</var>.</p></li> + <li><p>If <var>video capabilities</var> is <code>null</code>, return <code>NotSupported</code>.</p></li><!-- Video capabilities were specified, but none were supported. --> + <li><p>Set the <code><a href="#dom-mediakeysystemconfiguration-videocapabilities">videoCapabilities</a></code> member of <var>accumulated configuration</var> to <var>video capabilities</var>.</p></li> + </ol> + </dd> + <dt>Otherwise:</dt> + <dd><p>Set the <code><a href="#dom-mediakeysystemconfiguration-videocapabilities">videoCapabilities</a></code> member of <var>accumulated configuration</var> to an empty sequence.</p></dd> + </dl> + </li> + + <li> + <dl class="switch"> + <dt>If the <code><a href="#dom-mediakeysystemconfiguration-audiocapabilities">audioCapabilities</a></code> member in <var>candidate configuration</var> is non-empty:</dt> + <dd> + <ol> + <li><p>Let <var>audio capabilities</var> be the result of executing the <a href="#get-supported-capabilities-for-audio-video-type">Get Supported Capabilities for Audio/Video Type</a> algorithm on Audio, <var>candidate configuration</var>'s <code><a href="#dom-mediakeysystemconfiguration-audiocapabilities">audioCapabilities</a></code> member, <var>accumulated configuration</var>, and <var>restrictions</var>.</p></li> + <li><p>If <var>audio capabilities</var> is <code>null</code>, return <code>NotSupported</code>.</p></li><!-- Audio capabilities were specified, but none were supported. --> + <li><p>Set the <code><a href="#dom-mediakeysystemconfiguration-audiocapabilities">audioCapabilities</a></code> member of <var>accumulated configuration</var> to <var>audio capabilities</var>.</p></li> + </ol> + </dd> + <dt>Otherwise:</dt> + <dd><p>Set the <code><a href="#dom-mediakeysystemconfiguration-audiocapabilities">audioCapabilities</a></code> member of <var>accumulated configuration</var> to an empty sequence.</p></dd> + </dl> + </li> + + <!-- Replace "optional" values in the combined configuration before checking permissions and for the value exposed by MediaKeySystemAccess. --> + <li><p>If <var>accumulated configuration</var>'s <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> value is <code><a href="#idl-def-MediaKeysRequirement.optional">"optional"</a></code>, follow the steps for the first matching condition from the following list:</p> + <dl class="switch"> + <dt>If the <var>implementation</var> requires <a href="#uses-distinctive-identifiers-or-distinctive-permanent-identifiers">use Distinctive Identifier(s) or Distinctive Permanent Identifier(s)</a> for any of the combinations in <var>accumulated configuration</var></dt> + <dd> + <p>Change <var>accumulated configuration</var>'s <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> value to <code><a href="#idl-def-MediaKeysRequirement.required">"required"</a></code>.</p> + </dd> + <dt>Otherwise</dt> + <dd> + <p>Change <var>accumulated configuration</var>'s <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> value to <code><a href="#idl-def-MediaKeysRequirement.not-allowed">"not-allowed"</a></code>.</p> + </dd> + </dl> + </li> + + <li><p>If <var>accumulated configuration</var>'s <code><a href="#dom-mediakeysystemconfiguration-persistentstate">persistentState</a></code> value is <code><a href="#idl-def-MediaKeysRequirement.optional">"optional"</a></code>, follow the steps for the first matching condition from the following list:</p> + <dl class="switch"> + <dt>If the <var>implementation</var> requires persisting state for any of the combinations in <var>accumulated configuration</var></dt> + <dd> + <p>Change <var>accumulated configuration</var>'s <code><a href="#dom-mediakeysystemconfiguration-persistentstate">persistentState</a></code> value to <code><a href="#idl-def-MediaKeysRequirement.required">"required"</a></code>.</p> + </dd> + <dt>Otherwise</dt> + <dd> + <p>Change <var>accumulated configuration</var>'s <code><a href="#dom-mediakeysystemconfiguration-persistentstate">persistentState</a></code> value to <code><a href="#idl-def-MediaKeysRequirement.not-allowed">"not-allowed"</a></code>.</p> + </dd> + </dl> + </li> + + <li><p>If <var>implementation</var> in the configuration specified by the combination of the values in <var>accumulated configuration</var> is not supported or not allowed in the <var>origin</var>, return <code>NotSupported</code>.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-32" aria-level="6"><span>Note</span></div><p class="">In this step, "supported" includes the implementation being available for use when this algorithm returns, not just user agent support for such an implementation.</p></div> + </li> - <section id="update-expiration"> - <h4 id="x6.4.3-update-expiration"><span class="secno">6.4.3 </span>Update Expiration</h4> - <p>The Update Expiration algorithm updates the <a href="#expiration-time">expiration time</a> of a <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a>. Requests to run this algorithm include - a target <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object and the new expiration time, which may be <code>NaN</code>. + <li> + <p> + If <var>accumulated configuration</var>'s <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> value is <code><a href="#idl-def-MediaKeysRequirement.required">"required"</a></code> and + the <a href="#distinctive-identifier">Distinctive Identifier(s)</a> associated with <var>accumulated configuration</var> are not <a href="#per-origin-per-profile-identifiers">unique per origin and profile</a> and + <a href="#allow-identifiers-cleared">clearable</a>: </p> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note90"><span>Note</span></div> - <p class="">The algorithm is always run in a task.</p> - </div> - <p>The following steps are run:</p> <ol> - <li> - <p>Let the <var>session</var> be the associated <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object.</p> - </li> - <li> - <p>Let <var>expiration time</var> be <code>NaN</code>.</p> - </li> - <li> - <p>If the new expiration time is not <code>NaN</code>, let <var>expiration time</var> be that expiration time.</p> - </li> - <li> - <p>Set the <var>session</var>'s <code><a href="#dom-mediakeysession-expiration">expiration</a></code> attribute to <var>expiration time</var> expressed as <a href="#time">time</a>.</p> - </li> + <li> + <p> + Update <var>restrictions</var> to reflect that all configurations described by <var>accumulated configuration</var> + do not have user consent. + </p> + </li> + <li> + <p>Return <code>ConsentDenied</code> and <var>restrictions</var>.</p> + </li> </ol> - </section> - - <section id="session-closed"> - <h4 id="x6.4.4-session-closed"><span class="secno">6.4.4 </span>Session Closed</h4> - <p>The Session Closed algorithm updates the <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> state after a <a href="#key-session">key session</a> has been closed by the <a href="#cdm">CDM</a>.</p> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note91"><span>Note</span></div> - <p class="">The algorithm is always run in a task.</p> - </div> + <div class="note"><div role="heading" class="note-title marker" id="h-note-33" aria-level="6"><span>Note</span></div><div class=""> + <p> + The "unique per origin and profile" and "clearable" conditions cannot be false in a compliant implementation because implementations <em class="rfc2119" title="MUST">MUST</em> <a href="#per-origin-per-profile-identifiers">use per-origin per-profile identifiers</a> and <a href="#allow-identifiers-cleared">allow the user to clear identifier</a>. + </p> + </div></div> + </li> + <li> <p> - When a session is closed, the license(s) and key(s) associated with it are no longer available to decrypt <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a>. All <a href="#dom-mediakeysession" - class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> methods will fail and no further events will be queued for this object after this algorithm is run. + Let <var>consent status</var> and <var>updated restrictions</var> be the result of running the <a href="#get-consent-status">Get Consent Status</a> algorithm on <var>accumulated configuration</var>, <var>restrictions</var> and <var>origin</var> and follow the steps for the value of <var>consent status</var> from the following list: </p> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note92"><span>Note</span></div> - <div class=""> + + <dl class="switch"> + <dt><code>ConsentDenied</code>:</dt> + <dd> + <p> + Return <code>ConsentDenied</code> and <var>updated restrictions</var>. + </p> + </dd><dt><code>InformUser</code>:</dt> + <dd> + <p> + Inform the user that <var>accumulated configuration</var> is in use in the <var>origin</var> including, specifically, the information + that <a href="#distinctive-identifier">Distinctive Identifier(s)</a> and/or <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifier(s)</a> as appropriate will be used if the <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> + member of <var>accumulated configuration</var> is <code><a href="#idl-def-MediaKeysRequirement.required">"required"</a></code>. Continue to the next step. + </p> + </dd> + <dt><code>Allowed</code>:</dt> + <dd> + <p> + Continue to the next step. + </p> + </dd> + </dl> + </li> + + <li><p>Return <var>accumulated configuration</var>.</p></li> + </ol> + </section> + + <section id="get-supported-capabilities-for-audio-video-type"> + <h5 id="x3-1-1-3-get-supported-capabilities-for-audio-video-type"><span class="secno">3.1.1.3 </span>Get Supported Capabilities for Audio/Video Type</h5> + <p>Given an <var>audio/video type</var>, <a href="#dom-mediakeysystemmediacapability" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemMediaCapability</code></a> sequence <var>requested media capabilities</var>, <a href="#dom-mediakeysystemconfiguration" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemConfiguration</code></a> <var>accumulated configuration</var>, and <var>restrictions</var>, this algorithm returns a sequence of supported <a href="#dom-mediakeysystemmediacapability" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemMediaCapability</code></a> values for this audio/video type or <code>null</code> as appropriate.</p> + <ol> + <li><p>Let <var>local accumulated configuration</var> be a local copy of <var>accumulated configuration</var>.</p></li> + <li><p>Let <var>supported media capabilities</var> be an empty sequence of <a href="#dom-mediakeysystemmediacapability" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemMediaCapability</code></a> dictionaries.</p></li> + <li><p>For each <var>requested media capability</var> in <var>requested media capabilities</var>:</p> + <ol> + <li><p>Let <var>content type</var> be <var>requested media capability</var>'s <code><a href="#dom-mediakeysystemmediacapability-contenttype">contentType</a></code> member.</p></li> + <li><p>Let <var>robustness</var> be <var>requested media capability</var>'s <code><a href="#dom-mediakeysystemmediacapability-robustness">robustness</a></code> member.</p></li> + <li><p>If <var>content type</var> is the empty string, return <code>null</code>.</p></li><!-- Invalid input. --> + <li><p>If <var>content type</var> is not a <a href="#valid-media-mime-type">valid media MIME type</a> or is unrecognized, continue to the next iteration.</p></li> + <li><p>Let <var>container</var> be the container type specified by <var>content type</var>.</p></li> + <li><p>If the user agent does not support <var>container</var>, continue to the next iteration. The case-sensitivity of string comparisons is determined by the appropriate RFC.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-34" aria-level="6"><span>Note</span></div><p class="">Per RFC 6838 [<cite><a class="bibref" href="#bib-RFC6838">RFC6838</a></cite>], "Both top-level type and subtype names are case-insensitive."</p></div> + </li> + <li><p>Let <var>parameters</var> be the RFC 6381 [<cite><a class="bibref" href="#bib-RFC6381">RFC6381</a></cite>] parameters, if any, specified by <var>content type</var>.</p></li> + <li><p>If the user agent does not recognize one or more <var>parameters</var>, continue to the next iteration.</p></li> + <li><p>Let <var>media types</var> be the set of codecs and codec constraints specified by <var>parameters</var>. The case-sensitivity of string comparisons is determined by the appropriate RFC or other specification.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-35" aria-level="6"><span>Note</span></div><p class="">Case-sensitive string comparison is <em class="rfc2119" title="RECOMMENDED">RECOMMENDED</em> because RFC 6381 [<cite><a class="bibref" href="#bib-RFC6381">RFC6381</a></cite>] says, "Values are case sensitive" for some formats.</p></div> + </li> + <li> + <p> + If <var>media types</var> is empty: + </p> + <dl class="switch"> + <dt>If <var>container</var> normatively implies a specific set of codecs and codec constraints:</dt> + <dd> <p> - The CDM may close a session at any point, such as when the session is no longer needed or when system resources are lost. In that case, the <a href="#monitor-cdm">Monitor for CDM Changes</a> algorithm detects the change and - runs this algorithm. + Let <var>parameters</var> be that set. </p> - <p>Keys in other sessions <em class="rfc2119" title="MUST">MUST</em> be unaffected, even if they have overlapping key IDs.</p> + </dd> + <dt>Otherwise:</dt> + <dd> <p> - After this algorithm has run, event handlers for the events queued by this algorithm will be executed, but no further events can be queued. As a result, no messages can be sent by the CDM as a result of closing the session. + Continue to the next iteration. </p> - </div> - </div> - <p>The following steps are run:</p> - <ol> - <li> - <p>Let <var>session</var> be the associated <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object.</p> - </li> - <li> - <p>Let <var>promise</var> be the <var>session</var>'s <code><a href="#dom-mediakeysession-closed">closed</a></code> attribute.</p> - </li> - <!-- Avoid a race condition that could cause the algorithms below to be run multiple times. --> - <li> - <p>If <var>promise</var> is resolved, abort these steps.</p> - </li> - <!-- Handle the case that this algorithm is reached by a path other than close(). In all cases, the value is set before the algorithms below are run. --> - <li> - <p>Set the <var>session</var>'s <var>closing or closed</var> value to true.</p> - </li> - <li> + </dd> + </dl> + </li> + <li><p>If <var>content type</var> is not strictly a <var>audio/video type</var>, continue to the next iteration.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-36" aria-level="6"><span>Note</span></div><p class="">For example, if <var>audio/video type</var> is Video and the top-level type is not "video" or <var>media types</var> contains non-video codecs.</p></div> + </li> + <li><p>If <var>robustness</var> is not the empty string and contains an unrecognized value or a value not supported by <var>implementation</var>, continue to the next iteration. String comparison is case-sensitive.</p></li> + <li><p>If the user agent and <var>implementation</var> definitely support playback of encrypted <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a> for the combination of <var>container</var>, <var>media types</var>, <var>robustness</var> and <var>local accumulated configuration</var> in combination with <var>restrictions</var>:</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-37" aria-level="6"><span>Note</span></div><p class=""><var>requested media capability</var> (content type and robustness) must be supported when used together with all previously added requested media capabilities.</p></div> + <ol> + <li> <p> - If <var>session</var>'s <var>session type</var> is <code><a href="#idl-def-MediaKeySessionType.persistent-usage-record">"persistent-usage-record"</a></code>, execute the following steps: + Add <var>requested media capability</var> to <var>supported media capabilities</var>. </p> - <ol> - <li> - <p>Let <var>cdm</var> be the CDM instance represented by <var>session</var>'s <var>cdm instance</var> value.</p> - </li> - <li> - <p>Use <var>cdm</var> to store <var>session</var>'s <var>record of key usage</var>, if it exists.</p> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note93"><span>Note</span></div> - <div class=""> - <p> - The <var>record of key usage</var> may not exist if no keys have been used in the session or if it has been deleted as a result of the <code><a href="#dom-mediakeysession-update">update()</a></code> method processing - an acknowledgement of the <a href="#record-of-key-usage">record of key usage</a>. - </p> - <p> - Since it has no effects observable to the document, this step may be run asynchronously, including after the document has unloaded. - </p> - </div> - </div> - </li> - </ol> - - </li> - <li> - <p>Run the <a href="#update-key-statuses">Update Key Statuses</a> algorithm on the <var>session</var>, providing an empty sequence.</p> - </li> - <li> - <p>Run the <a href="#update-expiration">Update Expiration</a> algorithm on the <var>session</var>, providing <code>NaN</code>.</p> - </li> - <li> - <p>Resolve <var>promise</var>.</p> - </li> + <div class="note"><div role="heading" class="note-title marker" id="h-note-38" aria-level="6"><span>Note</span></div><p class=""> + This step ensures that the values of the members of entries in <var>supported media capabilities</var> are exactly the strings supplied in + <var>requested media capability</var> without modification by the User Agent. + </p></div> + </li> + <li> + <dl class="switch"> + <dt>If <var>audio/video type</var> is Video:</dt> + <dd> + <p> + Add <var>requested media capability</var> to the <code><a href="#dom-mediakeysystemconfiguration-videocapabilities">videoCapabilities</a></code> member of <var>local accumulated configuration</var>. + </p> + </dd> + <dt>If <var>audio/video type</var> is Audio:</dt> + <dd> + <p> + Add <var>requested media capability</var> to the <code><a href="#dom-mediakeysystemconfiguration-audiocapabilities">audioCapabilities</a></code> member of <var>local accumulated configuration</var>. + </p> + </dd> + </dl> + <div class="note"><div role="heading" class="note-title marker" id="h-note-39" aria-level="6"><span>Note</span></div><p class=""> + This step ensures that configurations are always checked with configurations from previous iterations, including from previous calls to this algorithm. + Otherwise, only configurations from previous calls to this algorithm would be checked in subsequent calls. + </p></div> + </li> + </ol> + </li> </ol> - </section> - <section id="media-key-session-destroyed"> - <h4 id="x6.4.5-mediakeysession-destroyed"><span class="secno">6.4.5 </span>MediaKeySession Destroyed</h4> + </li> + <li><p>If <var>supported media capabilities</var> is empty, return <code>null</code>.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-40" aria-level="6"><span>Note</span></div><p class="">None of the <a href="#dom-mediakeysystemmediacapability" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemMediaCapability</code></a> elements in <var>requested media capabilities</var> is supported in combination with <var>accumulated configuration</var>.</p></div> + </li> + <li><p>Return <var>supported media capabilities</var>.</p></li> + </ol> + </section> + + <section id="get-consent-status"> + <h5 id="x3-1-1-4-get-consent-status"><span class="secno">3.1.1.4 </span>Get Consent Status</h5> + <p> + Given an <var>accumulated configuration</var>, <var>restrictions</var> and <var>origin</var>, this algorithm returns the consent status for + <var>accumulated configuration</var> and <var>origin</var> as one of <code>ConsentDenied</code>, <code>InformUser</code> or <code>Allowed</code>, + together with an updated value for <var>restrictions</var> in the <code>ConsentDenied</code> case. + </p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-41" aria-level="6"><span>Note</span></div><div class=""> + <p> + Consent status for <var>accumulated configuration</var> depends at least on the value of the <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> member of + <var>accumulated configuration</var>. + </p> + <p> + Previous consent for <var>accumulated configuration</var> with <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> + set to <code><a href="#idl-def-MediaKeysRequirement.not-allowed">"not-allowed"</a></code> does not imply consent for the same configuration with <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> + set to <code><a href="#idl-def-MediaKeysRequirement.optional">"optional"</a></code> or <code><a href="#idl-def-MediaKeysRequirement.required">"required"</a></code>. + </p> + </div></div> + <ol> + <li> <p> - The MediaKeySession Destroyed algorithm performs steps that are necessary when a <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> that is not <a href="#media-key-session-closed">closed</a> is destroyed. + If there is persisted denial for <var>origin</var> indicating that <var>accumulated configuration</var> is not allowed, run the following steps: </p> - <p>The following steps are run in parallel to the main event loop:</p> <ol> - <li> - <p>Let <var>session</var> be the associated <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object.</p> - </li> - <li> - <p>Let <var>cdm</var> be the CDM instance represented by <var>session</var>'s <var>cdm instance</var> value.</p> - </li> - <li> - <p>Use <var>cdm</var> to execute the following steps:</p> - <ol> - <li> - <p>Close the <a href="#key-session">session</a> associated with <var>session</var>.</p> - </li> - <li> - <p> - If <var>session</var>'s <var>session type</var> is <code><a href="#idl-def-MediaKeySessionType.persistent-usage-record">"persistent-usage-record"</a></code>, store <var>session</var>'s <var>record of key usage</var>, - if it exists. - </p> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note94"><span>Note</span></div> - <p class=""> - Since it has no effects observable to the document, this step may be run asynchronously, including after the document has unloaded. - </p> - </div> - </li> - </ol> - </li> + <li> + <p>Update <var>restrictions</var> to reflect the configurations for which consent has been denied.</p> + </li> + <li> + <p>Return <code>ConsentDenied</code> and <var>restrictions</var>.</p> + </li> </ol> - </section> - <section id="monitor-cdm"> - <h4 id="x6.4.6-monitor-for-cdm-state-changes"><span class="secno">6.4.6 </span>Monitor for CDM State Changes</h4> + </li> + <li> <p> - The Monitor for CDM State Changes algorithm executes steps required when various aspects of CDM state change. + If there is persisted consent for <var>origin</var> indicating <var>accumulated configuration</var> is allowed, return <code>Allowed</code>. </p> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note95"><span>Note</span></div> - <p class="">This algorithm only applies to CDM state changes that are not covered by other algorithms. For example, <code><a href="#dom-mediakeysession-update">update()</a></code> may result in messages, key status changes and/or expiration changes, - but those are all handled within that algorithm.</p> - </div> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note96"><span>Note</span></div> - <p class="">The algorithm is always run in parallel to the main event loop.</p> - </div> + </li> + <li> <p> - The following steps are run: + If any of the following are true: </p> - + <ul> + <li> + <p> + The <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> member of <var>accumulated configuration</var> is not + <code><a href="#idl-def-MediaKeysRequirement.not-allowed">"not-allowed"</a></code> and the combination of the User Agent, <var>implementation</var> + and <var>accumulated configuration</var> does not follow all the recommendations of + <a href="#allow-persistent-data-cleared">Allow Persistent Data to Be Cleared</a> with respect to + <a href="#distinctive-identifier">Distinctive Identifier(s)</a>. + </p> + </li> + <li> + <p> + The user agent requires explicit user consent for the <var>accumulated configuration</var> for other reasons. + </p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-42" aria-level="6"><span>Note</span></div><p class=""> + Another reason for requiring explicit user consent may be due to the security properties of the CDM implementation. + </p></div> + </li> + </ul> + <p>then run the following steps:</p> <ol> - <li> - <p> - Let <var>session</var> be the <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object. - </p> - </li> - <li> - <p>Let <var>cdm</var> be the CDM instance represented by <var>session</var>'s <var>cdm instance</var> value.</p> - </li> - <li> - <p> - If <var>cdm</var> has an outgoing message that has not yet been sent, <a href="https://www.w3.org/TR/html51/webappapis.html#queuing">queue a task</a> to execute the following steps: - </p> - <ol> - <li> - <p> - Let <var>message type</var> and <var>message</var> be the message type and message, respectively. - </p> - </li> - <li> - <p> - Run the <a href="#queue-message">Queue a "message" Event</a> algorithm, passing <var>session</var>, <var>message type</var> and <var>message</var>. - </p> - </li> - </ol> - </li> - <li> - <p> - If <var>cdm</var> has changed the set of keys <a href="#known-key">known</a> to <var>session</var> or the status of one or more of the keys, - <a href="https://www.w3.org/TR/html51/webappapis.html#queuing">queue a task</a> to execute the following steps: - </p> - <ol> - <li> - <p> - Let <var>statuses</var> be a list of key ID and <a href="#dom-mediakeystatus" class="internalDFN" data-link-type="dfn"><code>MediaKeyStatus</code></a> value pairs containing one pair for each key - <a href="#known-key">known</a> to <var>session</var>. - </p> - </li> - <li> - <p> - Run the <a href="#update-key-statuses">Update Key Statuses</a> algorithm, passing <var>session</var> and <var>statuses</var>. - </p> - </li> - </ol> - </li> - <li> - <p> - If <var>cdm</var> has changed the <a href="#expiration-time">expiration time</a> of <var>session</var>, <a href="https://www.w3.org/TR/html51/webappapis.html#queuing">queue a task</a> to execute the following steps: - </p> - <ol> - <li> - <p> - Let <var>expiration time</var> be the new expiration time of <var>session</var>. - </p> - </li> - <li> - <p> - Run the <a href="#update-expiration">Update Expiration</a> algorithm, passing <var>session</var> and <var>expiration time</var>. - </p> - </li> - </ol> - </li> - <li> - <p> - If <var>cdm</var> has closed <var>session</var>, <a href="https://www.w3.org/TR/html51/webappapis.html#queuing">queue a task</a> to run the <a href="#session-closed">Session Closed</a> algorithm on <var>session</var>. - </p> - </li> - <li> - <p> - If <var>cdm</var> had become unavailable, <a href="https://www.w3.org/TR/html51/webappapis.html#queuing">queue a task</a> to run the <a href="#session-closed">Session Closed</a> algorithm on <var>session</var>. - </p> - </li> + <li> + <p> + Request user consent to use <var>accumulated configuration</var> in the <var>origin</var> and wait for the user response. + </p> + <p> + The consent <em class="rfc2119" title="MUST">MUST</em> include consent to use a <a href="#distinctive-identifier">Distinctive Identifier(s)</a> and/or <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifier(s)</a> as appropriate if + <var>accumulated configuration</var>'s <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> member is <code><a href="#idl-def-MediaKeysRequirement.required">"required"</a></code>. + </p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-43" aria-level="6"><span>Note</span></div><div class=""> + + <p>User consent to use <var>accumulated configuration</var> is specific to the <var>origin</var> and may be limited to configurations sharing certain properties with <var>accumulated configuration</var>.</p> + </div></div> + </li> + <li> + <p> + If consent was denied, run the following steps: + </p> + <ol> + <li><p>Update <var>restrictions</var> to reflect the configurations for which consent was denied.</p></li> + <li><p>Return <code>ConsentDenied</code> and <var>restrictions</var>.</p></li> + </ol> + </li> </ol> - </section> + </li> + <li> + <p> + If the <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> member of <var>accumulated configuration</var> is not + <code><a href="#idl-def-MediaKeysRequirement.not-allowed">"not-allowed"</a></code>, return <code>InformUser</code>. + </p> + </li> + <li> + <p> + If the user agent requires informing the user for the <var>accumulated configuration</var> for other reasons, return <code>InformUser</code>. + </p> + </li> + <li> + <p>Return <code>Allowed</code>.</p> + </li> + </ol> + </section> </section> - <section id="exceptions"> - <h3 id="x6.5-exceptions"><span class="secno">6.5 </span>Exceptions</h3> - <p id="error-names">The methods report errors by rejecting the returned promise with a <a href="https://heycam.github.io/webidl/#dfn-simple-exception">simple exception</a> [<cite><a class="bibref" href="#bib-WEBIDL">WEBIDL</a></cite>] or a <code><a href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code>. - The following <a href="https://heycam.github.io/webidl/#dfn-simple-exception">simple exceptions</a> and <a href="https://heycam.github.io/webidl/#idl-DOMException-error-names">DOMException names</a> from [<cite><a class="bibref" href="#bib-WEBIDL">WEBIDL</a></cite>] - are used in the algorithms. Causes specified specified in the algorithms are listed alongside each name, though these names <em class="rfc2119" title="MAY">MAY</em> be used for other reasons as well. - </p> + </section> - <table class="old-table"> - <tbody> - <tr> - <th>Name</th> - <th>Possible Causes (non-exhaustive)</th> - </tr> - <tr> - <td><dfn id="dfn-TypeError" data-dfn-type="dfn"><code>TypeError</code></dfn></td> - <td> - The parameter is empty.<br> Invalid initialization data.<br> Invalid response format.<br> A persistent license was provided for a <code><a href="#idl-def-MediaKeySessionType.temporary">"temporary"</a></code> session. - </td> - </tr> - <tr> - <td><dfn id="dfn-NotSupportedError" data-dfn-type="dfn"><code>NotSupportedError</code></dfn></td> - <td> - The existing MediaKeys object cannot be removed.<br> The key system is not supported.<br> The initialization data type is not supported by the key system.<br> The session type is not supported by the key system.<br> The initialization - data is not supported by the key system.<br> The operation is not supported by the key system. - </td> - </tr> - <tr> - <td><dfn id="dfn-InvalidStateError" data-dfn-type="dfn"><code>InvalidStateError</code></dfn></td> - <td>The existing MediaKeys object cannot be removed at this time.<br> The session has already been used.<br> The session is not yet initialized.<br> The session is closed. - </td> - </tr> - <tr> - <td><dfn id="dfn-QuotaExceededError" data-dfn-type="dfn"><code>QuotaExceededError</code></dfn></td> - <td>The MediaKeys object cannot be used with additional HTMLMediaElements.<br> A non-closed session already exists for this sessionId. - </td> - </tr> - </tbody> - </table> - </section> + <section id="mediakeysystemconfiguration-dictionary"> + <h3 id="x3-2-mediakeysystemconfiguration-dictionary"><span class="secno">3.2 </span><a href="#dom-mediakeysystemconfiguration" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemConfiguration</code></a> dictionary</h3> - <section id="session-storage"> - <h3 id="x6.6-session-storage-and-persistence"><span class="secno">6.6 </span>Session Storage and Persistence</h3> - <p>This section provides an overview of session storage and persistence that complements the algorithms.</p> - <p>The following requirements apply in addition to those in <a href="#media-keys-storage">Storage and Persistence</a>.</p> - <p>If the result of running the <a href="#is-persistent-session-type">Is persistent session type?</a> algorithm on this object's <var>session type</var> is <code>false</code>, the user agent and CDM <em class="rfc2119" title="MUST NOT">MUST NOT</em> persist a record of or data related to the session at any point. This includes license(s), key(s), <a href="#record-of-license-destruction">record(s) of license destruction</a>, <a href="#record-of-key-usage">record(s) of key usage</a>, - and the <a href="#session-id">Session ID</a>. + <div><div><pre class="def idl"><span class="idlEnum" id="idl-def-mediakeysrequirement" data-idl="" data-title="MediaKeysRequirement">enum <span class="idlEnumID"><a data-no-default="" data-link-for="" data-lt="" href="#dom-mediakeysrequirement" class="internalDFN" data-link-type="dfn"><code>MediaKeysRequirement</code></a></span> { + <a href="#dom-mediakeysrequirement-required" class="idlEnumItem">"required"</a>, + <a href="#dom-mediakeysrequirement-optional" class="idlEnumItem">"optional"</a>, + <a href="#dom-mediakeysrequirement-not-allowed" class="idlEnumItem">"not-allowed"</a> +};</span></pre></div> +<p> +The <dfn data-dfn-type="dfn" id="dom-mediakeysrequirement" data-idl="" data-title="MediaKeysRequirement" data-dfn-for=""><code>MediaKeysRequirement</code></dfn> enumeration is defined as follows: +</p> +<table class="simple" data-dfn-for="MediaKeysRequirement" data-link-for="MediaKeysRequirement"><tbody><tr><th colspan="2">Enumeration description</th></tr><tr><td><dfn data-dfn-for="mediakeysrequirement" data-dfn-type="dfn" id="dom-mediakeysrequirement-required" data-idl="" data-title="required"><code id="idl-def-MediaKeysRequirement.required">required</code></dfn></td><td> + <dl> + <dt>When used in a call to <code><a href="#dom-navigator-requestmediakeysystemaccess">requestMediaKeySystemAccess()</a></code></dt> + <dd>The returned object <em class="rfc2119" title="MUST">MUST</em> support this feature.</dd> + <dt>When returned by a <a href="#dom-mediakeysystemaccess" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemAccess</code></a> object</dt> + <dd>CDM instances created by the object <em class="rfc2119" title="MAY">MAY</em> use this feature.</dd> + </dl> + </td></tr><tr><td><dfn data-dfn-for="mediakeysrequirement" data-dfn-type="dfn" id="dom-mediakeysrequirement-optional" data-idl="" data-title="optional"><code id="idl-def-MediaKeysRequirement.optional">optional</code></dfn></td><td> + <dl> + <dt>When used in a call to <code><a href="#dom-navigator-requestmediakeysystemaccess">requestMediaKeySystemAccess()</a></code></dt> + <dd>The returned object <em class="rfc2119" title="MAY">MAY</em> support and use this feature.</dd> + <dt>When returned by a <a href="#dom-mediakeysystemaccess" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemAccess</code></a> object</dt> + <dd>This value cannot and <em class="rfc2119" title="MUST NOT">MUST NOT</em> be present in such an object.</dd> + </dl> + </td></tr><tr><td><dfn data-dfn-for="mediakeysrequirement" data-dfn-type="dfn" id="dom-mediakeysrequirement-not-allowed" data-idl="" data-title="not-allowed"><code id="idl-def-MediaKeysRequirement.not-allowed">not-allowed</code></dfn></td><td> + <dl> + <dt>When used in a call to <code><a href="#dom-navigator-requestmediakeysystemaccess">requestMediaKeySystemAccess()</a></code></dt> + <dd>The returned object <em class="rfc2119" title="MUST">MUST</em> function without using this feature and <em class="rfc2119" title="MUST NOT">MUST NOT</em> use it at any time.</dd> + <dt>When returned by a <a href="#dom-mediakeysystemaccess" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemAccess</code></a> object</dt> + <dd>CDM instances created by the object <em class="rfc2119" title="MUST NOT">MUST NOT</em> use this feature.</dd> + </dl> + </td></tr></tbody></table></div> + + <div><div><pre class="def idl"><span class="idlDictionary" id="idl-def-mediakeysystemconfiguration" data-idl="" data-title="MediaKeySystemConfiguration">dictionary <span class="idlDictionaryID"><a data-no-default="" data-link-for="" data-lt="" href="#dom-mediakeysystemconfiguration" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemConfiguration</code></a></span> { +<span class="idlMember" id="idl-def-mediakeysystemconfiguration-label" data-idl="" data-title="label" data-dfn-for="mediakeysystemconfiguration"> <span class="idlMemberType"><a href="https://heycam.github.io/webidl/#idl-DOMString">DOMString</a></span> <span class="idlMemberName"><a data-no-default="" data-link-for="mediakeysystemconfiguration" data-lt="" href="#dom-mediakeysystemconfiguration-label" class="internalDFN" data-link-type="dfn"><code>label</code></a></span> = <span class="idlMemberValue">""</span>;</span> +<span class="idlMember" id="idl-def-mediakeysystemconfiguration-initdatatypes" data-idl="" data-title="initDataTypes" data-dfn-for="mediakeysystemconfiguration"> <span class="idlMemberType"><a href="https://heycam.github.io/webidl/#idl-sequence">sequence</a><<a href="https://heycam.github.io/webidl/#idl-DOMString">DOMString</a>></span> <span class="idlMemberName"><a data-no-default="" data-link-for="mediakeysystemconfiguration" data-lt="" href="#dom-mediakeysystemconfiguration-initdatatypes" class="internalDFN" data-link-type="dfn"><code>initDataTypes</code></a></span> = <span class="idlMemberValue">[]</span>;</span> +<span class="idlMember" id="idl-def-mediakeysystemconfiguration-audiocapabilities" data-idl="" data-title="audioCapabilities" data-dfn-for="mediakeysystemconfiguration"> <span class="idlMemberType"><a href="https://heycam.github.io/webidl/#idl-sequence">sequence</a><<a href="#dom-mediakeysystemmediacapability" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemMediaCapability</code></a>></span> <span class="idlMemberName"><a data-no-default="" data-link-for="mediakeysystemconfiguration" data-lt="" href="#dom-mediakeysystemconfiguration-audiocapabilities" class="internalDFN" data-link-type="dfn"><code>audioCapabilities</code></a></span> = <span class="idlMemberValue">[]</span>;</span> +<span class="idlMember" id="idl-def-mediakeysystemconfiguration-videocapabilities" data-idl="" data-title="videoCapabilities" data-dfn-for="mediakeysystemconfiguration"> <span class="idlMemberType"><a href="https://heycam.github.io/webidl/#idl-sequence">sequence</a><<a href="#dom-mediakeysystemmediacapability" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemMediaCapability</code></a>></span> <span class="idlMemberName"><a data-no-default="" data-link-for="mediakeysystemconfiguration" data-lt="" href="#dom-mediakeysystemconfiguration-videocapabilities" class="internalDFN" data-link-type="dfn"><code>videoCapabilities</code></a></span> = <span class="idlMemberValue">[]</span>;</span> +<span class="idlMember" id="idl-def-mediakeysystemconfiguration-distinctiveidentifier" data-idl="" data-title="distinctiveIdentifier" data-dfn-for="mediakeysystemconfiguration"> <span class="idlMemberType"><a href="#dom-mediakeysrequirement" class="internalDFN" data-link-type="dfn"><code>MediaKeysRequirement</code></a></span> <span class="idlMemberName"><a data-no-default="" data-link-for="mediakeysystemconfiguration" data-lt="" href="#dom-mediakeysystemconfiguration-distinctiveidentifier" class="internalDFN" data-link-type="dfn"><code>distinctiveIdentifier</code></a></span> = <span class="idlMemberValue">"optional"</span>;</span> +<span class="idlMember" id="idl-def-mediakeysystemconfiguration-persistentstate" data-idl="" data-title="persistentState" data-dfn-for="mediakeysystemconfiguration"> <span class="idlMemberType"><a href="#dom-mediakeysrequirement" class="internalDFN" data-link-type="dfn"><code>MediaKeysRequirement</code></a></span> <span class="idlMemberName"><a data-no-default="" data-link-for="mediakeysystemconfiguration" data-lt="" href="#dom-mediakeysystemconfiguration-persistentstate" class="internalDFN" data-link-type="dfn"><code>persistentState</code></a></span> = <span class="idlMemberValue">"optional"</span>;</span> +<span class="idlMember" id="idl-def-mediakeysystemconfiguration-sessiontypes" data-idl="" data-title="sessionTypes" data-dfn-for="mediakeysystemconfiguration"> <span class="idlMemberType"><a href="https://heycam.github.io/webidl/#idl-sequence">sequence</a><<a href="https://heycam.github.io/webidl/#idl-DOMString">DOMString</a>></span> <span class="idlMemberName"><a data-no-default="" data-link-for="mediakeysystemconfiguration" data-lt="" href="#dom-mediakeysystemconfiguration-sessiontypes" class="internalDFN" data-link-type="dfn"><code>sessionTypes</code></a></span>;</span> +};</span></pre></div> +<p> + The dictionary <dfn data-dfn-type="dfn" id="dom-mediakeysystemconfiguration" data-idl="" data-title="MediaKeySystemConfiguration" data-dfn-for=""><code>MediaKeySystemConfiguration</code></dfn> contains the following members: +</p> + <dl class="dictionary-members" data-dfn-for="MediaKeySystemConfiguration" data-link-for="MediaKeySystemConfiguration"><dt><dfn data-dfn-for="mediakeysystemconfiguration" data-dfn-type="dfn" id="dom-mediakeysystemconfiguration-label" data-idl="" data-title="label"><code>label</code></dfn> of type <span class="idlMemberType">DOMString</span>, defaulting to <code>""</code></dt><dd> + An optional label that will be preserved in the <a href="#dom-mediakeysystemconfiguration" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemConfiguration</code></a> returned from the <code><a href="#dom-mediakeysystemaccess-getconfiguration">getConfiguration()</a></code> method of <a href="#dom-mediakeysystemaccess" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemAccess</code></a>. + </dd><dt><dfn data-dfn-for="mediakeysystemconfiguration" data-dfn-type="dfn" id="dom-mediakeysystemconfiguration-initdatatypes" data-idl="" data-title="initDataTypes"><code>initDataTypes</code></dfn> of type <span class="idlMemberType">sequence<DOMString></span>, defaulting to <code>[]</code></dt><dd> + A list of supported <a href="#initialization-data-type">Initialization Data Type</a> names. + The <a href="#initialization-data-type">Initialization Data Type</a> capability of this object is considered supported if the list is empty or contains one or more values that are supported with all other members (as determined by the algorithm). + Values in the sequence <em class="rfc2119" title="MUST">MUST</em> not be the empty string. + </dd><dt><dfn data-dfn-for="mediakeysystemconfiguration" data-dfn-type="dfn" id="dom-mediakeysystemconfiguration-audiocapabilities" data-idl="" data-title="audioCapabilities"><code>audioCapabilities</code></dfn> of type <span class="idlMemberType">sequence<<a href="#dom-mediakeysystemmediacapability" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemMediaCapability</code></a>></span>, defaulting to <code>[]</code></dt><dd> + A list of supported audio type and capability pairs. + The audio capability of this object is considered supported if the list is empty or contains one or more values that are supported with all other members (as determined by the algorithm). + When there is a conflict between values, the earlier value will be selected. An empty list indicates that no audio capabilities are supported. + In this case, the <code><a href="#dom-mediakeysystemconfiguration-videocapabilities">videoCapabilities</a></code> element must not be empty. + </dd><dt><dfn data-dfn-for="mediakeysystemconfiguration" data-dfn-type="dfn" id="dom-mediakeysystemconfiguration-videocapabilities" data-idl="" data-title="videoCapabilities"><code>videoCapabilities</code></dfn> of type <span class="idlMemberType">sequence<<a href="#dom-mediakeysystemmediacapability" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemMediaCapability</code></a>></span>, defaulting to <code>[]</code></dt><dd> + A list of supported video type and capability pairs. + The video capability of this object is considered supported if the list is empty or contains one or more values that are supported with all other members (as determined by the algorithm). + When there is a conflict between values, the earlier value will be selected. An empty list indicates that no video capabilities are supported. + In this case, the <code><a href="#dom-mediakeysystemconfiguration-audiocapabilities">audioCapabilities</a></code> element must not be empty. + </dd><dt><dfn data-dfn-for="mediakeysystemconfiguration" data-dfn-type="dfn" id="dom-mediakeysystemconfiguration-distinctiveidentifier" data-idl="" data-title="distinctiveIdentifier"><code>distinctiveIdentifier</code></dfn> of type <span class="idlMemberType"><a href="#dom-mediakeysrequirement" class="internalDFN" data-link-type="dfn"><code>MediaKeysRequirement</code></a></span>, defaulting to <code>"optional"</code></dt><dd> + Whether use of a <a href="#distinctive-identifier">Distinctive Identifier(s)</a> is required. + <p>When this member is <code><a href="#idl-def-MediaKeysRequirement.not-allowed">"not-allowed"</a></code>, the implementation <em class="rfc2119" title="MUST NOT">MUST NOT</em> <a href="#uses-distinctive-identifiers-or-distinctive-permanent-identifiers">use Distinctive Identifier(s) or Distinctive Permanent Identifier(s)</a> for any operations associated with any object created from this configuration. </p> - <p>The remainder of this section applies to session types for which the <a href="#is-persistent-session-type">Is persistent session type?</a> algorithm returns <code>true</code>.</p> - <p>The CDM <em class="rfc2119" title="SHOULD NOT">SHOULD NOT</em> store session data, including the Session ID, until <code><a href="#dom-mediakeysession-update">update()</a></code> is called the first time. Specifically, the CDM <em class="rfc2119" - title="SHOULD NOT">SHOULD NOT</em> store session data during the <code><a href="#dom-mediakeysession-generaterequest">generateRequest()</a></code> algorithm. This ensures that the application is aware of the session and knows it needs - to eventually remove it. + </dd><dt><dfn data-dfn-for="mediakeysystemconfiguration" data-dfn-type="dfn" id="dom-mediakeysystemconfiguration-persistentstate" data-idl="" data-title="persistentState"><code>persistentState</code></dfn> of type <span class="idlMemberType"><a href="#dom-mediakeysrequirement" class="internalDFN" data-link-type="dfn"><code>MediaKeysRequirement</code></a></span>, defaulting to <code>"optional"</code></dt><dd> + Whether the ability to persist state is required. This includes session data and any other type of state. + <p>The CDM <em class="rfc2119" title="MUST NOT">MUST NOT</em> persist any state related to the application or <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> of this object's <a href="https://www.w3.org/TR/dom/#concept-document">Document</a> when this member is <code><a href="#idl-def-MediaKeysRequirement.not-allowed">"not-allowed"</a></code>.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-44" aria-level="4"><span>Note</span></div><p class="">For the purposes of this member, persistent state does not include persistent unique identifiers (<a href="#distinctive-identifier">Distinctive Identifiers</a>) controlled by the <a href="#key-system">Key System</a> implementation. <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> independently reflects this requirement.</p></div> + <p>Only <code><a href="#idl-def-MediaKeySessionType.temporary">"temporary"</a></code> sessions may be created when persistent state is not supported.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-45" aria-level="4"><span>Note</span></div><p class="">For <code><a href="#idl-def-MediaKeySessionType.temporary">"temporary"</a></code> sessions, the need and ability to store state is <a href="#key-system">Key System</a> implementation-specific and may vary by feature used.</p></div> + <div class="note"><div role="heading" class="note-title marker" id="h-note-46" aria-level="4"><span>Note</span></div><p class="">Applications intending to create non-<code><a href="#idl-def-MediaKeySessionType.temporary">"temporary"</a></code> sessions, should set this member to <code><a href="#idl-def-MediaKeysRequirement.required">"required"</a></code> when calling <code><a href="#dom-navigator-requestmediakeysystemaccess">requestMediaKeySystemAccess()</a></code>.</p></div> + </dd><dt><dfn data-dfn-for="mediakeysystemconfiguration" data-dfn-type="dfn" id="dom-mediakeysystemconfiguration-sessiontypes" data-idl="" data-title="sessionTypes"><code>sessionTypes</code></dfn> of type <span class="idlMemberType">sequence<DOMString></span></dt><dd> + A list of <a href="#dom-mediakeysessiontype" class="internalDFN" data-link-type="dfn"><code>MediaKeySessionType</code></a>s that must be supported. All values must be supported. + <p>If this member is <a href="https://heycam.github.io/webidl/#dfn-present">not present</a> [<cite><a class="bibref" href="#bib-WEBIDL">WEBIDL</a></cite>] when the dictionary is passed to <code><a href="#dom-navigator-requestmediakeysystemaccess">requestMediaKeySystemAccess()</a></code>, the dictionary will be treated as if this member is set to <code>[ <code><a href="#idl-def-MediaKeySessionType.temporary">"temporary"</a></code> ]</code>.</p> + </dd></dl> + + <p>Implementations <em class="rfc2119" title="SHOULD NOT">SHOULD NOT</em> add members to this dictionary. + Should member(s) be added, they <em class="rfc2119" title="MUST">MUST</em> be of type <a href="#dom-mediakeysrequirement" class="internalDFN" data-link-type="dfn"><code>MediaKeysRequirement</code></a>, and it is <em class="rfc2119" title="RECOMMENDED">RECOMMENDED</em> that they have default values of <code><a href="#idl-def-MediaKeysRequirement.optional">"optional"</a></code> to support the widest range of application and client combinations. + </p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-47" aria-level="4"><span>Note</span></div><p class="">Dictionary members not recognized by a user agent implementation are ignored per [<cite><a class="bibref" href="#bib-WEBIDL">WEBIDL</a></cite>] and will not be considered in the <code><a href="#dom-navigator-requestmediakeysystemaccess">requestMediaKeySystemAccess()</a></code> algorithm. + Should an application use non-standard dictionary member(s), it <em class="rfc2119" title="MUST NOT">MUST NOT</em> rely on user agent implementations rejecting a configuration that includes such dictionary members. + </p></div> + <p>This dictionary <em class="rfc2119" title="MUST NOT">MUST NOT</em> be used to pass state or data to the CDM.</p> + + </div></section> + + <section id="mediakeysystemmediacapability-dictionary"> + <h3 id="x3-3-mediakeysystemmediacapability-dictionary"><span class="secno">3.3 </span><dfn data-dfn-type="dfn" id="dom-mediakeysystemmediacapability" data-idl="" data-title="MediaKeySystemMediaCapability" data-dfn-for=""><code>MediaKeySystemMediaCapability</code></dfn> dictionary</h3> + <div><div><pre class="def idl"><span class="idlDictionary" id="idl-def-mediakeysystemmediacapability" data-idl="" data-title="MediaKeySystemMediaCapability">dictionary <span class="idlDictionaryID"><a data-no-default="" data-link-for="" data-lt="" href="#dom-mediakeysystemmediacapability" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemMediaCapability</code></a></span> { +<span class="idlMember" id="idl-def-mediakeysystemmediacapability-contenttype" data-idl="" data-title="contentType" data-dfn-for="mediakeysystemmediacapability"> <span class="idlMemberType"><a href="https://heycam.github.io/webidl/#idl-DOMString">DOMString</a></span> <span class="idlMemberName"><a data-no-default="" data-link-for="mediakeysystemmediacapability" data-lt="" href="#dom-mediakeysystemmediacapability-contenttype" class="internalDFN" data-link-type="dfn"><code>contentType</code></a></span> = <span class="idlMemberValue">""</span>;</span> +<span class="idlMember" id="idl-def-mediakeysystemmediacapability-robustness" data-idl="" data-title="robustness" data-dfn-for="mediakeysystemmediacapability"> <span class="idlMemberType"><a href="https://heycam.github.io/webidl/#idl-DOMString">DOMString</a></span> <span class="idlMemberName"><a data-no-default="" data-link-for="mediakeysystemmediacapability" data-lt="" href="#dom-mediakeysystemmediacapability-robustness" class="internalDFN" data-link-type="dfn"><code>robustness</code></a></span> = <span class="idlMemberValue">""</span>;</span> +};</span></pre></div><section><h4 id="dictionary-mediakeysystemmediacapability-members">Dictionary <a class="idlType internalDFN" href="#dom-mediakeysystemmediacapability" data-link-type="dfn"><code>MediaKeySystemMediaCapability</code></a> Members</h4><dl class="dictionary-members" data-dfn-for="MediaKeySystemMediaCapability" data-link-for="MediaKeySystemMediaCapability"><dt><dfn data-dfn-for="mediakeysystemmediacapability" data-dfn-type="dfn" id="dom-mediakeysystemmediacapability-contenttype" data-idl="" data-title="contentType"><code>contentType</code></dfn> of type <span class="idlMemberType">DOMString</span>, defaulting to <code>""</code></dt><dd> + <p> + The type of the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-resource">media resource</a>. + Its value must be a <a href="#valid-media-mime-type">valid media MIME type</a>. + The empty string is invalid. </p> - <p><em>All</em> data associated with a session <em class="rfc2119" title="MUST">MUST</em> be cleared when the session is cleared, such as in <code><a href="#dom-mediakeysession-update">update()</a></code> when processing a <a href="#record-of-license-destruction">record of license destruction</a> acknowledgement or <a href="#record-of-key-usage">record of key usage</a> acknowledgement. See <a href="#persistent-state-requirements">Persistent Data</a>. + </dd><dt><dfn data-dfn-for="mediakeysystemmediacapability" data-dfn-type="dfn" id="dom-mediakeysystemmediacapability-robustness" data-idl="" data-title="robustness"><code>robustness</code></dfn> of type <span class="idlMemberType">DOMString</span>, defaulting to <code>""</code></dt><dd> + <p> + The robustness level associated with the content type. + The empty string indicates that any ability to decrypt and decode the content type is acceptable. </p> - <p>The CDM <em class="rfc2119" title="MUST">MUST</em> ensure that data for a given session is only present in one <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object that is not - <a href="#media-key-session-closed">closed</a> in any <a href="https://www.w3.org/TR/dom/#concept-document">Document</a>. In other words, <code><a href="#dom-mediakeysession-load">load()</a></code> <em class="rfc2119" title="MUST">MUST</em> fail when there is already a <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> representing the session specified by the <var>sessionId</var> parameter, either because the object that - created it via <code><a href="#dom-mediakeysession-generaterequest">generateRequest()</a></code> is still active or it has been loaded into another object via <code><a href="#dom-mediakeysession-load">load()</a></code>. A session <em class="rfc2119" - title="MAY">MAY</em> only be loaded again if all objects that have ever represented it are <a href="#media-key-session-closed">closed</a>. + <div class="note"><div role="heading" class="note-title marker" id="h-note-48" aria-level="5"><span>Note</span></div><div class=""> + <p> + Implementations <em class="rfc2119" title="MUST">MUST</em> configure the CDM to support at least the robustness levels specified in the configuration of the MediaKeySystemAccess object used to create the MediaKeys object. + Exact configuration of the CDM is implementation-specific, and implementations <em class="rfc2119" title="MAY">MAY</em> configure the CDM to use the highest robustness level in the configuration even if a higher robustness level is available. + If only the empty string is specified, implementations <em class="rfc2119" title="MAY">MAY</em> be configured to use the lowest robustness level the implementation supports. </p> - <p>An application that creates a session using a type for which the <a href="#is-persistent-session-type">Is persistent session type?</a> algorithm returns <code>true</code> <em class="rfc2119" title="SHOULD">SHOULD</em> later remove the stored - data by first initiating the removal process using <code><a href="#dom-mediakeysession-remove">remove()</a></code> and then ensuring that the removal process, which may involve message exchange(s), successfully completes. The CDM <em class="rfc2119" - title="MAY">MAY</em> also remove sessions as appropriate, but applications <em class="rfc2119" title="SHOULD NOT">SHOULD NOT</em> rely on this. + <p> + Applications <em class="rfc2119" title="SHOULD">SHOULD</em> specify the robustness level(s) they require to avoid unexpected client incompatibilities. </p> - <p>See <a href="#security" class="sec-ref"><span class="secno">10.</span> <span class="sec-title">Security</span></a> and <a href="#privacy" class="sec-ref"><span class="secno">11.</span> <span class="sec-title">Privacy</span></a> for additional - considerations when supporting persistent storage.</p> - </section> - </section> + </div></div></dd></dl></section></div> - <section id="htmlmediaelement-extensions"> - <!--OddPage--> - <h2 id="x7.-htmlmediaelement-extensions"><span class="secno">7. </span><dfn data-dfn-for="" data-dfn-type="dfn" id="dom-htmlmediaelement" data-idl="" data-title="HTMLMediaElement"><code>HTMLMediaElement</code></dfn> Extensions</h2> + <p>In order for the capability represented by this object to be considered supported, <code><a href="#dom-mediakeysystemmediacapability-contenttype">contentType</a></code> <em class="rfc2119" title="MUST NOT">MUST NOT</em> be the empty string and its entire value, including all codecs, <em class="rfc2119" title="MUST">MUST</em> be supported with <code><a href="#dom-mediakeysystemmediacapability-robustness">robustness</a></code>.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-49" aria-level="4"><span>Note</span></div><p class="">If any of a set of codecs is acceptable, use a separate instances of this dictionary for each codec.</p></div> + </section> + </section> - <!-- Put all the monkey-patching here --> - <p>This section specifies additions to and modifications of the <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#htmlmediaelement-htmlmediaelement">HTMLMediaElement</a></code> [<cite><a class="bibref" href="#bib-HTML51">HTML51</a></cite>] - when the Encrypted Media Extensions are supported.</p> - <p>The following internal values are added to the <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#htmlmediaelement-htmlmediaelement">HTMLMediaElement</a></code>:</p> - <ul> - <li> - <p><var>attaching media keys</var>, which <em class="rfc2119" title="SHALL">SHALL</em> have a boolean value, and</p> - </li> - <li> - <p><var>encrypted block queue</var>, which <em class="rfc2119" title="SHALL">SHALL</em> be a queue of encrypted blocks awaiting decryption, and</p> - </li> - <li> - <p><var>decryption blocked waiting for key</var>, which <em class="rfc2119" title="SHALL">SHALL</em> have a boolean value.</p> - </li> - <li> - <p><var>playback blocked waiting for key</var>, which <em class="rfc2119" title="SHALL">SHALL</em> have a boolean value.</p> - </li> - </ul> - <p>The following modifications are made to the behaviour of the <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#htmlmediaelement-htmlmediaelement">HTMLMediaElement</a></code>:</p> - <ul> - <li> - <p>When a <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#htmlmediaelement-htmlmediaelement">HTMLMediaElement</a></code> is created, its <var>attaching media keys</var> value <em class="rfc2119" title="SHALL">SHALL</em> be initialized to <code>false</code>, its <var>encrypted block queue</var> value <em class="rfc2119" title="SHALL">SHALL</em> be empty, its <var>decryption blocked waiting for key</var> value <em class="rfc2119" title="SHALL">SHALL</em> be initialized to <code>false</code>, and its <var>playback blocked waiting for key</var> value <em class="rfc2119" title="SHALL">SHALL</em> be initialized to <code>false</code>.</p> - </li> + <section id="mediakeysystemaccess-interface"> + <!--OddPage--><h2 id="x4-mediakeysystemaccess-interface"><span class="secno">4. </span><dfn data-dfn-type="dfn" id="dom-mediakeysystemaccess" data-idl="" data-title="MediaKeySystemAccess" data-dfn-for=""><code>MediaKeySystemAccess</code></dfn> Interface</h2> + <p>The MediaKeySystemAccess object provides access to a <a href="#key-system">Key System</a>.</p> + + <div><div><pre class="def idl"><span class="idlInterface" id="idl-def-mediakeysystemaccess" data-idl="" data-title="MediaKeySystemAccess">[<span class="extAttr"><span class="extAttrName"><a href="https://heycam.github.io/webidl/#SecureContext">SecureContext</a></span></span>] +interface <span class="idlInterfaceID"><a data-no-default="" data-link-for="" data-lt="" href="#dom-mediakeysystemaccess" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemAccess</code></a></span> { +<span class="idlAttribute" id="idl-def-mediakeysystemaccess-keysystem" data-idl="" data-title="keySystem" data-dfn-for="mediakeysystemaccess"> readonly attribute <span class="idlAttrType"><a href="https://heycam.github.io/webidl/#idl-DOMString">DOMString</a></span> <span class="idlAttrName"><a data-no-default="" data-link-for="mediakeysystemaccess" data-lt="" href="#dom-mediakeysystemaccess-keysystem" class="internalDFN" data-link-type="dfn"><code>keySystem</code></a></span>;</span> +<span class="idlMethod" id="idl-def-mediakeysystemaccess-getconfiguration" data-idl="" data-title="getConfiguration" data-dfn-for="mediakeysystemaccess"> <span class="idlMethType"><a href="#dom-mediakeysystemconfiguration" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemConfiguration</code></a></span> <span class="idlMethName"><a data-no-default="" data-link-for="mediakeysystemaccess" data-lt="getConfiguration|getconfiguration()" href="#dom-mediakeysystemaccess-getconfiguration" class="internalDFN" data-link-type="dfn"><code>getConfiguration</code></a></span>();</span> +<span class="idlMethod" id="idl-def-mediakeysystemaccess-createmediakeys" data-idl="" data-title="createMediaKeys" data-dfn-for="mediakeysystemaccess"> <span class="idlMethType"><a href="https://heycam.github.io/webidl/#idl-promise">Promise</a><<a href="#dfn-mediakeys" class="internalDFN" data-link-type="dfn">MediaKeys</a>></span> <span class="idlMethName"><a data-no-default="" data-link-for="mediakeysystemaccess" data-lt="createMediaKeys|createmediakeys()" href="#dom-mediakeysystemaccess-createmediakeys" class="internalDFN" data-link-type="dfn"><code>createMediaKeys</code></a></span>();</span> +};</span></pre></div><section><h3 id="attributes">Attributes</h3><dl class="attributes" data-dfn-for="MediaKeySystemAccess" data-link-for="MediaKeySystemAccess"><dt><dfn data-dfn-for="mediakeysystemaccess" data-dfn-type="dfn" id="dom-mediakeysystemaccess-keysystem" data-idl="" data-title="keySystem"><code>keySystem</code></dfn> of type <span class="idlAttrType">DOMString</span>, readonly </dt><dd> + Identifies the <a href="#key-system">Key System</a> being used. + </dd></dl></section><section><h3 id="methods-0">Methods</h3><dl class="methods" data-dfn-for="MediaKeySystemAccess" data-link-for="MediaKeySystemAccess"><dt><dfn data-dfn-for="mediakeysystemaccess" data-dfn-type="dfn" id="dom-mediakeysystemaccess-getconfiguration" data-idl="" data-title="getConfiguration" data-lt="getConfiguration|getconfiguration()"><code id="getConfiguration">getConfiguration</code></dfn></dt><dd> + <p>Returns the supported combination of configuration options selected by the <code><a href="#dom-navigator-requestmediakeysystemaccess">requestMediaKeySystemAccess()</a></code> algorithm. + </p> + <p>The returned object is a non-strict subset (plus any implied defaults) of the first satisfiable <a href="#dom-mediakeysystemconfiguration" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemConfiguration</code></a> configuration passed to the <code><a href="#dom-navigator-requestmediakeysystemaccess">requestMediaKeySystemAccess()</a></code> call that returned the promise that was resolved with this object. + It does not contain values capabilities not specified in that single configuration (other than implied defaults) and thus may not reflect all capabilities of the <a href="#key-system">Key System</a> implementation. + All values in the configuration may be used in any combination. + Members of type <a href="#dom-mediakeysrequirement" class="internalDFN" data-link-type="dfn"><code>MediaKeysRequirement</code></a> reflect whether the capability is required for any combination. They will not have the value <code><a href="#idl-def-MediaKeysRequirement.optional">"optional"</a></code>. + </p> + + + <div><em>No parameters.</em></div><div><em>Return type: </em><code>MediaKeySystemConfiguration</code></div><p>When this method is invoked, the user agent must run the following steps:</p><ol class="method-algorithm"> <li> - <p>When the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#current-position">current playback position</a> is changed other than advancing in the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#direction-of-playback">direction of playback</a> as part of normal playback, the <var>encrypted block queue</var> value <em class="rfc2119" title="SHALL">SHALL</em> be empty, the <var>decryption blocked waiting for key</var> value <em class="rfc2119" title="SHALL">SHALL</em> be initialized - to <code>false</code>, and the <var>playback blocked waiting for key</var> value <em class="rfc2119" title="SHALL">SHALL</em> be set to <code>false</code>.</p> - <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note97"><span>Note</span></div> - <p class=""> - In other words, these values should be reset when, for example, <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#loading-the-media-resource">loading the media resource</a> or <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#seeking">seeking</a>. - </p> - </div> + <p> + Return this object's <var>configuration</var> value. + </p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-50" aria-level="4"><span>Note</span></div><p class=""> + This results in a new object being created and initialized from <var>configuration</var> each time this method is called. + </p></div> </li> - <li> - <p>In addition to the criteria specified in [<cite><a class="bibref" href="#bib-HTML51">HTML51</a></cite>], an <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#htmlmediaelement-htmlmediaelement">HTMLMediaElement</a></code> <em class="rfc2119" title="SHALL">SHALL</em> be considered a <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#blocked-media-element">blocked media element</a> if its <var>playback blocked waiting for key</var> value is <code>true</code>.</p> + </ol></dd><dt><dfn data-dfn-for="mediakeysystemaccess" data-dfn-type="dfn" id="dom-mediakeysystemaccess-createmediakeys" data-idl="" data-title="createMediaKeys" data-lt="createMediaKeys|createmediakeys()"><code id="createMediaKeys">createMediaKeys</code></dfn></dt><dd> + <p>Creates a new <a href="#dfn-mediakeys" class="internalDFN" data-link-type="dfn">MediaKeys</a> object for <var>keySystem</var>.</p> + + + <div><em>No parameters.</em></div><div><em>Return type: </em><code>Promise<MediaKeys></code></div><p>When this method is invoked, the user agent must run the following steps:</p><ol class="method-algorithm"> + <li><p>Let <var>promise</var> be a new promise.</p></li> + <li><p>Run the following steps in parallel:</p> + <ol> + <li><p>Let <var>configuration</var> be the value of this object's <var>configuration</var> value.</p></li> + <li> + <p> + Let <var>use distinctive identifier</var> be <code>true</code> if the value of <var>configuration</var>'s <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> + member is <code><a href="#idl-def-MediaKeysRequirement.required">"required"</a></code> and <code>false</code> otherwise. + </p> + </li> + <li> + <p> + Let <var>persistent state allowed</var> be <code>true</code> if the value of <var>configuration</var>'s <code><a href="#dom-mediakeysystemconfiguration-persistentstate">persistentState</a></code> + member is <code><a href="#idl-def-MediaKeysRequirement.required">"required"</a></code> and <code>false</code> otherwise. + </p><p> + </p></li> + <li><p>Load and initialize the <a href="#key-system">Key System</a> implementation represented by this object's <var>cdm implementation</var> value if necessary.</p></li> + <li><p>Let <var>instance</var> be a new instance of the <a href="#key-system">Key System</a> implementation represented by this object's <var>cdm implementation</var> value.</p></li> + <li><p>Initialize <var>instance</var> to enable, disable and/or select <a href="#key-system">Key System</a> features using <var>configuration</var>.</p></li> + <li><p>If <var>use distinctive identifier</var> is <code>false</code>, prevent <var>instance</var> from <a href="#uses-distinctive-identifiers-or-distinctive-permanent-identifiers">using Distinctive Identifier(s) and Distinctive Permanent Identifier(s)</a>.</p></li> + <li><p>If <var>persistent state allowed</var> is <code>false</code>, prevent <var>instance</var> from persisting any state related to the application or <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> of this object's <a href="https://www.w3.org/TR/dom/#concept-document">Document</a>.</p></li> + <li><p>If any of the preceding steps failed, reject <var>promise</var> with a new <code><a href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code> whose name is the appropriate <a href="#error-names">error name</a>.</p></li> + <li><p>Let <var>media keys</var> be a new <a href="#dfn-mediakeys" class="internalDFN" data-link-type="dfn">MediaKeys</a> object, and initialize it as follows:</p> + <ol> + <li><p>Let the <var>use distinctive identifier</var> value be <var>use distinctive identifier</var>.</p></li> + <li><p>Let the <var>persistent state allowed</var> value be <var>persistent state allowed</var>.</p></li> + <li><p>Let the <var>supported session types</var> value be be the value of <var>configuration</var>'s <code><a href="#dom-mediakeysystemconfiguration-sessiontypes">sessionTypes</a></code> member.</p></li> + <li><p>Let the <var>cdm implementation</var> value be this object's <var>cdm implementation</var> value.</p></li> + <li><p>Let the <var>cdm instance</var> value be <var>instance</var>.</p></li> + </ol> + </li> + <li><p>Resolve <var>promise</var> with <var>media keys</var>.</p></li> + </ol> </li> + <li><p>Return <var>promise</var>.</p></li> + </ol></dd></dl></section></div> + </section> + + + <section id="mediakeys-interface"> + <!--OddPage--><h2 id="x5-mediakeys-interface"><span class="secno">5. </span><dfn data-dfn-type="dfn" id="dfn-mediakeys">MediaKeys</dfn> Interface</h2> + <p>The MediaKeys object represents a set of keys that an associated HTMLMediaElement can use for decryption of <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a> during playback. + It also represents a <a href="#cdm">CDM</a> instance. + </p> + <p>A <a href="#dfn-mediakeys" class="internalDFN" data-link-type="dfn">MediaKeys</a> object may be destroyed by the user agent when it is no longer accessible</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-51" aria-level="3"><span>Note</span></div><p class="">For example, when there are no script references and no attached media element.</p></div> + <p>For methods that return a promise, all errors are reported asynchronously by rejecting the returned Promise. This includes [<cite><a class="bibref" href="#bib-WEBIDL">WEBIDL</a></cite>] type mapping errors.</p> + <p>The steps of an algorithm are always aborted when rejecting a promise.</p> + + <div><div><pre class="def idl"><span class="idlEnum" id="idl-def-mediakeysessiontype" data-idl="" data-title="MediaKeySessionType">enum <span class="idlEnumID"><a data-no-default="" data-link-for="" data-lt="" href="#dom-mediakeysessiontype" class="internalDFN" data-link-type="dfn"><code>MediaKeySessionType</code></a></span> { + <a href="#dom-mediakeysessiontype-temporary" class="idlEnumItem">"temporary"</a>, + <a href="#dom-mediakeysessiontype-persistent-license" class="idlEnumItem">"persistent-license"</a>, + <a href="#dom-mediakeysessiontype-persistent-usage-record" class="idlEnumItem">"persistent-usage-record"</a> +};</span></pre></div> + <p>The <dfn data-dfn-type="dfn" id="dom-mediakeysessiontype" data-idl="" data-title="MediaKeySessionType" data-dfn-for=""><code>MediaKeySessionType</code></dfn> enumeration is defined as follows:</p> + <table class="simple" data-dfn-for="MediaKeySessionType" data-link-for="MediaKeySessionType"><tbody> + <tr><th colspan="2">Enumeration description</th></tr> + <tr><td><dfn data-dfn-for="mediakeysessiontype" data-dfn-type="dfn" id="dom-mediakeysessiontype-temporary" data-idl="" data-title="temporary"><code id="idl-def-MediaKeySessionType.temporary">temporary</code></dfn></td><td> + <p> + A session for which the license, key(s) and record of or data related to the session are not persisted. + </p> + <p> + The application need not worry about managing such storage. + Support for this session type is <em class="rfc2119" title="REQUIRED">REQUIRED</em>. + </p> + </td></tr> + <tr><td><dfn data-dfn-for="mediakeysessiontype" data-dfn-type="dfn" id="dom-mediakeysessiontype-persistent-license" data-idl="" data-title="persistent-license"><code id="idl-def-MediaKeySessionType.persistent-license">persistent-license</code></dfn></td><td> + <p> + A session for which the license (and potentially other data related to the session) will be persisted. + A <a href="#record-of-license-destruction">record of license destruction</a> <em class="rfc2119" title="SHALL">SHALL</em> be persisted when the license and key(s) it contains are destroyed. + The <dfn id="record-of-license-destruction" data-dfn-type="dfn">record of license destruction</dfn> is a <a href="#key-system">Key System</a>-specific attestation that the license and key(s) it contains are no longer usable by the client. + Support for this session type is <em class="rfc2119" title="OPTIONAL">OPTIONAL</em>. + </p> + <p> + Sessions of this type can only be created if the configuration associated with the <a href="#dom-mediakeysystemaccess" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemAccess</code></a> object that created this object has a <code><a href="#dom-mediakeysystemconfiguration-persistentstate">persistentState</a></code> value of <code><a href="#idl-def-MediaKeysRequirement.required">"required"</a></code>. + The session <em class="rfc2119" title="MUST">MUST</em> be loadable via its <a href="#session-id">Session ID</a> once <code><a href="#dom-mediakeysession-update">update()</a></code> is called successfully. + A <code><a href="#dom-evt-message">message</a></code> of type <code><a href="#idl-def-MediaKeyMessageType.license-release">"license-release"</a></code> containing the <a href="#record-of-license-destruction">record of license destruction</a> will be generated when <code><a href="#dom-mediakeysession-remove">remove()</a></code> is called until the record is acknowledged by a response passed to <code><a href="#dom-mediakeysession-update">update()</a></code>. + </p> + <p> + The application is responsible for ensuring that data persisted for such sessions is removed when the application no longer needs it. + See <a href="#session-storage">Session Storage and Persistence</a>. + </p> + </td></tr> + <tr><td><dfn data-dfn-for="mediakeysessiontype" data-dfn-type="dfn" id="dom-mediakeysessiontype-persistent-usage-record" data-idl="" data-title="persistent-usage-record"><code id="idl-def-MediaKeySessionType.persistent-usage-record">persistent-usage-record</code></dfn></td><td> + <p> + A session for which the license and key(s) are not persisted and for which a <a href="#record-of-key-usage">record of key usage</a> is persisted when + the keys available within the session are destroyed. + The <dfn id="record-of-key-usage" data-dfn-type="dfn">record of key usage</dfn> consists of: + </p> + <ul> <li> - <p>When the user agent is ready to begin playback and has encountered an indication that the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a> may contain encrypted blocks during the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#resource-fetch-algorithm">resource fetch algorithm</a>, - the user agent <em class="rfc2119" title="SHALL">SHALL</em> run the <a href="#media-may-contain-encrypted-blocks">Media Data May Contain Encrypted Blocks</a> algorithm.</p> - <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note98"><span>Note</span></div> - <p class=""> - For some container formats, such indication is separate from <a href="#initialization-data">Initialization Data</a>. - </p> - </div> - <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note99"><span>Note</span></div> - <p class=""> - The algorithm is to be run after parsing the relevant container data, including running the <a href="#initdata-encountered">Initialization Data Encountered</a> algorithm, but before decoding starts. - </p> - </div> + <p>A record of the <a href="#decryption-key-id">key IDs</a> of all the key(s) that were at any time <a href="#known-key">known</a> to the session,</p> </li> <li> - <p>When the user agent encounters <a href="#initialization-data">Initialization Data</a> in the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a> during the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#resource-fetch-algorithm">resource fetch algorithm</a>, - the user agent <em class="rfc2119" title="SHALL">SHALL</em> run the <a href="#initdata-encountered">Initialization Data Encountered</a> algorithm.</p> - <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note100"><span>Note</span></div> - <p class=""> - Some container formats may support encrypted media data that does not contain <a href="#initialization-data">Initialization Data</a> and thus support media data that does not trigger this algorithm. - </p> - </div> + <p> + <var>first decryption time</var> - The <dfn id="first-decryption-time" data-dfn-type="dfn">first decryption time</dfn>, defined as the time at which the session was first used to decrypt content, accurate to <var><var><a href="#key-usage-accuracy">key usage accuracy</a></var></var> and + </p> </li> <li> - <p>For each block of encrypted <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a> encountered during the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#resource-fetch-algorithm">resource fetch algorithm</a>, - the user agent <em class="rfc2119" title="SHALL">SHALL</em> run the <a href="#encrypted-block-encountered">Encrypted Block Encountered</a> algorithm in the order the encrypted blocks were encountered.</p> - <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note101"><span>Note</span></div> - <p class="">The above step provides flexibility for user agent implementations to perform decryption at any time after an encrypted block is encountered before it is needed for playback.</p> - </div> + <p> + <var>latest decryption time</var> - The <dfn id="latest-decryption-time" data-dfn-type="dfn">latest decryption time</dfn>, defined as the latest time at which the session was used to decrypt content, accurate to <var><var><a href="#key-usage-accuracy">key usage accuracy</a></var></var>. + </p> </li> - <li> - <p>When one of the following occurs while the <var>decryption blocked waiting for key</var> value is <code>true</code>, the user agent <em class="rfc2119" title="SHALL">SHALL</em> run the <a href="#wait-for-key">Wait for Key</a> algorithm.</p> - <ul> - <li> - <p>The user agent cannot advance the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#current-position">current playback position</a> in the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#direction-of-playback">direction of playback</a>.</p> - </li> - <li> - <p>The user agent cannot provide data for the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#current-position">current playback position</a>.</p> - <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note102"><span>Note</span></div> - <p class="">For example, at the beginning of playback or after <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#seeking">seeking</a>.</p> - </div> - </li> - </ul> + </ul> + <p> + A <code><a href="#dom-evt-message">message</a></code> of type <code><a href="#idl-def-MediaKeyMessageType.license-release">"license-release"</a></code> containing the <a href="#record-of-key-usage">record of key usage</a> will be generated each time <code><a href="#dom-mediakeysession-remove">remove()</a></code> is called, until the record is acknowledged by a response passed to <code><a href="#dom-mediakeysession-update">update()</a></code>. + </p> + <p> + The <dfn id="key-usage-accuracy" data-dfn-type="dfn"><var>key usage accuracy</var></dfn> is implementation-dependant but <em class="rfc2119" title="SHALL NOT">SHALL NOT</em> be greater than 60 seconds. + </p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-52" aria-level="3"><span>Note</span></div><p class=""> + Because the license and keys are not persisted, this record implicitly proves that the keys are no longer available in the session. + </p></div> + <div class="note"><div role="heading" class="note-title marker" id="h-note-53" aria-level="3"><span>Note</span></div><p class=""> + User agents <em class="rfc2119" title="MAY">MAY</em> implement this mechanism by means other than persisting data on key destruction - for example by persisting data during playback which is later used + to infer the fact of key destruction - provided the observable behavior is compliant to this specification. + </p></div> + <p> + The session <em class="rfc2119" title="MUST">MUST</em> be loadable via its <a href="#session-id">Session ID</a> once <code><a href="#dom-mediakeysession-update">update()</a></code> is called successfully. + The application is responsible for managing any such storage that may be generated by the CDM. + See <a href="#session-storage">Session Storage and Persistence</a>. + Can only be created if the configuration associated with the <a href="#dom-mediakeysystemaccess" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemAccess</code></a> object that created this object has a <code><a href="#dom-mediakeysystemconfiguration-persistentstate">persistentState</a></code> value of <code><a href="#idl-def-MediaKeysRequirement.required">"required"</a></code>. + Support for this session type is <em class="rfc2119" title="OPTIONAL">OPTIONAL</em>. + </p> + </td></tr> + </tbody></table></div> + + <div><div><pre class="def idl"><span class="idlInterface" id="idl-def-mediakeys" data-idl="" data-title="MediaKeys">[<span class="extAttr"><span class="extAttrName"><a href="https://heycam.github.io/webidl/#SecureContext">SecureContext</a></span></span>] +interface <span class="idlInterfaceID">MediaKeys</span> { +<span class="idlMethod" id="idl-def-mediakeys-createsession-sessiontype" data-idl="" data-title="createSession" data-dfn-for="mediakeys"> <span class="idlMethType"><a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a></span> <span class="idlMethName"><a data-no-default="" data-link-for="mediakeys" data-lt="createSession|createsession()" href="#dom-mediakeys-createsession" class="internalDFN" data-link-type="dfn"><code>createSession</code></a></span>(<span class="idlParam">optional <span class="idlParamType"><a href="#dom-mediakeysessiontype" class="internalDFN" data-link-type="dfn"><code>MediaKeySessionType</code></a></span> <span class="idlParamName">sessionType</span> = <span class="idlDefaultValue">"temporary"</span></span>);</span> +<span class="idlMethod" id="idl-def-mediakeys-setservercertificate-servercertificate" data-idl="" data-title="setServerCertificate" data-dfn-for="mediakeys"> <span class="idlMethType"><a href="https://heycam.github.io/webidl/#idl-promise">Promise</a><<a href="https://heycam.github.io/webidl/#idl-boolean">boolean</a>></span> <span class="idlMethName"><a data-no-default="" data-link-for="mediakeys" data-lt="setServerCertificate|setservercertificate()" href="#dom-mediakeys-setservercertificate" class="internalDFN" data-link-type="dfn"><code>setServerCertificate</code></a></span>(<span class="idlParam"><span class="idlParamType">BufferSource</span> <span class="idlParamName">serverCertificate</span></span>);</span> +};</span></pre></div><section><h3 id="methods-1">Methods</h3><dl class="methods" data-dfn-for="MediaKeys" data-link-for="MediaKeys"><dt><dfn data-dfn-for="mediakeys" data-dfn-type="dfn" id="dom-mediakeys-createsession" data-idl="" data-title="createSession" data-lt="createSession|createsession()"><code id="createSession">createSession</code></dfn></dt><dd> + <p>Returns a new <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object.</p> + + + + + <table class="parameters"><tbody><tr><th>Parameter</th><th>Type</th><th>Nullable</th><th>Optional</th><th>Description</th></tr><tr><td class="prmName">sessionType</td><td class="prmType"><code>MediaKeySessionType = "temporary"</code></td><td class="prmNullFalse"><span role="img" aria-label="False">✘</span></td><td class="prmOptTrue"><span role="img" aria-label="True">✔</span></td><td class="prmDesc"> + The type of session to create. The session type affects the behavior of the returned object. + </td></tr></tbody></table><div><em>Return type: </em><code>MediaKeySession</code></div><p>When this method is invoked, the user agent must run the following steps:</p><ol class="method-algorithm"> + <li><p>If this object's <var>supported session types</var> value does not contain <var>sessionType</var>, <a href="https://heycam.github.io/webidl/#dfn-throw">throw</a> [<cite><a class="bibref" href="#bib-WEBIDL">WEBIDL</a></cite>] a <code><a href="#dfn-NotSupportedError">NotSupportedError</a></code>.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-54" aria-level="4"><span>Note</span></div><p class=""><var>sessionType</var> values for which the <a href="#is-persistent-session-type">Is persistent session type?</a> algorithm returns <code>true</code> will fail if this object's <var>persistent state allowed</var> value is <code>false</code>.</p></div> </li> + <li><p>If the implementation does not support <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> operations in the current state, <a href="https://heycam.github.io/webidl/#dfn-throw">throw</a> [<cite><a class="bibref" href="#bib-WEBIDL">WEBIDL</a></cite>] an <code><a href="#dfn-InvalidStateError">InvalidStateError</a></code>.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-55" aria-level="4"><span>Note</span></div><p class="">Some implementations are unable to execute <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> algorithms until this <a href="#dfn-mediakeys" class="internalDFN" data-link-type="dfn">MediaKeys</a> object is associated with a media element using <code><a href="#dom-htmlmediaelement-setmediakeys">setMediaKeys()</a></code>. + This step enables applications to detect this uncommon behavior before attempting to perform such operations. + </p></div> + </li> + <li><p>Let <var>session</var> be a new <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object, and initialize it as follows:</p> + <ol> + <li><p>Let the <code><a href="#dom-mediakeysession-sessionid">sessionId</a></code> attribute be the empty string.</p></li> + <li><p>Let the <code><a href="#dom-mediakeysession-expiration">expiration</a></code> attribute be <code>NaN</code>.</p></li> + <li><p>Let the <code><a href="#dom-mediakeysession-closed">closed</a></code> attribute be a new promise.</p></li> + <li><p>Let <var>key status</var> be a new empty <a href="#dom-mediakeystatusmap" class="internalDFN" data-link-type="dfn"><code>MediaKeyStatusMap</code></a> object, and initialize it as follows:</p> + <ol> + <li><p>Let the <code><a href="#dom-mediakeystatusmap-size">size</a></code> attribute be 0.</p></li> + </ol> + </li> + <li><p>Let the <var>session type</var> value be <var>sessionType</var>.</p></li> + <li><p>Let the <var>uninitialized</var> value be true.</p></li> + <li><p>Let the <var>callable</var> value be false.</p></li> + <li><p>Let the <var>closing or closed</var> value be false.</p></li> + <li><p>Let the <var>use distinctive identifier</var> value be this object's <var>use distinctive identifier</var> value.</p></li> + <li><p>Let the <var>cdm implementation</var> value be this object's <var>cdm implementation</var>.</p></li> + <li><p>Let the <var>cdm instance</var> value be this object's <var>cdm instance</var>.</p></li> + </ol> + </li> + <li><p>Return <var>session</var>.</p></li> + </ol></dd><dt><dfn data-dfn-for="mediakeys" data-dfn-type="dfn" id="dom-mediakeys-setservercertificate" data-idl="" data-title="setServerCertificate" data-lt="setServerCertificate|setservercertificate()"><code id="setServerCertificate">setServerCertificate</code></dfn></dt><dd> + <p id="server-certificate">Provides a server certificate to be used to encrypt messages to the license server.</p> + <p>Key Systems that use such certificates <em class="rfc2119" title="MUST">MUST</em> also support requesting the certificate from the server via the <a href="#queue-message">Queue a "message" Event</a> algorithm.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-56" aria-level="4"><span>Note</span></div><p class="">This method allows an application to proactively provide a server certificate to implementations that support it to avoid the additional round trip should the CDM request it. + It is intended as an optimization, and applications are not required to use it. + </p></div> + + + + + <table class="parameters"><tbody><tr><th>Parameter</th><th>Type</th><th>Nullable</th><th>Optional</th><th>Description</th></tr><tr><td class="prmName">serverCertificate</td><td class="prmType"><code>BufferSource</code></td><td class="prmNullFalse"><span role="img" aria-label="False">✘</span></td><td class="prmOptFalse"><span role="img" aria-label="False">✘</span></td><td class="prmDesc"> + The server certificate. + The contents are <a href="#key-system">Key System</a>-specific. + It <em class="rfc2119" title="MUST NOT">MUST NOT</em> contain executable code. + </td></tr></tbody></table><div><em>Return type: </em><code>Promise<boolean></code></div><p>When this method is invoked, the user agent must run the following steps:</p><ol class="method-algorithm"> + <li><p>If the <a href="#key-system">Key System</a> implementation represented by this object's <var>cdm implementation</var> value does not support server certificates, return a promise resolved with <code>false</code>.</p></li> + <li><p>If <var>serverCertificate</var> is an empty array, return a promise rejected with a new a newly created <code><a href="#dfn-TypeError">TypeError</a></code>.</p></li> + + <li><p>Let <var>certificate</var> be a copy of the contents of the <var>serverCertificate</var> parameter.</p></li> + <li><p>Let <var>promise</var> be a new promise.</p></li> + <li><p>Run the following steps in parallel:</p> + <ol> + <li><p>Let <var>sanitized certificate</var> be a validated and/or sanitized version of <var>certificate</var>.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-57" aria-level="4"><span>Note</span></div><p class="">The user agent should thoroughly validate the certificate before passing it to the CDM. + This may include verifying values are within reasonable limits, stripping irrelevant data or fields, pre-parsing it, sanitizing it, and/or generating a fully sanitized version. + The user agent should check that the length and values of fields are reasonable. + Unknown fields should be rejected or removed. + </p></div> + </li> + <li><p>Use this object's <var>cdm instance</var> to process <var>sanitized certificate</var>.</p></li> + <li><p>If the preceding step failed, resolve <var>promise</var> with a new <code><a href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code> whose name is the appropriate <a href="#error-names">error name</a>.</p></li> + <li><p>Resolve <var>promise</var> with <code>true</code>.</p></li> + </ol> + </li> + <li><p>Return <var>promise</var>.</p></li> + </ol></dd></dl></section></div> + + <section id="algorithms-0"> + <h3 id="x5-1-algorithms"><span class="secno">5.1 </span>Algorithms</h3> + <section id="is-persistent-session-type"> + <h4 id="x5-1-1-is-persistent-session-type"><span class="secno">5.1.1 </span>Is persistent session type?</h4> + <p>The Is persistent session type? algorithm is run to determine whether the specified session type supports persistence of any kind. + Requests to run this algorithm include a <a href="#dom-mediakeysessiontype" class="internalDFN" data-link-type="dfn"><code>MediaKeySessionType</code></a> value. + </p> + <p>The following steps are run:</p> + <ol> + <li><p>Let the <var>session type</var> be the specified <a href="#dom-mediakeysessiontype" class="internalDFN" data-link-type="dfn"><code>MediaKeySessionType</code></a> value.</p></li> + <li><p>Follow the steps for the value of <var>session type</var> from the following list:</p> + <dl class="switch"> + <dt><code><a href="#idl-def-MediaKeySessionType.temporary">"temporary"</a></code></dt> + <dd>Return <code>false</code>.</dd> + <dt><code><a href="#idl-def-MediaKeySessionType.persistent-license">"persistent-license"</a></code></dt> + <dd>Return <code>true</code>.</dd> + <dt><code><a href="#idl-def-MediaKeySessionType.persistent-usage-record">"persistent-usage-record"</a></code></dt> + <dd>Return <code>true</code>.</dd> + </dl> + </li> + </ol> + </section> + + <section id="cdm-unavailable"> + <h4 id="x5-1-2-cdm-unavailable"><span class="secno">5.1.2 </span>CDM Unavailable</h4> + <p> + The CDM unavailable algorithm is run to close all <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> objects associated with a <a href="#dfn-mediakeys" class="internalDFN" data-link-type="dfn">MediaKeys</a> object, <var>media keys</var> + when the CDM instance becomes unavailable. + </p> + <p>The following step is run:</p> + <ol> <li> - <p>Additional attributes and a method are added, as specified below.</p> + <p>For each <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> created by the <var>media keys</var> that is not <a href="#media-key-session-closed">closed</a>, <a href="https://www.w3.org/TR/html51/webappapis.html#queuing">queue a task</a> to run the <a href="#session-closed">Session Closed</a> algorithm on the session.</p> </li> - </ul> + </ol> + </section> + </section> + <section id="media-keys-storage"> + <h3 id="x5-2-storage-and-persistence"><span class="secno">5.2 </span>Storage and Persistence</h3> + <p>This section describes general requirements related to storage and persistence.</p> + + <p> + If a <a href="#dfn-mediakeys" class="internalDFN" data-link-type="dfn">MediaKeys</a> object's <var>persistent state allowed</var> value is <code>false</code> then the object's <var>cdm instance</var> + <em class="rfc2119" title="SHALL NOT">SHALL NOT</em> persist state or access previously persisted state as a result of operations on this object or any sessions that it creates. + </p> + <p> + If a <a href="#dfn-mediakeys" class="internalDFN" data-link-type="dfn">MediaKeys</a> object's <var>persistent state allowed</var> value is <code>true</code> then the object's <var>cdm instance</var> + <em class="rfc2119" title="MAY">MAY</em> persist state or access previously persisted state as a result of operations on this object or any sessions that it creates. + </p> + + <p>Persisted data <em class="rfc2119" title="MUST">MUST</em> always be stored such that only the <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> of this object's <a href="https://www.w3.org/TR/dom/#concept-document">Document</a> can access it. + In addition, the data <em class="rfc2119" title="MUST">MUST</em> only be accessible by the current <a href="#browsing-profile">browsing profile</a>; other browsing profiles, user agents, and applications <em class="rfc2119" title="MUST NOT">MUST NOT</em> be able to access the stored data. + See <a href="#privacy-storedinfo">Information Stored on User Devices</a>. + </p> + + <p>See <a href="#security" class="sec-ref"><span class="secno">10.</span> <span class="sec-title">Security</span></a> and <a href="#privacy" class="sec-ref"><span class="secno">11.</span> <span class="sec-title">Privacy</span></a> for additional considerations when supporting persistent storage.</p> - <p>For methods that return a promise, all errors are reported asynchronously by rejecting the returned Promise. This includes [<cite><a class="bibref" href="#bib-WEBIDL">WEBIDL</a></cite>] type mapping errors.</p> - <p>The steps of an algorithm are always aborted when rejecting a promise.</p> + </section> + </section> - <div> - <div> - <pre class="def idl"><span class="idlInterface" id="idl-def-htmlmediaelement-partial-1" data-idl="" data-title="HTMLMediaElement">partial interface <span class="idlInterfaceID"><a data-lt="HTMLMediaElement" href="#dom-htmlmediaelement" class="internalDFN" data-link-type="dfn" data-for=""><code>HTMLMediaElement</code></a></span> { -<span class="idlAttribute" id="idl-def-htmlmediaelement-mediakeys" data-idl="" data-title="mediaKeys" data-dfn-for="htmlmediaelement"> [<span class="extAttr"><span class="extAttrName"><a href="https://heycam.github.io/webidl/#SecureContext">SecureContext</a></span></span>] - readonly attribute <span class="idlAttrType"><a href="#dom-mediakeys" class="internalDFN" data-link-type="dfn"><code>MediaKeys</code></a>?</span> <span class="idlAttrName"><a data-lt="mediaKeys" href="#dom-htmlmediaelement-mediakeys" class="internalDFN" data-link-type="dfn" data-for="HTMLMediaElement"><code>mediaKeys</code></a></span>;</span> -<span class="idlAttribute" id="idl-def-htmlmediaelement-onencrypted" data-idl="" data-title="onencrypted" data-dfn-for="htmlmediaelement"> attribute <span class="idlAttrType"><a href="https://html.spec.whatwg.org/multipage/#eventhandler">EventHandler</a></span> <span class="idlAttrName"><a data-lt="onencrypted" href="#dom-htmlmediaelement-onencrypted" class="internalDFN" data-link-type="dfn" data-for="HTMLMediaElement"><code>onencrypted</code></a></span>;</span> -<span class="idlAttribute" id="idl-def-htmlmediaelement-onwaitingforkey" data-idl="" data-title="onwaitingforkey" data-dfn-for="htmlmediaelement"> attribute <span class="idlAttrType"><a href="https://html.spec.whatwg.org/multipage/#eventhandler">EventHandler</a></span> <span class="idlAttrName"><a data-lt="onwaitingforkey" href="#dom-htmlmediaelement-onwaitingforkey" class="internalDFN" data-link-type="dfn" data-for="HTMLMediaElement"><code>onwaitingforkey</code></a></span>;</span> -<span class="idlMethod" id="idl-def-htmlmediaelement-setmediakeys(mediakeys)" data-idl="" data-title="setMediaKeys" data-dfn-for="htmlmediaelement"> [<span class="extAttr"><span class="extAttrName"><a href="https://heycam.github.io/webidl/#SecureContext">SecureContext</a></span></span>] <span class="idlMethType"><a href="https://heycam.github.io/webidl/#idl-promise">Promise</a><void></span> <span class="idlMethName"><a data-lt="setMediaKeys" href="#dom-htmlmediaelement-setmediakeys" class="internalDFN" data-link-type="dfn" data-for="HTMLMediaElement"><code>setMediaKeys</code></a></span>(<span class="idlParam"><span class="idlParamType"><a href="#dom-mediakeys" class="internalDFN" data-link-type="dfn"><code>MediaKeys</code></a>?</span> <span class="idlParamName">mediaKeys</span></span>);</span> -};</span></pre> - </div> - <section> - <h3 id="attributes-3">Attributes</h3> - <dl class="attributes" data-dfn-for="HTMLMediaElement" data-link-for="HTMLMediaElement"><dt><dfn data-dfn-for="htmlmediaelement" data-dfn-type="dfn" id="dom-htmlmediaelement-mediakeys" data-idl="" data-title="mediaKeys"><code>mediaKeys</code></dfn> of type <span class="idlAttrType"><!-- Restore when https://github.com/w3c/respec/issues/893 is fixed. <a> -->MediaKeys<!-- </a> --></span>, readonly , nullable</dt> - <dd> - <p>The - <!-- Restore when https://github.com/w3c/respec/issues/893 is fixed. <a> -->MediaKeys - <!-- </a> -->being used when decrypting encrypted <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a> for this media element.</p> - </dd><dt><dfn data-dfn-for="htmlmediaelement" data-dfn-type="dfn" id="dom-htmlmediaelement-onencrypted" data-idl="" data-title="onencrypted"><code>onencrypted</code></dfn> of type <span class="idlAttrType">EventHandler</span></dt> - <dd> - <p>Event handler for the <code><a href="#dom-evt-encrypted">encrypted</a></code> event. It <em class="rfc2119" title="MUST">MUST</em> be supported by all HTMLMediaElements as both a content attribute and an IDL attribute.</p> - </dd><dt><dfn data-dfn-for="htmlmediaelement" data-dfn-type="dfn" id="dom-htmlmediaelement-onwaitingforkey" data-idl="" data-title="onwaitingforkey"><code>onwaitingforkey</code></dfn> of type <span class="idlAttrType">EventHandler</span></dt> - <dd> - <p>Event handler for the <code><a href="#dom-evt-waitingforkey">waitingforkey</a></code> event. It <em class="rfc2119" title="MUST">MUST</em> be supported by all HTMLMediaElements as both a content attribute and an IDL attribute.</p> - </dd> - </dl> - </section> - <section> - <h3 id="methods-4">Methods</h3> - <dl class="methods" data-dfn-for="HTMLMediaElement" data-link-for="HTMLMediaElement"><dt><dfn data-dfn-for="htmlmediaelement" data-dfn-type="dfn" id="dom-htmlmediaelement-setmediakeys" data-idl="" data-title="setMediaKeys" data-lt="setmediakeys()|setMediaKeys"><code id="setMediaKeys">setMediaKeys</code></dfn></dt> - <dd> - <p>Provides the - <!-- Restore when https://github.com/w3c/respec/issues/893 is fixed. <a> -->MediaKeys - <!-- </a> -->to use when decrypting media data during playback.</p> - - <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note103"><span>Note</span></div> - <p class="">Support for clearing or replacing the associated - <!-- Restore when https://github.com/w3c/respec/issues/893 is fixed. <a> -->MediaKeys - <!-- </a> -->object during playback is a quality of implementation issue. In many cases it will result in a bad user experience or rejected promise.</p> - </div> - - - <table class="parameters"> - <tbody> - <tr> - <th>Parameter</th> - <th>Type</th> - <th>Nullable</th> - <th>Optional</th> - <th>Description</th> - </tr> - <tr> - <td class="prmName">mediaKeys</td> - <td class="prmType"><code>MediaKeys</code></td> - <td class="prmNullTrue"><span role="img" aria-label="True">✔</span></td> - <td class="prmOptFalse"><span role="img" aria-label="False">✘</span></td> - <td class="prmDesc"> - A - <!-- Restore when https://github.com/w3c/respec/issues/893 is fixed. <a> -->MediaKeys - <!-- </a> -->object. - </td> - </tr> - </tbody> - </table> - <div><em>Return type: </em><code>Promise<void></code></div> - <p>When this method is invoked, the user agent must run the following steps:</p> - <ol class="method-algorithm"> - <!-- For simplicity and consistency, do not allow multiple pending calls. --> - <li> - <p>If this object's <var>attaching media keys</var> value is true, return a promise rejected with an <code><a href="#dfn-InvalidStateError">InvalidStateError</a></code>.</p> - </li> - <li> - <p>If <var>mediaKeys</var> and the <code><a href="#dom-mediakeys">mediaKeys</a></code> attribute are the same object, return a resolved promise.</p> - </li> - <li> - <p>Let this object's <var>attaching media keys</var> value be true.</p> - </li> - <li> - <p>Let <var>promise</var> be a new promise.</p> - </li> - <li> - <p>Run the following steps in parallel:</p> - <ol> - <li> - <p>If all the following conditions hold:</p> - <ul> - <li> - <p><var>mediaKeys</var> is not null,</p> - </li> - <li> - <p>the CDM instance represented by <var>mediaKeys</var> is already in use by another media element</p> - </li> - <li> - <p>the user agent is unable to use it with this element</p> - </li> - </ul> - <p> - then let this object's <var>attaching media keys</var> value be false and reject <var>promise</var> with a <code><a href="#dfn-QuotaExceededError">QuotaExceededError</a></code>. - </p> - </li> - <li> - <p>If the <code><a href="#dom-mediakeys">mediaKeys</a></code> attribute is not null, run the following steps:</p> - <ol> - <li> - <p>If the user agent or CDM do not support removing the association, let this object's <var>attaching media keys</var> value be false and reject <var>promise</var> with a <code><a href="#dfn-NotSupportedError">NotSupportedError</a></code>.</p> - </li> - <li> - <p>If the association cannot currently be removed, let this object's <var>attaching media keys</var> value be false and reject <var>promise</var> with an <code><a href="#dfn-InvalidStateError">InvalidStateError</a></code>.</p> - <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note104"><span>Note</span></div> - <p class="">For example, some implementations may not allow removal during playback.</p> - </div> - </li> - <li> - <p>Stop using the CDM instance represented by the <code><a href="#dom-mediakeys">mediaKeys</a></code> attribute to decrypt <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a> and remove the association with the media element.</p> - </li> - <li> - <p>If the preceding step failed, let this object's <var>attaching media keys</var> value be false and reject <var>promise</var> with the appropriate <a href="#error-names">error name</a>.</p> - </li> - </ol> - </li> - <li> - <p>If <var>mediaKeys</var> is not null, run the following steps:</p> - <ol> - <li> - <p>Associate the CDM instance represented by <var>mediaKeys</var> with the media element for decrypting <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a>.</p> - </li> - <li> - <p>If the preceding step failed, run the following steps:</p> - <ol> - <li> - <p>Set the <code><a href="#dom-mediakeys">mediaKeys</a></code> attribute to null.</p> - </li> - <!-- In case it was previously not null since the previous association has been removed. --> - <li> - <p>Let this object's <var>attaching media keys</var> value be false.</p> - </li> - <li> - <p>Reject <var>promise</var> with a new <code><a href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code> whose name is the appropriate <a href="#error-names">error name</a>.</p> - </li> - </ol> - </li> - <li> - <p><a href="https://www.w3.org/TR/html51/webappapis.html#queuing">Queue a task</a> to run the <a href="#resume-playback">Attempt to Resume Playback If Necessary</a> algorithm on the media element.</p> - </li> - </ol> - </li> - <li> - <p>Set the <code><a href="#dom-mediakeys">mediaKeys</a></code> attribute to <var>mediaKeys</var>.</p> - </li> - <li> - <p>Let this object's <var>attaching media keys</var> value be false.</p> - </li> - <li> - <p>Resolve <var>promise</var>.</p> - </li> - </ol> - </li> - <li> - <p>Return <var>promise</var>.</p> - </li> - </ol> - </dd> - </dl> - </section> - </div> - <section id="mediaencryptedevent"> - <h3 id="x7.1-mediaencryptedevent"><span class="secno">7.1 </span><a href="#dom-mediaencryptedevent" class="internalDFN" data-link-type="dfn"><code>MediaEncryptedEvent</code></a></h3> - <p>The MediaEncryptedEvent object is used for the <code><a href="#dom-evt-encrypted">encrypted</a></code> event.</p> - <p>Events are constructed as defined in <a href="https://www.w3.org/TR/dom/#constructing-events">Constructing events</a> [<cite><a class="bibref" href="#bib-DOM">DOM</a></cite>].</p> - - <div> - <div> - <pre class="def idl"><span class="idlInterface" id="idl-def-mediaencryptedevent" data-idl="" data-title="MediaEncryptedEvent">[<span class="idlCtor"><span class="extAttrName"><a href="https://heycam.github.io/webidl/#Constructor">Constructor</a></span>(<span class="idlParam"><span class="idlParamType"><a href="https://heycam.github.io/webidl/#idl-DOMString">DOMString</a></span> <span class="idlParamName">type</span></span>, <span class="idlParam">optional <span class="idlParamType"><a href="#dom-mediaencryptedeventinit" class="internalDFN" data-link-type="dfn"><code>MediaEncryptedEventInit</code></a></span> <span class="idlParamName">eventInitDict</span></span>)</span>] -interface <span class="idlInterfaceID"><a data-lt="MediaEncryptedEvent" href="#dom-mediaencryptedevent" class="internalDFN" data-link-type="dfn" data-for=""><code>MediaEncryptedEvent</code></a></span> : <span class="idlSuperclass">Event</span> { -<span class="idlAttribute" id="idl-def-mediaencryptedevent-initdatatype" data-idl="" data-title="initDataType" data-dfn-for="mediaencryptedevent"> readonly attribute <span class="idlAttrType"><a href="https://heycam.github.io/webidl/#idl-DOMString">DOMString</a></span> <span class="idlAttrName"><a data-lt="initDataType" href="#dom-mediaencryptedevent-initdatatype" class="internalDFN" data-link-type="dfn" data-for="MediaEncryptedEvent"><code>initDataType</code></a></span>;</span> -<span class="idlAttribute" id="idl-def-mediaencryptedevent-initdata" data-idl="" data-title="initData" data-dfn-for="mediaencryptedevent"> readonly attribute <span class="idlAttrType"><a href="https://heycam.github.io/webidl/#idl-ArrayBuffer">ArrayBuffer</a>?</span> <span class="idlAttrName"><a data-lt="initData" href="#dom-mediaencryptedevent-initdata" class="internalDFN" data-link-type="dfn" data-for="MediaEncryptedEvent"><code>initData</code></a></span>;</span> -};</span></pre> - </div> - <section> - <h4 id="constructors-0">Constructors</h4> - <dl class="constructors" data-dfn-for="MediaEncryptedEvent" data-link-for="MediaEncryptedEvent"><dt><dfn data-dfn-for="" data-dfn-type="dfn" id="dom-mediaencryptedevent" data-idl="" data-title="MediaEncryptedEvent"><code>MediaEncryptedEvent</code></dfn></dt> + <section id="mediakeysession-interface"> + <!--OddPage--><h2 id="x6-mediakeysession-interface"><span class="secno">6. </span><dfn data-dfn-type="dfn" id="dom-mediakeysession" data-idl="" data-title="MediaKeySession" data-dfn-for=""><code>MediaKeySession</code></dfn> Interface</h2> + <p>The MediaKeySession object represents a <a href="#key-session">key session</a>.</p> + <p> + A <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object is <dfn id="media-key-session-closed" data-dfn-type="dfn">closed</dfn> if and only if the object's <code><a href="#dom-mediakeysession-closed">closed</a></code> attribute has been resolved. + </p> + <p> + The User Agent <em class="rfc2119" title="SHALL">SHALL</em> execute the <a href="#monitor-cdm">Monitor for CDM Changes</a> algorithm continuously for each <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object + that is not <a href="#media-key-session-closed">closed</a>. + The <a href="#monitor-cdm">Monitor for CDM Changes</a> algorithm <em class="rfc2119" title="MUST">MUST</em> be run in parallel to the main event loop but not in parallel to other procedures defined + in this specification that are also defined to be run in parallel. + </p> + <p> + A <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object <em class="rfc2119" title="SHALL NOT">SHALL NOT</em> be destroyed and <em class="rfc2119" title="SHALL">SHALL</em> continue to receive events if it is + not <a href="#media-key-session-closed">closed</a> and the <a href="#dfn-mediakeys" class="internalDFN" data-link-type="dfn">MediaKeys</a> object that created it remains accessible. + Otherwise, a <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object that is no longer accessible <em class="rfc2119" title="SHALL NOT">SHALL NOT</em> receive further + events and <em class="rfc2119" title="MAY">MAY</em> be destroyed. + </p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-58" aria-level="3"><span>Note</span></div><p class=""> + The above rule implies that the CDM instance must not be destroyed until all <a href="#dfn-mediakeys" class="internalDFN" data-link-type="dfn">MediaKeys</a> + objects and all <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> objects associated with the CDM instance are destroyed. + </p></div> + <p> + If a <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object is not <a href="#media-key-session-closed">closed</a> when it becomes inaccessible to the page, the CDM <em class="rfc2119" title="SHALL">SHALL</em> close the <a href="#key-session">key session</a> associated with the object. + </p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-59" aria-level="3"><span>Note</span></div><p class="">Closing the key session results in the destruction of any license(s) and key(s) that have not been explicitly stored.</p></div> + <div class="note"><div role="heading" class="note-title marker" id="h-note-60" aria-level="3"><span>Note</span></div><p class=""> + Exactly when the key session is closed is an implementation detail, and applications <em class="rfc2119" title="SHOULD NOT">SHOULD NOT</em> rely on specific timing. + <!-- TODO: Replace and/or expand on this with an implementation of Issue #360. --> + Applications that want to ensure a session is closed before taking some other action <em class="rfc2119" title="SHOULD">SHOULD</em> call <code><a href="#dom-mediakeysession-close">close()</a></code> and wait for the returned promise to be resolved. + </p></div> + <p> + If a <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object becomes inaccessible to the page + and is not <a href="#media-key-session-closed">closed</a>, the User Agent + <em class="rfc2119" title="MUST">MUST</em> run the <a href="#media-key-session-destroyed">MediaKeySession destroyed</a> algorithm before User Agent state + associated with the <a href="#key-session">session</a> is deleted. + </p> + <p>For methods that return a promise, all errors are reported asynchronously by rejecting the returned Promise. This includes [<cite><a class="bibref" href="#bib-WEBIDL">WEBIDL</a></cite>] type mapping errors.</p> + <p>The following steps of an algorithm are always aborted when rejecting a promise.</p> + + <div><div><pre class="def idl"><span class="idlInterface" id="idl-def-mediakeysession" data-idl="" data-title="MediaKeySession">[<span class="extAttr"><span class="extAttrName"><a href="https://heycam.github.io/webidl/#SecureContext">SecureContext</a></span></span>] +interface <span class="idlInterfaceID"><a data-no-default="" data-link-for="" data-lt="" href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a></span> : <span class="idlSuperclass">EventTarget</span> { +<span class="idlAttribute" id="idl-def-mediakeysession-sessionid" data-idl="" data-title="sessionId" data-dfn-for="mediakeysession"> readonly attribute <span class="idlAttrType"><a href="https://heycam.github.io/webidl/#idl-DOMString">DOMString</a></span> <span class="idlAttrName"><a data-no-default="" data-link-for="mediakeysession" data-lt="" href="#dom-mediakeysession-sessionid" class="internalDFN" data-link-type="dfn"><code>sessionId</code></a></span>;</span> +<span class="idlAttribute" id="idl-def-mediakeysession-expiration" data-idl="" data-title="expiration" data-dfn-for="mediakeysession"> readonly attribute <span class="idlAttrType"><a href="https://heycam.github.io/webidl/#idl-unrestricted-double">unrestricted double</a></span> <span class="idlAttrName"><a data-no-default="" data-link-for="mediakeysession" data-lt="" href="#dom-mediakeysession-expiration" class="internalDFN" data-link-type="dfn"><code>expiration</code></a></span>;</span> +<span class="idlAttribute" id="idl-def-mediakeysession-closed" data-idl="" data-title="closed" data-dfn-for="mediakeysession"> readonly attribute <span class="idlAttrType"><a href="https://heycam.github.io/webidl/#idl-promise">Promise</a><void></span> <span class="idlAttrName"><a data-no-default="" data-link-for="mediakeysession" data-lt="" href="#dom-mediakeysession-closed" class="internalDFN" data-link-type="dfn"><code>closed</code></a></span>;</span> +<span class="idlAttribute" id="idl-def-mediakeysession-keystatuses" data-idl="" data-title="keyStatuses" data-dfn-for="mediakeysession"> readonly attribute <span class="idlAttrType"><a href="#dom-mediakeystatusmap" class="internalDFN" data-link-type="dfn"><code>MediaKeyStatusMap</code></a></span> <span class="idlAttrName"><a data-no-default="" data-link-for="mediakeysession" data-lt="" href="#dom-mediakeysession-keystatuses" class="internalDFN" data-link-type="dfn"><code>keyStatuses</code></a></span>;</span> +<span class="idlAttribute" id="idl-def-mediakeysession-onkeystatuseschange" data-idl="" data-title="onkeystatuseschange" data-dfn-for="mediakeysession"> attribute <span class="idlAttrType"><a href="https://html.spec.whatwg.org/multipage/#eventhandler">EventHandler</a></span> <span class="idlAttrName"><a data-no-default="" data-link-for="mediakeysession" data-lt="" href="#dom-mediakeysession-onkeystatuseschange" class="internalDFN" data-link-type="dfn"><code>onkeystatuseschange</code></a></span>;</span> +<span class="idlAttribute" id="idl-def-mediakeysession-onmessage" data-idl="" data-title="onmessage" data-dfn-for="mediakeysession"> attribute <span class="idlAttrType"><a href="https://html.spec.whatwg.org/multipage/#eventhandler">EventHandler</a></span> <span class="idlAttrName"><a data-no-default="" data-link-for="mediakeysession" data-lt="" href="#dom-mediakeysession-onmessage" class="internalDFN" data-link-type="dfn"><code>onmessage</code></a></span>;</span> +<span class="idlMethod" id="idl-def-mediakeysession-generaterequest-initdatatype-initdata" data-idl="" data-title="generateRequest" data-dfn-for="mediakeysession"> <span class="idlMethType"><a href="https://heycam.github.io/webidl/#idl-promise">Promise</a><void></span> <span class="idlMethName"><a data-no-default="" data-link-for="mediakeysession" data-lt="generateRequest|generaterequest()" href="#dom-mediakeysession-generaterequest" class="internalDFN" data-link-type="dfn"><code>generateRequest</code></a></span>(<span class="idlParam"><span class="idlParamType"><a href="https://heycam.github.io/webidl/#idl-DOMString">DOMString</a></span> <span class="idlParamName">initDataType</span></span>, + <span class="idlParam"><span class="idlParamType">BufferSource</span> <span class="idlParamName">initData</span></span>);</span> +<span class="idlMethod" id="idl-def-mediakeysession-load-sessionid" data-idl="" data-title="load" data-dfn-for="mediakeysession"> <span class="idlMethType"><a href="https://heycam.github.io/webidl/#idl-promise">Promise</a><<a href="https://heycam.github.io/webidl/#idl-boolean">boolean</a>></span> <span class="idlMethName"><a data-no-default="" data-link-for="mediakeysession" data-lt="load|load()" href="#dom-mediakeysession-load" class="internalDFN" data-link-type="dfn"><code>load</code></a></span>(<span class="idlParam"><span class="idlParamType"><a href="https://heycam.github.io/webidl/#idl-DOMString">DOMString</a></span> <span class="idlParamName">sessionId</span></span>);</span> +<span class="idlMethod" id="idl-def-mediakeysession-update-response" data-idl="" data-title="update" data-dfn-for="mediakeysession"> <span class="idlMethType"><a href="https://heycam.github.io/webidl/#idl-promise">Promise</a><void></span> <span class="idlMethName"><a data-no-default="" data-link-for="mediakeysession" data-lt="update|update()" href="#dom-mediakeysession-update" class="internalDFN" data-link-type="dfn"><code>update</code></a></span>(<span class="idlParam"><span class="idlParamType">BufferSource</span> <span class="idlParamName">response</span></span>);</span> +<span class="idlMethod" id="idl-def-mediakeysession-close" data-idl="" data-title="close" data-dfn-for="mediakeysession"> <span class="idlMethType"><a href="https://heycam.github.io/webidl/#idl-promise">Promise</a><void></span> <span class="idlMethName"><a data-no-default="" data-link-for="mediakeysession" data-lt="close|close()" href="#dom-mediakeysession-close" class="internalDFN" data-link-type="dfn"><code>close</code></a></span>();</span> +<span class="idlMethod" id="idl-def-mediakeysession-remove" data-idl="" data-title="remove" data-dfn-for="mediakeysession"> <span class="idlMethType"><a href="https://heycam.github.io/webidl/#idl-promise">Promise</a><void></span> <span class="idlMethName"><a data-no-default="" data-link-for="mediakeysession" data-lt="remove|remove()" href="#dom-mediakeysession-remove" class="internalDFN" data-link-type="dfn"><code>remove</code></a></span>();</span> +};</span></pre></div><section><h3 id="attributes-0">Attributes</h3><dl class="attributes" data-dfn-for="MediaKeySession" data-link-for="MediaKeySession"><dt><dfn data-dfn-for="mediakeysession" data-dfn-type="dfn" id="dom-mediakeysession-sessionid" data-idl="" data-title="sessionId"><code>sessionId</code></dfn> of type <span class="idlAttrType">DOMString</span>, readonly </dt><dd> + <p>The <a href="#session-id">Session ID</a> for this object and the associated key(s) or license(s).</p> + </dd><dt><dfn data-dfn-for="mediakeysession" data-dfn-type="dfn" id="dom-mediakeysession-expiration" data-idl="" data-title="expiration"><code>expiration</code></dfn> of type <span class="idlAttrType">unrestricted double</span>, readonly </dt><dd> + <p>The <a href="#expiration-time">expiration time</a> for all key(s) in the session, or <code>NaN</code> if no such time exists or if the license explicitly never expires, as determined by the CDM.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-61" aria-level="4"><span>Note</span></div><p class="">This value <em class="rfc2119" title="MAY">MAY</em> change during the session lifetime, such as when an action triggers the start of a window.</p></div> + </dd><dt><dfn data-dfn-for="mediakeysession" data-dfn-type="dfn" id="dom-mediakeysession-closed" data-idl="" data-title="closed"><code>closed</code></dfn> of type <span class="idlAttrType">Promise<void></span>, readonly </dt><dd> + <p>Signals when the object becomes <a href="#media-key-session-closed">closed</a> as a result of the <a href="#session-closed">Session Closed</a> algorithm being run. + This promise can only be fulfilled and is never rejected.</p> + </dd><dt><dfn data-dfn-for="mediakeysession" data-dfn-type="dfn" id="dom-mediakeysession-keystatuses" data-idl="" data-title="keyStatuses"><code>keyStatuses</code></dfn> of type <span class="idlAttrType"><a href="#dom-mediakeystatusmap" class="internalDFN" data-link-type="dfn"><code>MediaKeyStatusMap</code></a></span>, readonly </dt><dd> + <p>A reference to a read-only map of <a href="#decryption-key-id">key IDs</a> <a href="#known-key">known</a> to the session to the current status of the associated key. + Each entry <em class="rfc2119" title="MUST">MUST</em> have a unique key ID. + </p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-62" aria-level="4"><span>Note</span></div><p class="">The map entries and their values may be updated whenever the event loop spins. + The map <em class="rfc2119" title="MUST NOT">MUST NOT</em> ever be inconsistent or partially updated, but it may change between accesses if the event loop spins in between the accesses. + Key IDs may be added as the result of a <code><a href="#dom-mediakeysession-load">load()</a></code> or <code><a href="#dom-mediakeysession-update">update()</a></code> call. + Key IDs may be removed as the result of a <code><a href="#dom-mediakeysession-update">update()</a></code> call that removes knowledge of existing keys (or replaces the existing set of keys with a new set). + Key IDs <em class="rfc2119" title="MUST NOT">MUST NOT</em> be removed because they became unusable, such as due to expiration. Instead, such keys <em class="rfc2119" title="MUST">MUST</em> be given an appropriate status, such as <code><a href="#idl-def-MediaKeyStatus.expired">"expired"</a></code>. + </p></div> + <div class="note"><div role="heading" class="note-title marker" id="h-note-63" aria-level="4"><span>Note</span></div><p class=""> + Some older platforms may contain Key System implementations that do not expose key IDs, making it impossible to provide a compliant user agent implementation. + To maximize interoperability, user agent implementations exposing such CDMs <em class="rfc2119" title="SHOULD">SHOULD</em> implement this member as follows: + Whenever a non-empty list is appropriate, such as when the <a href="#key-session">key session</a> represented by this object may contain <a href="#decryption-key">key(s)</a>, populate the map with a single pair containing + the one-byte key ID <code>0</code> and the <a href="#dom-mediakeystatus" class="internalDFN" data-link-type="dfn"><code>MediaKeyStatus</code></a> most appropriate for the aggregated status of this object. + </p></div> + </dd><dt><dfn data-dfn-for="mediakeysession" data-dfn-type="dfn" id="dom-mediakeysession-onkeystatuseschange" data-idl="" data-title="onkeystatuseschange"><code>onkeystatuseschange</code></dfn> of type <span class="idlAttrType">EventHandler</span></dt><dd> + <p>Event handler for the <code><a href="#dom-evt-keystatuseschange">keystatuseschange</a></code> event.</p> + </dd><dt><dfn data-dfn-for="mediakeysession" data-dfn-type="dfn" id="dom-mediakeysession-onmessage" data-idl="" data-title="onmessage"><code>onmessage</code></dfn> of type <span class="idlAttrType">EventHandler</span></dt><dd> + <p>Event handler for the <code><a href="#dom-evt-message">message</a></code> event.</p> + </dd></dl></section><section><h3 id="methods-2">Methods</h3><dl class="methods" data-dfn-for="MediaKeySession" data-link-for="MediaKeySession"><dt><dfn data-dfn-for="mediakeysession" data-dfn-type="dfn" id="dom-mediakeysession-generaterequest" data-idl="" data-title="generateRequest" data-lt="generateRequest|generaterequest()"><code id="generateRequest">generateRequest</code></dfn></dt><dd> + <p>Generates a license request based on the <var>initData</var>. + A <code><a href="#dom-evt-message">message</a></code> of type <code><a href="#idl-def-MediaKeyMessageType.license-request">"license-request"</a></code> or <code><a href="#idl-def-MediaKeyMessageType.individualization-request">"individualization-request"</a></code> will always be queued if the algorithm succeeds and the promise is resolved. + </p> + + + + + <table class="parameters"><tbody><tr><th>Parameter</th><th>Type</th><th>Nullable</th><th>Optional</th><th>Description</th></tr><tr><td class="prmName">initDataType</td><td class="prmType"><code>DOMString</code></td><td class="prmNullFalse"><span role="img" aria-label="False">✘</span></td><td class="prmOptFalse"><span role="img" aria-label="False">✘</span></td><td class="prmDesc"> + The <a href="#initialization-data-type">Initialization Data Type</a> of the <var>initData</var>. + </td></tr><tr><td class="prmName">initData</td><td class="prmType"><code>BufferSource</code></td><td class="prmNullFalse"><span role="img" aria-label="False">✘</span></td><td class="prmOptFalse"><span role="img" aria-label="False">✘</span></td><td class="prmDesc"> + <a href="#initialization-data">Initialization Data</a> + </td></tr></tbody></table><div><em>Return type: </em><code>Promise<void></code></div><p>When this method is invoked, the user agent must run the following steps:</p><ol class="method-algorithm"> + <li><p>If this object's <var>closing or closed</var> value is true, return a promise rejected with an <code><a href="#dfn-InvalidStateError">InvalidStateError</a></code>.</p></li> + <li><p>If this object's <var>uninitialized</var> value is false, return a promise rejected with an <code><a href="#dfn-InvalidStateError">InvalidStateError</a></code>.</p></li> + <li><p>Let this object's <var>uninitialized</var> value be false.</p></li><!-- For simplicity and consistency, this object cannot be reused after any failure. --> + <li><p>If <var>initDataType</var> is the empty string, return a promise rejected with a newly created <code><a href="#dfn-TypeError">TypeError</a></code>.</p></li> + <li><p>If <var>initData</var> is an empty array, return a promise rejected with a newly created <code><a href="#dfn-TypeError">TypeError</a></code>.</p></li> + <li><p>If the <a href="#key-system">Key System</a> implementation represented by this object's <var>cdm implementation</var> value does not support <var>initDataType</var> as an <a href="#initialization-data-type">Initialization Data Type</a>, return a promise rejected with a <code><a href="#dfn-NotSupportedError">NotSupportedError</a></code>. String comparison is case-sensitive.</p></li> + <li><p>Let <var>init data</var> be a copy of the contents of the <var>initData</var> parameter.</p></li> + <li><p>Let <var>session type</var> be this object's <var>session type</var>.</p></li> + <li><p>Let <var>promise</var> be a new promise.</p></li> + <li><p>Run the following steps in parallel:</p> + <ol> + <li><p>If the <var>init data</var> is not valid for <var>initDataType</var>, reject <var>promise</var> with a newly created <code><a href="#dfn-TypeError">TypeError</a></code>.</p></li> + <li><p>Let <var>sanitized init data</var> be a validated and sanitized version of <var>init data</var>.</p> + <p>The user agent <em class="rfc2119" title="MUST">MUST</em> thoroughly validate the <a href="#initialization-data">Initialization Data</a> before passing it to the CDM. + This includes verifying that the length and values of fields are reasonable, verifying that values are within reasonable limits, and stripping irrelevant, unsupported, or unknown data or fields. + It is <em class="rfc2119" title="RECOMMENDED">RECOMMENDED</em> that user agents pre-parse, sanitize, and/or generate a fully sanitized version of the <a href="#initialization-data">Initialization Data</a>. + If the <a href="#initialization-data">Initialization Data</a> format specified by <var>initDataType</var> supports multiple entries, the user agent <em class="rfc2119" title="SHOULD">SHOULD</em> remove entries that are not needed by the CDM. The user agent <em class="rfc2119" title="MUST NOT">MUST NOT</em> re-order entries within the <a href="#initialization-data">Initialization Data</a>. + </p> + </li> + <li><p>If the preceding step failed, reject <var>promise</var> with a newly created <code><a href="#dfn-TypeError">TypeError</a></code>.</p></li> + <li><p>If <var>sanitized init data</var> is empty, reject <var>promise</var> with a <code><a href="#dfn-NotSupportedError">NotSupportedError</a></code>.</p></li> + <li><p>Let <var>session id</var> be the empty string.</p></li> + <li><p>Let <var>message</var> be null.</p></li> + <li><p>Let <var>message type</var> be null.</p></li> + <li><p>Let <var>cdm</var> be the CDM instance represented by this object's <var>cdm instance</var> value.</p></li> + <li><p>Use the <var>cdm</var> to execute the following steps:</p> + <ol> + <li><p>If the <var>sanitized init data</var> is not supported by the <var>cdm</var>, reject <var>promise</var> with a <code><a href="#dfn-NotSupportedError">NotSupportedError</a></code>.</p></li> + <li><p>Follow the steps for the value of <var>session type</var> from the following list:</p> + <dl class="switch"> + <dt><code><a href="#idl-def-MediaKeySessionType.temporary">"temporary"</a></code></dt> <dd> - - <table class="parameters"> - <tbody> - <tr> - <th>Parameter</th> - <th>Type</th> - <th>Nullable</th> - <th>Optional</th> - <th>Description</th> - </tr> - <tr> - <td class="prmName">type</td> - <td class="prmType"><code>DOMString</code></td> - <td class="prmNullFalse"><span role="img" aria-label="False">✘</span></td> - <td class="prmOptFalse"><span role="img" aria-label="False">✘</span></td> - <td class="prmDesc"></td> - </tr> - <tr> - <td class="prmName">eventInitDict</td> - <td class="prmType"><code>MediaEncryptedEventInit</code></td> - <td class="prmNullFalse"><span role="img" aria-label="False">✘</span></td> - <td class="prmOptTrue"><span role="img" aria-label="True">✔</span></td> - <td class="prmDesc"></td> - </tr> - </tbody> - </table> + <p>Let <var>requested license type</var> be a temporary non-persistable license.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-64" aria-level="4"><span>Note</span></div><p class="">The returned license must not be persistable or require persisting information related to it.</p></div> </dd> - </dl> - </section> - <section> - <h4 id="attributes-4">Attributes</h4> - <dl class="attributes" data-dfn-for="MediaEncryptedEvent" data-link-for="MediaEncryptedEvent"><dt><dfn data-dfn-for="mediaencryptedevent" data-dfn-type="dfn" id="dom-mediaencryptedevent-initdatatype" data-idl="" data-title="initDataType"><code>initDataType</code></dfn> of type <span class="idlAttrType">DOMString</span>, readonly </dt> - <dd> - Indicates the <a href="#initialization-data-type">Initialization Data Type</a> of the <a href="#initialization-data">Initialization Data</a> contained in the <code><a href="#dom-mediaencryptedevent-initdata">initData</a></code> attribute. - </dd><dt><dfn data-dfn-for="mediaencryptedevent" data-dfn-type="dfn" id="dom-mediaencryptedevent-initdata" data-idl="" data-title="initData"><code>initData</code></dfn> of type <span class="idlAttrType">ArrayBuffer</span>, readonly , nullable</dt> + <dt><code><a href="#idl-def-MediaKeySessionType.persistent-license">"persistent-license"</a></code></dt> <dd> - The <a href="#initialization-data">Initialization Data</a> for the event. + <p>Let <var>requested license type</var> be a persistable license.</p> </dd> - </dl> - </section> - </div> - - <section id="mediaencryptedeventinit"> - <h4 id="x7.1.1-mediaencryptedeventinit"><span class="secno">7.1.1 </span><dfn data-dfn-for="" data-dfn-type="dfn" id="dom-mediaencryptedeventinit" data-idl="" data-title="MediaEncryptedEventInit"><code>MediaEncryptedEventInit</code></dfn></h4> - <div> - <div> - <pre class="def idl"><span class="idlDictionary" id="idl-def-mediaencryptedeventinit" data-idl="" data-title="MediaEncryptedEventInit">dictionary <span class="idlDictionaryID"><a data-lt="MediaEncryptedEventInit" href="#dom-mediaencryptedeventinit" class="internalDFN" data-link-type="dfn" data-for=""><code>MediaEncryptedEventInit</code></a></span> : <span class="idlSuperclass">EventInit</span> { -<span class="idlMember" id="idl-def-mediaencryptedeventinit-initdatatype" data-idl="" data-title="initDataType" data-dfn-for="mediaencryptedeventinit"> <span class="idlMemberType"><a href="https://heycam.github.io/webidl/#idl-DOMString">DOMString</a></span> <span class="idlMemberName"><a data-lt="initDataType" href="#dom-mediaencryptedeventinit-initdatatype" class="internalDFN" data-link-type="dfn" data-for="MediaEncryptedEventInit"><code>initDataType</code></a></span> = <span class="idlMemberValue">""</span>;</span> -<span class="idlMember" id="idl-def-mediaencryptedeventinit-initdata" data-idl="" data-title="initData" data-dfn-for="mediaencryptedeventinit"> <span class="idlMemberType"><a href="https://heycam.github.io/webidl/#idl-ArrayBuffer">ArrayBuffer</a>?</span> <span class="idlMemberName"><a data-lt="initData" href="#dom-mediaencryptedeventinit-initdata" class="internalDFN" data-link-type="dfn" data-for="MediaEncryptedEventInit"><code>initData</code></a></span> = <span class="idlMemberValue">null</span>;</span> -};</span></pre> - </div> - <section> - <h5 id="dictionary-mediaencryptedeventinit-members">Dictionary <a class="idlType internalDFN" href="#dom-mediaencryptedeventinit" data-link-type="dfn"><code>MediaEncryptedEventInit</code></a> Members</h5> - <dl class="dictionary-members" data-dfn-for="MediaEncryptedEventInit" data-link-for="MediaEncryptedEventInit"><dt><dfn data-dfn-for="mediaencryptedeventinit" data-dfn-type="dfn" id="dom-mediaencryptedeventinit-initdatatype" data-idl="" data-title="initDataType"><code>initDataType</code></dfn> of type <span class="idlMemberType">DOMString</span>, defaulting to <code>""</code></dt> - <dd> - The <a href="#initialization-data-type">Initialization Data Type</a>. - </dd><dt><dfn data-dfn-for="mediaencryptedeventinit" data-dfn-type="dfn" id="dom-mediaencryptedeventinit-initdata" data-idl="" data-title="initData"><code>initData</code></dfn> of type <span class="idlMemberType">ArrayBuffer</span>, nullable, defaulting to <code>null</code></dt> - <dd> - The <a href="#initialization-data">Initialization Data</a>. - </dd> - </dl> - </section> - </div> - </section> - </section> - - <section id="htmlmediaelement-events" class="informative"> - <h3 id="x7.2-event-summary"><span class="secno">7.2 </span>Event Summary</h3> - <p><em>This section is non-normative.</em></p> - - <table class="old-table"> - <thead> - <tr> - <th>Event name</th> - <th>Interface</th> - <th>Dispatched when...</th> - <th>Preconditions</th> - </tr> - </thead> - <tbody> - <tr> - <td><dfn id="dom-evt-encrypted"><code>encrypted</code></dfn></td> - <td><a href="#dom-mediaencryptedevent" class="internalDFN" data-link-type="dfn"><code>MediaEncryptedEvent</code></a></td> - <td>The user agent encounters <a href="#initialization-data">Initialization Data</a> in the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a>.</td> - <td>The element's <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-readystate">readyState</a></code> is equal to or greater than <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-have_metadata">HAVE_METADATA</a></code>. - <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note105"><span>Note</span></div> - <p class="">It is possible that the element is playing or has played.</p> - </div> - </td> - </tr> - <tr> - <td><dfn id="dom-evt-waitingforkey"><code>waitingforkey</code></dfn></td> - <td><code><a href="https://www.w3.org/TR/dom/#event">Event</a></code></td> - <td>Playback is blocked waiting for a key.</td> - <td> - The <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-readystate">readyState</a></code> is equal to or less than <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-have_current_data">HAVE_CURRENT_DATA</a></code>. - The element's <var>playback blocked waiting for key</var> value is newly <code>true</code>. - </td> - </tr> - </tbody> - </table> - </section> - - <section id="htmlmediaelement-algorithms"> - <h3 id="x7.3-algorithms"><span class="secno">7.3 </span>Algorithms</h3> - - <section id="media-may-contain-encrypted-blocks"> - <h4 id="x7.3.1-media-data-may-contain-encrypted-blocks"><span class="secno">7.3.1 </span>Media Data May Contain Encrypted Blocks</h4> - <p> - The Media Data May Contain Encrypted Blocks algorithm pauses playback if the user agent requires specification of a <a href="#dom-mediakeys" class="internalDFN" data-link-type="dfn"><code>MediaKeys</code></a> object before playing - the media data. Requests to run this algorithm include a target <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#htmlmediaelement-htmlmediaelement">HTMLMediaElement</a></code> object. - </p> - <p>The following steps are run:</p> - <ol> - <li> - <p>Let the <var>media element</var> be the specified <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#htmlmediaelement-htmlmediaelement">HTMLMediaElement</a></code> object.</p> - </li> - <li> - <p>If the <var>media element</var>'s <code><a href="#dom-mediakeys">mediaKeys</a></code> attribute is null and the implementation requires specification of a <a href="#dom-mediakeys" class="internalDFN" data-link-type="dfn"><code>MediaKeys</code></a> object before decoding potentially-encrypted <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a>, run the following steps:</p> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note106"><span>Note</span></div> - <p class="">These steps may be reached when the application provides <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a> before calling <code><a href="#dom-htmlmediaelement-setmediakeys">setMediaKeys()</a></code> to provide a <a href="#dom-mediakeys" class="internalDFN" data-link-type="dfn"><code>MediaKeys</code></a> object. Selecting a <a href="#cdm">CDM</a> may affect the pipeline and/or decoders used, so some implementations - may delay playback of media data that may contain encrypted blocks until a CDM is specified by passing a <a href="#dom-mediakeys" class="internalDFN" data-link-type="dfn"><code>MediaKeys</code></a> object to <code><a href="#dom-htmlmediaelement-setmediakeys">setMediaKeys()</a></code>. - </p> - </div> - <ol> - <li> - <p>Run the <a href="#wait-for-key">Wait for Key</a> algorithm on the <var>media element</var>.</p> - </li> - <li> - <p>Wait for a signal to resume playback.</p> - </li> - </ol> - </li> - </ol> - </section> - - <section id="initdata-encountered"> - <h4 id="x7.3.2-initialization-data-encountered"><span class="secno">7.3.2 </span>Initialization Data Encountered</h4> - <p> - The Initialization Data Encountered algorithm queues an <code><a href="#dom-evt-encrypted">encrypted</a></code> event for <a href="#initialization-data">Initialization Data</a> encounterd in the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a>. - Requests to run this algorithm include a target <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#htmlmediaelement-htmlmediaelement">HTMLMediaElement</a></code> object. - </p> - <p>The following steps are run:</p> - <ol> - <li> - <p>Let the <var>media element</var> be the specified <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#htmlmediaelement-htmlmediaelement">HTMLMediaElement</a></code> object.</p> - </li> - <li> - <p>Let <var>initDataType</var> be the empty string.</p> - </li> - <li> - <p>Let <var>initData</var> be null.</p> - </li> - <li> - <p>If the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a> is <a href="https://www.w3.org/TR/html51/browsers.html#same-origin">CORS-same-origin</a> and <em>not</em> <a href="#mixed-content">mixed content</a>, - run the following steps:</p> - <ol> - <li> - <p>Let <var>initDataType</var> be the string representing the <a href="#initialization-data-type">Initialization Data Type</a> of the Initialization Data.</p> - </li> + <dt><code><a href="#idl-def-MediaKeySessionType.persistent-usage-record">"persistent-usage-record"</a></code></dt> + <dd> + <ol> <li> - <p>Let <var>initData</var> be the Initialization Data.</p> + <p>Initialize this object's <var>record of key usage</var> as follows.</p> + <ul> + <li> + <p> + Set the list of <a href="#decryption-key-id">key IDs</a> <a href="#known-key">known</a> to the session to an empty list. + </p> + </li> + <li> + <p> + Set the <var>first decrypt time</var> to <code>null</code>. + </p> + </li> + <li> + <p> + Set the <var>latest decrypt time</var> to <code>null</code>. + </p> + </li> + </ul> </li> - </ol> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note107"><span>Note</span></div> - <p class="">While the media element may allow loading of "Optionally-blockable Content" [<cite><a class="bibref" href="#bib-MIXED-CONTENT">MIXED-CONTENT</a></cite>], the user agent <em class="rfc2119" title="MUST NOT">MUST NOT</em> expose - Initialization Data from such media data to the application.</p> - </div> - </li> - <li> - <p><a href="https://www.w3.org/TR/html51/webappapis.html#queuing">Queue a task</a> to create an event named <code><a href="#dom-evt-encrypted">encrypted</a></code> that does not bubble and is not cancellable using the <a href="#dom-mediaencryptedevent" - class="internalDFN" data-link-type="dfn"><code>MediaEncryptedEvent</code></a> interface with its <var>type</var> attribute set to <code>encrypted</code> and its <var>isTrusted</var> attribute initialized to <code>true</code>, - and dispatch it at the <var>media element</var>.</p> - <p>The event interface <a href="#dom-mediaencryptedevent" class="internalDFN" data-link-type="dfn"><code>MediaEncryptedEvent</code></a> has:</p> - <ul style="list-style-type:none"> <li> - <code><a href="#dom-mediaencryptedevent-initdatatype">initDataType</a></code> = <var>initDataType</var><br><br> - <code><a href="#dom-mediaencryptedevent-initdata">initData</a></code> = <var>initData</var> + <p>Let <var>requested license type</var> be a non-persistable license that will persist a <a href="#record-of-key-usage">record of key usage</a>.</p> </li> - </ul> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note108"><span>Note</span></div> - <p class=""><code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-readystate">readyState</a></code> is <em>not</em> changed and no algorithms are aborted. This event merely provides information.</p> - </div> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note109"><span>Note</span></div> - <p class="">The <code><a href="#dom-mediaencryptedevent-initdata">initData</a></code> attribute will be null if the media data is <em>not</em> <a href="https://www.w3.org/TR/html51/browsers.html#same-origin">CORS-same-origin</a> or is - <a href="#mixed-content">mixed content</a>. Applications may retrieve the Initialization Data from an alternate source. - </p> - </div> + </ol> + </dd> + </dl> </li> - </ol> - </section> - <section id="encrypted-block-encountered"> - <h4 id="x7.3.3-encrypted-block-encountered"><span class="secno">7.3.3 </span>Encrypted Block Encountered</h4> - <p> - The Encrypted Block Encountered algorithm queues a block of encrypted media data for decryption and attempts to decrypt if possible. Requests to run this algorithm include a target <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#htmlmediaelement-htmlmediaelement">HTMLMediaElement</a></code> object. - </p> - <p>The following steps are run:</p> - <ol> - <li> - <p>Let the <var>media element</var> be the specified <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#htmlmediaelement-htmlmediaelement">HTMLMediaElement</a></code> object.</p> - </li> - <li> - <p>Let <var>block</var> be the block of encrypted media data.</p> - </li> - <li> - <p>Add <var>block</var> to the end of the <var>media element</var>'s <var>encrypted block queue</var>.</p> - </li> - <li> - <p>If the <var>media element</var>'s <var>decryption blocked waiting for key</var> value is <code>false</code>, run the <a href="#attempt-to-decrypt">Attempt to Decrypt</a> algorithm.</p> - <!-- While media-may-contain-encrypted-blocks may also result in waiting for a key without setting this variable, it should not be possible to reach this algorithm in that case. --> - </li> - </ol> - </section> - <section id="attempt-to-decrypt"> - <h4 id="x7.3.4-attempt-to-decrypt"><span class="secno">7.3.4 </span>Attempt to Decrypt</h4> - <p> - The Attempt to Decrypt algorithm attempts to decrypt media data that is queued for decryption. Requests to run this algorithm include a target <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#htmlmediaelement-htmlmediaelement">HTMLMediaElement</a></code> object. - </p> - <p>The following steps are run:</p> - <ol> - <li> - <p>Let the <var>media element</var> be the specified <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#htmlmediaelement-htmlmediaelement">HTMLMediaElement</a></code> object.</p> - </li> - <li> - <p>If the <var>media element</var>'s <var>encrypted block queue</var> is empty, abort these steps.</p> + <li><p>Let <var>session id</var> be a unique <a href="#session-id">Session ID</a> string.</p> + <p>If the result of running the <a href="#is-persistent-session-type">Is persistent session type?</a> algorithm on <var>session type</var> is <code>true</code>, the ID <em class="rfc2119" title="MUST">MUST</em> be unique within the <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> of this object's <a href="https://www.w3.org/TR/dom/#concept-document">Document</a> over time, including across Documents and browsing sessions.</p> </li> <li> - <p>If the <var>media element</var>'s <code><a href="#dom-mediakeys">mediaKeys</a></code> attribute is not null, run the following steps:</p> - <ol> + <dl class="switch"> + <dt>If a license request for the <var>requested license type</var> can be generated based on the <var>sanitized init data</var>:</dt> + <dd> + <ol> <li> - <p>Let <var>media keys</var> be the <a href="#dom-mediakeys" class="internalDFN" data-link-type="dfn"><code>MediaKeys</code></a> object referenced by that attribute.</p> + <p> + Let <var>message</var> be a license request for the <var>requested license type</var> generated based on the <var>sanitized init data</var> + interpreted per <var>initDataType</var>. + </p> + <p> + The <var>cdm</var> <em class="rfc2119" title="MUST NOT">MUST NOT</em> use any stream-specific data, including <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a>, not provided via the + <var>sanitized init data</var>. + </p> + <p>The <var>cdm</var> <em class="rfc2119" title="SHOULD NOT">SHOULD NOT</em> store session data, including the session ID, at this point. See <a href="#session-storage">Session Storage and Persistence</a>.</p> </li> <li> - <p>Let <var>cdm</var> be the CDM instance represented by <var>media keys</var>'s <var>cdm instance</var> value.</p> + <p> + Let <var>message type</var> be <code><a href="#idl-def-MediaKeyMessageType.license-request">"license-request"</a></code>. + </p> </li> + </ol> + </dd> + <dt>Otherwise:</dt> + <dd> + <ol> <li> - <p>If <var>cdm</var> is no longer usable for any reason, run the following steps:</p> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note110"><span>Note</span></div> - <p class="">These steps are intended to be run on unrecoverable failures of the CDM.</p> - </div> - <ol> - <li> - <p>Run the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#fatal-decode-error">media data is corrupted</a> steps of the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#resource-fetch-algorithm">resource fetch algorithm</a>.</p> - </li> - <li> - <p>Run the <a href="#cdm-unavailable">CDM Unavailable</a> algorithm on <var>media keys</var>.</p> - </li> - <li> - <p>Abort these steps.</p> - </li> - </ol> + <p> + Let <var>message</var> be the request that needs to be processed before a license request request + for the <var>requested license type</var> can be generated based on the <var>sanitized init data</var>. + </p> + <p> + In a subsequent call to <code><a href="#dom-mediakeysession-update">update()</a></code> the CDM <em class="rfc2119" title="MUST">MUST</em> generate a license request for the <var>requested license type</var> + based on the <var>sanitized init data</var>, which is interpreted per <var>initDataType</var>. + </p> </li> <li> - <p>If there is at least one <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> created by the <var>media keys</var> that is not <a href="#media-key-session-closed">closed</a>, - run the following steps:</p> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note111"><span>Note</span></div> - <p class="">This check ensures the <var>cdm</var> has finished loading and is a prerequisite for a matching key being available.</p> - </div> - <ol> - <li> - <p>Let <var>block</var> be the first entry in the <var>media element</var>'s <var>encrypted block queue</var>.</p> - </li> - <li> - <p>Let the <var>block key ID</var> be the key ID of <var>block</var>.</p> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note112"><span>Note</span></div> - <p class="">The key ID is generally specified by the container.</p> - </div> - </li> - <li> - <p>Use the <var>cdm</var> to execute the following steps:</p> - <ol> - <li> - <p>Let <var>available keys</var> be the union of keys in sessions that were created by the <var>media keys</var>.</p> - </li> - <li> - <p>Let <var>block key</var> be null.</p> - </li> - <li> - <p>If any of the <var>available keys</var> corresponds to the <var>block key ID</var> and is <a href="#usable-for-decryption">usable for decryption</a>, let <var>session</var> be a - <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object containing that key and let <var>block key</var> be that key.</p> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note113"><span>Note</span></div> - <p class="">If multiple sessions contain a key that is <a href="#usable-for-decryption">usable for decryption</a> for the <var>block key ID</var>, which session and key to use is <a href="#key-system">Key System</a>-dependent.</p> - </div> - </li> - <li> - <p>If the status of any of the <var>available keys</var> changed as the result of running the preceding step, <a href="https://www.w3.org/TR/html51/webappapis.html#queuing">queue a task</a> to run the <a href="#update-key-statuses">Update Key Statuses</a> algorithm on each affected <var>session</var>, providing all <a href="#decryption-key-id">key ID(s)</a> in the session along with the appropriate <a href="#dom-mediakeystatus" class="internalDFN" data-link-type="dfn"><code>MediaKeyStatus</code></a> value(s) for each.</p> - </li> - <li> - <p>If <var>block key</var> is not null, run the following steps:</p> - <ol> - <li> - <p>If <var>session</var>'s <var>session type</var> is <code><a href="#idl-def-MediaKeySessionType.persistent-usage-record">"persistent-usage-record"</a></code>, run the following steps:</p> - <ol> - <li> - <p>Let <var>usage</var> be <var>session</var>'s <var>record of key usage</var>.</p> - </li> - <li> - <p> - If the <var>first decrypt time</var> of <var>usage</var> is <code>null</code>, set the <var>first decrypt time</var> of <var>usage</var> to the current time, accurate to within <var><a href="#key-usage-accuracy">key usage accuracy</a></var>. - </p> - </li> - <li> - <p> - Set the <var>latest decrypt time</var> of <var>usage</var> to the current time, accurate to within <var><a href="#key-usage-accuracy">key usage accuracy</a></var>. - </p> - </li> - </ol> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note114"><span>Note</span></div> - <p class=""> - Implementations <em class="rfc2119" title="MAY">MAY</em> optimize the times at which this step is executed provided the recorded key usage times remain accurate to within <var>key usage accuracy</var>. - </p> - </div> - </li> - <li> - <p>Use the <var>cdm</var> to decrypt <var>block</var> using <var>block key</var>.</p> - </li> - <li> - <p>Follow the steps for the first matching condition from the following list:</p> - <dl class="switch"> - <dt>If decryption fails</dt> - <dd> - <ol> - <li> - <p>Run the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#fatal-decode-error">media data is corrupted</a> steps of the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#resource-fetch-algorithm">resource fetch algorithm</a>.</p> - </li> - <li> - <p>If <var>cdm</var> is no longer usable for any reason then run the <a href="#cdm-unavailable">CDM Unavailable</a> algorithm on <var>media keys</var>.</p> - </li> - <li> - <p>Abort these steps.</p> - </li> - </ol> - </dd> - <dt>Otherwise</dt> - <dd> - <ol> - <li> - <p>Remove <var>block</var> from the front of the <var>media element</var>'s <var>encrypted block queue</var>.</p> - </li> - <li> - <p>Process the decrypted block as normal.</p> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note115"><span>Note</span></div> - <p class="">In other words, decode the block.</p> - </div> - </li> - <li> - <p>Return to the beginning of this algorithm.</p> - </li> - </ol> - - </dd> - </dl> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note116"><span>Note</span></div> - <p class="">Not all decryption problems (e.g., using the wrong key) will result in a decryption failure. In such cases, no error is fired here but one may be fired during decode.</p> - </div> - </li> - </ol> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note117"><span>Note</span></div> - <p class="">Otherwise, there is no key for the <var>block key ID</var> in any session so continue.</p> - </div> - </li> - </ol> - </li> - </ol> + <p> + Let <var>message type</var> reflect the type of <var>message</var>, either <code><a href="#idl-def-MediaKeyMessageType.license-request">"license-request"</a></code> or <code><a href="#idl-def-MediaKeyMessageType.individualization-request">"individualization-request"</a></code>. + </p> </li> - </ol> + </ol> + </dd> + </dl> </li> + </ol> + </li> + <li> + <p><a href="https://www.w3.org/TR/html51/webappapis.html#queuing">Queue a task</a> to run the following steps:</p> + <ol> + <li><p>If any of the preceding steps failed, reject <var>promise</var> with a new <code><a href="https://heycam.github.io/webidl/#dfn-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-mediakeysession-sessionid">sessionId</a></code> attribute to <var>session id</var>.</p></li> + <li><p>Set this object's <var>callable</var> value to true.</p></li> + <li><p>Run the <a href="#queue-message">Queue a "message" Event</a> algorithm on the <var>session</var>, providing <var>message type</var> and <var>message</var>.</p> + </li><li> + <p>Resolve <var>promise</var>.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-65" aria-level="4"><span>Note</span></div><p class="">Since promise handlers are queued as microtasks, these will be executed ahead of any events queued by the preceding steps.</p></div> + </li> + </ol> + </li> + </ol> + </li> + <li><p>Return <var>promise</var>.</p></li> + </ol></dd><dt><dfn data-dfn-for="mediakeysession" data-dfn-type="dfn" id="dom-mediakeysession-load" data-idl="" data-title="load" data-lt="load|load()"><code id="load">load</code></dfn></dt><dd> + <p>Loads the data stored for the specified session into this object.</p> + + + + + <table class="parameters"><tbody><tr><th>Parameter</th><th>Type</th><th>Nullable</th><th>Optional</th><th>Description</th></tr><tr><td class="prmName">sessionId</td><td class="prmType"><code>DOMString</code></td><td class="prmNullFalse"><span role="img" aria-label="False">✘</span></td><td class="prmOptFalse"><span role="img" aria-label="False">✘</span></td><td class="prmDesc"> + The <a href="#session-id">Session ID</a> of the session to load. + </td></tr></tbody></table><div><em>Return type: </em><code>Promise<boolean></code></div><p>When this method is invoked, the user agent must run the following steps:</p><ol class="method-algorithm"> + <li><p>If this object's <var>closing or closed</var> value is true, return a promise rejected with an <code><a href="#dfn-InvalidStateError">InvalidStateError</a></code>.</p></li> + <li><p>If this object's <var>uninitialized</var> value is false, return a promise rejected with an <code><a href="#dfn-InvalidStateError">InvalidStateError</a></code>.</p></li> + <li><p>Let this object's <var>uninitialized</var> value be false.</p></li><!-- For simplicity and consistency, this object cannot be reused after any failure. --> + <li><p>If <var>sessionId</var> is the empty string, return a promise rejected with a newly created <code><a href="#dfn-TypeError">TypeError</a></code>.</p></li> + <li><p>If the result of running the <a href="#is-persistent-session-type">Is persistent session type?</a> algorithm on this object's <var>session type</var> is <code>false</code>, return a promise rejected with a newly created <code><a href="#dfn-TypeError">TypeError</a></code>.</p></li> + <li><p>Let <var>origin</var> be the <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> of this object's <a href="https://www.w3.org/TR/dom/#concept-document">Document</a>.</p></li> + <li><p>Let <var>promise</var> be a new promise.</p></li> + <li><p>Run the following steps in parallel:</p> + <ol> + <li><p>Let <var>sanitized session ID</var> be a validated and/or sanitized version of <var>sessionId</var>.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-66" aria-level="4"><span>Note</span></div><p class="">The user agent should thoroughly validate the sessionId value before passing it to the CDM. + At a minimum, this should include checking that the length and value are reasonable (e.g., not longer than tens of characters and alphanumeric). + </p></div> + </li> + <li><p>If the preceding step failed, or if <var>sanitized session ID</var> is empty, reject <var>promise</var> with a newly created <code><a href="#dfn-TypeError">TypeError</a></code>.</p></li> + <li><p>If there is a <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object that is not <a href="#media-key-session-closed">closed</a> in this object's <a href="https://www.w3.org/TR/dom/#concept-document">Document</a> whose <code><a href="#dom-mediakeysession-sessionid">sessionId</a></code> attribute is <var>sanitized session ID</var>, reject <var>promise</var> with a <code><a href="#dfn-QuotaExceededError">QuotaExceededError</a></code>.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-67" aria-level="4"><span>Note</span></div><p class="">In other words, do not create a session if a non-closed session, regardless of type, already exists for this <var>sanitized session ID</var> in this browsing context.</p></div> + </li> + <li><p>Let <var>expiration time</var> be <code>NaN</code>.</p></li> + <li><p>Let <var>message</var> be null.</p></li> + <li><p>Let <var>message type</var> be null.</p></li> + <li><p>Let <var>cdm</var> be the CDM instance represented by this object's <var>cdm instance</var> value.</p></li> + <li><p>Use the <var>cdm</var> to execute the following steps:</p> + <ol> + <li><p>If there is no data stored for the <var>sanitized session ID</var> in the <var>origin</var>, resolve <var>promise</var> with <code>false</code> and abort these steps.<!-- Per https://github.com/w3ctag/promises-guide#rejections-should-be-used-for-exceptional-situations. --></p></li> + <li><p>If the stored session's <var>session type</var> is not the same as the current <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> <var>session type</var>, reject <var>promise</var> with a newly created <code><a href="#dfn-TypeError">TypeError</a></code>.</p></li> + <li><p>Let <var>session data</var> be the data stored for the <var>sanitized session ID</var> in the <var>origin</var>. + This <em class="rfc2119" title="MUST NOT">MUST NOT</em> include data from other origin(s) or that is not associated with an origin.</p></li> + <li><p>If there is a <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object that is not <a href="#media-key-session-closed">closed</a> in any <a href="https://www.w3.org/TR/dom/#concept-document">Document</a> and that + represents the <var>session data</var>, reject <var>promise</var> with a <code><a href="#dfn-QuotaExceededError">QuotaExceededError</a></code>.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-68" aria-level="4"><span>Note</span></div><p class="">In other words, do not create a session if a non-closed persistent session already exists for this <var>sanitized session ID</var> in any browsing context.</p></div> + </li> + <li><p>Load the <var>session data</var>.</p></li> + <li><p>If the <var>session data</var> indicates an <a href="#expiration-time">expiration time</a> for the session, let <var>expiration time</var> be that expiration time.</p></li> + <li><p>If a message needs to be sent, execute the following steps:</p> + <ol> + <li><p>Let <var>message</var> be a message generated based on the <var>session data</var>.</p></li> + <li><p>Let <var>message type</var> be the appropriate <a href="#dom-mediakeymessagetype" class="internalDFN" data-link-type="dfn"><code>MediaKeyMessageType</code></a> for the message.</p></li> + </ol> + </li> + </ol> + </li> + <li> + <p><a href="https://www.w3.org/TR/html51/webappapis.html#queuing">Queue a task</a> to run the following steps:</p> + <ol> + <li><p>If any of the preceding steps failed, reject <var>promise</var> with a the appropriate <a href="#error-names">error name</a>.</p></li> + <li><p>Set the <code><a href="#dom-mediakeysession-sessionid">sessionId</a></code> attribute to <var>sanitized session ID</var>.</p></li> + <li><p>Set this object's <var>callable</var> value to true.</p></li> <li> - <p>Set the <var>media element</var>'s <var>decryption blocked waiting for key</var> value to <code>true</code>.</p> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note118"><span>Note</span></div> - <p class="">This step is reached when there is no key that is <a href="#usable-for-decryption">usable for decryption</a> for <var>block</var>.</p> - </div> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note119"><span>Note</span></div> - <div class=""> - <p>Once the user agent has rendered the blocks preceding the block that cannot be decrypted (as much as it can, such as, all complete video frames), it will run the <a href="#wait-for-key">Wait for Key</a> algorithm.</p> - <p>That algorithm is not run directly here in order to allow implementations to decrypt and decode media data ahead of the ahead of the current playback position without affecting the visible behavior.</p> - </div> - </div> + <p> + If the loaded session contains information about any keys (there are <a href="#known-key">known keys</a>), run the <a href="#update-key-statuses">Update Key Statuses</a> algorithm on the <var>session</var>, providing each key's <a href="#decryption-key-id">key ID</a> along with the appropriate <a href="#dom-mediakeystatus" class="internalDFN" data-link-type="dfn"><code>MediaKeyStatus</code></a>. + </p> + <p>Should additional processing be necessary to determine with certainty the status of a key, use <code><a href="#idl-def-MediaKeyStatus.status-pending">"status-pending"</a></code>. + Once the additional processing for one or more keys has completed, run the <a href="#update-key-statuses">Update Key Statuses</a> algorithm again with the actual status(es). + </p> </li> - </ol> - - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note120"><span>Note</span></div> - <div class=""> - <p>For frame-based encryption, this may be implemented as follows when the media element attempts to decode a frame as part of the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#resource-fetch-algorithm">resource fetch algorithm</a>:</p> - <ol> - <li> - <p>Let <var>encrypted</var> be false.</p> - </li> - <li> - <p>Detect whether the frame is encrypted.</p> - <dl class="switch"> - <dt>If the frame is encrypted</dt> - <dd>Run the steps above.</dd> - <dt>Otherwise</dt> - <dd>Continue.</dd> - </dl> - </li> - <li> - <p>Decode the frame.</p> - </li> - <li> - <p>Provide the frame for rendering.</p> - </li> - </ol> - </div> - </div> - </section> + <li><p>Run the <a href="#update-expiration">Update Expiration</a> algorithm on the <var>session</var>, providing <var>expiration time</var>.</p></li> + <li><p>If <var>message</var> is not null, run the <a href="#queue-message">Queue a "message" Event</a> algorithm on the <var>session</var>, providing <var>message type</var> and <var>message</var>.</p></li> - <section id="wait-for-key"> - <h4 id="x7.3.5-wait-for-key"><span class="secno">7.3.5 </span>Wait for Key</h4> - <p> - The Wait for Key algorithm queues a <code><a href="#dom-evt-waitingforkey">waitingforkey</a></code> event and updates <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-readystate">readyState</a></code>. - It should only be called when the <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#htmlmediaelement-htmlmediaelement">HTMLMediaElement</a></code> object is <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#potentially-playing">potentially playing</a> and its <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-readystate">readyState</a></code> is equal to <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-have_future_data">HAVE_FUTURE_DATA</a></code> or greater. Requests to run this algorithm include a target <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#htmlmediaelement-htmlmediaelement">HTMLMediaElement</a></code> object. - </p> - <p>The following steps are run:</p> - <ol> - <li> - <p>Let the <var>media element</var> be the specified <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#htmlmediaelement-htmlmediaelement">HTMLMediaElement</a></code> object.</p> - </li> - <li> - <p>If the <var>media element</var>'s <var>playback blocked waiting for key</var> value is <code>true</code>, abort these steps.</p> - </li> <li> - <p>Set the <var>media element</var>'s <var>playback blocked waiting for key</var> value to <code>true</code>.</p> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note121"><span>Note</span></div> - <p class="">As a result of the above step, the media element will become a <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#blocked-media-element">blocked media element</a> if it wasn't already. In that case, the media - element will stop playback.</p> - </div> + <p>Resolve <var>promise</var> with <code>true</code>.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-69" aria-level="4"><span>Note</span></div><p class="">Since promise handlers are queued as microtasks, these will be executed ahead of any events queued by the preceding steps.</p></div> </li> - <li> - <p>Follow the steps for the first matching condition from the following list:</p> - <dl class="switch"> - <dt>If data for the immediate <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#current-position">current playback position</a> is available</dt> - <dd> - <p>Set the <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-readystate">readyState</a></code> of <var>media element</var> to <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-have_current_data">HAVE_CURRENT_DATA</a></code>.</p> + </ol> + </li> + </ol> + </li> + <li><p>Return <var>promise</var>.</p></li> + </ol></dd><dt><dfn data-dfn-for="mediakeysession" data-dfn-type="dfn" id="dom-mediakeysession-update" data-idl="" data-title="update" data-lt="update|update()"><code id="update">update</code></dfn></dt><dd> + <p>Provides messages, including licenses, to the CDM.</p> + + + + + <table class="parameters"><tbody><tr><th>Parameter</th><th>Type</th><th>Nullable</th><th>Optional</th><th>Description</th></tr><tr><td class="prmName">response</td><td class="prmType"><code>BufferSource</code></td><td class="prmNullFalse"><span role="img" aria-label="False">✘</span></td><td class="prmOptFalse"><span role="img" aria-label="False">✘</span></td><td class="prmDesc"> + A message to be provided to the CDM. + The contents are <a href="#key-system">Key System</a>-specific. + It <em class="rfc2119" title="MUST NOT">MUST NOT</em> contain executable code. + </td></tr></tbody></table><div><em>Return type: </em><code>Promise<void></code></div><p>When this method is invoked, the user agent must run the following steps:</p><ol class="method-algorithm"> + <li><p>If this object's <var>closing or closed</var> value is true, return a promise rejected with an <code><a href="#dfn-InvalidStateError">InvalidStateError</a></code>.</p></li> + <li><p>If this object's <var>callable</var> value is false, return a promise rejected with an <code><a href="#dfn-InvalidStateError">InvalidStateError</a></code>.</p></li> + <li><p>If <var>response</var> is an empty array, return a promise rejected with a newly created <code><a href="#dfn-TypeError">TypeError</a></code>.</p></li> + <li><p>Let <var>response copy</var> be a copy of the contents of the <var>response</var> parameter.</p></li> + <li><p>Let <var>promise</var> be a new promise.</p></li> + <li><p>Run the following steps in parallel:</p> + <ol> + <li><p>Let <var>sanitized response</var> be a validated and/or sanitized version of <var>response copy</var>.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-70" aria-level="4"><span>Note</span></div><p class="">The user agent should thoroughly validate the response before passing it to the CDM. + This may include verifying values are within reasonable limits, stripping irrelevant data or fields, pre-parsing it, sanitizing it, and/or generating a fully sanitized version. + The user agent should check that the length and values of fields are reasonable. + Unknown fields should be rejected or removed. + </p></div> + </li> + <li><p>If the preceding step failed, or if <var>sanitized response</var> is empty, reject <var>promise</var> with a newly created <code><a href="#dfn-TypeError">TypeError</a></code>.</p></li> + <li><p>Let <var>message</var> be null.</p></li> + <li><p>Let <var>message type</var> be null.</p></li> + <li><p>Let <var>session closed</var> be false.</p></li> + <li><p>Let <var>cdm</var> be the CDM instance represented by this object's <var>cdm instance</var> value.</p></li> + <li><p>Use the <var>cdm</var> to execute the following steps:</p> + <ol> + <li><p>If the format of <var>sanitized response</var> is invalid in any way, reject <var>promise</var> with a newly created <code><a href="#dfn-TypeError">TypeError</a></code>.</p></li> + <li><p>Process <var>sanitized response</var>, following the stipulation for the first matching condition from the following list:</p> + <dl class="switch"> + <dt>If <var>sanitized response</var> contains a license or key(s)</dt> + <dd> + <div class="note"><div role="heading" class="note-title marker" id="h-note-71" aria-level="4"><span>Note</span></div><p class="">This includes an initial license, an updated license, and a license renewal message.</p></div> + <p>Process <var>sanitized response</var>, following the stipulation for the first matching condition from the following list:</p> + <dl class="switch"> + <dt>If <var>sessionType</var> is <code><a href="#idl-def-MediaKeySessionType.temporary">"temporary"</a></code> and <var>sanitized response</var> does not specify that session data, including any license, key(s), or similar session data it contains, should be stored</dt> + <dd>Process <var>sanitized response</var>, not storing any session data.</dd> + <dt>If <var>sessionType</var> is <code><a href="#idl-def-MediaKeySessionType.persistent-license">"persistent-license"</a></code> and <var>sanitized response</var> contains a persistable license</dt> + <dd>Process <var>sanitized response</var>, storing the license/key(s) and related session data contained in <var>sanitized response</var>. + Such data <em class="rfc2119" title="MUST">MUST</em> be stored such that only the <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> of this object's <a href="https://www.w3.org/TR/dom/#concept-document">Document</a> can access it. </dd> - <dt>Otherwise</dt> + <dt>If <var>sessionType</var> is <code><a href="#idl-def-MediaKeySessionType.persistent-usage-record">"persistent-usage-record"</a></code> and <var>sanitized response</var> contains a non-persistable license</dt> <dd> - <p>Set the <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-readystate">readyState</a></code> of <var>media element</var> to <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-have_metadata">HAVE_METADATA</a></code>.</p> + <p>Run the following steps:</p> + <ol> + <li> + <p> + Process <var>sanitized response</var>, not storing any session data. + </p> + </li> + <li> + <p> + If processing <var>sanitized response</var> results in the addition of keys to the set of <a href="#known-key">known keys</a>, add the <a href="#decryption-key-id">key IDs</a> of these keys to this object's <var>record of key usage</var>. + </p> + </li> + </ol> </dd> - </dl> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note122"><span>Note</span></div> - <p class=""> - In other words, if the video frame and audio data for the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#current-position">current playback position</a> have been decoded because they were unencrypted - and/or successfully decrypted, set <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-readystate">readyState</a></code> to <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-have_current_data">HAVE_CURRENT_DATA</a></code>. - Otherwise, including if this was previously the case but the data is no longer available, set <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-readystate">readyState</a></code> to <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-have_metadata">HAVE_METADATA</a></code>. - </p> - </div> - </li> - <li> - <p><a href="https://www.w3.org/TR/html51/webappapis.html#queuing">Queue a task</a> to <a href="https://www.w3.org/TR/html51/webappapis.html#firing-a-simple-event-named-e">fire a simple event</a> named <code><a href="#dom-evt-waitingforkey">waitingforkey</a></code> at the <var>media element</var>.</p> - </li> - <li> - <p>Suspend playback.</p> - </li> - </ol> - </section> - - <section id="resume-playback"> - <h4 id="x7.3.6-attempt-to-resume-playback-if-necessary"><span class="secno">7.3.6 </span>Attempt to Resume Playback If Necessary</h4> - <p> - The Attempt to Resume Playback If Necessary algorithm resumes playback if the media element is blocked waiting for a key and necessary key is currently <a href="#usable-for-decryption">usable for decryption</a> Requests to run this - algorithm include a target <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#htmlmediaelement-htmlmediaelement">HTMLMediaElement</a></code> object. - </p> - <p>The following steps are run:</p> - <ol> - <li> - <p>Let the <var>media element</var> be the specified <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#htmlmediaelement-htmlmediaelement">HTMLMediaElement</a></code> object.</p> - </li> - <li> - <p>If the <var>media element</var>'s <var>playback blocked waiting for key</var> is <code>false</code>, abort these steps.</p> - </li> - <li> - <p>Run the <a href="#attempt-to-decrypt">Attempt to Decrypt</a> algorithm on the <var>media element</var>.</p> - </li> - <li> - <p>If the user agent can advance the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#current-position">current playback position</a> in the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#direction-of-playback">direction of playback</a>:</p> - <ol> - <li> - <p>Set the <var>media element</var>'s <var>decryption blocked waiting for key</var> value to <code>false</code>.</p> - </li> + <dt>Otherwise</dt> + <dd><p>Reject <var>promise</var> with a newly created <code><a href="#dfn-TypeError">TypeError</a></code>.</p></dd> + </dl> + <p>See also <a href="#session-storage">Session Storage and Persistence</a>.</p> + <p>State information, including keys, for each session <em class="rfc2119" title="MUST">MUST</em> be stored in such a way that closing one session does not affect the observable state in other session(s), even if they contain overlapping key IDs.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-72" aria-level="4"><span>Note</span></div><p class="">When <var>sanitized response</var> contains key(s) and/or related data, <var>cdm</var> will likely store (in memory) the key and related data indexed by key ID.</p></div> + <div class="note"><div role="heading" class="note-title marker" id="h-note-73" aria-level="4"><span>Note</span></div><p class="">The replacement algorithm within a session is <a href="#key-system">Key System</a>-dependent.</p></div> + <div class="note"><div role="heading" class="note-title marker" id="h-note-74" aria-level="4"><span>Note</span></div><p class="">It is <em class="rfc2119" title="RECOMMENDED">RECOMMENDED</em> that CDM implementations support a standard and reasonably high minimum number of keys per <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object, including a standard replacement algorithm, and a standard and reasonably high minimum number of <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> objects. + This enables a reasonable number of key rotation algorithms to be implemented across user agents and may reduce the likelihood of playback interruptions in use cases that involve various streams in the same element (e.g., adaptive streams, various audio and video tracks) using different keys. + </p></div> + </dd> + <dt>If <var>sanitized response</var> contains a <a href="#record-of-license-destruction">record of license destruction</a> acknowledgement and <var>sessionType</var> is <code><a href="#idl-def-MediaKeySessionType.persistent-license">"persistent-license"</a></code></dt> + <dd> + <p>Run the following steps:</p> + <ol> <li> - <p>Set the <var>media element</var>'s <var>playback blocked waiting for key</var> value to <code>false</code>.</p> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note123"><span>Note</span></div> - <p class="">As a result of the above step, the media element may no longer be a <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#blocked-media-element">blocked media element</a> and thus playback may resume.</p> - </div> + <p> + Close the <a href="#key-session">key session</a> and clear <em>all</em> stored session data associated with this object, + including the <code><a href="#dom-mediakeysession-sessionid">sessionId</a></code> and <a href="#record-of-license-destruction">record of license destruction</a>. + </p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-75" aria-level="4"><span>Note</span></div><p class="">A subsequent call to <code><a href="#dom-mediakeysession-load">load()</a></code> with the value of this object's <code><a href="#dom-mediakeysession-sessionid">sessionId</a></code> would fail because there is no data stored for that session ID.</p></div> </li> + <li><p>Set <var>session closed</var> to true.</p></li> + </ol> + </dd> + <dt>If <var>sanitized response</var> contains a <a href="#record-of-key-usage">record of key usage</a> acknowledgement and <var>sessionType</var> is <code><a href="#idl-def-MediaKeySessionType.persistent-usage-record">"persistent-usage-record"</a></code></dt> + <dd> + <p>Run the following steps:</p> + <ol> <li> - <p> - Set the <var>media element</var>'s <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-readystate">readyState</a></code> value to <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-have_current_data">HAVE_CURRENT_DATA</a></code>, - <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-have_future_data">HAVE_FUTURE_DATA</a></code> or - <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-have_enough_data">HAVE_ENOUGH_DATA</a></code> as <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#ready-states">appropriate</a></code>. - </p> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note124"><span>Note</span></div> - <div class=""> - <p> - States beyond <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-have_current_data">HAVE_CURRENT_DATA</a></code> and the <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#eventdef-media-canplaythrough">canplaythrough</a></code> event do not (or are unlikely to) consider key availability beyond the current key. - </p> - <p> - The change in ready state may also cause HTMLMediaElement events to be fired as described <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#ready-states">here</a></code>. - </p> - </div> - </div> + <p> + Close the <a href="#key-session">session</a> and clear <em>all</em> stored session data associated with this object, + including the <code><a href="#dom-mediakeysession-sessionid">sessionId</a></code> and <a href="#record-of-key-usage">record of key usage</a>. + </p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-76" aria-level="4"><span>Note</span></div><p class="">A subsequent call to <code><a href="#dom-mediakeysession-load">load()</a></code> with the value of this object's <code><a href="#dom-mediakeysession-sessionid">sessionId</a></code> would fail because there is no data stored for that session ID.</p></div> </li> - </ol> + <li><p>Set <var>session closed</var> to true.</p></li> + </ol> + </dd> + <dt>Otherwise</dt> + <dd>Process <var>sanitized response</var>, not storing any session data. + <div class="note"><div role="heading" class="note-title marker" id="h-note-77" aria-level="4"><span>Note</span></div><p class="">For example, <var>sanitized response</var> may contain information that will be used to generate another <code><a href="#dom-evt-message">message</a></code> event. + In this case, there is no need to verify the contents against the <var>sessionType</var>. + </p></div> + </dd> + </dl> </li> - </ol> - </section> - </section> - - <section id="media-element-restrictions" class="informative"> - <h3 id="x7.4-media-element-restrictions"><span class="secno">7.4 </span>Media Element Restrictions</h3> - <p><em>This section is non-normative.</em></p> - <p>Media data processed by a CDM <em class="rfc2119" title="MAY">MAY</em> be unavailable through web platform APIs in the usual way (for example using the CanvasRenderingContext2D drawImage() method and the AudioContext MediaElementAudioSourceNode). - This specification does not define conditions for such non-availability of media data, however, if media data is not available to through such APIs then they <em class="rfc2119" title="MAY">MAY</em> behave as if no media data was present - at all.</p> - <p>Where media rendering is not performed by the UA, for example in the case of a hardware-based media pipeline, the full set of HTML rendering capabilities, for example CSS Transforms, <em class="rfc2119" title="MAY">MAY</em> be unavailable. - One likely restriction is that video media <em class="rfc2119" title="MAY">MAY</em> be constrained to appear only in rectangular regions with sides parallel to the edges of the window and with normal orientation.</p> - </section> - </section> - - - <section id="implementation-requirements"> - <!--OddPage--> - <h2 id="x8.-implementation-requirements"><span class="secno">8. </span>Implementation Requirements</h2> - <p> - This section defines implementation requirements - for both user agents and <a href="#key-system">Key Systems</a>, including the <a href="#cdm">CDM</a> and server(s) - that may not be explicitly addressed in the algorithms. The requirements - here and throughout the spec apply to all implementations, regardless of whether the CDM is separate from or a part of the user agent. - </p> - - <section id="cdm-constraint-requirements"> - <h3 id="x8.1-cdm-constraints"><span class="secno">8.1 </span>CDM Constraints</h3> - <p> - User agent implementers <em class="rfc2119" title="MUST">MUST</em> ensure that CDMs do not access any information, storage or system capabilities that are not reasonably required for playback of protected media using the features of this - specification. Specifically, the CDM <em class="rfc2119" title="SHALL NOT">SHALL NOT</em>: - </p> - <ul> - <li> - <p> - Access network resources, either local or remote, except via the user agent as explicitly permitted by this specification. - </p> - </li> - <li> - <p> - Access storage (e.g., disk or memory), except where reasonably required for playback of protected media using the features of this specification. - </p> - </li> - <li> - <p> - Access user data other than CDM state and <a href="#persistent-state-requirements">persistent data</a>. - </p> - </li> - <li> - <p> - Access hardware components or devices, except where reasonably required for playback of protected media using the features of this specification. - </p> + <li><p>If a message needs to be sent, execute the following steps:</p> + <ol> + <li><p>Let <var>message</var> be that message.</p></li> + <li><p>Let <var>message type</var> be the appropriate <a href="#dom-mediakeymessagetype" class="internalDFN" data-link-type="dfn"><code>MediaKeyMessageType</code></a> for the message.</p></li> + </ol> + </li> + </ol> </li> - </ul> - <p> - User Agent implementers may use various techniques to meet the above requirements. For example, a User Agent implementer also implementing their own CDM may include the above as design requirements for that component. A User Agent implementer making use - of a third party CDM may ensure that it executes in a constrained environment (e.g., "sandbox") without access to the prohibited information and components. - </p> - </section> - - <section id="messaging-requirements"> - <h3 id="x8.2-messages-and-communication"><span class="secno">8.2 </span>Messages and Communication</h3> - <p> - All messages and communication to and from the CDM, such as between the CDM and a license server, <em class="rfc2119" title="MUST">MUST</em> be passed through the user agent. The CDM <em class="rfc2119" title="MUST NOT">MUST NOT</em> make - direct out-of band network requests. All messages and communication other than those described in <a href="#direct-individualization">Direct Individualization</a> <em class="rfc2119" title="MUST">MUST</em> be passed through the application - via the APIs defined in this specification. Specifically, all communication that contains application-, <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a>-, or content-specific information or is sent to - a URL specified by the application or based on its origin, <em class="rfc2119" title="MUST">MUST</em> pass through the APIs. This includes all license exchange messages. - </p> - </section> - - <section id="persistent-state-requirements"> - <h3 id="x8.3-persistent-data"><span class="secno">8.3 </span>Persistent Data</h3> - <p> - Persistent Data includes all data stored by the CDM, or by the User Agent on behalf of the CDM, that exists after the destruction of the <a href="#dom-mediakeys" class="internalDFN" data-link-type="dfn"><code>MediaKeys</code></a> object. - Specifically, it includes any identifiers (including <a href="#distinctive-identifier">Distinctive Identifier(s)</a>), licenses, keys, key IDs, <a href="#record-of-license-destruction">records of license destruction</a>, or <a href="#record-of-key-usage">records of key usage</a> stored by the CDM or by the User Agent on behalf of the CDM. - </p> - <section id="use-origin-specific-key-system-storage"> - <h4 id="x8.3.1-use-origin-specific-and-browsing-profile-specific-key-system-storage"><span class="secno">8.3.1 </span>Use origin-specific and browsing profile-specific Key System storage</h4> - <p>Persistent Data that might impact messages or behavior in an application- or license server-visible way <em class="rfc2119" title="MUST">MUST</em> be stored in an <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a>-specific - and <a href="#browsing-profile">browsing profile</a>-specific way and <em class="rfc2119" title="MUST NOT">MUST NOT</em> leak to or from private browsing sessions. Specifically but not exhaustively, session data, licenses, keys and - per-origin identifiers <em class="rfc2119" title="MUST">MUST</em> be stored per-<a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> and per-<a href="#browsing-profile">browsing profile</a>. - </p> - <p> - See <a href="#session-storage">Session Storage and Persistence</a>. - </p> - </section> - <section id="allow-persistent-data-cleared"> - <h4 id="x8.3.2-allow-persistent-data-to-be-cleared"><span class="secno">8.3.2 </span>Allow Persistent Data to Be Cleared</h4> - <p> - Implementations that use Persistent Data <em class="rfc2119" title="MUST">MUST</em> allow the user to clear that data such that it is no longer retrievable both outside, such as via the APIs defined in this specification, and on the - client device. - </p> - <p> - User Agents <em class="rfc2119" title="SHOULD">SHOULD</em>: - </p> - <ul> + <li> + <p><a href="https://www.w3.org/TR/html51/webappapis.html#queuing">Queue a task</a> to run the following steps:</p> + <ol> <li> - <p> - Treat Persistent Data like other site data, such as cookies [<cite><a class="bibref" href="#bib-COOKIES">COOKIES</a></cite>]. Specifically: - </p> - <ul> + <dl class="switch"> + <dt>If <var>session closed</var> is true:</dt> + <dd> + <p>Run the <a href="#session-closed">Session Closed</a> algorithm on this object.</p> + </dd> + <dt>Otherwise:</dt> + <dd> + <p>Run the following steps:</p> + <ol> <li> - <p id="allow-persistent-data-cleared-with-cookies"> - Allow users to clear Persistent Data along with cookies [<cite><a class="bibref" href="#bib-COOKIES">COOKIES</a></cite>] and other site data. - </p> + <p> + If the set of keys <a href="#known-key">known</a> to the CDM for this object changed or the status of any key(s) changed, run the <a href="#update-key-statuses">Update Key Statuses</a> algorithm on the <var>session</var>, providing each known key's <a href="#decryption-key-id">key ID</a> along with the appropriate <a href="#dom-mediakeystatus" class="internalDFN" data-link-type="dfn"><code>MediaKeyStatus</code></a>. + </p> + <p> + Should additional processing be necessary to determine with certainty the status of a key, use <code><a href="#idl-def-MediaKeyStatus.status-pending">"status-pending"</a></code>. + Once the additional processing for one or more keys has completed, run the <a href="#update-key-statuses">Update Key Statuses</a> algorithm again with the actual status(es). + </p> </li> <li> - <p> - Allow users to clear Persistent Data as part of user agent features to clear browsing history. - </p> + <p>If the <a href="#expiration-time">expiration time</a> for the session changed, run the <a href="#update-expiration">Update Expiration</a> algorithm on the <var>session</var>, providing the new expiration time.</p> </li> <li> - <p> - Include Persistent Data in "remove all data" features. - </p> + <p>If any of the preceding steps failed, reject <var>promise</var> with a new <code><a href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code> whose name is the appropriate <a href="#error-names">error name</a>.</p> </li> <li> - <p> - Present Persistent Data in the same UI locations as other site data. - </p> + <p>If <var>message</var> is not null, run the <a href="#queue-message">Queue a "message" Event</a> algorithm on the <var>session</var>, providing <var>message type</var> and <var>message</var>.</p> </li> - </ul> + </ol> + </dd> + </dl> </li> <li> - <p> - Allow users to clear Persistent Data on a per-<a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> and per-<a href="#browsing-profile">browsing profile</a> basis, particularly as part of a "Forget - about this site" feature that forgets cookies [<cite><a class="bibref" href="#bib-COOKIES">COOKIES</a></cite>], databases, etc. associated with a particular site. - </p> + <p>Resolve <var>promise</var>.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-78" aria-level="4"><span>Note</span></div><p class="">Since promise handlers are queued as microtasks, these will be executed ahead of any events queued by the preceding steps.</p></div> </li> + </ol> + </li> + </ol> + </li> + <li><p>Return <var>promise</var>.</p></li> + </ol></dd><dt><dfn data-dfn-for="mediakeysession" data-dfn-type="dfn" id="dom-mediakeysession-close" data-idl="" data-title="close" data-lt="close|close()"><code id="close">close</code></dfn></dt><dd> + <p>Indicates that the application no longer needs the session and the CDM should release any resources associated with the session and close it. Persisted data should not be released or cleared.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-79" aria-level="4"><span>Note</span></div><p class="">The returned promise is resolved when the request has been processed, and the <code><a href="#dom-mediakeysession-closed">closed</a></code> attribute promise is resolved when the session is closed.</p></div> + + + <div><em>No parameters.</em></div><div><em>Return type: </em><code>Promise<void></code></div><p>When this method is invoked, the user agent must run the following steps:</p><ol class="method-algorithm"> + <li><p>If this object's <var>closing or closed</var> value is true, return a resolved promise.</p></li> + <li><p>If this object's <var>callable</var> value is false, return a promise rejected with an <code><a href="#dfn-InvalidStateError">InvalidStateError</a></code>.</p></li> + <li><p>Let <var>promise</var> be a new promise.</p></li> + <li><p>Set this object's <var>closing or closed</var> value to true.</p></li> + <li><p>Run the following steps in parallel:</p> + <ol> + <li><p>Let <var>cdm</var> be the CDM instance represented by this object's <var>cdm instance</var> value.</p></li> + <li> + <p>Use <var>cdm</var> to close the <a href="#key-session">key session</a> associated with this object.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-80" aria-level="4"><span>Note</span></div><p class="">Closing the key session results in the destruction of any license(s) and key(s) that have not been explicitly stored.</p></div> + </li> + <li> + <p><a href="https://www.w3.org/TR/html51/webappapis.html#queuing">Queue a task</a> to run the following steps:</p> + <ol> + <li><p>Run the <a href="#session-closed">Session Closed</a> algorithm on this object.</p></li> <li> - <p> - Ensure that operations which clear Persistent Data are sufficiently atomic to prevent a "cookie resurrection" type of recorrelation of a new identifier with the old by relying on another type of locally stored data that did not get cleared at the same - time. See <a href="#incomplete-clearing">incomplete clearing of data</a>. - </p> + <p>Resolve <var>promise</var>.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-81" aria-level="4"><span>Note</span></div><p class="">Since promise handlers are queued as microtasks, these will be executed ahead of any events queued by the preceding steps.</p></div> </li> - <li> - <p> - Present these interfaces in a way that helps users to understand the possibility of <a href="#incomplete-clearing">incomplete clearing of data</a> and enables them to delete data associated with all features that persist data, - including cookies [<cite><a class="bibref" href="#bib-COOKIES">COOKIES</a></cite>] and web storage, simultaneously. - </p> + </ol> + </li> + </ol> + </li> + <li><p>Return <var>promise</var>.</p></li> + </ol></dd><dt><dfn data-dfn-for="mediakeysession" data-dfn-type="dfn" id="dom-mediakeysession-remove" data-idl="" data-title="remove" data-lt="remove|remove()"><code id="remove">remove</code></dfn></dt><dd> + <p> + Removes all license(s) and key(s) associated with the session. + For <a href="#is-persistent-session-type">persistent session types</a>, other session data will be cleared as defined for each session type once a release message acknowledgment is processed by <code><a href="#dom-mediakeysession-update">update()</a></code>. + </p> + + + <div><em>No parameters.</em></div><div><em>Return type: </em><code>Promise<void></code></div><p>When this method is invoked, the user agent must run the following steps:</p><ol class="method-algorithm"> + <li><p>If this object's <var>closing or closed</var> value is true, return a promise rejected with an <code><a href="#dfn-InvalidStateError">InvalidStateError</a></code>.</p></li> + <li><p>If this object's <var>callable</var> value is false, return a promise rejected with an <code><a href="#dfn-InvalidStateError">InvalidStateError</a></code>.</p></li> + <li><p>Let <var>promise</var> be a new promise.</p></li> + <li><p>Run the following steps in parallel:</p> + <ol> + <li><p>Let <var>cdm</var> be the CDM instance represented by this object's <var>cdm instance</var> value.</p></li> + <li><p>Let <var>message</var> be null.</p></li> + <li><p>Let <var>message type</var> be null.</p></li> + <li><p>Use the <var>cdm</var> to execute the following steps:</p> + <ol> + <li> + <p> + If any license(s) and/or key(s) are associated with the session: + </p> + <ol> + <li> + <p> + Destroy the license(s) and/or key(s) associated with the session. + </p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-82" aria-level="4"><span>Note</span></div><p class=""> + This implies destruction of the license(s) and/or keys(s) whether they are in memory, persistent store or both. + </p></div> + </li> + <li><p>Follow the steps for the value of this object's <var>session type</var> from the following list:</p> + <dl class="switch"> + <dt><code><a href="#idl-def-MediaKeySessionType.temporary">"temporary"</a></code></dt> + <dd> + <p>Continue with the following steps.</p> + </dd> + <dt><code><a href="#idl-def-MediaKeySessionType.persistent-license">"persistent-license"</a></code></dt> + <dd> + <ol> + <li> + <p> + Let <var>record of license destruction</var> be a <a href="#record-of-license-destruction">record of license destruction</a> for the license represented by this object. + </p> + </li> + <li> + <p> + Store the <var>record of license destruction</var>. + </p> + </li> + <li> + <p> + Let <var>message</var> be a message containing or reflecting the <var>record of license destruction</var>. + </p> + </li> + </ol> + </dd> + <dt><code><a href="#idl-def-MediaKeySessionType.persistent-usage-record">"persistent-usage-record"</a></code></dt> + <dd> + <ol> + <li> + Store this object's <var>record of key usage</var>. + </li> + <li> + <p> + Let <var>message</var> be a message containing or reflecting this object's <var>record of key usage</var>. + </p> + </li> + </ol> + </dd> + </dl> + </li> + </ol> </li> + </ol> + </li> + <li> + <p><a href="https://www.w3.org/TR/html51/webappapis.html#queuing">Queue a task</a> to run the following steps:</p> + <ol> <li> - <p> - Present the interfaces for disabling and re-enabling a Key System in a way that helps users to understand the possibility of <a href="#incomplete-clearing">incomplete clearing of data</a> and enables them to delete all such - data in all persistent storage features simultaneously. - </p> + <p> + Run the <a href="#update-key-statuses">Update Key Statuses</a> algorithm on the <var>session</var>, providing all <a href="#decryption-key-id">key ID(s)</a> in the session along with the <code><a href="#idl-def-MediaKeyStatus.released">"released"</a></code> <a href="#dom-mediakeystatus" class="internalDFN" data-link-type="dfn"><code>MediaKeyStatus</code></a> value for each. + </p> </li> + <li><p>Run the <a href="#update-expiration">Update Expiration</a> algorithm on the <var>session</var>, providing <code>NaN</code>.</p></li> + <li><p>If any of the preceding steps failed, reject <var>promise</var> with a new <code><a href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code> whose name is the appropriate <a href="#error-names">error name</a>.</p></li> + <li><p>Let <var>message type</var> be <code><a href="#idl-def-MediaKeyMessageType.license-release">"license-release"</a></code>.</p></li> + <li><p>If <var>message</var> is not <code>null</code>, run the <a href="#queue-message">Queue a "message" Event</a> algorithm on the <var>session</var>, providing <var>message type</var> and <var>message</var>.</p></li> <li> - <p> - Allow users to specifically delete Persistent Data, by <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> and/or for all origins. - </p> + <p>Resolve <var>promise</var>.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-83" aria-level="4"><span>Note</span></div><p class="">Since promise handlers are queued as microtasks, these will be executed ahead of any events queued by the preceding steps.</p></div> </li> - </ul> - </section> - <section id="encrypt-or-obfuscate-persistent-data"> - <h4 id="x8.3.3-encrypt-or-obfuscate-persistent-data"><span class="secno">8.3.3 </span>Encrypt or obfuscate Persistent Data</h4> - <p>User agents <em class="rfc2119" title="SHOULD">SHOULD</em> treat Persistent Data as potentially sensitive; it is quite possible for user privacy to be compromised by the release of this information. To this end, user agents <em class="rfc2119" - title="SHOULD">SHOULD</em> ensure that Persistent Data is securely stored and when deleting data, it is promptly deleted from the underlying storage. - </p> - </section> + </ol> + </li> + </ol> + </li> + <li><p>Return <var>promise</var>.</p></li> + </ol></dd></dl></section></div> + + <section id="mediakeystatusmap-interface"> + <h3 id="x6-1-mediakeystatusmap-interface"><span class="secno">6.1 </span><dfn data-dfn-type="dfn" id="dom-mediakeystatusmap" data-idl="" data-title="MediaKeyStatusMap" data-dfn-for=""><code>MediaKeyStatusMap</code></dfn> Interface</h3> + <p>The MediaKeyStatusMap object is a read-only map of <a href="#decryption-key-id">key IDs</a> to the current status of the associated key.</p> + <p>A key's status is independent of whether the key is currently being used and of media data.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-84" aria-level="4"><span>Note</span></div><p class="">For example, if a key has output requirements that cannot currently be met, the key's status should be <code><a href="#idl-def-MediaKeyStatus.output-downscaled">"output-downscaled"</a></code> or <code><a href="#idl-def-MediaKeyStatus.output-restricted">"output-restricted"</a></code>, as appropriate, regardless of whether that key has been or is currently needed to decrypt media data.</p></div> + <div><div><pre class="def idl"><span class="idlInterface" id="idl-def-mediakeystatusmap" data-idl="" data-title="MediaKeyStatusMap">[<span class="extAttr"><span class="extAttrName"><a href="https://heycam.github.io/webidl/#SecureContext">SecureContext</a></span></span>] +interface <span class="idlInterfaceID"><a data-no-default="" data-link-for="" data-lt="" href="#dom-mediakeystatusmap" class="internalDFN" data-link-type="dfn"><code>MediaKeyStatusMap</code></a></span> { +<span class="idlIterable" id="idl-def-mediakeystatusmap-iterable" data-idl="" data-title="iterable" data-dfn-for="mediakeystatusmap"> <a data-no-default="" data-link-for="mediakeystatusmap" data-lt="" href="#dom-mediakeystatusmap-iterable" class="internalDFN" data-link-type="dfn"><code>iterable</code></a><BufferSource, <a href="#dom-mediakeystatus" class="internalDFN" data-link-type="dfn"><code>MediaKeyStatus</code></a>>;</span> +<span class="idlAttribute" id="idl-def-mediakeystatusmap-size" data-idl="" data-title="size" data-dfn-for="mediakeystatusmap"> readonly attribute <span class="idlAttrType"><a href="https://heycam.github.io/webidl/#idl-unsigned-long">unsigned long</a></span> <span class="idlAttrName"><a data-no-default="" data-link-for="mediakeystatusmap" data-lt="" href="#dom-mediakeystatusmap-size" class="internalDFN" data-link-type="dfn"><code>size</code></a></span>;</span> +<span class="idlMethod" id="idl-def-mediakeystatusmap-has-keyid" data-idl="" data-title="has" data-dfn-for="mediakeystatusmap"> <span class="idlMethType"><a href="https://heycam.github.io/webidl/#idl-boolean">boolean</a></span> <span class="idlMethName"><a data-no-default="" data-link-for="mediakeystatusmap" data-lt="has|has()" href="#dom-mediakeystatusmap-has" class="internalDFN" data-link-type="dfn"><code>has</code></a></span>(<span class="idlParam"><span class="idlParamType">BufferSource</span> <span class="idlParamName">keyId</span></span>);</span> +<span class="idlMethod" id="idl-def-mediakeystatusmap-get-keyid" data-idl="" data-title="get" data-dfn-for="mediakeystatusmap"> <span class="idlMethType"><a href="https://heycam.github.io/webidl/#idl-any">any</a></span> <span class="idlMethName"><a data-no-default="" data-link-for="mediakeystatusmap" data-lt="get|get()" href="#dom-mediakeystatusmap-get" class="internalDFN" data-link-type="dfn"><code>get</code></a></span>(<span class="idlParam"><span class="idlParamType">BufferSource</span> <span class="idlParamName">keyId</span></span>);</span> +};</span></pre></div> + <section> + <h4 id="attributes-1">Attributes</h4> + <dl class="attributes" data-dfn-for="MediaKeyStatusMap" data-link-for="MediaKeyStatusMap"><dt><dfn data-dfn-for="mediakeystatusmap" data-dfn-type="dfn" id="dom-mediakeystatusmap-size" data-idl="" data-title="size"><code>size</code></dfn> of type <span class="idlAttrType">unsigned long</span>, readonly </dt><dd> + <p>The number of <a href="#known-key">known keys.</a></p> + </dd> + </dl> + </section> + + <section> + <h4 id="methods-3">Methods</h4> + <dl class="methods" data-dfn-for="MediaKeyStatusMap" data-link-for="MediaKeyStatusMap"> + <dt><dfn data-dfn-for="mediakeystatusmap" data-dfn-type="dfn" id="dom-mediakeystatusmap-has" data-idl="" data-title="has" data-lt="has|has()"><code id="has">has</code></dfn></dt> + <dd> + <p>Returns <code>true</code> if the status of the key identified by <var>keyId</var> is known.</p> + + <table class="parameters"><tbody><tr><th>Parameter</th><th>Type</th><th>Nullable</th><th>Optional</th><th>Description</th></tr><tr><td class="prmName">keyId</td><td class="prmType"><code>BufferSource</code></td><td class="prmNullFalse"><span role="img" aria-label="False">✘</span></td><td class="prmOptFalse"><span role="img" aria-label="False">✘</span></td><td class="prmDesc">The <a href="#decryption-key-id">key ID</a> of the key.</td></tr></tbody></table> + <div><em>Return type: </em><code>boolean</code></div> + </dd> + <dt><dfn data-dfn-for="mediakeystatusmap" data-dfn-type="dfn" id="dom-mediakeystatusmap-get" data-idl="" data-title="get" data-lt="get|get()"><code id="get">get</code></dfn></dt> + <dd> + <p>Returns the <a href="#dom-mediakeystatus" class="internalDFN" data-link-type="dfn"><code>MediaKeyStatus</code></a> of the key identified by <var>keyId</var> or <code>undefined</code> if the status of the key identified by <var>keyId</var> is not known.</p> + + <table class="parameters"><tbody><tr><th>Parameter</th><th>Type</th><th>Nullable</th><th>Optional</th><th>Description</th></tr><tr><td class="prmName">keyId</td><td class="prmType"><code>BufferSource</code></td><td class="prmNullFalse"><span role="img" aria-label="False">✘</span></td><td class="prmOptFalse"><span role="img" aria-label="False">✘</span></td><td class="prmDesc">The <a href="#decryption-key-id">key ID</a> of the key.</td></tr></tbody></table> + <div><em>Return type: </em><code>any</code></div> + </dd> + </dl> + <p> + This interface has <code>entries</code>, <code>keys</code>, <code>values</code>, <code>forEach</code> and <code>@@iterator</code> methods + brought by <dfn data-dfn-for="mediakeystatusmap" data-link-for="MediaKeyStatusMap" data-dfn-type="dfn" id="dom-mediakeystatusmap-iterable" data-idl="" data-title="iterable"><code>iterable</code></dfn> (see WebIDL, <a href="https://www.w3.org/TR/WebIDL-1/#idl-iterable">3.2.7 Iterable declarations</a>). + </p> + <p> + The value pairs to iterate over are a snapshot of the set of pairs formed from the <a href="#decryption-key-id">key ID</a> and + associated <a href="#dom-mediakeystatus" class="internalDFN" data-link-type="dfn"><code>MediaKeyStatus</code></a> value for all <a href="#known-key">known keys</a>, sorted by <a href="#decryption-key-id">key ID</a>. + Key IDs are compared as follows: + For key IDs <var>A</var> of length <var>m</var> and <var>B</var> of length <var>n</var>, assigned such that <var>m</var> <= <var>n</var>, + let <var>A</var> < <var>B</var> if and only if the <var>m</var> octets of <var>A</var> are less in lexicographical + order than the first <var>m</var> octets of <var>B</var> or those octets are equal and <var>m</var> < <var>n</var>. + </p> + </section> + </div> + + <div><div><pre class="def idl"><span class="idlEnum" id="idl-def-mediakeystatus" data-idl="" data-title="MediaKeyStatus">enum <span class="idlEnumID"><a data-no-default="" data-link-for="" data-lt="" href="#dom-mediakeystatus" class="internalDFN" data-link-type="dfn"><code>MediaKeyStatus</code></a></span> { + <a href="#dom-mediakeystatus-usable" class="idlEnumItem">"usable"</a>, + <a href="#dom-mediakeystatus-expired" class="idlEnumItem">"expired"</a>, + <a href="#dom-mediakeystatus-released" class="idlEnumItem">"released"</a>, + <a href="#dom-mediakeystatus-output-restricted" class="idlEnumItem">"output-restricted"</a>, + <a href="#dom-mediakeystatus-output-downscaled" class="idlEnumItem">"output-downscaled"</a>, + <a href="#dom-mediakeystatus-status-pending" class="idlEnumItem">"status-pending"</a>, + <a href="#dom-mediakeystatus-internal-error" class="idlEnumItem">"internal-error"</a> +};</span></pre></div> +<p>The <dfn data-dfn-type="dfn" id="dom-mediakeystatus" data-idl="" data-title="MediaKeyStatus" data-dfn-for=""><code>MediaKeyStatus</code></dfn> enumeration is defined as follows: +</p> + <table class="simple" data-dfn-for="MediaKeyStatus" data-link-for="MediaKeyStatus"><tbody><tr><th colspan="2">Enumeration description</th></tr><tr><td><dfn data-dfn-for="mediakeystatus" data-dfn-type="dfn" id="dom-mediakeystatus-usable" data-idl="" data-title="usable"><code id="idl-def-MediaKeyStatus.usable">usable</code></dfn></td><td> + The CDM is certain the key is currently <a href="#usable-for-decryption">usable for decryption</a>.<br> + Keys that <em>may not</em> currently be <a href="#usable-for-decryption">usable for decryption</a> <em class="rfc2119" title="MUST NOT">MUST NOT</em> have this status. + </td></tr><tr><td><dfn data-dfn-for="mediakeystatus" data-dfn-type="dfn" id="dom-mediakeystatus-expired" data-idl="" data-title="expired"><code id="idl-def-MediaKeyStatus.expired">expired</code></dfn></td><td> + The key is no longer <a href="#usable-for-decryption">usable for decryption</a> because its <a href="#expiration-time">expiration time</a> has passed.<br> + The time represented by the <code><a href="#dom-mediakeysession-expiration">expiration</a></code> attribute <em class="rfc2119" title="MUST">MUST</em> be earlier than the current time. + All other keys in the session <em class="rfc2119" title="MUST">MUST</em> have this status. + </td></tr><tr><td><dfn data-dfn-for="mediakeystatus" data-dfn-type="dfn" id="dom-mediakeystatus-released" data-idl="" data-title="released"><code id="idl-def-MediaKeyStatus.released">released</code></dfn></td><td> + The key itself is no longer available to the CDM, but information about the key, such as a <a href="#record-of-license-destruction">record of license destruction</a> or <a href="#record-of-key-usage">record of key usage</a>, is available. + </td></tr><tr><td><dfn data-dfn-for="mediakeystatus" data-dfn-type="dfn" id="dom-mediakeystatus-output-restricted" data-idl="" data-title="output-restricted"><code id="idl-def-MediaKeyStatus.output-restricted">output-restricted</code></dfn></td><td> + There are output restrictions associated with the key that cannot currently be met. + Media data decrypted with this key may be blocked from presentation, if necessary according to + the output restrictions. + The application should avoid using streams that will trigger the output restrictions associated + with the key. + </td></tr><tr><td><dfn data-dfn-for="mediakeystatus" data-dfn-type="dfn" id="dom-mediakeystatus-output-downscaled" data-idl="" data-title="output-downscaled"><code id="idl-def-MediaKeyStatus.output-downscaled">output-downscaled</code></dfn></td><td> + There are output restrictions associated with the key that cannot currently be met. + Media data decrypted with this key may be presented at a lower quality (e.g., resolution), + if necessary according to the output restrictions. + The application should avoid using streams that will trigger the output restrictions associated + with the key.<br> + Support for downscaling is <em class="rfc2119" title="OPTIONAL">OPTIONAL</em>. + Applications <em class="rfc2119" title="SHOULD NOT">SHOULD NOT</em> rely on downscaling to ensure uninterrupted playback when output requirements cannot be met. + </td></tr><tr><td><dfn data-dfn-for="mediakeystatus" data-dfn-type="dfn" id="dom-mediakeystatus-status-pending" data-idl="" data-title="status-pending"><code id="idl-def-MediaKeyStatus.status-pending">status-pending</code></dfn></td><td> + The status of the key is not yet known and is being determined. + The status will be updated with the actual status when it has been determined. + </td></tr><tr><td><dfn data-dfn-for="mediakeystatus" data-dfn-type="dfn" id="dom-mediakeystatus-internal-error" data-idl="" data-title="internal-error"><code id="idl-def-MediaKeyStatus.internal-error">internal-error</code></dfn></td><td> + The key is not currently <a href="#usable-for-decryption">usable for decryption</a> because of an error in the CDM unrelated to the other values. + This value is not actionable by the application. + </td></tr></tbody></table></div> + </section> + + <section id="mediakeymessageevent"> + <h3 id="x6-2-mediakeymessageevent"><span class="secno">6.2 </span><a href="#dom-mediakeymessageevent" class="internalDFN" data-link-type="dfn"><code>MediaKeyMessageEvent</code></a></h3> + <p>The MediaKeyMessageEvent object is used for the <code><a href="#dom-evt-message">message</a></code> event.</p> + <p>Events are constructed as defined in <a href="https://www.w3.org/TR/dom/#constructing-events">Constructing events</a> [<cite><a class="bibref" href="#bib-DOM">DOM</a></cite>].</p> + + <div><div><pre class="def idl"><span class="idlEnum" id="idl-def-mediakeymessagetype" data-idl="" data-title="MediaKeyMessageType">enum <span class="idlEnumID"><a data-no-default="" data-link-for="" data-lt="" href="#dom-mediakeymessagetype" class="internalDFN" data-link-type="dfn"><code>MediaKeyMessageType</code></a></span> { + <a href="#dom-mediakeymessagetype-license-request" class="idlEnumItem">"license-request"</a>, + <a href="#dom-mediakeymessagetype-license-renewal" class="idlEnumItem">"license-renewal"</a>, + <a href="#dom-mediakeymessagetype-license-release" class="idlEnumItem">"license-release"</a>, + <a href="#dom-mediakeymessagetype-individualization-request" class="idlEnumItem">"individualization-request"</a> +};</span></pre></div> +<p>The <dfn data-dfn-type="dfn" id="dom-mediakeymessagetype" data-idl="" data-title="MediaKeyMessageType" data-dfn-for=""><code>MediaKeyMessageType</code></dfn> is defined as follows:</p> + <table class="simple" data-dfn-for="MediaKeyMessageType" data-link-for="MediaKeyMessageType"><tbody><tr><th colspan="2">Enumeration description</th></tr><tr><td><dfn data-dfn-for="mediakeymessagetype" data-dfn-type="dfn" id="dom-mediakeymessagetype-license-request" data-idl="" data-title="license-request"><code id="idl-def-MediaKeyMessageType.license-request">license-request</code></dfn></td><td>The message contains a request for a new license.</td></tr><tr><td><dfn data-dfn-for="mediakeymessagetype" data-dfn-type="dfn" id="dom-mediakeymessagetype-license-renewal" data-idl="" data-title="license-renewal"><code id="idl-def-MediaKeyMessageType.license-renewal">license-renewal</code></dfn></td><td>The message contains a request to renew an existing license.</td></tr><tr><td><dfn data-dfn-for="mediakeymessagetype" data-dfn-type="dfn" id="dom-mediakeymessagetype-license-release" data-idl="" data-title="license-release"><code id="idl-def-MediaKeyMessageType.license-release">license-release</code></dfn></td><td>The message contains a <a href="#record-of-license-destruction">record of license destruction</a> or <a href="#record-of-key-usage">record of key usage</a>.</td></tr><tr><td><dfn data-dfn-for="mediakeymessagetype" data-dfn-type="dfn" id="dom-mediakeymessagetype-individualization-request" data-idl="" data-title="individualization-request"><code id="idl-def-MediaKeyMessageType.individualization-request">individualization-request</code></dfn></td><td> + The message contains a request for <a href="#app-assisted-individualization">App-Assisted Individualization</a> (or re-individualization).<br> + As with all other messages, any identifiers in the message <em class="rfc2119" title="MUST">MUST</em> be <a href="#per-origin-per-profile-identifiers">distinctive per origin and profile</a> and <em class="rfc2119" title="MUST NOT">MUST NOT</em> be <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifier(s)</a>. + </td></tr></tbody></table></div> + + <div><div><pre class="def idl"><span class="idlInterface" id="idl-def-mediakeymessageevent" data-idl="" data-title="MediaKeyMessageEvent">[<span class="extAttr"><span class="extAttrName"><a href="https://heycam.github.io/webidl/#SecureContext">SecureContext</a></span></span>, + <span class="idlCtor"><span class="extAttrName"><a href="https://heycam.github.io/webidl/#Constructor">Constructor</a></span>(<span class="idlParam"><span class="idlParamType"><a href="https://heycam.github.io/webidl/#idl-DOMString">DOMString</a></span> <span class="idlParamName">type</span></span>, <span class="idlParam"><span class="idlParamType"><a href="#dom-mediakeymessageeventinit" class="internalDFN" data-link-type="dfn"><code>MediaKeyMessageEventInit</code></a></span> <span class="idlParamName">eventInitDict</span></span>)</span>] +interface <span class="idlInterfaceID"><a data-no-default="" data-link-for="" data-lt="" href="#dom-mediakeymessageevent" class="internalDFN" data-link-type="dfn"><code>MediaKeyMessageEvent</code></a></span> : <span class="idlSuperclass">Event</span> { +<span class="idlAttribute" id="idl-def-mediakeymessageevent-messagetype" data-idl="" data-title="messageType" data-dfn-for="mediakeymessageevent"> readonly attribute <span class="idlAttrType"><a href="#dom-mediakeymessagetype" class="internalDFN" data-link-type="dfn"><code>MediaKeyMessageType</code></a></span> <span class="idlAttrName"><a data-no-default="" data-link-for="mediakeymessageevent" data-lt="" href="#dom-mediakeymessageevent-messagetype" class="internalDFN" data-link-type="dfn"><code>messageType</code></a></span>;</span> +<span class="idlAttribute" id="idl-def-mediakeymessageevent-message" data-idl="" data-title="message" data-dfn-for="mediakeymessageevent"> readonly attribute <span class="idlAttrType"><a href="https://heycam.github.io/webidl/#idl-ArrayBuffer">ArrayBuffer</a></span> <span class="idlAttrName"><a data-no-default="" data-link-for="mediakeymessageevent" data-lt="" href="#dom-mediakeymessageevent-message" class="internalDFN" data-link-type="dfn"><code>message</code></a></span>;</span> +};</span></pre></div><section><h4 id="constructors">Constructors</h4><dl class="constructors" data-dfn-for="MediaKeyMessageEvent" data-link-for="MediaKeyMessageEvent"><dt><dfn data-dfn-for="" data-dfn-type="dfn" id="dom-mediakeymessageevent" data-idl="" data-title="MediaKeyMessageEvent"><code>MediaKeyMessageEvent</code></dfn></dt><dd> + + <table class="parameters"><tbody><tr><th>Parameter</th><th>Type</th><th>Nullable</th><th>Optional</th><th>Description</th></tr><tr><td class="prmName">type</td><td class="prmType"><code>DOMString</code></td><td class="prmNullFalse"><span role="img" aria-label="False">✘</span></td><td class="prmOptFalse"><span role="img" aria-label="False">✘</span></td><td class="prmDesc"></td></tr><tr><td class="prmName">eventInitDict</td><td class="prmType"><code>MediaKeyMessageEventInit</code></td><td class="prmNullFalse"><span role="img" aria-label="False">✘</span></td><td class="prmOptTrue"><span role="img" aria-label="True">✔</span></td><td class="prmDesc"></td></tr></tbody></table></dd></dl></section><section><h4 id="attributes-2">Attributes</h4><dl class="attributes" data-dfn-for="MediaKeyMessageEvent" data-link-for="MediaKeyMessageEvent"><dt><dfn data-dfn-for="mediakeymessageevent" data-dfn-type="dfn" id="dom-mediakeymessageevent-messagetype" data-idl="" data-title="messageType"><code>messageType</code></dfn> of type <span class="idlAttrType"><a href="#dom-mediakeymessagetype" class="internalDFN" data-link-type="dfn"><code>MediaKeyMessageType</code></a></span>, readonly </dt><dd> + The type of the message. + <p>Implementations <em class="rfc2119" title="MUST NOT">MUST NOT</em> require applications to handle message types. + Implementations <em class="rfc2119" title="MUST">MUST</em> support applications that do not differentiate messages and <em class="rfc2119" title="MUST NOT">MUST NOT</em> require that applications handle message types. + Specifically, Key Systems <em class="rfc2119" title="MUST">MUST</em> support passing all types of messages to a single URL. + </p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-85" aria-level="5"><span>Note</span></div><p class="">This attribute allows an application to differentiate messages without parsing the message. + It is intended to enable optional application and/or server optimizations, but applications are not required to use it. + </p></div> + </dd><dt><dfn data-dfn-for="mediakeymessageevent" data-dfn-type="dfn" id="dom-mediakeymessageevent-message" data-idl="" data-title="message"><code>message</code></dfn> of type <span class="idlAttrType">ArrayBuffer</span>, readonly </dt><dd> + The message from the CDM. Messages are Key System-specific. + </dd></dl></section></div> + + <section id="mediakeymessageeventinit"> + <h4 id="x6-2-1-mediakeymessageeventinit"><span class="secno">6.2.1 </span><dfn data-dfn-type="dfn" id="dom-mediakeymessageeventinit" data-idl="" data-title="MediaKeyMessageEventInit" data-dfn-for=""><code>MediaKeyMessageEventInit</code></dfn></h4> + <div><div><pre class="def idl"><span class="idlDictionary" id="idl-def-mediakeymessageeventinit" data-idl="" data-title="MediaKeyMessageEventInit">dictionary <span class="idlDictionaryID"><a data-no-default="" data-link-for="" data-lt="" href="#dom-mediakeymessageeventinit" class="internalDFN" data-link-type="dfn"><code>MediaKeyMessageEventInit</code></a></span> : <span class="idlSuperclass">EventInit</span> { +<span class="idlMember" id="idl-def-mediakeymessageeventinit-messagetype" data-idl="" data-title="messageType" data-dfn-for="mediakeymessageeventinit"> required <span class="idlMemberType"><a href="#dom-mediakeymessagetype" class="internalDFN" data-link-type="dfn"><code>MediaKeyMessageType</code></a></span> <span class="idlMemberName"><a data-no-default="" data-link-for="mediakeymessageeventinit" data-lt="" href="#dom-mediakeymessageeventinit-messagetype" class="internalDFN" data-link-type="dfn"><code>messageType</code></a></span>;</span> +<span class="idlMember" id="idl-def-mediakeymessageeventinit-message" data-idl="" data-title="message" data-dfn-for="mediakeymessageeventinit"> required <span class="idlMemberType"><a href="https://heycam.github.io/webidl/#idl-ArrayBuffer">ArrayBuffer</a></span> <span class="idlMemberName"><a data-no-default="" data-link-for="mediakeymessageeventinit" data-lt="" href="#dom-mediakeymessageeventinit-message" class="internalDFN" data-link-type="dfn"><code>message</code></a></span>;</span> +};</span></pre></div><section><h5 id="dictionary-mediakeymessageeventinit-members">Dictionary <a class="idlType internalDFN" href="#dom-mediakeymessageeventinit" data-link-type="dfn"><code>MediaKeyMessageEventInit</code></a> Members</h5><dl class="dictionary-members" data-dfn-for="MediaKeyMessageEventInit" data-link-for="MediaKeyMessageEventInit"><dt><dfn data-dfn-for="mediakeymessageeventinit" data-dfn-type="dfn" id="dom-mediakeymessageeventinit-messagetype" data-idl="" data-title="messageType"><code>messageType</code></dfn> of type <span class="idlMemberType"><a href="#dom-mediakeymessagetype" class="internalDFN" data-link-type="dfn"><code>MediaKeyMessageType</code></a></span></dt><dd> + The type of the message. + </dd><dt><dfn data-dfn-for="mediakeymessageeventinit" data-dfn-type="dfn" id="dom-mediakeymessageeventinit-message" data-idl="" data-title="message"><code>message</code></dfn> of type <span class="idlMemberType">ArrayBuffer</span></dt><dd> + The message. + </dd></dl></section></div> + </section> + </section> + + <section id="mediakeysession-events" class="informative"> + <h3 id="x6-3-event-summary"><span class="secno">6.3 </span>Event Summary</h3><p><em>This section is non-normative.</em></p> + + <table class="old-table"> + <thead> + <tr> + <th>Event name</th> + <th>Interface</th> + <th>Dispatched when...</th> + </tr> + </thead> + <tbody> + <tr> + <td><dfn id="dom-evt-keystatuseschange"><code>keystatuseschange</code></dfn></td> + <td><code><a href="https://www.w3.org/TR/dom/#event">Event</a></code></td> + <td>There has been a change in the keys in the session or their status.</td> + </tr> + <tr> + <td><dfn id="dom-evt-message"><code>message</code></dfn></td> + <td><a href="#dom-mediakeymessageevent" class="internalDFN" data-link-type="dfn"><code>MediaKeyMessageEvent</code></a></td> + <td>The CDM has generated a message for the session.</td> + </tr> + </tbody> + </table> + </section> + + <section id="mediakeysession-algorithms"> + <h3 id="x6-4-algorithms"><span class="secno">6.4 </span>Algorithms</h3> + + <section id="queue-message"> + <h4 id="x6-4-1-queue-a-message-event"><span class="secno">6.4.1 </span>Queue a "message" Event</h4> + <p>The Queue a "message" Event algorithm queues a message event to a <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object. + Requests to run this algorithm include a target <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object, a <var>message type</var>, and a <var>message</var>. + </p> + <p> + <var>message</var> <em class="rfc2119" title="MUST NOT">MUST NOT</em> contain <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifier(s)</a>, even in an encrypted form. + <var>message</var> <em class="rfc2119" title="MUST NOT">MUST NOT</em> contain <a href="#distinctive-identifier">Distinctive Identifier(s)</a>, even in an encrypted form, if the <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object's <var>use distinctive identifier</var> value is false. + </p> + <p>The following steps are run:</p> + <ol> + <li><p>Let the <var>session</var> be the specified <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object.</p></li> + <li> + <p><a href="https://www.w3.org/TR/html51/webappapis.html#queuing">Queue a task</a> to create an event named <code><a href="#dom-evt-message">message</a></code> that does not bubble and is not cancellable using the <a href="#dom-mediakeymessageevent" class="internalDFN" data-link-type="dfn"><code>MediaKeyMessageEvent</code></a> interface with its <var>type</var> attribute set to <code>message</code> and its <var>isTrusted</var> attribute initialized to <code>true</code>, and dispatch it at the <var>session</var>.</p> + <p>The event interface <a href="#dom-mediakeymessageevent" class="internalDFN" data-link-type="dfn"><code>MediaKeyMessageEvent</code></a> has:</p> + <ul style="list-style-type:none"><li> + <code><a href="#dom-mediakeymessageevent-messagetype">messageType</a></code> = the specified <var>message type</var><br><br> + <code><a href="#dom-mediakeymessageevent-message">message</a></code> = the specified <var>message</var> + </li></ul> + </li> + </ol> + </section> + + <section id="update-key-statuses"> + <h4 id="x6-4-2-update-key-statuses"><span class="secno">6.4.2 </span>Update Key Statuses</h4> + <p>The Update Key Statuses algorithm updates the set of <a href="#known-key">known</a> keys for a <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> or the status of one or more of the keys. + Requests to run this algorithm include a target <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object and a sequence of <a href="#decryption-key-id">key ID</a> and associated <a href="#dom-mediakeystatus" class="internalDFN" data-link-type="dfn"><code>MediaKeyStatus</code></a> pairs. + </p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-86" aria-level="5"><span>Note</span></div><p class="">The algorithm is always run in a task.</p></div> + <p>The following steps are run:</p> + <ol> + <li><p>Let the <var>session</var> be the associated <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object.</p></li> + <li><p>Let the <var>input statuses</var> be the sequence of pairs key ID and associated <a href="#dom-mediakeystatus" class="internalDFN" data-link-type="dfn"><code>MediaKeyStatus</code></a> pairs.</p></li> + <li><p>Let the <var>statuses</var> be <var>session</var>'s <code><a href="#dom-mediakeysession-keystatuses">keyStatuses</a></code> attribute.</p></li> + <li><p>Run the following steps to replace the contents of <var>statuses</var>:</p> + <ol> + <li><p>Empty <var>statuses</var>.</p></li> + <li><p>For each pair in <var>input statuses</var>.</p> + <ol> + <li><p>Let <var>pair</var> be the pair.</p></li> + <li><p>Insert an entry for <var>pair</var>'s key ID into <var>statuses</var> with the value of <var>pair</var>'s <a href="#dom-mediakeystatus" class="internalDFN" data-link-type="dfn"><code>MediaKeyStatus</code></a> value.</p></li> + </ol> + </li> + </ol> + <div class="note"><div role="heading" class="note-title marker" id="h-note-87" aria-level="5"><span>Note</span></div><p class="">The effect of this steps is that the contents of <var>session</var>'s <code><a href="#dom-mediakeysession-keystatuses">keyStatuses</a></code> attribute are replaced without invalidating existing references to the attribute. + This replacement is atomic from a script perspective. That is, script <em class="rfc2119" title="MUST NOT">MUST NOT</em> ever see a partially populated sequence. + </p></div> + </li> + <li><p><a href="https://www.w3.org/TR/html51/webappapis.html#queuing">Queue a task</a> to <a href="https://www.w3.org/TR/html51/webappapis.html#firing-a-simple-event-named-e">fire a simple event</a> named <code><a href="#dom-evt-keystatuseschange">keystatuseschange</a></code> at the <var>session</var>.</p></li> + <li><p><a href="https://www.w3.org/TR/html51/webappapis.html#queuing">Queue a task</a> to run the <a href="#resume-playback">Attempt to Resume Playback If Necessary</a> algorithm on each of the media element(s) whose <code><a href="#dom-mediakeys">mediaKeys</a></code> attribute is the MediaKeys object that created the <var>session</var>.</p> + </li> + </ol> </section> - <section id="exposed-value-requirements"> - <h3 id="x8.4-values-exposed-to-the-application"><span class="secno">8.4 </span>Values Exposed to the Application</h3> - <p>Values exposed to or inferable by, such as via its use by the CDM, the application could be used to identify the client or user, regardless of whether they are designed to be identifiers. This section defines requirements for avoiding or at - least mitigating such concerns. There are additional requirements for <a href="#identifier-requirements">Identifiers</a>. + <section id="update-expiration"> + <h4 id="x6-4-3-update-expiration"><span class="secno">6.4.3 </span>Update Expiration</h4> + <p>The Update Expiration algorithm updates the <a href="#expiration-time">expiration time</a> of a <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a>. + Requests to run this algorithm include a target <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object and the new expiration time, which may be <code>NaN</code>. + </p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-88" aria-level="5"><span>Note</span></div><p class="">The algorithm is always run in a task.</p></div> + <p>The following steps are run:</p> + <ol> + <li><p>Let the <var>session</var> be the associated <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object.</p></li> + <li><p>Let <var>expiration time</var> be <code>NaN</code>.</p></li> + <li><p>If the new expiration time is not <code>NaN</code>, let <var>expiration time</var> be that expiration time.</p></li> + <li><p>Set the <var>session</var>'s <code><a href="#dom-mediakeysession-expiration">expiration</a></code> attribute to <var>expiration time</var> expressed as <a href="#time">time</a>.</p></li> + </ol> + </section> + + <section id="session-closed"> + <h4 id="x6-4-4-session-closed"><span class="secno">6.4.4 </span>Session Closed</h4> + <p>The Session Closed algorithm updates the <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> state after a <a href="#key-session">key session</a> has been closed by the <a href="#cdm">CDM</a>.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-89" aria-level="5"><span>Note</span></div><p class="">The algorithm is always run in a task.</p></div> + <p> + When a session is closed, the license(s) and key(s) associated with it are no longer available to + decrypt <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a>. All <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> methods will fail and no further events will be queued for this object + after this algorithm is run. + </p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-90" aria-level="5"><span>Note</span></div><div class=""> + <p> + The CDM may close a session at any point, such as when the session is no longer needed or when system resources are lost. + In that case, the <a href="#monitor-cdm">Monitor for CDM Changes</a> algorithm detects the change and runs this algorithm. </p> + <p>Keys in other sessions <em class="rfc2119" title="MUST">MUST</em> be unaffected, even if they have overlapping key IDs.</p> + <p> + After this algorithm has run, event handlers for the events queued by this algorithm will be executed, but no further events + can be queued. As a result, no messages can be sent by the CDM as a result of closing the session. + </p> + </div></div> + <p>The following steps are run:</p> + <ol> + <li><p>Let <var>session</var> be the associated <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object.</p></li> + <li><p>Let <var>promise</var> be the <var>session</var>'s <code><a href="#dom-mediakeysession-closed">closed</a></code> attribute.</p></li> + <!-- Avoid a race condition that could cause the algorithms below to be run multiple times. --> + <li><p>If <var>promise</var> is resolved, abort these steps.</p></li> + <!-- Handle the case that this algorithm is reached by a path other than close(). In all cases, the value is set before the algorithms below are run. --> + <li><p>Set the <var>session</var>'s <var>closing or closed</var> value to true.</p></li> + <li> + <p> + If <var>session</var>'s <var>session type</var> is <code><a href="#idl-def-MediaKeySessionType.persistent-usage-record">"persistent-usage-record"</a></code>, execute the following steps: + </p> + <ol> + <li><p>Let <var>cdm</var> be the CDM instance represented by <var>session</var>'s <var>cdm instance</var> value.</p></li> + <li> + <p>Use <var>cdm</var> to store <var>session</var>'s <var>record of key usage</var>, if it exists.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-91" aria-level="5"><span>Note</span></div><div class=""> + <p> + The <var>record of key usage</var> may not exist if no keys have been used in the session or if it has been deleted as + a result of the <code><a href="#dom-mediakeysession-update">update()</a></code> method processing an acknowledgement of the <a href="#record-of-key-usage">record of key usage</a>. + </p> + <p> + Since it has no effects observable to the document, this step may be run asynchronously, including after the document has unloaded. + </p> + </div></div> + </li> + </ol> - <section id="per-origin-per-profile-values"> - <h4 id="x8.4.1-use-per-origin-per-profile-values"><span class="secno">8.4.1 </span>Use Per-Origin Per-Profile Values</h4> - <!-- Issue #101 may affect this text. --> - <p> - All <a href="#distinctive-value">distinctive values</a> exposed to or inferable by the application <em class="rfc2119" title="MUST">MUST</em> be unique per <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> and <a href="#browsing-profile">browsing profile</a>. That is, the value(s) used for one <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> using the APIs defined in this specification <em class="rfc2119" - title="MUST">MUST</em> be different from those used for any other origin using the APIs, and value(s) used in one <a href="#browsing-profile">browsing profile</a> <em class="rfc2119" title="MUST">MUST</em> be different from those used - for any other profile, regardless of origin. Such values <em class="rfc2119" title="MUST NOT">MUST NOT</em> leak to or from private browsing sessions. - </p> - <p> - Values across origins and profiles <em class="rfc2119" title="MUST">MUST</em> be <a href="#non-associable-by-application">non-associable by applications</a>, meaning it <em class="rfc2119" title="MUST NOT">MUST NOT</em> be possible - to correlate values from multiple origins or profiles, such as to determine that they came from the same client or user. Specifically, implementations that derive per-origin values from an origin-independent and/or profile-independent - value, <em class="rfc2119" title="MUST">MUST</em> do so in a way that ensures the above non-associability property, such as by using derivation functions with appropriate non-reversible properties. - </p> - </section> + </li> + <li><p>Run the <a href="#update-key-statuses">Update Key Statuses</a> algorithm on the <var>session</var>, providing an empty sequence.</p></li> + <li><p>Run the <a href="#update-expiration">Update Expiration</a> algorithm on the <var>session</var>, providing <code>NaN</code>.</p></li> + <li><p>Resolve <var>promise</var>.</p></li> + </ol> + </section> + <section id="media-key-session-destroyed"> + <h4 id="x6-4-5-mediakeysession-destroyed"><span class="secno">6.4.5 </span>MediaKeySession Destroyed</h4> + <p> + The MediaKeySession Destroyed algorithm performs steps that are necessary when a <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> that is not <a href="#media-key-session-closed">closed</a> is destroyed. + </p> + <p>The following steps are run in parallel to the main event loop:</p> + <ol> + <li><p>Let <var>session</var> be the associated <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object.</p></li> + <li><p>Let <var>cdm</var> be the CDM instance represented by <var>session</var>'s <var>cdm instance</var> value.</p></li> + <li> + <p>Use <var>cdm</var> to execute the following steps:</p> + <ol> + <li><p>Close the <a href="#key-session">session</a> associated with <var>session</var>.</p></li> + <li> + <p> + If <var>session</var>'s <var>session type</var> is <code><a href="#idl-def-MediaKeySessionType.persistent-usage-record">"persistent-usage-record"</a></code>, + store <var>session</var>'s <var>record of key usage</var>, if it exists. + </p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-92" aria-level="5"><span>Note</span></div><p class=""> + Since it has no effects observable to the document, this step may be run asynchronously, including after the document has unloaded. + </p></div> + </li> + </ol> + </li> + </ol> + </section> + <section id="monitor-cdm"> + <h4 id="x6-4-6-monitor-for-cdm-state-changes"><span class="secno">6.4.6 </span>Monitor for CDM State Changes</h4> + <p> + The Monitor for CDM State Changes algorithm executes steps required when various aspects of CDM state change. + </p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-93" aria-level="5"><span>Note</span></div><p class="">This algorithm only applies to CDM state changes that are not covered by other algorithms. For example, <code><a href="#dom-mediakeysession-update">update()</a></code> may result in messages, key status changes and/or expiration changes, but those are all handled within that algorithm.</p></div> + <div class="note"><div role="heading" class="note-title marker" id="h-note-94" aria-level="5"><span>Note</span></div><p class="">The algorithm is always run in parallel to the main event loop.</p></div> + <p> + The following steps are run: + </p> + + <ol> + <li> + <p> + Let <var>session</var> be the <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object. + </p> + </li> + <li><p>Let <var>cdm</var> be the CDM instance represented by <var>session</var>'s <var>cdm instance</var> value.</p></li> + <li> + <p> + If <var>cdm</var> has an outgoing message that has not yet been sent, <a href="https://www.w3.org/TR/html51/webappapis.html#queuing">queue a task</a> to execute the following steps: + </p> + <ol> + <li> + <p> + Let <var>message type</var> and <var>message</var> be the message type and message, respectively. + </p> + </li> + <li> + <p> + Run the <a href="#queue-message">Queue a "message" Event</a> algorithm, passing <var>session</var>, <var>message type</var> and <var>message</var>. + </p> + </li> + </ol> + </li> + <li> + <p> + If <var>cdm</var> has changed the set of keys <a href="#known-key">known</a> to <var>session</var> or the status of one or more of the keys, + <a href="https://www.w3.org/TR/html51/webappapis.html#queuing">queue a task</a> to execute the following steps: + </p> + <ol> + <li> + <p> + Let <var>statuses</var> be a list of key ID and <a href="#dom-mediakeystatus" class="internalDFN" data-link-type="dfn"><code>MediaKeyStatus</code></a> value pairs containing one pair for each key + <a href="#known-key">known</a> to <var>session</var>. + </p> + </li> + <li> + <p> + Run the <a href="#update-key-statuses">Update Key Statuses</a> algorithm, passing <var>session</var> and <var>statuses</var>. + </p> + </li> + </ol> + </li> + <li> + <p> + If <var>cdm</var> has changed the <a href="#expiration-time">expiration time</a> of <var>session</var>, <a href="https://www.w3.org/TR/html51/webappapis.html#queuing">queue a task</a> to execute the following steps: + </p> + <ol> + <li> + <p> + Let <var>expiration time</var> be the new expiration time of <var>session</var>. + </p> + </li> + <li> + <p> + Run the <a href="#update-expiration">Update Expiration</a> algorithm, passing <var>session</var> and <var>expiration time</var>. + </p> + </li> + </ol> + </li> + <li> + <p> + If <var>cdm</var> has closed <var>session</var>, <a href="https://www.w3.org/TR/html51/webappapis.html#queuing">queue a task</a> to run the <a href="#session-closed">Session Closed</a> algorithm on <var>session</var>. + </p> + </li> + <li> + <p> + If <var>cdm</var> had become unavailable, <a href="https://www.w3.org/TR/html51/webappapis.html#queuing">queue a task</a> to run the <a href="#session-closed">Session Closed</a> algorithm on <var>session</var>. + </p> + </li> + </ol> + </section> + </section> + <section id="exceptions"> + <h3 id="x6-5-exceptions"><span class="secno">6.5 </span>Exceptions</h3> + <p id="error-names">The methods report errors by rejecting the returned promise with a <a href="https://heycam.github.io/webidl/#dfn-simple-exception">simple exception</a> [<cite><a class="bibref" href="#bib-WEBIDL">WEBIDL</a></cite>] or a <code><a href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code>. + The following <a href="https://heycam.github.io/webidl/#dfn-simple-exception">simple exceptions</a> and <a href="https://heycam.github.io/webidl/#idl-DOMException-error-names">DOMException names</a> from [<cite><a class="bibref" href="#bib-WEBIDL">WEBIDL</a></cite>] are used in the algorithms. + Causes specified specified in the algorithms are listed alongside each name, though these names <em class="rfc2119" title="MAY">MAY</em> be used for other reasons as well. + </p> - <section id="allow-values-to-be-cleared"> - <h4 id="x8.4.2-allow-values-to-be-cleared"><span class="secno">8.4.2 </span>Allow Values to Be Cleared</h4> - <p> - As a consequence of the requirements in <a href="#allow-persistent-data-cleared">Allow Persistent Data to Be Cleared</a>, all persisted values exposed to the application <em class="rfc2119" title="MUST">MUST</em> be clearable such - that the values are no longer retrievable, observable, or inferable both outside, such as via the APIs defined in this specification, and on the client device. - </p> - <p> - Once cleared, new <a href="#non-associable-by-application">non-associable by applications</a> value(s) <em class="rfc2119" title="MUST">MUST</em> be generated when values are subsequently needed. - </p> - </section> + <table class="old-table"> + <tbody> + <tr> + <th>Name</th> + <th>Possible Causes (non-exhaustive)</th> + </tr> + <tr> + <td><dfn id="dfn-TypeError" data-dfn-type="dfn"><code>TypeError</code></dfn></td> + <td> + The parameter is empty.<br> + Invalid initialization data.<br> + Invalid response format.<br> + A persistent license was provided for a <code><a href="#idl-def-MediaKeySessionType.temporary">"temporary"</a></code> session. + </td> + </tr> + <tr> + <td><dfn id="dfn-NotSupportedError" data-dfn-type="dfn"><code>NotSupportedError</code></dfn></td> + <td> + The existing MediaKeys object cannot be removed.<br> + The key system is not supported.<br> + The initialization data type is not supported by the key system.<br> + The session type is not supported by the key system.<br> + The initialization data is not supported by the key system.<br> + The operation is not supported by the key system. + </td> + </tr> + <tr> + <td><dfn id="dfn-InvalidStateError" data-dfn-type="dfn"><code>InvalidStateError</code></dfn></td> + <td>The existing MediaKeys object cannot be removed at this time.<br> + The session has already been used.<br> + The session is not yet initialized.<br> + The session is closed. + </td> + </tr> + <tr> + <td><dfn id="dfn-QuotaExceededError" data-dfn-type="dfn"><code>QuotaExceededError</code></dfn></td> + <td>The MediaKeys object cannot be used with additional HTMLMediaElements.<br> + A non-closed session already exists for this sessionId. + </td> + </tr> + </tbody> + </table> + </section> + + <section id="session-storage"> + <h3 id="x6-6-session-storage-and-persistence"><span class="secno">6.6 </span>Session Storage and Persistence</h3> + <p>This section provides an overview of session storage and persistence that complements the algorithms.</p> + <p>The following requirements apply in addition to those in <a href="#media-keys-storage">Storage and Persistence</a>.</p> + <p>If the result of running the <a href="#is-persistent-session-type">Is persistent session type?</a> algorithm on this object's <var>session type</var> is <code>false</code>, the user agent and CDM <em class="rfc2119" title="MUST NOT">MUST NOT</em> persist a record of or data related to the session at any point. + This includes license(s), key(s), <a href="#record-of-license-destruction">record(s) of license destruction</a>, <a href="#record-of-key-usage">record(s) of key usage</a>, and the <a href="#session-id">Session ID</a>. + </p> + <p>The remainder of this section applies to session types for which the <a href="#is-persistent-session-type">Is persistent session type?</a> algorithm returns <code>true</code>.</p> + <p>The CDM <em class="rfc2119" title="SHOULD NOT">SHOULD NOT</em> store session data, including the Session ID, until <code><a href="#dom-mediakeysession-update">update()</a></code> is called the first time. + Specifically, the CDM <em class="rfc2119" title="SHOULD NOT">SHOULD NOT</em> store session data during the <code><a href="#dom-mediakeysession-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><em>All</em> data associated with a session <em class="rfc2119" title="MUST">MUST</em> be cleared when the session is cleared, such as in <code><a href="#dom-mediakeysession-update">update()</a></code> when processing a <a href="#record-of-license-destruction">record of license destruction</a> acknowledgement or <a href="#record-of-key-usage">record of key usage</a> acknowledgement. + See <a href="#persistent-state-requirements">Persistent Data</a>. + </p> + <p>The CDM <em class="rfc2119" title="MUST">MUST</em> ensure that data for a given session is only present in one <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object that is not + <a href="#media-key-session-closed">closed</a> in any <a href="https://www.w3.org/TR/dom/#concept-document">Document</a>. + In other words, <code><a href="#dom-mediakeysession-load">load()</a></code> <em class="rfc2119" title="MUST">MUST</em> fail when there is already a <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> representing the session specified by the <var>sessionId</var> parameter, either because the object that created it via <code><a href="#dom-mediakeysession-generaterequest">generateRequest()</a></code> is still active or it has been loaded into another object via <code><a href="#dom-mediakeysession-load">load()</a></code>. + A session <em class="rfc2119" title="MAY">MAY</em> only be loaded again if all objects that have ever represented it are <a href="#media-key-session-closed">closed</a>. + </p> + <p>An application that creates a session using a type for which the <a href="#is-persistent-session-type">Is persistent session type?</a> algorithm returns <code>true</code> <em class="rfc2119" title="SHOULD">SHOULD</em> + later remove the stored data by first initiating the removal process using <code><a href="#dom-mediakeysession-remove">remove()</a></code> and then ensuring that the removal process, which may involve + message exchange(s), successfully completes. The CDM <em class="rfc2119" title="MAY">MAY</em> also remove sessions as appropriate, but applications <em class="rfc2119" title="SHOULD NOT">SHOULD NOT</em> rely on this. + </p> + <p>See <a href="#security" class="sec-ref"><span class="secno">10.</span> <span class="sec-title">Security</span></a> and <a href="#privacy" class="sec-ref"><span class="secno">11.</span> <span class="sec-title">Privacy</span></a> for additional considerations when supporting persistent storage.</p> + </section> + </section> + + <section id="htmlmediaelement-extensions"> + <!--OddPage--><h2 id="x7-htmlmediaelement-extensions"><span class="secno">7. </span><dfn data-dfn-type="dfn" id="dom-htmlmediaelement" data-idl="" data-title="HTMLMediaElement" data-dfn-for=""><code>HTMLMediaElement</code></dfn> Extensions</h2> + + <!-- Put all the monkey-patching here --> + + <p>This section specifies additions to and modifications of the <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#htmlmediaelement-htmlmediaelement">HTMLMediaElement</a></code> [<cite><a class="bibref" href="#bib-HTML51">HTML51</a></cite>] when the Encrypted Media Extensions are supported.</p> + <p>The following internal values are added to the <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#htmlmediaelement-htmlmediaelement">HTMLMediaElement</a></code>:</p> + <ul> + <li> + <p><var>attaching media keys</var>, which <em class="rfc2119" title="SHALL">SHALL</em> have a boolean value, and</p> + </li> + <li> + <p><var>encrypted block queue</var>, which <em class="rfc2119" title="SHALL">SHALL</em> be a queue of encrypted blocks awaiting decryption, and</p> + </li> + <li> + <p><var>decryption blocked waiting for key</var>, which <em class="rfc2119" title="SHALL">SHALL</em> have a boolean value.</p> + </li> + <li> + <p><var>playback blocked waiting for key</var>, which <em class="rfc2119" title="SHALL">SHALL</em> have a boolean value.</p> + </li> + </ul> + <p>The following modifications are made to the behaviour of the <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#htmlmediaelement-htmlmediaelement">HTMLMediaElement</a></code>:</p> + <ul> + <li> + <p>When a <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#htmlmediaelement-htmlmediaelement">HTMLMediaElement</a></code> is created, its <var>attaching media keys</var> value <em class="rfc2119" title="SHALL">SHALL</em> be initialized to <code>false</code>, its <var>encrypted block queue</var> value <em class="rfc2119" title="SHALL">SHALL</em> be empty, its <var>decryption blocked waiting for key</var> value <em class="rfc2119" title="SHALL">SHALL</em> be initialized to <code>false</code>, and its <var>playback blocked waiting for key</var> value <em class="rfc2119" title="SHALL">SHALL</em> be initialized to <code>false</code>.</p> + </li> + <li> + <p>When the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#current-position">current playback position</a> is changed other than advancing in the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#direction-of-playback">direction of playback</a> as part of normal playback, the <var>encrypted block queue</var> value <em class="rfc2119" title="SHALL">SHALL</em> be empty, the <var>decryption blocked waiting for key</var> value <em class="rfc2119" title="SHALL">SHALL</em> be initialized to <code>false</code>, and the <var>playback blocked waiting for key</var> value <em class="rfc2119" title="SHALL">SHALL</em> be set to <code>false</code>.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-95" aria-level="3"><span>Note</span></div><p class=""> + In other words, these values should be reset when, for example, <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#loading-the-media-resource">loading the media resource</a> or <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#seeking">seeking</a>. + </p></div> + </li> + <li> + <p>In addition to the criteria specified in [<cite><a class="bibref" href="#bib-HTML51">HTML51</a></cite>], an <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#htmlmediaelement-htmlmediaelement">HTMLMediaElement</a></code> <em class="rfc2119" title="SHALL">SHALL</em> be considered a <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#blocked-media-element">blocked media element</a> if its <var>playback blocked waiting for key</var> value is <code>true</code>.</p> + </li> + <li> + <p>When the user agent is ready to begin playback and has encountered an indication that the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a> may contain encrypted blocks during the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#resource-fetch-algorithm">resource fetch algorithm</a>, the user agent <em class="rfc2119" title="SHALL">SHALL</em> run the <a href="#media-may-contain-encrypted-blocks">Media Data May Contain Encrypted Blocks</a> algorithm.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-96" aria-level="3"><span>Note</span></div><p class=""> + For some container formats, such indication is separate from <a href="#initialization-data">Initialization Data</a>. + </p></div> + <div class="note"><div role="heading" class="note-title marker" id="h-note-97" aria-level="3"><span>Note</span></div><p class=""> + The algorithm is to be run after parsing the relevant container data, including running the <a href="#initdata-encountered">Initialization Data Encountered</a> algorithm, but before decoding starts. + </p></div> + </li> + <li> + <p>When the user agent encounters <a href="#initialization-data">Initialization Data</a> in the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a> during the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#resource-fetch-algorithm">resource fetch algorithm</a>, the user agent <em class="rfc2119" title="SHALL">SHALL</em> run the <a href="#initdata-encountered">Initialization Data Encountered</a> algorithm.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-98" aria-level="3"><span>Note</span></div><p class=""> + Some container formats may support encrypted media data that does not contain <a href="#initialization-data">Initialization Data</a> and thus support media data that does not trigger this algorithm. + </p></div> + </li> + <li> + <p>For each block of encrypted <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a> encountered during the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#resource-fetch-algorithm">resource fetch algorithm</a>, the user agent <em class="rfc2119" title="SHALL">SHALL</em> run the <a href="#encrypted-block-encountered">Encrypted Block Encountered</a> algorithm in the order the encrypted blocks were encountered.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-99" aria-level="3"><span>Note</span></div><p class="">The above step provides flexibility for user agent implementations to perform decryption at any time after an encrypted block is encountered before it is needed for playback.</p></div> + </li> + <li> + <p>When one of the following occurs while the <var>decryption blocked waiting for key</var> value is <code>true</code>, the user agent <em class="rfc2119" title="SHALL">SHALL</em> run the <a href="#wait-for-key">Wait for Key</a> algorithm.</p> + <ul> + <li><p>The user agent cannot advance the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#current-position">current playback position</a> in the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#direction-of-playback">direction of playback</a>.</p></li> + <li> + <p>The user agent cannot provide data for the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#current-position">current playback position</a>.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-100" aria-level="3"><span>Note</span></div><p class="">For example, at the beginning of playback or after <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#seeking">seeking</a>.</p></div> + </li> + </ul> + </li> + <li> + <p>Additional attributes and a method are added, as specified below.</p> + </li> + </ul> + + <p>For methods that return a promise, all errors are reported asynchronously by rejecting the returned Promise. This includes [<cite><a class="bibref" href="#bib-WEBIDL">WEBIDL</a></cite>] type mapping errors.</p> + <p>The steps of an algorithm are always aborted when rejecting a promise.</p> + + <div><div><pre class="def idl"><span class="idlInterface" id="idl-def-htmlmediaelement-partial-1" data-idl="" data-title="HTMLMediaElement">partial interface <span class="idlInterfaceID"><a data-no-default="" data-link-for="" data-lt="" href="#dom-htmlmediaelement" class="internalDFN" data-link-type="dfn"><code>HTMLMediaElement</code></a></span> { +<span class="idlAttribute" id="idl-def-htmlmediaelement-mediakeys" data-idl="" data-title="mediaKeys" data-dfn-for="htmlmediaelement"> [<span class="extAttr"><span class="extAttrName"><a href="https://heycam.github.io/webidl/#SecureContext">SecureContext</a></span></span>] + readonly attribute <span class="idlAttrType"><a href="#dfn-mediakeys" class="internalDFN" data-link-type="dfn">MediaKeys</a>?</span> <span class="idlAttrName"><a data-no-default="" data-link-for="htmlmediaelement" data-lt="" href="#dom-htmlmediaelement-mediakeys" class="internalDFN" data-link-type="dfn"><code>mediaKeys</code></a></span>;</span> +<span class="idlAttribute" id="idl-def-htmlmediaelement-onencrypted" data-idl="" data-title="onencrypted" data-dfn-for="htmlmediaelement"> attribute <span class="idlAttrType"><a href="https://html.spec.whatwg.org/multipage/#eventhandler">EventHandler</a></span> <span class="idlAttrName"><a data-no-default="" data-link-for="htmlmediaelement" data-lt="" href="#dom-htmlmediaelement-onencrypted" class="internalDFN" data-link-type="dfn"><code>onencrypted</code></a></span>;</span> +<span class="idlAttribute" id="idl-def-htmlmediaelement-onwaitingforkey" data-idl="" data-title="onwaitingforkey" data-dfn-for="htmlmediaelement"> attribute <span class="idlAttrType"><a href="https://html.spec.whatwg.org/multipage/#eventhandler">EventHandler</a></span> <span class="idlAttrName"><a data-no-default="" data-link-for="htmlmediaelement" data-lt="" href="#dom-htmlmediaelement-onwaitingforkey" class="internalDFN" data-link-type="dfn"><code>onwaitingforkey</code></a></span>;</span> +<span class="idlMethod" id="idl-def-htmlmediaelement-setmediakeys-mediakeys" data-idl="" data-title="setMediaKeys" data-dfn-for="htmlmediaelement"> [<span class="extAttr"><span class="extAttrName"><a href="https://heycam.github.io/webidl/#SecureContext">SecureContext</a></span></span>] <span class="idlMethType"><a href="https://heycam.github.io/webidl/#idl-promise">Promise</a><void></span> <span class="idlMethName"><a data-no-default="" data-link-for="htmlmediaelement" data-lt="setMediaKeys|setmediakeys()" href="#dom-htmlmediaelement-setmediakeys" class="internalDFN" data-link-type="dfn"><code>setMediaKeys</code></a></span>(<span class="idlParam"><span class="idlParamType"><a href="#dfn-mediakeys" class="internalDFN" data-link-type="dfn">MediaKeys</a>?</span> <span class="idlParamName">mediaKeys</span></span>);</span> +};</span></pre></div><section><h3 id="attributes-3">Attributes</h3><dl class="attributes" data-dfn-for="HTMLMediaElement" data-link-for="HTMLMediaElement"><dt><dfn data-dfn-for="htmlmediaelement" data-dfn-type="dfn" id="dom-htmlmediaelement-mediakeys" data-idl="" data-title="mediaKeys"><code>mediaKeys</code></dfn> of type <span class="idlAttrType"><!-- Restore when https://github.com/w3c/respec/issues/893 is fixed. <a> -->MediaKeys<!-- </a> --></span>, readonly , nullable</dt><dd> + <p>The <!-- Restore when https://github.com/w3c/respec/issues/893 is fixed. <a> -->MediaKeys<!-- </a> --> being used when decrypting encrypted <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a> for this media element.</p> + </dd><dt><dfn data-dfn-for="htmlmediaelement" data-dfn-type="dfn" id="dom-htmlmediaelement-onencrypted" data-idl="" data-title="onencrypted"><code>onencrypted</code></dfn> of type <span class="idlAttrType">EventHandler</span></dt><dd> + <p>Event handler for the <code><a href="#dom-evt-encrypted">encrypted</a></code> event. It <em class="rfc2119" title="MUST">MUST</em> be supported by all HTMLMediaElements as both a content attribute and an IDL attribute.</p> + </dd><dt><dfn data-dfn-for="htmlmediaelement" data-dfn-type="dfn" id="dom-htmlmediaelement-onwaitingforkey" data-idl="" data-title="onwaitingforkey"><code>onwaitingforkey</code></dfn> of type <span class="idlAttrType">EventHandler</span></dt><dd> + <p>Event handler for the <code><a href="#dom-evt-waitingforkey">waitingforkey</a></code> event. It <em class="rfc2119" title="MUST">MUST</em> be supported by all HTMLMediaElements as both a content attribute and an IDL attribute.</p> + </dd></dl></section><section><h3 id="methods-4">Methods</h3><dl class="methods" data-dfn-for="HTMLMediaElement" data-link-for="HTMLMediaElement"><dt><dfn data-dfn-for="htmlmediaelement" data-dfn-type="dfn" id="dom-htmlmediaelement-setmediakeys" data-idl="" data-title="setMediaKeys" data-lt="setMediaKeys|setmediakeys()"><code id="setMediaKeys">setMediaKeys</code></dfn></dt><dd> + <p>Provides the <!-- Restore when https://github.com/w3c/respec/issues/893 is fixed. <a> -->MediaKeys<!-- </a> --> to use when decrypting media data during playback.</p> + + <div class="note"><div role="heading" class="note-title marker" id="h-note-101" aria-level="4"><span>Note</span></div><p class="">Support for clearing or replacing the associated <!-- Restore when https://github.com/w3c/respec/issues/893 is fixed. <a> -->MediaKeys<!-- </a> --> object during playback is a quality of implementation issue. In many cases it will result in a bad user experience or rejected promise.</p></div> + + + <table class="parameters"><tbody><tr><th>Parameter</th><th>Type</th><th>Nullable</th><th>Optional</th><th>Description</th></tr><tr><td class="prmName">mediaKeys</td><td class="prmType"><code>MediaKeys</code></td><td class="prmNullTrue"><span role="img" aria-label="True">✔</span></td><td class="prmOptFalse"><span role="img" aria-label="False">✘</span></td><td class="prmDesc"> + A <!-- Restore when https://github.com/w3c/respec/issues/893 is fixed. <a> -->MediaKeys<!-- </a> --> object. + </td></tr></tbody></table><div><em>Return type: </em><code>Promise<void></code></div><p>When this method is invoked, the user agent must run the following steps:</p><ol class="method-algorithm"> + <!-- For simplicity and consistency, do not allow multiple pending calls. --> + <li><p>If this object's <var>attaching media keys</var> value is true, return a promise rejected with an <code><a href="#dfn-InvalidStateError">InvalidStateError</a></code>.</p></li> + <li><p>If <var>mediaKeys</var> and the <code><a href="#dom-mediakeys">mediaKeys</a></code> attribute are the same object, return a resolved promise.</p></li> + <li><p>Let this object's <var>attaching media keys</var> value be true.</p></li> + <li><p>Let <var>promise</var> be a new promise.</p></li> + <li><p>Run the following steps in parallel:</p> + <ol> + <li> + <p>If all the following conditions hold:</p> + <ul> + <li><p><var>mediaKeys</var> is not null,</p></li> + <li> + <p>the CDM instance represented by <var>mediaKeys</var> is already in use by another media element</p> + </li> + <li><p>the user agent is unable to use it with this element</p></li> + </ul> + <p> + then let this object's <var>attaching media keys</var> value be false and reject <var>promise</var> with a <code><a href="#dfn-QuotaExceededError">QuotaExceededError</a></code>. + </p> + </li> + <li><p>If the <code><a href="#dom-mediakeys">mediaKeys</a></code> attribute is not null, run the following steps:</p> + <ol> + <li><p>If the user agent or CDM do not support removing the association, let this object's <var>attaching media keys</var> value be false and reject <var>promise</var> with a <code><a href="#dfn-NotSupportedError">NotSupportedError</a></code>.</p></li> + <li><p>If the association cannot currently be removed, let this object's <var>attaching media keys</var> value be false and reject <var>promise</var> with an <code><a href="#dfn-InvalidStateError">InvalidStateError</a></code>.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-102" aria-level="4"><span>Note</span></div><p class="">For example, some implementations may not allow removal during playback.</p></div> + </li> + <li><p>Stop using the CDM instance represented by the <code><a href="#dom-mediakeys">mediaKeys</a></code> attribute to decrypt <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a> and remove the association with the media element.</p></li> + <li><p>If the preceding step failed, let this object's <var>attaching media keys</var> value be false and reject <var>promise</var> with the appropriate <a href="#error-names">error name</a>.</p></li> + </ol> + </li> + <li><p>If <var>mediaKeys</var> is not null, run the following steps:</p> + <ol> + <li><p>Associate the CDM instance represented by <var>mediaKeys</var> with the media element for decrypting <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a>.</p></li> + <li><p>If the preceding step failed, run the following steps:</p> + <ol> + <li><p>Set the <code><a href="#dom-mediakeys">mediaKeys</a></code> attribute to null.</p></li><!-- In case it was previously not null since the previous association has been removed. --> + <li><p>Let this object's <var>attaching media keys</var> value be false.</p></li> + <li><p>Reject <var>promise</var> with a new <code><a href="https://heycam.github.io/webidl/#dfn-DOMException">DOMException</a></code> whose name is the appropriate <a href="#error-names">error name</a>.</p></li> + </ol> + </li> + <li><p><a href="https://www.w3.org/TR/html51/webappapis.html#queuing">Queue a task</a> to run the <a href="#resume-playback">Attempt to Resume Playback If Necessary</a> algorithm on the media element.</p> + </li> + </ol> + </li> + <li><p>Set the <code><a href="#dom-mediakeys">mediaKeys</a></code> attribute to <var>mediaKeys</var>.</p></li> + <li><p>Let this object's <var>attaching media keys</var> value be false.</p></li> + <li><p>Resolve <var>promise</var>.</p></li> + </ol> + </li> + <li><p>Return <var>promise</var>.</p></li> + </ol></dd></dl></section></div> + + <section id="mediaencryptedevent"> + <h3 id="x7-1-mediaencryptedevent"><span class="secno">7.1 </span><a href="#dom-mediaencryptedevent" class="internalDFN" data-link-type="dfn"><code>MediaEncryptedEvent</code></a></h3> + <p>The MediaEncryptedEvent object is used for the <code><a href="#dom-evt-encrypted">encrypted</a></code> event.</p> + <p>Events are constructed as defined in <a href="https://www.w3.org/TR/dom/#constructing-events">Constructing events</a> [<cite><a class="bibref" href="#bib-DOM">DOM</a></cite>].</p> + + <div><div><pre class="def idl"><span class="idlInterface" id="idl-def-mediaencryptedevent" data-idl="" data-title="MediaEncryptedEvent">[<span class="idlCtor"><span class="extAttrName"><a href="https://heycam.github.io/webidl/#Constructor">Constructor</a></span>(<span class="idlParam"><span class="idlParamType"><a href="https://heycam.github.io/webidl/#idl-DOMString">DOMString</a></span> <span class="idlParamName">type</span></span>, <span class="idlParam">optional <span class="idlParamType"><a href="#dom-mediaencryptedeventinit" class="internalDFN" data-link-type="dfn"><code>MediaEncryptedEventInit</code></a></span> <span class="idlParamName">eventInitDict</span></span>)</span>] +interface <span class="idlInterfaceID"><a data-no-default="" data-link-for="" data-lt="" href="#dom-mediaencryptedevent" class="internalDFN" data-link-type="dfn"><code>MediaEncryptedEvent</code></a></span> : <span class="idlSuperclass">Event</span> { +<span class="idlAttribute" id="idl-def-mediaencryptedevent-initdatatype" data-idl="" data-title="initDataType" data-dfn-for="mediaencryptedevent"> readonly attribute <span class="idlAttrType"><a href="https://heycam.github.io/webidl/#idl-DOMString">DOMString</a></span> <span class="idlAttrName"><a data-no-default="" data-link-for="mediaencryptedevent" data-lt="" href="#dom-mediaencryptedevent-initdatatype" class="internalDFN" data-link-type="dfn"><code>initDataType</code></a></span>;</span> +<span class="idlAttribute" id="idl-def-mediaencryptedevent-initdata" data-idl="" data-title="initData" data-dfn-for="mediaencryptedevent"> readonly attribute <span class="idlAttrType"><a href="https://heycam.github.io/webidl/#idl-ArrayBuffer">ArrayBuffer</a>?</span> <span class="idlAttrName"><a data-no-default="" data-link-for="mediaencryptedevent" data-lt="" href="#dom-mediaencryptedevent-initdata" class="internalDFN" data-link-type="dfn"><code>initData</code></a></span>;</span> +};</span></pre></div><section><h4 id="constructors-0">Constructors</h4><dl class="constructors" data-dfn-for="MediaEncryptedEvent" data-link-for="MediaEncryptedEvent"><dt><dfn data-dfn-for="" data-dfn-type="dfn" id="dom-mediaencryptedevent" data-idl="" data-title="MediaEncryptedEvent"><code>MediaEncryptedEvent</code></dfn></dt><dd> + + <table class="parameters"><tbody><tr><th>Parameter</th><th>Type</th><th>Nullable</th><th>Optional</th><th>Description</th></tr><tr><td class="prmName">type</td><td class="prmType"><code>DOMString</code></td><td class="prmNullFalse"><span role="img" aria-label="False">✘</span></td><td class="prmOptFalse"><span role="img" aria-label="False">✘</span></td><td class="prmDesc"></td></tr><tr><td class="prmName">eventInitDict</td><td class="prmType"><code>MediaEncryptedEventInit</code></td><td class="prmNullFalse"><span role="img" aria-label="False">✘</span></td><td class="prmOptTrue"><span role="img" aria-label="True">✔</span></td><td class="prmDesc"></td></tr></tbody></table></dd></dl></section><section><h4 id="attributes-4">Attributes</h4><dl class="attributes" data-dfn-for="MediaEncryptedEvent" data-link-for="MediaEncryptedEvent"><dt><dfn data-dfn-for="mediaencryptedevent" data-dfn-type="dfn" id="dom-mediaencryptedevent-initdatatype" data-idl="" data-title="initDataType"><code>initDataType</code></dfn> of type <span class="idlAttrType">DOMString</span>, readonly </dt><dd> + Indicates the <a href="#initialization-data-type">Initialization Data Type</a> of the <a href="#initialization-data">Initialization Data</a> contained in the <code><a href="#dom-mediaencryptedevent-initdata">initData</a></code> attribute. + </dd><dt><dfn data-dfn-for="mediaencryptedevent" data-dfn-type="dfn" id="dom-mediaencryptedevent-initdata" data-idl="" data-title="initData"><code>initData</code></dfn> of type <span class="idlAttrType">ArrayBuffer</span>, readonly , nullable</dt><dd> + The <a href="#initialization-data">Initialization Data</a> for the event. + </dd></dl></section></div> + + <section id="mediaencryptedeventinit"> + <h4 id="x7-1-1-mediaencryptedeventinit"><span class="secno">7.1.1 </span><dfn data-dfn-type="dfn" id="dom-mediaencryptedeventinit" data-idl="" data-title="MediaEncryptedEventInit" data-dfn-for=""><code>MediaEncryptedEventInit</code></dfn></h4> + <div><div><pre class="def idl"><span class="idlDictionary" id="idl-def-mediaencryptedeventinit" data-idl="" data-title="MediaEncryptedEventInit">dictionary <span class="idlDictionaryID"><a data-no-default="" data-link-for="" data-lt="" href="#dom-mediaencryptedeventinit" class="internalDFN" data-link-type="dfn"><code>MediaEncryptedEventInit</code></a></span> : <span class="idlSuperclass">EventInit</span> { +<span class="idlMember" id="idl-def-mediaencryptedeventinit-initdatatype" data-idl="" data-title="initDataType" data-dfn-for="mediaencryptedeventinit"> <span class="idlMemberType"><a href="https://heycam.github.io/webidl/#idl-DOMString">DOMString</a></span> <span class="idlMemberName"><a data-no-default="" data-link-for="mediaencryptedeventinit" data-lt="" href="#dom-mediaencryptedeventinit-initdatatype" class="internalDFN" data-link-type="dfn"><code>initDataType</code></a></span> = <span class="idlMemberValue">""</span>;</span> +<span class="idlMember" id="idl-def-mediaencryptedeventinit-initdata" data-idl="" data-title="initData" data-dfn-for="mediaencryptedeventinit"> <span class="idlMemberType"><a href="https://heycam.github.io/webidl/#idl-ArrayBuffer">ArrayBuffer</a>?</span> <span class="idlMemberName"><a data-no-default="" data-link-for="mediaencryptedeventinit" data-lt="" href="#dom-mediaencryptedeventinit-initdata" class="internalDFN" data-link-type="dfn"><code>initData</code></a></span> = <span class="idlMemberValue">null</span>;</span> +};</span></pre></div><section><h5 id="dictionary-mediaencryptedeventinit-members">Dictionary <a class="idlType internalDFN" href="#dom-mediaencryptedeventinit" data-link-type="dfn"><code>MediaEncryptedEventInit</code></a> Members</h5><dl class="dictionary-members" data-dfn-for="MediaEncryptedEventInit" data-link-for="MediaEncryptedEventInit"><dt><dfn data-dfn-for="mediaencryptedeventinit" data-dfn-type="dfn" id="dom-mediaencryptedeventinit-initdatatype" data-idl="" data-title="initDataType"><code>initDataType</code></dfn> of type <span class="idlMemberType">DOMString</span>, defaulting to <code>""</code></dt><dd> + The <a href="#initialization-data-type">Initialization Data Type</a>. + </dd><dt><dfn data-dfn-for="mediaencryptedeventinit" data-dfn-type="dfn" id="dom-mediaencryptedeventinit-initdata" data-idl="" data-title="initData"><code>initData</code></dfn> of type <span class="idlMemberType">ArrayBuffer</span>, nullable, defaulting to <code>null</code></dt><dd> + The <a href="#initialization-data">Initialization Data</a>. + </dd></dl></section></div> + </section> + </section> + + <section id="htmlmediaelement-events" class="informative"> + <h3 id="x7-2-event-summary"><span class="secno">7.2 </span>Event Summary</h3><p><em>This section is non-normative.</em></p> + + <table class="old-table"> + <thead> + <tr> + <th>Event name</th> + <th>Interface</th> + <th>Dispatched when...</th> + <th>Preconditions</th> + </tr> + </thead> + <tbody> + <tr> + <td><dfn id="dom-evt-encrypted"><code>encrypted</code></dfn></td> + <td><a href="#dom-mediaencryptedevent" class="internalDFN" data-link-type="dfn"><code>MediaEncryptedEvent</code></a></td> + <td>The user agent encounters <a href="#initialization-data">Initialization Data</a> in the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a>.</td> + <td>The element's <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-readystate">readyState</a></code> is equal to or greater than <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-have_metadata">HAVE_METADATA</a></code>. + <div class="note"><div role="heading" class="note-title marker" id="h-note-103" aria-level="4"><span>Note</span></div><p class="">It is possible that the element is playing or has played.</p></div> + </td> + </tr> + <tr> + <td><dfn id="dom-evt-waitingforkey"><code>waitingforkey</code></dfn></td> + <td><code><a href="https://www.w3.org/TR/dom/#event">Event</a></code></td> + <td>Playback is blocked waiting for a key.</td> + <td> + The <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-readystate">readyState</a></code> is equal to or less than <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-have_current_data">HAVE_CURRENT_DATA</a></code>. + The element's <var>playback blocked waiting for key</var> value is newly <code>true</code>. + </td> + </tr> + </tbody> + </table> + </section> + + <section id="htmlmediaelement-algorithms"> + <h3 id="x7-3-algorithms"><span class="secno">7.3 </span>Algorithms</h3> + + <section id="media-may-contain-encrypted-blocks"> + <h4 id="x7-3-1-media-data-may-contain-encrypted-blocks"><span class="secno">7.3.1 </span>Media Data May Contain Encrypted Blocks</h4> + <p> + The Media Data May Contain Encrypted Blocks algorithm pauses playback if the user agent requires specification of a <a href="#dfn-mediakeys" class="internalDFN" data-link-type="dfn">MediaKeys</a> object before playing the media data. + Requests to run this algorithm include a target <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#htmlmediaelement-htmlmediaelement">HTMLMediaElement</a></code> object. + </p> + <p>The following steps are run:</p> + <ol> + <li><p>Let the <var>media element</var> be the specified <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#htmlmediaelement-htmlmediaelement">HTMLMediaElement</a></code> object.</p></li> + <li> + <p>If the <var>media element</var>'s <code><a href="#dom-mediakeys">mediaKeys</a></code> attribute is null and the implementation requires specification of a <a href="#dfn-mediakeys" class="internalDFN" data-link-type="dfn">MediaKeys</a> object before decoding potentially-encrypted <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a>, run the following steps:</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-104" aria-level="5"><span>Note</span></div><p class="">These steps may be reached when the application provides <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a> before calling <code><a href="#dom-htmlmediaelement-setmediakeys">setMediaKeys()</a></code> to provide a <a href="#dfn-mediakeys" class="internalDFN" data-link-type="dfn">MediaKeys</a> object. + Selecting a <a href="#cdm">CDM</a> may affect the pipeline and/or decoders used, so some implementations may delay playback of media data that may contain encrypted blocks until a CDM is specified by passing a <a href="#dfn-mediakeys" class="internalDFN" data-link-type="dfn">MediaKeys</a> object to <code><a href="#dom-htmlmediaelement-setmediakeys">setMediaKeys()</a></code>. + </p></div> + <ol> + <li><p>Run the <a href="#wait-for-key">Wait for Key</a> algorithm on the <var>media element</var>.</p></li> + <li><p>Wait for a signal to resume playback.</p></li> + </ol> + </li> + </ol> </section> - <section id="identifier-requirements"> - <h3 id="x8.5-identifiers"><span class="secno">8.5 </span>Identifiers</h3> - <p>The use of identifiers, especially <a href="#uses-distinctive-identifiers-or-distinctive-permanent-identifiers">Distinctive Identifier(s) or Distinctive Permanent Identifier(s)</a>, by implementations presents a privacy concern. This section - defines requirements for avoiding or at least mitigating such concerns. The requirements for <a href="#exposed-value-requirements">Values Exposed to the Application</a> also apply to identifiers exposed to the application. - </p> - <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note125"><span>Note</span></div> - <div class=""> - <p>In summary:</p> - <ul> - <li> - <p><a href="#limit-or-avoid-use-of-distinctive-identifiers-and-permanent-identifiers">Limit or Avoid use of Distinctive Identifiers and Permanent Identifiers</a>.</p> - </li> - <li> - <p> - All identifers except <a href="#permanent-identifier">Permanent Identifiers</a> <em class="rfc2119" title="MUST">MUST</em> be <a href="#per-origin-per-profile-identifiers">unique per origin and profile</a>, <a href="#non-associable-identifiers">non-associable</a>, - and <a href="#allow-identifiers-cleared">clearable</a>. - </p> - </li> - <li> - <p> - All identifers <em class="rfc2119" title="SHOULD">SHOULD</em> be <a href="#encrypt-identifiers">encrypted</a> when exposed outside the client. - </p> - </li> - <li> - <p><a href="#distinctive-identifier">Distinctive Identifiers</a> <em class="rfc2119" title="MUST">MUST</em> be <a href="#encrypt-identifiers">encrypted</a> when exposed outside the client, <a href="#per-origin-per-profile-identifiers">unique per origin and profile</a>, - and <a href="#allow-identifiers-cleared">clearable</a>.</p> - </li> - <li> - <p><a href="#distinctive-permanent-identifier">Distinctive Permanent Identifiers</a> <em class="rfc2119" title="MUST">MUST</em> be <a href="#encrypt-identifiers">encrypted</a> when exposed outside the client and <em class="rfc2119" - title="MUST NOT">MUST NOT</em> be exposed to the application.</p> - </li> - <li> - <p> - All potential identifiers or <a href="#distinctive-value">distinctive values</a> not covered above that are generated as a result of use of the APIs defined in this specification <em class="rfc2119" title="MUST">MUST</em> be <a href="#per-origin-per-profile-identifiers">unique per origin and profile</a> and <a href="#allow-identifiers-cleared">clearable</a>. This includes but is not limited to random identifiers, session data, and other - CDM data. - </p> - </li> - </ul> - </div> - </div> + <section id="initdata-encountered"> + <h4 id="x7-3-2-initialization-data-encountered"><span class="secno">7.3.2 </span>Initialization Data Encountered</h4> + <p> + The Initialization Data Encountered algorithm queues an <code><a href="#dom-evt-encrypted">encrypted</a></code> event for <a href="#initialization-data">Initialization Data</a> encounterd in the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a>. + Requests to run this algorithm include a target <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#htmlmediaelement-htmlmediaelement">HTMLMediaElement</a></code> object. + </p> + <p>The following steps are run:</p> + <ol> + <li><p>Let the <var>media element</var> be the specified <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#htmlmediaelement-htmlmediaelement">HTMLMediaElement</a></code> object.</p></li> + <li><p>Let <var>initDataType</var> be the empty string.</p></li> + <li><p>Let <var>initData</var> be null.</p></li> + <li> + <p>If the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a> is <a href="https://www.w3.org/TR/html51/browsers.html#same-origin">CORS-same-origin</a> and <em>not</em> <a href="#mixed-content">mixed content</a>, run the following steps:</p> + <ol> + <li><p>Let <var>initDataType</var> be the string representing the <a href="#initialization-data-type">Initialization Data Type</a> of the Initialization Data.</p></li> + <li><p>Let <var>initData</var> be the Initialization Data.</p></li> + </ol> + <div class="note"><div role="heading" class="note-title marker" id="h-note-105" aria-level="5"><span>Note</span></div><p class="">While the media element may allow loading of "Optionally-blockable Content" [<cite><a class="bibref" href="#bib-MIXED-CONTENT">MIXED-CONTENT</a></cite>], the user agent <em class="rfc2119" title="MUST NOT">MUST NOT</em> expose Initialization Data from such media data to the application.</p></div> + </li> + <li> + <p><a href="https://www.w3.org/TR/html51/webappapis.html#queuing">Queue a task</a> to create an event named <code><a href="#dom-evt-encrypted">encrypted</a></code> that does not bubble and is not cancellable using the <a href="#dom-mediaencryptedevent" class="internalDFN" data-link-type="dfn"><code>MediaEncryptedEvent</code></a> interface with its <var>type</var> attribute set to <code>encrypted</code> and its <var>isTrusted</var> attribute initialized to <code>true</code>, and dispatch it at the <var>media element</var>.</p> + <p>The event interface <a href="#dom-mediaencryptedevent" class="internalDFN" data-link-type="dfn"><code>MediaEncryptedEvent</code></a> has:</p> + <ul style="list-style-type:none"><li> + <code><a href="#dom-mediaencryptedevent-initdatatype">initDataType</a></code> = <var>initDataType</var><br><br> + <code><a href="#dom-mediaencryptedevent-initdata">initData</a></code> = <var>initData</var> + </li></ul> + <div class="note"><div role="heading" class="note-title marker" id="h-note-106" aria-level="5"><span>Note</span></div><p class=""><code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-readystate">readyState</a></code> is <em>not</em> changed and no algorithms are aborted. This event merely provides information.</p></div> + <div class="note"><div role="heading" class="note-title marker" id="h-note-107" aria-level="5"><span>Note</span></div><p class="">The <code><a href="#dom-mediaencryptedevent-initdata">initData</a></code> attribute will be null if the media data is <em>not</em> <a href="https://www.w3.org/TR/html51/browsers.html#same-origin">CORS-same-origin</a> or is <a href="#mixed-content">mixed content</a>. + Applications may retrieve the Initialization Data from an alternate source. + </p></div> + </li> + </ol> + </section> - <section id="limit-or-avoid-use-of-distinctive-identifiers-and-permanent-identifiers"> - <h4 id="x8.5.1-limit-or-avoid-use-of-distinctive-identifiers-and-permanent-identifiers"><span class="secno">8.5.1 </span>Limit or Avoid use of Distinctive Identifiers and Permanent Identifiers</h4> - <ul> + <section id="encrypted-block-encountered"> + <h4 id="x7-3-3-encrypted-block-encountered"><span class="secno">7.3.3 </span>Encrypted Block Encountered</h4> + <p> + The Encrypted Block Encountered algorithm queues a block of encrypted media data for decryption and attempts to decrypt if possible. + Requests to run this algorithm include a target <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#htmlmediaelement-htmlmediaelement">HTMLMediaElement</a></code> object. + </p> + <p>The following steps are run:</p> + <ol> + <li><p>Let the <var>media element</var> be the specified <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#htmlmediaelement-htmlmediaelement">HTMLMediaElement</a></code> object.</p></li> + <li> + <p>Let <var>block</var> be the block of encrypted media data.</p> + </li> + <li> + <p>Add <var>block</var> to the end of the <var>media element</var>'s <var>encrypted block queue</var>.</p> + </li> + <li> + <p>If the <var>media element</var>'s <var>decryption blocked waiting for key</var> value is <code>false</code>, run the <a href="#attempt-to-decrypt">Attempt to Decrypt</a> algorithm.</p> + <!-- While media-may-contain-encrypted-blocks may also result in waiting for a key without setting this variable, it should not be possible to reach this algorithm in that case. --> + </li> + </ol> + </section> + <section id="attempt-to-decrypt"> + <h4 id="x7-3-4-attempt-to-decrypt"><span class="secno">7.3.4 </span>Attempt to Decrypt</h4> + <p> + The Attempt to Decrypt algorithm attempts to decrypt media data that is queued for decryption. + Requests to run this algorithm include a target <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#htmlmediaelement-htmlmediaelement">HTMLMediaElement</a></code> object. + </p> + <p>The following steps are run:</p> + <ol> + <li><p>Let the <var>media element</var> be the specified <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#htmlmediaelement-htmlmediaelement">HTMLMediaElement</a></code> object.</p></li> + <li><p>If the <var>media element</var>'s <var>encrypted block queue</var> is empty, abort these steps.</p></li> + <li><p>If the <var>media element</var>'s <code><a href="#dom-mediakeys">mediaKeys</a></code> attribute is not null, run the following steps:</p> + <ol> + <li><p>Let <var>media keys</var> be the <a href="#dfn-mediakeys" class="internalDFN" data-link-type="dfn">MediaKeys</a> object referenced by that attribute.</p></li> + <li><p>Let <var>cdm</var> be the CDM instance represented by <var>media keys</var>'s <var>cdm instance</var> value.</p></li> + <li> + <p>If <var>cdm</var> is no longer usable for any reason, run the following steps:</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-108" aria-level="5"><span>Note</span></div><p class="">These steps are intended to be run on unrecoverable failures of the CDM.</p></div> + <ol> <li> - <p>Implementations <em class="rfc2119" title="SHOULD">SHOULD</em> avoid <a href="#uses-distinctive-identifiers-or-distinctive-permanent-identifiers">use of Distinctive Identifier(s) or Distinctive Permanent Identifier(s)</a>.</p> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note126"><span>Note</span></div> - <p class="">For example, use identifiers or other values that apply to a group of clients or devices rather than individual clients.</p> - </div> + <p>Run the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#fatal-decode-error">media data is corrupted</a> steps of the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#resource-fetch-algorithm">resource fetch algorithm</a>.</p> </li> <li> - <p>Implementations <em class="rfc2119" title="SHOULD">SHOULD</em> only <a href="#uses-distinctive-identifiers-or-distinctive-permanent-identifiers">use Distinctive Identifier(s) or Distinctive Permanent Identifier(s)</a> when necessary - to enforce the policies related to the specific CDM instance and session.</p> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note127"><span>Note</span></div> - <p class="">For example, <code><a href="#idl-def-MediaKeySessionType.temporary">"temporary"</a></code> and <code><a href="#idl-def-MediaKeySessionType.persistent-license">"persistent-license"</a></code> sessions may have different requirements.</p> - </div> + <p>Run the <a href="#cdm-unavailable">CDM Unavailable</a> algorithm on <var>media keys</var>.</p> </li> <li> - <p> - Implementations that <a href="#uses-distinctive-identifiers-or-distinctive-permanent-identifiers">use Distinctive Identifier(s) or Distinctive Permanent Identifier(s)</a> <em class="rfc2119" title="SHOULD">SHOULD</em> support - the option to not use them. Implementations with such support <em class="rfc2119" title="SHOULD">SHOULD</em> expose the ability for the user to select this option. - </p> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note128"><span>Note</span></div> - <div class=""> - <p> - When supported, applications can select for this mode using <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> = <code><a href="#idl-def-MediaKeysRequirement.not-allowed">"not-allowed"</a></code>. - Selecting such an option may affect the results of the <code><a href="#dom-navigator-requestmediakeysystemaccess">requestMediaKeySystemAccess()</a></code> call and/or the license requests that are generated from subsequently - generated sessions. - </p> - <p> - Providing the user access to select or choose this implementation capability may allow the user to access content while maintaining a higher degree of privacy. - </p> - </div> - </div> + <p>Abort these steps.</p> </li> - </ul> - </section> - - <section id="encrypt-identifiers"> - <h4 id="x8.5.2-encrypt-identifiers"><span class="secno">8.5.2 </span>Encrypt Identifiers</h4> - <p> - <a href="#distinctive-identifier">Distinctive Identifiers</a> and <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifiers</a> <em class="rfc2119" title="MUST">MUST</em> be encrypted at the message exchange level - when exposed outside the client. All other identifiers <em class="rfc2119" title="SHOULD">SHOULD</em> be encrypted at the message exchange level when exposed outside the client. The encryption <em class="rfc2119" title="MUST">MUST</em> ensure that any two instances of the identifier ciphertext are <a href="#associable-by-entity">associable</a> only by an entity in possession of the decryption key. - </p> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note129"><span>Note</span></div> - <div class=""> - <p>Identifiers may be exposed in the following ways:</p> - <ul> - <li> - <p>To the application via a <code><a href="#dom-evt-message">message</a></code> event.</p> - </li> - <li> - <p>In a message from a server, such as one that is passed to <code><a href="#dom-mediakeysession-update">update()</a></code>.</p> - </li> - <li> - <p>As part of <a href="#individualization">individualization</a>.</p> - </li> - </ul> - </div> - </div> - <p> - The <a href="#cdm">CDM</a> <em class="rfc2119" title="MUST">MUST</em> verify that the encryption key belongs to a valid server for its Key System. For identifers exposed to the application, this <em class="rfc2119" title="MAY">MAY</em> be implemented using a <a href="#server-certificate">server certificate</a>. - </p> - <p>The server <em class="rfc2119" title="MUST NOT">MUST NOT</em> expose a <a href="#distinctive-identifier">Distinctive Identifier</a> to any entity other than the CDM that sent it.</p> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note130"><span>Note</span></div> - <p class="">Specifically, it should not be provided to the application or included unencrypted in messages to the CDM. This can be accomplished by encrypting the identifier or message with the identifier or such that it is only decryptable by - that specific CDM. - </p> - </div> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note131"><span>Note</span></div> - <div class=""> - <p>Among other things, this means that:</p> - <ul> - <li> - <p>Every signature made with device-specific or user-specific keys <em class="rfc2119" title="MUST">MUST</em> be different, even given the same plaintext.</p> - </li> - <li> - <p>Identifiers, keys, or certificates relating to device-specific or user-specific keys <em class="rfc2119" title="MUST">MUST</em> be encrypted for the license or <a href="#individualization">individualization</a> server.</p> - </li> + </ol> + </li> + <li><p>If there is at least one <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> created by the <var>media keys</var> that is not <a href="#media-key-session-closed">closed</a>, run the following steps:</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-109" aria-level="5"><span>Note</span></div><p class="">This check ensures the <var>cdm</var> has finished loading and is a prerequisite for a matching key being available.</p></div> + <ol> + <li><p>Let <var>block</var> be the first entry in the <var>media element</var>'s <var>encrypted block queue</var>.</p></li> + <li><p>Let the <var>block key ID</var> be the key ID of <var>block</var>.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-110" aria-level="5"><span>Note</span></div><p class="">The key ID is generally specified by the container.</p></div> + </li> + <li><p>Use the <var>cdm</var> to execute the following steps:</p> + <ol> + <li><p>Let <var>available keys</var> be the union of keys in sessions that were created by the <var>media keys</var>.</p></li> + <li><p>Let <var>block key</var> be null.</p></li> + <li><p>If any of the <var>available keys</var> corresponds to the <var>block key ID</var> and is <a href="#usable-for-decryption">usable for decryption</a>, let <var>session</var> be a + <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object containing that key and let <var>block key</var> be that key.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-111" aria-level="5"><span>Note</span></div><p class="">If multiple sessions contain a key that is <a href="#usable-for-decryption">usable for decryption</a> for the <var>block key ID</var>, which session and key to use is <a href="#key-system">Key System</a>-dependent.</p></div> + </li> + <li><p>If the status of any of the <var>available keys</var> changed as the result of running the preceding step, <a href="https://www.w3.org/TR/html51/webappapis.html#queuing">queue a task</a> to run the <a href="#update-key-statuses">Update Key Statuses</a> algorithm on each affected <var>session</var>, providing all <a href="#decryption-key-id">key ID(s)</a> in the session along with the appropriate <a href="#dom-mediakeystatus" class="internalDFN" data-link-type="dfn"><code>MediaKeyStatus</code></a> value(s) for each.</p></li> + <li><p>If <var>block key</var> is not null, run the following steps:</p> + <ol> <li> - <p>Messages from the license server to the CDM <em class="rfc2119" title="MUST NOT">MUST NOT</em> expose recipient-unique identifiers, such as the ID of the intended decryption key, on the outside of the encryption envelope.</p> + <p>If <var>session</var>'s <var>session type</var> is <code><a href="#idl-def-MediaKeySessionType.persistent-usage-record">"persistent-usage-record"</a></code>, run the following steps:</p> + <ol> + <li> + <p>Let <var>usage</var> be <var>session</var>'s <var>record of key usage</var>.</p> + </li> + <li> + <p> + If the <var>first decrypt time</var> of <var>usage</var> is <code>null</code>, set the <var>first decrypt time</var> of <var>usage</var> to the current time, accurate to within <var><a href="#key-usage-accuracy">key usage accuracy</a></var>. + </p> + </li> + <li> + <p> + Set the <var>latest decrypt time</var> of <var>usage</var> to the current time, accurate to within <var><a href="#key-usage-accuracy">key usage accuracy</a></var>. + </p> + </li> + </ol> + <div class="note"><div role="heading" class="note-title marker" id="h-note-112" aria-level="5"><span>Note</span></div><p class=""> + Implementations <em class="rfc2119" title="MAY">MAY</em> optimize the times at which this step is executed provided the recorded key usage times remain + accurate to within <var>key usage accuracy</var>. + </p></div> + </li> + <li><p>Use the <var>cdm</var> to decrypt <var>block</var> using <var>block key</var>.</p></li> + <li><p>Follow the steps for the first matching condition from the following list:</p> + <dl class="switch"> + <dt>If decryption fails</dt> + <dd> + <ol> + <li> + <p>Run the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#fatal-decode-error">media data is corrupted</a> steps of the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#resource-fetch-algorithm">resource fetch algorithm</a>.</p> + </li> + <li> + <p>If <var>cdm</var> is no longer usable for any reason then run the <a href="#cdm-unavailable">CDM Unavailable</a> algorithm on <var>media keys</var>.</p> + </li> + <li> + <p>Abort these steps.</p> + </li> + </ol> + </dd> + <dt>Otherwise</dt> + <dd> + <ol> + <li><p>Remove <var>block</var> from the front of the <var>media element</var>'s <var>encrypted block queue</var>.</p></li> + <li><p>Process the decrypted block as normal.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-113" aria-level="5"><span>Note</span></div><p class="">In other words, decode the block.</p></div> + </li> + <li><p>Return to the beginning of this algorithm.</p></li> + </ol> + + </dd> + </dl> + <div class="note"><div role="heading" class="note-title marker" id="h-note-114" aria-level="5"><span>Note</span></div><p class="">Not all decryption problems (e.g., using the wrong key) will result in a decryption failure. In such cases, no error is fired here but one may be fired during decode.</p></div> </li> - </ul> - </div> - </div> - </section> + </ol> + <div class="note"><div role="heading" class="note-title marker" id="h-note-115" aria-level="5"><span>Note</span></div><p class="">Otherwise, there is no key for the <var>block key ID</var> in any session so continue.</p></div> + </li> + </ol> + </li> + </ol> + </li> + </ol> + </li> + <li> + <p>Set the <var>media element</var>'s <var>decryption blocked waiting for key</var> value to <code>true</code>.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-116" aria-level="5"><span>Note</span></div><p class="">This step is reached when there is no key that is <a href="#usable-for-decryption">usable for decryption</a> for <var>block</var>.</p></div> + <div class="note"><div role="heading" class="note-title marker" id="h-note-117" aria-level="5"><span>Note</span></div><div class=""> + <p>Once the user agent has rendered the blocks preceding the block that cannot be decrypted (as much as it can, such as, all complete video frames), it will run the <a href="#wait-for-key">Wait for Key</a> algorithm.</p> + <p>That algorithm is not run directly here in order to allow implementations to decrypt and decode media data ahead of the ahead of the current playback position without affecting the visible behavior.</p> + </div></div></li> + </ol> + + <div class="note"><div role="heading" class="note-title marker" id="h-note-118" aria-level="5"><span>Note</span></div><div class=""> + <p>For frame-based encryption, this may be implemented as follows when the media element attempts to decode a frame as part of the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#resource-fetch-algorithm">resource fetch algorithm</a>:</p> + <ol> + <li><p>Let <var>encrypted</var> be false.</p></li> + <li><p>Detect whether the frame is encrypted.</p> + <dl class="switch"> + <dt>If the frame is encrypted</dt> + <dd>Run the steps above.</dd> + <dt>Otherwise</dt> + <dd>Continue.</dd> + </dl> + </li> + <li><p>Decode the frame.</p></li> + <li><p>Provide the frame for rendering.</p></li> + </ol> + </div></div> + </section> + + <section id="wait-for-key"> + <h4 id="x7-3-5-wait-for-key"><span class="secno">7.3.5 </span>Wait for Key</h4> + <p> + The Wait for Key algorithm queues a <code><a href="#dom-evt-waitingforkey">waitingforkey</a></code> event and updates <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-readystate">readyState</a></code>. + It should only be called when the <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#htmlmediaelement-htmlmediaelement">HTMLMediaElement</a></code> object is <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#potentially-playing">potentially playing</a> and its <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-readystate">readyState</a></code> is equal to <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-have_future_data">HAVE_FUTURE_DATA</a></code> or greater. + Requests to run this algorithm include a target <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#htmlmediaelement-htmlmediaelement">HTMLMediaElement</a></code> object. + </p> + <p>The following steps are run:</p> + <ol> + <li><p>Let the <var>media element</var> be the specified <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#htmlmediaelement-htmlmediaelement">HTMLMediaElement</a></code> object.</p></li> + <li><p>If the <var>media element</var>'s <var>playback blocked waiting for key</var> value is <code>true</code>, abort these steps.</p></li> + <li> + <p>Set the <var>media element</var>'s <var>playback blocked waiting for key</var> value to <code>true</code>.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-119" aria-level="5"><span>Note</span></div><p class="">As a result of the above step, the media element will become a <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#blocked-media-element">blocked media element</a> if it wasn't already. In that case, the media element will stop playback.</p></div> + </li> + <li> + <p>Follow the steps for the first matching condition from the following list:</p> + <dl class="switch"> + <dt>If data for the immediate <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#current-position">current playback position</a> is available</dt> + <dd> + <p>Set the <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-readystate">readyState</a></code> of <var>media element</var> to <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-have_current_data">HAVE_CURRENT_DATA</a></code>.</p> + </dd> + <dt>Otherwise</dt> + <dd> + <p>Set the <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-readystate">readyState</a></code> of <var>media element</var> to <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-have_metadata">HAVE_METADATA</a></code>.</p> + </dd> + </dl> + <div class="note"><div role="heading" class="note-title marker" id="h-note-120" aria-level="5"><span>Note</span></div><p class=""> + In other words, if the video frame and audio data for the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#current-position">current playback position</a> have been decoded because they were unencrypted and/or successfully decrypted, set <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-readystate">readyState</a></code> to <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-have_current_data">HAVE_CURRENT_DATA</a></code>. + Otherwise, including if this was previously the case but the data is no longer available, set <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-readystate">readyState</a></code> to <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-have_metadata">HAVE_METADATA</a></code>. + </p></div> + </li> + <li><p><a href="https://www.w3.org/TR/html51/webappapis.html#queuing">Queue a task</a> to <a href="https://www.w3.org/TR/html51/webappapis.html#firing-a-simple-event-named-e">fire a simple event</a> named <code><a href="#dom-evt-waitingforkey">waitingforkey</a></code> at the <var>media element</var>.</p></li> + <li><p>Suspend playback.</p></li> + </ol> + </section> - <section id="per-origin-per-profile-identifiers"> - <h4 id="x8.5.3-use-per-origin-per-profile-identifiers"><span class="secno">8.5.3 </span>Use Per-Origin Per-Profile Identifiers</h4> - <p> - All identifiers except <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifiers</a> <em class="rfc2119" title="MUST">MUST</em> be unique per <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> and <a href="#browsing-profile">browsing profile</a>. See <a href="#per-origin-per-profile-values" class="sec-ref"><span class="secno">8.4.1</span> <span class="sec-title">Use Per-Origin Per-Profile Values</span></a>. - </p> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note132"><span>Note</span></div> - <div class=""> - <p>This includes but is not limited to <a href="#distinctive-identifier">Distinctive Identifiers</a>.</p> - <p><a href="#distinctive-permanent-identifier">Distinctive Permanent Identifiers</a> <em class="rfc2119" title="MUST NOT">MUST NOT</em> be exposed to the application or origin.</p> - </div> - </div> - </section> - - <section id="non-associable-identifiers"> - <h4 id="x8.5.4-use-non-associable-identifiers"><span class="secno">8.5.4 </span>Use Non-Associable Identifiers</h4> - <p> - All identifiers, including <a href="#distinctive-identifier">Distinctive Identifiers</a>, exposed by the implementation to applications, even in encrypted form, <em class="rfc2119" title="MUST">MUST</em> be <a href="#non-associable-by-application">non-associable by application(s)</a> across <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origins</a>, <a href="#browsing-profile">browsing profiles</a>, and <a href="#allow-identifiers-cleared">clearing of identifiers</a>. - </p> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note133"><span>Note</span></div> - <p class=""> - For all such identifiers, it <em class="rfc2119" title="MUST NOT">MUST NOT</em> be possible for one or more applications, including related license or other servers to achieve such correlation or association. + <section id="resume-playback"> + <h4 id="x7-3-6-attempt-to-resume-playback-if-necessary"><span class="secno">7.3.6 </span>Attempt to Resume Playback If Necessary</h4> + <p> + The Attempt to Resume Playback If Necessary algorithm resumes playback if the media element is blocked waiting for a key and necessary key is currently <a href="#usable-for-decryption">usable for decryption</a> + Requests to run this algorithm include a target <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#htmlmediaelement-htmlmediaelement">HTMLMediaElement</a></code> object. + </p> + <p>The following steps are run:</p> + <ol> + <li><p>Let the <var>media element</var> be the specified <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#htmlmediaelement-htmlmediaelement">HTMLMediaElement</a></code> object.</p></li> + <li><p>If the <var>media element</var>'s <var>playback blocked waiting for key</var> is <code>false</code>, abort these steps.</p></li> + <li><p>Run the <a href="#attempt-to-decrypt">Attempt to Decrypt</a> algorithm on the <var>media element</var>.</p></li> + <li><p>If the user agent can advance the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#current-position">current playback position</a> in the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#direction-of-playback">direction of playback</a>:</p> + <ol> + <li> + <p>Set the <var>media element</var>'s <var>decryption blocked waiting for key</var> value to <code>false</code>.</p> + </li> + <li> + <p>Set the <var>media element</var>'s <var>playback blocked waiting for key</var> value to <code>false</code>.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-121" aria-level="5"><span>Note</span></div><p class="">As a result of the above step, the media element may no longer be a <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#blocked-media-element">blocked media element</a> and thus playback may resume.</p></div> + </li> + <li> + <p> + Set the <var>media element</var>'s <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-readystate">readyState</a></code> value to <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-have_current_data">HAVE_CURRENT_DATA</a></code>, <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-have_future_data">HAVE_FUTURE_DATA</a></code> or + <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-have_enough_data">HAVE_ENOUGH_DATA</a></code> as <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#ready-states">appropriate</a></code>. + </p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-122" aria-level="5"><span>Note</span></div><div class=""> + <p> + States beyond <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#dom-htmlmediaelement-have_current_data">HAVE_CURRENT_DATA</a></code> and the <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#eventdef-media-canplaythrough">canplaythrough</a></code> event do not + (or are unlikely to) consider key availability beyond the current key. </p> - </div> - </section> - - <section id="allow-identifiers-cleared"> - <h4 id="x8.5.5-allow-identifiers-to-be-cleared"><span class="secno">8.5.5 </span>Allow Identifiers to Be Cleared</h4> - <p> - As a consequence of the requirements in <a href="#allow-persistent-data-cleared">Allow Persistent Data to Be Cleared</a>, all potential identifiers or <a href="#distinctive-value">distinctive values</a> except <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifiers</a> <em class="rfc2119" title="MUST">MUST</em> be clearable such that the values are no longer retrievable, observable, or inferable both outside, such as via the APIs defined in this specification, and on the client device. - </p> - <p> - Implementations that <a href="#uses-distinctive-identifiers">use Distinctive Identifier(s)</a> <em class="rfc2119" title="MUST">MUST</em> allow the user to clear the <a href="#distinctive-identifier">Distinctive Identifier(s)</a>. - Implementations that <a href="#uses-distinctive-permanent-identifiers">use Distinctive Permanent Identifier(s)</a> <em class="rfc2119" title="MUST">MUST</em> allow the user to clear values associated with the <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifier(s)</a>. - </p> - <p> - Once cleared, new <a href="#non-associable-by-application">non-associable by applications</a> value(s) <em class="rfc2119" title="MUST">MUST</em> be generated when values, such as <a href="#distinctive-identifier">Distinctive Identifiers</a>, - are subsequently needed. - </p> - </section> + <p> + The change in ready state may also cause HTMLMediaElement events to be fired as described <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#ready-states">here</a></code>. + </p> + </div></div> + </li> + </ol> + </li> + </ol> </section> + </section> + + <section id="media-element-restrictions" class="informative"> + <h3 id="x7-4-media-element-restrictions"><span class="secno">7.4 </span>Media Element Restrictions</h3><p><em>This section is non-normative.</em></p> + <p>Media data processed by a CDM <em class="rfc2119" title="MAY">MAY</em> be unavailable through web platform APIs in the usual way (for example using the CanvasRenderingContext2D drawImage() method and the AudioContext MediaElementAudioSourceNode). + This specification does not define conditions for such non-availability of media data, however, if media data is not available to through such APIs then they <em class="rfc2119" title="MAY">MAY</em> behave as if no media data was present at all.</p> + <p>Where media rendering is not performed by the UA, for example in the case of a hardware-based media pipeline, the full set of HTML rendering capabilities, for example CSS Transforms, <em class="rfc2119" title="MAY">MAY</em> be unavailable. One likely restriction is that + video media <em class="rfc2119" title="MAY">MAY</em> be constrained to appear only in rectangular regions with sides parallel to the edges of the window and with normal orientation.</p> + </section> + </section> + - <section id="individualization"> - <h3 id="x8.6-individualization"><span class="secno">8.6 </span>Individualization</h3> + <section id="implementation-requirements"> + <!--OddPage--><h2 id="x8-implementation-requirements"><span class="secno">8. </span>Implementation Requirements</h2> + <p> + This section defines implementation requirements - for both user agents and <a href="#key-system">Key Systems</a>, including the <a href="#cdm">CDM</a> and server(s) - that may not be explicitly addressed in the algorithms. + The requirements here and throughout the spec apply to all implementations, regardless of whether the CDM is separate from or a part of the user agent. + </p> + + <section id="cdm-constraint-requirements"> + <h3 id="x8-1-cdm-constraints"><span class="secno">8.1 </span>CDM Constraints</h3> + <p> + User agent implementers <em class="rfc2119" title="MUST">MUST</em> ensure that CDMs do not access any information, storage or system capabilities that are not reasonably required for playback of protected media using the features of this specification. + Specifically, the CDM <em class="rfc2119" title="SHALL NOT">SHALL NOT</em>: + </p> + <ul> + <li> <p> - Identifiers, especially <a href="#distinctive-identifier">Distinctive Identifiers</a>, are sometimes generated or obtained via a process called individualization or provisioning. The resulting identifier(s) <em class="rfc2119" title="MUST">MUST</em> be <a href="#non-associable-by-application">non-associable by applications</a> and <a href="#uses-distinctive-identifiers">use of them</a> <em class="rfc2119" title="MUST">MUST</em> only be exposed to a <a href="#per-origin-per-profile-identifiers">single origin from a single profile</a>. - This process <em class="rfc2119" title="MAY">MAY</em> be performed multiple times, such as after identifier(s) are <a href="#allow-identifiers-cleared">cleared</a>. + Access network resources, either local or remote, except via the user agent as explicitly permitted by this specification. </p> - <p>This process <em class="rfc2119" title="MUST">MUST</em> be performed either <a href="#direct-individualization">directly by the user agent</a> or <a href="#app-assisted-individualization">through the application</a>. The mechanisms, flow, - and restrictions for the two types of individualization are different, as described in the following sections. Which method is used depends on the CDM implementation and application of the requirements of this specification, especially - those below. + </li> + <li> + <p> + Access storage (e.g., disk or memory), except where reasonably required for playback of protected media using the features of this specification. </p> - <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note134"><span>Note</span></div> - <p class=""> - <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> controls whether <a href="#distinctive-identifier">Distinctive Identifiers</a> and <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifiers</a> may be <a href="#uses-distinctive-identifiers-or-distinctive-permanent-identifiers">used</a>, including for individualization. Specifically, such identifiers may only be <a href="#uses-distinctive-identifiers-or-distinctive-permanent-identifiers">used</a> when the value of the <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> member of the <a href="#dom-mediakeysystemaccess" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemAccess</code></a> used to create the <a href="#dom-mediakeys" class="internalDFN" data-link-type="dfn"><code>MediaKeys</code></a> object is <code><a href="#idl-def-MediaKeysRequirement.required">"required"</a></code>. - </p> - </div> + </li> + <li> + <p> + Access user data other than CDM state and <a href="#persistent-state-requirements">persistent data</a>. + </p> + </li> + <li> + <p> + Access hardware components or devices, except where reasonably required for playback of protected media using the features of this specification. + </p> + </li> + </ul> + <p> + User Agent implementers may use various techniques to meet the above requirements. For example, a User Agent implementer also implementing their own CDM may include the above as design requirements for that component. + A User Agent implementer making use of a third party CDM may ensure that it executes in a constrained environment (e.g., "sandbox") without access to the prohibited information and components. + </p> + </section> - <section id="direct-individualization"> - <h4 id="x8.6.1-direct-individualization"><span class="secno">8.6.1 </span>Direct Individualization</h4> - <p> - Direct Individualization is performed between the <a href="#cdm">CDM</a> and an origin- and application-independent server. Although the server is origin-independent, the result of the individualization enables the CDM to provide origin-specific - identifiers per the other requirements of this specification. The process <em class="rfc2119" title="MUST">MUST</em> be performed by the user agent and <em class="rfc2119" title="MUST NOT">MUST NOT</em> use the APIs defined in this - specification. - </p> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note135"><span>Note</span></div> - <p class="">For example, such a process may initialize a client device and/or obtain a <a href="#per-origin-per-profile-identifiers">per-origin</a> <a href="#allow-identifiers-cleared">clearable</a> identifier for <a href="#per-origin-per-profile-identifiers">a single browsing profile</a> by communicating with a pre-determined server hosted by the user agent or CDM vendor, possibly <a href="#uses-distinctive-permanent-identifiers">using Distinctive Permanent Identifier(s)</a> or other <a href="#permanent-identifier">Permanent Identifier(s)</a> from the client device. - </p> - </div> - <p>For such individualization, all message exchanges:</p> - <ul> - <li> - <p><em class="rfc2119" title="MUST">MUST</em> be handled by the user agent and performed by the user agent via the user agent's network stack.</p> - </li> - <li> - <p><em class="rfc2119" title="MUST NOT">MUST NOT</em> be performed directly by the CDM.</p> - </li> - <li> - <p><em class="rfc2119" title="MUST NOT">MUST NOT</em> be passed to or through the application via the APIs defined in this specification.</p> - </li> - <li> - <p><em class="rfc2119" title="MUST">MUST</em> be sent to a URL selected independently of any origin and application.</p> - </li> - <li> - <p><em class="rfc2119" title="MUST">MUST</em> encrypt all <a href="#distinctive-identifier">Distinctive Identifiers</a> and <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifiers</a>.</p> - </li> - <li> - <p><em class="rfc2119" title="MUST">MUST</em> use TLS.</p> - </li> - </ul> - <p> - Implementations <em class="rfc2119" title="MUST NOT">MUST NOT</em> expose, even in encrypted form, <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin(s)</a>, origin- or application-specific information, - or values that are <a href="#associable">associable</a> with origin(s) to centralized servers since this could create a central record of all origins visited by a user or device. - </p> - </section> + <section id="messaging-requirements"> + <h3 id="x8-2-messages-and-communication"><span class="secno">8.2 </span>Messages and Communication</h3> + <p> + All messages and communication to and from the CDM, such as between the CDM and a license server, <em class="rfc2119" title="MUST">MUST</em> be passed through the user agent. + The CDM <em class="rfc2119" title="MUST NOT">MUST NOT</em> make direct out-of band network requests. + All messages and communication other than those described in <a href="#direct-individualization">Direct Individualization</a> <em class="rfc2119" title="MUST">MUST</em> be passed through the application via the APIs defined in this specification. + Specifically, all communication that contains application-, <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a>-, or content-specific information or is sent to a URL specified by the application or based on its origin, <em class="rfc2119" title="MUST">MUST</em> pass through the APIs. + This includes all license exchange messages. + </p> + </section> + + <section id="persistent-state-requirements"> + <h3 id="x8-3-persistent-data"><span class="secno">8.3 </span>Persistent Data</h3> + <p> + Persistent Data includes all data stored by the CDM, or by the User Agent on behalf of the CDM, that exists after the destruction of the <a href="#dfn-mediakeys" class="internalDFN" data-link-type="dfn">MediaKeys</a> object. Specifically, it includes any identifiers (including <a href="#distinctive-identifier">Distinctive Identifier(s)</a>), licenses, keys, key IDs, <a href="#record-of-license-destruction">records of license destruction</a>, or <a href="#record-of-key-usage">records of key usage</a> stored by the CDM or by the User Agent on behalf of the CDM. + </p> + <section id="use-origin-specific-key-system-storage"> + <h4 id="x8-3-1-use-origin-specific-and-browsing-profile-specific-key-system-storage"><span class="secno">8.3.1 </span>Use origin-specific and browsing profile-specific Key System storage</h4> + <p>Persistent Data that might impact messages or behavior in an application- or license server-visible way <em class="rfc2119" title="MUST">MUST</em> be stored in an <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a>-specific and <a href="#browsing-profile">browsing profile</a>-specific way and <em class="rfc2119" title="MUST NOT">MUST NOT</em> leak to or from private browsing sessions. + Specifically but not exhaustively, session data, licenses, keys and per-origin identifiers <em class="rfc2119" title="MUST">MUST</em> be stored per-<a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> and per-<a href="#browsing-profile">browsing profile</a>. + </p> + <p> + See <a href="#session-storage">Session Storage and Persistence</a>. + </p> + </section> + <section id="allow-persistent-data-cleared"> + <h4 id="x8-3-2-allow-persistent-data-to-be-cleared"><span class="secno">8.3.2 </span>Allow Persistent Data to Be Cleared</h4> + <p> + Implementations that use Persistent Data <em class="rfc2119" title="MUST">MUST</em> allow the user to clear that data such that it is no longer retrievable both outside, such as via the APIs defined in this specification, and on the client device. + </p> + <p> + User Agents <em class="rfc2119" title="SHOULD">SHOULD</em>: + </p> + <ul> + <li> + <p> + Treat Persistent Data like other site data, such as cookies [<cite><a class="bibref" href="#bib-COOKIES">COOKIES</a></cite>]. Specifically: + </p> + <ul> + <li> + <p id="allow-persistent-data-cleared-with-cookies"> + Allow users to clear Persistent Data along with cookies [<cite><a class="bibref" href="#bib-COOKIES">COOKIES</a></cite>] and other site data. + </p> + </li> + <li> + <p> + Allow users to clear Persistent Data as part of user agent features to clear browsing history. + </p> + </li> + <li> + <p> + Include Persistent Data in "remove all data" features. + </p> + </li> + <li> + <p> + Present Persistent Data in the same UI locations as other site data. + </p> + </li> + </ul> + </li> + <li> + <p> + Allow users to clear Persistent Data on a per-<a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> and per-<a href="#browsing-profile">browsing profile</a> basis, particularly as part of a "Forget about this site" feature that forgets cookies [<cite><a class="bibref" href="#bib-COOKIES">COOKIES</a></cite>], databases, etc. associated with a particular site. + </p> + </li> + <li> + <p> + Ensure that operations which clear Persistent Data are sufficiently atomic to prevent a "cookie resurrection" type of recorrelation of a new identifier with the old by relying on another type of locally stored data that did not get cleared at the same time. See <a href="#incomplete-clearing">incomplete clearing of data</a>. + </p></li><li> + <p> + Present these interfaces in a way that helps users to understand the possibility of <a href="#incomplete-clearing">incomplete clearing of data</a> and enables them to delete data associated with all features that persist data, including cookies [<cite><a class="bibref" href="#bib-COOKIES">COOKIES</a></cite>] and web storage, simultaneously. + </p> + </li> + <li> + <p> + Present the interfaces for disabling and re-enabling a Key System in a way that helps users to understand the possibility of <a href="#incomplete-clearing">incomplete clearing of data</a> and enables them to delete all such data in all persistent storage features simultaneously. + </p> + </li> + <li> + <p> + Allow users to specifically delete Persistent Data, by <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> and/or for all origins. + </p> + </li> + </ul> + </section> + <section id="encrypt-or-obfuscate-persistent-data"> + <h4 id="x8-3-3-encrypt-or-obfuscate-persistent-data"><span class="secno">8.3.3 </span>Encrypt or obfuscate Persistent Data</h4> + <p>User agents <em class="rfc2119" title="SHOULD">SHOULD</em> treat Persistent Data as potentially sensitive; it is quite possible for user privacy to be compromised by the release of this information. + To this end, user agents <em class="rfc2119" title="SHOULD">SHOULD</em> ensure that Persistent Data is securely stored and when deleting data, it is promptly deleted from the underlying storage. + </p> + </section> + </section> + + <section id="exposed-value-requirements"> + <h3 id="x8-4-values-exposed-to-the-application"><span class="secno">8.4 </span>Values Exposed to the Application</h3> + <p>Values exposed to or inferable by, such as via its use by the CDM, the application could be used to identify the client or user, regardless of whether they are designed to be identifiers. + This section defines requirements for avoiding or at least mitigating such concerns. + There are additional requirements for <a href="#identifier-requirements">Identifiers</a>. + </p> - <section id="app-assisted-individualization"> - <h4 id="x8.6.2-app-assisted-individualization"><span class="secno">8.6.2 </span>App-Assisted Individualization</h4> - <p>App-Assisted Individualization is performed between the <a href="#cdm">CDM</a> and the application, including an application-selected server, and results in a per-origin identifier. The process <em class="rfc2119" title="MUST">MUST</em> be performed via the APIs defined in this specification and <em class="rfc2119" title="MUST NOT">MUST NOT</em> involve other methods of communication. As with all other uses of the APIs, the process <em class="rfc2119" title="MAY">MAY</em> <a href="#uses-distinctive-identifiers">use one or more Distinctive Identifier(s)</a>, but it <em class="rfc2119" title="MUST NOT">MUST NOT</em> <a href="#uses-distinctive-permanent-identifiers">use Distinctive Permanent Identifier(s)</a> or non-origin-specific values, even in encrypted form. If the process <a href="#uses-distinctive-identifiers">use one or more Distinctive Identifier(s)</a>, the resulting identifier is by definition also a <a href="#distinctive-identifier">Distinctive Identifier</a>. - </p> - <p>For such individualization, all message exchanges:</p> - <ul> - <li> - <p><em class="rfc2119" title="MUST">MUST</em> be passed to or through the application via the APIs defined in this specification.</p> - </li> - <li> - <p><em class="rfc2119" title="SHALL">SHALL</em> use the message type <code><a href="#idl-def-MediaKeyMessageType.individualization-request">"individualization-request"</a></code> for all related <code><a href="#dom-evt-message">message</a></code> events.</p> - </li> - <li> - <p><em class="rfc2119" title="MUST NOT">MUST NOT</em> be performed by the user agent.</p> - </li> - <li> - <p><em class="rfc2119" title="MUST NOT">MUST NOT</em> be performed directly by the CDM.</p> - </li> - <li> - <p><em class="rfc2119" title="MUST NOT">MUST NOT</em> contain or otherwise <a href="#uses-distinctive-permanent-identifiers">use Distinctive Permanent Identifier(s)</a>.</p> - </li> - <li> - <p><em class="rfc2119" title="MUST NOT">MUST NOT</em> contain non-origin-specific per-client information</p> - </li> - <li> - <p><em class="rfc2119" title="MUST">MUST</em> adhere to the <a href="#identifier-requirements">identifier requirements</a>.</p> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note136"><span>Note</span></div> - <p class="">This includes only using values that are <a href="#per-origin-per-profile-identifiers">unique per origin and profile</a> and <a href="#allow-identifiers-cleared">clearable</a> and <a href="#encrypt-identifiers">encrypting</a> them as required.</p> - </div> - </li> - <li> - <p><em class="rfc2119" title="MUST NOT">MUST NOT</em> provide executable code to the CDM.</p> - </li> - </ul> + <section id="per-origin-per-profile-values"> + <h4 id="x8-4-1-use-per-origin-per-profile-values"><span class="secno">8.4.1 </span>Use Per-Origin Per-Profile Values</h4> + <!-- Issue #101 may affect this text. --> + <p> + All <a href="#distinctive-value">distinctive values</a> exposed to or inferable by the application <em class="rfc2119" title="MUST">MUST</em> be unique per <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> and <a href="#browsing-profile">browsing profile</a>. + That is, the value(s) used for one <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> using the APIs defined in this specification <em class="rfc2119" title="MUST">MUST</em> be different from those used for any other origin using the APIs, + and value(s) used in one <a href="#browsing-profile">browsing profile</a> <em class="rfc2119" title="MUST">MUST</em> be different from those used for any other profile, regardless of origin. + Such values <em class="rfc2119" title="MUST NOT">MUST NOT</em> leak to or from private browsing sessions. + </p> + <p> + Values across origins and profiles <em class="rfc2119" title="MUST">MUST</em> be <a href="#non-associable-by-application">non-associable by applications</a>, meaning it <em class="rfc2119" title="MUST NOT">MUST NOT</em> be possible to correlate values from multiple origins or profiles, such as to determine that they came from the same client or user. + Specifically, implementations that derive per-origin values from an origin-independent and/or profile-independent value, <em class="rfc2119" title="MUST">MUST</em> do so in a way that ensures the above non-associability + property, such as by using derivation functions with appropriate non-reversible properties. + </p> + </section> + + <section id="allow-values-to-be-cleared"> + <h4 id="x8-4-2-allow-values-to-be-cleared"><span class="secno">8.4.2 </span>Allow Values to Be Cleared</h4> + <p> + As a consequence of the requirements in <a href="#allow-persistent-data-cleared">Allow Persistent Data to Be Cleared</a>, + all persisted values exposed to the application <em class="rfc2119" title="MUST">MUST</em> be clearable + such that the values are no longer retrievable, observable, or inferable both outside, such as via the APIs defined in this specification, and on the client device. + </p> + <p> + Once cleared, new <a href="#non-associable-by-application">non-associable by applications</a> value(s) <em class="rfc2119" title="MUST">MUST</em> be generated when values are subsequently needed. + </p> + </section> + </section> + + <section id="identifier-requirements"> + <h3 id="x8-5-identifiers"><span class="secno">8.5 </span>Identifiers</h3> + <p>The use of identifiers, especially <a href="#uses-distinctive-identifiers-or-distinctive-permanent-identifiers">Distinctive Identifier(s) or Distinctive Permanent Identifier(s)</a>, by implementations presents a privacy concern. + This section defines requirements for avoiding or at least mitigating such concerns. + The requirements for <a href="#exposed-value-requirements">Values Exposed to the Application</a> also apply to identifiers exposed to the application. + </p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-123" aria-level="4"><span>Note</span></div><div class=""> + <p>In summary:</p> + <ul> + <li><p><a href="#limit-or-avoid-use-of-distinctive-identifiers-and-permanent-identifiers">Limit or Avoid use of Distinctive Identifiers and Permanent Identifiers</a>.</p></li> + <li> + <p> + All identifers except <a href="#permanent-identifier">Permanent Identifiers</a> <em class="rfc2119" title="MUST">MUST</em> be <a href="#per-origin-per-profile-identifiers">unique per origin and profile</a>, <a href="#non-associable-identifiers">non-associable</a>, and <a href="#allow-identifiers-cleared">clearable</a>. + </p> + </li> + <li> + <p> + All identifers <em class="rfc2119" title="SHOULD">SHOULD</em> be <a href="#encrypt-identifiers">encrypted</a> when exposed outside the client. + </p> + </li> + <li><p><a href="#distinctive-identifier">Distinctive Identifiers</a> <em class="rfc2119" title="MUST">MUST</em> be <a href="#encrypt-identifiers">encrypted</a> when exposed outside the client, <a href="#per-origin-per-profile-identifiers">unique per origin and profile</a>, and <a href="#allow-identifiers-cleared">clearable</a>.</p></li> + <li><p><a href="#distinctive-permanent-identifier">Distinctive Permanent Identifiers</a> <em class="rfc2119" title="MUST">MUST</em> be <a href="#encrypt-identifiers">encrypted</a> when exposed outside the client and <em class="rfc2119" title="MUST NOT">MUST NOT</em> be exposed to the application.</p></li> + <li> + <p> + All potential identifiers or <a href="#distinctive-value">distinctive values</a> not covered above that are generated as a result of use of the APIs defined in this specification <em class="rfc2119" title="MUST">MUST</em> be <a href="#per-origin-per-profile-identifiers">unique per origin and profile</a> and <a href="#allow-identifiers-cleared">clearable</a>. + This includes but is not limited to random identifiers, session data, and other CDM data. + </p> + </li> + </ul> + </div></div> + + <section id="limit-or-avoid-use-of-distinctive-identifiers-and-permanent-identifiers"> + <h4 id="x8-5-1-limit-or-avoid-use-of-distinctive-identifiers-and-permanent-identifiers"><span class="secno">8.5.1 </span>Limit or Avoid use of Distinctive Identifiers and Permanent Identifiers</h4> + <ul> + <li> + <p>Implementations <em class="rfc2119" title="SHOULD">SHOULD</em> avoid <a href="#uses-distinctive-identifiers-or-distinctive-permanent-identifiers">use of Distinctive Identifier(s) or Distinctive Permanent Identifier(s)</a>.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-124" aria-level="5"><span>Note</span></div><p class="">For example, use identifiers or other values that apply to a group of clients or devices rather than individual clients.</p></div> + </li> + <li> + <p>Implementations <em class="rfc2119" title="SHOULD">SHOULD</em> only <a href="#uses-distinctive-identifiers-or-distinctive-permanent-identifiers">use Distinctive Identifier(s) or Distinctive Permanent Identifier(s)</a> when necessary to enforce the policies related to the specific CDM instance and session.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-125" aria-level="5"><span>Note</span></div><p class="">For example, <code><a href="#idl-def-MediaKeySessionType.temporary">"temporary"</a></code> and <code><a href="#idl-def-MediaKeySessionType.persistent-license">"persistent-license"</a></code> sessions may have different requirements.</p></div> + </li> + <li> + <p> + Implementations that <a href="#uses-distinctive-identifiers-or-distinctive-permanent-identifiers">use Distinctive Identifier(s) or Distinctive Permanent Identifier(s)</a> <em class="rfc2119" title="SHOULD">SHOULD</em> support the option to not use them. + Implementations with such support <em class="rfc2119" title="SHOULD">SHOULD</em> expose the ability for the user to select this option. + </p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-126" aria-level="5"><span>Note</span></div><div class=""> <p> - When <a href="#associable">associable</a> values, including <a href="#distinctive-identifier">Distinctive Identifier(s)</a>, are <a href="#uses-distinctive-identifiers">used</a> in the process, implementations <em class="rfc2119" title="MUST NOT">MUST NOT</em> expose, even in encrypted form, <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin(s)</a>-, origin- or application-specific information, or values that are <a href="#associable">associable</a> with origin(s) - to centralized servers since this could create a central record of all origins visited by a user or device. + When supported, applications can select for this mode using <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> = <code><a href="#idl-def-MediaKeysRequirement.not-allowed">"not-allowed"</a></code>. + Selecting such an option may affect the results of the <code><a href="#dom-navigator-requestmediakeysystemaccess">requestMediaKeySystemAccess()</a></code> call and/or the license requests that are generated from subsequently generated sessions. </p> - <p>With appropriate precautions, such individualization can provide better privacy than <a href="#direct-individualization">Direct Individualization</a>, though not as good as models that do not <a href="#uses-distinctive-identifiers">use Distinctive Identifier(s)</a>. - To preserve the benefits of such a design and to avoid introducing other privacy concerns, such implementations and the applications that support them <em class="rfc2119" title="SHOULD">SHOULD</em> avoid deferring or forwarding individualization - messages to a central server or other server not controlled by the application author. + <p> + Providing the user access to select or choose this implementation capability may allow the user to access content while maintaining a higher degree of privacy. </p> - </section> + </div></div> + </li> + </ul> </section> - <section id="support-multiple-keys"> - <h3 id="x8.7-support-multiple-keys"><span class="secno">8.7 </span>Support Multiple Keys</h3> - <p>Implementations <em class="rfc2119" title="MUST">MUST</em> support multiple keys in each <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object.</p> - <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note137"><span>Note</span></div> - <p class="">The mechanics of how multiple keys are supported is an implementation detail, but it <em class="rfc2119" title="MUST">MUST</em> be transparent to the application and the APIs defined in this specification.</p> - </div> + <section id="encrypt-identifiers"> + <h4 id="x8-5-2-encrypt-identifiers"><span class="secno">8.5.2 </span>Encrypt Identifiers</h4> + <p> + <a href="#distinctive-identifier">Distinctive Identifiers</a> and <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifiers</a> <em class="rfc2119" title="MUST">MUST</em> be encrypted at the message exchange level when exposed outside the client. + All other identifiers <em class="rfc2119" title="SHOULD">SHOULD</em> be encrypted at the message exchange level when exposed outside the client. + The encryption <em class="rfc2119" title="MUST">MUST</em> ensure that any two instances of the identifier ciphertext are <a href="#associable-by-entity">associable</a> only by an entity in possession of the decryption key. + </p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-127" aria-level="5"><span>Note</span></div><div class=""> + <p>Identifiers may be exposed in the following ways:</p> + <ul> + <li><p>To the application via a <code><a href="#dom-evt-message">message</a></code> event.</p></li> + <li><p>In a message from a server, such as one that is passed to <code><a href="#dom-mediakeysession-update">update()</a></code>.</p></li> + <li><p>As part of <a href="#individualization">individualization</a>.</p></li> + </ul> + </div></div> + <p> + The <a href="#cdm">CDM</a> <em class="rfc2119" title="MUST">MUST</em> verify that the encryption key belongs to a valid server for its Key System. + For identifers exposed to the application, this <em class="rfc2119" title="MAY">MAY</em> be implemented using a <a href="#server-certificate">server certificate</a>. + </p> + <p>The server <em class="rfc2119" title="MUST NOT">MUST NOT</em> expose a <a href="#distinctive-identifier">Distinctive Identifier</a> to any entity other than the CDM that sent it.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-128" aria-level="5"><span>Note</span></div><p class="">Specifically, it should not be provided to the application or included unencrypted in messages to the CDM. + This can be accomplished by encrypting the identifier or message with the identifier or such that it is only decryptable by that specific CDM. + </p></div> + <div class="note"><div role="heading" class="note-title marker" id="h-note-129" aria-level="5"><span>Note</span></div><div class=""> + <p>Among other things, this means that:</p> + <ul> + <li><p>Every signature made with device-specific or user-specific keys <em class="rfc2119" title="MUST">MUST</em> be different, even given the same plaintext.</p></li> + <li><p>Identifiers, keys, or certificates relating to device-specific or user-specific keys <em class="rfc2119" title="MUST">MUST</em> be encrypted for the license or <a href="#individualization">individualization</a> server.</p></li> + <li><p>Messages from the license server to the CDM <em class="rfc2119" title="MUST NOT">MUST NOT</em> expose recipient-unique identifiers, such as the ID of the intended decryption key, on the outside of the encryption envelope.</p></li> + </ul> + </div></div> + </section> - <p>Implementations <em class="rfc2119" title="MUST">MUST</em> support seamless switching between keys during playback. This includes both keys in the same <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> and keys in separate <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> objects. - </p> + <section id="per-origin-per-profile-identifiers"> + <h4 id="x8-5-3-use-per-origin-per-profile-identifiers"><span class="secno">8.5.3 </span>Use Per-Origin Per-Profile Identifiers</h4> + <p> + All identifiers except <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifiers</a> <em class="rfc2119" title="MUST">MUST</em> be unique per <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> and <a href="#browsing-profile">browsing profile</a>. + See <a href="#per-origin-per-profile-values" class="sec-ref"><span class="secno">8.4.1</span> <span class="sec-title">Use Per-Origin Per-Profile Values</span></a>. + </p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-130" aria-level="5"><span>Note</span></div><div class=""> + <p>This includes but is not limited to <a href="#distinctive-identifier">Distinctive Identifiers</a>.</p> + <p><a href="#distinctive-permanent-identifier">Distinctive Permanent Identifiers</a> <em class="rfc2119" title="MUST NOT">MUST NOT</em> be exposed to the application or origin.</p> + </div></div> </section> - <section id="initialization-data-type-support-requirements"> - <h3 id="x8.8-initialization-data-type-support"><span class="secno">8.8 </span>Initialization Data Type Support</h3> - <section id="licenses-generated-are-independent-of-content-type"> - <h4 id="x8.8.1-licenses-generated-are-independent-of-content-type"><span class="secno">8.8.1 </span>Licenses Generated are Independent of Content Type</h4> - <p>Implementations <em class="rfc2119" title="SHOULD">SHOULD</em> allow licenses generated with any <a href="#initialization-data-type">Initialization Data Type</a> they support to be used with any content type.</p> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note138"><span>Note</span></div> - <p class="">Otherwise, the <code><a href="#dom-navigator-requestmediakeysystemaccess">requestMediaKeySystemAccess()</a></code> algorithm might, for example, reject a <a href="#dom-mediakeysystemconfiguration" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemConfiguration</code></a> because one of the <code><a href="#dom-mediakeysystemconfiguration-initdatatypes">initDataTypes</a></code> is not supported with one of the <code><a href="#dom-mediakeysystemconfiguration-videocapabilities">videoCapabilities</a></code>.</p> - </div> - </section> - - <section id="support-extraction-from-media-data"> - <h4 id="x8.8.2-support-extraction-from-media-data"><span class="secno">8.8.2 </span>Support Extraction From Media Data</h4> - <p>For any supported <a href="#initialization-data-type">Initialization Data Type</a> that may appear in a supported container, the user agents <em class="rfc2119" title="MUST">MUST</em> support <a href="#initdata-encountered">extracting</a> that type of <a href="#initialization-data">Initialization Data</a> from each such supported container.</p> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note139"><span>Note</span></div> - <p class="">In other words, indicating support for an <a href="#initialization-data-type">Initialization Data Type</a> implies both CDM support for generating license requests and, for container-specific types, user agent support for extracting - it from the container. This does <strong>not</strong> mean that implementations must be able to parse <em>any</em> supported <a href="#initialization-data">Initialization Data</a> from <em>any</em> supported content type. - </p> - </div> - </section> + <section id="non-associable-identifiers"> + <h4 id="x8-5-4-use-non-associable-identifiers"><span class="secno">8.5.4 </span>Use Non-Associable Identifiers</h4> + <p> + All identifiers, including <a href="#distinctive-identifier">Distinctive Identifiers</a>, exposed by the implementation to applications, even in encrypted form, <em class="rfc2119" title="MUST">MUST</em> be <a href="#non-associable-by-application">non-associable by application(s)</a> across <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origins</a>, <a href="#browsing-profile">browsing profiles</a>, and <a href="#allow-identifiers-cleared">clearing of identifiers</a>. + </p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-131" aria-level="5"><span>Note</span></div><p class=""> + For all such identifiers, it <em class="rfc2119" title="MUST NOT">MUST NOT</em> be possible for one or more applications, including related license or other servers to achieve such correlation or association. + </p></div> + </section> + + <section id="allow-identifiers-cleared"> + <h4 id="x8-5-5-allow-identifiers-to-be-cleared"><span class="secno">8.5.5 </span>Allow Identifiers to Be Cleared</h4> + <p> + As a consequence of the requirements in <a href="#allow-persistent-data-cleared">Allow Persistent Data to Be Cleared</a>, + all potential identifiers or <a href="#distinctive-value">distinctive values</a> except <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifiers</a> <em class="rfc2119" title="MUST">MUST</em> be clearable + such that the values are no longer retrievable, observable, or inferable both outside, such as via the APIs defined in this specification, and on the client device. + </p> + <p> + Implementations that <a href="#uses-distinctive-identifiers">use Distinctive Identifier(s)</a> <em class="rfc2119" title="MUST">MUST</em> allow the user to clear the <a href="#distinctive-identifier">Distinctive Identifier(s)</a>. + Implementations that <a href="#uses-distinctive-permanent-identifiers">use Distinctive Permanent Identifier(s)</a> <em class="rfc2119" title="MUST">MUST</em> allow the user to clear values associated with the <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifier(s)</a>. + </p> + <p> + Once cleared, new <a href="#non-associable-by-application">non-associable by applications</a> value(s) <em class="rfc2119" title="MUST">MUST</em> be generated when values, such as <a href="#distinctive-identifier">Distinctive Identifiers</a>, are subsequently needed. + </p> </section> + </section> - <section id="media-requirements"> - <h3 id="x8.9-supported-media"><span class="secno">8.9 </span>Supported Media</h3> - <p>This section defines properties of content (<a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-resource">media resource</a>) supported by implementations of this specification.</p> + <section id="individualization"> + <h3 id="x8-6-individualization"><span class="secno">8.6 </span>Individualization</h3> + <p> + Identifiers, especially <a href="#distinctive-identifier">Distinctive Identifiers</a>, are sometimes generated or obtained via a process called individualization or provisioning. + The resulting identifier(s) <em class="rfc2119" title="MUST">MUST</em> be <a href="#non-associable-by-application">non-associable by applications</a> and <a href="#uses-distinctive-identifiers">use of them</a> <em class="rfc2119" title="MUST">MUST</em> only be exposed to a <a href="#per-origin-per-profile-identifiers">single origin from a single profile</a>. + This process <em class="rfc2119" title="MAY">MAY</em> be performed multiple times, such as after identifier(s) are <a href="#allow-identifiers-cleared">cleared</a>. + </p> + <p>This process <em class="rfc2119" title="MUST">MUST</em> be performed either <a href="#direct-individualization">directly by the user agent</a> or <a href="#app-assisted-individualization">through the application</a>. + The mechanisms, flow, and restrictions for the two types of individualization are different, as described in the following sections. + Which method is used depends on the CDM implementation and application of the requirements of this specification, especially those below. + </p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-132" aria-level="4"><span>Note</span></div><p class=""> + <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> controls whether <a href="#distinctive-identifier">Distinctive Identifiers</a> and <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifiers</a> may be <a href="#uses-distinctive-identifiers-or-distinctive-permanent-identifiers">used</a>, including for individualization. + Specifically, such identifiers may only be <a href="#uses-distinctive-identifiers-or-distinctive-permanent-identifiers">used</a> when the value of the <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> member of the <a href="#dom-mediakeysystemaccess" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemAccess</code></a> used to create the <a href="#dfn-mediakeys" class="internalDFN" data-link-type="dfn">MediaKeys</a> object is <code><a href="#idl-def-MediaKeysRequirement.required">"required"</a></code>. + </p></div> + + <section id="direct-individualization"> + <h4 id="x8-6-1-direct-individualization"><span class="secno">8.6.1 </span>Direct Individualization</h4> + <p> + Direct Individualization is performed between the <a href="#cdm">CDM</a> and an origin- and application-independent server. + Although the server is origin-independent, the result of the individualization enables the CDM to provide origin-specific identifiers per the other + requirements of this specification. + The process <em class="rfc2119" title="MUST">MUST</em> be performed by the user agent and <em class="rfc2119" title="MUST NOT">MUST NOT</em> use the APIs defined in this specification. + </p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-133" aria-level="5"><span>Note</span></div><p class="">For example, such a process may initialize a client device and/or obtain a <a href="#per-origin-per-profile-identifiers">per-origin</a> <a href="#allow-identifiers-cleared">clearable</a> identifier for <a href="#per-origin-per-profile-identifiers">a single browsing profile</a> by communicating with a pre-determined server hosted by the user agent or CDM vendor, possibly <a href="#uses-distinctive-permanent-identifiers">using Distinctive Permanent Identifier(s)</a> or other <a href="#permanent-identifier">Permanent Identifier(s)</a> from the client device. + </p></div> + <p>For such individualization, all message exchanges:</p> + <ul> + <li><p><em class="rfc2119" title="MUST">MUST</em> be handled by the user agent and performed by the user agent via the user agent's network stack.</p></li> + <li><p><em class="rfc2119" title="MUST NOT">MUST NOT</em> be performed directly by the CDM.</p></li> + <li><p><em class="rfc2119" title="MUST NOT">MUST NOT</em> be passed to or through the application via the APIs defined in this specification.</p></li> + <li><p><em class="rfc2119" title="MUST">MUST</em> be sent to a URL selected independently of any origin and application.</p></li> + <li><p><em class="rfc2119" title="MUST">MUST</em> encrypt all <a href="#distinctive-identifier">Distinctive Identifiers</a> and <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifiers</a>.</p></li> + <li><p><em class="rfc2119" title="MUST">MUST</em> use TLS.</p></li> + </ul> + <p> + Implementations <em class="rfc2119" title="MUST NOT">MUST NOT</em> expose, even in encrypted form, <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin(s)</a>, origin- or application-specific information, or values that are <a href="#associable">associable</a> with origin(s) to centralized servers since this could create a central record of all origins visited by a user or device. + </p> + </section> - <section id="unencrypted-container"> - <h4 id="x8.9.1-unencrypted-container"><span class="secno">8.9.1 </span>Unencrypted Container</h4> - <p> - The media container <em class="rfc2119" title="MUST NOT">MUST NOT</em> be encrypted. This specification relies on the user agent's ability to parse the media container without having to decrypt any of the media data. This includes - the <a href="#encrypted-block-encountered">Encrypted Block Encountered</a> and <a href="#initdata-encountered">Initialization Data Encountered</a> algorithms as well as supporting standard <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#htmlmediaelement-htmlmediaelement">HTMLMediaElement</a></code> [<cite><a class="bibref" href="#bib-HTML51">HTML51</a></cite>] functionality, such as <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#seeking">seeking</a>. - </p> - </section> + <section id="app-assisted-individualization"> + <h4 id="x8-6-2-app-assisted-individualization"><span class="secno">8.6.2 </span>App-Assisted Individualization</h4> + <p>App-Assisted Individualization is performed between the <a href="#cdm">CDM</a> and the application, including an application-selected server, and results in a per-origin identifier. + The process <em class="rfc2119" title="MUST">MUST</em> be performed via the APIs defined in this specification and <em class="rfc2119" title="MUST NOT">MUST NOT</em> involve other methods of communication. + As with all other uses of the APIs, the process <em class="rfc2119" title="MAY">MAY</em> <a href="#uses-distinctive-identifiers">use one or more Distinctive Identifier(s)</a>, but it <em class="rfc2119" title="MUST NOT">MUST NOT</em> <a href="#uses-distinctive-permanent-identifiers">use Distinctive Permanent Identifier(s)</a> or non-origin-specific values, even in encrypted form. + If the process <a href="#uses-distinctive-identifiers">use one or more Distinctive Identifier(s)</a>, the resulting identifier is by definition also a <a href="#distinctive-identifier">Distinctive Identifier</a>. + </p> + <p>For such individualization, all message exchanges:</p> + <ul> + <li><p><em class="rfc2119" title="MUST">MUST</em> be passed to or through the application via the APIs defined in this specification.</p></li> + <li><p><em class="rfc2119" title="SHALL">SHALL</em> use the message type <code><a href="#idl-def-MediaKeyMessageType.individualization-request">"individualization-request"</a></code> for all related <code><a href="#dom-evt-message">message</a></code> events.</p></li> + <li><p><em class="rfc2119" title="MUST NOT">MUST NOT</em> be performed by the user agent.</p></li> + <li><p><em class="rfc2119" title="MUST NOT">MUST NOT</em> be performed directly by the CDM.</p></li> + <li><p><em class="rfc2119" title="MUST NOT">MUST NOT</em> contain or otherwise <a href="#uses-distinctive-permanent-identifiers">use Distinctive Permanent Identifier(s)</a>.</p></li> + <li><p><em class="rfc2119" title="MUST NOT">MUST NOT</em> contain non-origin-specific per-client information</p></li> + <li> + <p><em class="rfc2119" title="MUST">MUST</em> adhere to the <a href="#identifier-requirements">identifier requirements</a>.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-134" aria-level="5"><span>Note</span></div><p class="">This includes only using values that are <a href="#per-origin-per-profile-identifiers">unique per origin and profile</a> and <a href="#allow-identifiers-cleared">clearable</a> and <a href="#encrypt-identifiers">encrypting</a> them as required.</p></div> + </li> + <li><p><em class="rfc2119" title="MUST NOT">MUST NOT</em> provide executable code to the CDM.</p></li> + </ul> + <p> + When <a href="#associable">associable</a> values, including <a href="#distinctive-identifier">Distinctive Identifier(s)</a>, are <a href="#uses-distinctive-identifiers">used</a> in the process, + implementations <em class="rfc2119" title="MUST NOT">MUST NOT</em> expose, even in encrypted form, <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin(s)</a>-, origin- or application-specific information, or values that are <a href="#associable">associable</a> with origin(s) to centralized servers since this could create a central record of all origins visited by a user or device. + </p> + <p>With appropriate precautions, such individualization can provide better privacy than <a href="#direct-individualization">Direct Individualization</a>, though not as good as models that do not <a href="#uses-distinctive-identifiers">use Distinctive Identifier(s)</a>. + To preserve the benefits of such a design and to avoid introducing other privacy concerns, + such implementations and the applications that support them <em class="rfc2119" title="SHOULD">SHOULD</em> avoid deferring or forwarding individualization messages to a central server or other server not controlled by the application author. + </p> + </section> + </section> - <section id="interoperably-encrypted"> - <h4 id="x8.9.2-interoperably-encrypted"><span class="secno">8.9.2 </span>Interoperably Encrypted</h4> - <p> - <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-resource">Media resources</a>, including all tracks, <em class="rfc2119" title="MUST">MUST</em> be encrypted and packaged per a container-specific "common - encryption" specification that allows the content to be decrypted in a fully specified and compatible way when a key or keys are provided. - </p> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note140"><span>Note</span></div> - <p class=""> - The Encrypted Media Extensions Stream Format and Initialization Data Format Registry [<cite><a class="bibref" href="#bib-EME-STREAM-REGISTRY">EME-STREAM-REGISTRY</a></cite>] provides references to such stream formats. - </p> - </div> - </section> + <section id="support-multiple-keys"> + <h3 id="x8-7-support-multiple-keys"><span class="secno">8.7 </span>Support Multiple Keys</h3> + <p>Implementations <em class="rfc2119" title="MUST">MUST</em> support multiple keys in each <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> object.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-135" aria-level="4"><span>Note</span></div><p class="">The mechanics of how multiple keys are supported is an implementation detail, but it <em class="rfc2119" title="MUST">MUST</em> be transparent to the application and the APIs defined in this specification.</p></div> - <section id="unencrypted-in-band-support-content"> - <h4 id="x8.9.3-unencrypted-in-band-support-content"><span class="secno">8.9.3 </span>Unencrypted In-band Support Content</h4> - <p> - In-band support content, such as captions, described audio, and transcripts, <em class="rfc2119" title="SHOULD NOT">SHOULD NOT</em> be encrypted. - </p> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note141"><span>Note</span></div> - <p class=""> - Decryption of such tracks - especially such that they can be provided back the user agent - is not generally supported by implementations. Thus, encrypting such tracks would prevent them from being widely available for use with accessibility features - in user agent implementations. - </p> - </div> - <p> - To ensure accessibility information is available in usable form, for implementations that choose to support encrypted in-band support content: a) the CDM <em class="rfc2119" title="MUST">MUST</em> provide the decrypted data to the - user agent and b) the user agent <em class="rfc2119" title="MUST">MUST</em> process it in the same way as equivalent unencrypted support content. For example, to be exposed as <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#timed-text-tracks">timed text tracks</a></code> [<cite><a class="bibref" href="#bib-HTML51">HTML51</a></cite>]. - </p> - </section> + <p>Implementations <em class="rfc2119" title="MUST">MUST</em> support seamless switching between keys during playback. + This includes both keys in the same <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> and keys in separate <a href="#dom-mediakeysession" class="internalDFN" data-link-type="dfn"><code>MediaKeySession</code></a> objects. + </p> + </section> + + <section id="initialization-data-type-support-requirements"> + <h3 id="x8-8-initialization-data-type-support"><span class="secno">8.8 </span>Initialization Data Type Support</h3> + <section id="licenses-generated-are-independent-of-content-type"> + <h4 id="x8-8-1-licenses-generated-are-independent-of-content-type"><span class="secno">8.8.1 </span>Licenses Generated are Independent of Content Type</h4> + <p>Implementations <em class="rfc2119" title="SHOULD">SHOULD</em> allow licenses generated with any <a href="#initialization-data-type">Initialization Data Type</a> they support to be used with any content type.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-136" aria-level="5"><span>Note</span></div><p class="">Otherwise, the <code><a href="#dom-navigator-requestmediakeysystemaccess">requestMediaKeySystemAccess()</a></code> algorithm might, for example, reject a <a href="#dom-mediakeysystemconfiguration" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemConfiguration</code></a> because one of the <code><a href="#dom-mediakeysystemconfiguration-initdatatypes">initDataTypes</a></code> is not supported with one of the <code><a href="#dom-mediakeysystemconfiguration-videocapabilities">videoCapabilities</a></code>.</p></div> </section> - </section> + <section id="support-extraction-from-media-data"> + <h4 id="x8-8-2-support-extraction-from-media-data"><span class="secno">8.8.2 </span>Support Extraction From Media Data</h4> + <p>For any supported <a href="#initialization-data-type">Initialization Data Type</a> that may appear in a supported container, the user agents <em class="rfc2119" title="MUST">MUST</em> support <a href="#initdata-encountered">extracting</a> that type of <a href="#initialization-data">Initialization Data</a> from each such supported container.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-137" aria-level="5"><span>Note</span></div><p class="">In other words, indicating support for an <a href="#initialization-data-type">Initialization Data Type</a> implies both CDM support for generating license requests and, for container-specific types, user agent support for extracting it from the container. + This does <strong>not</strong> mean that implementations must be able to parse <em>any</em> supported <a href="#initialization-data">Initialization Data</a> from <em>any</em> supported content type. + </p></div> + </section> + </section> + + <section id="media-requirements"> + <h3 id="x8-9-supported-media"><span class="secno">8.9 </span>Supported Media</h3> + <p>This section defines properties of content (<a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-resource">media resource</a>) supported by implementations of this specification.</p> + + <section id="unencrypted-container"> + <h4 id="x8-9-1-unencrypted-container"><span class="secno">8.9.1 </span>Unencrypted Container</h4> + <p> + The media container <em class="rfc2119" title="MUST NOT">MUST NOT</em> be encrypted. + This specification relies on the user agent's ability to parse the media container without having to decrypt any of the media data. + This includes the <a href="#encrypted-block-encountered">Encrypted Block Encountered</a> and <a href="#initdata-encountered">Initialization Data Encountered</a> algorithms as well as supporting standard <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#htmlmediaelement-htmlmediaelement">HTMLMediaElement</a></code> [<cite><a class="bibref" href="#bib-HTML51">HTML51</a></cite>] functionality, such as <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#seeking">seeking</a>. + </p> + </section> - <section id="common-key-systems"> - <!--OddPage--> - <h2 id="x9.-common-key-systems"><span class="secno">9. </span>Common Key Systems</h2> - <p>All user agents <em class="rfc2119" title="MUST">MUST</em> support the common key systems described in this section.</p> - <div class="note"> - <div class="note-title marker" aria-level="3" role="heading" id="h-note142"><span>Note</span></div> - <p class="">This ensures that there is a common baseline level of functionality that is guaranteed to be supported in all user agents, including those that are entirely open source. Thus, content providers that need only basic decryption can build simple - applications that will work on all platforms without needing to work with any content protection providers. - </p> - </div> + <section id="interoperably-encrypted"> + <h4 id="x8-9-2-interoperably-encrypted"><span class="secno">8.9.2 </span>Interoperably Encrypted</h4> + <p> + <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-resource">Media resources</a>, including all tracks, <em class="rfc2119" title="MUST">MUST</em> be encrypted and packaged per a container-specific "common encryption" specification that allows the content to be decrypted in a fully specified and compatible way when a key or keys are provided. + </p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-138" aria-level="5"><span>Note</span></div><p class=""> + The Encrypted Media Extensions Stream Format and Initialization Data Format Registry [<cite><a class="bibref" href="#bib-EME-STREAM-REGISTRY">EME-STREAM-REGISTRY</a></cite>] provides references to such stream formats. + </p></div> + </section> - <section id="clear-key"> - <h3 id="x9.1-clear-key"><span class="secno">9.1 </span>Clear Key</h3> - <p>The <code>"org.w3.clearkey"</code> <a href="#key-system">Key System</a> uses plain-text clear (unencrypted) key(s) to decrypt the source. No additional client-side content protection is required. This Key System is described below. - </p> + <section id="unencrypted-in-band-support-content"> + <h4 id="x8-9-3-unencrypted-in-band-support-content"><span class="secno">8.9.3 </span>Unencrypted In-band Support Content</h4> + <p> + In-band support content, such as captions, described audio, and transcripts, <em class="rfc2119" title="SHOULD NOT">SHOULD NOT</em> be encrypted. + </p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-139" aria-level="5"><span>Note</span></div><p class=""> + Decryption of such tracks - especially such that they can be provided back the user agent - is not generally supported by implementations. + Thus, encrypting such tracks would prevent them from being widely available for use with accessibility features in user agent implementations. + </p></div> + <p> + To ensure accessibility information is available in usable form, for implementations that choose to support encrypted in-band support content: a) the CDM <em class="rfc2119" title="MUST">MUST</em> provide the decrypted data to the user agent and + b) the user agent <em class="rfc2119" title="MUST">MUST</em> process it in the same way as equivalent unencrypted support content. For example, to be exposed as <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#timed-text-tracks">timed text tracks</a></code> [<cite><a class="bibref" href="#bib-HTML51">HTML51</a></cite>]. + </p> + </section> + </section> - <section id="clear-key-capabilities"> - <h4 id="x9.1.1-capabilities"><span class="secno">9.1.1 </span>Capabilities</h4> - <p>The following describe how Clear Key supports key system-specific capabilities:</p> - <ul> - <li> - <p><a href="#dom-mediakeysystemconfiguration" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemConfiguration</code></a>:</p> - <ol> - <li> - <p><code><a href="#dom-mediakeysystemmediacapability-robustness">robustness</a></code>: Only the empty string is supported.</p> - </li> - <li> - <p><code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code>: <code><a href="#idl-def-MediaKeysRequirement.required">"required"</a></code> is not supported.</p> - </li> - <li> - <p><code><a href="#dom-mediakeysystemconfiguration-persistentstate">persistentState</a></code>: Not <code><a href="#idl-def-MediaKeysRequirement.required">"required"</a></code> unless the application intends to create non-<code><a href="#idl-def-MediaKeySessionType.temporary">"temporary"</a></code> sessions, if supported.</p> - </li> - </ol> - </li> - <li> - <p>The <code><a href="#idl-def-MediaKeySessionType.persistent-license">"persistent-license"</a></code> <a href="#dom-mediakeysessiontype" class="internalDFN" data-link-type="dfn"><code>MediaKeySessionType</code></a>: Implementations - <em class="rfc2119" title="MAY">MAY</em> support this type.</p> - </li> - <li> - <p>The <code><a href="#idl-def-MediaKeySessionType.persistent-usage-record">"persistent-usage-record"</a></code> <a href="#dom-mediakeysessiontype" class="internalDFN" data-link-type="dfn"><code>MediaKeySessionType</code></a>: Implementations - <em class="rfc2119" title="MAY">MAY</em> support this type.</p> - </li> + </section> - <li> - <p>The <code><a href="#dom-mediakeys-setservercertificate">setServerCertificate()</a></code> method: Not supported.</p> - </li> - <li> - <p>The <code><a href="#dom-htmlmediaelement-setmediakeys">setMediaKeys()</a></code> method: Implementations <em class="rfc2119" title="MAY">MAY</em> support associating the <a href="#dom-mediakeys" class="internalDFN" data-link-type="dfn"><code>MediaKeys</code></a> object with more than one <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#htmlmediaelement-htmlmediaelement">HTMLMediaElement</a></code>.</p> - </li> - </ul> - </section> + <section id="common-key-systems"> + <!--OddPage--><h2 id="x9-common-key-systems"><span class="secno">9. </span>Common Key Systems</h2> + <p>All user agents <em class="rfc2119" title="MUST">MUST</em> support the common key systems described in this section.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-140" aria-level="3"><span>Note</span></div><p class="">This ensures that there is a common baseline level of functionality that is guaranteed to be supported in all user agents, including those that are entirely open source. + Thus, content providers that need only basic decryption can build simple applications that will work on all platforms without needing to work with any content protection providers. + </p></div> + + <section id="clear-key"> + <h3 id="x9-1-clear-key"><span class="secno">9.1 </span>Clear Key</h3> + <p>The <code>"org.w3.clearkey"</code> <a href="#key-system">Key System</a> uses plain-text clear (unencrypted) key(s) to decrypt the source. + No additional client-side content protection is required. + This Key System is described below. + </p> - <section id="clear-key-behavior"> - <h4 id="x9.1.2-behavior"><span class="secno">9.1.2 </span>Behavior</h4> - <p>The following describe how Clear Key implements key system-specific behaviors:</p> - <ul> - <li> - <p>In the <code><a href="#dom-mediakeysession-generaterequest">generateRequest()</a></code> algorithm:</p> - <ul> - <li> - <p>The generated <var>message</var> is a JSON object encoded in UTF-8 as described in <a href="#clear-key-request-format">License Request Format</a>.</p> - </li> - <li> - <p>The request is generated by extracting the key IDs from the <var>sanitized init data</var>.</p> - </li> - <li> - <p>The "type" member value is the value of the <var>sessionType</var> parameter.</p> - </li> - </ul> - </li> - <li> - <p>The <code><a href="#dom-mediakeysession-sessionid">sessionId</a></code> attribute is a numerical value representable by a 32-bit integer.</p> - </li> - <li> - <p>The <code><a href="#dom-mediakeysession-expiration">expiration</a></code> attribute is always <code>NaN</code>.</p> - </li> - <li> - <p>In the <code><a href="#dom-mediakeysession-update">update()</a></code> algorithm:</p> - <ul> - <li> - <p> - The <var>response</var> parameter is either a JWK Set as described in <a href="#clear-key-license-format">License Format</a>, or a JSON object encoded in UTF-8 as described in <a href="#clear-key-release-ack-format">License Release Acknowledgement Format</a>. - </p> - </li> - <li> - <p> - In the first case, <var>sanitized response</var> is considered invalid if it is not a valid JWK Set with at least one valid JWK key of a valid length for the audio/video type. In the second case <var>sanitized response</var> is considered invalid if it is not a valid JSON object. - </p> - </li> - </ul> - </li> - <li> - <p> - For sessions of type <code><a href="#idl-def-MediaKeySessionType.persistent-license">"persistent-license"</a></code>, in the <code><a href="#dom-mediakeysession-remove">remove()</a></code> algorithm, the <var>message</var> reflecting the <var>record of license destruction</var> is a JSON object encoded in UTF-8 as described in <a href="#clear-key-release-format">License Release Format</a>. - </p> - </li> - <li> - <p> - For sessions of type <code><a href="#idl-def-MediaKeySessionType.persistent-usage-record">"persistent-usage-record"</a></code>, in the <code><a href="#dom-mediakeysession-remove">remove()</a></code> and <code><a href="#dom-mediakeysession-load">load()</a></code> algorithms, the <var>message</var> reflecting the object's <var>record of key usage</var> is a JSON object encoded in UTF-8 as described in <a href="#clear-key-release-format">License Release Format</a>. - </p> - </li> - <li> - <p> - The <code><a href="#dom-mediakeysession-keystatuses">keyStatuses</a></code> attribute method initially contains all key IDs that have been provided via <code><a href="#dom-mediakeysession-update">update()</a></code>, with status - <code><a href="#idl-def-MediaKeyStatus.usable">"usable"</a></code>. When the <code><a href="#dom-mediakeysession-remove">remove()</a></code> algorithm is executed, the <code><a href="#dom-mediakeysession-keystatuses">keyStatuses</a></code> attribute will be set to an empty list. - </p> - </li> - <li> - <p> - <a href="#initialization-data">Initialization Data</a>: Implementations <em class="rfc2119" title="MAY">MAY</em> support any combination of registered Initialization Data Types [<cite><a class="bibref" href="#bib-EME-INITDATA-REGISTRY">EME-INITDATA-REGISTRY</a></cite>]. - Implementations <em class="rfc2119" title="SHOULD">SHOULD</em> support the <code>"keyids"</code> type [<cite><a class="bibref" href="#bib-EME-INITDATA-KEYIDS">EME-INITDATA-KEYIDS</a></cite>] and other types appropriate for - content types supported by the user agent. - </p> - </li> - </ul> - </section> - - <section id="clear-key-request-format"> - <h4 id="x9.1.3-license-request-format"><span class="secno">9.1.3 </span>License Request Format</h4> - <p>This section describes the format of the license request provided to the application via the <code><a href="#dom-mediakeymessageevent-message">message</a></code> attribute of the <code><a href="#dom-evt-message">message</a></code> event.</p> - - <p>The format is a JSON object containing the following members:</p> - <dl> - <dt>"kids"</dt> - <dd>An array of <a href="#decryption-key-id">key IDs</a>. Each element of the array is the base64url encoding of the octet sequence containing the key ID value.</dd> - <dt>"type"</dt> - <dd>The requested <a href="#dom-mediakeysessiontype" class="internalDFN" data-link-type="dfn"><code>MediaKeySessionType</code></a></dd> - </dl> + <section id="clear-key-capabilities"> + <h4 id="x9-1-1-capabilities"><span class="secno">9.1.1 </span>Capabilities</h4> + <p>The following describe how Clear Key supports key system-specific capabilities:</p> + <ul> + <li> + <p><a href="#dom-mediakeysystemconfiguration" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemConfiguration</code></a>:</p> + <ol> + <li><p><code><a href="#dom-mediakeysystemmediacapability-robustness">robustness</a></code>: Only the empty string is supported.</p></li> + <li><p><code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code>: <code><a href="#idl-def-MediaKeysRequirement.required">"required"</a></code> is not supported.</p></li> + <li><p><code><a href="#dom-mediakeysystemconfiguration-persistentstate">persistentState</a></code>: Not <code><a href="#idl-def-MediaKeysRequirement.required">"required"</a></code> unless the application intends to create non-<code><a href="#idl-def-MediaKeySessionType.temporary">"temporary"</a></code> sessions, if supported.</p></li> + </ol> + </li> + <li><p>The <code><a href="#idl-def-MediaKeySessionType.persistent-license">"persistent-license"</a></code> <a href="#dom-mediakeysessiontype" class="internalDFN" data-link-type="dfn"><code>MediaKeySessionType</code></a>: Implementations <em class="rfc2119" title="MAY">MAY</em> support this type.</p></li> + <li><p>The <code><a href="#idl-def-MediaKeySessionType.persistent-usage-record">"persistent-usage-record"</a></code> <a href="#dom-mediakeysessiontype" class="internalDFN" data-link-type="dfn"><code>MediaKeySessionType</code></a>: Implementations <em class="rfc2119" title="MAY">MAY</em> support this type.</p></li> + + <li><p>The <code><a href="#dom-mediakeys-setservercertificate">setServerCertificate()</a></code> method: Not supported.</p></li> + <li><p>The <code><a href="#dom-htmlmediaelement-setmediakeys">setMediaKeys()</a></code> method: Implementations <em class="rfc2119" title="MAY">MAY</em> support associating the <a href="#dfn-mediakeys" class="internalDFN" data-link-type="dfn">MediaKeys</a> object with more than one <code><a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#htmlmediaelement-htmlmediaelement">HTMLMediaElement</a></code>.</p></li> + </ul> + </section> - <p>When contained in the ArrayBuffer <code><a href="#dom-mediakeymessageevent-message">message</a></code> attribute of a <a href="#dom-mediakeymessageevent" class="internalDFN" data-link-type="dfn"><code>MediaKeyMessageEvent</code></a> object, - the JSON string is encoded in UTF-8 as specified in the Encoding specification [<cite><a class="bibref" href="#bib-ENCODING">ENCODING</a></cite>]. Applications <em class="rfc2119" title="MAY">MAY</em> decode the contents of the ArrayBuffer - to a JSON string using the <a href="https://www.w3.org/TR/encoding/#interface-textdecoder">TextDecoder interface</a> [<cite><a class="bibref" href="#bib-ENCODING">ENCODING</a></cite>]. - </p> + <section id="clear-key-behavior"> + <h4 id="x9-1-2-behavior"><span class="secno">9.1.2 </span>Behavior</h4> + <p>The following describe how Clear Key implements key system-specific behaviors:</p> + <ul> + <li><p>In the <code><a href="#dom-mediakeysession-generaterequest">generateRequest()</a></code> algorithm:</p> + <ul> + <li><p>The generated <var>message</var> is a JSON object encoded in UTF-8 as described in <a href="#clear-key-request-format">License Request Format</a>.</p></li> + <li><p>The request is generated by extracting the key IDs from the <var>sanitized init data</var>.</p></li> + <li><p>The "type" member value is the value of the <var>sessionType</var> parameter.</p></li> + </ul> + </li> + <li><p>The <code><a href="#dom-mediakeysession-sessionid">sessionId</a></code> attribute is a numerical value representable by a 32-bit integer.</p></li> + <li><p>The <code><a href="#dom-mediakeysession-expiration">expiration</a></code> attribute is always <code>NaN</code>.</p></li> + <li><p>In the <code><a href="#dom-mediakeysession-update">update()</a></code> algorithm:</p> + <ul> + <li> + <p> + The <var>response</var> parameter is either a JWK Set as described in <a href="#clear-key-license-format">License Format</a>, + or a JSON object encoded in UTF-8 as described in <a href="#clear-key-release-ack-format">License Release Acknowledgement Format</a>. + </p> + </li> + <li> + <p> + In the first case, <var>sanitized response</var> is considered invalid if it is not a valid JWK Set with at least one valid JWK key of a valid length for the audio/video type. + In the second case <var>sanitized response</var> is considered invalid if it is not a valid JSON object. + </p> + </li> + </ul> + </li> + <li> + <p> + For sessions of type <code><a href="#idl-def-MediaKeySessionType.persistent-license">"persistent-license"</a></code>, in the <code><a href="#dom-mediakeysession-remove">remove()</a></code> algorithm, the <var>message</var> reflecting + the <var>record of license destruction</var> is a JSON object encoded in UTF-8 as described in <a href="#clear-key-release-format">License Release Format</a>. + </p> + </li> + <li> + <p> + For sessions of type <code><a href="#idl-def-MediaKeySessionType.persistent-usage-record">"persistent-usage-record"</a></code>, in the <code><a href="#dom-mediakeysession-remove">remove()</a></code> and <code><a href="#dom-mediakeysession-load">load()</a></code> algorithms, the <var>message</var> reflecting + the object's <var>record of key usage</var> is a JSON object encoded in UTF-8 as described in <a href="#clear-key-release-format">License Release Format</a>. + </p> + </li> + <li> + <p> + The <code><a href="#dom-mediakeysession-keystatuses">keyStatuses</a></code> attribute method initially contains all key IDs that have been provided via <code><a href="#dom-mediakeysession-update">update()</a></code>, with status <code><a href="#idl-def-MediaKeyStatus.usable">"usable"</a></code>. + When the <code><a href="#dom-mediakeysession-remove">remove()</a></code> algorithm is executed, the <code><a href="#dom-mediakeysession-keystatuses">keyStatuses</a></code> attribute will be set to an empty list. + </p> + </li> + <li> + <p> + <a href="#initialization-data">Initialization Data</a>: Implementations <em class="rfc2119" title="MAY">MAY</em> support any combination of registered Initialization Data Types [<cite><a class="bibref" href="#bib-EME-INITDATA-REGISTRY">EME-INITDATA-REGISTRY</a></cite>]. + Implementations <em class="rfc2119" title="SHOULD">SHOULD</em> support the <code>"keyids"</code> type [<cite><a class="bibref" href="#bib-EME-INITDATA-KEYIDS">EME-INITDATA-KEYIDS</a></cite>] and other types appropriate for content types supported by the user agent. + </p> + </li> + </ul> + </section> - <section id="clear-key-request-format-example" class="informative"> - <h5 id="x9.1.3.1-example"><span class="secno">9.1.3.1 </span>Example</h5> - <p><em>This section is non-normative.</em></p> - <p>The following example is a license request for a temporary license for two key IDs. (Line breaks are for readability only.)</p> - <div class="example"> - <div class="example-title marker"><span>Example 1</span></div> - <pre class="highlight hljs json" aria-busy="false" aria-live="polite">{ + <section id="clear-key-request-format"> + <h4 id="x9-1-3-license-request-format"><span class="secno">9.1.3 </span>License Request Format</h4> + <p>This section describes the format of the license request provided to the application via the <code><a href="#dom-mediakeymessageevent-message">message</a></code> attribute of the <code><a href="#dom-evt-message">message</a></code> event.</p> + + <p>The format is a JSON object containing the following members:</p> + <dl> + <dt>"kids"</dt> + <dd>An array of <a href="#decryption-key-id">key IDs</a>. Each element of the array is the base64url encoding of the octet sequence containing the key ID value.</dd> + <dt>"type"</dt> + <dd>The requested <a href="#dom-mediakeysessiontype" class="internalDFN" data-link-type="dfn"><code>MediaKeySessionType</code></a></dd> + </dl> + + <p>When contained in the ArrayBuffer <code><a href="#dom-mediakeymessageevent-message">message</a></code> attribute of a <a href="#dom-mediakeymessageevent" class="internalDFN" data-link-type="dfn"><code>MediaKeyMessageEvent</code></a> object, the JSON string is encoded in UTF-8 as specified in the Encoding specification [<cite><a class="bibref" href="#bib-ENCODING">ENCODING</a></cite>]. + Applications <em class="rfc2119" title="MAY">MAY</em> decode the contents of the ArrayBuffer to a JSON string using the <a href="https://www.w3.org/TR/encoding/#interface-textdecoder">TextDecoder interface</a> [<cite><a class="bibref" href="#bib-ENCODING">ENCODING</a></cite>]. + </p> + + <section id="clear-key-request-format-example" class="informative"> + <h5 id="x9-1-3-1-example"><span class="secno">9.1.3.1 </span>Example</h5><p><em>This section is non-normative.</em></p> + <p>The following example is a license request for a temporary license for two key IDs. (Line breaks are for readability only.)</p> + <div class="example"><div class="example-title marker"><span>Example 1</span></div><pre class="highlight hljs json" aria-busy="false" aria-live="polite">{ <span class="hljs-attr">"kids"</span>: [ <span class="hljs-string">"LwVHf8JLtPrv2GUXFW2v_A"</span>, <span class="hljs-string">"0DdtU9od-Bh5L3xbv0Xf_A"</span> ], <span class="hljs-attr">"type"</span>:<span class="hljs-string">"temporary"</span> -}</pre> - </div> - </section> - </section> - - <section id="clear-key-license-format"> - <h4 id="x9.1.4-license-format"><span class="secno">9.1.4 </span>License Format</h4> - <p>This section describes the format of the license to be provided via the <var>response</var> parameter of the <code><a href="#dom-mediakeysession-update">update()</a></code> method.</p> - - <p>The format is a JSON Web Key (JWK) Set containing representation of the symmetric key to be used for decryption, as defined in the JSON Web Key (JWK) specification [<cite><a class="bibref" href="#bib-RFC7517">RFC7517</a></cite>].</p> - - <p>For each JWK in the set, the parameter values are as follows:</p> - <dl> - <dt>"kty" (key type)</dt> - <dd>"oct" (octet sequence)</dd> - <dt>"k" (key value)</dt> - <dd>The base64url encoding of the octet sequence containing the symmetric <a href="#decryption-key">key</a> value</dd> - <dt>"kid" (key ID)</dt> - <dd>The base64url encoding of the octet sequence containing the <a href="#decryption-key-id">key ID</a> value</dd> - </dl> - - <p>The JSON object <em class="rfc2119" title="MAY">MAY</em> have an optional "type" member value, which <em class="rfc2119" title="MUST">MUST</em> be one of the <a href="#dom-mediakeysessiontype" class="internalDFN" data-link-type="dfn"><code>MediaKeySessionType</code></a> values. If not specified, the default value of <code><a href="#idl-def-MediaKeySessionType.temporary">"temporary"</a></code> is used. The <code><a href="#dom-mediakeysession-update">update()</a></code> algorithm compares this value - to the <var>sessionType</var>. - </p> - - <p>When passed to the <code><a href="#dom-mediakeysession-update">update()</a></code> method as the ArrayBuffer <var>response</var> parameter, the JSON string <em class="rfc2119" title="MUST">MUST</em> be encoded in UTF-8 as specified in - the Encoding specification [<cite><a class="bibref" href="#bib-ENCODING">ENCODING</a></cite>]. Applications <em class="rfc2119" title="MAY">MAY</em> encode the JSON string using the <a href="https://www.w3.org/TR/encoding/#interface-textencoder">TextEncoder interface</a> [<cite><a class="bibref" href="#bib-ENCODING">ENCODING</a></cite>]. - </p> - - <section id="clear-key-license-format-example" class="informative"> - <h5 id="x9.1.4.1-example"><span class="secno">9.1.4.1 </span>Example</h5> - <p><em>This section is non-normative.</em></p> - <p>The following example is a JWK Set containing a single symmetric key. (Line breaks are for readability only.)</p> - <div class="example"> - <div class="example-title marker"><span>Example 2</span></div> - <pre class="highlight hljs javascript" aria-busy="false" aria-live="polite">{ - <span class="hljs-string">"keys"</span>: - [{ - <span class="hljs-string">"kty"</span>:<span class="hljs-string">"oct"</span>, - <span class="hljs-string">"k"</span>:<span class="hljs-string">"tQ0bJVWb6b0KPL6KtZIy_A"</span>, - <span class="hljs-string">"kid"</span>:<span class="hljs-string">"LwVHf8JLtPrv2GUXFW2v_A"</span> - }], - <span class="hljs-string">'type'</span>:<span class="hljs-string">"temporary"</span> -}</pre> - </div> - </section> - </section> - - <section id="clear-key-release-format"> - - <h4 id="x9.1.5-license-release-format"><span class="secno">9.1.5 </span>License Release Format</h4> - <p>This section describes the format of the license release message to be provided via the <code><a href="#dom-mediakeymessageevent-message">message</a></code> attribute of the <code><a href="#dom-evt-message">message</a></code> event.</p> - <p> - The format is a JSON object. For sessions of type <code><a href="#idl-def-MediaKeySessionType.persistent-license">"persistent-license"</a></code> and <code><a href="#idl-def-MediaKeySessionType.persistent-usage-record">"persistent-usage-record"</a></code>, - the object shall contain the following member: - </p> - <dl> - <dt>"kids"</dt> - <dd>An array of <a href="#decryption-key-id">key IDs</a>. Each element of the array is the base64url encoding of the octet sequence containing the key ID value.</dd> - </dl> - <p> - For sessions of type <code><a href="#idl-def-MediaKeySessionType.persistent-usage-record">"persistent-usage-record"</a></code> the object shall also contain the following members: - </p> - <dl> - <dt>"firstTime"</dt> - <dd>The <a href="#first-decryption-time">first decryption time</a> expressed as a number giving the time, in milliseconds since 01 January, 1970 UTC.</dd> - <dt>"latestTime"</dt> - <dd>The <a href="#latest-decryption-time">latest decryption time</a> expressed as a number giving the time, in milliseconds since 01 January, 1970 UTC.</dd> - </dl> +}</pre></div> + </section> + </section> - <p>When contained in the ArrayBuffer <code><a href="#dom-mediakeymessageevent-message">message</a></code> attribute of a <a href="#dom-mediakeymessageevent" class="internalDFN" data-link-type="dfn"><code>MediaKeyMessageEvent</code></a> object, - the JSON string is encoded in UTF-8 as specified in the Encoding specification [<cite><a class="bibref" href="#bib-ENCODING">ENCODING</a></cite>]. Applications <em class="rfc2119" title="MAY">MAY</em> decode the contents of the ArrayBuffer - to a JSON string using the <a href="https://www.w3.org/TR/encoding/#interface-textdecoder">TextDecoder interface</a> [<cite><a class="bibref" href="#bib-ENCODING">ENCODING</a></cite>]. - </p> + <section id="clear-key-license-format"> + <h4 id="x9-1-4-license-format"><span class="secno">9.1.4 </span>License Format</h4> + <p>This section describes the format of the license to be provided via the <var>response</var> parameter of the <code><a href="#dom-mediakeysession-update">update()</a></code> method.</p> + + <p>The format is a JSON Web Key (JWK) Set containing representation of the symmetric key to be used for decryption, as defined in the JSON Web Key (JWK) specification [<cite><a class="bibref" href="#bib-RFC7517">RFC7517</a></cite>].</p> + + <p>For each JWK in the set, the parameter values are as follows:</p> + <dl> + <dt>"kty" (key type)</dt> + <dd>"oct" (octet sequence)</dd> + <dt>"k" (key value)</dt> + <dd>The base64url encoding of the octet sequence containing the symmetric <a href="#decryption-key">key</a> value</dd> + <dt>"kid" (key ID)</dt> + <dd>The base64url encoding of the octet sequence containing the <a href="#decryption-key-id">key ID</a> value</dd> + </dl> + + <p>The JSON object <em class="rfc2119" title="MAY">MAY</em> have an optional "type" member value, which <em class="rfc2119" title="MUST">MUST</em> be one of the <a href="#dom-mediakeysessiontype" class="internalDFN" data-link-type="dfn"><code>MediaKeySessionType</code></a> values. + If not specified, the default value of <code><a href="#idl-def-MediaKeySessionType.temporary">"temporary"</a></code> is used. + The <code><a href="#dom-mediakeysession-update">update()</a></code> algorithm compares this value to the <var>sessionType</var>. + </p> + + <p>When passed to the <code><a href="#dom-mediakeysession-update">update()</a></code> method as the ArrayBuffer <var>response</var> parameter, the JSON string <em class="rfc2119" title="MUST">MUST</em> be encoded in UTF-8 as specified in the Encoding specification [<cite><a class="bibref" href="#bib-ENCODING">ENCODING</a></cite>]. + Applications <em class="rfc2119" title="MAY">MAY</em> encode the JSON string using the <a href="https://www.w3.org/TR/encoding/#interface-textencoder">TextEncoder interface</a> [<cite><a class="bibref" href="#bib-ENCODING">ENCODING</a></cite>]. + </p> + + <section id="clear-key-license-format-example" class="informative"> + <h5 id="x9-1-4-1-example"><span class="secno">9.1.4.1 </span>Example</h5><p><em>This section is non-normative.</em></p> + <p>The following example is a JWK Set containing a single symmetric key. (Line breaks are for readability only.)</p> + <div class="example"><div class="example-title marker"><span>Example 2</span></div><pre class="highlight hljs javascript" aria-busy="false" aria-live="polite">{ + <span class="hljs-string">"keys"</span>: + [{ + <span class="hljs-string">"kty"</span>:<span class="hljs-string">"oct"</span>, + <span class="hljs-string">"k"</span>:<span class="hljs-string">"tQ0bJVWb6b0KPL6KtZIy_A"</span>, + <span class="hljs-string">"kid"</span>:<span class="hljs-string">"LwVHf8JLtPrv2GUXFW2v_A"</span> + }], + <span class="hljs-string">'type'</span>:<span class="hljs-string">"temporary"</span> +}</pre></div> + </section> + </section> - <section id="clear-key-release-format-example-1" class="informative"> - <h5 id="x9.1.5.1-example-message-reflecting-a"><span class="secno">9.1.5.1 </span>Example message reflecting a <a href="#record-of-license-destruction">record of license destruction</a></h5> - <p><em>This section is non-normative.</em></p> - <p> - The following example is a license release for a <code><a href="#idl-def-MediaKeySessionType.persistent-license">"persistent-license"</a></code> session that contained two keys. (Line breaks are for readability only.) - </p> - <div class="example"> - <div class="example-title marker"><span>Example 3</span></div> - <pre class="highlight hljs json" aria-busy="false" aria-live="polite">{ + <section id="clear-key-release-format"> + + <h4 id="x9-1-5-license-release-format"><span class="secno">9.1.5 </span>License Release Format</h4> + <p>This section describes the format of the license release message to be provided via the <code><a href="#dom-mediakeymessageevent-message">message</a></code> attribute of the <code><a href="#dom-evt-message">message</a></code> event.</p> + <p> + The format is a JSON object. For sessions of type <code><a href="#idl-def-MediaKeySessionType.persistent-license">"persistent-license"</a></code> and <code><a href="#idl-def-MediaKeySessionType.persistent-usage-record">"persistent-usage-record"</a></code>, + the object shall contain the following member: + </p> + <dl> + <dt>"kids"</dt> + <dd>An array of <a href="#decryption-key-id">key IDs</a>. Each element of the array is the base64url encoding of the octet sequence containing the key ID value.</dd> + </dl> + <p> + For sessions of type <code><a href="#idl-def-MediaKeySessionType.persistent-usage-record">"persistent-usage-record"</a></code> the object shall also contain the following members: + </p> + <dl> + <dt>"firstTime"</dt> + <dd>The <a href="#first-decryption-time">first decryption time</a> expressed as a number giving the time, in milliseconds since 01 January, 1970 UTC.</dd> + <dt>"latestTime"</dt> + <dd>The <a href="#latest-decryption-time">latest decryption time</a> expressed as a number giving the time, in milliseconds since 01 January, 1970 UTC.</dd> + </dl> + + <p>When contained in the ArrayBuffer <code><a href="#dom-mediakeymessageevent-message">message</a></code> attribute of a <a href="#dom-mediakeymessageevent" class="internalDFN" data-link-type="dfn"><code>MediaKeyMessageEvent</code></a> object, the JSON string is encoded in UTF-8 as specified in the Encoding specification [<cite><a class="bibref" href="#bib-ENCODING">ENCODING</a></cite>]. + Applications <em class="rfc2119" title="MAY">MAY</em> decode the contents of the ArrayBuffer to a JSON string using the <a href="https://www.w3.org/TR/encoding/#interface-textdecoder">TextDecoder interface</a> [<cite><a class="bibref" href="#bib-ENCODING">ENCODING</a></cite>]. + </p> + + <section id="clear-key-release-format-example-1" class="informative"> + <h5 id="x9-1-5-1-example-message-reflecting-a"><span class="secno">9.1.5.1 </span>Example message reflecting a <a href="#record-of-license-destruction">record of license destruction</a></h5><p><em>This section is non-normative.</em></p> + <p> + The following example is a license release for a <code><a href="#idl-def-MediaKeySessionType.persistent-license">"persistent-license"</a></code> session that contained two keys. + (Line breaks are for readability only.) + </p> + <div class="example"><div class="example-title marker"><span>Example 3</span></div><pre class="highlight hljs json" aria-busy="false" aria-live="polite">{ <span class="hljs-attr">"kids"</span>: [ <span class="hljs-string">"LwVHf8JLtPrv2GUXFW2v_A"</span>, <span class="hljs-string">"0DdtU9od-Bh5L3xbv0Xf_A"</span> ] -}</pre> - </div> - </section> +}</pre></div> + </section> - <section id="clear-key-release-format-example-2" class="informative"> - <h5 id="x9.1.5.2-example-message-reflecting-a"><span class="secno">9.1.5.2 </span>Example message reflecting a <a href="#record-of-key-usage">record of key usage</a></h5> - <p><em>This section is non-normative.</em></p> - <p> - The following example is a license release for a <code><a href="#idl-def-MediaKeySessionType.persistent-usage-record">"persistent-usage-record"</a></code> session that contained two keys. (Line breaks are for readability only.) - </p> - <div class="example"> - <div class="example-title marker"><span>Example 4</span></div> - <pre class="highlight hljs json" aria-busy="false" aria-live="polite">{ + <section id="clear-key-release-format-example-2" class="informative"> + <h5 id="x9-1-5-2-example-message-reflecting-a"><span class="secno">9.1.5.2 </span>Example message reflecting a <a href="#record-of-key-usage">record of key usage</a></h5><p><em>This section is non-normative.</em></p> + <p> + The following example is a license release for a <code><a href="#idl-def-MediaKeySessionType.persistent-usage-record">"persistent-usage-record"</a></code> session that contained two keys. + (Line breaks are for readability only.) + </p> + <div class="example"><div class="example-title marker"><span>Example 4</span></div><pre class="highlight hljs json" aria-busy="false" aria-live="polite">{ <span class="hljs-attr">"kids"</span>: [ <span class="hljs-string">"LwVHf8JLtPrv2GUXFW2v_A"</span>, <span class="hljs-string">"0DdtU9od-Bh5L3xbv0Xf_A"</span> ], <span class="hljs-attr">"firstTime"</span> : <span class="hljs-number">1430425323757</span>, <span class="hljs-attr">"latestTime"</span> : <span class="hljs-number">1430425383757</span> -}</pre> - </div> - </section> - </section> - - <section id="clear-key-release-ack-format"> - <h4 id="x9.1.6-license-release-acknowledgement-format"><span class="secno">9.1.6 </span>License Release Acknowledgement Format</h4> - <p>This section describes the format of the license release acknowledgement provided via the <var>response</var> parameter of the <code><a href="#dom-mediakeysession-update">update()</a></code> method.</p> - - <p>The format is a JSON object containing the following members:</p> - <dl> - <dt>"kids"</dt> - <dd>An array of <a href="#decryption-key-id">key IDs</a>. Each element of the array is the base64url encoding of the octet sequence containing the key ID value.</dd> - </dl> +}</pre></div> + </section> + </section> - <p>When passed to the <code><a href="#dom-mediakeysession-update">update()</a></code> method as the ArrayBuffer <var>response</var> parameter, the JSON string <em class="rfc2119" title="MUST">MUST</em> be encoded in UTF-8 as specified in - the Encoding specification [<cite><a class="bibref" href="#bib-ENCODING">ENCODING</a></cite>]. Applications <em class="rfc2119" title="MAY">MAY</em> encode the JSON string using the <a href="https://www.w3.org/TR/encoding/#interface-textencoder">TextEncoder interface</a> [<cite><a class="bibref" href="#bib-ENCODING">ENCODING</a></cite>]. - </p> + <section id="clear-key-release-ack-format"> + <h4 id="x9-1-6-license-release-acknowledgement-format"><span class="secno">9.1.6 </span>License Release Acknowledgement Format</h4> + <p>This section describes the format of the license release acknowledgement provided via the <var>response</var> parameter of the <code><a href="#dom-mediakeysession-update">update()</a></code> method.</p> + + <p>The format is a JSON object containing the following members:</p> + <dl> + <dt>"kids"</dt> + <dd>An array of <a href="#decryption-key-id">key IDs</a>. Each element of the array is the base64url encoding of the octet sequence containing the key ID value.</dd> + </dl> - <section id="clear-key-release-ack-format-example" class="informative"> - <h5 id="x9.1.6.1-example"><span class="secno">9.1.6.1 </span>Example</h5> - <p><em>This section is non-normative.</em></p> - <p>The following example is a license request for a temporary license for two key IDs. (Line breaks are for readability only.)</p> - <div class="example"> - <div class="example-title marker"><span>Example 5</span></div> - <pre class="highlight hljs json" aria-busy="false" aria-live="polite">{ + <p>When passed to the <code><a href="#dom-mediakeysession-update">update()</a></code> method as the ArrayBuffer <var>response</var> parameter, the JSON string <em class="rfc2119" title="MUST">MUST</em> be encoded in UTF-8 as specified in the Encoding specification [<cite><a class="bibref" href="#bib-ENCODING">ENCODING</a></cite>]. + Applications <em class="rfc2119" title="MAY">MAY</em> encode the JSON string using the <a href="https://www.w3.org/TR/encoding/#interface-textencoder">TextEncoder interface</a> [<cite><a class="bibref" href="#bib-ENCODING">ENCODING</a></cite>]. + </p> + + <section id="clear-key-release-ack-format-example" class="informative"> + <h5 id="x9-1-6-1-example"><span class="secno">9.1.6.1 </span>Example</h5><p><em>This section is non-normative.</em></p> + <p>The following example is a license request for a temporary license for two key IDs. (Line breaks are for readability only.)</p> + <div class="example"><div class="example-title marker"><span>Example 5</span></div><pre class="highlight hljs json" aria-busy="false" aria-live="polite">{ <span class="hljs-attr">"kids"</span>: [ <span class="hljs-string">"LwVHf8JLtPrv2GUXFW2v_A"</span>, <span class="hljs-string">"0DdtU9od-Bh5L3xbv0Xf_A"</span> ] -}</pre> - </div> - </section> - </section> - <section id="using-base64url" class="informative"> - <h4 id="x9.1.7-using-base64url"><span class="secno">9.1.7 </span>Using base64url</h4> - <p><em>This section is non-normative.</em></p> - <p>For more information on base64url and working with it, see the "Base64url Encoding" terminology definition and "Notes on implementing base64url encoding without padding" in [<cite><a class="bibref" href="#bib-RFC7515">RFC7515</a></cite>]. - Specifically, there is no '=' padding, and the characters '-' and '_' <em class="rfc2119" title="MUST">MUST</em> be used instead of '+' and '/', respectively. - </p> - </section> +}</pre></div> + </section> </section> + <section id="using-base64url" class="informative"> + <h4 id="x9-1-7-using-base64url"><span class="secno">9.1.7 </span>Using base64url</h4><p><em>This section is non-normative.</em></p> + <p>For more information on base64url and working with it, see the "Base64url Encoding" terminology definition and "Notes on implementing base64url encoding without padding" in [<cite><a class="bibref" href="#bib-RFC7515">RFC7515</a></cite>]. + Specifically, there is no '=' padding, and the characters '-' and '_' <em class="rfc2119" title="MUST">MUST</em> be used instead of '+' and '/', respectively. + </p> + </section> + </section> </section> <section id="security"> - <!--OddPage--> - <h2 id="x10.-security"><span class="secno">10. </span>Security</h2> - - <section id="input-data-security"> - <h3 id="x10.1-input-data-attacks-and-vulnerabilities"><span class="secno">10.1 </span>Input Data Attacks and Vulnerabilities</h3> - <p>User Agent and Key System implementations <em class="rfc2119" title="MUST">MUST</em> consider <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a>, <a href="#initialization-data">Initialization Data</a>, - data passed to <code><a href="#dom-mediakeysession-update">update()</a></code>, licenses, key data, and all other data provided by the application as untrusted content and potential attack vectors. They <em class="rfc2119" title="MUST">MUST</em> use appropriate safeguards to mitigate any associated threats and take care to safely parse, decrypt, etc. such data. User Agents <em class="rfc2119" title="SHOULD">SHOULD</em> validate data before passing it to the CDM. - </p> - <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note143"><span>Note</span></div> - <p class="">Such validation is especially important if the CDM does not run in the same (sandboxed) context as, for example, the DOM.</p> - </div> - - <p>Implementations <em class="rfc2119" title="MUST NOT">MUST NOT</em> return active content or passive content that affects program control flow to the application.</p> - <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note144"><span>Note</span></div> - <p class="">For example, it is not safe to expose URLs or other information that may have come from media data, such as is the case for the <a href="#initialization-data">Initialization Data</a> passed to <code><a href="#dom-mediakeysession-generaterequest">generateRequest()</a></code>. - Applications must determine the URLs to use. The <code><a href="#dom-mediakeymessageevent-messagetype">messageType</a></code> attribute of the <code><a href="#dom-evt-message">message</a></code> event can be used by the application - to select among a set of URLs if applicable. - </p> - </div> - </section> + <!--OddPage--><h2 id="x10-security"><span class="secno">10. </span>Security</h2> - <section id="cdm-security"> - <h3 id="x10.2-cdm-attacks-and-vulnerabilities"><span class="secno">10.2 </span>CDM Attacks and Vulnerabilities</h3> - <p>User Agents are responsible for providing users with a secure way to browse the web. This responsibility applies to any functionality used by User Agents, including functionalities from third parties. User agent implementers <em class="rfc2119" - title="MUST">MUST</em> obtain sufficient information from Key System implementers to enable them to properly assess the security implications of integrating with the Key System. User agent implementers <em class="rfc2119" title="MUST">MUST</em> ensure CDM implementations provide and/or support sufficient controls for the user agent to provide security for the user. User agent implementers <em class="rfc2119" title="MUST">MUST</em> ensure CDM implementations can and will be quickly - and proactively updated in the event of security vulnerabilities. - </p> - <p>Exploiting a CDM implementation that is not fully sandboxed and/or uses platform features may allow an attacker to access OS or platform features, elevate privilege (e.g., to run as system or root), and/or access drivers, kernel, firmware, - hardware, etc. Such features, software, and hardware may not be written to be robust against hostile software or web-based attacks and may not be updated with security fixes, especially compared to the user agent. Lack of, infrequent, - or slow updates for fixes to security vulnerabilities in CDM implementations increases the risk. Such CDM implementations and UAs that expose them <em class="rfc2119" title="MUST">MUST</em> be especially careful in all areas of security, - including parsing of <a href="#input-data-security">all data</a>. - </p> - <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note145"><span>Note</span></div> - <p class="">User agents should be especially diligent when using a CDM or underlying mechanism that is part of or provided by the client OS, platform and/or hardware.</p> - </div> + <section id="input-data-security"> + <h3 id="x10-1-input-data-attacks-and-vulnerabilities"><span class="secno">10.1 </span>Input Data Attacks and Vulnerabilities</h3> + <p>User Agent and Key System implementations <em class="rfc2119" title="MUST">MUST</em> consider <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a>, <a href="#initialization-data">Initialization Data</a>, data passed to <code><a href="#dom-mediakeysession-update">update()</a></code>, licenses, key data, and all other data provided by the application as untrusted content and potential attack vectors. + They <em class="rfc2119" title="MUST">MUST</em> use appropriate safeguards to mitigate any associated threats and take care to safely parse, decrypt, etc. such data. + User Agents <em class="rfc2119" title="SHOULD">SHOULD</em> validate data before passing it to the CDM. + </p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-141" aria-level="4"><span>Note</span></div><p class="">Such validation is especially important if the CDM does not run in the same (sandboxed) context as, for example, the DOM.</p></div> + + <p>Implementations <em class="rfc2119" title="MUST NOT">MUST NOT</em> return active content or passive content that affects program control flow to the application.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-142" aria-level="4"><span>Note</span></div><p class="">For example, it is not safe to expose URLs or other information that may have come from media data, such as is the case for the <a href="#initialization-data">Initialization Data</a> passed to <code><a href="#dom-mediakeysession-generaterequest">generateRequest()</a></code>. + Applications must determine the URLs to use. The <code><a href="#dom-mediakeymessageevent-messagetype">messageType</a></code> attribute of the <code><a href="#dom-evt-message">message</a></code> event can be used by the application to select among a set of URLs if applicable. + </p></div> + </section> + + <section id="cdm-security"> + <h3 id="x10-2-cdm-attacks-and-vulnerabilities"><span class="secno">10.2 </span>CDM Attacks and Vulnerabilities</h3> + <p>User Agents are responsible for providing users with a secure way to browse the web. + This responsibility applies to any functionality used by User Agents, including functionalities from third parties. + User agent implementers <em class="rfc2119" title="MUST">MUST</em> obtain sufficient information from Key System implementers to enable them to properly assess the security implications of integrating with the Key System. + User agent implementers <em class="rfc2119" title="MUST">MUST</em> ensure CDM implementations provide and/or support sufficient controls for the user agent to provide security for the user. + User agent implementers <em class="rfc2119" title="MUST">MUST</em> ensure CDM implementations can and will be quickly and proactively updated in the event of security vulnerabilities. + </p> + <p>Exploiting a CDM implementation that is not fully sandboxed and/or uses platform features may allow an attacker to access OS or platform features, elevate privilege (e.g., to run as system or root), and/or access drivers, kernel, firmware, hardware, etc. + Such features, software, and hardware may not be written to be robust against hostile software or web-based attacks and may not be updated with security fixes, especially compared to the user agent. + Lack of, infrequent, or slow updates for fixes to security vulnerabilities in CDM implementations increases the risk. + Such CDM implementations and UAs that expose them <em class="rfc2119" title="MUST">MUST</em> be especially careful in all areas of security, including parsing of <a href="#input-data-security">all data</a>. + </p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-143" aria-level="4"><span>Note</span></div><p class="">User agents should be especially diligent when using a CDM or underlying mechanism that is part of or provided by the client OS, platform and/or hardware.</p></div> - <p>If a user agent chooses to support a Key System implementation that cannot be sufficiently sandboxed or otherwise secured, the user agent <em class="rfc2119" title="SHOULD">SHOULD</em> <a href="#security-consent">ensure that users are fully informed and/or give explicit consent</a> before loading or invoking it. - </p> - <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note146"><span>Note</span></div> - <p class="">Granting permissions to unauthenticated origins is equivalent to granting the permissions to any origin in the presence of a network attacker. See <a href="#persisted-consent-abuse">abuse of persisted consent</a>. - </p> - </div> + <p>If a user agent chooses to support a Key System implementation that cannot be sufficiently sandboxed or otherwise secured, the user agent <em class="rfc2119" title="SHOULD">SHOULD</em> <a href="#security-consent">ensure that users are fully informed and/or give explicit consent</a> before loading or invoking it. + </p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-144" aria-level="4"><span>Note</span></div><p class="">Granting permissions to unauthenticated origins is equivalent to granting the permissions to any origin in the presence of a network attacker. + See <a href="#persisted-consent-abuse">abuse of persisted consent</a>. + </p></div> + </section> + + <section id="network-attacks"> + <h3 id="x10-3-network-attacks"><span class="secno">10.3 </span>Network Attacks</h3> + <section class="informative" id="potential-attacks"> + <h4 id="x10-3-1-potential-attacks"><span class="secno">10.3.1 </span>Potential Attacks</h4><p><em>This section is non-normative.</em></p> + <p>Potential network attacks and their implications include:</p> + <ul> + <li><p>DNS spoofing attacks: One cannot guarantee that a host claiming to be in a certain domain (<a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a>) really is from that domain.</p></li> + <li><p>Passive network attacks: One cannot guarantee that data, including <a href="#distinctive-identifier">Distinctive Identifiers</a> and <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifiers</a>, transmitted between the client and server is not viewed by other entities. See <a href="#user-tracking">User Tracking</a>.</p></li> + <li> + <p>Active network attacks: One cannot guarantee that Additional scripts or iframes are not injected into pages (both those that use the APIs defined in this specification for legitimate purposes and pages that do not use them). + The consequences are that: + </p> + <ul> + <li><p>Calls to the APIs defined in this specification can be injected into any page.</p></li> + <li><p>Calls to the APIs defined in this specification from pages using them for legitimate reasons can be manipulated, including modifying the requested functionality, modifying or adding calls, and modifying or injecting data. See also <a href="#input-data-security">Input Data Attacks and Vulnerabilities</a></p></li> + <li><p>Data, including <a href="#distinctive-identifier">Distinctive Identifiers</a> and <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifiers</a>, transmitted between the client and server can be viewed and/or modified by other entities. See <a href="#user-tracking">User Tracking</a>.</p></li> + </ul> + </li> + <li> + <p> + <span id="persisted-consent-abuse">Abuse of persisted consent</span>: One cannot guarantee that the host requesting use of the APIs defined in this specification is the host to which the user previously provided consent. + The consequences are that granting permissions to unauthenticated origins is equivalent to granting the permissions to any origin in the presence of a network attacker. + </p> + </li> + </ul> </section> + <section id="mitigations"> + <h4 id="x10-3-2-mitigations"><span class="secno">10.3.2 </span>Mitigations</h4> + <p>The following techniques may mitigate the risks:</p> + <dl> + <dt>Use TLS</dt> + <dd> + <p>Applications using TLS can be sure that only the user, software working on behalf of the user, and other pages using TLS that have certificates identifying them as being from the same domain, can interact with that application. + Furthermore, <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a>-specific permissions in combination with a secure origin, ensure that permissions granted to an application cannot be abused by a network attacker. + </p> + <p>The APIs defined in this specification are only exposed on secure contexts. + See also <a href="#privacy-secureorigin">Secure Origin and Transport</a>. + </p> + </dd> - <section id="network-attacks"> - <h3 id="x10.3-network-attacks"><span class="secno">10.3 </span>Network Attacks</h3> - <section class="informative" id="potential-attacks"> - <h4 id="x10.3.1-potential-attacks"><span class="secno">10.3.1 </span>Potential Attacks</h4> - <p><em>This section is non-normative.</em></p> - <p>Potential network attacks and their implications include:</p> - <ul> - <li> - <p>DNS spoofing attacks: One cannot guarantee that a host claiming to be in a certain domain (<a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a>) really is from that domain.</p> - </li> - <li> - <p>Passive network attacks: One cannot guarantee that data, including <a href="#distinctive-identifier">Distinctive Identifiers</a> and <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifiers</a>, transmitted - between the client and server is not viewed by other entities. See <a href="#user-tracking">User Tracking</a>.</p> - </li> - <li> - <p>Active network attacks: One cannot guarantee that Additional scripts or iframes are not injected into pages (both those that use the APIs defined in this specification for legitimate purposes and pages that do not use them). The - consequences are that: - </p> - <ul> - <li> - <p>Calls to the APIs defined in this specification can be injected into any page.</p> - </li> - <li> - <p>Calls to the APIs defined in this specification from pages using them for legitimate reasons can be manipulated, including modifying the requested functionality, modifying or adding calls, and modifying or injecting data. - See also <a href="#input-data-security">Input Data Attacks and Vulnerabilities</a></p> - </li> - <li> - <p>Data, including <a href="#distinctive-identifier">Distinctive Identifiers</a> and <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifiers</a>, transmitted between the client and server can be viewed - and/or modified by other entities. See <a href="#user-tracking">User Tracking</a>.</p> - </li> - </ul> - </li> - <li> - <p> - <span id="persisted-consent-abuse">Abuse of persisted consent</span>: One cannot guarantee that the host requesting use of the APIs defined in this specification is the host to which the user previously provided consent. The - consequences are that granting permissions to unauthenticated origins is equivalent to granting the permissions to any origin in the presence of a network attacker. - </p> - </li> - </ul> - </section> - <section id="mitigations"> - <h4 id="x10.3.2-mitigations"><span class="secno">10.3.2 </span>Mitigations</h4> - <p>The following techniques may mitigate the risks:</p> - <dl> - <dt>Use TLS</dt> - <dd> - <p>Applications using TLS can be sure that only the user, software working on behalf of the user, and other pages using TLS that have certificates identifying them as being from the same domain, can interact with that application. - Furthermore, <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a>-specific permissions in combination with a secure origin, ensure that permissions granted to an application cannot be abused - by a network attacker. - </p> - <p>The APIs defined in this specification are only exposed on secure contexts. See also <a href="#privacy-secureorigin">Secure Origin and Transport</a>. - </p> - </dd> + <dt>Block Mixed Content</dt> + <dd> + <p>User agents <em class="rfc2119" title="MUST">MUST</em> properly handle Mixed Content [<cite><a class="bibref" href="#bib-MIXED-CONTENT">MIXED-CONTENT</a></cite>], including blocking "Blockable Content" [<cite><a class="bibref" href="#bib-MIXED-CONTENT">MIXED-CONTENT</a></cite>] to avoid potential exposure to insecure content. + Such exposure could compromise other mitigations, such as use of TLS. + </p> + <p>User agents <em class="rfc2119" title="MAY">MAY</em> choose to block all Mixed Content, including "Optionally-blockable Content" [<cite><a class="bibref" href="#bib-MIXED-CONTENT">MIXED-CONTENT</a></cite>] to further increase security by preventing <a href="#input-data-security">untrusted media data</a> from being passed to the CDM (see <a href="#cdm-security">CDM Attacks and Vulnerabilities</a>).</p> + </dd> - <dt>Block Mixed Content</dt> - <dd> - <p>User agents <em class="rfc2119" title="MUST">MUST</em> properly handle Mixed Content [<cite><a class="bibref" href="#bib-MIXED-CONTENT">MIXED-CONTENT</a></cite>], including blocking "Blockable Content" [<cite><a class="bibref" href="#bib-MIXED-CONTENT">MIXED-CONTENT</a></cite>] - to avoid potential exposure to insecure content. Such exposure could compromise other mitigations, such as use of TLS. - </p> - <p>User agents <em class="rfc2119" title="MAY">MAY</em> choose to block all Mixed Content, including "Optionally-blockable Content" [<cite><a class="bibref" href="#bib-MIXED-CONTENT">MIXED-CONTENT</a></cite>] to further increase security - by preventing <a href="#input-data-security">untrusted media data</a> from being passed to the CDM (see <a href="#cdm-security">CDM Attacks and Vulnerabilities</a>).</p> - </dd> - - <dt id="security-consent">Fully inform users and/or require explicit user consent</dt> - <dd> - <p>User agents <em class="rfc2119" title="SHOULD">SHOULD</em> ensure that users are fully informed and/or give explicit consent before a Key System that presents security concerns that are greater than other user agent features (e.g., - DOM content) may be accessed by an <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a>. - </p> - <p>Such mechanisms <em class="rfc2119" title="MUST">MUST</em> be per <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> to avoid valid uses enabling subsequent malicious access and <em class="rfc2119" - title="MUST">MUST</em> be per <a href="#browsing-profile">browsing profile</a>. - </p> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note147"><span>Note</span></div> - <p class="">The restriction of the APIs defined in this specification to secure contexts ensures that a <a href="#network-attacks">network attacker</a> cannot exploit permissions granted to an unauthenticated origin. See <a href="#persisted-consent-abuse">abuse of persisted consent</a>. - </p> - </div> - </dd> - </dl> - </section> + <dt id="security-consent">Fully inform users and/or require explicit user consent</dt> + <dd> + <p>User agents <em class="rfc2119" title="SHOULD">SHOULD</em> ensure that users are fully informed and/or give explicit consent before a Key System that presents security concerns that are greater than other user agent features (e.g., DOM content) may be accessed by an <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a>. + </p> + <p>Such mechanisms <em class="rfc2119" title="MUST">MUST</em> be per <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> to avoid valid uses enabling subsequent malicious access and <em class="rfc2119" title="MUST">MUST</em> be per <a href="#browsing-profile">browsing profile</a>. + </p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-145" aria-level="5"><span>Note</span></div><p class="">The restriction of the APIs defined in this specification to secure contexts ensures that a <a href="#network-attacks">network attacker</a> cannot exploit permissions granted to an unauthenticated origin. + See <a href="#persisted-consent-abuse">abuse of persisted consent</a>. + </p></div> + </dd> + </dl> </section> - - <section id="iframe-attacks"> - <h3 id="x10.4-iframe-attacks"><span class="secno">10.4 </span><code>iframe</code> Attacks</h3> - <section class="informative" id="potential-attacks-0"> - <h4 id="x10.4.1-potential-attacks"><span class="secno">10.4.1 </span>Potential Attacks</h4> - <p><em>This section is non-normative.</em></p> - <p>Malicious pages could host legitimate applications in an iframe in an attempt hide an attack or deceive the user as to the source, such as making the use appear to be from a legitimate content provider. This is especially relevent for - implementations that <a href="#security-consent">inform the user or require consent</a>, such as for security and/or <a href="#privacy-consent">privacy reasons</a>. In addition to <a href="#network-attacks">Network Attacks</a>, attackers - could try to exploit legitimate uses of the APIs defined in this specification by hosting them in an <code>iframe</code>. By having the legitimate application performing the actions, the attacker can reuse existing granted permissions - (or whitelisting) and/or appear to be a legitimate request or use. - </p> - </section> - <section id="mitigations-0"> - <h4 id="x10.4.2-mitigations"><span class="secno">10.4.2 </span>Mitigations</h4> - <p>User agents that <a href="#security-consent">inform the user or require consent</a>, including for security and/or <a href="#privacy-consent">privacy reasons</a>, - <em class="rfc2119" title="SHOULD">SHOULD</em> base the UI and persistence of consent on the combination of <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> of the top-level <a href="https://www.w3.org/TR/dom/#concept-document">Document</a> and the <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> using the APIs defined in this specification. This ensures that users are informed of the main document making the request and that persisting - a permission for one (legitimate) combination does not inadvertently allow malicious use to go undetected. - </p> - <p>Authors <em class="rfc2119" title="SHOULD">SHOULD</em> prevent other entities from hosting their applications in <code>iframe</code>s. Applications that must support being hosted for legitimate application-design reasons <em class="rfc2119" - title="SHOULD NOT">SHOULD NOT</em> allow hosting documents to provide <a href="#input-data-security">any data to be passed to the CDM</a> - either via the APIs defined in this specification or as media data - and <em class="rfc2119" - title="SHOULD NOT">SHOULD NOT</em> allow hosting frames to invoke the APIs defined in this specification. - </p> - </section> + </section> + + <section id="iframe-attacks"> + <h3 id="x10-4-iframe-attacks"><span class="secno">10.4 </span><code>iframe</code> Attacks</h3> + <section class="informative" id="potential-attacks-0"> + <h4 id="x10-4-1-potential-attacks"><span class="secno">10.4.1 </span>Potential Attacks</h4><p><em>This section is non-normative.</em></p> + <p>Malicious pages could host legitimate applications in an iframe in an attempt hide an attack or deceive the user as to the source, such as making the use appear to be from a legitimate content provider. + This is especially relevent for implementations that <a href="#security-consent">inform the user or require consent</a>, such as for security and/or <a href="#privacy-consent">privacy reasons</a>. + In addition to <a href="#network-attacks">Network Attacks</a>, attackers could try to exploit legitimate uses of the APIs defined in this specification by hosting them in an <code>iframe</code>. + By having the legitimate application performing the actions, the attacker can reuse existing granted permissions (or whitelisting) and/or appear to be a legitimate request or use. + </p> </section> - - <section id="cross-directory-attacks" class="informative"> - <h3 id="x10.5-cross-directory-attacks"><span class="secno">10.5 </span>Cross-Directory Attacks</h3> - <p><em>This section is non-normative.</em></p> - <p>Different authors sharing one host name, for example users hosting content on <code>geocities.com</code>, all share one <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a>. User agents do not provide features - to restrict access to APIs by pathname. - </p> - <p>Using the APIs defined in this specification on shared hosts compromises origin-based security and privacy mitigations implemented by user agents. For example, per-origin <a href="#distinctive-identifier">Distinctive Identifiers</a> are shared - by all authors on one host name, and peristed data may be accessed and manipulated by any author on the host. The latter is especially important if, for example, modification or deletion of such data could erase a user's right to specific - content. - </p> - <div class="note"> - <div class="note-title marker" aria-level="4" role="heading" id="h-note148"><span>Note</span></div> - <p class="">Even if a path-restriction feature was made available by user agents, the usual DOM scripting security model would make it trivial to bypass this protection and access the data from any path.</p> - </div> - <p>Authors on shared hosts are therefore <em class="rfc2119" title="RECOMMENDED">RECOMMENDED</em> to avoid using the APIs defined in this specification because doing so compromises origin-based security and privacy mitigations in user agents.</p> + <section id="mitigations-0"> + <h4 id="x10-4-2-mitigations"><span class="secno">10.4.2 </span>Mitigations</h4> + <p>User agents that <a href="#security-consent">inform the user or require consent</a>, including for security and/or <a href="#privacy-consent">privacy reasons</a>, + <em class="rfc2119" title="SHOULD">SHOULD</em> base the UI and persistence of consent on the combination of <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> of the top-level <a href="https://www.w3.org/TR/dom/#concept-document">Document</a> and the <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> using the APIs defined in this specification. + This ensures that users are informed of the main document making the request and that persisting a permission for one (legitimate) combination does not inadvertently allow malicious use to go undetected. + </p> + <p>Authors <em class="rfc2119" title="SHOULD">SHOULD</em> prevent other entities from hosting their applications in <code>iframe</code>s. + Applications that must support being hosted for legitimate application-design reasons <em class="rfc2119" title="SHOULD NOT">SHOULD NOT</em> allow hosting documents to provide <a href="#input-data-security">any data to be passed to the CDM</a> - either via the APIs defined in this specification or as media data - and <em class="rfc2119" title="SHOULD NOT">SHOULD NOT</em> allow hosting frames to invoke the APIs defined in this specification. + </p> </section> + </section> + + <section id="cross-directory-attacks" class="informative"> + <h3 id="x10-5-cross-directory-attacks"><span class="secno">10.5 </span>Cross-Directory Attacks</h3><p><em>This section is non-normative.</em></p> + <p>Different authors sharing one host name, for example users hosting content on <code>geocities.com</code>, all share one <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a>. + User agents do not provide features to restrict access to APIs by pathname. + </p> + <p>Using the APIs defined in this specification on shared hosts compromises origin-based security and privacy mitigations implemented by user agents. + For example, per-origin <a href="#distinctive-identifier">Distinctive Identifiers</a> are shared by all authors on one host name, and peristed data may be accessed and manipulated by any author on the host. + The latter is especially important if, for example, modification or deletion of such data could erase a user's right to specific content. + </p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-146" aria-level="4"><span>Note</span></div><p class="">Even if a path-restriction feature was made available by user agents, the usual DOM scripting security model would make it trivial to bypass this protection and access the data from any path.</p></div> + <p>Authors on shared hosts are therefore <em class="rfc2119" title="RECOMMENDED">RECOMMENDED</em> to avoid using the APIs defined in this specification because doing so compromises origin-based security and privacy mitigations in user agents.</p> + </section> </section> <section id="privacy"> - <!--OddPage--> - <h2 id="x11.-privacy"><span class="secno">11. </span>Privacy</h2> - - <p>The presence or use of Key System(s) on a user's device raises a number of privacy issues, falling into two categories: (a) user-specific information that may be disclosed by the EME interface itself or within Key System messages and (b) user-specific - information that may be persistently stored on the user's device.</p> - <p>User Agents <em class="rfc2119" title="MUST">MUST</em> take responsibility for providing users with adequate control over their own privacy. Since User Agents may integrate with third party CDM implementations, CDM implementers <em class="rfc2119" - title="MUST">MUST</em> provide sufficient information and controls to user agent implementers to enable them to implement appropriate techniques to ensure users have control over their privacy, including but not limited to the techniques described - below. + <!--OddPage--><h2 id="x11-privacy"><span class="secno">11. </span>Privacy</h2> + + <p>The presence or use of Key System(s) on a user's device raises a number of privacy issues, falling into two categories: (a) user-specific information that may be disclosed by the EME interface itself or within Key System messages and (b) user-specific information that may be persistently stored on the user's device.</p> + <p>User Agents <em class="rfc2119" title="MUST">MUST</em> take responsibility for providing users with adequate control over their own privacy. + Since User Agents may integrate with third party CDM implementations, CDM implementers <em class="rfc2119" title="MUST">MUST</em> provide sufficient information and controls to user agent implementers to enable them to implement appropriate techniques to ensure users have control over their privacy, including but not limited to the techniques described below. + </p> + + <section id="privacy-disclosure"> + <h3 id="x11-1-information-disclosed-by-eme-and-key-systems"><span class="secno">11.1 </span>Information Disclosed by EME and Key Systems</h3> + <p>Concerns regarding information disclosed by EME and Key Systems fall into two categories: (a) concerns about non-specific information that may nevertheless contribute to the possibility of fingerprinting a user agent or device and (b) user-specific information that may be used directly for <a href="#user-tracking">user tracking</a>.</p> + </section> + + <section id="privacy-fingerprinting"> + <h3 id="x11-2-fingerprinting"><span class="secno">11.2 </span>Fingerprinting</h3> + <p>Malicious applications may be able to fingerprint users or user agents by detecting or enumerating the list of Key Systems that are supported and related information. + If proper origin protections are not provided this could include detection of sites that have been visited and information stored for those sites. In particular, Key Systems <em class="rfc2119" title="MUST">MUST</em> not share key or other data between <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origins</a>. </p> - - <section id="privacy-disclosure"> - <h3 id="x11.1-information-disclosed-by-eme-and-key-systems"><span class="secno">11.1 </span>Information Disclosed by EME and Key Systems</h3> - <p>Concerns regarding information disclosed by EME and Key Systems fall into two categories: (a) concerns about non-specific information that may nevertheless contribute to the possibility of fingerprinting a user agent or device and (b) user-specific - information that may be used directly for <a href="#user-tracking">user tracking</a>.</p> - </section> - - <section id="privacy-fingerprinting"> - <h3 id="x11.2-fingerprinting"><span class="secno">11.2 </span>Fingerprinting</h3> - <p>Malicious applications may be able to fingerprint users or user agents by detecting or enumerating the list of Key Systems that are supported and related information. If proper origin protections are not provided this could include detection - of sites that have been visited and information stored for those sites. In particular, Key Systems <em class="rfc2119" title="MUST">MUST</em> not share key or other data between <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origins</a>. - </p> + </section> + + <section id="privacy-leakage"> + <h3 id="x11-3-information-leakage"><span class="secno">11.3 </span>Information Leakage</h3> + <section class="informative" id="concerns"> + <h4 id="x11-3-1-concerns"><span class="secno">11.3.1 </span>Concerns</h4><p><em>This section is non-normative.</em></p> + <p>CDMs, especially those implemented outside the user agent, may not have the same fundamental isolations as the web platform. + It is important that steps be taken to avoid information leakage, especially across origins. + This includes both in-memory and stored data. + Failure to do so could lead to information leakage to/from private browsing sessions, across <a href="#browsing-profile">browsing profiles</a> (including across operating system user accounts) and even across different browsers or applications. + </p> </section> - - <section id="privacy-leakage"> - <h3 id="x11.3-information-leakage"><span class="secno">11.3 </span>Information Leakage</h3> - <section class="informative" id="concerns"> - <h4 id="x11.3.1-concerns"><span class="secno">11.3.1 </span>Concerns</h4> - <p><em>This section is non-normative.</em></p> - <p>CDMs, especially those implemented outside the user agent, may not have the same fundamental isolations as the web platform. It is important that steps be taken to avoid information leakage, especially across origins. This includes both - in-memory and stored data. Failure to do so could lead to information leakage to/from private browsing sessions, across <a href="#browsing-profile">browsing profiles</a> (including across operating system user accounts) and even across - different browsers or applications. - </p> - </section> - <section id="mitigations-1"> - <h4 id="x11.3.2-mitigations"><span class="secno">11.3.2 </span>Mitigations</h4> - <p>To avoid such issues, user agent and CDM implementations <em class="rfc2119" title="MUST">MUST</em> ensure that:</p> + <section id="mitigations-1"> + <h4 id="x11-3-2-mitigations"><span class="secno">11.3.2 </span>Mitigations</h4> + <p>To avoid such issues, user agent and CDM implementations <em class="rfc2119" title="MUST">MUST</em> ensure that:</p> + <ul> + <li><p>CDMs have a concept of a CDM instance that is associated one-to-one with a MediaKeys object.</p></li> + <li><p>Keys, licenses, other session data, and the presence of sessions are restricted to the CDM instance associated with the MediaKeys object that created the session.</p></li> + <li><p>Session data is not shared between MediaKeys objects or CDM instances.</p></li> + <li> + <p> + Session data is not shared with media elements not associated with the MediaKeys object that created the session. + Among other things, this means a session's keys <em class="rfc2119" title="MUST">MUST</em> not be used to decrypt content loaded by a media element whose <code><a href="#dom-mediakeys">mediaKeys</a></code> attribute is not that MediaKeys object. + </p> + </li> + <li><p>MediaKeys objects and the underlying implementation do not expose information outside the <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a>.</p></li> + <li><p>Persisted session data, if applicable, is stored on a per-<a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> basis.</p></li> + <li><p>Only data stored by the requesting <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> may be loaded.</p></li> + <li> + <p> + It is not possible to extract, derive or infer information from the CDM that is not either explicitly described in this specification + or available to the page through other web platform APIs without user permission. This applies to any information that is exposed outside + the client device or to the application, including, for example, in CDM messages. + </p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-147" aria-level="5"><span>Note</span></div><div class=""> + <p>The type of information covered by this requirement includes but is not limited to:</p> <ul> - <li> - <p>CDMs have a concept of a CDM instance that is associated one-to-one with a MediaKeys object.</p> - </li> - <li> - <p>Keys, licenses, other session data, and the presence of sessions are restricted to the CDM instance associated with the MediaKeys object that created the session.</p> - </li> - <li> - <p>Session data is not shared between MediaKeys objects or CDM instances.</p> - </li> - <li> - <p> - Session data is not shared with media elements not associated with the MediaKeys object that created the session. Among other things, this means a session's keys <em class="rfc2119" title="MUST">MUST</em> not be used to decrypt - content loaded by a media element whose <code><a href="#dom-mediakeys">mediaKeys</a></code> attribute is not that MediaKeys object. - </p> - </li> - <li> - <p>MediaKeys objects and the underlying implementation do not expose information outside the <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a>.</p> - </li> - <li> - <p>Persisted session data, if applicable, is stored on a per-<a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> basis.</p> - </li> - <li> - <p>Only data stored by the requesting <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> may be loaded.</p> - </li> - <li> - <p> - It is not possible to extract, derive or infer information from the CDM that is not either explicitly described in this specification or available to the page through other web platform APIs without user permission. This applies to any information that - is exposed outside the client device or to the application, including, for example, in CDM messages. - </p> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note149"><span>Note</span></div> - <div class=""> - <p>The type of information covered by this requirement includes but is not limited to:</p> - <ul> - <li> - <p>Location, including geolocation</p> - </li> - <li> - <p>Credentials or identifiers other than Distinctive Identifiers</p> - </li> - <li> - <p>OS account name and other potential PII</p> - </li> - <li> - <p>Local directory paths, which may contain similar information.</p> - </li> - <li> - <p>Local network details (for example, the device's local IP address)</p> - </li> - <li> - <p>Local devices, including but not limited to Bluetooth, USB, and user media.</p> - </li> - <li> - <p>User state not associated with or stored as a result of the APIs defined in this specification.</p> - </li> - </ul> - </div> - </div> - </li> + <li><p>Location, including geolocation</p></li> + <li><p>Credentials or identifiers other than Distinctive Identifiers</p></li> + <li><p>OS account name and other potential PII</p></li> + <li><p>Local directory paths, which may contain similar information.</p></li> + <li><p>Local network details (for example, the device's local IP address)</p></li> + <li><p>Local devices, including but not limited to Bluetooth, USB, and user media.</p></li> + <li><p>User state not associated with or stored as a result of the APIs defined in this specification.</p></li> </ul> - </section> + </div></div> + </li> + </ul> </section> + </section> + + <section id="user-tracking"> + <h3 id="x11-4-user-tracking"><span class="secno">11.4 </span>User Tracking</h3> + <section class="informative" id="concerns-0"> + <h4 id="x11-4-1-concerns"><span class="secno">11.4.1 </span>Concerns</h4><p><em>This section is non-normative.</em></p> + <p>A third-party host (or any entity, such as an advertiser, capable of getting content distributed to multiple sites) could use a <a href="#distinctive-identifier">Distinctive Identifier</a> or persistent data, including licenses, keys, key IDs, <a href="#record-of-license-destruction">records of license destruction</a>, or <a href="#record-of-key-usage">records of key usage</a>, stored by or on behalf of the <a href="#cdm">CDM</a> to track a user across multiple sessions (including across <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origins</a> and <a href="#browsing-profile">browsing profiles</a>), building a profile of the user's activities or interests. + Such tracking would undermine the privacy protections provided by the rest of the web platform and could, for example, enable highly-targeted advertising not otherwise possible. + In conjunction with a site that is aware of the user's real identity (for example, a content provider or e-commerce site that requires authenticated credentials), this could allow oppressive groups to target individuals with greater accuracy than in a world with purely anonymous web usage. + </p> + + <p>User- or client-specific information that could be obtained via implementations of the APIs in this specification includes:</p> + <ul> + <li><p><a href="#distinctive-identifier">Distinctive Identifier(s)</a></p></li> + <li><p><a href="#distinctive-permanent-identifier">Distinctive Permanent Identifier(s)</a></p></li> + <li><p>Origins visited (via stored or in-memory data, permissions, etc.)</p></li> + <li><p>Content viewed (via stored or in-memory licenses, keys, key IDs, <a href="#record-of-license-destruction">records of license destruction</a>, <a href="#record-of-key-usage">records of key usage</a>, etc.)</p></li> + </ul> + <p>This specification presents a specific concern because such information is commonly stored outside the user agent (and associated <a href="#browsing-profile">browsing profile</a> storage), often in the CDM.</p> + + <p>Since the content of licenses, <a href="#record-of-license-destruction">records of license destruction</a>, and <a href="#record-of-key-usage">records of key usage</a> are Key System-specific and since key IDs may contain any value, these data items could be abused to store user-identifying information.</p> + + <p>Key Systems may access or create persistent or semi-persistent identifier(s) for a device or user of a device. + In some cases these identifiers may be bound to a specific device in a secure manner. + If these identifiers are present in Key System messages, then devices and/or users may be tracked. + If the mitigations below are not applied, this could include both tracking of users / devices over time and associating multiple users of a given device. + </p> + + <p>It is important to note that such identifiers, especially those that are non-clearable, non-<a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a>-specific, or <a href="#permanent-identifier">permanent</a>, exceed the tracking impact of existing techniques such as cookies [<cite><a class="bibref" href="#bib-COOKIES">COOKIES</a></cite>] or session identifiers embedded in URLs.</p> + + <p>If not mitigated, such tracking may take three forms depending on the design of the Key System:</p> + <ul> + <li><p>In all cases, such identifiers are expected to be available to sites and/or servers that fully support the Key System (and thus can interpret Key System messages) enabling tracking by such sites.</p></li> + <li><p>If identifiers exposed by Key Systems are not origin-specific, then two sites and/or servers that fully support the Key System may collude to track the user.</p></li> + <li><p>If Key System messages contain information derived from a user identifier in a consistent manner, for example such that a portion of the initial Key System message for a specific content item does not change over time and is dependent on the user identifier, then this information could be used by any application to track the device or user over time.</p></li> + </ul> + + <p>In addition, if a Key System permits keys or other data to be stored and to be re-used between origins, then it may be possible for two origins to collude and track a unique user by recording their ability to access a common key.</p> + <p>Finally, if any user interface for user control of Key Systems presents data separately from data in HTTP session cookies [<cite><a class="bibref" href="#bib-COOKIES">COOKIES</a></cite>] or persistent storage, then users are likely to modify site authorization or delete data in one and not the others. + This would allow sites to use the various features as redundant backup for each other, defeating a user's attempts to protect his or her privacy. + </p> + + <p> + In addition to the potential for sites and other third-parties to track users, the user agent implementer, CDM vendor, or device vendor could build a profile of the user's activities or interests, such as sites using the APIs defined in this specification that the user visits. + Such tracking would undermine the privacy protections provided by the rest of the web platform, especially those related to isolation of origins. + </p> + + <p> + Identifiers, such as <a href="#distinctive-identifier">Distinctive Identifiers</a>, may be obtained from a server operated or provided by the CDM vendor, such as via an <a href="#individualization">individualization</a> process. + The process may include providing client identifier(s), including <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifier(s)</a>, to the server. + In order to generate a per-origin identifier, a value representing the origin may also be provided. + </p> + + <p> + In such an implementation, the CDM vendor may be able to track the activity of the user, such as number of origins visited or number of times a new identifier is required. + If the origin or a value <a href="#associable">associable</a> with the origin is provided in the identifier request, the CDM vendor could track the sites visited by the user or user(s) of a device. + </p> + <p>The following section describes techniques that may mitigate the risks of tracking without user consent.</p> + </section> + <section id="mitigations-2"> + <h4 id="x11-4-2-mitigations"><span class="secno">11.4.2 </span>Mitigations</h4> + <dl> + <dt>Do not <a href="#uses-distinctive-identifiers-or-distinctive-permanent-identifiers">use Distinctive Identifiers or Distinctive Permanent Identifiers</a></dt> + <dd> + <p>Key System implementations <em class="rfc2119" title="SHOULD">SHOULD</em> avoid <a href="#uses-distinctive-identifiers-or-distinctive-permanent-identifiers">using Distinctive Identifiers and Distinctive Permanent Identifiers</a> whenever possible and only use them when they meaningfully contribute to the robustness of the implementation. + See <a href="#limit-or-avoid-use-of-distinctive-identifiers-and-permanent-identifiers">Limit or Avoid use of Distinctive Identifiers and Permanent Identifiers</a>. + </p> + </dd> - <section id="user-tracking"> - <h3 id="x11.4-user-tracking"><span class="secno">11.4 </span>User Tracking</h3> - <section class="informative" id="concerns-0"> - <h4 id="x11.4.1-concerns"><span class="secno">11.4.1 </span>Concerns</h4> - <p><em>This section is non-normative.</em></p> - <p>A third-party host (or any entity, such as an advertiser, capable of getting content distributed to multiple sites) could use a <a href="#distinctive-identifier">Distinctive Identifier</a> or persistent data, including licenses, keys, - key IDs, <a href="#record-of-license-destruction">records of license destruction</a>, or <a href="#record-of-key-usage">records of key usage</a>, stored by or on behalf of the <a href="#cdm">CDM</a> to track a user across multiple - sessions (including across <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origins</a> and <a href="#browsing-profile">browsing profiles</a>), building a profile of the user's activities or interests. Such - tracking would undermine the privacy protections provided by the rest of the web platform and could, for example, enable highly-targeted advertising not otherwise possible. In conjunction with a site that is aware of the user's real - identity (for example, a content provider or e-commerce site that requires authenticated credentials), this could allow oppressive groups to target individuals with greater accuracy than in a world with purely anonymous web usage. - </p> - - <p>User- or client-specific information that could be obtained via implementations of the APIs in this specification includes:</p> - <ul> - <li> - <p><a href="#distinctive-identifier">Distinctive Identifier(s)</a></p> - </li> - <li> - <p><a href="#distinctive-permanent-identifier">Distinctive Permanent Identifier(s)</a></p> - </li> - <li> - <p>Origins visited (via stored or in-memory data, permissions, etc.)</p> - </li> - <li> - <p>Content viewed (via stored or in-memory licenses, keys, key IDs, <a href="#record-of-license-destruction">records of license destruction</a>, <a href="#record-of-key-usage">records of key usage</a>, etc.)</p> - </li> - </ul> - <p>This specification presents a specific concern because such information is commonly stored outside the user agent (and associated <a href="#browsing-profile">browsing profile</a> storage), often in the CDM.</p> - - <p>Since the content of licenses, <a href="#record-of-license-destruction">records of license destruction</a>, and <a href="#record-of-key-usage">records of key usage</a> are Key System-specific and since key IDs may contain any value, these - data items could be abused to store user-identifying information.</p> - - <p>Key Systems may access or create persistent or semi-persistent identifier(s) for a device or user of a device. In some cases these identifiers may be bound to a specific device in a secure manner. If these identifiers are present in Key - System messages, then devices and/or users may be tracked. If the mitigations below are not applied, this could include both tracking of users / devices over time and associating multiple users of a given device. - </p> - - <p>It is important to note that such identifiers, especially those that are non-clearable, non-<a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a>-specific, or <a href="#permanent-identifier">permanent</a>, - exceed the tracking impact of existing techniques such as cookies [<cite><a class="bibref" href="#bib-COOKIES">COOKIES</a></cite>] or session identifiers embedded in URLs.</p> - - <p>If not mitigated, such tracking may take three forms depending on the design of the Key System:</p> - <ul> - <li> - <p>In all cases, such identifiers are expected to be available to sites and/or servers that fully support the Key System (and thus can interpret Key System messages) enabling tracking by such sites.</p> - </li> - <li> - <p>If identifiers exposed by Key Systems are not origin-specific, then two sites and/or servers that fully support the Key System may collude to track the user.</p> - </li> - <li> - <p>If Key System messages contain information derived from a user identifier in a consistent manner, for example such that a portion of the initial Key System message for a specific content item does not change over time and is dependent - on the user identifier, then this information could be used by any application to track the device or user over time.</p> - </li> - </ul> - - <p>In addition, if a Key System permits keys or other data to be stored and to be re-used between origins, then it may be possible for two origins to collude and track a unique user by recording their ability to access a common key.</p> - <p>Finally, if any user interface for user control of Key Systems presents data separately from data in HTTP session cookies [<cite><a class="bibref" href="#bib-COOKIES">COOKIES</a></cite>] or persistent storage, then users are likely to - modify site authorization or delete data in one and not the others. This would allow sites to use the various features as redundant backup for each other, defeating a user's attempts to protect his or her privacy. - </p> - - <p> - In addition to the potential for sites and other third-parties to track users, the user agent implementer, CDM vendor, or device vendor could build a profile of the user's activities or interests, such as sites using the APIs defined in this specification - that the user visits. Such tracking would undermine the privacy protections provided by the rest of the web platform, especially those related to isolation of origins. - </p> + <dt>Do not expose <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifiers</a> to the application</dt> + <dd> + <p> + Implementations <em class="rfc2119" title="MUST NOT">MUST NOT</em> expose <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifiers</a> to the application or origin. + </p> + </dd> - <p> - Identifiers, such as <a href="#distinctive-identifier">Distinctive Identifiers</a>, may be obtained from a server operated or provided by the CDM vendor, such as via an <a href="#individualization">individualization</a> process. The - process may include providing client identifier(s), including <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifier(s)</a>, to the server. In order to generate a per-origin identifier, a value representing the - origin may also be provided. - </p> + <dt>Encrypt <a href="#distinctive-identifier">Distinctive Identifiers</a></dt> + <dd> + <p><a href="#distinctive-identifier">Distinctive Identifiers</a> in Key System messages <em class="rfc2119" title="MUST">MUST</em> be encrypted, together with a timestamp or nonce, such that the Key System messages are always different. + This prevents the use of Key System messages for tracking except by servers fully supporting the Key System. + See <a href="#encrypt-identifiers">Encrypt Identifiers</a>. + </p> + </dd> - <p> - In such an implementation, the CDM vendor may be able to track the activity of the user, such as number of origins visited or number of times a new identifier is required. If the origin or a value <a href="#associable">associable</a> with the origin is provided in the identifier request, the CDM vendor could track the sites visited by the user or user(s) of a device. - </p> - <p>The following section describes techniques that may mitigate the risks of tracking without user consent.</p> - </section> - <section id="mitigations-2"> - <h4 id="x11.4.2-mitigations"><span class="secno">11.4.2 </span>Mitigations</h4> - <dl> - <dt>Do not <a href="#uses-distinctive-identifiers-or-distinctive-permanent-identifiers">use Distinctive Identifiers or Distinctive Permanent Identifiers</a></dt> - <dd> - <p>Key System implementations <em class="rfc2119" title="SHOULD">SHOULD</em> avoid <a href="#uses-distinctive-identifiers-or-distinctive-permanent-identifiers">using Distinctive Identifiers and Distinctive Permanent Identifiers</a> whenever possible and only use them when they meaningfully contribute to the robustness of the implementation. See <a href="#limit-or-avoid-use-of-distinctive-identifiers-and-permanent-identifiers">Limit or Avoid use of Distinctive Identifiers and Permanent Identifiers</a>. - </p> - </dd> + <dt id="like-cookies">Treat <a href="#distinctive-identifier">Distinctive Identifiers</a> and Key System stored data like cookies / web storage</dt> + <dd> + <p>User agents <em class="rfc2119" title="SHOULD">SHOULD</em> present the presence of <a href="#distinctive-identifier">Distinctive Identifiers</a> and data stored by Key Systems to the user in a way that associates them strongly with HTTP session cookies [<cite><a class="bibref" href="#bib-COOKIES">COOKIES</a></cite>], including it in "remove all data", and presenting it in the same UI locations. + This might encourage users to view such identifiers with healthy suspicion. + User agents <em class="rfc2119" title="SHOULD">SHOULD</em> help the user avoid <a href="#incomplete-clearing">Incomplete Clearing of Data</a>. + </p> + </dd> - <dt>Do not expose <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifiers</a> to the application</dt> - <dd> - <p> - Implementations <em class="rfc2119" title="MUST NOT">MUST NOT</em> expose <a href="#distinctive-permanent-identifier">Distinctive Permanent Identifiers</a> to the application or origin. - </p> - </dd> + <dt>Do not expose per-origin information to unrelated entities</dt> + <dd> + <p> + Do not provide <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin(s)</a> or values <a href="#associable">associable</a> with origins to individualization servers or other entities not related to the origin. + Follow the requirements and recommendations in the <a href="#individualization">Individualization</a> section if such a process is used by the implementation. + </p> + </dd> - <dt>Encrypt <a href="#distinctive-identifier">Distinctive Identifiers</a></dt> - <dd> - <p><a href="#distinctive-identifier">Distinctive Identifiers</a> in Key System messages <em class="rfc2119" title="MUST">MUST</em> be encrypted, together with a timestamp or nonce, such that the Key System messages are always different. - This prevents the use of Key System messages for tracking except by servers fully supporting the Key System. See <a href="#encrypt-identifiers">Encrypt Identifiers</a>. - </p> - </dd> + <dt>Use non-associable per-origin per-profile values and identifiers</dt> + <dd> + <!-- Issue #101 may affect this text. --> + <p> + For all <a href="#distinctive-value">distinctive values</a> exposed to the application, + implementations <em class="rfc2119" title="MUST">MUST</em> use a different <a href="#non-associable-by-application">non-associable by applications</a> value for each <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> and <a href="#browsing-profile">browsing profile</a>. + See <a href="#per-origin-per-profile-values" class="sec-ref"><span class="secno">8.4.1</span> <span class="sec-title">Use Per-Origin Per-Profile Values</span></a>. + </p> + <p> + This is especially important for implementations that <a href="#uses-distinctive-identifiers">use Distinctive Identifier(s)</a>. + See <a href="#per-origin-per-profile-identifiers" class="sec-ref"><span class="secno">8.5.3</span> <span class="sec-title">Use Per-Origin Per-Profile Identifiers</span></a>. + </p> + </dd> - <dt id="like-cookies">Treat <a href="#distinctive-identifier">Distinctive Identifiers</a> and Key System stored data like cookies / web storage</dt> - <dd> - <p>User agents <em class="rfc2119" title="SHOULD">SHOULD</em> present the presence of <a href="#distinctive-identifier">Distinctive Identifiers</a> and data stored by Key Systems to the user in a way that associates them strongly - with HTTP session cookies [<cite><a class="bibref" href="#bib-COOKIES">COOKIES</a></cite>], including it in "remove all data", and presenting it in the same UI locations. This might encourage users to view such identifiers - with healthy suspicion. User agents <em class="rfc2119" title="SHOULD">SHOULD</em> help the user avoid <a href="#incomplete-clearing">Incomplete Clearing of Data</a>. - </p> - </dd> + <dt>Use origin-specific and browsing profile-specific Key System storage</dt> + <dd> + <p>Any data used by the CDM that might impact messages or behavior in an application- or license server-visible way <em class="rfc2119" title="MUST">MUST</em> be partitioned by <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> and <a href="#browsing-profile">browsing profile</a> and <em class="rfc2119" title="MUST NOT">MUST NOT</em> leak to or from private browsing sessions. + This includes both in-memory and persisted data. + Specifically but not exhaustively, session data, licenses, keys, and per-origin identifiers <em class="rfc2119" title="MUST">MUST</em> be partitioned per-<a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> and per-<a href="#browsing-profile">browsing profile</a>. + See <a href="#use-origin-specific-key-system-storage" class="sec-ref"><span class="secno">8.3.1</span> <span class="sec-title">Use origin-specific and browsing profile-specific Key System storage</span></a> and <a href="#per-origin-per-profile-values" class="sec-ref"><span class="secno">8.4.1</span> <span class="sec-title">Use Per-Origin Per-Profile Values</span></a>. + </p> + </dd> - <dt>Do not expose per-origin information to unrelated entities</dt> - <dd> - <p> - Do not provide <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin(s)</a> or values <a href="#associable">associable</a> with origins to individualization servers or other entities not related to - the origin. Follow the requirements and recommendations in the <a href="#individualization">Individualization</a> section if such a process is used by the implementation. - </p> - </dd> + <dt>Provide user deletion of persistent data, including <a href="#distinctive-identifier">Distinctive Identifiers</a></dt> + <dd> + <p>User agents <em class="rfc2119" title="MUST">MUST</em> provide users with the ability to clear any persistent data, including <a href="#distinctive-identifier">Distinctive Identifiers</a>, maintained by Key Systems. + See <a href="#allow-persistent-data-cleared">Allow Persistent Data to Be Cleared</a>. + </p> + </dd> - <dt>Use non-associable per-origin per-profile values and identifiers</dt> - <dd> - <!-- Issue #101 may affect this text. --> - <p> - For all <a href="#distinctive-value">distinctive values</a> exposed to the application, implementations <em class="rfc2119" title="MUST">MUST</em> use a different <a href="#non-associable-by-application">non-associable by applications</a> value for each <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> and <a href="#browsing-profile">browsing profile</a>. See <a href="#per-origin-per-profile-values" class="sec-ref"><span class="secno">8.4.1</span> <span class="sec-title">Use Per-Origin Per-Profile Values</span></a>. - </p> - <p> - This is especially important for implementations that <a href="#uses-distinctive-identifiers">use Distinctive Identifier(s)</a>. See <a href="#per-origin-per-profile-identifiers" class="sec-ref"><span class="secno">8.5.3</span> <span class="sec-title">Use Per-Origin Per-Profile Identifiers</span></a>. - </p> - </dd> - - <dt>Use origin-specific and browsing profile-specific Key System storage</dt> - <dd> - <p>Any data used by the CDM that might impact messages or behavior in an application- or license server-visible way <em class="rfc2119" title="MUST">MUST</em> be partitioned by <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> and <a href="#browsing-profile">browsing profile</a> and <em class="rfc2119" title="MUST NOT">MUST NOT</em> leak to or from private browsing sessions. This includes both in-memory and persisted data. Specifically but not exhaustively, - session data, licenses, keys, and per-origin identifiers <em class="rfc2119" title="MUST">MUST</em> be partitioned per-<a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> and per-<a href="#browsing-profile">browsing profile</a>. - See <a href="#use-origin-specific-key-system-storage" class="sec-ref"><span class="secno">8.3.1</span> <span class="sec-title">Use origin-specific and browsing profile-specific Key System storage</span></a> and <a href="#per-origin-per-profile-values" - class="sec-ref"><span class="secno">8.4.1</span> <span class="sec-title">Use Per-Origin Per-Profile Values</span></a>. - </p> - </dd> + <dt>Expire stored data</dt> + <dd> + <p>User agents <em class="rfc2119" title="MAY">MAY</em>, possibly in a manner configured by the user, automatically delete <a href="#distinctive-identifier">Distinctive Identifiers</a> and/or other Key System data after a period of time.</p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-148" aria-level="5"><span>Note</span></div><div class=""> + <p>For example, a user agent could be configured to store such data as session-only storage, deleting the data once the user had closed all the browsing contexts that could access it.</p> + <p>This can restrict the ability of a site to track a user, as the site would then only be able to track the user across multiple sessions when the user authenticates with the site itself (e.g., by making a purchase or signing in to a service).</p> + <p>However, this can also put the user's access to content, especially purchased or rented content, at risk if the user does not fully understand the implications of such expiration.</p> + </div></div> + </dd> - <dt>Provide user deletion of persistent data, including <a href="#distinctive-identifier">Distinctive Identifiers</a></dt> - <dd> - <p>User agents <em class="rfc2119" title="MUST">MUST</em> provide users with the ability to clear any persistent data, including <a href="#distinctive-identifier">Distinctive Identifiers</a>, maintained by Key Systems. See <a href="#allow-persistent-data-cleared">Allow Persistent Data to Be Cleared</a>. - </p> - </dd> - - <dt>Expire stored data</dt> - <dd> - <p>User agents <em class="rfc2119" title="MAY">MAY</em>, possibly in a manner configured by the user, automatically delete <a href="#distinctive-identifier">Distinctive Identifiers</a> and/or other Key System data after a period of - time.</p> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note150"><span>Note</span></div> - <div class=""> - <p>For example, a user agent could be configured to store such data as session-only storage, deleting the data once the user had closed all the browsing contexts that could access it.</p> - <p>This can restrict the ability of a site to track a user, as the site would then only be able to track the user across multiple sessions when the user authenticates with the site itself (e.g., by making a purchase or signing - in to a service).</p> - <p>However, this can also put the user's access to content, especially purchased or rented content, at risk if the user does not fully understand the implications of such expiration.</p> - </div> - </div> - </dd> - - <dt>Block third-party access</dt> - <dd> - <!-- Issue #101 may affect this text. --> - <p>User agents <em class="rfc2119" title="MAY">MAY</em> restrict access to Key Systems and/or features to scripts originating at the <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> of the top-level - <a href="https://www.w3.org/TR/dom/#concept-document">Document</a> of the browsing context. For example, <code><a href="#dom-navigator-requestmediakeysystemaccess">requestMediaKeySystemAccess()</a></code> may deny requests - for certain configurations for pages from other origins running in <code>iframe</code>s. - </p> - </dd> + <dt>Block third-party access</dt> + <dd> + <!-- Issue #101 may affect this text. --> + <p>User agents <em class="rfc2119" title="MAY">MAY</em> restrict access to Key Systems and/or features to scripts originating at the <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> of the top-level <a href="https://www.w3.org/TR/dom/#concept-document">Document</a> of the browsing context. + For example, <code><a href="#dom-navigator-requestmediakeysystemaccess">requestMediaKeySystemAccess()</a></code> may deny requests for certain configurations for pages from other origins running in <code>iframe</code>s. + </p> + </dd> - <dt id="privacy-consent">Fully inform users and/or require explicit user consent</dt> - <dd> - <p>User agents <em class="rfc2119" title="MUST">MUST</em> ensure that users are fully informed and/or give explicit consent before <a href="#uses-distinctive-identifiers-or-distinctive-permanent-identifiers">using Distinctive Identifier(s) and Distinctive Permanent Identifier(s)</a>. - </p> - <p>Such mechanisms <em class="rfc2119" title="MUST">MUST</em> be per <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> to avoid valid uses enabling subsequent malicious access and <em class="rfc2119" - title="MUST">MUST</em> be per <a href="#browsing-profile">browsing profile</a>. - </p> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note151"><span>Note</span></div> - <p class="">The restriction of the APIs defined in this specification to secure contexts ensures that a <a href="#network-attacks">network attacker</a> cannot exploit permissions granted to an unauthenticated origin. See <a href="#persisted-consent-abuse">abuse of persisted consent</a>. - </p> - </div> - </dd> + <dt id="privacy-consent">Fully inform users and/or require explicit user consent</dt> + <dd> + <p>User agents <em class="rfc2119" title="MUST">MUST</em> ensure that users are fully informed and/or give explicit consent before <a href="#uses-distinctive-identifiers-or-distinctive-permanent-identifiers">using Distinctive Identifier(s) and Distinctive Permanent Identifier(s)</a>. + </p> + <p>Such mechanisms <em class="rfc2119" title="MUST">MUST</em> be per <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a> to avoid valid uses enabling subsequent malicious access and <em class="rfc2119" title="MUST">MUST</em> be per <a href="#browsing-profile">browsing profile</a>. + </p> + <div class="note"><div role="heading" class="note-title marker" id="h-note-149" aria-level="5"><span>Note</span></div><p class="">The restriction of the APIs defined in this specification to secure contexts ensures that a <a href="#network-attacks">network attacker</a> cannot exploit permissions granted to an unauthenticated origin. + See <a href="#persisted-consent-abuse">abuse of persisted consent</a>. + </p></div> + </dd> - <dt>Provide user controls to disable Key Systems or Key System use of identifiers</dt> - <dd> - <p>User Agents <em class="rfc2119" title="SHOULD">SHOULD</em> provide users with a global control of whether a Key System is enabled and/or whether Key System <a href="#uses-distinctive-identifiers-or-distinctive-permanent-identifiers">use of Distinctive Identifier(s) and Distinctive Permanent Identifier(s)</a> is enabled (if supported by the Key System). User agents <em class="rfc2119" title="SHOULD">SHOULD</em> help the user avoid <a href="#incomplete-clearing">Incomplete Clearing of Data</a>. - </p> - </dd> + <dt>Provide user controls to disable Key Systems or Key System use of identifiers</dt> + <dd> + <p>User Agents <em class="rfc2119" title="SHOULD">SHOULD</em> provide users with a global control of whether a Key System is enabled and/or whether Key System <a href="#uses-distinctive-identifiers-or-distinctive-permanent-identifiers">use of Distinctive Identifier(s) and Distinctive Permanent Identifier(s)</a> is enabled (if supported by the Key System). + User agents <em class="rfc2119" title="SHOULD">SHOULD</em> help the user avoid <a href="#incomplete-clearing">Incomplete Clearing of Data</a>. + </p> + </dd> - <dt>Require site-specific whitelisting of access to each Key System</dt> - <dd> - <p>User agents <em class="rfc2119" title="MAY">MAY</em> require the user to explicitly authorize access to each Key System - and/or certain features - before a site can use it. User agents <em class="rfc2119" title="SHOULD">SHOULD</em> enable users to revoke this authorization either temporarily or permanently. - </p> - </dd> + <dt>Require site-specific whitelisting of access to each Key System</dt> + <dd> + <p>User agents <em class="rfc2119" title="MAY">MAY</em> require the user to explicitly authorize access to each Key System - and/or certain features - before a site can use it. + User agents <em class="rfc2119" title="SHOULD">SHOULD</em> enable users to revoke this authorization either temporarily or permanently. + </p> + </dd> - <dt>Use shared blacklists</dt> - <dd> - <p>User agents <em class="rfc2119" title="MAY">MAY</em> allow users to share blacklists of <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origins</a> and/or Key Systems. This would allow communities to act - together to protect their privacy. - </p> - </dd> - </dl> + <dt>Use shared blacklists</dt> + <dd> + <p>User agents <em class="rfc2119" title="MAY">MAY</em> allow users to share blacklists of <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origins</a> and/or Key Systems. + This would allow communities to act together to protect their privacy. + </p> + </dd> + </dl> - <div class="note"> - <div class="note-title marker" aria-level="5" role="heading" id="h-note152"><span>Note</span></div> - <p class="">While these suggestions prevent trivial use of the APIs defined in this specification for user tracking, they do not block it altogether. Within a single origin, a site can continue to track the user during a session, and can then - pass all this information to a third party along with any identifying information (names, credit card numbers, addresses) obtained by the site. If a third party cooperates with multiple sites to obtain such information, and if - identifiers are not - <!-- Issue #101 may affect this text. --><a href="#per-origin-per-profile-identifiers">unique per origin and profile</a>, then a profile can still be created. - </p> - </div> - </section> + <div class="note"><div role="heading" class="note-title marker" id="h-note-150" aria-level="5"><span>Note</span></div><p class="">While these suggestions prevent trivial use of the APIs defined in this specification for user tracking, they do not block it altogether. + Within a single origin, a site can continue to track the user during a session, and can then pass all this information to a third party along with any identifying information (names, credit card numbers, addresses) obtained by the site. + If a third party cooperates with multiple sites to obtain such information, and if identifiers are not <!-- Issue #101 may affect this text. --><a href="#per-origin-per-profile-identifiers">unique per origin and profile</a>, then a profile can still be created. + </p></div> </section> - - <section id="privacy-storedinfo"> - <h3 id="x11.5-information-stored-on-user-devices"><span class="secno">11.5 </span>Information Stored on User Devices</h3> - <section class="informative" id="concerns-1"> - <h4 id="x11.5.1-concerns"><span class="secno">11.5.1 </span>Concerns</h4> - <p><em>This section is non-normative.</em></p> - <p>Key Systems may store information on a user's device, or user agents may store information on behalf of Key Systems. Potentially, this could reveal information about a user to another user of the same device, including potentially the - <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origins</a> that have used a particular Key System (i.e., sites visited) or even the content that has been decrypted using a Key System. - </p> - <p>If information stored by one origin affects the operation of the Key System for another origin, then potentially the sites visited or content viewed by a user on one site may be revealed to another, potentially malicious, site.</p> - <p>If information stored for one <a href="#browsing-profile">browsing profile</a> on the client device affects the operation of the Key System for other <a href="#browsing-profile">browsing profiles</a>, or browsers, then potentially the - sites visited or content viewed in one may be revealed by or correlatable with another <a href="#browsing-profile">browsing profile</a>, even including for different operating system user accounts or browsers.</p> - </section> - <section id="mitigations-3"> - <h4 id="x11.5.2-mitigations"><span class="secno">11.5.2 </span>Mitigations</h4> - <p>Requirements mitigating these concerns are defined in <a href="#persistent-state-requirements" class="sec-ref"><span class="secno">8.3</span> <span class="sec-title">Persistent Data</span></a>.</p> - </section> + </section> + + <section id="privacy-storedinfo"> + <h3 id="x11-5-information-stored-on-user-devices"><span class="secno">11.5 </span>Information Stored on User Devices</h3> + <section class="informative" id="concerns-1"> + <h4 id="x11-5-1-concerns"><span class="secno">11.5.1 </span>Concerns</h4><p><em>This section is non-normative.</em></p> + <p>Key Systems may store information on a user's device, or user agents may store information on behalf of Key Systems. + Potentially, this could reveal information about a user to another user of the same device, including potentially the <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origins</a> that have used a particular Key System (i.e., sites visited) or even the content that has been decrypted using a Key System. + </p> + <p>If information stored by one origin affects the operation of the Key System for another origin, then potentially the sites visited or content viewed by a user on one site may be revealed to another, potentially malicious, site.</p> + <p>If information stored for one <a href="#browsing-profile">browsing profile</a> on the client device affects the operation of the Key System for other <a href="#browsing-profile">browsing profiles</a>, or browsers, then potentially the sites visited or content viewed in one may be revealed by or correlatable with another <a href="#browsing-profile">browsing profile</a>, even including for different operating system user accounts or browsers.</p> </section> - - <section id="incomplete-clearing"> - <h3 id="x11.6-incomplete-clearing-of-data"><span class="secno">11.6 </span>Incomplete Clearing of Data</h3> - <section class="informative" id="concerns-2"> - <h4 id="x11.6.1-concerns"><span class="secno">11.6.1 </span>Concerns</h4> - <p><em>This section is non-normative.</em></p> - <p>A user's attempts to protect his or her privacy by clearing <a href="#distinctive-identifier">Distinctive Identifiers</a> and stored data and/or disabling a Key System may be defeated if all such data and functionality as well as cookies - [<cite><a class="bibref" href="#bib-COOKIES">COOKIES</a></cite>] and other site data are not cleared and/or disabled at the same time. For example: - </p> - <ul> - <li> - <p>If a user clears cookies or other persistent storage without also clearing <a href="#distinctive-identifier">Distinctive Identifiers</a> and data stored by Key Systems, sites can defeat those attempts by using the various features - as redundant backup for each other.</p> - </li> - <li> - <p>If a user clears <a href="#distinctive-identifier">Distinctive Identifiers</a> without also clearing data stored by Key Systems, including persistent sessions, as well as cookies and other persistent storage, sites can defeat those - attempts by using the remaining data to associate the old and new identifiers.</p> - </li> - <li> - <p>If a user disables a key system, especially for a specific <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a>, without also clearing cookies or other persistent storage, sites can defeat those - attempts by using the remaining features.</p> - </li> - <li> - <p>If a user disables a key system, then later decide to enable the key system, without also clearing clearing cookies or other persistent storage, <a href="#distinctive-identifier">Distinctive Identifiers</a>, and data stored by - Key Systems, sites may be able to associate data prior to the disabling with data and behavior after the key system is re-enabled.</p> - </li> - </ul> - </section> - <section id="mitigations-4"> - <h4 id="x11.6.2-mitigations"><span class="secno">11.6.2 </span>Mitigations</h4> - <p>Recommendations mitigating these concerns are defined in <a href="#persistent-state-requirements" class="sec-ref"><span class="secno">8.3</span> <span class="sec-title">Persistent Data</span></a>.</p> - </section> + <section id="mitigations-3"> + <h4 id="x11-5-2-mitigations"><span class="secno">11.5.2 </span>Mitigations</h4> + <p>Requirements mitigating these concerns are defined in <a href="#persistent-state-requirements" class="sec-ref"><span class="secno">8.3</span> <span class="sec-title">Persistent Data</span></a>.</p> </section> - - <section id="private-browsing"> - <h3 id="x11.7-private-browsing-modes"><span class="secno">11.7 </span>Private Browsing Modes</h3> - <p>User agents may support a mode (e.g., private browsing) of operation intended to preserve user anonymity and/or ensure records of browsing activity are not persisted on the client. The privacy concerns discussed in previous sections may be - especially concerning for users employing such modes. - </p> - <p>User agent implementers that support such mode(s) <em class="rfc2119" title="SHOULD">SHOULD</em> carefully consider whether access to Key Systems should be disabled in these mode(s). For example, such modes <em class="rfc2119" title="MAY">MAY</em> prohibit creation of <a href="#dom-mediakeysystemaccess" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemAccess</code></a> objects that support or use <code><a href="#dom-mediakeysystemconfiguration-persistentstate">persistentState</a></code> or a <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> (either as part of the CDM implementation or because the application indicated they were <code><a href="#idl-def-MediaKeysRequirement.required">"required"</a></code>). - If implementations do not prohibit such creation, they <em class="rfc2119" title="SHOULD">SHOULD</em> inform the user of the implications and potential consequences for the expected privacy properties of such modes before allowing their - use. - </p> + </section> + + <section id="incomplete-clearing"> + <h3 id="x11-6-incomplete-clearing-of-data"><span class="secno">11.6 </span>Incomplete Clearing of Data</h3> + <section class="informative" id="concerns-2"> + <h4 id="x11-6-1-concerns"><span class="secno">11.6.1 </span>Concerns</h4><p><em>This section is non-normative.</em></p> + <p>A user's attempts to protect his or her privacy by clearing <a href="#distinctive-identifier">Distinctive Identifiers</a> and stored data and/or disabling a Key System may be defeated if all such data and functionality as well as cookies [<cite><a class="bibref" href="#bib-COOKIES">COOKIES</a></cite>] and other site data are not cleared and/or disabled at the same time. + For example: + </p> + <ul> + <li><p>If a user clears cookies or other persistent storage without also clearing <a href="#distinctive-identifier">Distinctive Identifiers</a> and data stored by Key Systems, sites can defeat those attempts by using the various features as redundant backup for each other.</p></li> + <li><p>If a user clears <a href="#distinctive-identifier">Distinctive Identifiers</a> without also clearing data stored by Key Systems, including persistent sessions, as well as cookies and other persistent storage, sites can defeat those attempts by using the remaining data to associate the old and new identifiers.</p></li> + <li><p>If a user disables a key system, especially for a specific <a href="https://www.w3.org/TR/html51/browsers.html#concept-cross-origin">origin</a>, without also clearing cookies or other persistent storage, sites can defeat those attempts by using the remaining features.</p></li> + <li><p>If a user disables a key system, then later decide to enable the key system, without also clearing clearing cookies or other persistent storage, <a href="#distinctive-identifier">Distinctive Identifiers</a>, and data stored by Key Systems, sites may be able to associate data prior to the disabling with data and behavior after the key system is re-enabled.</p></li> + </ul> </section> - - <section id="privacy-secureorigin"> - <h3 id="x11.8-secure-origin-and-transport"><span class="secno">11.8 </span>Secure Origin and Transport</h3> - <p> - The APIs defined in this specification are only supported on secure origins, protecting information discussed in previous sections. Identifiers are additionally encrypted as specified in <a href="#encrypt-identifiers">Encrypt Identifiers</a>. - </p> - <p>Applications, including the servers they use, <em class="rfc2119" title="SHOULD">SHOULD</em> use secure transport for all traffic involving or containing data or messages from the CDM, including but is not limited to all data passed from <code><a href="#dom-evt-message">message</a></code> events and to <code><a href="#dom-mediakeysession-update">update()</a></code>.</p> - <p>All user agents <em class="rfc2119" title="MUST">MUST</em> properly handle Mixed Content [<cite><a class="bibref" href="#bib-MIXED-CONTENT">MIXED-CONTENT</a></cite>] to avoid exposure to insecure content or transport when the user agent or - application wish to enforce secure origin and transport.</p> + <section id="mitigations-4"> + <h4 id="x11-6-2-mitigations"><span class="secno">11.6.2 </span>Mitigations</h4> + <p>Recommendations mitigating these concerns are defined in <a href="#persistent-state-requirements" class="sec-ref"><span class="secno">8.3</span> <span class="sec-title">Persistent Data</span></a>.</p> </section> + </section> - </section> - - <section id="conformance"> - <!--OddPage--> - <h2 id="x12.-conformance"><span class="secno">12. </span>Conformance</h2> - <p> - As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative. + <section id="private-browsing"> + <h3 id="x11-7-private-browsing-modes"><span class="secno">11.7 </span>Private Browsing Modes</h3> + <p>User agents may support a mode (e.g., private browsing) of operation intended to preserve user anonymity and/or ensure records of browsing activity are not persisted on the client. + The privacy concerns discussed in previous sections may be especially concerning for users employing such modes. </p> - <p id="respecRFC2119">The key words <em class="rfc2119">MAY</em>, <em class="rfc2119">MUST</em>, <em class="rfc2119">MUST NOT</em>, <em class="rfc2119">OPTIONAL</em>, <em class="rfc2119">RECOMMENDED</em>, <em class="rfc2119">REQUIRED</em>, <em class="rfc2119">SHALL</em>, - <em class="rfc2119">SHALL NOT</em>, <em class="rfc2119">SHOULD</em>, and <em class="rfc2119">SHOULD NOT</em> are to be interpreted as described in [<cite><a class="bibref" href="#bib-RFC2119">RFC2119</a></cite>]. + <p>User agent implementers that support such mode(s) <em class="rfc2119" title="SHOULD">SHOULD</em> carefully consider whether access to Key Systems should be disabled in these mode(s). + For example, such modes <em class="rfc2119" title="MAY">MAY</em> prohibit creation of <a href="#dom-mediakeysystemaccess" class="internalDFN" data-link-type="dfn"><code>MediaKeySystemAccess</code></a> objects that support or use <code><a href="#dom-mediakeysystemconfiguration-persistentstate">persistentState</a></code> or a <code><a href="#dom-mediakeysystemconfiguration-distinctiveidentifier">distinctiveIdentifier</a></code> (either as part of the CDM implementation or because the application indicated they were <code><a href="#idl-def-MediaKeysRequirement.required">"required"</a></code>). + If implementations do not prohibit such creation, they <em class="rfc2119" title="SHOULD">SHOULD</em> inform the user of the implications and potential consequences for the expected privacy properties of such modes before allowing their use. </p> - </section> + </section> - <section id="examples" class="informative"> - <!--OddPage--> - <h2 id="x13.-examples"><span class="secno">13. </span>Examples</h2> - <p><em>This section is non-normative.</em></p> - <p>This section contains example solutions for various use cases using the proposed extensions. These are not the only solutions to these use cases. Video elements are used in the examples, but the same would apply to all media elements. In some - cases, such as using synchronous XHR, the examples are simplified to keep the focus on the extensions. + <section id="privacy-secureorigin"> + <h3 id="x11-8-secure-origin-and-transport"><span class="secno">11.8 </span>Secure Origin and Transport</h3> + <p> + The APIs defined in this specification are only supported on secure origins, protecting information discussed in previous sections. + Identifiers are additionally encrypted as specified in <a href="#encrypt-identifiers">Encrypt Identifiers</a>. </p> + <p>Applications, including the servers they use, <em class="rfc2119" title="SHOULD">SHOULD</em> use secure transport for all traffic involving or containing data or messages from the CDM, including but is not limited to all data passed from <code><a href="#dom-evt-message">message</a></code> events and to <code><a href="#dom-mediakeysession-update">update()</a></code>.</p> + <p>All user agents <em class="rfc2119" title="MUST">MUST</em> properly handle Mixed Content [<cite><a class="bibref" href="#bib-MIXED-CONTENT">MIXED-CONTENT</a></cite>] to avoid exposure to insecure content or transport when the user agent or application wish to enforce secure origin and transport.</p> + </section> - <section id="example-source-and-key-known"> - <h3 id="x13.1-source-and-key-known-at-page-load-(clear-key)"><span class="secno">13.1 </span>Source and Key Known at Page Load (Clear Key)</h3> - <p class="exampledescription">In this simple example, the source file and <a href="#clear-key">clear-text license</a> are hard-coded in the page. Only one session will ever be created.</p> + </section> + + <section id="conformance"><!--OddPage--><h2 id="x12-conformance"><span class="secno">12. </span>Conformance</h2> +<p> + As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, + and notes in this specification are non-normative. Everything else in this specification is + normative. +</p> +<p id="respecRFC2119">The key words <em class="rfc2119">MAY</em>, <em class="rfc2119">MUST</em>, <em class="rfc2119">MUST NOT</em>, <em class="rfc2119">OPTIONAL</em>, <em class="rfc2119">RECOMMENDED</em>, <em class="rfc2119">REQUIRED</em>, <em class="rfc2119">SHALL</em>, <em class="rfc2119">SHALL NOT</em>, <em class="rfc2119">SHOULD</em>, and <em class="rfc2119">SHOULD NOT</em> are + to be interpreted as described in [<cite><a class="bibref" href="#bib-RFC2119">RFC2119</a></cite>]. +</p> +</section> - <div class="example"> - <div class="example-title marker"><span>Example 6</span></div> - <pre class="highlight hljs xml" aria-busy="false" aria-live="polite"><span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="javascript"> + <section id="examples" class="informative"> + <!--OddPage--><h2 id="x13-examples"><span class="secno">13. </span>Examples</h2><p><em>This section is non-normative.</em></p> + <p>This section contains example solutions for various use cases using the proposed extensions. + These are not the only solutions to these use cases. + Video elements are used in the examples, but the same would apply to all media elements. + In some cases, such as using synchronous XHR, the examples are simplified to keep the focus on the extensions. + </p> + + <section id="example-source-and-key-known"> + <h3 id="x13-1-source-and-key-known-at-page-load-clear-key"><span class="secno">13.1 </span>Source and Key Known at Page Load (Clear Key)</h3> + <p class="exampledescription">In this simple example, the source file and <a href="#clear-key">clear-text license</a> are hard-coded in the page. + Only one session will ever be created.</p> + + <div class="example"><div class="example-title marker"><span>Example 6</span></div><pre class="highlight hljs xml" aria-busy="false" aria-live="polite"><span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="javascript"> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">onLoad</span>(<span class="hljs-params"></span>) </span>{ <span class="hljs-keyword">var</span> video = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'video'</span>); @@ -8151,19 +6270,17 @@ <h3 id="x13.1-source-and-key-known-at-page-load-(clear-key)"><span class="secno" <span class="hljs-tag"><<span class="hljs-name">body</span> <span class="hljs-attr">onload</span>=<span class="hljs-string">'onLoad()'</span>></span> <span class="hljs-tag"><<span class="hljs-name">video</span> <span class="hljs-attr">src</span>=<span class="hljs-string">'foo.webm'</span> <span class="hljs-attr">autoplay</span> <span class="hljs-attr">id</span>=<span class="hljs-string">'video'</span>></span><span class="hljs-tag"></<span class="hljs-name">video</span>></span> -<span class="hljs-tag"></<span class="hljs-name">body</span>></span></pre> - </div> - </section> - - <section id="example-selecting-key-system"> - <h3 id="x13.2-selecting-a-supported-key-system-and-using-initialization-data-from-the-"encrypted"-event"><span class="secno">13.2 </span>Selecting a Supported Key System and Using Initialization Data from the "encrypted" Event</h3> - <p class="exampledescription">This example selects a supported <a href="#key-system">Key System</a> using the <code><a href="#dom-navigator-requestmediakeysystemaccess">requestMediaKeySystemAccess()</a></code> method then uses the <a href="#initialization-data">Initialization Data</a> from the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a> to generate the license request and send it to the appropriate license server. One of the supported key systems uses a serverCertificate, - which is provided proactively. - </p> +<span class="hljs-tag"></<span class="hljs-name">body</span>></span></pre></div> + </section> + + <section id="example-selecting-key-system"> + <h3 id="x13-2-selecting-a-supported-key-system-and-using-initialization-data-from-the-encrypted-event"><span class="secno">13.2 </span>Selecting a Supported Key System and Using Initialization Data from the "encrypted" Event</h3> + <p class="exampledescription">This example selects a supported <a href="#key-system">Key System</a> using the <code><a href="#dom-navigator-requestmediakeysystemaccess">requestMediaKeySystemAccess()</a></code> method then uses + the <a href="#initialization-data">Initialization Data</a> from the <a href="https://www.w3.org/TR/html51/semantics-embedded-content.html#media-data">media data</a> to generate the license request and send it to the appropriate license server. + One of the supported key systems uses a serverCertificate, which is provided proactively. + </p> - <div class="example"> - <div class="example-title marker"><span>Example 7</span></div> - <pre class="highlight hljs xml" aria-busy="false" aria-live="polite"><span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="javascript"> + <div class="example"><div class="example-title marker"><span>Example 7</span></div><pre class="highlight hljs xml" aria-busy="false" aria-live="polite"><span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="javascript"> <span class="hljs-keyword">var</span> licenseUrl; <span class="hljs-keyword">var</span> serverCertificate; @@ -8292,19 +6409,17 @@ <h3 id="x13.2-selecting-a-supported-key-system-and-using-initialization-data-fro } </span><span class="hljs-tag"></<span class="hljs-name">script</span>></span> -<span class="hljs-tag"><<span class="hljs-name">video</span> <span class="hljs-attr">autoplay</span> <span class="hljs-attr">onencrypted</span>=<span class="hljs-string">'handleInitData(event)'</span>></span><span class="hljs-tag"></<span class="hljs-name">video</span>></span></pre> - </div> - </section> +<span class="hljs-tag"><<span class="hljs-name">video</span> <span class="hljs-attr">autoplay</span> <span class="hljs-attr">onencrypted</span>=<span class="hljs-string">'handleInitData(event)'</span>></span><span class="hljs-tag"></<span class="hljs-name">video</span>></span></pre></div> + </section> - <section id="example-mediakeys-before-source"> - <h3 id="x13.3-create-mediakeys-before-loading-media"><span class="secno">13.3 </span>Create MediaKeys Before Loading Media</h3> - <p class="exampledescription">Initialization is much simpler if encrypted events do not need to be handled during MediaKeys initialization. This can be accomplished either by providing the <a href="#initialization-data">Initialization Data</a> in other ways or setting - the source after the MediaKeys object has been created. This example does the latter. - </p> + <section id="example-mediakeys-before-source"> + <h3 id="x13-3-create-mediakeys-before-loading-media"><span class="secno">13.3 </span>Create MediaKeys Before Loading Media</h3> + <p class="exampledescription">Initialization is much simpler if encrypted events do not need to be handled during MediaKeys initialization. + This can be accomplished either by providing the <a href="#initialization-data">Initialization Data</a> in other ways or setting the source after the MediaKeys object has been created. + This example does the latter. + </p> - <div class="example"> - <div class="example-title marker"><span>Example 8</span></div> - <pre class="highlight hljs xml" aria-busy="false" aria-live="polite"><span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="javascript"> + <div class="example"><div class="example-title marker"><span>Example 8</span></div><pre class="highlight hljs xml" aria-busy="false" aria-live="polite"><span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="javascript"> <span class="hljs-keyword">var</span> licenseUrl; <span class="hljs-keyword">var</span> serverCertificate; <span class="hljs-keyword">var</span> mediaKeys; @@ -8332,19 +6447,15 @@ <h3 id="x13.3-create-mediakeys-before-loading-media"><span class="secno">13.3 </ ); </span><span class="hljs-tag"></<span class="hljs-name">script</span>></span> -<span class="hljs-tag"><<span class="hljs-name">video</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"v"</span> <span class="hljs-attr">autoplay</span> <span class="hljs-attr">onencrypted</span>=<span class="hljs-string">'handleInitData(event)'</span>></span><span class="hljs-tag"></<span class="hljs-name">video</span>></span></pre> - </div> - </section> +<span class="hljs-tag"><<span class="hljs-name">video</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"v"</span> <span class="hljs-attr">autoplay</span> <span class="hljs-attr">onencrypted</span>=<span class="hljs-string">'handleInitData(event)'</span>></span><span class="hljs-tag"></<span class="hljs-name">video</span>></span></pre></div> + </section> - <section id="example-using-all-events"> - <h3 id="x13.4-using-all-events"><span class="secno">13.4 </span>Using All Events</h3> - <p class="exampledescription">This is a more complete example showing all events being used.</p> - <p class="exampledescription">Note that <code>handleMessage()</code> could be called multiple times, including in response to the <code><a href="#dom-mediakeysession-update">update()</a></code> call if multiple round trips are required and for any other reason the Key - System might need to send a message.</p> + <section id="example-using-all-events"> + <h3 id="x13-4-using-all-events"><span class="secno">13.4 </span>Using All Events</h3> + <p class="exampledescription">This is a more complete example showing all events being used.</p> + <p class="exampledescription">Note that <code>handleMessage()</code> could be called multiple times, including in response to the <code><a href="#dom-mediakeysession-update">update()</a></code> call if multiple round trips are required and for any other reason the Key System might need to send a message.</p> - <div class="example"> - <div class="example-title marker"><span>Example 9</span></div> - <pre class="highlight hljs xml" aria-busy="false" aria-live="polite"><span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="javascript"> + <div class="example"><div class="example-title marker"><span>Example 9</span></div><pre class="highlight hljs xml" aria-busy="false" aria-live="polite"><span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="javascript"> <span class="hljs-keyword">var</span> licenseUrl; <span class="hljs-keyword">var</span> serverCertificate; <span class="hljs-keyword">var</span> mediaKeys; @@ -8428,17 +6539,14 @@ <h3 id="x13.4-using-all-events"><span class="secno">13.4 </span>Using All Events ); </span><span class="hljs-tag"></<span class="hljs-name">script</span>></span> -<span class="hljs-tag"><<span class="hljs-name">video</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"v"</span> <span class="hljs-attr">autoplay</span> <span class="hljs-attr">onencrypted</span>=<span class="hljs-string">'handleInitData(event)'</span>></span><span class="hljs-tag"></<span class="hljs-name">video</span>></span></pre> - </div> - </section> +<span class="hljs-tag"><<span class="hljs-name">video</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"v"</span> <span class="hljs-attr">autoplay</span> <span class="hljs-attr">onencrypted</span>=<span class="hljs-string">'handleInitData(event)'</span>></span><span class="hljs-tag"></<span class="hljs-name">video</span>></span></pre></div> + </section> - <section id="example-stored-license"> - <h3 id="x13.5-stored-license"><span class="secno">13.5 </span>Stored License</h3> - <p class="exampledescription">This example requests a persistent license for future use and stores it. It also provides functions for later retrieving the license and for destroying it.</p> + <section id="example-stored-license"> + <h3 id="x13-5-stored-license"><span class="secno">13.5 </span>Stored License</h3> + <p class="exampledescription">This example requests a persistent license for future use and stores it. It also provides functions for later retrieving the license and for destroying it.</p> - <div class="example"> - <div class="example-title marker"><span>Example 10</span></div> - <pre class="highlight hljs xml" aria-busy="false" aria-live="polite"><span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="javascript"> + <div class="example"><div class="example-title marker"><span>Example 10</span></div><pre class="highlight hljs xml" aria-busy="false" aria-live="polite"><span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="javascript"> <span class="hljs-keyword">var</span> licenseUrl; <span class="hljs-keyword">var</span> serverCertificate; <span class="hljs-keyword">var</span> mediaKeys; @@ -8532,72 +6640,32 @@ <h3 id="x13.5-stored-license"><span class="secno">13.5 </span>Stored License</h3 ); </span><span class="hljs-tag"></<span class="hljs-name">script</span>></span> -<span class="hljs-tag"><<span class="hljs-name">video</span> <span class="hljs-attr">id</span>=<span class="hljs-string">'v'</span> <span class="hljs-attr">src</span>=<span class="hljs-string">'foo.webm'</span> <span class="hljs-attr">autoplay</span>></span><span class="hljs-tag"></<span class="hljs-name">video</span>></span></pre> - </div> - </section> +<span class="hljs-tag"><<span class="hljs-name">video</span> <span class="hljs-attr">id</span>=<span class="hljs-string">'v'</span> <span class="hljs-attr">src</span>=<span class="hljs-string">'foo.webm'</span> <span class="hljs-attr">autoplay</span>></span><span class="hljs-tag"></<span class="hljs-name">video</span>></span></pre></div> + </section> </section> <section id="acknowledgements"> - <!--OddPage--> - <h2 id="x14.-acknowledgments"><span class="secno">14. </span>Acknowledgments</h2> - The editors would like to thank Aaron Colwell, Alex Russell, Anne van Kesteren, Bob Lund, Boris Zbarsky, Chris Pearce, David Singer, Domenic Denicola, Frank Galligan, Glenn Adams, Henri Sivonen, Jer Noble, Joe Steele, Joey Parrish, John Simmons, Mark - Vickers, Pavel Pergamenshchik, Philip Jägenstedt, Pierre Lemieux, Robert O'Callahan, Ryan Sleevi, Steve Heffernan, Steven Robertson, Thomás Inskip, Travis Leithead, and Xiaohan Wang for their contributions to this specification. Thank you also - to the many others who contributed to the specification, including through their participation on the mailing list and in the issues. + <!--OddPage--><h2 id="x14-acknowledgments"><span class="secno">14. </span>Acknowledgments</h2> + The editors would like to thank Aaron Colwell, Alex Russell, Anne van Kesteren, Bob Lund, Boris Zbarsky, Chris Pearce, David Singer, Domenic Denicola, Frank Galligan, Glenn Adams, Henri Sivonen, Jer Noble, Joe Steele, Joey Parrish, John Simmons, Mark Vickers, Pavel Pergamenshchik, Philip Jägenstedt, Pierre Lemieux, Robert O'Callahan, Ryan Sleevi, Steve Heffernan, Steven Robertson, Thomás Inskip, Travis Leithead, and Xiaohan Wang for their contributions to this specification. Thank you also to the many others who contributed to the specification, including through their participation on the mailing list and in the issues. </section> - <section id="references" class="appendix"> - <!--OddPage--> - <h2 id="a.-references"><span class="secno">A. </span>References</h2> - <section id="normative-references"> - <h3 id="a.1-normative-references"><span class="secno">A.1 </span>Normative references</h3> - <dl class="bibliography"><dt id="bib-COOKIES">[COOKIES]</dt> - <dd><a href="https://tools.ietf.org/html/rfc6265"><cite>HTTP State Management Mechanism</cite></a>. A. Barth. IETF. April 2011. Proposed Standard. URL: <a href="https://tools.ietf.org/html/rfc6265">https://tools.ietf.org/html/rfc6265</a> - </dd><dt id="bib-DOM">[DOM]</dt> - <dd><a href="https://dom.spec.whatwg.org/"><cite>DOM Standard</cite></a>. Anne van Kesteren. WHATWG. Living Standard. URL: <a href="https://dom.spec.whatwg.org/">https://dom.spec.whatwg.org/</a> - </dd><dt id="bib-ECMA-262">[ECMA-262]</dt> - <dd><a href="https://tc39.github.io/ecma262/"><cite>ECMAScript Language Specification</cite></a>. Ecma International. URL: <a href="https://tc39.github.io/ecma262/">https://tc39.github.io/ecma262/</a> - </dd><dt id="bib-ENCODING">[ENCODING]</dt> - <dd><a href="https://encoding.spec.whatwg.org/"><cite>Encoding Standard</cite></a>. Anne van Kesteren. WHATWG. Living Standard. URL: <a href="https://encoding.spec.whatwg.org/">https://encoding.spec.whatwg.org/</a> - </dd><dt id="bib-HTML51">[HTML51]</dt> - <dd><a href="https://www.w3.org/TR/html51/"><cite>HTML 5.1 2nd Edition</cite></a>. Steve Faulkner; Arron Eicholz; Travis Leithead; Alex Danilo. W3C. 3 August 2017. W3C Proposed Recommendation. URL: <a href="https://www.w3.org/TR/html51/">https://www.w3.org/TR/html51/</a> - </dd><dt id="bib-MIXED-CONTENT">[MIXED-CONTENT]</dt> - <dd><a href="https://www.w3.org/TR/mixed-content/"><cite>Mixed Content</cite></a>. Mike West. W3C. 2 August 2016. W3C Candidate Recommendation. URL: <a href="https://www.w3.org/TR/mixed-content/">https://www.w3.org/TR/mixed-content/</a> - </dd><dt id="bib-RFC2119">[RFC2119]</dt> - <dd><a href="https://tools.ietf.org/html/rfc2119"><cite>Key words for use in RFCs to Indicate Requirement Levels</cite></a>. S. Bradner. IETF. March 1997. Best Current Practice. URL: <a href="https://tools.ietf.org/html/rfc2119">https://tools.ietf.org/html/rfc2119</a> - </dd><dt id="bib-RFC6381">[RFC6381]</dt> - <dd><a href="https://tools.ietf.org/html/rfc6381"><cite>The 'Codecs' and 'Profiles' Parameters for "Bucket" Media Types</cite></a>. R. Gellens; D. Singer; P. Frojdh. IETF. August 2011. Proposed Standard. URL: <a href="https://tools.ietf.org/html/rfc6381">https://tools.ietf.org/html/rfc6381</a> - </dd><dt id="bib-RFC7517">[RFC7517]</dt> - <dd><a href="https://tools.ietf.org/html/rfc7517"><cite>JSON Web Key (JWK)</cite></a>. M. Jones. IETF. May 2015. Proposed Standard. URL: <a href="https://tools.ietf.org/html/rfc7517">https://tools.ietf.org/html/rfc7517</a> - </dd><dt id="bib-WEBIDL">[WEBIDL]</dt> - <dd><a href="https://heycam.github.io/webidl/"><cite>Web IDL</cite></a>. Cameron McCormack; Boris Zbarsky; Tobie Langel. W3C. 15 December 2016. W3C Editor's Draft. URL: <a href="https://heycam.github.io/webidl/">https://heycam.github.io/webidl/</a> - </dd> - </dl> - </section> - <section id="informative-references"> - <h3 id="a.2-informative-references"><span class="secno">A.2 </span>Informative references</h3> - <dl class="bibliography"><dt id="bib-EME-INITDATA-KEYIDS">[EME-INITDATA-KEYIDS]</dt> - <dd><a href="format-registry/initdata/keyids.html"><cite>"keyids" Initialization Data Format</cite></a>. David Dorwin; Adrian Bateman; Mark Watson; Jerry Smith. W3C. URL: <a href="format-registry/initdata/keyids.html">format-registry/initdata/keyids.html</a> - </dd><dt id="bib-EME-INITDATA-REGISTRY">[EME-INITDATA-REGISTRY]</dt> - <dd><a href="format-registry/initdata/index.html"><cite>Encrypted Media Extensions Initialization Data Format Registry</cite></a>. David Dorwin; Adrian Bateman; Mark Watson. W3C. URL: <a href="format-registry/initdata/index.html">format-registry/initdata/index.html</a> - </dd><dt id="bib-EME-STREAM-REGISTRY">[EME-STREAM-REGISTRY]</dt> - <dd><a href="format-registry/stream/index.html"><cite>Encrypted Media Extensions Stream Format Registry</cite></a>. David Dorwin; Adrian Bateman; Mark Watson. W3C. URL: <a href="format-registry/stream/index.html">format-registry/stream/index.html</a> - </dd><dt id="bib-HTML">[HTML]</dt> - <dd><a href="https://html.spec.whatwg.org/multipage/"><cite>HTML Standard</cite></a>. Anne van Kesteren; Domenic Denicola; Ian Hickson; Philip Jägenstedt; Simon Pieters. WHATWG. Living Standard. URL: <a href="https://html.spec.whatwg.org/multipage/">https://html.spec.whatwg.org/multipage/</a> - </dd><dt id="bib-MEDIA-SOURCE">[MEDIA-SOURCE]</dt> - <dd><a href="https://www.w3.org/TR/media-source/"><cite>Media Source Extensions™</cite></a>. Matthew Wolenetz; Jerry Smith; Mark Watson; Aaron Colwell; Adrian Bateman. W3C. 17 November 2016. W3C Recommendation. URL: <a href="https://www.w3.org/TR/media-source/">https://www.w3.org/TR/media-source/</a> - </dd><dt id="bib-RFC6838">[RFC6838]</dt> - <dd><a href="https://tools.ietf.org/html/rfc6838"><cite>Media Type Specifications and Registration Procedures</cite></a>. N. Freed; J. Klensin; T. Hansen. IETF. January 2013. Best Current Practice. URL: <a href="https://tools.ietf.org/html/rfc6838">https://tools.ietf.org/html/rfc6838</a> - </dd><dt id="bib-RFC7515">[RFC7515]</dt> - <dd><a href="https://tools.ietf.org/html/rfc7515"><cite>JSON Web Signature (JWS)</cite></a>. M. Jones; J. Bradley; N. Sakimura. IETF. May 2015. Proposed Standard. URL: <a href="https://tools.ietf.org/html/rfc7515">https://tools.ietf.org/html/rfc7515</a> - </dd><dt id="bib-SECURE-CONTEXTS">[SECURE-CONTEXTS]</dt> - <dd><a href="https://www.w3.org/TR/secure-contexts/"><cite>Secure Contexts</cite></a>. Mike West. W3C. 15 September 2016. W3C Candidate Recommendation. URL: <a href="https://www.w3.org/TR/secure-contexts/">https://www.w3.org/TR/secure-contexts/</a> - </dd> - </dl> - </section> - </section> - <p role="navigation" id="back-to-top"><a href="#toc"><abbr title="Back to Top">↑</abbr></a></p> - <script src="https://www.w3.org/scripts/TR/2016/fixup.js"></script> -</body> - -</html> \ No newline at end of file +<section id="references" class="appendix"><!--OddPage--><h2 id="a-references"><span class="secno">A. </span>References</h2><section id="normative-references"><h3 id="a-1-normative-references"><span class="secno">A.1 </span>Normative references</h3><dl class="bibliography"><dt id="bib-COOKIES">[COOKIES]</dt><dd><a href="https://tools.ietf.org/html/rfc6265"><cite>HTTP State Management Mechanism</cite></a>. A. Barth. IETF. April 2011. Proposed Standard. URL: <a href="https://tools.ietf.org/html/rfc6265">https://tools.ietf.org/html/rfc6265</a> +</dd><dt id="bib-DOM">[DOM]</dt><dd><a href="https://dom.spec.whatwg.org/"><cite>DOM Standard</cite></a>. Anne van Kesteren. WHATWG. Living Standard. URL: <a href="https://dom.spec.whatwg.org/">https://dom.spec.whatwg.org/</a> +</dd><dt id="bib-ECMA-262">[ECMA-262]</dt><dd><a href="https://tc39.github.io/ecma262/"><cite>ECMAScript Language Specification</cite></a>. Ecma International. URL: <a href="https://tc39.github.io/ecma262/">https://tc39.github.io/ecma262/</a> +</dd><dt id="bib-ENCODING">[ENCODING]</dt><dd><a href="https://encoding.spec.whatwg.org/"><cite>Encoding Standard</cite></a>. Anne van Kesteren. WHATWG. Living Standard. URL: <a href="https://encoding.spec.whatwg.org/">https://encoding.spec.whatwg.org/</a> +</dd><dt id="bib-HTML51">[HTML51]</dt><dd><a href="https://www.w3.org/TR/html51/"><cite>HTML 5.1 2nd Edition</cite></a>. Steve Faulkner; Arron Eicholz; Travis Leithead; Alex Danilo. W3C. 3 October 2017. W3C Recommendation. URL: <a href="https://www.w3.org/TR/html51/">https://www.w3.org/TR/html51/</a> +</dd><dt id="bib-MIXED-CONTENT">[MIXED-CONTENT]</dt><dd><a href="https://www.w3.org/TR/mixed-content/"><cite>Mixed Content</cite></a>. Mike West. W3C. 2 August 2016. W3C Candidate Recommendation. URL: <a href="https://www.w3.org/TR/mixed-content/">https://www.w3.org/TR/mixed-content/</a> +</dd><dt id="bib-RFC2119">[RFC2119]</dt><dd><a href="https://tools.ietf.org/html/rfc2119"><cite>Key words for use in RFCs to Indicate Requirement Levels</cite></a>. S. Bradner. IETF. March 1997. Best Current Practice. URL: <a href="https://tools.ietf.org/html/rfc2119">https://tools.ietf.org/html/rfc2119</a> +</dd><dt id="bib-RFC6381">[RFC6381]</dt><dd><a href="https://tools.ietf.org/html/rfc6381"><cite>The 'Codecs' and 'Profiles' Parameters for "Bucket" Media Types</cite></a>. R. Gellens; D. Singer; P. Frojdh. IETF. August 2011. Proposed Standard. URL: <a href="https://tools.ietf.org/html/rfc6381">https://tools.ietf.org/html/rfc6381</a> +</dd><dt id="bib-RFC7517">[RFC7517]</dt><dd><a href="https://tools.ietf.org/html/rfc7517"><cite>JSON Web Key (JWK)</cite></a>. M. Jones. IETF. May 2015. Proposed Standard. URL: <a href="https://tools.ietf.org/html/rfc7517">https://tools.ietf.org/html/rfc7517</a> +</dd><dt id="bib-WEBIDL">[WEBIDL]</dt><dd><a href="https://heycam.github.io/webidl/"><cite>Web IDL</cite></a>. Cameron McCormack; Boris Zbarsky; Tobie Langel. W3C. 15 December 2016. W3C Editor's Draft. URL: <a href="https://heycam.github.io/webidl/">https://heycam.github.io/webidl/</a> +</dd></dl></section><section id="informative-references"><h3 id="a-2-informative-references"><span class="secno">A.2 </span>Informative references</h3><dl class="bibliography"><dt id="bib-EME-INITDATA-KEYIDS">[EME-INITDATA-KEYIDS]</dt><dd><a href="format-registry/initdata/keyids.html"><cite>"keyids" Initialization Data Format</cite></a>. David Dorwin; Adrian Bateman; Mark Watson; Jerry Smith. W3C. URL: <a href="format-registry/initdata/keyids.html">format-registry/initdata/keyids.html</a> +</dd><dt id="bib-EME-INITDATA-REGISTRY">[EME-INITDATA-REGISTRY]</dt><dd><a href="format-registry/initdata/index.html"><cite>Encrypted Media Extensions Initialization Data Format Registry</cite></a>. David Dorwin; Adrian Bateman; Mark Watson. W3C. URL: <a href="format-registry/initdata/index.html">format-registry/initdata/index.html</a> +</dd><dt id="bib-EME-STREAM-REGISTRY">[EME-STREAM-REGISTRY]</dt><dd><a href="format-registry/stream/index.html"><cite>Encrypted Media Extensions Stream Format Registry</cite></a>. David Dorwin; Adrian Bateman; Mark Watson. W3C. URL: <a href="format-registry/stream/index.html">format-registry/stream/index.html</a> +</dd><dt id="bib-HTML">[HTML]</dt><dd><a href="https://html.spec.whatwg.org/multipage/"><cite>HTML Standard</cite></a>. Anne van Kesteren; Domenic Denicola; Ian Hickson; Philip Jägenstedt; Simon Pieters. WHATWG. Living Standard. URL: <a href="https://html.spec.whatwg.org/multipage/">https://html.spec.whatwg.org/multipage/</a> +</dd><dt id="bib-MEDIA-SOURCE">[MEDIA-SOURCE]</dt><dd><a href="https://www.w3.org/TR/media-source/"><cite>Media Source Extensions™</cite></a>. Matthew Wolenetz; Jerry Smith; Mark Watson; Aaron Colwell; Adrian Bateman. W3C. 17 November 2016. W3C Recommendation. URL: <a href="https://www.w3.org/TR/media-source/">https://www.w3.org/TR/media-source/</a> +</dd><dt id="bib-RFC6838">[RFC6838]</dt><dd><a href="https://tools.ietf.org/html/rfc6838"><cite>Media Type Specifications and Registration Procedures</cite></a>. N. Freed; J. Klensin; T. Hansen. IETF. January 2013. Best Current Practice. URL: <a href="https://tools.ietf.org/html/rfc6838">https://tools.ietf.org/html/rfc6838</a> +</dd><dt id="bib-RFC7515">[RFC7515]</dt><dd><a href="https://tools.ietf.org/html/rfc7515"><cite>JSON Web Signature (JWS)</cite></a>. M. Jones; J. Bradley; N. Sakimura. IETF. May 2015. Proposed Standard. URL: <a href="https://tools.ietf.org/html/rfc7515">https://tools.ietf.org/html/rfc7515</a> +</dd><dt id="bib-SECURE-CONTEXTS">[SECURE-CONTEXTS]</dt><dd><a href="https://www.w3.org/TR/secure-contexts/"><cite>Secure Contexts</cite></a>. Mike West. W3C. 15 September 2016. W3C Candidate Recommendation. URL: <a href="https://www.w3.org/TR/secure-contexts/">https://www.w3.org/TR/secure-contexts/</a> +</dd></dl></section></section><p role="navigation" id="back-to-top"><a href="#toc"><abbr title="Back to Top">↑</abbr></a></p><script src="https://www.w3.org/scripts/TR/2016/fixup.js"></script></body></html> \ No newline at end of file From e8f0dc48bcecded0fc88568772ff6192b2a17a91 Mon Sep 17 00:00:00 2001 From: Joey Parrish <joeyparrish@users.noreply.github.com> Date: Thu, 15 Feb 2018 20:48:56 -0800 Subject: [PATCH 3/4] Update editors to add w3cid --- encrypted-media-respec.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/encrypted-media-respec.html b/encrypted-media-respec.html index 81f8388a..6ea75a78 100644 --- a/encrypted-media-respec.html +++ b/encrypted-media-respec.html @@ -54,7 +54,7 @@ company: "Netflix Inc.", companyURL: "https://www.netflix.com/" }, { name: "Jerry Smith", w3cid: "60176", company: "Microsoft Corporation", companyURL: "https://www.microsoft.com/" }, - { name: "Joey Parrish", + { name: "Joey Parrish", w3cid: "105371", company: "Google Inc.", companyURL: "https://www.google.com/" }, { name: "David Dorwin", note: "Until September 2017", w3cid: "52505", company: "Google Inc.", companyURL: "https://www.google.com/" }, From 9c9d14c6c01e35718d60ea2c1c9439a49ca0cb63 Mon Sep 17 00:00:00 2001 From: Joey Parrish <joeyparrish@google.com> Date: Thu, 15 Feb 2018 21:00:55 -0800 Subject: [PATCH 4/4] Regenerate index.html --- index.html | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/index.html b/index.html index 502461af..319f8c2f 100644 --- a/index.html +++ b/index.html @@ -1,4 +1,4 @@ -<!DOCTYPE html><html lang="en" dir="ltr"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta name="generator" content="ReSpec 18.3.0"><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"><style>/* --- EXAMPLES --- */ +<!DOCTYPE html><html lang="en" dir="ltr"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta name="generator" content="ReSpec 19.6.0"><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"><style>/* --- EXAMPLES --- */ div.example-title { min-width: 7.5em; color: #b9ab2d; @@ -324,7 +324,7 @@ color: #c00; } -.idlImplements a { +.idlImplements a, .idlIncludes a { font-weight: bold; } @@ -813,6 +813,7 @@ }, { "name": "Joey Parrish", + "w3cid": "105371", "company": "Google Inc.", "companyURL": "https://www.google.com/" }, @@ -1852,16 +1853,15 @@ "publisher": "W3C" } }, - "publishISODate": "2017-11-17T00:00:00.000Z", - "generatedSubtitle": "Editor's Draft 17 November 2017" + "publishISODate": "2018-02-16T00:00:00.000Z", + "generatedSubtitle": "Editor's Draft 16 February 2018" }</script><meta name="description" content="This proposal extends HTMLMediaElement [HTML51] providing APIs to control playback of encrypted content."></head> <body aria-busy="false" class="h-entry"><div class="head"> - <p> - <a class="logo" href="https://www.w3.org/"><img width="72" height="48" src="https://www.w3.org/StyleSheets/TR/2016/logos/W3C" alt="W3C"></a> - </p> - <p><!--_hyper: -1132959517;--></p> + <p><a href="https://www.w3.org/" class="logo"> + <img alt="W3C" width="72" height="48" src="https://www.w3.org/StyleSheets/TR/2016/logos/W3C"> + </a><!--_hyper: 1701180376;--></p> <h1 class="title p-name" id="title">Encrypted Media Extensions</h1> - <h2 id="w3c-editor-s-draft-17-november-2017"><abbr title="World Wide Web Consortium">W3C</abbr> Editor's Draft <time class="dt-published" datetime="2017-11-17">17 November 2017</time></h2> + <h2 id="w3c-editor-s-draft-16-february-2018"><abbr title="World Wide Web Consortium">W3C</abbr> Editor's Draft <time class="dt-published" datetime="2018-02-16">16 February 2018</time></h2> <dl> <dt>This version:</dt> <dd><a class="u-url" href="https://w3c.github.io/encrypted-media/">https://w3c.github.io/encrypted-media/</a></dd> @@ -1874,7 +1874,7 @@ <h2 id="w3c-editor-s-draft-17-november-2017"><abbr title="World Wide Web Consort <dt>Editors:</dt> <dd class="p-author h-card vcard" data-editor-id="46379"><span class="p-name fn">Mark Watson</span>, <a class="p-org org h-org h-card" href="https://www.netflix.com/">Netflix Inc.</a></dd> <dd class="p-author h-card vcard" data-editor-id="60176"><span class="p-name fn">Jerry Smith</span>, <a class="p-org org h-org h-card" href="https://www.microsoft.com/">Microsoft Corporation</a></dd> -<dd class="p-author h-card vcard" data-editor-id="60176"><span class="p-name fn">Joey Parrish</span>, <a class="p-org org h-org h-card" href="https://www.google.com/">Google Inc.</a></dd> +<dd class="p-author h-card vcard" data-editor-id="105371"><span class="p-name fn">Joey Parrish</span>, <a class="p-org org h-org h-card" href="https://www.google.com/">Google Inc.</a></dd> <dd class="p-author h-card vcard" data-editor-id="52505"><span class="p-name fn">David Dorwin</span>, <a class="p-org org h-org h-card" href="https://www.google.com/">Google Inc.</a> (Until September 2017)</dd> <dd class="p-author h-card vcard" data-editor-id="42763"><span class="p-name fn">Adrian Bateman</span>, <a class="p-org org h-org h-card" href="https://www.microsoft.com/">Microsoft Corporation</a> (Until May 2014)</dd> @@ -1897,7 +1897,7 @@ <h2 id="w3c-editor-s-draft-17-november-2017"><abbr title="World Wide Web Consort </dl> <p class="copyright"> <a href="https://www.w3.org/Consortium/Legal/ipr-notice#Copyright">Copyright</a> © - 2017 + 2018 <a href="https://www.w3.org/"><abbr title="World Wide Web Consortium">W3C</abbr></a><sup>®</sup> (<a href="https://www.csail.mit.edu/"><abbr title="Massachusetts Institute of Technology">MIT</abbr></a>, @@ -1962,8 +1962,8 @@ <h2 id="w3c-editor-s-draft-17-november-2017"><abbr title="World Wide Web Consort <a href="https://www.w3.org/Consortium/Patent-Policy/#sec-Disclosure">section 6 of the <abbr title="World Wide Web Consortium">W3C</abbr> Patent Policy</a>. </p> - <p>This document is governed by the <a id="w3c_process_revision" href="https://www.w3.org/2017/Process-20170301/">1 March 2017 <abbr title="World Wide Web Consortium">W3C</abbr> Process Document</a>. - </p> + <p>This document is governed by the <a id="w3c_process_revision" href="https://www.w3.org/2018/Process-20180201/">1 February 2018 <abbr title="World Wide Web Consortium">W3C</abbr> Process Document</a>. + </p> </section><nav id="toc"><h2 class="introductory" id="table-of-contents">Table of Contents</h2><ol class="toc"><li class="tocline"><a href="#introduction" class="tocxref"><span class="secno">1. </span>Introduction</a></li><li class="tocline"><a href="#definitions" class="tocxref"><span class="secno">2. </span>Definitions</a></li><li class="tocline"><a href="#obtaining-access-to-key-systems" class="tocxref"><span class="secno">3. </span>Obtaining Access to Key Systems</a><ol class="toc"><li class="tocline"><a href="#navigator-extension-requestmediakeysystemaccess" class="tocxref"><span class="secno">3.1 </span><span data-dfn-type="dfn" data-idl="" data-title="Navigator" data-dfn-for=""><code>Navigator</code></span> Extension: <code>requestMediaKeySystemAccess()</code></a><ol class="toc"><li class="tocline"><a href="#algorithms" class="tocxref"><span class="secno">3.1.1 </span>Algorithms</a><ol class="toc"><li class="tocline"><a href="#get-supported-configuration" class="tocxref"><span class="secno">3.1.1.1 </span>Get Supported Configuration</a></li><li class="tocline"><a href="#get-supported-configuration-and-consent" class="tocxref"><span class="secno">3.1.1.2 </span>Get Supported Configuration and Consent</a></li><li class="tocline"><a href="#get-supported-capabilities-for-audio-video-type" class="tocxref"><span class="secno">3.1.1.3 </span>Get Supported Capabilities for Audio/Video Type</a></li><li class="tocline"><a href="#get-consent-status" class="tocxref"><span class="secno">3.1.1.4 </span>Get Consent Status</a></li></ol></li></ol></li><li class="tocline"><a href="#mediakeysystemconfiguration-dictionary" class="tocxref"><span class="secno">3.2 </span><span class="formerLink" data-link-type="dfn"><code>MediaKeySystemConfiguration</code></span> dictionary</a></li><li class="tocline"><a href="#mediakeysystemmediacapability-dictionary" class="tocxref"><span class="secno">3.3 </span><span data-dfn-type="dfn" data-idl="" data-title="MediaKeySystemMediaCapability" data-dfn-for=""><code>MediaKeySystemMediaCapability</code></span> dictionary</a></li></ol></li><li class="tocline"><a href="#mediakeysystemaccess-interface" class="tocxref"><span class="secno">4. </span><span data-dfn-type="dfn" data-idl="" data-title="MediaKeySystemAccess" data-dfn-for=""><code>MediaKeySystemAccess</code></span> Interface</a></li><li class="tocline"><a href="#mediakeys-interface" class="tocxref"><span class="secno">5. </span><span data-dfn-type="dfn">MediaKeys</span> Interface</a><ol class="toc"><li class="tocline"><a href="#algorithms-0" class="tocxref"><span class="secno">5.1 </span>Algorithms</a><ol class="toc"><li class="tocline"><a href="#is-persistent-session-type" class="tocxref"><span class="secno">5.1.1 </span>Is persistent session type?</a></li><li class="tocline"><a href="#cdm-unavailable" class="tocxref"><span class="secno">5.1.2 </span>CDM Unavailable</a></li></ol></li><li class="tocline"><a href="#media-keys-storage" class="tocxref"><span class="secno">5.2 </span>Storage and Persistence</a></li></ol></li><li class="tocline"><a href="#mediakeysession-interface" class="tocxref"><span class="secno">6. </span><span data-dfn-type="dfn" data-idl="" data-title="MediaKeySession" data-dfn-for=""><code>MediaKeySession</code></span> Interface</a><ol class="toc"><li class="tocline"><a href="#mediakeystatusmap-interface" class="tocxref"><span class="secno">6.1 </span><span data-dfn-type="dfn" data-idl="" data-title="MediaKeyStatusMap" data-dfn-for=""><code>MediaKeyStatusMap</code></span> Interface</a></li><li class="tocline"><a href="#mediakeymessageevent" class="tocxref"><span class="secno">6.2 </span><span class="formerLink" data-link-type="dfn"><code>MediaKeyMessageEvent</code></span></a><ol class="toc"><li class="tocline"><a href="#mediakeymessageeventinit" class="tocxref"><span class="secno">6.2.1 </span><span data-dfn-type="dfn" data-idl="" data-title="MediaKeyMessageEventInit" data-dfn-for=""><code>MediaKeyMessageEventInit</code></span></a></li></ol></li><li class="tocline"><a href="#mediakeysession-events" class="tocxref"><span class="secno">6.3 </span>Event Summary</a></li><li class="tocline"><a href="#mediakeysession-algorithms" class="tocxref"><span class="secno">6.4 </span>Algorithms</a><ol class="toc"><li class="tocline"><a href="#queue-message" class="tocxref"><span class="secno">6.4.1 </span>Queue a "message" Event</a></li><li class="tocline"><a href="#update-key-statuses" class="tocxref"><span class="secno">6.4.2 </span>Update Key Statuses</a></li><li class="tocline"><a href="#update-expiration" class="tocxref"><span class="secno">6.4.3 </span>Update Expiration</a></li><li class="tocline"><a href="#session-closed" class="tocxref"><span class="secno">6.4.4 </span>Session Closed</a></li><li class="tocline"><a href="#media-key-session-destroyed" class="tocxref"><span class="secno">6.4.5 </span>MediaKeySession Destroyed</a></li><li class="tocline"><a href="#monitor-cdm" class="tocxref"><span class="secno">6.4.6 </span>Monitor for CDM State Changes</a></li></ol></li><li class="tocline"><a href="#exceptions" class="tocxref"><span class="secno">6.5 </span>Exceptions</a></li><li class="tocline"><a href="#session-storage" class="tocxref"><span class="secno">6.6 </span>Session Storage and Persistence</a></li></ol></li><li class="tocline"><a href="#htmlmediaelement-extensions" class="tocxref"><span class="secno">7. </span><span data-dfn-type="dfn" data-idl="" data-title="HTMLMediaElement" data-dfn-for=""><code>HTMLMediaElement</code></span> Extensions</a><ol class="toc"><li class="tocline"><a href="#mediaencryptedevent" class="tocxref"><span class="secno">7.1 </span><span class="formerLink" data-link-type="dfn"><code>MediaEncryptedEvent</code></span></a><ol class="toc"><li class="tocline"><a href="#mediaencryptedeventinit" class="tocxref"><span class="secno">7.1.1 </span><span data-dfn-type="dfn" data-idl="" data-title="MediaEncryptedEventInit" data-dfn-for=""><code>MediaEncryptedEventInit</code></span></a></li></ol></li><li class="tocline"><a href="#htmlmediaelement-events" class="tocxref"><span class="secno">7.2 </span>Event Summary</a></li><li class="tocline"><a href="#htmlmediaelement-algorithms" class="tocxref"><span class="secno">7.3 </span>Algorithms</a><ol class="toc"><li class="tocline"><a href="#media-may-contain-encrypted-blocks" class="tocxref"><span class="secno">7.3.1 </span>Media Data May Contain Encrypted Blocks</a></li><li class="tocline"><a href="#initdata-encountered" class="tocxref"><span class="secno">7.3.2 </span>Initialization Data Encountered</a></li><li class="tocline"><a href="#encrypted-block-encountered" class="tocxref"><span class="secno">7.3.3 </span>Encrypted Block Encountered</a></li><li class="tocline"><a href="#attempt-to-decrypt" class="tocxref"><span class="secno">7.3.4 </span>Attempt to Decrypt</a></li><li class="tocline"><a href="#wait-for-key" class="tocxref"><span class="secno">7.3.5 </span>Wait for Key</a></li><li class="tocline"><a href="#resume-playback" class="tocxref"><span class="secno">7.3.6 </span>Attempt to Resume Playback If Necessary</a></li></ol></li><li class="tocline"><a href="#media-element-restrictions" class="tocxref"><span class="secno">7.4 </span>Media Element Restrictions</a></li></ol></li><li class="tocline"><a href="#implementation-requirements" class="tocxref"><span class="secno">8. </span>Implementation Requirements</a><ol class="toc"><li class="tocline"><a href="#cdm-constraint-requirements" class="tocxref"><span class="secno">8.1 </span>CDM Constraints</a></li><li class="tocline"><a href="#messaging-requirements" class="tocxref"><span class="secno">8.2 </span>Messages and Communication</a></li><li class="tocline"><a href="#persistent-state-requirements" class="tocxref"><span class="secno">8.3 </span>Persistent Data</a><ol class="toc"><li class="tocline"><a href="#use-origin-specific-key-system-storage" class="tocxref"><span class="secno">8.3.1 </span>Use origin-specific and browsing profile-specific Key System storage</a></li><li class="tocline"><a href="#allow-persistent-data-cleared" class="tocxref"><span class="secno">8.3.2 </span>Allow Persistent Data to Be Cleared</a></li><li class="tocline"><a href="#encrypt-or-obfuscate-persistent-data" class="tocxref"><span class="secno">8.3.3 </span>Encrypt or obfuscate Persistent Data</a></li></ol></li><li class="tocline"><a href="#exposed-value-requirements" class="tocxref"><span class="secno">8.4 </span>Values Exposed to the Application</a><ol class="toc"><li class="tocline"><a href="#per-origin-per-profile-values" class="tocxref"><span class="secno">8.4.1 </span>Use Per-Origin Per-Profile Values</a></li><li class="tocline"><a href="#allow-values-to-be-cleared" class="tocxref"><span class="secno">8.4.2 </span>Allow Values to Be Cleared</a></li></ol></li><li class="tocline"><a href="#identifier-requirements" class="tocxref"><span class="secno">8.5 </span>Identifiers</a><ol class="toc"><li class="tocline"><a href="#limit-or-avoid-use-of-distinctive-identifiers-and-permanent-identifiers" class="tocxref"><span class="secno">8.5.1 </span>Limit or Avoid use of Distinctive Identifiers and Permanent Identifiers</a></li><li class="tocline"><a href="#encrypt-identifiers" class="tocxref"><span class="secno">8.5.2 </span>Encrypt Identifiers</a></li><li class="tocline"><a href="#per-origin-per-profile-identifiers" class="tocxref"><span class="secno">8.5.3 </span>Use Per-Origin Per-Profile Identifiers</a></li><li class="tocline"><a href="#non-associable-identifiers" class="tocxref"><span class="secno">8.5.4 </span>Use Non-Associable Identifiers</a></li><li class="tocline"><a href="#allow-identifiers-cleared" class="tocxref"><span class="secno">8.5.5 </span>Allow Identifiers to Be Cleared</a></li></ol></li><li class="tocline"><a href="#individualization" class="tocxref"><span class="secno">8.6 </span>Individualization</a><ol class="toc"><li class="tocline"><a href="#direct-individualization" class="tocxref"><span class="secno">8.6.1 </span>Direct Individualization</a></li><li class="tocline"><a href="#app-assisted-individualization" class="tocxref"><span class="secno">8.6.2 </span>App-Assisted Individualization</a></li></ol></li><li class="tocline"><a href="#support-multiple-keys" class="tocxref"><span class="secno">8.7 </span>Support Multiple Keys</a></li><li class="tocline"><a href="#initialization-data-type-support-requirements" class="tocxref"><span class="secno">8.8 </span>Initialization Data Type Support</a><ol class="toc"><li class="tocline"><a href="#licenses-generated-are-independent-of-content-type" class="tocxref"><span class="secno">8.8.1 </span>Licenses Generated are Independent of Content Type</a></li><li class="tocline"><a href="#support-extraction-from-media-data" class="tocxref"><span class="secno">8.8.2 </span>Support Extraction From Media Data</a></li></ol></li><li class="tocline"><a href="#media-requirements" class="tocxref"><span class="secno">8.9 </span>Supported Media</a><ol class="toc"><li class="tocline"><a href="#unencrypted-container" class="tocxref"><span class="secno">8.9.1 </span>Unencrypted Container</a></li><li class="tocline"><a href="#interoperably-encrypted" class="tocxref"><span class="secno">8.9.2 </span>Interoperably Encrypted</a></li><li class="tocline"><a href="#unencrypted-in-band-support-content" class="tocxref"><span class="secno">8.9.3 </span>Unencrypted In-band Support Content</a></li></ol></li></ol></li><li class="tocline"><a href="#common-key-systems" class="tocxref"><span class="secno">9. </span>Common Key Systems</a><ol class="toc"><li class="tocline"><a href="#clear-key" class="tocxref"><span class="secno">9.1 </span>Clear Key</a><ol class="toc"><li class="tocline"><a href="#clear-key-capabilities" class="tocxref"><span class="secno">9.1.1 </span>Capabilities</a></li><li class="tocline"><a href="#clear-key-behavior" class="tocxref"><span class="secno">9.1.2 </span>Behavior</a></li><li class="tocline"><a href="#clear-key-request-format" class="tocxref"><span class="secno">9.1.3 </span>License Request Format</a><ol class="toc"><li class="tocline"><a href="#clear-key-request-format-example" class="tocxref"><span class="secno">9.1.3.1 </span>Example</a></li></ol></li><li class="tocline"><a href="#clear-key-license-format" class="tocxref"><span class="secno">9.1.4 </span>License Format</a><ol class="toc"><li class="tocline"><a href="#clear-key-license-format-example" class="tocxref"><span class="secno">9.1.4.1 </span>Example</a></li></ol></li><li class="tocline"><a href="#clear-key-release-format" class="tocxref"><span class="secno">9.1.5 </span>License Release Format</a><ol class="toc"><li class="tocline"><a href="#clear-key-release-format-example-1" class="tocxref"><span class="secno">9.1.5.1 </span>Example message reflecting a <span def-id="record-of-license-destruction" class="formerLink"></span></a></li><li class="tocline"><a href="#clear-key-release-format-example-2" class="tocxref"><span class="secno">9.1.5.2 </span>Example message reflecting a <span def-id="record-of-key-usage" class="formerLink"></span></a></li></ol></li><li class="tocline"><a href="#clear-key-release-ack-format" class="tocxref"><span class="secno">9.1.6 </span>License Release Acknowledgement Format</a><ol class="toc"><li class="tocline"><a href="#clear-key-release-ack-format-example" class="tocxref"><span class="secno">9.1.6.1 </span>Example</a></li></ol></li><li class="tocline"><a href="#using-base64url" class="tocxref"><span class="secno">9.1.7 </span>Using base64url</a></li></ol></li></ol></li><li class="tocline"><a href="#security" class="tocxref"><span class="secno">10. </span>Security</a><ol class="toc"><li class="tocline"><a href="#input-data-security" class="tocxref"><span class="secno">10.1 </span>Input Data Attacks and Vulnerabilities</a></li><li class="tocline"><a href="#cdm-security" class="tocxref"><span class="secno">10.2 </span>CDM Attacks and Vulnerabilities</a></li><li class="tocline"><a href="#network-attacks" class="tocxref"><span class="secno">10.3 </span>Network Attacks</a><ol class="toc"><li class="tocline"><a href="#potential-attacks" class="tocxref"><span class="secno">10.3.1 </span>Potential Attacks</a></li><li class="tocline"><a href="#mitigations" class="tocxref"><span class="secno">10.3.2 </span>Mitigations</a></li></ol></li><li class="tocline"><a href="#iframe-attacks" class="tocxref"><span class="secno">10.4 </span><code>iframe</code> Attacks</a><ol class="toc"><li class="tocline"><a href="#potential-attacks-0" class="tocxref"><span class="secno">10.4.1 </span>Potential Attacks</a></li><li class="tocline"><a href="#mitigations-0" class="tocxref"><span class="secno">10.4.2 </span>Mitigations</a></li></ol></li><li class="tocline"><a href="#cross-directory-attacks" class="tocxref"><span class="secno">10.5 </span>Cross-Directory Attacks</a></li></ol></li><li class="tocline"><a href="#privacy" class="tocxref"><span class="secno">11. </span>Privacy</a><ol class="toc"><li class="tocline"><a href="#privacy-disclosure" class="tocxref"><span class="secno">11.1 </span>Information Disclosed by EME and Key Systems</a></li><li class="tocline"><a href="#privacy-fingerprinting" class="tocxref"><span class="secno">11.2 </span>Fingerprinting</a></li><li class="tocline"><a href="#privacy-leakage" class="tocxref"><span class="secno">11.3 </span>Information Leakage</a><ol class="toc"><li class="tocline"><a href="#concerns" class="tocxref"><span class="secno">11.3.1 </span>Concerns</a></li><li class="tocline"><a href="#mitigations-1" class="tocxref"><span class="secno">11.3.2 </span>Mitigations</a></li></ol></li><li class="tocline"><a href="#user-tracking" class="tocxref"><span class="secno">11.4 </span>User Tracking</a><ol class="toc"><li class="tocline"><a href="#concerns-0" class="tocxref"><span class="secno">11.4.1 </span>Concerns</a></li><li class="tocline"><a href="#mitigations-2" class="tocxref"><span class="secno">11.4.2 </span>Mitigations</a></li></ol></li><li class="tocline"><a href="#privacy-storedinfo" class="tocxref"><span class="secno">11.5 </span>Information Stored on User Devices</a><ol class="toc"><li class="tocline"><a href="#concerns-1" class="tocxref"><span class="secno">11.5.1 </span>Concerns</a></li><li class="tocline"><a href="#mitigations-3" class="tocxref"><span class="secno">11.5.2 </span>Mitigations</a></li></ol></li><li class="tocline"><a href="#incomplete-clearing" class="tocxref"><span class="secno">11.6 </span>Incomplete Clearing of Data</a><ol class="toc"><li class="tocline"><a href="#concerns-2" class="tocxref"><span class="secno">11.6.1 </span>Concerns</a></li><li class="tocline"><a href="#mitigations-4" class="tocxref"><span class="secno">11.6.2 </span>Mitigations</a></li></ol></li><li class="tocline"><a href="#private-browsing" class="tocxref"><span class="secno">11.7 </span>Private Browsing Modes</a></li><li class="tocline"><a href="#privacy-secureorigin" class="tocxref"><span class="secno">11.8 </span>Secure Origin and Transport</a></li></ol></li><li class="tocline"><a href="#conformance" class="tocxref"><span class="secno">12. </span>Conformance</a></li><li class="tocline"><a href="#examples" class="tocxref"><span class="secno">13. </span>Examples</a><ol class="toc"><li class="tocline"><a href="#example-source-and-key-known" class="tocxref"><span class="secno">13.1 </span>Source and Key Known at Page Load (Clear Key)</a></li><li class="tocline"><a href="#example-selecting-key-system" class="tocxref"><span class="secno">13.2 </span>Selecting a Supported Key System and Using Initialization Data from the "encrypted" Event</a></li><li class="tocline"><a href="#example-mediakeys-before-source" class="tocxref"><span class="secno">13.3 </span>Create MediaKeys Before Loading Media</a></li><li class="tocline"><a href="#example-using-all-events" class="tocxref"><span class="secno">13.4 </span>Using All Events</a></li><li class="tocline"><a href="#example-stored-license" class="tocxref"><span class="secno">13.5 </span>Stored License</a></li></ol></li><li class="tocline"><a href="#acknowledgements" class="tocxref"><span class="secno">14. </span>Acknowledgments</a></li><li class="tocline"><a href="#references" class="tocxref"><span class="secno">A. </span>References</a><ol class="toc"><li class="tocline"><a href="#normative-references" class="tocxref"><span class="secno">A.1 </span>Normative references</a></li><li class="tocline"><a href="#informative-references" class="tocxref"><span class="secno">A.2 </span>Informative references</a></li></ol></li></ol></nav> @@ -5607,7 +5607,7 @@ <h4 id="x9-1-3-license-request-format"><span class="secno">9.1.3 </span>License <section id="clear-key-request-format-example" class="informative"> <h5 id="x9-1-3-1-example"><span class="secno">9.1.3.1 </span>Example</h5><p><em>This section is non-normative.</em></p> <p>The following example is a license request for a temporary license for two key IDs. (Line breaks are for readability only.)</p> - <div class="example"><div class="example-title marker"><span>Example 1</span></div><pre class="highlight hljs json" aria-busy="false" aria-live="polite">{ + <div class="example"><div class="example-title marker"><span>Example 1</span></div><pre class="highlight hljs json" aria-busy="false">{ <span class="hljs-attr">"kids"</span>: [ <span class="hljs-string">"LwVHf8JLtPrv2GUXFW2v_A"</span>, @@ -5646,7 +5646,7 @@ <h4 id="x9-1-4-license-format"><span class="secno">9.1.4 </span>License Format</ <section id="clear-key-license-format-example" class="informative"> <h5 id="x9-1-4-1-example"><span class="secno">9.1.4.1 </span>Example</h5><p><em>This section is non-normative.</em></p> <p>The following example is a JWK Set containing a single symmetric key. (Line breaks are for readability only.)</p> - <div class="example"><div class="example-title marker"><span>Example 2</span></div><pre class="highlight hljs javascript" aria-busy="false" aria-live="polite">{ + <div class="example"><div class="example-title marker"><span>Example 2</span></div><pre class="highlight hljs javascript" aria-busy="false">{ <span class="hljs-string">"keys"</span>: [{ <span class="hljs-string">"kty"</span>:<span class="hljs-string">"oct"</span>, @@ -5690,7 +5690,7 @@ <h5 id="x9-1-5-1-example-message-reflecting-a"><span class="secno">9.1.5.1 </spa The following example is a license release for a <code><a href="#idl-def-MediaKeySessionType.persistent-license">"persistent-license"</a></code> session that contained two keys. (Line breaks are for readability only.) </p> - <div class="example"><div class="example-title marker"><span>Example 3</span></div><pre class="highlight hljs json" aria-busy="false" aria-live="polite">{ + <div class="example"><div class="example-title marker"><span>Example 3</span></div><pre class="highlight hljs json" aria-busy="false">{ <span class="hljs-attr">"kids"</span>: [ <span class="hljs-string">"LwVHf8JLtPrv2GUXFW2v_A"</span>, <span class="hljs-string">"0DdtU9od-Bh5L3xbv0Xf_A"</span> ] }</pre></div> </section> @@ -5701,7 +5701,7 @@ <h5 id="x9-1-5-2-example-message-reflecting-a"><span class="secno">9.1.5.2 </spa The following example is a license release for a <code><a href="#idl-def-MediaKeySessionType.persistent-usage-record">"persistent-usage-record"</a></code> session that contained two keys. (Line breaks are for readability only.) </p> - <div class="example"><div class="example-title marker"><span>Example 4</span></div><pre class="highlight hljs json" aria-busy="false" aria-live="polite">{ + <div class="example"><div class="example-title marker"><span>Example 4</span></div><pre class="highlight hljs json" aria-busy="false">{ <span class="hljs-attr">"kids"</span>: [ <span class="hljs-string">"LwVHf8JLtPrv2GUXFW2v_A"</span>, <span class="hljs-string">"0DdtU9od-Bh5L3xbv0Xf_A"</span> ], <span class="hljs-attr">"firstTime"</span> : <span class="hljs-number">1430425323757</span>, <span class="hljs-attr">"latestTime"</span> : <span class="hljs-number">1430425383757</span> @@ -5726,7 +5726,7 @@ <h4 id="x9-1-6-license-release-acknowledgement-format"><span class="secno">9.1.6 <section id="clear-key-release-ack-format-example" class="informative"> <h5 id="x9-1-6-1-example"><span class="secno">9.1.6.1 </span>Example</h5><p><em>This section is non-normative.</em></p> <p>The following example is a license request for a temporary license for two key IDs. (Line breaks are for readability only.)</p> - <div class="example"><div class="example-title marker"><span>Example 5</span></div><pre class="highlight hljs json" aria-busy="false" aria-live="polite">{ + <div class="example"><div class="example-title marker"><span>Example 5</span></div><pre class="highlight hljs json" aria-busy="false">{ <span class="hljs-attr">"kids"</span>: [ <span class="hljs-string">"LwVHf8JLtPrv2GUXFW2v_A"</span>, @@ -6221,7 +6221,7 @@ <h3 id="x13-1-source-and-key-known-at-page-load-clear-key"><span class="secno">1 <p class="exampledescription">In this simple example, the source file and <a href="#clear-key">clear-text license</a> are hard-coded in the page. Only one session will ever be created.</p> - <div class="example"><div class="example-title marker"><span>Example 6</span></div><pre class="highlight hljs xml" aria-busy="false" aria-live="polite"><span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="javascript"> + <div class="example"><div class="example-title marker"><span>Example 6</span></div><pre class="highlight hljs xml" aria-busy="false"><span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="javascript"> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">onLoad</span>(<span class="hljs-params"></span>) </span>{ <span class="hljs-keyword">var</span> video = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'video'</span>); @@ -6280,7 +6280,7 @@ <h3 id="x13-2-selecting-a-supported-key-system-and-using-initialization-data-fro One of the supported key systems uses a serverCertificate, which is provided proactively. </p> - <div class="example"><div class="example-title marker"><span>Example 7</span></div><pre class="highlight hljs xml" aria-busy="false" aria-live="polite"><span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="javascript"> + <div class="example"><div class="example-title marker"><span>Example 7</span></div><pre class="highlight hljs xml" aria-busy="false"><span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="javascript"> <span class="hljs-keyword">var</span> licenseUrl; <span class="hljs-keyword">var</span> serverCertificate; @@ -6419,7 +6419,7 @@ <h3 id="x13-3-create-mediakeys-before-loading-media"><span class="secno">13.3 </ This example does the latter. </p> - <div class="example"><div class="example-title marker"><span>Example 8</span></div><pre class="highlight hljs xml" aria-busy="false" aria-live="polite"><span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="javascript"> + <div class="example"><div class="example-title marker"><span>Example 8</span></div><pre class="highlight hljs xml" aria-busy="false"><span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="javascript"> <span class="hljs-keyword">var</span> licenseUrl; <span class="hljs-keyword">var</span> serverCertificate; <span class="hljs-keyword">var</span> mediaKeys; @@ -6455,7 +6455,7 @@ <h3 id="x13-4-using-all-events"><span class="secno">13.4 </span>Using All Events <p class="exampledescription">This is a more complete example showing all events being used.</p> <p class="exampledescription">Note that <code>handleMessage()</code> could be called multiple times, including in response to the <code><a href="#dom-mediakeysession-update">update()</a></code> call if multiple round trips are required and for any other reason the Key System might need to send a message.</p> - <div class="example"><div class="example-title marker"><span>Example 9</span></div><pre class="highlight hljs xml" aria-busy="false" aria-live="polite"><span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="javascript"> + <div class="example"><div class="example-title marker"><span>Example 9</span></div><pre class="highlight hljs xml" aria-busy="false"><span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="javascript"> <span class="hljs-keyword">var</span> licenseUrl; <span class="hljs-keyword">var</span> serverCertificate; <span class="hljs-keyword">var</span> mediaKeys; @@ -6546,7 +6546,7 @@ <h3 id="x13-4-using-all-events"><span class="secno">13.4 </span>Using All Events <h3 id="x13-5-stored-license"><span class="secno">13.5 </span>Stored License</h3> <p class="exampledescription">This example requests a persistent license for future use and stores it. It also provides functions for later retrieving the license and for destroying it.</p> - <div class="example"><div class="example-title marker"><span>Example 10</span></div><pre class="highlight hljs xml" aria-busy="false" aria-live="polite"><span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="javascript"> + <div class="example"><div class="example-title marker"><span>Example 10</span></div><pre class="highlight hljs xml" aria-busy="false"><span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="javascript"> <span class="hljs-keyword">var</span> licenseUrl; <span class="hljs-keyword">var</span> serverCertificate; <span class="hljs-keyword">var</span> mediaKeys;