Bug 1304247 - Implement HTMLMediaElement.onwaitingforkeys. r?smaug draft
authorChris Pearce <cpearce@mozilla.com>
Wed, 21 Sep 2016 14:10:26 +1200
changeset 415771 e002522efd463acac3dcd71cf08596d66acf482b
parent 415495 62f79d676e0e11b3ad59a5425b3ebb3ec5bbefb5
child 415779 c3f988c59afaba6d2b7d1ffb143e1b82ee9d04f9
child 415780 f4a11a9eac294c345e93b2f66e88baee0f060b02
push id29969
push usercpearce@mozilla.com
push dateWed, 21 Sep 2016 02:20:45 +0000
reviewerssmaug
bugs1304247
milestone52.0a1
Bug 1304247 - Implement HTMLMediaElement.onwaitingforkeys. r?smaug MozReview-Commit-ID: DhNV30BfksS
dom/base/nsGkAtomList.h
dom/html/HTMLMediaElement.cpp
dom/html/HTMLMediaElement.h
dom/media/test/test_eme_waitingforkey.html
dom/webidl/HTMLMediaElement.webidl
testing/web-platform/meta/encrypted-media/idlharness.html.ini
--- a/dom/base/nsGkAtomList.h
+++ b/dom/base/nsGkAtomList.h
@@ -2094,16 +2094,17 @@ GK_ATOM(ondurationchange, "ondurationcha
 GK_ATOM(onvolumechange, "onvolumechange")
 GK_ATOM(onaddtrack, "onaddtrack")
 GK_ATOM(oncontrollerchange, "oncontrollerchange")
 GK_ATOM(oncuechange, "oncuechange")
 GK_ATOM(onenter, "onenter")
 GK_ATOM(onexit, "onexit")
 GK_ATOM(onencrypted, "onencrypted")
 GK_ATOM(encrypted, "encrypted")
+GK_ATOM(onwaitingforkey, "onwaitingforkey")
 GK_ATOM(onremovetrack, "onremovetrack")
 GK_ATOM(loadstart, "loadstart")
 GK_ATOM(suspend, "suspend")
 GK_ATOM(emptied, "emptied")
 GK_ATOM(stalled, "stalled")
 GK_ATOM(play, "play")
 GK_ATOM(pause, "pause")
 GK_ATOM(loadedmetadata, "loadedmetadata")
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -6227,16 +6227,33 @@ void
 HTMLMediaElement::SetOnencrypted(EventHandlerNonNull* handler)
 {
   EventListenerManager *elm = GetOrCreateListenerManager();
   if (elm) {
     elm->SetEventHandler(nsGkAtoms::onencrypted, EmptyString(), handler);
   }
 }
 
+EventHandlerNonNull*
+HTMLMediaElement::GetOnwaitingforkey()
+{
+  EventListenerManager *elm = GetExistingListenerManager();
+  return elm ? elm->GetEventHandler(nsGkAtoms::onwaitingforkey, EmptyString())
+             : nullptr;
+}
+
+void
+HTMLMediaElement::SetOnwaitingforkey(EventHandlerNonNull* handler)
+{
+  EventListenerManager *elm = GetOrCreateListenerManager();
+  if (elm) {
+    elm->SetEventHandler(nsGkAtoms::onwaitingforkey, EmptyString(), handler);
+  }
+}
+
 void
 HTMLMediaElement::DispatchEncrypted(const nsTArray<uint8_t>& aInitData,
                                     const nsAString& aInitDataType)
 {
   if (mReadyState == nsIDOMHTMLMediaElement::HAVE_NOTHING) {
     // Ready state not HAVE_METADATA (yet), don't dispatch encrypted now.
     // Queueing for later dispatch in MetadataLoaded.
     mPendingEncryptedInitData.AddInitData(aInitDataType, aInitData);
--- a/dom/html/HTMLMediaElement.h
+++ b/dom/html/HTMLMediaElement.h
@@ -630,16 +630,19 @@ public:
   MediaKeys* GetMediaKeys() const;
 
   already_AddRefed<Promise> SetMediaKeys(MediaKeys* mediaKeys,
                                          ErrorResult& aRv);
 
   mozilla::dom::EventHandlerNonNull* GetOnencrypted();
   void SetOnencrypted(mozilla::dom::EventHandlerNonNull* listener);
 
+  mozilla::dom::EventHandlerNonNull* GetOnwaitingforkey();
+  void SetOnwaitingforkey(mozilla::dom::EventHandlerNonNull* listener);
+
   void DispatchEncrypted(const nsTArray<uint8_t>& aInitData,
                          const nsAString& aInitDataType) override;
 
   bool IsEventAttributeName(nsIAtom* aName) override;
 
   // Returns the principal of the "top level" document; the origin displayed
   // in the URL bar of the browser window.
   already_AddRefed<nsIPrincipal> GetTopLevelPrincipal();
--- a/dom/media/test/test_eme_waitingforkey.html
+++ b/dom/media/test/test_eme_waitingforkey.html
@@ -53,39 +53,45 @@ function startTest(test, token)
     },
   };
   var v = SetupEME(test, token, params);
 
   document.body.appendChild(v);
 
   var gotEncrypted = 0;
   var gotWaitingForKey = 0;
+  var gotOnwaitingforkey = 0;
 
   v.addEventListener("encrypted", function() {
     gotEncrypted += 1;
     TestIfDoneDelaying();
   });
 
   v.addEventListener("waitingforkey", function() {
     gotWaitingForKey += 1;
     TestIfDoneDelaying()
   });
 
+  v.onwaitingforkey = function() {
+    gotOnwaitingforkey += 1;
+  };
+
   v.addEventListener("loadedmetadata", function() {
     ok(SpecialPowers.do_lookupGetter(v, "isEncrypted").apply(v),
        TimeStamp(token) + " isEncrypted should be true");
     is(v.isEncrypted, undefined, "isEncrypted should not be accessible from content");
   });
 
   v.addEventListener("ended", function() {
     ok(true, TimeStamp(token) + " got ended event");
     // We expect only one waitingForKey as we delay until all sessions are ready.
     // I.e. one waitingForKey should be fired, after which, we process all sessions,
     // so it should not be possible to be blocked by a key after that point.
     ok(gotWaitingForKey == 1,  "Expected number 1 wait, got: " + gotWaitingForKey);
+    ok(gotOnwaitingforkey == gotWaitingForKey, "Expected as many onwaitingforkey as waitingforkey events, got: " + gotOnwaitingforkey);
 
     v.closeSessions().then(() => manager.finished(token));
   });
 
   LoadTest(test, v, token)
   .then(function() {
     loaded = true;
     TestIfDoneDelaying();
--- a/dom/webidl/HTMLMediaElement.webidl
+++ b/dom/webidl/HTMLMediaElement.webidl
@@ -160,16 +160,19 @@ partial interface HTMLMediaElement {
   readonly attribute MediaKeys? mediaKeys;
 
   // void, not any: https://www.w3.org/Bugs/Public/show_bug.cgi?id=26457
   [Pref="media.eme.apiVisible", NewObject]
   Promise<void> setMediaKeys(MediaKeys? mediaKeys);
 
   [Pref="media.eme.apiVisible"]
   attribute EventHandler onencrypted;
+
+  [Pref="media.eme.apiVisible"]
+  attribute EventHandler onwaitingforkey;
 };
 #endif
 
 // This is just for testing
 partial interface HTMLMediaElement {
   [Pref="media.useAudioChannelService.testing"]
   readonly attribute double computedVolume;
   [Pref="media.useAudioChannelService.testing"]
--- a/testing/web-platform/meta/encrypted-media/idlharness.html.ini
+++ b/testing/web-platform/meta/encrypted-media/idlharness.html.ini
@@ -1,11 +1,8 @@
 [idlharness.html]
   type: testharness
-  [HTMLMediaElement interface: attribute onwaitingforkey]
-    expected: FAIL
-
   [MediaKeySession interface: attribute onkeystatuseschange]
     expected: FAIL
 
   [MediaKeySession interface: attribute onmessage]
     expected: FAIL