/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* 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 dom_plugins_ipc_PluginAsyncSurrogate_h #define dom_plugins_ipc_PluginAsyncSurrogate_h #include "mozilla/UniquePtr.h" #include "npapi.h" #include "npfunctions.h" #include "npruntime.h" #include "nsISupportsImpl.h" #include "nsPluginHost.h" #include "nsString.h" #include "nsTArray.h" #include "PluginDataResolver.h" namespace mozilla { namespace plugins { struct ParentNPObject; class PluginInstanceParent; class PluginModuleParent; class PluginAsyncSurrogate : public PluginDataResolver { public: NS_INLINE_DECL_REFCOUNTING(PluginAsyncSurrogate) bool Init(NPMIMEType aPluginType, NPP aInstance, uint16_t aMode, int16_t aArgc, char* aArgn[], char* aArgv[]); nsresult NPP_New(NPError* aError); NPError NPP_Destroy(NPSavedData** aSave); NPError NPP_GetValue(NPPVariable aVariable, void* aRetval); NPError NPP_SetValue(NPNVariable aVariable, void* aValue); NPError NPP_NewStream(NPMIMEType aType, NPStream* aStream, NPBool aSeekable, uint16_t* aStype); NPError NPP_SetWindow(NPWindow* aWindow); nsresult AsyncSetWindow(NPWindow* aWindow); void NPP_Print(NPPrint* aPrintInfo); int16_t NPP_HandleEvent(void* aEvent); int32_t NPP_WriteReady(NPStream* aStream); NPError NPP_DestroyStream(NPStream* aStream, NPReason aReason); void OnInstanceCreated(PluginInstanceParent* aInstance); static bool Create(PluginModuleParent* aParent, NPMIMEType aPluginType, NPP aInstance, uint16_t aMode, int16_t aArgc, char* aArgn[], char* aArgv[]); static const NPClass* GetClass() { return &sNPClass; } static void NP_GetEntryPoints(NPPluginFuncs* aFuncs); static PluginAsyncSurrogate* Cast(NPP aInstance); static void NotifyDestroyPending(NPP aInstance); void NotifyDestroyPending(); virtual PluginAsyncSurrogate* GetAsyncSurrogate() { return this; } virtual PluginInstanceParent* GetInstance() { return nullptr; } NPP GetNPP(); bool GetPropertyHelper(NPObject* aObject, NPIdentifier aName, bool* aHasProperty, bool* aHasMethod, NPVariant* aResult); PluginModuleParent* GetParent() { return mParent; } bool IsDestroyPending() const { return mDestroyPending; } bool SetAcceptingCalls(bool aAccept) { bool prevState = mAcceptCalls; if (mInstantiated) { aAccept = true; } mAcceptCalls = aAccept; return prevState; } void AsyncCallDeparting(); void AsyncCallArriving(); void NotifyAsyncInitFailed(); void DestroyAsyncStream(NPStream* aStream); private: explicit PluginAsyncSurrogate(PluginModuleParent* aParent); virtual ~PluginAsyncSurrogate(); bool WaitForInit(); static bool SetStreamType(NPStream* aStream, uint16_t aStreamType); static NPError NPP_Destroy(NPP aInstance, NPSavedData** aSave); static NPError NPP_GetValue(NPP aInstance, NPPVariable aVariable, void* aRetval); static NPError NPP_SetValue(NPP aInstance, NPNVariable aVariable, void* aValue); static NPError NPP_NewStream(NPP aInstance, NPMIMEType aType, NPStream* aStream, NPBool aSeekable, uint16_t* aStype); static NPError NPP_SetWindow(NPP aInstance, NPWindow* aWindow); static void NPP_Print(NPP aInstance, NPPrint* aPrintInfo); static int16_t NPP_HandleEvent(NPP aInstance, void* aEvent); static int32_t NPP_WriteReady(NPP aInstance, NPStream* aStream); static NPError NPP_DestroyStream(NPP aInstance, NPStream* aStream, NPReason aReason); static NPObject* ScriptableAllocate(NPP aInstance, NPClass* aClass); static void ScriptableInvalidate(NPObject* aObject); static void ScriptableDeallocate(NPObject* aObject); static bool ScriptableHasMethod(NPObject* aObject, NPIdentifier aName); static bool ScriptableInvoke(NPObject* aObject, NPIdentifier aName, const NPVariant* aArgs, uint32_t aArgCount, NPVariant* aResult); static bool ScriptableInvokeDefault(NPObject* aObject, const NPVariant* aArgs, uint32_t aArgCount, NPVariant* aResult); static bool ScriptableHasProperty(NPObject* aObject, NPIdentifier aName); static bool ScriptableGetProperty(NPObject* aObject, NPIdentifier aName, NPVariant* aResult); static bool ScriptableSetProperty(NPObject* aObject, NPIdentifier aName, const NPVariant* aValue); static bool ScriptableRemoveProperty(NPObject* aObject, NPIdentifier aName); static bool ScriptableEnumerate(NPObject* aObject, NPIdentifier** aIdentifiers, uint32_t* aCount); static bool ScriptableConstruct(NPObject* aObject, const NPVariant* aArgs, uint32_t aArgCount, NPVariant* aResult); static nsNPAPIPluginStreamListener* GetStreamListener(NPStream* aStream); private: struct PendingNewStreamCall { PendingNewStreamCall(NPMIMEType aType, NPStream* aStream, NPBool aSeekable); ~PendingNewStreamCall() {} nsCString mType; NPStream* mStream; NPBool mSeekable; }; private: PluginModuleParent* mParent; // These values are used to construct the plugin instance nsCString mMimeType; mozilla::WeakPtr<nsNPAPIPluginInstance> mInstance; uint16_t mMode; InfallibleTArray<nsCString> mNames; InfallibleTArray<nsCString> mValues; // This is safe to store as a pointer because the spec says it will remain // valid until destruction or a subsequent NPP_SetWindow call. NPWindow* mWindow; nsTArray<PendingNewStreamCall> mPendingNewStreamCalls; UniquePtr<PluginDestructionGuard> mPluginDestructionGuard; bool mAcceptCalls; bool mInstantiated; bool mAsyncSetWindow; bool mInitCancelled; bool mDestroyPending; int32_t mAsyncCallsInFlight; static const NPClass sNPClass; }; struct AsyncNPObject : NPObject { explicit AsyncNPObject(PluginAsyncSurrogate* aSurrogate); ~AsyncNPObject(); NPObject* GetRealObject(); RefPtr<PluginAsyncSurrogate> mSurrogate; ParentNPObject* mRealObject; }; class MOZ_STACK_CLASS PushSurrogateAcceptCalls { public: explicit PushSurrogateAcceptCalls(PluginInstanceParent* aInstance); ~PushSurrogateAcceptCalls(); private: PluginAsyncSurrogate* mSurrogate; bool mPrevAcceptCallsState; }; } // namespace plugins } // namespace mozilla #endif // dom_plugins_ipc_PluginAsyncSurrogate_h