Bug 1343409 - HTMLMediaElement::MozRequestDebugInfo returns EMEInfo. r?cpearce draft
authorkaro <kkoorts@mozilla.com>
Wed, 01 Mar 2017 12:56:29 +1300
changeset 491147 3830d40d0049e0286c22aa614ae1becf12b4f73e
parent 488932 7d50c8e3086d4cd1f05895b3dceac091f8825f1a
child 492621 89f7ad0f018798fd71a2ebc4ec27940b53044a88
child 492634 db0cb39d757383ba466423d8ab166d9642fc6f2b
push id47334
push userbmo:kkoorts@mozilla.com
push dateWed, 01 Mar 2017 20:52:40 +0000
reviewerscpearce
bugs1343409
milestone54.0a1
Bug 1343409 - HTMLMediaElement::MozRequestDebugInfo returns EMEInfo. r?cpearce MozReview-Commit-ID: 1iQP3OJmwdP
dom/html/HTMLMediaElement.cpp
dom/html/HTMLMediaElement.h
dom/media/eme/MediaKeyStatusMap.cpp
dom/media/eme/MediaKeyStatusMap.h
dom/media/eme/MediaKeys.cpp
dom/media/eme/MediaKeys.h
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -115,16 +115,17 @@ static mozilla::LazyLogModule gMediaElem
 
 #include "nsIPermissionManager.h"
 #include "nsDocShell.h"
 
 #include "mozilla/EventStateManager.h"
 
 #include "mozilla/dom/HTMLVideoElement.h"
 #include "mozilla/dom/VideoPlaybackQuality.h"
+#include "HTMLMediaElement.h"
 
 using namespace mozilla::layers;
 using mozilla::net::nsMediaFragmentURIParser;
 
 namespace mozilla {
 namespace dom {
 
 // Number of milliseconds between progress events as defined by spec
@@ -1472,16 +1473,24 @@ HTMLMediaElement::MozRequestDebugInfo(Er
   RefPtr<Promise> promise = CreateDOMPromise(aRv);
   if (NS_WARN_IF(aRv.Failed())) {
     return nullptr;
   }
 
   nsAutoString result;
   GetMozDebugReaderData(result);
 
+  if (mMediaKeys) {
+    nsString EMEInfo;
+    GetEMEInfo(EMEInfo);
+    result.AppendLiteral("EME Info: ");
+    result.Append(EMEInfo);
+    result.AppendLiteral("\n");
+  }
+
   if (mDecoder) {
     mDecoder->RequestDebugInfo()->Then(
       AbstractThread::MainThread(), __func__,
       [promise, result] (const nsACString& aString) {
         promise->MaybeResolve(result + NS_ConvertUTF8toUTF16(aString));
       },
       [promise, result] () {
         promise->MaybeResolve(result);
@@ -7324,16 +7333,35 @@ HTMLMediaElement::AsyncRejectPendingPlay
                                                      TakePendingPlayPromises(),
                                                      aError);
 
   OwnerDoc()->Dispatch("nsResolveOrRejectPendingPlayPromisesRunner",
                        TaskCategory::Other,
                        event.forget());
 }
 
+void
+HTMLMediaElement::GetEMEInfo(nsString& aEMEInfo)
+{
+  if (!mMediaKeys) {
+    return;
+  }
+
+  nsString keySystem;
+  mMediaKeys->GetKeySystem(keySystem);
+
+  nsString sessionsInfo;
+  mMediaKeys->GetSessionsInfo(sessionsInfo);
+
+  aEMEInfo.AppendLiteral("Key System=");
+  aEMEInfo.Append(keySystem);
+  aEMEInfo.AppendLiteral(" SessionsInfo=");
+  aEMEInfo.Append(sessionsInfo);
+}
+
 bool HasDebuggerPrivilege(JSContext* aCx, JSObject* aObj)
 {
   return nsContentUtils::CallerHasPermission(aCx,
                                              NS_LITERAL_STRING("debugger"));
  }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/html/HTMLMediaElement.h
+++ b/dom/html/HTMLMediaElement.h
@@ -277,16 +277,18 @@ public:
   // principal. If there are no live video tracks but content has been rendered
   // to the image container, we return the last video principal we had. Should
   // the image container be empty with no live video tracks, we return nullptr.
   already_AddRefed<nsIPrincipal> GetCurrentVideoPrincipal();
 
   // called to notify that the principal of the decoder's media resource has changed.
   void NotifyDecoderPrincipalChanged() final override;
 
+  void GetEMEInfo(nsString& aEMEInfo);
+
   // An interface for observing principal changes on the media elements
   // MediaDecoder. This will also be notified if the active CORSMode changes.
   class DecoderPrincipalChangeObserver
   {
   public:
     virtual void NotifyDecoderPrincipalChanged() = 0;
   };
 
--- a/dom/media/eme/MediaKeyStatusMap.cpp
+++ b/dom/media/eme/MediaKeyStatusMap.cpp
@@ -90,16 +90,23 @@ MediaKeyStatusMap::GetIterableLength() c
 
 TypedArrayCreator<ArrayBuffer>
 MediaKeyStatusMap::GetKeyAtIndex(uint32_t aIndex) const
 {
   MOZ_ASSERT(aIndex < GetIterableLength());
   return TypedArrayCreator<ArrayBuffer>(mStatuses[aIndex].mKeyId);
 }
 
+nsString
+MediaKeyStatusMap::GetKeyIDAsHexString(uint32_t aIndex) const
+{
+  MOZ_ASSERT(aIndex < GetIterableLength());
+  return NS_ConvertUTF8toUTF16(ToHexString(mStatuses[aIndex].mKeyId));
+}
+
 MediaKeyStatus
 MediaKeyStatusMap::GetValueAtIndex(uint32_t aIndex) const
 {
   MOZ_ASSERT(aIndex < GetIterableLength());
   return mStatuses[aIndex].mStatus;
 }
 
 uint32_t
--- a/dom/media/eme/MediaKeyStatusMap.h
+++ b/dom/media/eme/MediaKeyStatusMap.h
@@ -48,16 +48,17 @@ public:
            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;
+  nsString GetKeyIDAsHexString(uint32_t aIndex) const;
   MediaKeyStatus GetValueAtIndex(uint32_t aIndex) const;
 
   void Update(const nsTArray<CDMCaps::KeyStatus>& keys);
 
 private:
 
   nsCOMPtr<nsPIDOMWindowInner> mParent;
 
--- a/dom/media/eme/MediaKeys.cpp
+++ b/dom/media/eme/MediaKeys.cpp
@@ -572,10 +572,38 @@ MediaKeys::Bind(HTMLMediaElement* aEleme
 
 void
 MediaKeys::Unbind()
 {
   MOZ_ASSERT(NS_IsMainThread());
   mElement = nullptr;
 }
 
+void
+MediaKeys::GetSessionsInfo(nsString& sessionsInfo)
+{
+  for (KeySessionHashMap::Iterator it = mKeySessions.Iter();
+       !it.Done();
+       it.Next()) {
+    MediaKeySession* keySession = it.Data();
+    nsString sessionID;
+    keySession->GetSessionId(sessionID);
+    sessionsInfo.AppendLiteral("(sid:");
+    sessionsInfo.Append(sessionID);
+    MediaKeyStatusMap* keyStatusMap = keySession->KeyStatuses();
+    for (uint32_t i = 0; i < keyStatusMap->GetIterableLength(); i++) {
+      nsString keyID = keyStatusMap->GetKeyIDAsHexString(i);
+      sessionsInfo.AppendLiteral("(kid:");
+      sessionsInfo.Append(keyID);
+      using IntegerType = typename std::underlying_type<MediaKeyStatus>::type;
+      auto idx = static_cast<IntegerType>(keyStatusMap->GetValueAtIndex(i));
+      const char* keyStatus = MediaKeyStatusValues::strings[idx].value;
+      sessionsInfo.AppendLiteral(" status:");
+      sessionsInfo.Append(
+        NS_ConvertUTF8toUTF16((nsDependentCString(keyStatus))));
+      sessionsInfo.AppendLiteral(")");
+    }
+    sessionsInfo.AppendLiteral(")");
+  }
+}
+
 } // namespace dom
 } // namespace mozilla
--- a/dom/media/eme/MediaKeys.h
+++ b/dom/media/eme/MediaKeys.h
@@ -123,16 +123,18 @@ public:
 
   // Called by CDMProxy when CDM crashes or shuts down. It is different from
   // Shutdown which is called from the script/dom side.
   void Terminated();
 
   // Returns true if this MediaKeys has been bound to a media element.
   bool IsBoundToMediaElement() const;
 
+  void GetSessionsInfo(nsString& sessionsInfo);
+
 private:
 
   // Instantiate CDMProxy instance.
   // It could be MediaDrmCDMProxy (Widevine on Fennec) or GMPCDMProxy (the rest).
   already_AddRefed<CDMProxy> CreateCDMProxy();
 
   // Removes promise from mPromises, and returns it.
   already_AddRefed<DetailedPromise> RetrievePromise(PromiseId aId);