Re: [EME] object-oriented design representing sessions as objects

After thinking about this more, I realize there are some issues with the
updated proposal:

   -
   - There is no way to associate the generateKeyRequest() call (and thus
   the initData/stream) with the keymessage (and thus sessionId).
      - This is also a problem with the current design (
      https://www.w3.org/Bugs/Public/show_bug.cgi?id=16614), but using
      session objects was one possible solution.
   - There is no way for Clear Key and other non-license-based key systems
   to associate the key with initData/key ID. Specifically, Clear Key cannot
   provide a key ID for each key.
      - This is because of the above issue and because the initData
      parameter has been removed from addKey().
      - There is a general problem for Clear Key with ISO CENC where more
      than one key ID can be contained in the initData.

We may need to go back to one initData per session object (as in section
9.2). This seems more natural, with the lifetime of each [set of] keys for
a particular initData being represented by a session object. We would need
to accept that each initData, whether it be from the same stream or
multiple streams, would be a different session with a different ID. (See
http://lists.w3.org/Archives/Public/public-html-media/2012Jun/0056.html.)

Another concern I have is whether having generateKeyRequest() create the
session, as in 9.2, would work if the events are fired at the session
object. The problem is that event handlers can't be registered until an
action that might fire those events has been initiated. We may be okay as
long as the user agent fires the events asynchronously and the application
sets the handlers synchronously (as in the examples). Will that work in all
implementations?

On Sun, Jun 24, 2012 at 9:23 PM, David Dorwin <ddorwin@google.com> wrote:

> Below are a modified version of the proposed IDL changes along with a
> couple examples modified to reflect the changes.
>
> I modified the proposal in section 9.2 to have an explicit
> createKeySession() method and keep together generateKeyRequest() with the
> other methods on the session object. sessionId is also no longer optional.
> Moving generateKeyRequest() allows multiple initData values to be managed
> in the same session. While not shown here, needkey is still fired at the
> media element and the other events are fired at the session object. It is
> still TBD whether needkey can be fired at the session object.
>
> The only real drawback I encountered while modifying the examples was that
> related event handlers must be specified on different objects and those on
> the session object could no longer be specified declaratively. I also had
> to be careful to get some values (keySystem and sessionId) from the session
> object (event.target) rather than the event.
>
> partial interface HTMLMediaElement {
>     MediaKeySession createKeySession <#13824929695dd8d9_13824502e1344c8b_13821e0f42f01c10_dom-createkeysession>(in DOMString keySystem <#13824929695dd8d9_13824502e1344c8b_13821e0f42f01c10_key-system>);
> };
>
> interface MediaKeySession : EventTarget <#13824929695dd8d9_13824502e1344c8b_13821e0f42f01c10_dom-eventtarget> {
>     readonly attribute DOMString keySystem <#13824929695dd8d9_13824502e1344c8b_13821e0f42f01c10_dom-keysystem>;
>     readonly attribute DOMString sessionId <#13824929695dd8d9_13824502e1344c8b_13821e0f42f01c10_dom-sessionid>;
>
>     void generateKeyRequest <#13824929695dd8d9_13824502e1344c8b_13821e0f42f01c10_dom-generatekeyrequest>(in Uint8Array? initData);
>     void addKey <#13824929695dd8d9_13824502e1344c8b_13821e0f42f01c10_dom-addkey>(in Uint8Array key);
>     void cancel();
> };
>
>
> This is an updated version of Example 7.2.2.
>
> <script>
>   function handleKeyNeeded(event) {
>     if (event.keySystem <#13824929695dd8d9_13824502e1344c8b_13821e0f42f01c10_dom-keysystem> && event.keySystem <#13824929695dd8d9_13824502e1344c8b_13821e0f42f01c10_dom-keysystem> != "com.example.somesystem.1_0")
>       throw "Unhandled keySystem in event";
>     var initData = event.initData <#13824929695dd8d9_13824502e1344c8b_13821e0f42f01c10_dom-initdata>;
>     var video = event.target;
>
>     var session = video.createKeySession("com.example.somesystem.1_0");
>     session.onkeymessage <#13824929695dd8d9_13824502e1344c8b_13821e0f42f01c10_dom-keymessage>="licenseRequestReady(event)"
>     session.generateKeyRequest <#13824929695dd8d9_13824502e1344c8b_13821e0f42f01c10_dom-generatekeyrequest>(initData);
>   }
>
>   function licenseRequestReady(event) {
>     var session = event.target;
>     if (session.keySystem <#13824929695dd8d9_13824502e1344c8b_13821e0f42f01c10_dom-keysystem> != "com.example.somesystem.1_0")
>       throw "Unhandled keySystem in event";
>     var request = event.message <#13824929695dd8d9_13824502e1344c8b_13821e0f42f01c10_dom-message>;
>     if (!request)
>       throw "Could not create license request";
>
>     var xmlhttp = new XMLHttpRequest();
>     xmlhttp.open("POST", "http://.../getkey", false);
>     xmlhttp.send(request);
>     var license = new Uint8Array(xmlhttp.response);
>     session.addKey <#13824929695dd8d9_13824502e1344c8b_13821e0f42f01c10_dom-addkey>(license);
>   }
> </script>
>
> <video src="foo.webm" autoplay onneedkey <#13824929695dd8d9_13824502e1344c8b_13821e0f42f01c10_dom-needkey>="handleKeyNeeded(event)"></video>
>
>
> This is an updated version of Example 7.4.
>
>
> <script>
>   var keySystem;
>   var licenseUrl;
>
>   function handleMessageResponse() {
>     var license = new Uint8Array(xmlhttp.response);
>     this.session.addKey <#13824929695dd8d9_13824502e1344c8b_13821e0f42f01c10_dom-addkey>(license);
>   }
>
>   function sendMessage(message, session) {
>     xmlhttp = new XMLHttpRequest();
>     xmlhttp.session = session;
>     xmlhttp.onreadystatechange = handleMessageResponse;
>     xmlhttp.open("POST", licenseUrl, true);
>     xmlhttp.send(message);
>   }
>
>   function handleKeyMessage(event) {
>     var session = event.target;
>     if (session.keySystem <#13824929695dd8d9_13824502e1344c8b_13821e0f42f01c10_dom-keysystem> != keySystem)
>       throw "Message from unexpected Key System";
>     var message = event.message <#13824929695dd8d9_13824502e1344c8b_13821e0f42f01c10_dom-message>;
>     if (!message)
>       throw "Invalid key message";
>
>     sendMessage(message, session);
>   }
>
>   function handleKeyComplete(event) {
>     // Do some bookkeeping with event.target.sessionId <#13824929695dd8d9_13824502e1344c8b_13821e0f42f01c10_dom-sessionid> if necessary.
>   }
>
>   function handleKeyError(event) {
>     // Report event.errorCode <#13824929695dd8d9_13824502e1344c8b_13821e0f42f01c10_dom-errorcode> and do some bookkeeping with event.target.sessionId <#13824929695dd8d9_13824502e1344c8b_13821e0f42f01c10_dom-sessionid> if necessary.
>   }
>
>   function handleKeyNeeded(event) {
>     var targetKeySystem = event.keySystem <#13824929695dd8d9_13824502e1344c8b_13821e0f42f01c10_dom-keysystem>;
>     if (targetKeySystem == null) {
>       selectKeySystem(video);  // See previous example for implementation.
>       targetKeySystem = keySystem;
>     }
>     var initData = event.initData <#13824929695dd8d9_13824502e1344c8b_13821e0f42f01c10_dom-initdata>;
>     var video = event.target;
>
>     var session = video.createKeySession(targetKeySystem);
>     session.onkeymessage <#13824929695dd8d9_13824502e1344c8b_13821e0f42f01c10_dom-keymessage>="handleKeyMessage(event)";
>     session.onkeyadded <#13824929695dd8d9_13824502e1344c8b_13821e0f42f01c10_dom-keyadded>="handleKeyComplete(event)";
>     session.onkeyerror <#13824929695dd8d9_13824502e1344c8b_13821e0f42f01c10_dom-keyerror>="handleKeyError(event)";
>
>     session.generateKeyRequest <#13824929695dd8d9_13824502e1344c8b_13821e0f42f01c10_dom-generatekeyrequest>(initData);
>   }
> </script>
>
> <video src="foo.webm" autoplay onneedkey <#13824929695dd8d9_13824502e1344c8b_13821e0f42f01c10_dom-needkey>="handleKeyNeeded(event)"></video>
>
>

Received on Monday, 25 June 2012 17:12:01 UTC