This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 25594 - The read-only attribute usableKeyIds cannot be variable length
Summary: The read-only attribute usableKeyIds cannot be variable length
Status: RESOLVED FIXED
Alias: None
Product: HTML WG
Classification: Unclassified
Component: Encrypted Media Extensions (show other bugs)
Version: unspecified
Hardware: All All
: P3 normal
Target Milestone: ---
Assignee: Mark Watson
QA Contact: HTML WG Bugzilla archive list
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 25409
  Show dependency treegraph
 
Reported: 2014-05-07 23:06 UTC by David Dorwin
Modified: 2014-07-02 01:44 UTC (History)
7 users (show)

See Also:


Attachments

Description David Dorwin 2014-05-07 23:06:51 UTC
The spec currently has the following IDL definition:
  readonly attribute Array<Uint8Array> usableKeyIds;

However, http://www.w3.org/TR/WebIDL/#idl-array says "If an array is read only, then it is also implicitly fixed length."

The intent was for usableKeyIds to be an always up-to-date list of available key IDs. Thus, the application should not be able to modify it.

We might need to convert the attribute to a method that returns a fixed length array:
  Array<Uint8Array> getUsableKeyIds();
Comment 1 David Dorwin 2014-05-10 00:53:02 UTC
If we are already making this a method, we might consider having that method return a promise that provides the Array<Uint8Array> when resolved. This avoids tracking the array in the MediaKeySession and having the CDM update it. However, the CDM is already calling into the MediaKeySession to fire the keyschange event. A promise-based solution would allow user agents to choose either implementation.

After this is resolved, we should change the loadSession() algorithm to *not* update the array when constructing the new MediaKeySession. It's probably better to be consistent and always fire the keyschange event.
Comment 2 Boris Zbarsky 2014-05-27 20:12:47 UTC
The invalid part here is the Array<> bit.

You should also not use #idl-array.  It's slated for removal from the IDL specification.

Either return an ES array object (using "sequence" or "object" depending on how you're doing it) or return an instance of an interface with an indexed getter.
Comment 3 Anne 2014-05-28 08:45:02 UTC
The pattern we try to advocate people to use for now is return an object (as IDL does not allow returning a sequence) and define in prose that you return a JavaScript Array Object that represents a snapshot of the underlying data. Whenever you update the underlying data, you also need to create a fresh snapshot object. 

So you end up with two variables (underlying data, Array object) and an update algorithm.
Comment 4 David Dorwin 2014-06-11 22:20:42 UTC
(In reply to Anne from comment #3)
> The pattern we try to advocate people to use for now is return an object (as
> IDL does not allow returning a sequence) and define in prose that you return
> a JavaScript Array Object that represents a snapshot of the underlying data.
> Whenever you update the underlying data, you also need to create a fresh
> snapshot object. 
> 
> So you end up with two variables (underlying data, Array object) and an
> update algorithm.

Are you saying that the following is the recommended style?
  object getUsableKeyIds();

Is that preferred to asynchronously looking up the data only when queried? For example:
  Promise<object> getUsableKeyIds();
where the promise is resolved with an object that is a JavaScript Array Object that represents a snapshot of the underlying data.
Comment 5 Boris Zbarsky 2014-06-12 02:00:29 UTC
>Are you saying that the following is the recommended style?
>  object getUsableKeyIds();

In this case, you could do:

  sequence<Uint8Array> getUsableKeyIds();

or:

  attribute object usableKeyIds;

with the latter having prose that describes when the object is created, etc.

> Is that preferred to asynchronously looking up the data only when queried?

Not particularly, no.  Sync vs async is a separate API decision from what type results from the API call; they are not tied to each other.
Comment 6 Anne 2014-06-12 08:59:09 UTC
It seems per comment 1 asynchronous might be better to allow flexibility in implementations. In that case I would recommend a method that always returns a new promise that at some point resolves with a snapshot of the underlying data. The IDL you want in that case reads:

  Promise<sequence<Uint8Array>> getUsableKeyIds();
Comment 7 Chris Pearce 2014-06-12 09:47:12 UTC
(In reply to Anne from comment #6)
>   Promise<sequence<Uint8Array>> getUsableKeyIds();

I support this proposal, as it seems to me that managing the list of usable keys is the business of the CDM. This way, the browser can just query the CDM for its keys when getUsableKeyIds() is called, and we don't have to worry about keeping a copy of the keys in the browser up to date.
Comment 8 David Dorwin 2014-06-17 15:09:08 UTC
We'll implement the promise version in the previous comments.
Comment 10 David Dorwin 2014-07-02 01:44:03 UTC
Changeset https://dvcs.w3.org/hg/html-media/rev/c4a18d018444 tweaks some of the changes in c02fbe3a2c13 and updates the example to use the promise returned by the new method.

(In reply to David Dorwin from comment #1)
> After this is resolved, we should change the loadSession() algorithm to
> *not* update the array when constructing the new MediaKeySession. It's
> probably better to be consistent and always fire the keyschange event.

Updating the array was removed as part of changeset c02fbe3a2c13.
In https://dvcs.w3.org/hg/html-media/rev/75051d4bb6a7, I made loadSession() run the Usable Keys Changed algorithm for consistency with created sessions and update(). Specifically, the "keyschange" event will fire in both cases.