- From: David Dorwin <ddorwin@google.com>
- Date: Wed, 24 Sep 2014 17:37:59 -0700
- To: "public-html-media@w3.org" <public-html-media@w3.org>
- Cc: Anne van Kesteren <annevk@annevk.nl>
- Message-ID: <CAHD2rsg4jvU+0ngLcAw7PbKDo13HUVEeam5xEW=OirVbbZSUtg@mail.gmail.com>
In bug 25923 <https://www.w3.org/Bugs/Public/show_bug.cgi?id=25923>, we have been discussing the proper way to report key system support when the answer might depend on permissions, whether the user authorizes CDM download, etc. I'd like to have a broader discussion on solving these issues and get feedback from authors. I have included a concrete proposal that I think is better than the current state, but it does have some theoretical deficiencies. *Background* EME currently has a synchronous isTypeSupported() <https://dvcs.w3.org/hg/html-media/raw-file/default/encrypted-media/encrypted-media.html#dom-istypesupported> method to determine whether key system, media type, and capability combinations are supported by the user agent. Its design is similar to canPlayType(). As with canPlayType(), it is expected that applications may make many calls to check various combinations before picking one. The current assumption is that any permission prompts would be presented during the asynchronous MediaKeys.create(). There are some scenarios that are not handled well in this model. For example, how should isTypeSupported() respond if the user has not yet been prompted (and thus allowed) the CDM to be used. There are other variants where the CDM needs to be downloaded, which could add additional delay. *Proposal* I propose a model inspired by Web MIDI's MIDIAccess object. Permissions, installation delays, etc. would be handled as part of the creation of a new object, MediaKeySystemAccess. In most cases, this object is returned quickly, though asynchronously. Once the application has the object, it can use it to check details (i.e. supported codecs) and instantiate the CDM (creating a MediaKeys object). Since the MediaKeySystemAccess object should be returned almost immediately in subsequent calls, applications should still be able to use the codec checks to select streams to download just as quickly (effectively) as with the current synchronous model. *IDL* Add a new method to request access to a key system. All download and permission prompts are handled here before resolving the promise. If the |keySystem| is not supported (or is declined), the promise is rejected. Otherwise, it is resolved with a new MediaKeySystemAccess object. partial interface Navigator { Promise<MediaKeySystemAccess> requestMediaKeySystem(DOMString keySystem); }; MediaKeySystemAccess contains non-static methods that were once static methods in MediaKeys: - isTypeSupported remains synchronous, but becomes a member and only checks the codecs and capabilities. - isInitDataTypeSupported() is added to handle exactly one attribute of the CDM. (There is no reason to check combinations of Initialization Data Types and containers/codecs.) - createMediaKeys() is still asynchronous to allow the CDM to be loaded asynchronously. enum IsTypeSupportedResult { "" /* empty string */, "maybe", "probably" }; interface MediaKeySystemAccess { boolean isInitDataTypeSupported(DOMString initDataType); IsTypeSupportedResult isTypeSupported(DOMString contentType, optional DOMString capability); Promise<MediaKeys> createMediaKeys(); }; MediaKeys continues to exist, but is mainly used to create sessions. MediaKeySession is unchanged. interface MediaKeys { MediaKeySession createSession(optional SessionType sessionType = "temporary"); Promise<void> setServerCertificate((ArrayBuffer or ArrayBufferView) serverCertificate); }; *Example Usage* > navigator.requestMediaKeySystem("com.example.somesystem").then( > function(keySystemAccess) { > if (keySystemAccess.isInitDataTypeSupported("keyids") && > (keySystemAccess.isTypeSupported("video/foo; codecs='bar,baz'") || > keySystemAccess.isTypeSupported("video/foo; codecs='bar2,baz'"))) > { > return keySystemAccess.createMediaKeys(); > } > // Throw to fall into the catch. > ... > } > ).catch( > function(error) { > // Try the next key system. > navigator.requestMediaKeySystem("org.w3.clearkey").then( ... } ... ).catch( // No supported key systems . ... ); *Concerns* Although this proposal solves the scenarios mentioned in the Background and that motivated bug 25923, it introduces some new ones related to multiple key system support and does not address others. *New Issues* These new issues do not exist with the current synchronous isTypeSupported() model. See also the discussion beginning with comment 35 <https://www.w3.org/Bugs/Public/show_bug.cgi?id=25923#c35>. 1. An application looking for specific type support (i.e. codecs or Initialization Data Type) may need to create multiple objects - and thus generate multiple user prompts - to find a key system that supports those type(s). 2. Applications must serialize the *asynchronous* checks for multiple key systems to avoid the possibility of multiple prompts, similar to the above issue. (Note how the requestMediaKeySystem() calls are serialized in the example.) *Unaddressed Issues* These issues exist in the current model *and* various proposed models. 1. CDM download/install and permission to use must be presented to the user in the same UI. For example, it is not possible to download and install the CDM without also approving exposure of a unique ID (without some far-too-complex UI). 2. There is no way for an application to prefer, for example, the key system that will generate the least alarming UI (or none at all). Since different CDMs (or even configurations) may have very different security and privacy properties, the related UI/UX could be different. *Possible Solutions* One or more of the above issues could potentially be addressed by the following: - Maintaining some level of synchronous checks for the best-case support (i.e. respond as if the CDM is installed and allowed). - Applications would still need to use the MediaKeySystemAccess methods for definitive responses. - Allowing the application to specify conditions to requestMediaKeySystem(). - For example, types that must be supported or to fail if a prompt is required, - If the condition cannot be met, the promise would be rejected. - Allowing the application to query/request multiple key systems at once.
Received on Thursday, 25 September 2014 00:38:46 UTC