From b5801fa3f7e0691dd14b3e6811def893e906f82b Mon Sep 17 00:00:00 2001 From: Jim Mathies Date: Mon, 25 Jul 2016 15:45:29 -0500 Subject: [PATCH] Bug 1283274 - Disable windowless workaround if we detect a flash library that support async rendering. r=aklotz MozReview-Commit-ID: 3RubBjRoeEa --- dom/plugins/base/nsPluginHost.cpp | 2 ++ dom/plugins/base/nsPluginTags.cpp | 4 ++++ dom/plugins/base/nsPluginTags.h | 2 ++ dom/plugins/base/nsPluginsDir.h | 1 + dom/plugins/base/nsPluginsDirWin.cpp | 21 ++++++++++++++++++--- dom/plugins/ipc/PPluginModule.ipdl | 5 +++++ dom/plugins/ipc/PluginModuleChild.cpp | 24 ++++++++++++++++++++---- dom/plugins/ipc/PluginModuleChild.h | 4 ++++ dom/plugins/ipc/PluginModuleParent.cpp | 11 ++++++++--- dom/plugins/ipc/PluginTypes.ipdlh | 1 + 10 files changed, 65 insertions(+), 10 deletions(-) diff --git a/dom/plugins/base/nsPluginHost.cpp b/dom/plugins/base/nsPluginHost.cpp index 4ea8079cc86f..33cebf546901 100644 --- a/dom/plugins/base/nsPluginHost.cpp +++ b/dom/plugins/base/nsPluginHost.cpp @@ -2461,6 +2461,7 @@ nsPluginHost::FindPluginsInContent(bool aCreatePluginList, bool* aPluginsChanged tag.isJavaPlugin(), tag.isFlashPlugin(), tag.supportsAsyncInit(), + tag.supportsAsyncRender(), tag.lastModifiedTime(), tag.isFromExtension(), tag.sandboxLevel()); @@ -2701,6 +2702,7 @@ nsPluginHost::FindPluginsForContent(uint32_t aPluginEpoch, tag->mIsJavaPlugin, tag->mIsFlashPlugin, tag->mSupportsAsyncInit, + tag->mSupportsAsyncRender, tag->FileName(), tag->Version(), tag->mLastModifiedTime, diff --git a/dom/plugins/base/nsPluginTags.cpp b/dom/plugins/base/nsPluginTags.cpp index 1620935ecb3b..aa1dae42f7eb 100644 --- a/dom/plugins/base/nsPluginTags.cpp +++ b/dom/plugins/base/nsPluginTags.cpp @@ -236,6 +236,7 @@ nsPluginTag::nsPluginTag(nsPluginInfo* aPluginInfo, mIsJavaPlugin(false), mIsFlashPlugin(false), mSupportsAsyncInit(false), + mSupportsAsyncRender(false), mFullPath(aPluginInfo->fFullPath), mLastModifiedTime(aLastModifiedTime), mSandboxLevel(0), @@ -271,6 +272,7 @@ nsPluginTag::nsPluginTag(const char* aName, mIsJavaPlugin(false), mIsFlashPlugin(false), mSupportsAsyncInit(false), + mSupportsAsyncRender(false), mFullPath(aFullPath), mLastModifiedTime(aLastModifiedTime), mSandboxLevel(0), @@ -298,6 +300,7 @@ nsPluginTag::nsPluginTag(uint32_t aId, bool aIsJavaPlugin, bool aIsFlashPlugin, bool aSupportsAsyncInit, + bool aSupportsAsyncRender, int64_t aLastModifiedTime, bool aFromExtension, int32_t aSandboxLevel) @@ -309,6 +312,7 @@ nsPluginTag::nsPluginTag(uint32_t aId, mIsJavaPlugin(aIsJavaPlugin), mIsFlashPlugin(aIsFlashPlugin), mSupportsAsyncInit(aSupportsAsyncInit), + mSupportsAsyncRender(aSupportsAsyncRender), mLastModifiedTime(aLastModifiedTime), mSandboxLevel(aSandboxLevel), mNiceFileName(), diff --git a/dom/plugins/base/nsPluginTags.h b/dom/plugins/base/nsPluginTags.h index 71b1d7154d9d..f74b4f49bf44 100644 --- a/dom/plugins/base/nsPluginTags.h +++ b/dom/plugins/base/nsPluginTags.h @@ -133,6 +133,7 @@ public: bool aIsJavaPlugin, bool aIsFlashPlugin, bool aSupportsAsyncInit, + bool aSupportsAsyncRender, int64_t aLastModifiedTime, bool aFromExtension, int32_t aSandboxLevel); @@ -172,6 +173,7 @@ public: bool mIsJavaPlugin; bool mIsFlashPlugin; bool mSupportsAsyncInit; + bool mSupportsAsyncRender; nsCString mFullPath; // UTF-8 int64_t mLastModifiedTime; nsCOMPtr mUnloadTimer; diff --git a/dom/plugins/base/nsPluginsDir.h b/dom/plugins/base/nsPluginsDir.h index 998a47b2772f..925bbb48bf0a 100644 --- a/dom/plugins/base/nsPluginsDir.h +++ b/dom/plugins/base/nsPluginsDir.h @@ -34,6 +34,7 @@ struct nsPluginInfo { char* fFileName; char* fFullPath; char* fVersion; + bool fSupportsAsyncRender; }; /** diff --git a/dom/plugins/base/nsPluginsDirWin.cpp b/dom/plugins/base/nsPluginsDirWin.cpp index eb771af5cfb1..8c2d26ca2c7a 100644 --- a/dom/plugins/base/nsPluginsDirWin.cpp +++ b/dom/plugins/base/nsPluginsDirWin.cpp @@ -109,6 +109,20 @@ static char* GetVersion(void* verbuf) return nullptr; } +// Returns a boolean indicating if the key's value contains a string +// entry equal to "1" or "0". No entry for the key returns false. +static bool GetBooleanFlag(void* verbuf, const WCHAR* key, + UINT language, UINT codepage) +{ + char* flagStr = GetKeyValue(verbuf, key, language, codepage); + if (!flagStr) { + return false; + } + bool result = (PL_strncmp("1", flagStr, 1) == 0); + PL_strfree(flagStr); + return result; +} + static uint32_t CalculateVariantCount(char* mimeTypes) { uint32_t variants = 1; @@ -356,11 +370,12 @@ nsresult nsPluginFile::GetPluginInfo(nsPluginInfo& info, PRLibrary **outLibrary) if (::GetFileVersionInfoW(lpFilepath, 0, versionsize, verbuf)) { // TODO: get appropriately-localized info from plugin file - UINT lang = 1033; // language = English - UINT cp = 1252; // codepage = Western + UINT lang = 1033; // language = English, 0x409 + UINT cp = 1252; // codepage = Western, 0x4E4 info.fName = GetKeyValue(verbuf, L"ProductName", lang, cp); info.fDescription = GetKeyValue(verbuf, L"FileDescription", lang, cp); - + info.fSupportsAsyncRender = GetBooleanFlag(verbuf, L"AsyncDrawingSupport", lang, cp); + char *mimeType = GetKeyValue(verbuf, L"MIMEType", lang, cp); char *mimeDescription = GetKeyValue(verbuf, L"FileOpenName", lang, cp); char *extensions = GetKeyValue(verbuf, L"FileExtents", lang, cp); diff --git a/dom/plugins/ipc/PPluginModule.ipdl b/dom/plugins/ipc/PPluginModule.ipdl index 9d803b03755d..dd7efd52dfe2 100644 --- a/dom/plugins/ipc/PPluginModule.ipdl +++ b/dom/plugins/ipc/PPluginModule.ipdl @@ -48,6 +48,11 @@ both: child: async DisableFlashProtectedMode(); + // Sync query to check if a Flash library indicates it + // supports async rendering mode. + intr ModuleSupportsAsyncRender() + returns (bool result); + // Forces the child process to update its plugin function table. intr NP_GetEntryPoints() returns (NPError rv); diff --git a/dom/plugins/ipc/PluginModuleChild.cpp b/dom/plugins/ipc/PluginModuleChild.cpp index 27bbd609f0b9..23f6cfa479bc 100644 --- a/dom/plugins/ipc/PluginModuleChild.cpp +++ b/dom/plugins/ipc/PluginModuleChild.cpp @@ -123,6 +123,7 @@ PluginModuleChild::PluginModuleChild(bool aIsChrome) #ifdef OS_WIN , mNestedEventHook(nullptr) , mGlobalCallWndProcHook(nullptr) + , mAsyncRenderSupport(false) #endif { memset(&mFunctions, 0, sizeof(mFunctions)); @@ -243,26 +244,29 @@ PluginModuleChild::InitForChrome(const std::string& aPluginFilename, nsPluginFile pluginFile(localFile); -#if defined(MOZ_X11) || defined(XP_MACOSX) nsPluginInfo info = nsPluginInfo(); if (NS_FAILED(pluginFile.GetPluginInfo(info, &mLibrary))) { return false; } +#if defined(XP_WIN) + // XXX quirks isn't initialized yet + mAsyncRenderSupport = info.fSupportsAsyncRender; +#endif #if defined(MOZ_X11) NS_NAMED_LITERAL_CSTRING(flash10Head, "Shockwave Flash 10."); if (StringBeginsWith(nsDependentCString(info.fDescription), flash10Head)) { AddQuirk(QUIRK_FLASH_EXPOSE_COORD_TRANSLATION); } -#else // defined(XP_MACOSX) +#endif +#if defined(XP_MACOSX) const char* namePrefix = "Plugin Content"; char nameBuffer[80]; snprintf(nameBuffer, sizeof(nameBuffer), "%s (%s)", namePrefix, info.fName); mozilla::plugins::PluginUtilsOSX::SetProcessName(nameBuffer); #endif - pluginFile.FreePluginInfo(info); - +#if defined(MOZ_X11) || defined(XP_MACOSX) if (!mLibrary) #endif { @@ -2104,6 +2108,18 @@ PluginModuleChild::InitQuirksModes(const nsCString& aMimeType) mQuirks = GetQuirksFromMimeTypeAndFilename(aMimeType, mPluginFilename); } +bool +PluginModuleChild::AnswerModuleSupportsAsyncRender(bool* aResult) +{ +#if defined(XP_WIN) + *aResult = gChromeInstance->mAsyncRenderSupport; + return true; +#else + NS_NOTREACHED("Shouldn't get here!"); + return false; +#endif +} + bool PluginModuleChild::RecvPPluginInstanceConstructor(PPluginInstanceChild* aActor, const nsCString& aMimeType, diff --git a/dom/plugins/ipc/PluginModuleChild.h b/dom/plugins/ipc/PluginModuleChild.h index 0f7ec11605ec..25f4a091df64 100644 --- a/dom/plugins/ipc/PluginModuleChild.h +++ b/dom/plugins/ipc/PluginModuleChild.h @@ -144,6 +144,8 @@ protected: virtual bool RecvStopProfiler() override; virtual bool RecvGatherProfile() override; + virtual bool + AnswerModuleSupportsAsyncRender(bool* aResult) override; public: explicit PluginModuleChild(bool aIsChrome); virtual ~PluginModuleChild(); @@ -362,6 +364,8 @@ private: void ResetEventHooks(); HHOOK mNestedEventHook; HHOOK mGlobalCallWndProcHook; +public: + bool mAsyncRenderSupport; #endif }; diff --git a/dom/plugins/ipc/PluginModuleParent.cpp b/dom/plugins/ipc/PluginModuleParent.cpp index 71bcda3a10de..af377d4ca1ea 100755 --- a/dom/plugins/ipc/PluginModuleParent.cpp +++ b/dom/plugins/ipc/PluginModuleParent.cpp @@ -2714,11 +2714,16 @@ PluginModuleParent::NPP_NewInternal(NPMIMEType pluginType, NPP instance, if (mIsFlashPlugin) { parentInstance->InitMetadata(strPluginType, srcAttribute); #ifdef XP_WIN - // Force windowless mode (bug 1201904) when sandbox level >= 2 or Win64 + bool supportsAsyncRender = false; + CallModuleSupportsAsyncRender(&supportsAsyncRender); #ifdef _WIN64 - { + // For 64-bit builds force windowless if the flash library doesn't support + // async rendering regardless of sandbox level. + if (!supportsAsyncRender) { #else - if (mSandboxLevel >= 2) { + // For 32-bit builds force windowless if the flash library doesn't support + // async rendering and the sandbox level is 2 or greater. + if (!supportsAsyncRender && mSandboxLevel >= 2) { #endif NS_NAMED_LITERAL_CSTRING(wmodeAttributeName, "wmode"); NS_NAMED_LITERAL_CSTRING(opaqueAttributeValue, "opaque"); diff --git a/dom/plugins/ipc/PluginTypes.ipdlh b/dom/plugins/ipc/PluginTypes.ipdlh index 90b1046551f3..ed5ae0c71d01 100644 --- a/dom/plugins/ipc/PluginTypes.ipdlh +++ b/dom/plugins/ipc/PluginTypes.ipdlh @@ -17,6 +17,7 @@ struct PluginTag bool isJavaPlugin; bool isFlashPlugin; bool supportsAsyncInit; + bool supportsAsyncRender; // flash specific nsCString filename; nsCString version; int64_t lastModifiedTime;