Bug 1312540 - Use GMP caps cached in content process for GetPluginVersion. r=gerald draft
authorChris Pearce <cpearce@mozilla.com>
Tue, 01 Nov 2016 16:55:08 +1300
changeset 432364 c16244e5649f28fade6a08813aaaffa33ae43446
parent 432363 e59fe8503a54d0e99184c0f76c5df8243b6b7693
child 432365 9705f154f2709aa3f56bc9639da88ee2b71515cc
push id34282
push usercpearce@mozilla.com
push dateTue, 01 Nov 2016 20:25:28 +0000
reviewersgerald
bugs1312540
milestone52.0a1
Bug 1312540 - Use GMP caps cached in content process for GetPluginVersion. r=gerald MozReview-Commit-ID: 1nDHsW527Tu
dom/media/gmp/GMPParent.cpp
dom/media/gmp/GMPParent.h
dom/media/gmp/GMPServiceChild.cpp
dom/media/gmp/GMPServiceParent.cpp
--- a/dom/media/gmp/GMPParent.cpp
+++ b/dom/media/gmp/GMPParent.cpp
@@ -559,37 +559,54 @@ GMPParent::GMPThread()
     // to use swap() under a lock.
     mps->GetThread(getter_AddRefs(mGMPThread));
     MOZ_ASSERT(mGMPThread);
   }
 
   return mGMPThread;
 }
 
+/* static */
 bool
-GMPParent::SupportsAPI(const nsCString& aAPI, const nsCString& aTag)
+GMPCapability::Supports(const nsTArray<GMPCapability>& aCapabilities,
+                        const nsCString& aAPI,
+                        const nsTArray<nsCString>& aTags)
 {
-  for (uint32_t i = 0; i < mCapabilities.Length(); i++) {
-    if (!mCapabilities[i].mAPIName.Equals(aAPI)) {
+  for (const nsCString& tag : aTags) {
+    if (!GMPCapability::Supports(aCapabilities, aAPI, tag)) {
+      return false;
+    }
+  }
+  return true;
+}
+
+/* static */
+bool
+GMPCapability::Supports(const nsTArray<GMPCapability>& aCapabilities,
+                        const nsCString& aAPI,
+                        const nsCString& aTag)
+{
+  for (uint32_t i = 0; i < aCapabilities.Length(); i++) {
+    if (!aCapabilities[i].mAPIName.Equals(aAPI)) {
       continue;
     }
-    nsTArray<nsCString>& tags = mCapabilities[i].mAPITags;
+    const nsTArray<nsCString>& tags = aCapabilities[i].mAPITags;
     for (uint32_t j = 0; j < tags.Length(); j++) {
       if (tags[j].Equals(aTag)) {
 #ifdef XP_WIN
         // Clearkey on Windows advertises that it can decode in its GMP info
         // file, but uses Windows Media Foundation to decode. That's not present
         // on Windows XP, and on some Vista, Windows N, and KN variants without
         // certain services packs.
         if (tags[j].Equals(kEMEKeySystemClearkey)) {
-          if (mCapabilities[i].mAPIName.EqualsLiteral(GMP_API_VIDEO_DECODER)) {
+          if (aCapabilities[i].mAPIName.EqualsLiteral(GMP_API_VIDEO_DECODER)) {
             if (!WMFDecoderModule::HasH264()) {
               continue;
             }
-          } else if (mCapabilities[i].mAPIName.EqualsLiteral(GMP_API_AUDIO_DECODER)) {
+          } else if (aCapabilities[i].mAPIName.EqualsLiteral(GMP_API_AUDIO_DECODER)) {
             if (!WMFDecoderModule::HasAAC()) {
               continue;
             }
           }
         }
 #endif
         return true;
       }
--- a/dom/media/gmp/GMPParent.h
+++ b/dom/media/gmp/GMPParent.h
@@ -49,16 +49,24 @@ public:
   {
   }
   explicit GMPCapability(const nsCString& aAPIName)
     : mAPIName(aAPIName)
   {}
   explicit GMPCapability(const GMPCapability& aOther) = default;
   nsCString mAPIName;
   nsTArray<nsCString> mAPITags;
+
+  static bool Supports(const nsTArray<GMPCapability>& aCapabilities,
+                       const nsCString& aAPI,
+                       const nsTArray<nsCString>& aTags);
+
+  static bool Supports(const nsTArray<GMPCapability>& aCapabilities,
+                       const nsCString& aAPI,
+                       const nsCString& aTag);
 };
 
 enum GMPState {
   GMPStateNotLoaded,
   GMPStateLoaded,
   GMPStateUnloading,
   GMPStateClosing
 };
--- a/dom/media/gmp/GMPServiceChild.cpp
+++ b/dom/media/gmp/GMPServiceChild.cpp
@@ -215,22 +215,32 @@ GeckoMediaPluginServiceChild::GetPluginV
                                                      nsACString& aOutVersion)
 {
   dom::ContentChild* contentChild = dom::ContentChild::GetSingleton();
   if (!contentChild) {
     return NS_ERROR_FAILURE;
   }
 
   MOZ_ASSERT(NS_IsMainThread());
+  if (!sGMPCapabilities) {
+    *aHasPlugin = false;
+    return NS_OK;
+  }
 
-  nsCString version;
-  bool ok = contentChild->SendGetGMPPluginVersionForAPI(nsCString(aAPI), *aTags,
-                                                        aHasPlugin, &version);
-  aOutVersion = version;
-  return ok ? NS_OK : NS_ERROR_FAILURE;
+  nsCString api(aAPI);
+  for (const GMPCapabilityAndVersion& plugin : *sGMPCapabilities) {
+    if (GMPCapability::Supports(plugin.mCapabilities, api, *aTags)) {
+      aOutVersion = plugin.mVersion;
+      *aHasPlugin = true;
+      return NS_OK;
+    }
+  }
+
+  *aHasPlugin = false;
+  return NS_OK;
 }
 
 class GetNodeIdDone : public GetServiceChildCallback
 {
 public:
   GetNodeIdDone(const nsAString& aOrigin, const nsAString& aTopLevelOrigin,
                 const nsAString& aGMPName,
                 bool aInPrivateBrowsing, UniquePtr<GetNodeIdCallback>&& aCallback)
--- a/dom/media/gmp/GMPServiceParent.cpp
+++ b/dom/media/gmp/GMPServiceParent.cpp
@@ -1015,25 +1015,17 @@ already_AddRefed<GMPParent>
 GeckoMediaPluginServiceParent::FindPluginForAPIFrom(size_t aSearchStartIndex,
                                                     const nsCString& aAPI,
                                                     const nsTArray<nsCString>& aTags,
                                                     size_t* aOutPluginIndex)
 {
   mMutex.AssertCurrentThreadOwns();
   for (size_t i = aSearchStartIndex; i < mPlugins.Length(); i++) {
     RefPtr<GMPParent> gmp = mPlugins[i];
-    bool supportsAllTags = true;
-    for (size_t t = 0; t < aTags.Length(); t++) {
-      const nsCString& tag = aTags.ElementAt(t);
-      if (!gmp->SupportsAPI(aAPI, tag)) {
-        supportsAllTags = false;
-        break;
-      }
-    }
-    if (!supportsAllTags) {
+    if (!GMPCapability::Supports(gmp->GetCapabilities(), aAPI, aTags)) {
       continue;
     }
     if (aOutPluginIndex) {
       *aOutPluginIndex = i;
     }
     return gmp.forget();
   }
   return nullptr;