Bug 1312540 - Use GMP caps cached in content process for GetPluginVersion. r=gerald
MozReview-Commit-ID: 1nDHsW527Tu
--- a/dom/media/gmp/GMPParent.cpp
+++ b/dom/media/gmp/GMPParent.cpp
@@ -559,37 +559,53 @@ 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 (const GMPCapability& capabilities : aCapabilities) {
+ if (!capabilities.mAPIName.Equals(aAPI)) {
continue;
}
- nsTArray<nsCString>& tags = mCapabilities[i].mAPITags;
- for (uint32_t j = 0; j < tags.Length(); j++) {
- if (tags[j].Equals(aTag)) {
+ for (const nsCString& tag : capabilities.mAPITags) {
+ if (tag.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 (tag.Equals(kEMEKeySystemClearkey)) {
+ if (capabilities.mAPIName.EqualsLiteral(GMP_API_VIDEO_DECODER)) {
if (!WMFDecoderModule::HasH264()) {
continue;
}
- } else if (mCapabilities[i].mAPIName.EqualsLiteral(GMP_API_AUDIO_DECODER)) {
+ } else if (capabilities.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
};
@@ -105,18 +113,16 @@ public:
bool IsMarkedForDeletion();
// Called by the GMPService to forcibly close active de/encoders at shutdown
void Shutdown();
// This must not be called while we're in the middle of abnormal ActorDestroy
void DeleteProcess();
- bool SupportsAPI(const nsCString& aAPI, const nsCString& aTag);
-
GMPState State() const;
nsIThread* GMPThread();
// A GMP can either be a single instance shared across all NodeIds (like
// in the OpenH264 case), or we can require a new plugin instance for every
// NodeIds running the plugin (as in the EME plugin case).
//
// A NodeId is a hash of the ($urlBarOrigin, $ownerDocOrigin) pair.
--- a/dom/media/gmp/GMPServiceChild.cpp
+++ b/dom/media/gmp/GMPServiceChild.cpp
@@ -209,28 +209,33 @@ GeckoMediaPluginServiceChild::UpdateGMPC
}
NS_IMETHODIMP
GeckoMediaPluginServiceChild::GetPluginVersionForAPI(const nsACString& aAPI,
nsTArray<nsCString>* aTags,
bool* aHasPlugin,
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;
}
- MOZ_ASSERT(NS_IsMainThread());
+ nsCString api(aAPI);
+ for (const GMPCapabilityAndVersion& plugin : *sGMPCapabilities) {
+ if (GMPCapability::Supports(plugin.mCapabilities, api, *aTags)) {
+ aOutVersion = plugin.mVersion;
+ *aHasPlugin = true;
+ return NS_OK;
+ }
+ }
- nsCString version;
- bool ok = contentChild->SendGetGMPPluginVersionForAPI(nsCString(aAPI), *aTags,
- aHasPlugin, &version);
- aOutVersion = version;
- return ok ? NS_OK : NS_ERROR_FAILURE;
+ *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;