Files
palemoon27/dom/plugins/ipc/PluginModuleParent.h
T
roytam1 e9ba40cf6b import changes from `dev' branch of rmottola/Arctic-Fox:
- Bug 1178833 - Fix for unified builds when a new file is added to layout/base. r=mstange (bf961c00fd)
- Bug 1178847 - Add a MobileViewportManager to manage setting the CSS viewport on B2G. r=botond,tn (937ba486fa)
- Bug 1178847 - Don't use the MobileViewportManager code on Mulet or Fennec yet. r=botond (3061b2c617)
- Bug 1168950. Add the document to DoProcessRestyles profile label. r=dbaron (2347b76411)
- Bug 1187792 - Don't set the SPCSPS unless meta-viewport or zooming is enabled. r=botond (a8f5ed1006)
- Bug 1193062 - Don't double-send target APZC confirmations that might race each other. r=kats (de48467401)
- Bug 1186004 - Add a pref to enable/disable APZ zooming behaviour. r=botond (fc3653c979)
- Bug 1193062 - Add a PAN_MOMENTUM state. r=kats (10c8bb1a5e)
- Bug 1148350 - Have ConvertToGecko use a live screen-to-apzc transform to avoid transform mismatches. r=botond (9eee9ea6f2)
- Bug 1169844 - Remove incorrect assertion and properly untransform wheel events for overscroll situations. r=botond (9b101b53bb)
- Bug 1169690 - Accelerate flings correctly in the presence of overscroll handoff. r=kats (49d55c05f4)
- Bug 1158424 - Extract a BreadthFirstSearch() helper function. r=kats (6a49498185)
- Bug 1158424 - Add APZCTreeManager::FindRootContentApzcForLayersId(). r=kats (d6c7ecf781)
- Bug 1158424 - Fix APZCTreeManager::GetMultitouchTarget(). r=kats (bf8571a4ca)
- Bug 1174205 - Make sure to acquire the tree lock before finding the multitouch target. r=botond (bdbd98f2c7)
- Bug 1211660 - Remove dead obj argument from two functions. r=Waldo. (efba5a2f8d)
- Bug 1158424 - Undeprecate HasNoParentWithSameLayersId(). r=kats (d994ea28f8)
- Fix AsyncCompositionManager not comparing layer tree IDs when finding scrollbar targets. (bug 1151169, r=kats) (c7dbc4776a)
- Bug 1163259. Make sure we don't look at the parent ref layer when looking for a layer with the frame metrics for a scrollbar. r=kats (8b99d2c830)
- Bug 1164340. Convert the scrollbar thumb ratio to a unitless ratio properly for non-zoomable scrollframes. r=botond (27f56cab56)
- Bug 1164340. Fix up some scrollbar related comments in AsyncCompositionManager. r=botond (b9d540bea9)
- Bug 1164767. Modify async scrollbar positioning code to deal with containerless root scrollables. r=botond (501d07592e)
- Bug 1158424 - Remove FrameMetrics::IsRootScrollable() (it just duplicated IsRootContent()). r=kats (672fd034b3)
- Bug 1120683 - Properly handle unapplying 3D projective transforms throughout APZ code. r=botond (a46612811a)
- Bug 1148868 - Make APZ wheel handling handle pixel scrolling on OS X. r=dvander, r=kats (da3bd34135)
- Bug 1193062 - Add fields to PanGestureInput and ScrollWheelInput. r=kats (716ba34e18)
- Bug 1189565 - Send resize events when backing scale factor changes. r=mstange (4e81a7bbf7)
- Bug 1193062 - Add nsCocoaUtils::ModifiersForEvent. r=smichaud (da67b22ff7)
- Bug 1016035 - Remove the ability to swipe vertically. r=kats (fa315e0b97)
- Bug 1016035 - Refactor the code that decides whether we want to start a swipe. r=kats (3091961328)
- Bug 1016035 - Make the threshold in AxisPhysicsMSDModel::IsFinished controllable by the caller. r=kip (76df4d85a2)
- Bug 1016035 - More swipe refactoring. r=kats (2abcd05b33)
- Bug 1016035 - Implement the swipe animation ourselves instead of calling the NSEvent trackSwipe API. r=kats (4842b2a728)
- Bug 1016035 - Move swipe tracking code into DispatchAPZWheelInputEvent. r=kats (bb1052b87c)
- Bug 1016035 - Also mark widgetWheelEvents that are handled by APZ with mCanStartSwipe. r=kats (21809b902d)
- Bug 1016035 - Put PanGestureInput events into a queue if they can end up as a swipe. r=kats (2ebac59047)
- Bug 1016035 - Split up MaybeTrackScrollEventAsSwipe into SendMayStartSwipe and TrackScrollEventAsSwipe. r=kats (ced10d9671)
- Bug 1016035 - Send MayStartSwipe event before sending the wheel event. r=kats (b3346b81fb)
- Fix some fields missing in the widget event IPC glue. (bug 1139711, r=kats) (1298b25705)
- Bug 1016035 - Add mCanTriggerSwipe and TriggersSwipe(). r=masayuki (664a059972)
- Bug 1016035 - Make APZEventState report defaultPrevented=true when the event started a swipe. r=kats (128d627ac7)
- Bug 1016035 - Set scroll overflow information on potential swipe start events that have been processed by APZ. r=masayuki (b5931f6320)
- Bug 1206801 - fix broken CONFIG['DEBUG'] checks in moz.build files; r=mshal (292d5ac709)
- Bug 1186424: Refactor AsmJSValidate.cpp in preparation for parallelization; r=luke (4868bc66ca)
- Bug 1129267 - Fix by backing out patch for bug 1118615. r=mstange (ea8aaba04e)
- Bug 1182411 Part 1: Make plugin quirks available to the Parent as well as the Child. r=jimm (1f2551a6b7)
- Bug 1228462 - "PluginQuirks.* uses DOS CRLF". r=jmathies (b569a6c6c8)
- Bug 1152300 - When focus shifts from a native plugin window to content, content needs to forward the request for focus change to chrome. r=enn (5bd811fadd)
- Bug 1185529: On Windows, ensure that NPAPI child window has the correct parent before setwindow is called. r=jimm (9d94fdf2ff)
- Bug 1182411 Part 2: Change winless popup surrogate to have its parent set in the chrome process. r=jimm (adee9bb012)
2022-02-02 12:04:50 +08:00

567 lines
18 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: sw=4 ts=4 et :
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_plugins_PluginModuleParent_h
#define mozilla_plugins_PluginModuleParent_h
#include "base/process.h"
#include "mozilla/FileUtils.h"
#include "mozilla/HangAnnotations.h"
#include "mozilla/PluginLibrary.h"
#include "mozilla/plugins/PluginProcessParent.h"
#include "mozilla/plugins/PPluginModuleParent.h"
#include "mozilla/plugins/PluginMessageUtils.h"
#include "mozilla/plugins/PluginTypes.h"
#include "mozilla/plugins/TaskFactory.h"
#include "mozilla/TimeStamp.h"
#include "npapi.h"
#include "npfunctions.h"
#include "nsAutoPtr.h"
#include "nsDataHashtable.h"
#include "nsHashKeys.h"
#include "nsIObserver.h"
#ifdef XP_WIN
#include "nsWindowsHelpers.h"
#endif
class nsIProfileSaveEvent;
class nsPluginTag;
namespace mozilla {
#ifdef MOZ_ENABLE_PROFILER_SPS
class ProfileGatherer;
#endif
namespace plugins {
//-----------------------------------------------------------------------------
class BrowserStreamParent;
class PluginAsyncSurrogate;
class PluginInstanceParent;
#ifdef XP_WIN
class PluginHangUIParent;
#endif
#ifdef MOZ_CRASHREPORTER_INJECTOR
class FinishInjectorInitTask;
#endif
/**
* PluginModuleParent
*
* This class implements the NPP API from the perspective of the rest
* of Gecko, forwarding NPP calls along to the child process that is
* actually running the plugin.
*
* This class /also/ implements a version of the NPN API, because the
* child process needs to make these calls back into Gecko proper.
* This class is responsible for "actually" making those function calls.
*
* If a plugin is running, there will always be one PluginModuleParent for it in
* the chrome process. In addition, any content process using the plugin will
* have its own PluginModuleParent. The subclasses PluginModuleChromeParent and
* PluginModuleContentParent implement functionality that is specific to one
* case or the other.
*/
class PluginModuleParent
: public PPluginModuleParent
, public PluginLibrary
{
protected:
typedef mozilla::PluginLibrary PluginLibrary;
PPluginInstanceParent*
AllocPPluginInstanceParent(const nsCString& aMimeType,
const uint16_t& aMode,
const InfallibleTArray<nsCString>& aNames,
const InfallibleTArray<nsCString>& aValues)
override;
virtual bool
DeallocPPluginInstanceParent(PPluginInstanceParent* aActor) override;
public:
explicit PluginModuleParent(bool aIsChrome);
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; }
virtual void SetPlugin(nsNPAPIPlugin* plugin) override
{
mPlugin = plugin;
}
virtual void ActorDestroy(ActorDestroyReason why) override;
const NPNetscapeFuncs* GetNetscapeFuncs() {
return mNPNIface;
}
bool OkToCleanup() const {
return !IsOnCxxStack();
}
void ProcessRemoteNativeEventsInInterruptCall() override;
virtual bool WaitForIPCConnection() { return true; }
nsCString GetHistogramKey() const {
return mPluginName + mPluginVersion;
}
virtual nsresult GetRunID(uint32_t* aRunID) override;
virtual void SetHasLocalInstance() override {
mHadLocalInstance = true;
}
int GetQuirks() { return mQuirks; }
protected:
virtual mozilla::ipc::RacyInterruptPolicy
MediateInterruptRace(const Message& parent, const Message& child) override
{
return MediateRace(parent, child);
}
virtual bool
RecvBackUpXResources(const FileDescriptor& aXSocketFd) override;
virtual bool AnswerProcessSomeEvents() override;
virtual bool
RecvProcessNativeEventsInInterruptCall() override;
virtual bool
RecvPluginShowWindow(const uint32_t& aWindowId, const bool& aModal,
const int32_t& aX, const int32_t& aY,
const size_t& aWidth, const size_t& aHeight) override;
virtual bool
RecvPluginHideWindow(const uint32_t& aWindowId) override;
virtual bool
RecvSetCursor(const NSCursorInfo& aCursorInfo) override;
virtual bool
RecvShowCursor(const bool& aShow) override;
virtual bool
RecvPushCursor(const NSCursorInfo& aCursorInfo) override;
virtual bool
RecvPopCursor() override;
virtual bool
RecvNPN_SetException(const nsCString& aMessage) override;
virtual bool
RecvNPN_ReloadPlugins(const bool& aReloadPages) override;
virtual bool
RecvNP_InitializeResult(const NPError& aError) override;
static BrowserStreamParent* StreamCast(NPP instance, NPStream* s,
PluginAsyncSurrogate** aSurrogate = nullptr);
protected:
void SetChildTimeout(const int32_t aChildTimeout);
static void TimeoutChanged(const char* aPref, void* aModule);
virtual void UpdatePluginTimeout() {}
virtual bool RecvNotifyContentModuleDestroyed() override { return true; }
virtual bool RecvProfile(const nsCString& aProfile) override { return true; }
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
// messages then get forwarded along to the plugin instance,
// and then eventually the child process.
static NPError NPP_Destroy(NPP instance, NPSavedData** save);
static NPError NPP_SetWindow(NPP instance, NPWindow* window);
static NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream,
NPBool seekable, uint16_t* stype);
static NPError NPP_DestroyStream(NPP instance,
NPStream* stream, NPReason reason);
static int32_t NPP_WriteReady(NPP instance, NPStream* stream);
static int32_t NPP_Write(NPP instance, NPStream* stream,
int32_t offset, int32_t len, void* buffer);
static void NPP_StreamAsFile(NPP instance,
NPStream* stream, const char* fname);
static void NPP_Print(NPP instance, NPPrint* platformPrint);
static int16_t NPP_HandleEvent(NPP instance, void* event);
static void NPP_URLNotify(NPP instance, const char* url,
NPReason reason, void* notifyData);
static NPError NPP_GetValue(NPP instance,
NPPVariable variable, void *ret_value);
static NPError NPP_SetValue(NPP instance, NPNVariable variable,
void *value);
static void NPP_URLRedirectNotify(NPP instance, const char* url,
int32_t status, void* notifyData);
virtual bool HasRequiredFunctions() override;
virtual nsresult AsyncSetWindow(NPP aInstance, NPWindow* aWindow) override;
virtual nsresult GetImageContainer(NPP aInstance, mozilla::layers::ImageContainer** aContainer) override;
virtual nsresult GetImageSize(NPP aInstance, nsIntSize* aSize) override;
virtual bool IsOOP() override { return true; }
virtual nsresult SetBackgroundUnknown(NPP instance) override;
virtual nsresult BeginUpdateBackground(NPP instance,
const nsIntRect& aRect,
gfxContext** aCtx) override;
virtual nsresult EndUpdateBackground(NPP instance,
gfxContext* aCtx,
const nsIntRect& aRect) override;
#if defined(XP_UNIX) && !defined(XP_MACOSX) && !defined(MOZ_WIDGET_GONK)
virtual nsresult NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs, NPError* error) override;
#else
virtual nsresult NP_Initialize(NPNetscapeFuncs* bFuncs, NPError* error) override;
#endif
virtual nsresult NP_Shutdown(NPError* error) override;
virtual nsresult NP_GetMIMEDescription(const char** mimeDesc) override;
virtual nsresult NP_GetValue(void *future, NPPVariable aVariable,
void *aValue, NPError* error) override;
#if defined(XP_WIN) || defined(XP_MACOSX)
virtual nsresult NP_GetEntryPoints(NPPluginFuncs* pFuncs, NPError* error) override;
#endif
virtual nsresult NPP_New(NPMIMEType pluginType, NPP instance,
uint16_t mode, int16_t argc, char* argn[],
char* argv[], NPSavedData* saved,
NPError* error) override;
virtual nsresult NPP_ClearSiteData(const char* site, uint64_t flags,
uint64_t maxAge) override;
virtual nsresult NPP_GetSitesWithData(InfallibleTArray<nsCString>& result) override;
private:
nsCString mPluginFilename;
int mQuirks;
void InitQuirksModes(const nsCString& aMimeType);
public:
#if defined(XP_MACOSX)
virtual nsresult IsRemoteDrawingCoreAnimation(NPP instance, bool *aDrawing) override;
virtual nsresult ContentsScaleFactorChanged(NPP instance, double aContentsScaleFactor) override;
#endif
void InitAsyncSurrogates();
protected:
void NotifyFlashHang();
void NotifyPluginCrashed();
void OnInitFailure();
bool MaybeRunDeferredShutdown();
bool DoShutdown(NPError* error);
bool GetSetting(NPNVariable aVariable);
void GetSettings(PluginSettings* aSettings);
bool mIsChrome;
bool mShutdown;
bool mHadLocalInstance;
bool mClearSiteDataSupported;
bool mGetSitesWithDataSupported;
NPNetscapeFuncs* mNPNIface;
NPPluginFuncs* mNPPIface;
nsNPAPIPlugin* mPlugin;
TaskFactory<PluginModuleParent> mTaskFactory;
nsString mPluginDumpID;
nsString mBrowserDumpID;
nsString mHangID;
nsRefPtr<nsIObserver> mProfilerObserver;
TimeDuration mTimeBlocked;
nsCString mPluginName;
nsCString mPluginVersion;
bool mIsFlashPlugin;
#ifdef MOZ_X11
// Dup of plugin's X socket, used to scope its resources to this
// object instead of the plugin process's lifetime
ScopedClose mPluginXSocketFdDup;
#endif
bool
GetPluginDetails();
friend class mozilla::plugins::PluginAsyncSurrogate;
bool mIsStartingAsync;
bool mNPInitialized;
bool mIsNPShutdownPending;
nsTArray<nsRefPtr<PluginAsyncSurrogate>> mSurrogateInstances;
nsresult mAsyncNewRv;
uint32_t mRunID;
};
class PluginModuleContentParent : public PluginModuleParent
{
public:
explicit PluginModuleContentParent();
static PluginLibrary* LoadModule(uint32_t aPluginId);
static PluginModuleContentParent* Initialize(mozilla::ipc::Transport* aTransport,
base::ProcessId aOtherProcess);
static void OnLoadPluginResult(const uint32_t& aPluginId, const bool& aResult);
static void AssociatePluginId(uint32_t aPluginId, base::ProcessId aProcessId);
virtual ~PluginModuleContentParent();
#if defined(XP_WIN) || defined(XP_MACOSX)
nsresult NP_Initialize(NPNetscapeFuncs* bFuncs, NPError* error) override;
#endif
private:
virtual bool ShouldContinueFromReplyTimeout() override;
virtual void OnExitedSyncSend() override;
static PluginModuleContentParent* sSavedModuleParent;
uint32_t mPluginId;
};
class PluginModuleChromeParent
: public PluginModuleParent
, public mozilla::HangMonitor::Annotator
{
public:
/**
* LoadModule
*
* This may or may not launch a plugin child process,
* and may or may not be very expensive.
*/
static PluginLibrary* LoadModule(const char* aFilePath, uint32_t aPluginId,
nsPluginTag* aPluginTag);
/**
* The following two functions are called by SetupBridge to determine
* whether an existing plugin module was reused, or whether a new module
* was instantiated by the plugin host.
*/
static void ClearInstantiationFlag() { sInstantiated = false; }
static bool DidInstantiate() { return sInstantiated; }
virtual ~PluginModuleChromeParent();
/*
* Terminates the plugin process associated with this plugin module. Also
* generates appropriate crash reports. Takes ownership of the file
* associated with aBrowserDumpId on success.
*
* @param aMsgLoop the main message pump associated with the module
* protocol.
* @param aMonitorDescription a string describing the hang monitor that
* is making this call. This string is added to the crash reporter
* annotations for the plugin process.
* @param aBrowserDumpId (optional) previously taken browser dump id. If
* provided TerminateChildProcess will use this browser dump file in
* generating a multi-process crash report. If not provided a browser
* dump will be taken at the time of this call.
*/
void TerminateChildProcess(MessageLoop* aMsgLoop,
const nsCString& aMonitorDescription,
const nsAString& aBrowserDumpId);
#ifdef XP_WIN
/**
* Called by Plugin Hang UI to notify that the user has clicked continue.
* Used for chrome hang annotations.
*/
void
OnHangUIContinue();
void
EvaluateHangUIState(const bool aReset);
#endif // XP_WIN
virtual bool WaitForIPCConnection() override;
virtual bool
RecvNP_InitializeResult(const NPError& aError) override;
void
SetContentParent(dom::ContentParent* aContentParent);
bool
SendAssociatePluginId();
void CachedSettingChanged();
void OnEnteredCall() override;
void OnExitedCall() override;
void OnEnteredSyncSend() override;
void OnExitedSyncSend() override;
#ifdef MOZ_ENABLE_PROFILER_SPS
void GatherAsyncProfile(mozilla::ProfileGatherer* aGatherer);
void GatheredAsyncProfile(nsIProfileSaveEvent* aSaveEvent);
#endif
virtual bool
RecvProfile(const nsCString& aProfile) override;
private:
virtual void
EnteredCxxStack() override;
void
ExitedCxxStack() override;
mozilla::ipc::IProtocol* GetInvokingProtocol();
PluginInstanceParent* GetManagingInstance(mozilla::ipc::IProtocol* aProtocol);
virtual void
AnnotateHang(mozilla::HangMonitor::HangAnnotations& aAnnotations) override;
virtual bool ShouldContinueFromReplyTimeout() override;
PluginProcessParent* Process() const { return mSubprocess; }
base::ProcessHandle ChildProcessHandle() { return mSubprocess->GetChildProcessHandle(); }
#if defined(XP_UNIX) && !defined(XP_MACOSX) && !defined(MOZ_WIDGET_GONK)
virtual nsresult NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs, NPError* error) override;
#else
virtual nsresult NP_Initialize(NPNetscapeFuncs* bFuncs, NPError* error) override;
#endif
#if defined(XP_WIN) || defined(XP_MACOSX)
virtual nsresult NP_GetEntryPoints(NPPluginFuncs* pFuncs, NPError* error) override;
#endif
virtual void ActorDestroy(ActorDestroyReason why) override;
// aFilePath is UTF8, not native!
explicit PluginModuleChromeParent(const char* aFilePath, uint32_t aPluginId,
int32_t aSandboxLevel);
void CleanupFromTimeout(const bool aByHangUI);
virtual void UpdatePluginTimeout() override;
#ifdef MOZ_ENABLE_PROFILER_SPS
void InitPluginProfiling();
void ShutdownPluginProfiling();
#endif
void RegisterSettingsCallbacks();
void UnregisterSettingsCallbacks();
virtual bool RecvNotifyContentModuleDestroyed() override;
static void CachedSettingChanged(const char* aPref, void* aModule);
PluginProcessParent* mSubprocess;
uint32_t mPluginId;
TaskFactory<PluginModuleChromeParent> mChromeTaskFactory;
enum HangAnnotationFlags
{
kInPluginCall = (1u << 0),
kHangUIShown = (1u << 1),
kHangUIContinued = (1u << 2),
kHangUIDontShow = (1u << 3)
};
Atomic<uint32_t> mHangAnnotationFlags;
mozilla::Mutex mHangAnnotatorMutex;
InfallibleTArray<mozilla::ipc::IProtocol*> mProtocolCallStack;
#ifdef XP_WIN
InfallibleTArray<float> mPluginCpuUsageOnHang;
PluginHangUIParent *mHangUIParent;
bool mHangUIEnabled;
bool mIsTimerReset;
int32_t mSandboxLevel;
/**
* Launches the Plugin Hang UI.
*
* @return true if plugin-hang-ui.exe has been successfully launched.
* false if the Plugin Hang UI is disabled, already showing,
* or the launch failed.
*/
bool
LaunchHangUI();
/**
* Finishes the Plugin Hang UI and cancels if it is being shown to the user.
*/
void
FinishHangUI();
#endif
friend class mozilla::plugins::PluginAsyncSurrogate;
#ifdef MOZ_CRASHREPORTER_INJECTOR
friend class mozilla::plugins::FinishInjectorInitTask;
void InitializeInjector();
void DoInjection(const nsAutoHandle& aSnapshot);
static DWORD WINAPI GetToolhelpSnapshot(LPVOID aContext);
void OnCrash(DWORD processID) override;
DWORD mFlashProcess1;
DWORD mFlashProcess2;
mozilla::plugins::FinishInjectorInitTask* mFinishInitTask;
#endif
void OnProcessLaunched(const bool aSucceeded);
class LaunchedTask : public LaunchCompleteTask
{
public:
explicit LaunchedTask(PluginModuleChromeParent* aModule)
: mModule(aModule)
{
MOZ_ASSERT(aModule);
}
void Run() override
{
mModule->OnProcessLaunched(mLaunchSucceeded);
}
private:
PluginModuleChromeParent* mModule;
};
friend class LaunchedTask;
bool mInitOnAsyncConnect;
nsresult mAsyncInitRv;
NPError mAsyncInitError;
dom::ContentParent* mContentParent;
nsCOMPtr<nsIObserver> mOfflineObserver;
#ifdef MOZ_ENABLE_PROFILER_SPS
nsRefPtr<mozilla::ProfileGatherer> mGatherer;
#endif
nsCString mProfile;
bool mIsBlocklisted;
static bool sInstantiated;
};
} // namespace plugins
} // namespace mozilla
#endif // mozilla_plugins_PluginModuleParent_h