Bug 998863: Asynchronous Plugin Initialization, Part 9: PluginModuleParent changes; r=jimm

This commit is contained in:
Aaron Klotz 2014-12-29 16:13:54 -07:00
parent d9fc63ab86
commit 66e006ee8b
9 changed files with 816 additions and 178 deletions

View File

@ -951,7 +951,7 @@ mozilla::plugins::PPluginModuleParent*
ContentChild::AllocPPluginModuleParent(mozilla::ipc::Transport* aTransport, ContentChild::AllocPPluginModuleParent(mozilla::ipc::Transport* aTransport,
base::ProcessId aOtherProcess) base::ProcessId aOtherProcess)
{ {
return plugins::PluginModuleContentParent::Create(aTransport, aOtherProcess); return plugins::PluginModuleContentParent::Initialize(aTransport, aOtherProcess);
} }
PContentBridgeChild* PContentBridgeChild*
@ -2474,6 +2474,21 @@ ContentChild::RecvGetProfile(nsCString* aProfile)
return true; return true;
} }
bool
ContentChild::RecvLoadPluginResult(const uint32_t& aPluginId, const bool& aResult)
{
plugins::PluginModuleContentParent::OnLoadPluginResult(aPluginId, aResult);
return true;
}
bool
ContentChild::RecvAssociatePluginId(const uint32_t& aPluginId,
const base::ProcessId& aProcessId)
{
plugins::PluginModuleContentParent::AssociatePluginId(aPluginId, aProcessId);
return true;
}
PBrowserOrId PBrowserOrId
ContentChild::GetBrowserOrId(TabChild* aTabChild) ContentChild::GetBrowserOrId(TabChild* aTabChild)
{ {

View File

@ -362,6 +362,11 @@ public:
virtual bool RecvOnAppThemeChanged() MOZ_OVERRIDE; virtual bool RecvOnAppThemeChanged() MOZ_OVERRIDE;
virtual bool RecvAssociatePluginId(const uint32_t& aPluginId,
const base::ProcessId& aProcessId) MOZ_OVERRIDE;
virtual bool RecvLoadPluginResult(const uint32_t& aPluginId,
const bool& aResult) MOZ_OVERRIDE;
virtual bool RecvStartProfiler(const uint32_t& aEntries, virtual bool RecvStartProfiler(const uint32_t& aEntries,
const double& aInterval, const double& aInterval,
const nsTArray<nsCString>& aFeatures, const nsTArray<nsCString>& aFeatures,

View File

@ -59,6 +59,7 @@ using struct ChromePackage from "mozilla/chrome/RegistryMessageUtils.h";
using struct ResourceMapping from "mozilla/chrome/RegistryMessageUtils.h"; using struct ResourceMapping from "mozilla/chrome/RegistryMessageUtils.h";
using struct OverrideMapping from "mozilla/chrome/RegistryMessageUtils.h"; using struct OverrideMapping from "mozilla/chrome/RegistryMessageUtils.h";
using base::ChildPrivileges from "base/process_util.h"; using base::ChildPrivileges from "base/process_util.h";
using base::ProcessId from "base/process.h";
using struct IPC::Permission from "mozilla/net/NeckoMessageUtils.h"; using struct IPC::Permission from "mozilla/net/NeckoMessageUtils.h";
using class IPC::Principal from "mozilla/dom/PermissionMessageUtils.h"; using class IPC::Principal from "mozilla/dom/PermissionMessageUtils.h";
using struct mozilla::null_t from "ipc/IPCMessageUtils.h"; using struct mozilla::null_t from "ipc/IPCMessageUtils.h";
@ -518,6 +519,19 @@ child:
*/ */
OnAppThemeChanged(); OnAppThemeChanged();
/**
* Called during plugin initialization to map a plugin id to a child process
* id.
*/
async AssociatePluginId(uint32_t aPluginId, ProcessId aProcessId);
/**
* This call is used by async plugin initialization to notify the
* PluginModuleContentParent that the PluginModuleChromeParent's async
* init has completed.
*/
async LoadPluginResult(uint32_t aPluginId, bool aResult);
/** /**
* Control the Gecko Profiler in the child process. * Control the Gecko Profiler in the child process.
*/ */

View File

@ -167,11 +167,7 @@ PluginInstanceParent::AllocPBrowserStreamParent(const nsCString& url,
const uint32_t& length, const uint32_t& length,
const uint32_t& lastmodified, const uint32_t& lastmodified,
PStreamNotifyParent* notifyData, PStreamNotifyParent* notifyData,
const nsCString& headers, const nsCString& headers)
const nsCString& mimeType,
const bool& seekable,
NPError* rv,
uint16_t *stype)
{ {
NS_RUNTIMEABORT("Not reachable"); NS_RUNTIMEABORT("Not reachable");
return nullptr; return nullptr;

View File

@ -74,11 +74,8 @@ public:
const uint32_t& length, const uint32_t& length,
const uint32_t& lastmodified, const uint32_t& lastmodified,
PStreamNotifyParent* notifyData, PStreamNotifyParent* notifyData,
const nsCString& headers, const nsCString& headers)
const nsCString& mimeType, MOZ_OVERRIDE;
const bool& seekable,
NPError* rv,
uint16_t *stype) MOZ_OVERRIDE;
virtual bool virtual bool
DeallocPBrowserStreamParent(PBrowserStreamParent* stream) MOZ_OVERRIDE; DeallocPBrowserStreamParent(PBrowserStreamParent* stream) MOZ_OVERRIDE;

File diff suppressed because it is too large Load Diff

View File

@ -40,6 +40,7 @@ namespace plugins {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
class BrowserStreamParent; class BrowserStreamParent;
class PluginAsyncSurrogate;
class PluginInstanceParent; class PluginInstanceParent;
#ifdef XP_WIN #ifdef XP_WIN
@ -79,8 +80,8 @@ protected:
AllocPPluginInstanceParent(const nsCString& aMimeType, AllocPPluginInstanceParent(const nsCString& aMimeType,
const uint16_t& aMode, const uint16_t& aMode,
const InfallibleTArray<nsCString>& aNames, const InfallibleTArray<nsCString>& aNames,
const InfallibleTArray<nsCString>& aValues, const InfallibleTArray<nsCString>& aValues)
NPError* rv) MOZ_OVERRIDE; MOZ_OVERRIDE;
virtual bool virtual bool
DeallocPPluginInstanceParent(PPluginInstanceParent* aActor) MOZ_OVERRIDE; DeallocPPluginInstanceParent(PPluginInstanceParent* aActor) MOZ_OVERRIDE;
@ -89,6 +90,13 @@ public:
explicit PluginModuleParent(bool aIsChrome); explicit PluginModuleParent(bool aIsChrome);
virtual ~PluginModuleParent(); virtual ~PluginModuleParent();
bool RemovePendingSurrogate(const nsRefPtr<PluginAsyncSurrogate>& aSurrogate);
/** @return the state of the pref that controls async plugin init */
bool IsStartingAsync() const { return mIsStartingAsync; }
/** @return whether this modules NP_Initialize has successfully completed
executing */
bool IsInitialized() const { return mNPInitialized; }
bool IsChrome() const { return mIsChrome; } bool IsChrome() const { return mIsChrome; }
virtual void SetPlugin(nsNPAPIPlugin* plugin) MOZ_OVERRIDE virtual void SetPlugin(nsNPAPIPlugin* plugin) MOZ_OVERRIDE
@ -108,6 +116,8 @@ public:
void ProcessRemoteNativeEventsInInterruptCall(); void ProcessRemoteNativeEventsInInterruptCall();
virtual bool WaitForIPCConnection() { return true; }
nsCString GetHistogramKey() const { nsCString GetHistogramKey() const {
return mPluginName + mPluginVersion; return mPluginName + mPluginVersion;
} }
@ -159,8 +169,11 @@ protected:
virtual bool virtual bool
RecvNPN_ReloadPlugins(const bool& aReloadPages) MOZ_OVERRIDE; RecvNPN_ReloadPlugins(const bool& aReloadPages) MOZ_OVERRIDE;
static PluginInstanceParent* InstCast(NPP instance); virtual bool
static BrowserStreamParent* StreamCast(NPP instance, NPStream* s); RecvNP_InitializeResult(const NPError& aError) MOZ_OVERRIDE;
static BrowserStreamParent* StreamCast(NPP instance, NPStream* s,
PluginAsyncSurrogate** aSurrogate = nullptr);
protected: protected:
virtual void UpdatePluginTimeout() {} virtual void UpdatePluginTimeout() {}
@ -169,6 +182,11 @@ protected:
void SetPluginFuncs(NPPluginFuncs* aFuncs); void SetPluginFuncs(NPPluginFuncs* aFuncs);
nsresult NPP_NewInternal(NPMIMEType pluginType, NPP instance, uint16_t mode,
InfallibleTArray<nsCString>& names,
InfallibleTArray<nsCString>& values,
NPSavedData* saved, NPError* error);
// NPP-like API that Gecko calls are trampolined into. These // NPP-like API that Gecko calls are trampolined into. These
// messages then get forwarded along to the plugin instance, // messages then get forwarded along to the plugin instance,
// and then eventually the child process. // and then eventually the child process.
@ -235,8 +253,11 @@ protected:
virtual nsresult ContentsScaleFactorChanged(NPP instance, double aContentsScaleFactor); virtual nsresult ContentsScaleFactorChanged(NPP instance, double aContentsScaleFactor);
#endif #endif
void InitAsyncSurrogates();
protected: protected:
void NotifyPluginCrashed(); void NotifyPluginCrashed();
void OnInitFailure();
bool GetSetting(NPNVariable aVariable); bool GetSetting(NPNVariable aVariable);
void GetSettings(PluginSettings* aSettings); void GetSettings(PluginSettings* aSettings);
@ -245,7 +266,7 @@ protected:
bool mShutdown; bool mShutdown;
bool mClearSiteDataSupported; bool mClearSiteDataSupported;
bool mGetSitesWithDataSupported; bool mGetSitesWithDataSupported;
const NPNetscapeFuncs* mNPNIface; NPNetscapeFuncs* mNPNIface;
nsNPAPIPlugin* mPlugin; nsNPAPIPlugin* mPlugin;
ScopedMethodFactory<PluginModuleParent> mTaskFactory; ScopedMethodFactory<PluginModuleParent> mTaskFactory;
nsString mPluginDumpID; nsString mPluginDumpID;
@ -266,18 +287,29 @@ protected:
GetPluginDetails(nsACString& aPluginName, nsACString& aPluginVersion); GetPluginDetails(nsACString& aPluginName, nsACString& aPluginVersion);
friend class mozilla::dom::CrashReporterParent; friend class mozilla::dom::CrashReporterParent;
friend class mozilla::plugins::PluginAsyncSurrogate;
bool mIsStartingAsync;
bool mNPInitialized;
nsTArray<nsRefPtr<PluginAsyncSurrogate>> mSurrogateInstances;
nsresult mAsyncNewRv;
NPPluginFuncs* mAsyncInitPluginFuncs;
}; };
class PluginModuleContentParent : public PluginModuleParent class PluginModuleContentParent : public PluginModuleParent
{ {
public: public:
explicit PluginModuleContentParent();
static PluginLibrary* LoadModule(uint32_t aPluginId); static PluginLibrary* LoadModule(uint32_t aPluginId);
static PluginModuleContentParent* Create(mozilla::ipc::Transport* aTransport, static PluginModuleContentParent* Initialize(mozilla::ipc::Transport* aTransport,
base::ProcessId aOtherProcess); base::ProcessId aOtherProcess);
static void OnLoadPluginResult(const uint32_t& aPluginId, const bool& aResult);
static void AssociatePluginId(uint32_t aPluginId, base::ProcessId aProcessId);
private: private:
explicit PluginModuleContentParent();
#ifdef MOZ_CRASHREPORTER_INJECTOR #ifdef MOZ_CRASHREPORTER_INJECTOR
void OnCrash(DWORD processID) MOZ_OVERRIDE {} void OnCrash(DWORD processID) MOZ_OVERRIDE {}
@ -313,6 +345,17 @@ class PluginModuleChromeParent
OnHangUIContinue(); OnHangUIContinue();
#endif // XP_WIN #endif // XP_WIN
virtual bool WaitForIPCConnection() MOZ_OVERRIDE;
virtual bool
RecvNP_InitializeResult(const NPError& aError) MOZ_OVERRIDE;
void
SetContentParent(dom::ContentParent* aContentParent);
bool
SendAssociatePluginId();
void CachedSettingChanged(); void CachedSettingChanged();
private: private:
@ -341,8 +384,14 @@ private:
PluginProcessParent* Process() const { return mSubprocess; } PluginProcessParent* Process() const { return mSubprocess; }
base::ProcessHandle ChildProcessHandle() { return mSubprocess->GetChildProcessHandle(); } base::ProcessHandle ChildProcessHandle() { return mSubprocess->GetChildProcessHandle(); }
#if !defined(XP_UNIX) || defined(XP_MACOSX) || defined(MOZ_WIDGET_GONK) #if defined(XP_UNIX) && !defined(XP_MACOSX) && !defined(MOZ_WIDGET_GONK)
virtual nsresult NP_Initialize(NPNetscapeFuncs* bFuncs, NPError* error); virtual nsresult NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs, NPError* error) MOZ_OVERRIDE;
#else
virtual nsresult NP_Initialize(NPNetscapeFuncs* bFuncs, NPError* error) MOZ_OVERRIDE;
#endif
#if defined(XP_WIN) || defined(XP_MACOSX)
virtual nsresult NP_GetEntryPoints(NPPluginFuncs* pFuncs, NPError* error) MOZ_OVERRIDE;
#endif #endif
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE; virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;
@ -421,6 +470,7 @@ private:
#endif #endif
friend class mozilla::dom::CrashReporterParent; friend class mozilla::dom::CrashReporterParent;
friend class mozilla::plugins::PluginAsyncSurrogate;
#ifdef MOZ_CRASHREPORTER_INJECTOR #ifdef MOZ_CRASHREPORTER_INJECTOR
void InitializeInjector(); void InitializeInjector();
@ -431,7 +481,34 @@ private:
DWORD mFlashProcess2; DWORD mFlashProcess2;
#endif #endif
void OnProcessLaunched(const bool aSucceeded);
class LaunchedTask : public LaunchCompleteTask
{
public:
explicit LaunchedTask(PluginModuleChromeParent* aModule)
: mModule(aModule)
{
MOZ_ASSERT(aModule);
}
void Run() MOZ_OVERRIDE
{
mModule->OnProcessLaunched(mLaunchSucceeded);
}
private:
PluginModuleChromeParent* mModule;
};
friend class LaunchedTask;
bool mInitOnAsyncConnect;
nsresult mAsyncInitRv;
NPError mAsyncInitError;
dom::ContentParent* mContentParent;
nsCOMPtr<nsIObserver> mOfflineObserver; nsCOMPtr<nsIObserver> mOfflineObserver;
bool mIsFlashPlugin;
}; };
} // namespace plugins } // namespace plugins

View File

@ -129,6 +129,7 @@ PluginProcessParent::OnChannelConnected(int32_t peer_pid)
{ {
GeckoChildProcessHost::OnChannelConnected(peer_pid); GeckoChildProcessHost::OnChannelConnected(peer_pid);
if (mLaunchCompleteTask && !mRunCompleteTaskImmediately) { if (mLaunchCompleteTask && !mRunCompleteTaskImmediately) {
mLaunchCompleteTask->SetLaunchSucceeded();
mMainMsgLoop->PostTask(FROM_HERE, mLaunchCompleteTask.release()); mMainMsgLoop->PostTask(FROM_HERE, mLaunchCompleteTask.release());
} }
} }

View File

@ -2367,6 +2367,8 @@ pref("dom.ipc.plugins.reportCrashURL", true);
// Defaults to 30 seconds. // Defaults to 30 seconds.
pref("dom.ipc.plugins.unloadTimeoutSecs", 30); pref("dom.ipc.plugins.unloadTimeoutSecs", 30);
pref("dom.ipc.plugins.asyncInit", false);
pref("dom.ipc.processCount", 1); pref("dom.ipc.processCount", 1);
// Enable caching of Moz2D Path objects for SVG geometry elements // Enable caching of Moz2D Path objects for SVG geometry elements