Bug 1247763 - Remove info file parsing from GMP child process. r=gerald

The only reason we need to parse the info file in the GMP child process
is because we need to read the "Libs:" line so that the child process
can preload DLLs on Windows. We already parse the GMP info file in the
parent process, so we can remove the need to parse it again if we parse
the "Libs" field in the parent, and pass that through to the child.
This commit is contained in:
Chris Pearce 2016-02-24 07:21:47 +13:00
parent 6fba740086
commit 1db0b39f51
5 changed files with 32 additions and 43 deletions

View File

@ -137,17 +137,6 @@ GetPluginFile(const nsAString& aPluginPath,
}
#endif
static bool
GetInfoFile(const nsAString& aPluginPath,
nsCOMPtr<nsIFile>& aInfoFile)
{
nsAutoString baseName;
GetFileBase(aPluginPath, aInfoFile, baseName);
nsAutoString infoFileName = baseName + NS_LITERAL_STRING(".info");
aInfoFile->AppendRelativePath(infoFileName);
return true;
}
#if defined(XP_MACOSX) && defined(MOZ_GMP_SANDBOX)
static nsCString
GetNativeTarget(nsIFile* aFile)
@ -268,14 +257,6 @@ GMPChild::Init(const nsAString& aPluginPath,
mPluginPath = aPluginPath;
mSandboxVoucherPath = aVoucherPath;
nsCOMPtr<nsIFile> infoFile;
if (!GetInfoFile(mPluginPath, infoFile) || !infoFile) {
return false;
}
if (!mInfoParser.Init(infoFile)) {
return false;
}
return true;
}
@ -300,12 +281,12 @@ GMPChild::GetAPI(const char* aAPIName, void* aHostAPI, void** aPluginAPI)
return mGMPLoader->GetAPI(aAPIName, aHostAPI, aPluginAPI);
}
#ifdef XP_WIN
// Pre-load DLLs that need to be used by the EME plugin but that can't be
// loaded after the sandbox has started
bool
GMPChild::PreLoadLibraries()
GMPChild::RecvPreloadLibs(const nsCString& aLibs)
{
#ifdef XP_WIN
// Pre-load DLLs that need to be used by the EME plugin but that can't be
// loaded after the sandbox has started
// Items in this must be lowercase!
static const char* whitelist[] = {
"d3d9.dll", // Create an `IDirect3D9` to get adapter information
@ -319,12 +300,8 @@ GMPChild::PreLoadLibraries()
"msmpeg2vdec.dll", // H.264 decoder
};
if (!mInfoParser.Contains(NS_LITERAL_CSTRING("libraries"))) {
return false;
}
nsTArray<nsCString> libs;
SplitAt(", ", mInfoParser.Get(NS_LITERAL_CSTRING("libraries")), libs);
SplitAt(", ", aLibs, libs);
for (nsCString lib : libs) {
ToLowerCase(lib);
for (const char* whiteListedLib : whitelist) {
@ -334,10 +311,9 @@ GMPChild::PreLoadLibraries()
}
}
}
#endif
return true;
}
#endif
bool
GMPChild::GetUTF8LibPath(nsACString& aOutLibPath)
@ -373,9 +349,6 @@ GMPChild::AnswerStartPlugin()
{
LOGD("%s", __FUNCTION__);
#if defined(XP_WIN)
PreLoadLibraries();
#endif
if (!PreLoadPluginVoucher()) {
NS_WARNING("Plugin voucher failed to load!");
return false;

View File

@ -13,7 +13,6 @@
#include "gmp-async-shutdown.h"
#include "gmp-entrypoints.h"
#include "prlink.h"
#include "GMPUtils.h"
namespace mozilla {
namespace gmp {
@ -32,9 +31,6 @@ public:
base::ProcessId aParentPid,
MessageLoop* aIOLoop,
IPC::Channel* aChannel);
#ifdef XP_WIN
bool PreLoadLibraries();
#endif
MessageLoop* GMPMessageLoop();
// Main thread only.
@ -58,6 +54,7 @@ private:
bool RecvSetNodeId(const nsCString& aNodeId) override;
bool AnswerStartPlugin() override;
bool RecvPreloadLibs(const nsCString& aLibs) override;
PCrashReporterChild* AllocPCrashReporterChild(const NativeThreadId& aThread) override;
bool DeallocPCrashReporterChild(PCrashReporterChild*) override;
@ -94,7 +91,6 @@ private:
GMPLoader* mGMPLoader;
nsTArray<uint8_t> mPluginVoucher;
nsTArray<uint8_t> mSandboxVoucher;
GMPInfoFileParser mInfoParser;
};
} // namespace gmp

View File

@ -162,6 +162,17 @@ GMPParent::LoadProcess()
}
LOGD("%s: Sent node id to child process", __FUNCTION__);
#ifdef XP_WIN
if (!mLibs.IsEmpty()) {
bool ok = SendPreloadLibs(mLibs);
if (!ok) {
LOGD("%s: Failed to send preload-libs to child process", __FUNCTION__);
return NS_ERROR_FAILURE;
}
LOGD("%s: Sent preload-libs ('%s') to child process", __FUNCTION__, mLibs.get());
}
#endif
// Intr call to block initialization on plugin load.
ok = CallStartPlugin();
if (!ok) {
@ -731,7 +742,7 @@ GMPParent::DeallocPGMPTimerParent(PGMPTimerParent* aActor)
}
bool
ReadRequiredField(GMPInfoFileParser& aParser, const nsCString& aKey, nsACString& aOutValue)
ReadInfoField(GMPInfoFileParser& aParser, const nsCString& aKey, nsACString& aOutValue)
{
if (!aParser.Contains(aKey) || aParser.Get(aKey).IsEmpty()) {
return false;
@ -759,13 +770,18 @@ GMPParent::ReadGMPMetaData()
}
nsAutoCString apis;
if (!ReadRequiredField(parser, NS_LITERAL_CSTRING("name"), mDisplayName) ||
!ReadRequiredField(parser, NS_LITERAL_CSTRING("description"), mDescription) ||
!ReadRequiredField(parser, NS_LITERAL_CSTRING("version"), mVersion) ||
!ReadRequiredField(parser, NS_LITERAL_CSTRING("apis"), apis)) {
if (!ReadInfoField(parser, NS_LITERAL_CSTRING("name"), mDisplayName) ||
!ReadInfoField(parser, NS_LITERAL_CSTRING("description"), mDescription) ||
!ReadInfoField(parser, NS_LITERAL_CSTRING("version"), mVersion) ||
!ReadInfoField(parser, NS_LITERAL_CSTRING("apis"), apis)) {
return NS_ERROR_FAILURE;
}
#ifdef XP_WIN
// "Libraries" field is optional.
ReadInfoField(parser, NS_LITERAL_CSTRING("libraries"), mLibs);
#endif
nsTArray<nsCString> apiTokens;
SplitAt(", ", apis, apiTokens);
for (nsCString api : apiTokens) {

View File

@ -193,6 +193,9 @@ private:
nsCString mDisplayName; // name of plugin displayed to users
nsCString mDescription; // description of plugin for display to users
nsCString mVersion;
#ifdef XP_WIN
nsCString mLibs;
#endif
uint32_t mPluginId;
nsTArray<nsAutoPtr<GMPCapability>> mCapabilities;
GMPProcessParent* mProcess;

View File

@ -36,6 +36,7 @@ child:
async CrashPluginNow();
intr StartPlugin();
async SetNodeId(nsCString nodeId);
async PreloadLibs(nsCString libs);
async CloseActive();
};