Skip to content

Commit

Permalink
Add getStatusForPolicy (#515)
Browse files Browse the repository at this point in the history
* Add getStatusForPolicy

* Fix return type and non-existing anchors

* Add pre-fetch example
  • Loading branch information
gregwfreedman authored Nov 14, 2023
1 parent 4089d85 commit 0b2d5e3
Show file tree
Hide file tree
Showing 2 changed files with 127 additions and 12 deletions.
128 changes: 118 additions & 10 deletions encrypted-media-respec.html
Original file line number Diff line number Diff line change
Expand Up @@ -1564,14 +1564,21 @@ <h2><dfn>MediaKeys</dfn> Interface</h2>
</td></tr>
</tbody></table></div>

<div><pre class="idl">[Exposed=Window, SecureContext] interface MediaKeys {
MediaKeySession createSession (optional MediaKeySessionType sessionType = "temporary");
Promise&lt;boolean&gt; setServerCertificate (BufferSource serverCertificate);
};</pre><section><h2>Methods</h2><dl class="methods" data-dfn-for="MediaKeys" data-link-for="MediaKeys"><dt><dfn><code>createSession</code></dfn></dt><dd>
<div>
<pre class="idl">
[Exposed=Window, SecureContext] interface MediaKeys {
MediaKeySession createSession (optional MediaKeySessionType sessionType = "temporary");
Promise&lt;MediaKeyStatus&gt; getStatusForPolicy (optional MediaKeysPolicy policy = {});
Promise&lt;boolean&gt; setServerCertificate (BufferSource serverCertificate);
};
</pre>

<section id="">
<h2>Methods</h2>
<dl class="methods" data-dfn-for="MediaKeys" data-link-for="MediaKeys">
<dt><dfn><code>createSession</code></dfn></dt><dd>
<p>Returns a new <a>MediaKeySession</a> object.</p>



<ol class="method-algorithm">
<li><p>If this object's <var>supported session types</var> value does not contain <var>sessionType</var>, <a def-id="throw"></a> [[WEBIDL]] a <a def-id="NotSupportedError"></a>.</p>
<p class="note"><var>sessionType</var> values for which the <a def-id="is-persistent-session-type-algorithm"></a> algorithm returns <code>true</code> will fail if this object's <var>persistent state allowed</var> value is <code>false</code>.</p>
Expand Down Expand Up @@ -1604,15 +1611,95 @@ <h2><dfn>MediaKeys</dfn> Interface</h2>
</ol>
<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></dd><dt><dfn><code>setServerCertificate</code></dfn></dt><dd>
</td></tr></tbody></table><div><em>Return type: </em><code>MediaKeySession</code></div></dd>
<dt><dfn><code>getStatusForPolicy</code></dfn></dt>
<dd>
<p id="status-for-policy">Returns the <a>MediaKeyStatus</a> for a given <a>MediaKeysPolicy</a>.</p>

<ol class="method-algorithm">
<li>If <var>policy</var> has no <a def-id="present-dictionary-member"></a> <a def-id="dictionary-member">members</a>, return a promise rejected with a newly created <a def-id="TypeError"></a>.</li>
<li><p>Let <var>promise</var> be a new promise.</p>
<ol>
<li><p>For each <a def-id="dictionary-member">member</a> of <var>policy</var>, run the following steps:</p>
<ol>
<li><p>If the CDM cannot determine the <a>MediaKeyStatus</a> for <a def-id="dictionary-member">member</a>, then reject <var>promise</var> with <a def-id="NotSupportedError"></a> and abort these steps.</p></li>
</ol>
</li>
<li><p>For each <a def-id="dictionary-member">member</a> of <var>policy</var>, run the following steps:</p>
<ol>
<li><p>If the CDM would block presentation of decrypted media data for <a def-id="dictionary-member">member</a>, then resolve <var>promise</var> with <a def-id="status-output-restricted"></a>.</p></li>
</ol>
</li>
<li><p>Resolve <var>promise</var> with <a def-id="status-usable"></a>.</p></li>
</ol>
</li>
<li><p>Return <var>promise</var>.</p></li>
</ol>
<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">policy</td>
<td class="prmType">
<code>MediaKeysPolicy</code>
</td>
<td class="prmNullFalse">
<span role="img" aria-label="False"></span>
</td>
<td class="prmOptFalse">
<span role="img" aria-label="True"></span>
</td>
<td class="prmDesc">A set of policy requirements</td>
</tr>
</tbody>
</table>
<div><em>Return type: </em><code>Promise&lt;MediaKeyStatus&gt;</code></div>

<div>
<pre class="idl">
dictionary MediaKeysPolicy {
HDCPVersion minHdcpVersion;
};
</pre>
<p>The <a>MediaKeysPolicy</a> dictionary is an object consisting of only optional properties. Each property represents a
policy requirement. A policy is said to be fulfilled if the CDM would allow presentation of decrypted
media data based on all of the requirements.</p>
</div>
<div>
<pre class="idl">
enum HDCPVersion {
"1.0",
"1.1",
"1.2",
"1.3",
"1.4",
"2.0",
"2.1",
"2.2",
"2.3",
};
</pre>
<p>The HDCP Policy is represented by <a def-id="dom-mediakeyspolicy-minhdcpversion">minHdcpVersion</a>. When set, the policy requirement will be fulfilled if the system
supports <a def-id="dom-mediakeyspolicy-minhdcpversion">minHdcpVersion</a> on the current display.</p>
<p class="note">The determination of HDCP status should be done in the same way that the CDM would enforce such a
restriction during playback. In this way, application developers can get a reasonable hint to allow them to
optimize what content they fetch to start playback.</p>
</div>
</dd>

<dt><dfn><code>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 MUST also support requesting the certificate from the server via the <a def-id="queue-message-algorithm"></a> algorithm.</p>
<p class="note">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>



<ol class="method-algorithm">
<li><p>If the <a def-id="keysystem"></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 <a def-id="TypeError"></a>.</p></li>
Expand All @@ -1639,7 +1726,11 @@ <h2><dfn>MediaKeys</dfn> Interface</h2>
The server certificate.
The contents are <a def-id="keysystem"></a>-specific.
It MUST NOT contain executable code.
</td></tr></tbody></table><div><em>Return type: </em><code>Promise&lt;boolean&gt;</code></div></dd></dl></section></div>
</td></tr></tbody></table><div><em>Return type: </em><code>Promise&lt;boolean&gt;</code></div>
</dd>
</dl>
</section>
</div>

<section id="">
<h3>Algorithms</h3>
Expand Down Expand Up @@ -4755,6 +4846,23 @@ <h3>Stored License</h3>
&lt;video id='v' src='foo.webm' autoplay&gt;&lt;/video&gt;
</pre>
</section>

<section id="example-getStatusForPolicy">
<h3>Pre-fetch Media With HDCP Policy</h3>
<p class="exampledescription">If some media will have an HDCP policy in the license, an application can check for that version before pre-fetching.</p>

<pre class="example highlight">
const status = await video.mediaKeys.getStatusForPolicy({
minHdcpVersion: '1.4'
});

if (status === 'usable') {
// Pre-fetch HD content.
} else { // 'output-restricted'
// Pre-fetch SD content.
}
</pre>
</section>
</section>

<section id="acknowledgements">
Expand Down
11 changes: 9 additions & 2 deletions encrypted-media.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
var HTML_spec_url = "https://html.spec.whatwg.org/multipage/media.html";
var DOM_spec_url = "https://dom.spec.whatwg.org/";
var IDL_spec_url = "https://webidl.spec.whatwg.org/";
var INFRA_spec_url = "https://infra.spec.whatwg.org/";

function url_helper(doc, url) {
if (url[0] == "#" && doc.emeDefGroupName != window.respecConfig.emeDefGroupName) {
Expand Down Expand Up @@ -75,6 +76,10 @@
df.appendChild($("<code/>").wrapInner($("<a/>").attr({href: DOM_spec_url + "#" + id}).text(text))[0]);
}

function infra_helper(doc, df, id, text) {
link_helper(doc, df, INFRA_spec_url + '#' + id, text);
}

function webidl_helper(doc, df, id, text) {
link_helper(doc, df, IDL_spec_url + '#' + id, text);
}
Expand Down Expand Up @@ -216,6 +221,7 @@

'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"', },
'dom-mediakeyspolicy-minhdcpversion': { func: idlref_helper, fragment: 'dom-mediakeyspolicy-minhdcpversion', link_text: "minHdcpVersion"},
'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', },

Expand Down Expand Up @@ -328,8 +334,9 @@
'new-domexception-named': { func: new_domexception_helper, fragment: '', },
'domexception': { func: domexception_helper, fragment: '', },
'domexception-names': { func: webidl_helper, fragment: 'idl-DOMException-error-names', link_text: '', },
'present-dictionary-member': { func: webidl_helper, fragment: 'map-exists', link_text: 'present', },
'not-present-dictionary-member': { func: webidl_helper, fragment: 'map-exists', link_text: 'not present', },
'dictionary-member': { func: webidl_helper, fragment: 'dfn-dictionary-member', link_text: 'member', },
'present-dictionary-member': { func: infra_helper, fragment: 'map-exists', link_text: 'present', },
'not-present-dictionary-member': { func: infra_helper, fragment: 'map-exists', link_text: 'not present', },
'simple-exception': { func: webidl_helper, fragment: 'dfn-simple-exception', link_text: 'simple exception', },
'throw': { func: webidl_helper, fragment: 'dfn-throw', link_text: 'throw', },

Expand Down

0 comments on commit 0b2d5e3

Please sign in to comment.