Bug 1289942 - Make MediaKeyStatusMap.get() return undefined for unknown keys. r=bz draft
authorChris Pearce <cpearce@mozilla.com>
Thu, 28 Jul 2016 14:03:01 +1200
changeset 395451 cd067f545cdbd9352ba64fea914128201b458d9c
parent 394995 ffac2798999c5b84f1b4605a1280994bb665a406
child 526996 bc1739aca2e497a9c3b532e92080ec2b1a5d8a48
push id24776
push usercpearce@mozilla.com
push dateTue, 02 Aug 2016 08:13:09 +0000
reviewersbz
bugs1289942
milestone51.0a1
Bug 1289942 - Make MediaKeyStatusMap.get() return undefined for unknown keys. r=bz The spec requires the MediaKeyStatusMap.get(keyId) function to return an 'any' type, which is undefined for known keys, or a MediaKeyStatus enum value for known keys. https://w3c.github.io/encrypted-media/#idl-def-mediakeystatusmap MozReview-Commit-ID: 3TOFYLacZSc
dom/media/eme/MediaKeyStatusMap.cpp
dom/media/eme/MediaKeyStatusMap.h
dom/media/test/test_eme_playback.html
dom/webidl/MediaKeyStatusMap.webidl
--- a/dom/media/eme/MediaKeyStatusMap.cpp
+++ b/dom/media/eme/MediaKeyStatusMap.cpp
@@ -37,31 +37,37 @@ MediaKeyStatusMap::WrapObject(JSContext*
 }
 
 nsPIDOMWindowInner*
 MediaKeyStatusMap::GetParentObject() const
 {
   return mParent;
 }
 
-MediaKeyStatus
-MediaKeyStatusMap::Get(const ArrayBufferViewOrArrayBuffer& aKey) const
+void
+MediaKeyStatusMap::Get(JSContext* aCx,
+                       const ArrayBufferViewOrArrayBuffer& aKey,
+                       JS::MutableHandle<JS::Value> aOutValue,
+                       ErrorResult& aOutRv) const
 {
   ArrayData keyId = GetArrayBufferViewOrArrayBufferData(aKey);
   if (!keyId.IsValid()) {
-    return MediaKeyStatus::Internal_error;
+    aOutValue.setUndefined();
+    return;
   }
-
   for (const KeyStatus& status : mStatuses) {
     if (keyId == status.mKeyId) {
-      return status.mStatus;
+      bool ok = ToJSValue(aCx, status.mStatus, aOutValue);
+      if (!ok) {
+        aOutRv.NoteJSContextException(aCx);
+      }
+      return;
     }
   }
-
-  return MediaKeyStatus::Internal_error;
+  aOutValue.setUndefined();
 }
 
 bool
 MediaKeyStatusMap::Has(const ArrayBufferViewOrArrayBuffer& aKey) const
 {
   ArrayData keyId = GetArrayBufferViewOrArrayBufferData(aKey);
   if (!keyId.IsValid()) {
     return false;
--- a/dom/media/eme/MediaKeyStatusMap.h
+++ b/dom/media/eme/MediaKeyStatusMap.h
@@ -39,17 +39,20 @@ public:
 protected:
   ~MediaKeyStatusMap();
 
 public:
   nsPIDOMWindowInner* GetParentObject() const;
 
   JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
 
-  MediaKeyStatus Get(const ArrayBufferViewOrArrayBuffer& aKey) const;
+  void Get(JSContext* aCx,
+           const ArrayBufferViewOrArrayBuffer& aKey,
+           JS::MutableHandle<JS::Value> aOutValue,
+           ErrorResult& aOutRv) const;
   bool Has(const ArrayBufferViewOrArrayBuffer& aKey) const;
   uint32_t Size() const;
 
   uint32_t GetIterableLength() const;
   TypedArrayCreator<ArrayBuffer> GetKeyAtIndex(uint32_t aIndex) const;
   MediaKeyStatus GetValueAtIndex(uint32_t aIndex) const;
 
   void Update(const nsTArray<CDMCaps::KeyStatus>& keys);
--- a/dom/media/test/test_eme_playback.html
+++ b/dom/media/test/test_eme_playback.html
@@ -33,18 +33,25 @@ function KeysChangeFunc(session, keys, t
     session.keyIdsReceived[keyid] = false;
   }
   return function(ev) {
     var session = ev.target;
     session.gotKeysChanged = true;
 
     var keyList = [];
     var valueList = [];
+    var map = session.keyStatuses;
 
-    var map = session.keyStatuses;
+    // Test that accessing keys not known to the CDM has expected behaviour.
+    var absentKey = new Uint8Array([0xeb, 0xdd, 0x62, 0xf1, 0x68, 0x14, 0xd2, 0x7b,
+                                    0x68, 0xef, 0x12, 0x2a, 0xfc, 0xe4, 0xae, 0x3c]);
+    is(map.has(absentKey), false, "Shouldn't have a key that's not in the media");
+    is(map.get(absentKey), undefined, "Unknown keys should undefined status");
+
+    // Verify known keys have expected status.
     for (var [key, val] of map.entries()) {
       is(key.constructor, ArrayBuffer, "keyId should be ArrayBuffer");
       ok(map.has(key), "MediaKeyStatusMap.has() should work.");
       is(map.get(key), val, "MediaKeyStatusMap.get() should work.");
       keyList.push(key);
       valueList.push(val);
       is(val, "usable", token + ": key status should be usable");
       var kid = Base64ToHex(window.btoa(ArrayBufferToString(key)));
--- a/dom/webidl/MediaKeyStatusMap.webidl
+++ b/dom/webidl/MediaKeyStatusMap.webidl
@@ -20,10 +20,11 @@ enum MediaKeyStatus {
   "internal-error"
 };
 
 [Pref="media.eme.apiVisible"]
 interface MediaKeyStatusMap {
   iterable<ArrayBuffer,MediaKeyStatus>;
   readonly attribute unsigned long size;
   boolean has (BufferSource keyId);
-  MediaKeyStatus get (BufferSource keyId);
+  [Throws]
+  any get (BufferSource keyId);
 };