[encrypted-media] Consider changing how the MediaKeySession method algorithms run other algorithms to more accurately reflect implementations

ddorwin has just created a new issue for
https://github.com/w3c/encrypted-media:

== Consider changing how the MediaKeySession method algorithms run
other algorithms to more accurately reflect implementations ==
The `generateRequest()`, `load()`, `update()`, and `remove()`
algorithms all run other algorithms **after** the CDM step and
**before** resolving the promise. This has the advantage of separating
responsibilities, **ensuring all failures are caught before firing
events**, and having promise resolution as the last step, but it seems
unlikely to accurately represent implementations, possibly in a way
that is observable to applications. We should consider whether there
is a better way organize things.

I'll use the current `load()` algorithm as an example.
If the CDM steps succeed, the user agent has been provided with a
message. The user agent then:
 1. Initializes some application-observable state (`sessionId`
attribute and _callable_ state)
 2. May run the usable keys changed algorithm, which fires an event at
the session.
 3. Runs the update expiration algorithm, which updates the expiration
attribute.
 4. May run the queue a "message" event algorithm with the message
provided by the CDM.
 5. Resolves the promise.

However, a likely implementation pattern would be one of the
following:
I. CDM reports success once all operations have completed.
 1. User agent asks the CDM to load a session.
   1. The CDM loads the session.
   1. The CDM triggers the usable keys changed algorithm.
   1. The CDM triggers the update expiration algorithm.
   1. The CDM provides a message to be provided to the application.
   1. The CDM reports success to the user agent.
 2. The user agent initializes some application-observable state
(`sessionId` attribute and _callable_ state).
 3. The user agent resolves the promise.

II. CDM reports success after processing the request but before all
operations have completed.
 1. User agent asks the CDM to load a session.
 2. The CDM loads the session and reports success to the user agent.
 3. The user agent initializes some application-observable state
(`sessionId` attribute and _callable_ state).
 4. The user agent resolves the promise.
 5. In parallel or subsequently:
   1. The CDM triggers the usable keys changed algorithm.
   1. The CDM triggers the update expiration algorithm.
   1. The CDM provides a message to be provided to the application.

Converting either of those implementation patterns to the observable
behavior specified in the current algorithm likely requires one of the
following undesirable solutions:
 1. Caching requests from the CDM until the CDM reports success.
 2. Session initialization-specific mechanisms for reporting key
updates, expiration, and messages.
An example of (1) would be a `CompleteLoad()` method that takes all of
these values rather than reusing existing `SendMessage()`, etc.
methods.


We should also consider the desired application-observable behavior.
* Not getting events until the load succeeds is nice.
* However, it might be weird to get events from an operation before it
has succeeded.
* The callable state must be set to true before any events are fired
to ensure that the application is able to respond to the event by
calling one of the methods.
* There is currently a potential race condition between the
`generateRequest()` promise being resolved, indicating that sessionId
is valid, and the application receiving the license request message.
* Since the expiration attribute does not currently have an event,
updating the expiration attribute before resolving the promise in the
`load()` and `update()` algorithms provides a deterministic place for
applications to check the expiration.
  - Maybe `Object.observe()` could be used to detect changes to this
attribute instead. Would we get this behavior for free?


Note: The `update()` algorithm currently has the CDM running the the
usable keys changed algorithm and update expiration algorithm rather
than deferring these to the user agent. This is more consistent with
implementation pattern (I) above. Regardless of the outcome of this
bug, the algorithms should be consistent. We should change the steps
in those algorithms to be “Provide the user agent with X and have it
run the following steps.”

[Migrated from https://www.w3.org/Bugs/Public/show_bug.cgi?id=27138
with only formatting and numbering changes.]

See https://github.com/w3c/encrypted-media/issues/14

Received on Thursday, 15 January 2015 21:12:50 UTC