diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp index 135e40048f71..b0f9ae79eb37 100644 --- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -951,7 +951,7 @@ mozilla::plugins::PPluginModuleParent* ContentChild::AllocPPluginModuleParent(mozilla::ipc::Transport* aTransport, base::ProcessId aOtherProcess) { - return plugins::PluginModuleContentParent::Initialize(aTransport, aOtherProcess); + return plugins::PluginModuleContentParent::Create(aTransport, aOtherProcess); } PContentBridgeChild* @@ -2470,21 +2470,6 @@ ContentChild::RecvGetProfile(nsCString* aProfile) 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 ContentChild::GetBrowserOrId(TabChild* aTabChild) { diff --git a/dom/ipc/ContentChild.h b/dom/ipc/ContentChild.h index 79d87dfa6b49..8315b6f180fa 100644 --- a/dom/ipc/ContentChild.h +++ b/dom/ipc/ContentChild.h @@ -360,11 +360,6 @@ public: 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, const double& aInterval, const nsTArray& aFeatures, diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl index d0dbacd53b3b..cd49ba903215 100644 --- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -59,7 +59,6 @@ using struct ChromePackage from "mozilla/chrome/RegistryMessageUtils.h"; using struct ResourceMapping from "mozilla/chrome/RegistryMessageUtils.h"; using struct OverrideMapping from "mozilla/chrome/RegistryMessageUtils.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 class IPC::Principal from "mozilla/dom/PermissionMessageUtils.h"; using struct mozilla::null_t from "ipc/IPCMessageUtils.h"; @@ -516,19 +515,6 @@ child: */ 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. */ diff --git a/dom/plugins/base/nsJSNPRuntime.cpp b/dom/plugins/base/nsJSNPRuntime.cpp index a50f21bd578f..9d63f0415afd 100644 --- a/dom/plugins/base/nsJSNPRuntime.cpp +++ b/dom/plugins/base/nsJSNPRuntime.cpp @@ -28,10 +28,7 @@ #include "js/HashTable.h" #include "mozilla/HashFunctions.h" #include "mozilla/dom/ScriptSettings.h" -#include "mozilla/plugins/PluginAsyncSurrogate.h" -using mozilla::plugins::AsyncNPObject; -using mozilla::plugins::PluginAsyncSurrogate; #define NPRUNTIME_JSCLASS_NAME "NPObject JS wrapper class" @@ -97,24 +94,10 @@ static nsTArray* sDelayedReleases; namespace { -inline void -CastNPObject(NPObject *aObj, PluginScriptableObjectParent*& aActor, - PluginAsyncSurrogate*& aSurrogate) -{ - aActor = nullptr; - aSurrogate = nullptr; - if (aObj->_class == PluginScriptableObjectParent::GetClass()) { - aActor = static_cast(aObj)->parent; - } else if (aObj->_class == PluginAsyncSurrogate::GetClass()) { - aSurrogate = static_cast(aObj)->mSurrogate; - } -} - inline bool NPObjectIsOutOfProcessProxy(NPObject *obj) { - return obj->_class == PluginScriptableObjectParent::GetClass() || - obj->_class == PluginAsyncSurrogate::GetClass(); + return obj->_class == PluginScriptableObjectParent::GetClass(); } } // anonymous namespace @@ -1406,23 +1389,15 @@ NPObjWrapper_GetProperty(JSContext *cx, JS::Handle obj, JS::Handle(npobj)->parent; - // actor and surrogate may be null if the plugin crashed. - if (!actor && !surrogate) + // actor may be null if the plugin crashed. + if (!actor) return false; - bool success = false; - if (surrogate) { - success = surrogate->GetPropertyHelper(npobj, identifier, &hasProperty, - &hasMethod, &npv); - } else if (actor) { - success = actor->GetPropertyHelper(identifier, &hasProperty, &hasMethod, - &npv); - } - + bool success = actor->GetPropertyHelper(identifier, &hasProperty, + &hasMethod, &npv); if (!ReportExceptionIfPending(cx)) { if (success) _releasevariantvalue(&npv); @@ -2278,35 +2253,3 @@ NPObjectMember_Trace(JSTracer *trc, JSObject *obj) "NPObject Member => npobjWrapper"); } } - -// static -bool -nsJSObjWrapper::HasOwnProperty(NPObject *npobj, NPIdentifier npid) -{ - NPP npp = NPPStack::Peek(); - dom::AutoJSAPI jsapi; - if (NS_WARN_IF(!jsapi.InitWithLegacyErrorReporting(GetGlobalObject(npp)))) { - return false; - } - JSContext *cx = jsapi.cx(); - - if (!npobj) { - ThrowJSException(cx, - "Null npobj in nsJSObjWrapper::NP_HasOwnProperty!"); - - return false; - } - - nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj; - bool found, ok = false; - - AutoJSExceptionReporter reporter(cx); - JS::Rooted jsobj(cx, npjsobj->mJSObj); - JSAutoCompartment ac(cx, jsobj); - - NS_ASSERTION(NPIdentifierIsInt(npid) || NPIdentifierIsString(npid), - "id must be either string or int!\n"); - JS::Rooted id(cx, NPIdentifierToJSId(npid)); - ok = ::JS_AlreadyHasOwnPropertyById(cx, jsobj, id, &found); - return ok && found; -} diff --git a/dom/plugins/base/nsJSNPRuntime.h b/dom/plugins/base/nsJSNPRuntime.h index e361b94e1879..7d1a5f5c197e 100644 --- a/dom/plugins/base/nsJSNPRuntime.h +++ b/dom/plugins/base/nsJSNPRuntime.h @@ -44,7 +44,6 @@ public: static NPObject *GetNewOrUsed(NPP npp, JSContext *cx, JS::Handle obj); - static bool HasOwnProperty(NPObject* npobj, NPIdentifier npid); protected: explicit nsJSObjWrapper(NPP npp); diff --git a/dom/plugins/base/nsNPAPIPluginInstance.cpp b/dom/plugins/base/nsNPAPIPluginInstance.cpp index cf16dce7a330..5d809fea64ea 100644 --- a/dom/plugins/base/nsNPAPIPluginInstance.cpp +++ b/dom/plugins/base/nsNPAPIPluginInstance.cpp @@ -523,7 +523,7 @@ nsNPAPIPluginInstance::Start() return NS_ERROR_FAILURE; } - return newResult; + return NS_OK; } nsresult nsNPAPIPluginInstance::SetWindow(NPWindow* window) diff --git a/dom/plugins/base/nsNPAPIPluginStreamListener.cpp b/dom/plugins/base/nsNPAPIPluginStreamListener.cpp index 1383f8563c52..aa4bfbdeb156 100644 --- a/dom/plugins/base/nsNPAPIPluginStreamListener.cpp +++ b/dom/plugins/base/nsNPAPIPluginStreamListener.cpp @@ -331,32 +331,20 @@ nsNPAPIPluginStreamListener::OnStartBinding(nsPluginStreamListenerPeer* streamPe if (error != NPERR_NO_ERROR) return NS_ERROR_FAILURE; - - if (streamType == nsPluginStreamListenerPeer::STREAM_TYPE_UNKNOWN) { - SuspendRequest(); - } else if (!SetStreamType(streamType, false)) { - return NS_ERROR_FAILURE; - } - - return NS_OK; -} - -bool -nsNPAPIPluginStreamListener::SetStreamType(uint16_t aType, bool aNeedsResume) -{ - switch(aType) + + switch(streamType) { case NP_NORMAL: - mStreamType = NP_NORMAL; + mStreamType = NP_NORMAL; break; case NP_ASFILEONLY: - mStreamType = NP_ASFILEONLY; + mStreamType = NP_ASFILEONLY; break; case NP_ASFILE: - mStreamType = NP_ASFILE; + mStreamType = NP_ASFILE; break; case NP_SEEK: - mStreamType = NP_SEEK; + mStreamType = NP_SEEK; // Seekable streams should continue to exist even after OnStopRequest // is fired, so we AddRef ourself an extra time and Release when the // plugin calls NPN_DestroyStream (CleanUpStream). If the plugin never @@ -365,16 +353,11 @@ nsNPAPIPluginStreamListener::SetStreamType(uint16_t aType, bool aNeedsResume) NS_ADDREF_THIS(); break; default: - return false; + return NS_ERROR_FAILURE; } + mStreamStarted = true; - if (aNeedsResume) { - if (mStreamListenerPeer) { - mStreamListenerPeer->OnStreamTypeSet(mStreamType); - } - ResumeRequest(); - } - return true; + return NS_OK; } void @@ -386,20 +369,18 @@ nsNPAPIPluginStreamListener::SuspendRequest() nsresult rv = StartDataPump(); if (NS_FAILED(rv)) return; - + mIsSuspended = true; if (mStreamListenerPeer) { - mStreamListenerPeer->SuspendRequests(); + mStreamListenerPeer->SuspendRequests(); } } void nsNPAPIPluginStreamListener::ResumeRequest() { - if (mStreamListenerPeer) { - mStreamListenerPeer->ResumeRequests(); - } + mStreamListenerPeer->ResumeRequests(); mIsSuspended = false; } @@ -409,7 +390,7 @@ nsNPAPIPluginStreamListener::StartDataPump() nsresult rv; mDataPumpTimer = do_CreateInstance("@mozilla.org/timer;1", &rv); NS_ENSURE_SUCCESS(rv, rv); - + // Start pumping data to the plugin every 100ms until it obeys and // eats the data. return mDataPumpTimer->InitWithCallback(this, 100, diff --git a/dom/plugins/base/nsNPAPIPluginStreamListener.h b/dom/plugins/base/nsNPAPIPluginStreamListener.h index 775bc9afabd1..01b19dfe09b4 100644 --- a/dom/plugins/base/nsNPAPIPluginStreamListener.h +++ b/dom/plugins/base/nsNPAPIPluginStreamListener.h @@ -83,7 +83,6 @@ public: nsresult OnStopBinding(nsPluginStreamListenerPeer* streamPeer, nsresult status); nsresult GetStreamType(int32_t *result); - bool SetStreamType(uint16_t aType, bool aNeedsResume = true); bool IsStarted(); nsresult CleanUpStream(NPReason reason); diff --git a/dom/plugins/base/nsPluginHost.cpp b/dom/plugins/base/nsPluginHost.cpp index b16313650a6f..7fa3671eb552 100644 --- a/dom/plugins/base/nsPluginHost.cpp +++ b/dom/plugins/base/nsPluginHost.cpp @@ -50,7 +50,6 @@ #include "nsPluginStreamListenerPeer.h" #include "mozilla/dom/ContentChild.h" #include "mozilla/LoadInfo.h" -#include "mozilla/plugins/PluginAsyncSurrogate.h" #include "mozilla/plugins/PluginBridge.h" #include "mozilla/plugins/PluginTypes.h" #include "mozilla/Preferences.h" @@ -111,7 +110,6 @@ using namespace mozilla; using mozilla::TimeStamp; using mozilla::plugins::PluginTag; -using mozilla::plugins::PluginAsyncSurrogate; // Null out a strong ref to a linked list iteratively to avoid // exhausting the stack (bug 486349). @@ -832,7 +830,6 @@ nsPluginHost::InstantiatePluginInstance(const char *aMimeType, nsIURI* aURL, if (NS_FAILED(rv)) { return NS_ERROR_FAILURE; } - const bool isAsyncInit = (rv == NS_PLUGIN_INIT_PENDING); nsRefPtr instance; rv = instanceOwner->GetInstance(getter_AddRefs(instance)); @@ -840,9 +837,11 @@ nsPluginHost::InstantiatePluginInstance(const char *aMimeType, nsIURI* aURL, return rv; } - // Async init plugins will initiate their own widget creation. - if (!isAsyncInit && instance) { - CreateWidget(instanceOwner); + if (instance) { + instanceOwner->CreateWidget(); + + // If we've got a native window, the let the plugin know about it. + instanceOwner->CallSetWindow(); } // At this point we consider instantiation to be successful. Do not return an error. @@ -3328,14 +3327,6 @@ nsresult nsPluginHost::NewPluginStreamListener(nsIURI* aURI, return NS_OK; } -void nsPluginHost::CreateWidget(nsPluginInstanceOwner* aOwner) -{ - aOwner->CreateWidget(); - - // If we've got a native window, the let the plugin know about it. - aOwner->CallSetWindow(); -} - NS_IMETHODIMP nsPluginHost::Observe(nsISupports *aSubject, const char *aTopic, const char16_t *someData) @@ -3963,12 +3954,6 @@ PluginDestructionGuard::PluginDestructionGuard(nsNPAPIPluginInstance *aInstance) Init(); } -PluginDestructionGuard::PluginDestructionGuard(PluginAsyncSurrogate *aSurrogate) - : mInstance(static_cast(aSurrogate->GetNPP()->ndata)) -{ - InitAsync(); -} - PluginDestructionGuard::PluginDestructionGuard(NPP npp) : mInstance(npp ? static_cast(npp->ndata) : nullptr) { diff --git a/dom/plugins/base/nsPluginHost.h b/dom/plugins/base/nsPluginHost.h index 8124dde36d07..092b8a9033bf 100644 --- a/dom/plugins/base/nsPluginHost.h +++ b/dom/plugins/base/nsPluginHost.h @@ -30,12 +30,6 @@ #include "nsCRT.h" #include "mozilla/plugins/PluginTypes.h" -namespace mozilla { -namespace plugins { -class PluginAsyncSurrogate; -} // namespace mozilla -} // namespace plugins - class nsNPAPIPlugin; class nsIComponentManager; class nsIFile; @@ -209,8 +203,6 @@ public: nsNPAPIPluginInstance* aInstance, nsIStreamListener **aStreamListener); - void CreateWidget(nsPluginInstanceOwner* aOwner); - private: friend class nsPluginUnloadRunnable; @@ -341,11 +333,11 @@ private: static nsPluginHost* sInst; }; -class PluginDestructionGuard : protected PRCList +class MOZ_STACK_CLASS PluginDestructionGuard : protected PRCList { public: explicit PluginDestructionGuard(nsNPAPIPluginInstance *aInstance); - explicit PluginDestructionGuard(mozilla::plugins::PluginAsyncSurrogate *aSurrogate); + explicit PluginDestructionGuard(NPP npp); ~PluginDestructionGuard(); @@ -363,18 +355,6 @@ protected: PR_INSERT_BEFORE(this, &sListHead); } - void InitAsync() - { - NS_ASSERTION(NS_IsMainThread(), "Should be on the main thread"); - - mDelayedDestroy = false; - - PR_INIT_CLIST(this); - // Instances with active surrogates must be inserted *after* sListHead so - // that they appear to be at the bottom of the stack - PR_INSERT_AFTER(this, &sListHead); - } - nsRefPtr mInstance; bool mDelayedDestroy; diff --git a/dom/plugins/base/nsPluginInstanceOwner.cpp b/dom/plugins/base/nsPluginInstanceOwner.cpp index 1e6e3f233f30..794fb6076e4e 100644 --- a/dom/plugins/base/nsPluginInstanceOwner.cpp +++ b/dom/plugins/base/nsPluginInstanceOwner.cpp @@ -1452,28 +1452,6 @@ void nsPluginInstanceOwner::ExitFullScreen(jobject view) { #endif -void -nsPluginInstanceOwner::NotifyHostAsyncInitFailed() -{ - nsCOMPtr content = do_QueryInterface(mContent); - content->StopPluginInstance(); -} - -void -nsPluginInstanceOwner::NotifyHostCreateWidget() -{ - mPluginHost->CreateWidget(this); -#ifdef XP_MACOSX - FixUpPluginWindow(ePluginPaintEnable); -#else - if (mPluginFrame) { - mPluginFrame->InvalidateFrame(); - } else { - CallSetWindow(); - } -#endif -} - nsresult nsPluginInstanceOwner::DispatchFocusToPlugin(nsIDOMEvent* aFocusEvent) { #ifdef MOZ_WIDGET_ANDROID @@ -3191,10 +3169,6 @@ nsPluginInstanceOwner::UpdateDocumentActiveState(bool aIsActive) NS_IMETHODIMP nsPluginInstanceOwner::CallSetWindow() { - if (!mWidgetCreationComplete) { - // No widget yet, we can't run this code - return NS_OK; - } if (mPluginFrame) { mPluginFrame->CallSetWindow(false); } else if (mInstance) { diff --git a/dom/plugins/base/nsPluginInstanceOwner.h b/dom/plugins/base/nsPluginInstanceOwner.h index a3e99d790758..acebe36ee40b 100644 --- a/dom/plugins/base/nsPluginInstanceOwner.h +++ b/dom/plugins/base/nsPluginInstanceOwner.h @@ -255,10 +255,7 @@ public: // Called from AndroidJNI when we removed the fullscreen view. static void ExitFullScreen(jobject view); #endif - - void NotifyHostAsyncInitFailed(); - void NotifyHostCreateWidget(); - + private: virtual ~nsPluginInstanceOwner(); diff --git a/dom/plugins/base/nsPluginStreamListenerPeer.cpp b/dom/plugins/base/nsPluginStreamListenerPeer.cpp index 1a4eb8cc42ce..3a72b31744a8 100644 --- a/dom/plugins/base/nsPluginStreamListenerPeer.cpp +++ b/dom/plugins/base/nsPluginStreamListenerPeer.cpp @@ -266,7 +266,6 @@ nsPluginStreamListenerPeer::nsPluginStreamListenerPeer() mHaveFiredOnStartRequest = false; mDataForwardToRequest = nullptr; - mUseLocalCache = false; mSeekable = false; mModified = 0; mStreamOffset = 0; @@ -534,9 +533,7 @@ nsPluginStreamListenerPeer::OnStartRequest(nsIRequest *request, // Set up the stream listener... rv = SetUpStreamListener(request, aURL); - if (NS_FAILED(rv)) { - return rv; - } + if (NS_FAILED(rv)) return rv; return rv; } @@ -1049,6 +1046,8 @@ nsresult nsPluginStreamListenerPeer::SetUpStreamListener(nsIRequest *request, mPStreamListener->SetStreamListenerPeer(this); + bool useLocalCache = false; + // get httpChannel to retrieve some info we need for nsIPluginStreamInfo setup nsCOMPtr channel = do_QueryInterface(request); nsCOMPtr httpChannel = do_QueryInterface(channel); @@ -1104,7 +1103,7 @@ nsresult nsPluginStreamListenerPeer::SetUpStreamListener(nsIRequest *request, nsAutoCString contentEncoding; if (NS_SUCCEEDED(httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("Content-Encoding"), contentEncoding))) { - mUseLocalCache = true; + useLocalCache = true; } else { // set seekability (seekable if the stream has a known length and if the // http server accepts byte ranges). @@ -1133,9 +1132,6 @@ nsresult nsPluginStreamListenerPeer::SetUpStreamListener(nsIRequest *request, } } - MOZ_ASSERT(!mRequest); - mRequest = request; - rv = mPStreamListener->OnStartBinding(this); mStartBinding = true; @@ -1143,37 +1139,23 @@ nsresult nsPluginStreamListenerPeer::SetUpStreamListener(nsIRequest *request, if (NS_FAILED(rv)) return rv; - int32_t streamType = NP_NORMAL; - mPStreamListener->GetStreamType(&streamType); + mPStreamListener->GetStreamType(&mStreamType); - if (streamType != STREAM_TYPE_UNKNOWN) { - OnStreamTypeSet(streamType); + if (!useLocalCache && mStreamType >= NP_ASFILE) { + // check it out if this is not a file channel. + nsCOMPtr fileChannel = do_QueryInterface(request); + if (!fileChannel) { + useLocalCache = true; + } + } + + if (useLocalCache) { + SetupPluginCacheFile(channel); } return NS_OK; } -void -nsPluginStreamListenerPeer::OnStreamTypeSet(const int32_t aStreamType) -{ - MOZ_ASSERT(mRequest); - mStreamType = aStreamType; - if (!mUseLocalCache && mStreamType >= NP_ASFILE) { - // check it out if this is not a file channel. - nsCOMPtr fileChannel = do_QueryInterface(mRequest); - if (!fileChannel) { - mUseLocalCache = true; - } - } - - if (mUseLocalCache) { - nsCOMPtr channel = do_QueryInterface(mRequest); - SetupPluginCacheFile(channel); - } -} - -const int32_t nsPluginStreamListenerPeer::STREAM_TYPE_UNKNOWN = UINT16_MAX; - nsresult nsPluginStreamListenerPeer::OnFileAvailable(nsIFile* aFile) { diff --git a/dom/plugins/base/nsPluginStreamListenerPeer.h b/dom/plugins/base/nsPluginStreamListenerPeer.h index 6a19562b7cd1..c940329676d4 100644 --- a/dom/plugins/base/nsPluginStreamListenerPeer.h +++ b/dom/plugins/base/nsPluginStreamListenerPeer.h @@ -128,11 +128,6 @@ public: requestsCopy[i]->Resume(); } - // Called by nsNPAPIPluginStreamListener - void OnStreamTypeSet(const int32_t aStreamType); - - static const int32_t STREAM_TYPE_UNKNOWN; - private: nsresult SetUpStreamListener(nsIRequest* request, nsIURI* aURL); nsresult SetupPluginCacheFile(nsIChannel* channel); @@ -164,8 +159,6 @@ private: nsDataHashtable* mDataForwardToRequest; nsCString mContentType; - bool mUseLocalCache; - nsCOMPtr mRequest; bool mSeekable; uint32_t mModified; nsRefPtr mPluginInstance; diff --git a/dom/plugins/ipc/BrowserStreamChild.cpp b/dom/plugins/ipc/BrowserStreamChild.cpp index 4a3ff033fab1..fecccf37204e 100644 --- a/dom/plugins/ipc/BrowserStreamChild.cpp +++ b/dom/plugins/ipc/BrowserStreamChild.cpp @@ -17,7 +17,11 @@ BrowserStreamChild::BrowserStreamChild(PluginInstanceChild* instance, const uint32_t& length, const uint32_t& lastmodified, StreamNotifyChild* notifyData, - const nsCString& headers) + const nsCString& headers, + const nsCString& mimeType, + const bool& seekable, + NPError* rv, + uint16_t* stype) : mInstance(instance) , mStreamStatus(kStreamOpen) , mDestroyPending(NOT_DESTROYED) @@ -30,9 +34,9 @@ BrowserStreamChild::BrowserStreamChild(PluginInstanceChild* instance, , mStreamNotify(notifyData) , mDeliveryTracker(MOZ_THIS_IN_INITIALIZER_LIST()) { - PLUGIN_LOG_DEBUG(("%s (%s, %i, %i, %p, %s)", FULLFUNCTION, + PLUGIN_LOG_DEBUG(("%s (%s, %i, %i, %p, %s, %s)", FULLFUNCTION, url.get(), length, lastmodified, (void*) notifyData, - headers.get())); + headers.get(), mimeType.get())); AssertPluginThread(); @@ -42,10 +46,8 @@ BrowserStreamChild::BrowserStreamChild(PluginInstanceChild* instance, mStream.end = length; mStream.lastmodified = lastmodified; mStream.headers = NullableStringGet(mHeaders); - if (notifyData) { + if (notifyData) mStream.notifyData = notifyData->mClosure; - notifyData->SetAssociatedStream(this); - } } NPError @@ -66,6 +68,9 @@ BrowserStreamChild::StreamConstructed( } else { mState = ALIVE; + + if (mStreamNotify) + mStreamNotify->SetAssociatedStream(this); } return rv; diff --git a/dom/plugins/ipc/BrowserStreamChild.h b/dom/plugins/ipc/BrowserStreamChild.h index 56a63943ca7d..d16b29b534c4 100644 --- a/dom/plugins/ipc/BrowserStreamChild.h +++ b/dom/plugins/ipc/BrowserStreamChild.h @@ -23,7 +23,11 @@ public: const uint32_t& length, const uint32_t& lastmodified, StreamNotifyChild* notifyData, - const nsCString& headers); + const nsCString& headers, + const nsCString& mimeType, + const bool& seekable, + NPError* rv, + uint16_t* stype); virtual ~BrowserStreamChild(); virtual bool IsBrowserStream() MOZ_OVERRIDE { return true; } diff --git a/dom/plugins/ipc/BrowserStreamParent.cpp b/dom/plugins/ipc/BrowserStreamParent.cpp index 508833d88d3d..1dc411916b43 100644 --- a/dom/plugins/ipc/BrowserStreamParent.cpp +++ b/dom/plugins/ipc/BrowserStreamParent.cpp @@ -5,7 +5,6 @@ #include "BrowserStreamParent.h" -#include "PluginAsyncSurrogate.h" #include "PluginInstanceParent.h" #include "nsNPAPIPlugin.h" @@ -22,15 +21,9 @@ BrowserStreamParent::BrowserStreamParent(PluginInstanceParent* npp, NPStream* stream) : mNPP(npp) , mStream(stream) - , mDeferredDestroyReason(NPRES_DONE) - , mState(INITIALIZING) + , mState(ALIVE) { mStream->pdata = static_cast(this); - nsNPAPIStreamWrapper* wrapper = - reinterpret_cast(mStream->ndata); - if (wrapper) { - mStreamListener = wrapper->GetStreamListener(); - } } BrowserStreamParent::~BrowserStreamParent() @@ -43,43 +36,6 @@ BrowserStreamParent::ActorDestroy(ActorDestroyReason aWhy) // Implement me! Bug 1005159 } -bool -BrowserStreamParent::RecvAsyncNPP_NewStreamResult(const NPError& rv, - const uint16_t& stype) -{ - PLUGIN_LOG_DEBUG_FUNCTION; - PluginAsyncSurrogate* surrogate = mNPP->GetAsyncSurrogate(); - MOZ_ASSERT(surrogate); - surrogate->AsyncCallArriving(); - nsRefPtr streamListener = mStreamListener.forget(); - if (mState == DEFERRING_DESTROY) { - // We've been asked to destroy ourselves before init was complete. - mState = DYING; - unused << SendNPP_DestroyStream(mDeferredDestroyReason); - return true; - } - - NPError error = rv; - if (error == NPERR_NO_ERROR) { - if (!streamListener) { - return false; - } - if (streamListener->SetStreamType(stype)) { - mState = ALIVE; - } else { - error = NPERR_GENERIC_ERROR; - } - } - - if (error != NPERR_NO_ERROR) { - // We need to clean up the stream - parent::_destroystream(mNPP->GetNPP(), mStream, NPRES_DONE); - unused << PBrowserStreamParent::Send__delete__(this); - } - - return true; -} - bool BrowserStreamParent::AnswerNPN_RequestRead(const IPCByteRanges& ranges, NPError* result) @@ -87,11 +43,6 @@ BrowserStreamParent::AnswerNPN_RequestRead(const IPCByteRanges& ranges, PLUGIN_LOG_DEBUG_FUNCTION; switch (mState) { - case INITIALIZING: - NS_ERROR("Requesting a read before initialization has completed"); - *result = NPERR_GENERIC_ERROR; - return false; - case ALIVE: break; @@ -144,16 +95,9 @@ BrowserStreamParent::RecvNPN_DestroyStream(const NPReason& reason) void BrowserStreamParent::NPP_DestroyStream(NPReason reason) { - NS_ASSERTION(ALIVE == mState || INITIALIZING == mState, - "NPP_DestroyStream called twice?"); - bool stillInitializing = INITIALIZING == mState; - if (stillInitializing) { - mState = DEFERRING_DESTROY; - mDeferredDestroyReason = reason; - } else { - mState = DYING; - unused << SendNPP_DestroyStream(reason); - } + NS_ASSERTION(ALIVE == mState, "NPP_DestroyStream called twice?"); + mState = DYING; + unused << SendNPP_DestroyStream(reason); } bool @@ -173,9 +117,6 @@ BrowserStreamParent::RecvStreamDestroyed() int32_t BrowserStreamParent::WriteReady() { - if (mState == INITIALIZING) { - return 0; - } return kSendDataChunk; } diff --git a/dom/plugins/ipc/BrowserStreamParent.h b/dom/plugins/ipc/BrowserStreamParent.h index 79cacbf5d2cc..726cc8517cea 100644 --- a/dom/plugins/ipc/BrowserStreamParent.h +++ b/dom/plugins/ipc/BrowserStreamParent.h @@ -8,8 +8,6 @@ #include "mozilla/plugins/PBrowserStreamParent.h" #include "mozilla/plugins/AStream.h" -#include "nsNPAPIPluginStreamListener.h" -#include "nsPluginStreamListenerPeer.h" namespace mozilla { namespace plugins { @@ -30,10 +28,6 @@ public: virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE; - virtual bool RecvAsyncNPP_NewStreamResult( - const NPError& rv, - const uint16_t& stype) MOZ_OVERRIDE; - virtual bool AnswerNPN_RequestRead(const IPCByteRanges& ranges, NPError* result) MOZ_OVERRIDE; @@ -47,25 +41,14 @@ public: void NPP_DestroyStream(NPReason reason); - void SetAlive() - { - if (mState == INITIALIZING) { - mState = ALIVE; - } - } - private: using PBrowserStreamParent::SendNPP_DestroyStream; PluginInstanceParent* mNPP; NPStream* mStream; nsCOMPtr mStreamPeer; - nsRefPtr mStreamListener; - NPReason mDeferredDestroyReason; enum { - INITIALIZING, - DEFERRING_DESTROY, ALIVE, DYING, DELETING diff --git a/dom/plugins/ipc/PBrowserStream.ipdl b/dom/plugins/ipc/PBrowserStream.ipdl index 8d927d60eedc..e28da3c3c493 100644 --- a/dom/plugins/ipc/PBrowserStream.ipdl +++ b/dom/plugins/ipc/PBrowserStream.ipdl @@ -36,7 +36,6 @@ child: async __delete__(); parent: - async AsyncNPP_NewStreamResult(NPError rv, uint16_t stype); intr NPN_RequestRead(IPCByteRanges ranges) returns (NPError result); async NPN_DestroyStream(NPReason reason); diff --git a/dom/plugins/ipc/PPluginInstance.ipdl b/dom/plugins/ipc/PPluginInstance.ipdl index 659805e99981..e289056b873d 100644 --- a/dom/plugins/ipc/PPluginInstance.ipdl +++ b/dom/plugins/ipc/PPluginInstance.ipdl @@ -207,29 +207,21 @@ parent: // them to use the plugin. sync NegotiatedCarbon(); - // Notifies the parent of its NPP_New result code. - async AsyncNPP_NewResult(NPError aResult); - both: async PPluginScriptableObject(); child: /* NPP_NewStream */ - async PBrowserStream(nsCString url, - uint32_t length, - uint32_t lastmodified, - nullable PStreamNotify notifyData, - nsCString headers); - - // Implements the legacy (synchronous) version of NPP_NewStream for when - // async plugin init is preffed off. - intr NPP_NewStream(PBrowserStream actor, nsCString mimeType, bool seekable) + intr PBrowserStream(nsCString url, + uint32_t length, + uint32_t lastmodified, + nullable PStreamNotify notifyData, + nsCString headers, + nsCString mimeType, + bool seekable) returns (NPError rv, uint16_t stype); - // Implements the async plugin init version of NPP_NewStream. - async AsyncNPP_NewStream(PBrowserStream actor, nsCString mimeType, bool seekable); - parent: /* NPN_NewStream */ intr PPluginStream(nsCString mimeType, diff --git a/dom/plugins/ipc/PPluginModule.ipdl b/dom/plugins/ipc/PPluginModule.ipdl index 203986502590..c54a0892ef2b 100644 --- a/dom/plugins/ipc/PPluginModule.ipdl +++ b/dom/plugins/ipc/PPluginModule.ipdl @@ -54,21 +54,12 @@ child: intr NP_Initialize(PluginSettings settings) returns (NPError rv); - async AsyncNP_Initialize(PluginSettings settings); - - async PPluginInstance(nsCString aMimeType, - uint16_t aMode, - nsCString[] aNames, - nsCString[] aValues); - - // Implements the synchronous version of NPP_New for when async plugin init - // is preffed off. - intr SyncNPP_New(PPluginInstance aActor) + intr PPluginInstance(nsCString aMimeType, + uint16_t aMode, + nsCString[] aNames, + nsCString[] aValues) returns (NPError rv); - // Implements the async plugin init version of NPP_New. - async AsyncNPP_New(PPluginInstance aActor); - intr NP_Shutdown() returns (NPError rv); @@ -98,15 +89,12 @@ child: async StartProfiler(uint32_t aEntries, double aInterval, nsCString[] aFeatures, nsCString[] aThreadNameFilters); async StopProfiler(); - intr GetProfile() returns (nsCString aProfile); async SettingChanged(PluginSettings settings); parent: - async NP_InitializeResult(NPError aError); - /** * This message is only used on X11 platforms. * diff --git a/dom/plugins/ipc/PluginAsyncSurrogate.cpp b/dom/plugins/ipc/PluginAsyncSurrogate.cpp deleted file mode 100644 index 9f7ab4bbe26f..000000000000 --- a/dom/plugins/ipc/PluginAsyncSurrogate.cpp +++ /dev/null @@ -1,882 +0,0 @@ -/* -*- 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/. */ - -#include "PluginAsyncSurrogate.h" - -#include "base/message_loop.h" -#include "base/message_pump_default.h" -#include "mozilla/dom/ContentChild.h" -#include "mozilla/plugins/PluginInstanceParent.h" -#include "mozilla/plugins/PluginModuleParent.h" -#include "mozilla/plugins/PluginScriptableObjectParent.h" -#include "mozilla/Telemetry.h" -#include "nsJSNPRuntime.h" -#include "nsNPAPIPlugin.h" -#include "nsNPAPIPluginInstance.h" -#include "nsNPAPIPluginStreamListener.h" -#include "nsPluginInstanceOwner.h" -#include "nsPluginStreamListenerPeer.h" -#include "npruntime.h" -#include "nsThreadUtils.h" -#include "PluginMessageUtils.h" - -namespace mozilla { -namespace plugins { - -AsyncNPObject::AsyncNPObject(PluginAsyncSurrogate* aSurrogate) - : NPObject() - , mSurrogate(aSurrogate) - , mRealObject(nullptr) -{ -} - -AsyncNPObject::~AsyncNPObject() -{ - if (mRealObject) { - parent::_releaseobject(mRealObject); - mRealObject = nullptr; - } -} - -NPObject* -AsyncNPObject::GetRealObject() -{ - if (mRealObject) { - return mRealObject; - } - PluginInstanceParent* instance = PluginInstanceParent::Cast(mSurrogate->GetNPP()); - if (!instance) { - return nullptr; - } - NPError err = instance->NPP_GetValue(NPPVpluginScriptableNPObject, - &mRealObject); - if (err != NPERR_NO_ERROR) { - return nullptr; - } - return mRealObject; -} - -class MOZ_STACK_CLASS RecursionGuard -{ -public: - RecursionGuard() - : mIsRecursive(sHasEntered) - { - if (!mIsRecursive) { - sHasEntered = true; - } - } - - ~RecursionGuard() - { - if (!mIsRecursive) { - sHasEntered = false; - } - } - - inline bool - IsRecursive() - { - return mIsRecursive; - } - -private: - bool mIsRecursive; - static bool sHasEntered; -}; - -bool RecursionGuard::sHasEntered = false; - -PluginAsyncSurrogate::PluginAsyncSurrogate(PluginModuleParent* aParent) - : mParent(aParent) - , mInstance(nullptr) - , mMode(0) - , mWindow(nullptr) - , mAcceptCalls(false) - , mInstantiated(false) - , mAsyncSetWindow(false) - , mInitCancelled(false) - , mAsyncCallsInFlight(0) -{ - MOZ_ASSERT(aParent); -} - -PluginAsyncSurrogate::~PluginAsyncSurrogate() -{ -} - -bool -PluginAsyncSurrogate::Init(NPMIMEType aPluginType, NPP aInstance, uint16_t aMode, - int16_t aArgc, char* aArgn[], char* aArgv[]) -{ - mMimeType = aPluginType; - mInstance = aInstance; - mMode = aMode; - for (int i = 0; i < aArgc; ++i) { - mNames.AppendElement(NullableString(aArgn[i])); - mValues.AppendElement(NullableString(aArgv[i])); - } - return true; -} - -/* static */ bool -PluginAsyncSurrogate::Create(PluginModuleParent* aParent, NPMIMEType aPluginType, - NPP aInstance, uint16_t aMode, int16_t aArgc, - char* aArgn[], char* aArgv[]) -{ - nsRefPtr surrogate(new PluginAsyncSurrogate(aParent)); - if (!surrogate->Init(aPluginType, aInstance, aMode, aArgc, aArgn, aArgv)) { - return false; - } - PluginAsyncSurrogate* rawSurrogate = nullptr; - surrogate.forget(&rawSurrogate); - aInstance->pdata = static_cast(rawSurrogate); - return true; -} - -/* static */ PluginAsyncSurrogate* -PluginAsyncSurrogate::Cast(NPP aInstance) -{ - MOZ_ASSERT(aInstance); - PluginDataResolver* resolver = - reinterpret_cast(aInstance->pdata); - if (!resolver) { - return nullptr; - } - return resolver->GetAsyncSurrogate(); -} - -nsresult -PluginAsyncSurrogate::NPP_New(NPError* aError) -{ - nsresult rv = mParent->NPP_NewInternal(mMimeType.BeginWriting(), mInstance, - mMode, mNames, mValues, nullptr, - aError); - if (NS_FAILED(rv)) { - return rv; - } - return NS_OK; -} - -void -PluginAsyncSurrogate::NP_GetEntryPoints(NPPluginFuncs* aFuncs) -{ - aFuncs->version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR; - aFuncs->destroy = &NPP_Destroy; - aFuncs->getvalue = &NPP_GetValue; - aFuncs->setvalue = &NPP_SetValue; - aFuncs->newstream = &NPP_NewStream; - aFuncs->setwindow = &NPP_SetWindow; - aFuncs->writeready = &NPP_WriteReady; - aFuncs->event = &NPP_HandleEvent; - // We need to set these so that content code doesn't make assumptions - // about these operations not being supported - aFuncs->write = &PluginModuleParent::NPP_Write; - aFuncs->asfile = &PluginModuleParent::NPP_StreamAsFile; - aFuncs->destroystream = &PluginModuleParent::NPP_DestroyStream; -} - -NPError -PluginAsyncSurrogate::NPP_Destroy(NPSavedData** aSave) -{ - if (!WaitForInit()) { - return NPERR_GENERIC_ERROR; - } - return PluginModuleParent::NPP_Destroy(mInstance, aSave); -} - -NPError -PluginAsyncSurrogate::NPP_GetValue(NPPVariable aVariable, void* aRetval) -{ - if (aVariable != NPPVpluginScriptableNPObject) { - if (!WaitForInit()) { - return NPERR_GENERIC_ERROR; - } - PluginInstanceParent* instance = PluginInstanceParent::Cast(mInstance); - MOZ_ASSERT(instance); - return instance->NPP_GetValue(aVariable, aRetval); - } - - NPObject* npobject = parent::_createobject(mInstance, - const_cast(GetClass())); - MOZ_ASSERT(npobject); - MOZ_ASSERT(npobject->_class == GetClass()); - MOZ_ASSERT(npobject->referenceCount == 1); - *(NPObject**)aRetval = npobject; - return npobject ? NPERR_NO_ERROR : NPERR_GENERIC_ERROR; -} - -NPError -PluginAsyncSurrogate::NPP_SetValue(NPNVariable aVariable, void* aValue) -{ - if (!WaitForInit()) { - return NPERR_GENERIC_ERROR; - } - return PluginModuleParent::NPP_SetValue(mInstance, aVariable, aValue); -} - -NPError -PluginAsyncSurrogate::NPP_NewStream(NPMIMEType aType, NPStream* aStream, - NPBool aSeekable, uint16_t* aStype) -{ - mPendingNewStreamCalls.AppendElement(PendingNewStreamCall(aType, aStream, - aSeekable)); - if (aStype) { - *aStype = nsPluginStreamListenerPeer::STREAM_TYPE_UNKNOWN; - } - return NPERR_NO_ERROR; -} - -NPError -PluginAsyncSurrogate::NPP_SetWindow(NPWindow* aWindow) -{ - mWindow = aWindow; - mAsyncSetWindow = false; - return NPERR_NO_ERROR; -} - -nsresult -PluginAsyncSurrogate::AsyncSetWindow(NPWindow* aWindow) -{ - mWindow = aWindow; - mAsyncSetWindow = true; - return NS_OK; -} - -void -PluginAsyncSurrogate::NPP_Print(NPPrint* aPrintInfo) -{ - // Do nothing, we've got nothing to print right now -} - -int16_t -PluginAsyncSurrogate::NPP_HandleEvent(void* event) -{ - // Drop the event -- the plugin isn't around to handle it - return false; -} - -int32_t -PluginAsyncSurrogate::NPP_WriteReady(NPStream* aStream) -{ - // We'll tell the browser to retry in a bit. Eventually NPP_WriteReady - // will resolve to the plugin's NPP_WriteReady and this should all just work. - return 0; -} - -/* static */ NPError -PluginAsyncSurrogate::NPP_Destroy(NPP aInstance, NPSavedData** aSave) -{ - PluginAsyncSurrogate* rawSurrogate = Cast(aInstance); - MOZ_ASSERT(rawSurrogate); - PluginModuleParent* module = rawSurrogate->GetParent(); - if (module && !module->IsInitialized()) { - // Take ownership of pdata's surrogate since we're going to release it - nsRefPtr surrogate(dont_AddRef(rawSurrogate)); - aInstance->pdata = nullptr; - // We haven't actually called NPP_New yet, so we should remove the - // surrogate for this instance. - bool removeOk = module->RemovePendingSurrogate(surrogate); - MOZ_ASSERT(removeOk); - if (!removeOk) { - return NPERR_GENERIC_ERROR; - } - surrogate->mInitCancelled = true; - return NPERR_NO_ERROR; - } - return rawSurrogate->NPP_Destroy(aSave); -} - -/* static */ NPError -PluginAsyncSurrogate::NPP_GetValue(NPP aInstance, NPPVariable aVariable, - void* aRetval) -{ - PluginAsyncSurrogate* surrogate = Cast(aInstance); - MOZ_ASSERT(surrogate); - return surrogate->NPP_GetValue(aVariable, aRetval); -} - -/* static */ NPError -PluginAsyncSurrogate::NPP_SetValue(NPP aInstance, NPNVariable aVariable, - void* aValue) -{ - PluginAsyncSurrogate* surrogate = Cast(aInstance); - MOZ_ASSERT(surrogate); - return surrogate->NPP_SetValue(aVariable, aValue); -} - -/* static */ NPError -PluginAsyncSurrogate::NPP_NewStream(NPP aInstance, NPMIMEType aType, - NPStream* aStream, NPBool aSeekable, - uint16_t* aStype) -{ - PluginAsyncSurrogate* surrogate = Cast(aInstance); - MOZ_ASSERT(surrogate); - return surrogate->NPP_NewStream(aType, aStream, aSeekable, aStype); -} - -/* static */ NPError -PluginAsyncSurrogate::NPP_SetWindow(NPP aInstance, NPWindow* aWindow) -{ - PluginAsyncSurrogate* surrogate = Cast(aInstance); - MOZ_ASSERT(surrogate); - return surrogate->NPP_SetWindow(aWindow); -} - -/* static */ void -PluginAsyncSurrogate::NPP_Print(NPP aInstance, NPPrint* aPrintInfo) -{ - PluginAsyncSurrogate* surrogate = Cast(aInstance); - MOZ_ASSERT(surrogate); - surrogate->NPP_Print(aPrintInfo); -} - -/* static */ int16_t -PluginAsyncSurrogate::NPP_HandleEvent(NPP aInstance, void* aEvent) -{ - PluginAsyncSurrogate* surrogate = Cast(aInstance); - MOZ_ASSERT(surrogate); - return surrogate->NPP_HandleEvent(aEvent); -} - -/* static */ int32_t -PluginAsyncSurrogate::NPP_WriteReady(NPP aInstance, NPStream* aStream) -{ - PluginAsyncSurrogate* surrogate = Cast(aInstance); - MOZ_ASSERT(surrogate); - return surrogate->NPP_WriteReady(aStream); -} - -PluginAsyncSurrogate::PendingNewStreamCall::PendingNewStreamCall( - NPMIMEType aType, NPStream* aStream, NPBool aSeekable) - : mType(NullableString(aType)) - , mStream(aStream) - , mSeekable(aSeekable) -{ -} - -/* static */ bool -PluginAsyncSurrogate::SetStreamType(NPStream* aStream, uint16_t aStreamType) -{ - nsNPAPIStreamWrapper* wrapper = - reinterpret_cast(aStream->ndata); - if (!wrapper) { - return false; - } - nsNPAPIPluginStreamListener* streamListener = wrapper->GetStreamListener(); - if (!streamListener) { - return false; - } - return streamListener->SetStreamType(aStreamType); -} - -void -PluginAsyncSurrogate::OnInstanceCreated(PluginInstanceParent* aInstance) -{ - for (PRUint32 i = 0, len = mPendingNewStreamCalls.Length(); i < len; ++i) { - PendingNewStreamCall& curPendingCall = mPendingNewStreamCalls[i]; - uint16_t streamType = NP_NORMAL; - NPError curError = aInstance->NPP_NewStream( - const_cast(NullableStringGet(curPendingCall.mType)), - curPendingCall.mStream, curPendingCall.mSeekable, - &streamType); - if (curError != NPERR_NO_ERROR) { - // If we failed here then the send failed and we need to clean up - parent::_destroystream(mInstance, curPendingCall.mStream, NPRES_DONE); - } - } - mPendingNewStreamCalls.Clear(); - mInstantiated = true; -} - -/** - * During asynchronous initialization it might be necessary to wait for the - * plugin to complete its initialization. This typically occurs when the result - * of a plugin call depends on the plugin being fully instantiated. For example, - * if some JS calls into the plugin, the call must be executed synchronously to - * preserve correctness. - * - * This function works by pumping the plugin's IPC channel for events until - * initialization has completed. - */ -bool -PluginAsyncSurrogate::WaitForInit() -{ - if (mInitCancelled) { - return false; - } - if (mAcceptCalls) { - return true; - } - Telemetry::AutoTimer - timer(mParent->GetHistogramKey()); - bool result = false; - MOZ_ASSERT(mParent); - if (mParent->IsChrome()) { - PluginProcessParent* process = static_cast(mParent)->Process(); - MOZ_ASSERT(process); - process->SetCallRunnableImmediately(true); - if (!process->WaitUntilConnected()) { - return false; - } - } - if (!mParent->WaitForIPCConnection()) { - return false; - } - if (!mParent->IsChrome()) { - // For e10s content processes, we need to spin the content channel until the - // protocol bridging has occurred. - dom::ContentChild* cp = dom::ContentChild::GetSingleton(); - mozilla::ipc::MessageChannel* contentChannel = cp->GetIPCChannel(); - MOZ_ASSERT(contentChannel); - while (!mParent->mNPInitialized) { - result = contentChannel->WaitForIncomingMessage(); - if (!result) { - return result; - } - } - } - mozilla::ipc::MessageChannel* channel = mParent->GetIPCChannel(); - MOZ_ASSERT(channel); - while (!mAcceptCalls) { - result = channel->WaitForIncomingMessage(); - if (!result) { - break; - } - } - return result; -} - -void -PluginAsyncSurrogate::AsyncCallDeparting() -{ - ++mAsyncCallsInFlight; - if (!mPluginDestructionGuard) { - mPluginDestructionGuard = MakeUnique(this); - } -} - -void -PluginAsyncSurrogate::AsyncCallArriving() -{ - MOZ_ASSERT(mAsyncCallsInFlight > 0); - if (--mAsyncCallsInFlight == 0) { - mPluginDestructionGuard.reset(nullptr); - } -} - -void -PluginAsyncSurrogate::NotifyAsyncInitFailed() -{ - // Clean up any pending NewStream requests - for (uint32_t i = 0, len = mPendingNewStreamCalls.Length(); i < len; ++i) { - PendingNewStreamCall& curPendingCall = mPendingNewStreamCalls[i]; - parent::_destroystream(mInstance, curPendingCall.mStream, NPRES_DONE); - } - mPendingNewStreamCalls.Clear(); - - nsNPAPIPluginInstance* inst = - static_cast(mInstance->ndata); - if (!inst) { - return; - } - nsPluginInstanceOwner* owner = inst->GetOwner(); - if (!owner) { - return; - } - owner->NotifyHostAsyncInitFailed(); -} - -// static -NPObject* -PluginAsyncSurrogate::ScriptableAllocate(NPP aInstance, NPClass* aClass) -{ - PLUGIN_LOG_DEBUG_FUNCTION; - if (aClass != GetClass()) { - NS_ERROR("Huh?! Wrong class!"); - return nullptr; - } - - return new AsyncNPObject(Cast(aInstance)); -} - -// static -void -PluginAsyncSurrogate::ScriptableInvalidate(NPObject* aObject) -{ - PLUGIN_LOG_DEBUG_FUNCTION; - if (aObject->_class != GetClass()) { - NS_ERROR("Don't know what kind of object this is!"); - return; - } - - AsyncNPObject* object = static_cast(aObject); - if (!object->mSurrogate->WaitForInit()) { - return; - } - NPObject* realObject = object->GetRealObject(); - if (!realObject) { - return; - } - realObject->_class->invalidate(realObject); -} - -// static -void -PluginAsyncSurrogate::ScriptableDeallocate(NPObject* aObject) -{ - PLUGIN_LOG_DEBUG_FUNCTION; - if (aObject->_class != GetClass()) { - NS_ERROR("Don't know what kind of object this is!"); - return; - } - - AsyncNPObject* object = static_cast(aObject); - delete object; -} - -// static -bool -PluginAsyncSurrogate::ScriptableHasMethod(NPObject* aObject, - NPIdentifier aName) -{ - PLUGIN_LOG_DEBUG_FUNCTION; - if (aObject->_class != GetClass()) { - NS_ERROR("Don't know what kind of object this is!"); - return false; - } - - RecursionGuard guard; - if (guard.IsRecursive()) { - return false; - } - - AsyncNPObject* object = static_cast(aObject); - MOZ_ASSERT(object); - bool checkPluginObject = !object->mSurrogate->mInstantiated && - !object->mSurrogate->mAcceptCalls; - - if (!object->mSurrogate->WaitForInit()) { - return false; - } - NPObject* realObject = object->GetRealObject(); - if (!realObject) { - return false; - } - bool result = realObject->_class->hasMethod(realObject, aName); - if (!result && checkPluginObject) { - // We may be calling into this object because properties in the WebIDL - // object hadn't been set yet. Now that we're further along in - // initialization, we should try again. - const NPNetscapeFuncs* npn = object->mSurrogate->mParent->GetNetscapeFuncs(); - NPObject* pluginObject = nullptr; - NPError nperror = npn->getvalue(object->mSurrogate->mInstance, - NPNVPluginElementNPObject, - (void*)&pluginObject); - if (nperror == NPERR_NO_ERROR) { - NPPAutoPusher nppPusher(object->mSurrogate->mInstance); - result = pluginObject->_class->hasMethod(pluginObject, aName); - npn->releaseobject(pluginObject); - NPUTF8* idstr = npn->utf8fromidentifier(aName); - npn->memfree(idstr); - } - } - return result; -} - -bool -PluginAsyncSurrogate::GetPropertyHelper(NPObject* aObject, NPIdentifier aName, - bool* aHasProperty, bool* aHasMethod, - NPVariant* aResult) -{ - PLUGIN_LOG_DEBUG_FUNCTION; - - if (!aObject) { - return false; - } - - RecursionGuard guard; - if (guard.IsRecursive()) { - return false; - } - - WaitForInit(); - - AsyncNPObject* object = static_cast(aObject); - NPObject* realObject = object->GetRealObject(); - if (realObject->_class != PluginScriptableObjectParent::GetClass()) { - NS_ERROR("Don't know what kind of object this is!"); - return false; - } - - PluginScriptableObjectParent* actor = - static_cast(realObject)->parent; - bool success = actor->GetPropertyHelper(aName, aHasProperty, aHasMethod, aResult); - if (!success) { - const NPNetscapeFuncs* npn = mParent->GetNetscapeFuncs(); - NPObject* pluginObject = nullptr; - NPError nperror = npn->getvalue(mInstance, NPNVPluginElementNPObject, - (void*)&pluginObject); - if (nperror == NPERR_NO_ERROR) { - NPPAutoPusher nppPusher(mInstance); - bool hasProperty = nsJSObjWrapper::HasOwnProperty(pluginObject, aName); - NPUTF8* idstr = npn->utf8fromidentifier(aName); - npn->memfree(idstr); - bool hasMethod = false; - if (hasProperty) { - hasMethod = pluginObject->_class->hasMethod(pluginObject, aName); - success = pluginObject->_class->getProperty(pluginObject, aName, aResult); - idstr = npn->utf8fromidentifier(aName); - npn->memfree(idstr); - } - *aHasProperty = hasProperty; - *aHasMethod = hasMethod; - npn->releaseobject(pluginObject); - } - } - return success; -} - -// static -bool -PluginAsyncSurrogate::ScriptableInvoke(NPObject* aObject, - NPIdentifier aName, - const NPVariant* aArgs, - uint32_t aArgCount, - NPVariant* aResult) -{ - PLUGIN_LOG_DEBUG_FUNCTION; - if (aObject->_class != GetClass()) { - NS_ERROR("Don't know what kind of object this is!"); - return false; - } - - AsyncNPObject* object = static_cast(aObject); - if (!object->mSurrogate->WaitForInit()) { - return false; - } - NPObject* realObject = object->GetRealObject(); - if (!realObject) { - return false; - } - return realObject->_class->invoke(realObject, aName, aArgs, aArgCount, aResult); -} - -// static -bool -PluginAsyncSurrogate::ScriptableInvokeDefault(NPObject* aObject, - const NPVariant* aArgs, - uint32_t aArgCount, - NPVariant* aResult) -{ - PLUGIN_LOG_DEBUG_FUNCTION; - if (aObject->_class != GetClass()) { - NS_ERROR("Don't know what kind of object this is!"); - return false; - } - - AsyncNPObject* object = static_cast(aObject); - if (!object->mSurrogate->WaitForInit()) { - return false; - } - NPObject* realObject = object->GetRealObject(); - if (!realObject) { - return false; - } - return realObject->_class->invokeDefault(realObject, aArgs, aArgCount, aResult); -} - -// static -bool -PluginAsyncSurrogate::ScriptableHasProperty(NPObject* aObject, - NPIdentifier aName) -{ - PLUGIN_LOG_DEBUG_FUNCTION; - if (aObject->_class != GetClass()) { - NS_ERROR("Don't know what kind of object this is!"); - return false; - } - - RecursionGuard guard; - if (guard.IsRecursive()) { - return false; - } - - AsyncNPObject* object = static_cast(aObject); - MOZ_ASSERT(object); - bool checkPluginObject = !object->mSurrogate->mInstantiated && - !object->mSurrogate->mAcceptCalls; - - if (!object->mSurrogate->WaitForInit()) { - return false; - } - NPObject* realObject = object->GetRealObject(); - if (!realObject) { - return false; - } - bool result = realObject->_class->hasProperty(realObject, aName); - const NPNetscapeFuncs* npn = object->mSurrogate->mParent->GetNetscapeFuncs(); - NPUTF8* idstr = npn->utf8fromidentifier(aName); - npn->memfree(idstr); - if (!result && checkPluginObject) { - // We may be calling into this object because properties in the WebIDL - // object hadn't been set yet. Now that we're further along in - // initialization, we should try again. - NPObject* pluginObject = nullptr; - NPError nperror = npn->getvalue(object->mSurrogate->mInstance, - NPNVPluginElementNPObject, - (void*)&pluginObject); - if (nperror == NPERR_NO_ERROR) { - NPPAutoPusher nppPusher(object->mSurrogate->mInstance); - result = nsJSObjWrapper::HasOwnProperty(pluginObject, aName); - npn->releaseobject(pluginObject); - idstr = npn->utf8fromidentifier(aName); - npn->memfree(idstr); - } - } - return result; -} - -// static -bool -PluginAsyncSurrogate::ScriptableGetProperty(NPObject* aObject, - NPIdentifier aName, - NPVariant* aResult) -{ - PLUGIN_LOG_DEBUG_FUNCTION; - // See GetPropertyHelper below. - NS_NOTREACHED("Shouldn't ever call this directly!"); - return false; -} - -// static -bool -PluginAsyncSurrogate::ScriptableSetProperty(NPObject* aObject, - NPIdentifier aName, - const NPVariant* aValue) -{ - PLUGIN_LOG_DEBUG_FUNCTION; - if (aObject->_class != GetClass()) { - NS_ERROR("Don't know what kind of object this is!"); - return false; - } - - AsyncNPObject* object = static_cast(aObject); - if (!object->mSurrogate->WaitForInit()) { - return false; - } - NPObject* realObject = object->GetRealObject(); - if (!realObject) { - return false; - } - return realObject->_class->setProperty(realObject, aName, aValue); -} - -// static -bool -PluginAsyncSurrogate::ScriptableRemoveProperty(NPObject* aObject, - NPIdentifier aName) -{ - PLUGIN_LOG_DEBUG_FUNCTION; - if (aObject->_class != GetClass()) { - NS_ERROR("Don't know what kind of object this is!"); - return false; - } - - AsyncNPObject* object = static_cast(aObject); - if (!object->mSurrogate->WaitForInit()) { - return false; - } - NPObject* realObject = object->GetRealObject(); - if (!realObject) { - return false; - } - return realObject->_class->removeProperty(realObject, aName); -} - -// static -bool -PluginAsyncSurrogate::ScriptableEnumerate(NPObject* aObject, - NPIdentifier** aIdentifiers, - uint32_t* aCount) -{ - PLUGIN_LOG_DEBUG_FUNCTION; - if (aObject->_class != GetClass()) { - NS_ERROR("Don't know what kind of object this is!"); - return false; - } - - AsyncNPObject* object = static_cast(aObject); - if (!object->mSurrogate->WaitForInit()) { - return false; - } - NPObject* realObject = object->GetRealObject(); - if (!realObject) { - return false; - } - return realObject->_class->enumerate(realObject, aIdentifiers, aCount); -} - -// static -bool -PluginAsyncSurrogate::ScriptableConstruct(NPObject* aObject, - const NPVariant* aArgs, - uint32_t aArgCount, - NPVariant* aResult) -{ - PLUGIN_LOG_DEBUG_FUNCTION; - if (aObject->_class != GetClass()) { - NS_ERROR("Don't know what kind of object this is!"); - return false; - } - - AsyncNPObject* object = static_cast(aObject); - if (!object->mSurrogate->WaitForInit()) { - return false; - } - NPObject* realObject = object->GetRealObject(); - if (!realObject) { - return false; - } - return realObject->_class->construct(realObject, aArgs, aArgCount, aResult); -} - -const NPClass PluginAsyncSurrogate::sNPClass = { - NP_CLASS_STRUCT_VERSION, - PluginAsyncSurrogate::ScriptableAllocate, - PluginAsyncSurrogate::ScriptableDeallocate, - PluginAsyncSurrogate::ScriptableInvalidate, - PluginAsyncSurrogate::ScriptableHasMethod, - PluginAsyncSurrogate::ScriptableInvoke, - PluginAsyncSurrogate::ScriptableInvokeDefault, - PluginAsyncSurrogate::ScriptableHasProperty, - PluginAsyncSurrogate::ScriptableGetProperty, - PluginAsyncSurrogate::ScriptableSetProperty, - PluginAsyncSurrogate::ScriptableRemoveProperty, - PluginAsyncSurrogate::ScriptableEnumerate, - PluginAsyncSurrogate::ScriptableConstruct -}; - -PushSurrogateAcceptCalls::PushSurrogateAcceptCalls(PluginInstanceParent* aInstance) - : mSurrogate(nullptr) - , mPrevAcceptCallsState(false) -{ - MOZ_ASSERT(aInstance); - mSurrogate = aInstance->GetAsyncSurrogate(); - if (mSurrogate) { - mPrevAcceptCallsState = mSurrogate->SetAcceptingCalls(true); - } -} - -PushSurrogateAcceptCalls::~PushSurrogateAcceptCalls() -{ - if (mSurrogate) { - mSurrogate->SetAcceptingCalls(mPrevAcceptCallsState); - } -} - -} // namespace plugins -} // namespace mozilla diff --git a/dom/plugins/ipc/PluginAsyncSurrogate.h b/dom/plugins/ipc/PluginAsyncSurrogate.h deleted file mode 100644 index 2734183deee0..000000000000 --- a/dom/plugins/ipc/PluginAsyncSurrogate.h +++ /dev/null @@ -1,179 +0,0 @@ -/* -*- 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 "nsAutoPtr.h" -#include "nsISupportsImpl.h" -#include "nsPluginHost.h" -#include "nsString.h" -#include "nsTArray.h" -#include "PluginDataResolver.h" - -namespace mozilla { -namespace plugins { - -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); - 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); - - virtual PluginAsyncSurrogate* - GetAsyncSurrogate() { return this; } - - virtual PluginInstanceParent* - GetInstance() { return nullptr; } - - NPP GetNPP() { return mInstance; } - - bool GetPropertyHelper(NPObject* aObject, NPIdentifier aName, - bool* aHasProperty, bool* aHasMethod, - NPVariant* aResult); - - PluginModuleParent* - GetParent() { return mParent; } - - bool SetAcceptingCalls(bool aAccept) - { - bool prevState = mAcceptCalls; - if (mInstantiated) { - aAccept = true; - } - mAcceptCalls = aAccept; - return prevState; - } - - void AsyncCallDeparting(); - void AsyncCallArriving(); - - void NotifyAsyncInitFailed(); - -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 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); - -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; - NPP mInstance; - uint16_t mMode; - InfallibleTArray mNames; - InfallibleTArray 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 mPendingNewStreamCalls; - UniquePtr mPluginDestructionGuard; - - bool mAcceptCalls; - bool mInstantiated; - bool mAsyncSetWindow; - bool mInitCancelled; - int32_t mAsyncCallsInFlight; - - static const NPClass sNPClass; -}; - -struct AsyncNPObject : NPObject -{ - explicit AsyncNPObject(PluginAsyncSurrogate* aSurrogate); - ~AsyncNPObject(); - - NPObject* GetRealObject(); - - nsRefPtr mSurrogate; - NPObject* 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 diff --git a/dom/plugins/ipc/PluginDataResolver.h b/dom/plugins/ipc/PluginDataResolver.h deleted file mode 100644 index 8371c4df7456..000000000000 --- a/dom/plugins/ipc/PluginDataResolver.h +++ /dev/null @@ -1,26 +0,0 @@ -/* -*- 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_PluginDataResolver_h -#define dom_plugins_ipc_PluginDataResolver_h - -namespace mozilla { -namespace plugins { - -class PluginAsyncSurrogate; -class PluginInstanceParent; - -class PluginDataResolver -{ -public: - virtual PluginAsyncSurrogate* GetAsyncSurrogate() = 0; - virtual PluginInstanceParent* GetInstance() = 0; -}; - -} // namespace plugins -} // namespace mozilla - -#endif // dom_plugins_ipc_PluginDataResolver_h diff --git a/dom/plugins/ipc/PluginInstanceChild.cpp b/dom/plugins/ipc/PluginInstanceChild.cpp index 1adc1a1935fa..4ba8c5448fc3 100644 --- a/dom/plugins/ipc/PluginInstanceChild.cpp +++ b/dom/plugins/ipc/PluginInstanceChild.cpp @@ -119,16 +119,8 @@ CreateDrawTargetForSurface(gfxASurface *aSurface) return drawTarget; } -PluginInstanceChild::PluginInstanceChild(const NPPluginFuncs* aPluginIface, - const nsCString& aMimeType, - const uint16_t& aMode, - const InfallibleTArray& aNames, - const InfallibleTArray& aValues) +PluginInstanceChild::PluginInstanceChild(const NPPluginFuncs* aPluginIface) : mPluginIface(aPluginIface) - , mMimeType(aMimeType) - , mMode(aMode) - , mNames(aNames) - , mValues(aValues) #if defined(XP_MACOSX) , mContentsScaleFactor(1.0) #endif @@ -218,54 +210,6 @@ PluginInstanceChild::~PluginInstanceChild() #endif } -NPError -PluginInstanceChild::DoNPP_New() -{ - // unpack the arguments into a C format - int argc = mNames.Length(); - NS_ASSERTION(argc == (int) mValues.Length(), - "argn.length != argv.length"); - - nsAutoArrayPtr argn(new char*[1 + argc]); - nsAutoArrayPtr argv(new char*[1 + argc]); - argn[argc] = 0; - argv[argc] = 0; - - for (int i = 0; i < argc; ++i) { - argn[i] = const_cast(NullableStringGet(mNames[i])); - argv[i] = const_cast(NullableStringGet(mValues[i])); - } - - NPP npp = GetNPP(); - - NPError rv = mPluginIface->newp((char*)NullableStringGet(mMimeType), npp, - mMode, argc, argn, argv, 0); - if (NPERR_NO_ERROR != rv) { - return rv; - } - - Initialize(); - -#if defined(XP_MACOSX) && defined(__i386__) - // If an i386 Mac OS X plugin has selected the Carbon event model then - // we have to fail. We do not support putting Carbon event model plugins - // out of process. Note that Carbon is the default model so out of process - // plugins need to actively negotiate something else in order to work - // out of process. - if (EventModel() == NPEventModelCarbon) { - // Send notification that a plugin tried to negotiate Carbon NPAPI so that - // users can be notified that restarting the browser in i386 mode may allow - // them to use the plugin. - SendNegotiatedCarbon(); - - // Fail to instantiate. - rv = NPERR_MODULE_LOAD_FAILED_ERROR; - } -#endif - - return rv; -} - int PluginInstanceChild::GetQuirks() { @@ -2290,86 +2234,21 @@ PluginInstanceChild::RecvPPluginScriptableObjectConstructor( } bool -PluginInstanceChild::RecvPBrowserStreamConstructor( +PluginInstanceChild::AnswerPBrowserStreamConstructor( PBrowserStreamChild* aActor, const nsCString& url, const uint32_t& length, const uint32_t& lastmodified, PStreamNotifyChild* notifyData, - const nsCString& headers) -{ - return true; -} - -NPError -PluginInstanceChild::DoNPP_NewStream(BrowserStreamChild* actor, - const nsCString& mimeType, - const bool& seekable, - uint16_t* stype) + const nsCString& headers, + const nsCString& mimeType, + const bool& seekable, + NPError* rv, + uint16_t* stype) { AssertPluginThread(); - NPError rv = actor->StreamConstructed(mimeType, seekable, stype); - return rv; -} - -bool -PluginInstanceChild::AnswerNPP_NewStream(PBrowserStreamChild* actor, - const nsCString& mimeType, - const bool& seekable, - NPError* rv, - uint16_t* stype) -{ - *rv = DoNPP_NewStream(static_cast(actor), mimeType, - seekable, stype); - return true; -} - -class NewStreamAsyncCall : public ChildAsyncCall -{ -public: - NewStreamAsyncCall(PluginInstanceChild* aInstance, - BrowserStreamChild* aBrowserStreamChild, - const nsCString& aMimeType, - const bool aSeekable) - : ChildAsyncCall(aInstance, nullptr, nullptr) - , mBrowserStreamChild(aBrowserStreamChild) - , mMimeType(aMimeType) - , mSeekable(aSeekable) - { - } - - void Run() MOZ_OVERRIDE - { - RemoveFromAsyncList(); - - uint16_t stype = NP_NORMAL; - NPError rv = mInstance->DoNPP_NewStream(mBrowserStreamChild, mMimeType, - mSeekable, &stype); - DebugOnly sendOk = - mBrowserStreamChild->SendAsyncNPP_NewStreamResult(rv, stype); - MOZ_ASSERT(sendOk); - } - -private: - BrowserStreamChild* mBrowserStreamChild; - const nsCString mMimeType; - const bool mSeekable; -}; - -bool -PluginInstanceChild::RecvAsyncNPP_NewStream(PBrowserStreamChild* actor, - const nsCString& mimeType, - const bool& seekable) -{ - // Reusing ChildAsyncCall so that the task is cancelled properly on Destroy - BrowserStreamChild* child = static_cast(actor); - NewStreamAsyncCall* task = new NewStreamAsyncCall(this, child, mimeType, - seekable); - { - MutexAutoLock lock(mAsyncCallMutex); - mPendingAsyncCalls.AppendElement(task); - } - MessageLoop::current()->PostTask(FROM_HERE, task); + *rv = static_cast(aActor) + ->StreamConstructed(mimeType, seekable, stype); return true; } @@ -2378,12 +2257,16 @@ PluginInstanceChild::AllocPBrowserStreamChild(const nsCString& url, const uint32_t& length, const uint32_t& lastmodified, PStreamNotifyChild* notifyData, - const nsCString& headers) + const nsCString& headers, + const nsCString& mimeType, + const bool& seekable, + NPError* rv, + uint16_t *stype) { AssertPluginThread(); return new BrowserStreamChild(this, url, length, lastmodified, static_cast(notifyData), - headers); + headers, mimeType, seekable, rv, stype); } bool diff --git a/dom/plugins/ipc/PluginInstanceChild.h b/dom/plugins/ipc/PluginInstanceChild.h index 91b00cb08719..f9a0b76eee55 100644 --- a/dom/plugins/ipc/PluginInstanceChild.h +++ b/dom/plugins/ipc/PluginInstanceChild.h @@ -143,31 +143,29 @@ protected: virtual bool RecvPPluginScriptableObjectConstructor(PPluginScriptableObjectChild* aActor) MOZ_OVERRIDE; - virtual bool - RecvPBrowserStreamConstructor(PBrowserStreamChild* aActor, const nsCString& url, - const uint32_t& length, const uint32_t& lastmodified, - PStreamNotifyChild* notifyData, const nsCString& headers); - - virtual bool - AnswerNPP_NewStream( - PBrowserStreamChild* actor, - const nsCString& mimeType, - const bool& seekable, - NPError* rv, - uint16_t* stype) MOZ_OVERRIDE; - - virtual bool - RecvAsyncNPP_NewStream( - PBrowserStreamChild* actor, - const nsCString& mimeType, - const bool& seekable) MOZ_OVERRIDE; - virtual PBrowserStreamChild* AllocPBrowserStreamChild(const nsCString& url, const uint32_t& length, const uint32_t& lastmodified, PStreamNotifyChild* notifyData, - const nsCString& headers) MOZ_OVERRIDE; + const nsCString& headers, + const nsCString& mimeType, + const bool& seekable, + NPError* rv, + uint16_t *stype) MOZ_OVERRIDE; + + virtual bool + AnswerPBrowserStreamConstructor( + PBrowserStreamChild* aActor, + const nsCString& url, + const uint32_t& length, + const uint32_t& lastmodified, + PStreamNotifyChild* notifyData, + const nsCString& headers, + const nsCString& mimeType, + const bool& seekable, + NPError* rv, + uint16_t* stype) MOZ_OVERRIDE; virtual bool DeallocPBrowserStreamChild(PBrowserStreamChild* stream) MOZ_OVERRIDE; @@ -204,22 +202,10 @@ protected: #endif public: - PluginInstanceChild(const NPPluginFuncs* aPluginIface, - const nsCString& aMimeType, - const uint16_t& aMode, - const InfallibleTArray& aNames, - const InfallibleTArray& aValues); + explicit PluginInstanceChild(const NPPluginFuncs* aPluginIface); virtual ~PluginInstanceChild(); - NPError DoNPP_New(); - - // Common sync+async implementation of NPP_NewStream - NPError DoNPP_NewStream(BrowserStreamChild* actor, - const nsCString& mimeType, - const bool& seekable, - uint16_t* stype); - bool Initialize(); NPP GetNPP() @@ -366,10 +352,6 @@ private: #endif const NPPluginFuncs* mPluginIface; - nsCString mMimeType; - uint16_t mMode; - InfallibleTArray mNames; - InfallibleTArray mValues; NPP_t mData; NPWindow mWindow; #if defined(XP_MACOSX) diff --git a/dom/plugins/ipc/PluginInstanceParent.cpp b/dom/plugins/ipc/PluginInstanceParent.cpp index 5be8e325bec3..e10758c24415 100644 --- a/dom/plugins/ipc/PluginInstanceParent.cpp +++ b/dom/plugins/ipc/PluginInstanceParent.cpp @@ -10,7 +10,6 @@ #include "mozilla/Telemetry.h" #include "PluginInstanceParent.h" #include "BrowserStreamParent.h" -#include "PluginAsyncSurrogate.h" #include "PluginBackgroundDestroyer.h" #include "PluginModuleParent.h" #include "PluginStreamParent.h" @@ -22,7 +21,6 @@ #include "gfxPlatform.h" #include "gfxSharedImageSurface.h" #include "nsNPAPIPluginInstance.h" -#include "nsPluginInstanceOwner.h" #ifdef MOZ_X11 #include "gfxXlibSurface.h" #endif @@ -77,9 +75,7 @@ PluginInstanceParent::PluginInstanceParent(PluginModuleParent* parent, NPP npp, const nsCString& aMimeType, const NPNetscapeFuncs* npniface) - : mParent(parent) - , mSurrogate(PluginAsyncSurrogate::Cast(npp)) - , mUseSurrogate(true) + : mParent(parent) , mNPP(npp) , mNPNIface(npniface) , mWindowType(NPWindowTypeWindow) @@ -171,7 +167,11 @@ PluginInstanceParent::AllocPBrowserStreamParent(const nsCString& url, const uint32_t& length, const uint32_t& lastmodified, PStreamNotifyParent* notifyData, - const nsCString& headers) + const nsCString& headers, + const nsCString& mimeType, + const bool& seekable, + NPError* rv, + uint16_t *stype) { NS_RUNTIMEABORT("Not reachable"); return nullptr; @@ -783,12 +783,6 @@ PluginInstanceParent::EndUpdateBackground(gfxContext* aCtx, return NS_OK; } -PluginAsyncSurrogate* -PluginInstanceParent::GetAsyncSurrogate() -{ - return mSurrogate; -} - bool PluginInstanceParent::CreateBackground(const nsIntSize& aSize) { @@ -1315,37 +1309,25 @@ PluginInstanceParent::NPP_NewStream(NPMIMEType type, NPStream* stream, BrowserStreamParent* bs = new BrowserStreamParent(this, stream); - if (!SendPBrowserStreamConstructor(bs, - NullableString(stream->url), - stream->end, - stream->lastmodified, - static_cast(stream->notifyData), - NullableString(stream->headers))) { - return NPERR_GENERIC_ERROR; - } - - Telemetry::AutoTimer - timer(Module()->GetHistogramKey()); - - NPError err = NPERR_NO_ERROR; - if (mParent->IsStartingAsync()) { - MOZ_ASSERT(mSurrogate); - mSurrogate->AsyncCallDeparting(); - if (SendAsyncNPP_NewStream(bs, NullableString(type), seekable)) { - *stype = UINT16_MAX; - } else { - err = NPERR_GENERIC_ERROR; - } - } else { - bs->SetAlive(); - if (!CallNPP_NewStream(bs, NullableString(type), seekable, &err, stype)) { - err = NPERR_GENERIC_ERROR; - } - if (NPERR_NO_ERROR != err) { - unused << PBrowserStreamParent::Send__delete__(bs); + NPError err; + { // Scope for timer + Telemetry::AutoTimer + timer(Module()->GetHistogramKey()); + if (!CallPBrowserStreamConstructor(bs, + NullableString(stream->url), + stream->end, + stream->lastmodified, + static_cast(stream->notifyData), + NullableString(stream->headers), + NullableString(type), seekable, + &err, stype)) { + return NPERR_GENERIC_ERROR; } } + if (NPERR_NO_ERROR != err) + unused << PBrowserStreamParent::Send__delete__(bs); + return err; } @@ -1654,49 +1636,6 @@ PluginInstanceParent::RecvNegotiatedCarbon() return true; } -nsPluginInstanceOwner* -PluginInstanceParent::GetOwner() -{ - nsNPAPIPluginInstance* inst = static_cast(mNPP->ndata); - if (!inst) { - return nullptr; - } - return inst->GetOwner(); -} - -bool -PluginInstanceParent::RecvAsyncNPP_NewResult(const NPError& aResult) -{ - // NB: mUseSurrogate must be cleared before doing anything else, especially - // calling NPP_SetWindow! - mUseSurrogate = false; - - mSurrogate->AsyncCallArriving(); - if (aResult == NPERR_NO_ERROR) { - mSurrogate->SetAcceptingCalls(true); - } - - nsPluginInstanceOwner* owner = GetOwner(); - if (!owner) { - // This is possible in async plugin land; the instance may outlive - // the owner - return true; - } - - if (aResult != NPERR_NO_ERROR) { - owner->NotifyHostAsyncInitFailed(); - return true; - } - - // Now we need to do a bunch of exciting post-NPP_New housekeeping. - owner->NotifyHostCreateWidget(); - - MOZ_ASSERT(mSurrogate); - mSurrogate->OnInstanceCreated(this); - - return true; -} - #if defined(OS_WIN) /* @@ -1936,29 +1875,3 @@ PluginInstanceParent::AnswerPluginFocusChange(const bool& gotFocus) return false; #endif } - -PluginInstanceParent* -PluginInstanceParent::Cast(NPP aInstance, PluginAsyncSurrogate** aSurrogate) -{ - PluginDataResolver* resolver = - static_cast(aInstance->pdata); - - // If the plugin crashed and the PluginInstanceParent was deleted, - // aInstance->pdata will be nullptr. - if (!resolver) { - return nullptr; - } - - PluginInstanceParent* instancePtr = resolver->GetInstance(); - - if (instancePtr && aInstance != instancePtr->mNPP) { - NS_RUNTIMEABORT("Corrupted plugin data."); - } - - if (aSurrogate) { - *aSurrogate = resolver->GetAsyncSurrogate(); - } - - return instancePtr; -} - diff --git a/dom/plugins/ipc/PluginInstanceParent.h b/dom/plugins/ipc/PluginInstanceParent.h index 31448da8b9eb..f38dcfea0ef1 100644 --- a/dom/plugins/ipc/PluginInstanceParent.h +++ b/dom/plugins/ipc/PluginInstanceParent.h @@ -22,7 +22,6 @@ #include "nsDataHashtable.h" #include "nsHashKeys.h" #include "nsRect.h" -#include "PluginDataResolver.h" #ifdef MOZ_X11 class gfxXlibSurface; @@ -31,7 +30,6 @@ class gfxXlibSurface; class gfxASurface; class gfxContext; -class nsPluginInstanceOwner; namespace mozilla { namespace layers { @@ -44,7 +42,6 @@ class PBrowserStreamParent; class PluginModuleParent; class PluginInstanceParent : public PPluginInstanceParent - , public PluginDataResolver { friend class PluginModuleParent; friend class BrowserStreamParent; @@ -77,7 +74,11 @@ public: const uint32_t& length, const uint32_t& lastmodified, PStreamNotifyParent* notifyData, - const nsCString& headers) MOZ_OVERRIDE; + const nsCString& headers, + const nsCString& mimeType, + const bool& seekable, + NPError* rv, + uint16_t *stype) MOZ_OVERRIDE; virtual bool DeallocPBrowserStreamParent(PBrowserStreamParent* stream) MOZ_OVERRIDE; @@ -209,9 +210,6 @@ public: virtual bool RecvNegotiatedCarbon() MOZ_OVERRIDE; - virtual bool - RecvAsyncNPP_NewResult(const NPError& aResult) MOZ_OVERRIDE; - NPError NPP_SetWindow(const NPWindow* aWindow); NPError NPP_GetValue(NPPVariable variable, void* retval); @@ -256,12 +254,6 @@ public: return mNPP; } - bool - UseSurrogate() const - { - return mUseSurrogate; - } - virtual bool AnswerPluginFocusChange(const bool& gotFocus) MOZ_OVERRIDE; @@ -279,13 +271,6 @@ public: const nsIntRect& aRect); void DidComposite() { unused << SendNPP_DidComposite(); } - virtual PluginAsyncSurrogate* GetAsyncSurrogate(); - - virtual PluginInstanceParent* GetInstance() { return this; } - - static PluginInstanceParent* Cast(NPP instance, - PluginAsyncSurrogate** aSurrogate = nullptr); - private: // Create an appropriate platform surface for a background of size // |aSize|. Return true if successful. @@ -306,12 +291,8 @@ private: PPluginScriptableObjectParent** aValue, NPError* aResult); - nsPluginInstanceOwner* GetOwner(); - private: PluginModuleParent* mParent; - nsRefPtr mSurrogate; - bool mUseSurrogate; NPP mNPP; const NPNetscapeFuncs* mNPNIface; NPWindowType mWindowType; diff --git a/dom/plugins/ipc/PluginModuleChild.cpp b/dom/plugins/ipc/PluginModuleChild.cpp index 034db619d28e..ac51826d4c9a 100644 --- a/dom/plugins/ipc/PluginModuleChild.cpp +++ b/dom/plugins/ipc/PluginModuleChild.cpp @@ -95,13 +95,6 @@ static GetWindowInfoPtr sGetWindowInfoPtrStub = nullptr; static HWND sBrowserHwnd = nullptr; #endif -template<> -struct RunnableMethodTraits -{ - static void RetainCallee(PluginModuleChild* obj) { } - static void ReleaseCallee(PluginModuleChild* obj) { } -}; - /* static */ PluginModuleChild* PluginModuleChild::CreateForContentProcess(mozilla::ipc::Transport* aTransport, @@ -1888,21 +1881,7 @@ PluginModuleChild::AnswerNP_GetEntryPoints(NPError* _retval) } bool -PluginModuleChild::AnswerNP_Initialize(const PluginSettings& aSettings, NPError* rv) -{ - *rv = DoNP_Initialize(aSettings); - return true; -} - -bool -PluginModuleChild::RecvAsyncNP_Initialize(const PluginSettings& aSettings) -{ - NPError error = DoNP_Initialize(aSettings); - return SendNP_InitializeResult(error); -} - -NPError -PluginModuleChild::DoNP_Initialize(const PluginSettings& aSettings) +PluginModuleChild::AnswerNP_Initialize(const PluginSettings& aSettings, NPError* _retval) { PLUGIN_LOG_DEBUG_METHOD; AssertPluginThread(); @@ -1921,11 +1900,12 @@ PluginModuleChild::DoNP_Initialize(const PluginSettings& aSettings) SendBackUpXResources(FileDescriptor(xSocketFd)); #endif - NPError result; #if defined(OS_LINUX) || defined(OS_BSD) - result = mInitializeFunc(&sBrowserFuncs, &mFunctions); + *_retval = mInitializeFunc(&sBrowserFuncs, &mFunctions); + return true; #elif defined(OS_WIN) || defined(OS_MACOSX) - result = mInitializeFunc(&sBrowserFuncs); + *_retval = mInitializeFunc(&sBrowserFuncs); + return true; #else # error Please implement me for your platform #endif @@ -1933,8 +1913,6 @@ PluginModuleChild::DoNP_Initialize(const PluginSettings& aSettings) #ifdef XP_WIN CleanupProtectedModeHook(); #endif - - return result; } #if defined(XP_WIN) @@ -2057,7 +2035,8 @@ PPluginInstanceChild* PluginModuleChild::AllocPPluginInstanceChild(const nsCString& aMimeType, const uint16_t& aMode, const InfallibleTArray& aNames, - const InfallibleTArray& aValues) + const InfallibleTArray& aValues, + NPError* rv) { PLUGIN_LOG_DEBUG_METHOD; AssertPluginThread(); @@ -2073,8 +2052,7 @@ PluginModuleChild::AllocPPluginInstanceChild(const nsCString& aMimeType, } #endif - return new PluginInstanceChild(&mFunctions, aMimeType, aMode, aNames, - aValues); + return new PluginInstanceChild(&mFunctions); } void @@ -2127,39 +2105,68 @@ PluginModuleChild::InitQuirksModes(const nsCString& aMimeType) } bool -PluginModuleChild::RecvPPluginInstanceConstructor(PPluginInstanceChild* aActor, - const nsCString& aMimeType, - const uint16_t& aMode, - const InfallibleTArray& aNames, - const InfallibleTArray& aValues) +PluginModuleChild::AnswerPPluginInstanceConstructor(PPluginInstanceChild* aActor, + const nsCString& aMimeType, + const uint16_t& aMode, + const InfallibleTArray& aNames, + const InfallibleTArray& aValues, + NPError* rv) { PLUGIN_LOG_DEBUG_METHOD; AssertPluginThread(); - NS_ASSERTION(aActor, "Null actor!"); - return true; -} - -bool -PluginModuleChild::AnswerSyncNPP_New(PPluginInstanceChild* aActor, NPError* rv) -{ - PLUGIN_LOG_DEBUG_METHOD; PluginInstanceChild* childInstance = reinterpret_cast(aActor); - AssertPluginThread(); - *rv = childInstance->DoNPP_New(); - return true; -} + NS_ASSERTION(childInstance, "Null actor!"); + + // unpack the arguments into a C format + int argc = aNames.Length(); + NS_ASSERTION(argc == (int) aValues.Length(), + "argn.length != argv.length"); + + nsAutoArrayPtr argn(new char*[1 + argc]); + nsAutoArrayPtr argv(new char*[1 + argc]); + argn[argc] = 0; + argv[argc] = 0; + + for (int i = 0; i < argc; ++i) { + argn[i] = const_cast(NullableStringGet(aNames[i])); + argv[i] = const_cast(NullableStringGet(aValues[i])); + } + + NPP npp = childInstance->GetNPP(); + + // FIXME/cjones: use SAFE_CALL stuff + *rv = mFunctions.newp((char*)NullableStringGet(aMimeType), + npp, + aMode, + argc, + argn, + argv, + 0); + if (NPERR_NO_ERROR != *rv) { + return true; + } + + childInstance->Initialize(); + +#if defined(XP_MACOSX) && defined(__i386__) + // If an i386 Mac OS X plugin has selected the Carbon event model then + // we have to fail. We do not support putting Carbon event model plugins + // out of process. Note that Carbon is the default model so out of process + // plugins need to actively negotiate something else in order to work + // out of process. + if (childInstance->EventModel() == NPEventModelCarbon) { + // Send notification that a plugin tried to negotiate Carbon NPAPI so that + // users can be notified that restarting the browser in i386 mode may allow + // them to use the plugin. + childInstance->SendNegotiatedCarbon(); + + // Fail to instantiate. + *rv = NPERR_MODULE_LOAD_FAILED_ERROR; + } +#endif -bool -PluginModuleChild::RecvAsyncNPP_New(PPluginInstanceChild* aActor) -{ - PLUGIN_LOG_DEBUG_METHOD; - PluginInstanceChild* childInstance = - reinterpret_cast(aActor); - AssertPluginThread(); - NPError rv = childInstance->DoNPP_New(); - childInstance->SendAsyncNPP_NewResult(rv); return true; } diff --git a/dom/plugins/ipc/PluginModuleChild.h b/dom/plugins/ipc/PluginModuleChild.h index bf0770dfe1c1..16ab97900978 100644 --- a/dom/plugins/ipc/PluginModuleChild.h +++ b/dom/plugins/ipc/PluginModuleChild.h @@ -78,10 +78,6 @@ protected: virtual bool RecvDisableFlashProtectedMode() MOZ_OVERRIDE; virtual bool AnswerNP_GetEntryPoints(NPError* rv) MOZ_OVERRIDE; virtual bool AnswerNP_Initialize(const PluginSettings& aSettings, NPError* rv) MOZ_OVERRIDE; - virtual bool RecvAsyncNP_Initialize(const PluginSettings& aSettings) MOZ_OVERRIDE; - virtual bool AnswerSyncNPP_New(PPluginInstanceChild* aActor, NPError* rv) - MOZ_OVERRIDE; - virtual bool RecvAsyncNPP_New(PPluginInstanceChild* aActor) MOZ_OVERRIDE; virtual PPluginModuleChild* AllocPPluginModuleChild(mozilla::ipc::Transport* aTransport, @@ -91,19 +87,19 @@ protected: AllocPPluginInstanceChild(const nsCString& aMimeType, const uint16_t& aMode, const InfallibleTArray& aNames, - const InfallibleTArray& aValues) - MOZ_OVERRIDE; + const InfallibleTArray& aValues, + NPError* rv) MOZ_OVERRIDE; virtual bool DeallocPPluginInstanceChild(PPluginInstanceChild* aActor) MOZ_OVERRIDE; virtual bool - RecvPPluginInstanceConstructor(PPluginInstanceChild* aActor, - const nsCString& aMimeType, - const uint16_t& aMode, - const InfallibleTArray& aNames, - const InfallibleTArray& aValues) - MOZ_OVERRIDE; + AnswerPPluginInstanceConstructor(PPluginInstanceChild* aActor, + const nsCString& aMimeType, + const uint16_t& aMode, + const InfallibleTArray& aNames, + const InfallibleTArray& aValues, + NPError* rv) MOZ_OVERRIDE; virtual bool AnswerNP_Shutdown(NPError *rv) MOZ_OVERRIDE; @@ -290,7 +286,6 @@ public: const PluginSettings& Settings() const { return mCachedSettings; } private: - NPError DoNP_Initialize(const PluginSettings& aSettings); void AddQuirk(PluginQuirks quirk) { if (mQuirks == QUIRKS_NOT_INITIALIZED) mQuirks = 0; diff --git a/dom/plugins/ipc/PluginModuleParent.cpp b/dom/plugins/ipc/PluginModuleParent.cpp index 8d597721fca1..9ed9a9ab6e2f 100755 --- a/dom/plugins/ipc/PluginModuleParent.cpp +++ b/dom/plugins/ipc/PluginModuleParent.cpp @@ -17,7 +17,6 @@ #include "mozilla/dom/PCrashReporterParent.h" #include "mozilla/ipc/MessageChannel.h" #include "mozilla/plugins/BrowserStreamParent.h" -#include "mozilla/plugins/PluginAsyncSurrogate.h" #include "mozilla/plugins/PluginBridge.h" #include "mozilla/plugins/PluginInstanceParent.h" #include "mozilla/Preferences.h" @@ -71,7 +70,6 @@ using namespace CrashReporter; static const char kChildTimeoutPref[] = "dom.ipc.plugins.timeoutSecs"; static const char kParentTimeoutPref[] = "dom.ipc.plugins.parentTimeoutSecs"; static const char kLaunchTimeoutPref[] = "dom.ipc.plugins.processLaunchTimeoutSecs"; -static const char kAsyncInitPref[] = "dom.ipc.plugins.asyncInit"; #ifdef XP_WIN static const char kHangUITimeoutPref[] = "dom.ipc.plugins.hangUITimeoutSecs"; static const char kHangUIMinDisplayPref[] = "dom.ipc.plugins.hangUIMinDisplaySecs"; @@ -97,228 +95,61 @@ mozilla::plugins::SetupBridge(uint32_t aPluginId, dom::ContentParent* aContentPa if (NS_FAILED(rv)) { return false; } - PluginModuleChromeParent* chromeParent = static_cast(plugin->GetLibrary()); - chromeParent->SetContentParent(aContentParent); - if (chromeParent->IsStartingAsync()) { - // We'll handle the bridging asynchronously - return true; - } - if (!chromeParent->SendAssociatePluginId()) { - return false; - } + PluginModuleParent* chromeParent = static_cast(plugin->GetLibrary()); return PPluginModule::Bridge(aContentParent, chromeParent); } -/** - * Objects of this class remain linked until either an error occurs in the - * plugin initialization sequence, or until - * PluginModuleContentParent::OnLoadPluginResult has completed executing. - */ -class PluginModuleMapping : public PRCList -{ -public: - explicit PluginModuleMapping(uint32_t aPluginId) - : mPluginId(aPluginId) - , mProcessIdValid(false) - , mModule(nullptr) - , mChannelOpened(false) - { - MOZ_COUNT_CTOR(PluginModuleMapping); - PR_INIT_CLIST(this); - PR_APPEND_LINK(this, &sModuleListHead); - } - - ~PluginModuleMapping() - { - PR_REMOVE_LINK(this); - MOZ_COUNT_DTOR(PluginModuleMapping); - } - - bool - IsChannelOpened() const - { - return mChannelOpened; - } - - void - SetChannelOpened() - { - mChannelOpened = true; - } - - PluginModuleContentParent* - GetModule() - { - if (!mModule) { - mModule = new PluginModuleContentParent(); - } - return mModule; - } - - static PluginModuleMapping* - AssociateWithProcessId(uint32_t aPluginId, base::ProcessId aProcessId) - { - PluginModuleMapping* mapping = - static_cast(PR_NEXT_LINK(&sModuleListHead)); - while (mapping != &sModuleListHead) { - if (mapping->mPluginId == aPluginId) { - mapping->AssociateWithProcessId(aProcessId); - return mapping; - } - mapping = static_cast(PR_NEXT_LINK(mapping)); - } - return nullptr; - } - - static PluginModuleMapping* - FindModuleByProcessId(base::ProcessId aProcessId) - { - PluginModuleMapping* mapping = - static_cast(PR_NEXT_LINK(&sModuleListHead)); - while (mapping != &sModuleListHead) { - if (mapping->mProcessIdValid && mapping->mProcessId == aProcessId) { - return mapping; - } - mapping = static_cast(PR_NEXT_LINK(mapping)); - } - return nullptr; - } - - static PluginModuleMapping* - FindModuleByPluginId(uint32_t aPluginId) - { - PluginModuleMapping* mapping = - static_cast(PR_NEXT_LINK(&sModuleListHead)); - while (mapping != &sModuleListHead) { - if (mapping->mPluginId == aPluginId) { - return mapping; - } - mapping = static_cast(PR_NEXT_LINK(mapping)); - } - return nullptr; - } - -private: - void - AssociateWithProcessId(base::ProcessId aProcessId) - { - MOZ_ASSERT(!mProcessIdValid); - mProcessId = aProcessId; - mProcessIdValid = true; - } - - uint32_t mPluginId; - bool mProcessIdValid; - base::ProcessId mProcessId; - PluginModuleContentParent* mModule; - bool mChannelOpened; - - static PRCList sModuleListHead; -}; - -PRCList PluginModuleMapping::sModuleListHead = - PR_INIT_STATIC_CLIST(&PluginModuleMapping::sModuleListHead); +PluginModuleContentParent* PluginModuleContentParent::sSavedModuleParent; /* static */ PluginLibrary* PluginModuleContentParent::LoadModule(uint32_t aPluginId) { - nsAutoPtr mapping(new PluginModuleMapping(aPluginId)); - + MOZ_ASSERT(!sSavedModuleParent); MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Content); /* * We send a LoadPlugin message to the chrome process using an intr * message. Before it sends its response, it sends a message to create * PluginModuleParent instance. That message is handled by - * PluginModuleContentParent::Initialize, which saves the instance in - * its module mapping. We fetch it from there after LoadPlugin finishes. + * PluginModuleContentParent::Create, which saves the instance in + * sSavedModuleParent. We fetch it from there after LoadPlugin finishes. */ dom::ContentChild* cp = dom::ContentChild::GetSingleton(); if (!cp->SendLoadPlugin(aPluginId)) { return nullptr; } - PluginModuleContentParent* parent = mapping->GetModule(); + PluginModuleContentParent* parent = sSavedModuleParent; MOZ_ASSERT(parent); - - if (!mapping->IsChannelOpened()) { - // mapping is linked into PluginModuleMapping::sModuleListHead and is - // needed later, so since this function is returning successfully we - // forget it here. - mapping.forget(); - } + sSavedModuleParent = nullptr; return parent; } -/* static */ void -PluginModuleContentParent::AssociatePluginId(uint32_t aPluginId, - base::ProcessId aProcessId) -{ - DebugOnly mapping = - PluginModuleMapping::AssociateWithProcessId(aPluginId, aProcessId); - MOZ_ASSERT(mapping); -} - /* static */ PluginModuleContentParent* -PluginModuleContentParent::Initialize(mozilla::ipc::Transport* aTransport, - base::ProcessId aOtherProcess) +PluginModuleContentParent::Create(mozilla::ipc::Transport* aTransport, + base::ProcessId aOtherProcess) { - nsAutoPtr moduleMapping( - PluginModuleMapping::FindModuleByProcessId(aOtherProcess)); - MOZ_ASSERT(moduleMapping); - PluginModuleContentParent* parent = moduleMapping->GetModule(); - MOZ_ASSERT(parent); - + nsAutoPtr parent(new PluginModuleContentParent()); ProcessHandle handle; if (!base::OpenProcessHandle(aOtherProcess, &handle)) { // Bug 1090578 - need to kill |aOtherProcess|, it's boned. return nullptr; } + MOZ_ASSERT(!sSavedModuleParent); + sSavedModuleParent = parent; + DebugOnly ok = parent->Open(aTransport, handle, XRE_GetIOMessageLoop(), mozilla::ipc::ParentSide); MOZ_ASSERT(ok); - moduleMapping->SetChannelOpened(); - // Request Windows message deferral behavior on our channel. This // applies to the top level and all sub plugin protocols since they // all share the same channel. parent->GetIPCChannel()->SetChannelFlags(MessageChannel::REQUIRE_DEFERRED_MESSAGE_PROTECTION); - // moduleMapping is linked into PluginModuleMapping::sModuleListHead and is - // needed later, so since this function is returning successfully we - // forget it here. - moduleMapping.forget(); - return parent; -} - -/* static */ void -PluginModuleContentParent::OnLoadPluginResult(const uint32_t& aPluginId, - const bool& aResult) -{ - nsAutoPtr moduleMapping( - PluginModuleMapping::FindModuleByPluginId(aPluginId)); - MOZ_ASSERT(moduleMapping); - PluginModuleContentParent* parent = moduleMapping->GetModule(); - MOZ_ASSERT(parent); - parent->RecvNP_InitializeResult(aResult ? NPERR_NO_ERROR - : NPERR_GENERIC_ERROR); -} - -void -PluginModuleChromeParent::SetContentParent(dom::ContentParent* aContentParent) -{ - MOZ_ASSERT(aContentParent); - mContentParent = aContentParent; -} - -bool -PluginModuleChromeParent::SendAssociatePluginId() -{ - MOZ_ASSERT(mContentParent); - return mContentParent->SendAssociatePluginId(mPluginId, OtherSidePID()); + return parent.forget(); } // static @@ -328,118 +159,49 @@ PluginModuleChromeParent::LoadModule(const char* aFilePath, uint32_t aPluginId, { PLUGIN_LOG_DEBUG_FUNCTION; + int32_t prefSecs = Preferences::GetInt(kLaunchTimeoutPref, 0); + + // Block on the child process being launched and initialized. nsAutoPtr parent(new PluginModuleChromeParent(aFilePath, aPluginId)); - UniquePtr onLaunchedRunnable(new LaunchedTask(parent)); - parent->mSubprocess->SetCallRunnableImmediately(!parent->mIsStartingAsync); TimeStamp launchStart = TimeStamp::Now(); - bool launched = parent->mSubprocess->Launch(Move(onLaunchedRunnable)); + bool launched = parent->mSubprocess->Launch(prefSecs * 1000); if (!launched) { // We never reached open parent->mShutdown = true; return nullptr; } - if (!parent->mIsStartingAsync) { - int32_t launchTimeoutSecs = Preferences::GetInt(kLaunchTimeoutPref, 0); - if (!parent->mSubprocess->WaitUntilConnected(launchTimeoutSecs * 1000)) { - parent->mShutdown = true; - return nullptr; - } - } TimeStamp launchEnd = TimeStamp::Now(); parent->mTimeBlocked = (launchEnd - launchStart); - parent->mIsFlashPlugin = aPluginTag->mIsFlashPlugin; - return parent.forget(); -} - -void -PluginModuleChromeParent::OnProcessLaunched(const bool aSucceeded) -{ - if (!aSucceeded) { - mShutdown = true; - OnInitFailure(); - return; - } - // We may have already been initialized by another call that was waiting - // for process connect. If so, this function doesn't need to run. - if (mAsyncInitRv != NS_ERROR_NOT_INITIALIZED || mShutdown) { - return; - } - Open(mSubprocess->GetChannel(), mSubprocess->GetChildProcessHandle()); + parent->Open(parent->mSubprocess->GetChannel(), + parent->mSubprocess->GetChildProcessHandle()); // Request Windows message deferral behavior on our channel. This // applies to the top level and all sub plugin protocols since they // all share the same channel. - GetIPCChannel()->SetChannelFlags(MessageChannel::REQUIRE_DEFERRED_MESSAGE_PROTECTION); + parent->GetIPCChannel()->SetChannelFlags(MessageChannel::REQUIRE_DEFERRED_MESSAGE_PROTECTION); - TimeoutChanged(CHILD_TIMEOUT_PREF, this); - - Preferences::RegisterCallback(TimeoutChanged, kChildTimeoutPref, this); - Preferences::RegisterCallback(TimeoutChanged, kParentTimeoutPref, this); -#ifdef XP_WIN - Preferences::RegisterCallback(TimeoutChanged, kHangUITimeoutPref, this); - Preferences::RegisterCallback(TimeoutChanged, kHangUIMinDisplayPref, this); -#endif + TimeoutChanged(CHILD_TIMEOUT_PREF, parent); #ifdef MOZ_CRASHREPORTER // If this fails, we're having IPC troubles, and we're doomed anyways. - if (!CrashReporterParent::CreateCrashReporter(this)) { - mShutdown = true; - Close(); - OnInitFailure(); - return; + if (!CrashReporterParent::CreateCrashReporter(parent.get())) { + parent->Close(); + return nullptr; } #ifdef XP_WIN - { // Scope for lock - mozilla::MutexAutoLock lock(mCrashReporterMutex); - mCrashReporter = CrashReporter(); - } + mozilla::MutexAutoLock lock(parent->mCrashReporterMutex); + parent->mCrashReporter = parent->CrashReporter(); #endif #endif #ifdef XP_WIN - if (mIsFlashPlugin && + if (aPluginTag->mIsFlashPlugin && Preferences::GetBool("dom.ipc.plugins.flash.disable-protected-mode", false)) { - SendDisableFlashProtectedMode(); + parent->SendDisableFlashProtectedMode(); } #endif - if (mInitOnAsyncConnect) { - mInitOnAsyncConnect = false; -#if defined(XP_WIN) - mAsyncInitRv = NP_GetEntryPoints(mAsyncInitPluginFuncs, - &mAsyncInitError); - if (NS_SUCCEEDED(mAsyncInitRv)) -#endif - { -#if defined(XP_UNIX) && !defined(XP_MACOSX) && !defined(MOZ_WIDGET_GONK) - mAsyncInitRv = NP_Initialize(mNPNIface, - mAsyncInitPluginFuncs, - &mAsyncInitError); -#else - mAsyncInitRv = NP_Initialize(mNPNIface, - &mAsyncInitError); -#endif - } - -#if defined(XP_MACOSX) - if (NS_SUCCEEDED(mAsyncInitRv)) { - mAsyncInitRv = NP_GetEntryPoints(mAsyncInitPluginFuncs, - &mAsyncInitError); - } -#endif - } -} - -bool -PluginModuleChromeParent::WaitForIPCConnection() -{ - PluginProcessParent* process = Process(); - MOZ_ASSERT(process); - process->SetCallRunnableImmediately(true); - if (!process->WaitUntilConnected()) { - return false; - } - return true; + return parent.forget(); } PluginModuleParent::PluginModuleParent(bool aIsChrome) @@ -450,14 +212,7 @@ PluginModuleParent::PluginModuleParent(bool aIsChrome) , mNPNIface(nullptr) , mPlugin(nullptr) , mTaskFactory(MOZ_THIS_IN_INITIALIZER_LIST()) - , mIsStartingAsync(false) - , mNPInitialized(false) - , mAsyncNewRv(NS_ERROR_NOT_INITIALIZED) - , mAsyncInitPluginFuncs(nullptr) { -#if defined(XP_WIN) || defined(XP_MACOSX) || defined(MOZ_WIDGET_GTK) - mIsStartingAsync = Preferences::GetBool(kAsyncInitPref, false); -#endif } PluginModuleParent::~PluginModuleParent() @@ -498,14 +253,16 @@ PluginModuleChromeParent::PluginModuleChromeParent(const char* aFilePath, uint32 , mFlashProcess1(0) , mFlashProcess2(0) #endif - , mInitOnAsyncConnect(false) - , mAsyncInitRv(NS_ERROR_NOT_INITIALIZED) - , mAsyncInitError(NPERR_NO_ERROR) - , mContentParent(nullptr) - , mIsFlashPlugin(false) { NS_ASSERTION(mSubprocess, "Out of memory!"); + Preferences::RegisterCallback(TimeoutChanged, kChildTimeoutPref, this); + Preferences::RegisterCallback(TimeoutChanged, kParentTimeoutPref, this); +#ifdef XP_WIN + Preferences::RegisterCallback(TimeoutChanged, kHangUITimeoutPref, this); + Preferences::RegisterCallback(TimeoutChanged, kHangUIMinDisplayPref, this); +#endif + RegisterSettingsCallbacks(); #ifdef MOZ_ENABLE_PROFILER_SPS @@ -1190,7 +947,8 @@ PPluginInstanceParent* PluginModuleParent::AllocPPluginInstanceParent(const nsCString& aMimeType, const uint16_t& aMode, const InfallibleTArray& aNames, - const InfallibleTArray& aValues) + const InfallibleTArray& aValues, + NPError* rv) { NS_ERROR("Not reachable!"); return nullptr; @@ -1242,19 +1000,6 @@ PluginModuleParent::SetPluginFuncs(NPPluginFuncs* aFuncs) } } -#define RESOLVE_AND_CALL(instance, func) \ -NP_BEGIN_MACRO \ - PluginAsyncSurrogate* surrogate = nullptr; \ - PluginInstanceParent* i = PluginInstanceParent::Cast(instance, &surrogate);\ - if (surrogate && (!i || i->UseSurrogate())) { \ - return surrogate->func; \ - } \ - if (!i) { \ - return NPERR_GENERIC_ERROR; \ - } \ - return i->func; \ -NP_END_MACRO - NPError PluginModuleParent::NPP_Destroy(NPP instance, NPSavedData** /*saved*/) @@ -1264,9 +1009,10 @@ PluginModuleParent::NPP_Destroy(NPP instance, // (2) the child shuts down its instance // (3) remove both parent and child IDs from map // (4) free parent - PLUGIN_LOG_DEBUG_FUNCTION; - PluginInstanceParent* parentInstance = PluginInstanceParent::Cast(instance); + + PluginInstanceParent* parentInstance = + static_cast(instance->pdata); if (!parentInstance) return NPERR_NO_ERROR; @@ -1285,13 +1031,23 @@ PluginModuleParent::NPP_NewStream(NPP instance, NPMIMEType type, { PROFILER_LABEL("PluginModuleParent", "NPP_NewStream", js::ProfileEntry::Category::OTHER); - RESOLVE_AND_CALL(instance, NPP_NewStream(type, stream, seekable, stype)); + + PluginInstanceParent* i = InstCast(instance); + if (!i) + return NPERR_GENERIC_ERROR; + + return i->NPP_NewStream(type, stream, seekable, + stype); } NPError PluginModuleParent::NPP_SetWindow(NPP instance, NPWindow* window) { - RESOLVE_AND_CALL(instance, NPP_SetWindow(window)); + PluginInstanceParent* i = InstCast(instance); + if (!i) + return NPERR_GENERIC_ERROR; + + return i->NPP_SetWindow(window); } NPError @@ -1299,7 +1055,7 @@ PluginModuleParent::NPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason) { - PluginInstanceParent* i = PluginInstanceParent::Cast(instance); + PluginInstanceParent* i = InstCast(instance); if (!i) return NPERR_GENERIC_ERROR; @@ -1310,14 +1066,9 @@ int32_t PluginModuleParent::NPP_WriteReady(NPP instance, NPStream* stream) { - PluginAsyncSurrogate* surrogate = nullptr; - BrowserStreamParent* s = StreamCast(instance, stream, &surrogate); - if (!s) { - if (surrogate) { - return surrogate->NPP_WriteReady(stream); - } + BrowserStreamParent* s = StreamCast(instance, stream); + if (!s) return -1; - } return s->WriteReady(); } @@ -1351,22 +1102,26 @@ PluginModuleParent::NPP_StreamAsFile(NPP instance, void PluginModuleParent::NPP_Print(NPP instance, NPPrint* platformPrint) { - - PluginInstanceParent* i = PluginInstanceParent::Cast(instance); - i->NPP_Print(platformPrint); + PluginInstanceParent* i = InstCast(instance); + if (i) + i->NPP_Print(platformPrint); } int16_t PluginModuleParent::NPP_HandleEvent(NPP instance, void* event) { - RESOLVE_AND_CALL(instance, NPP_HandleEvent(event)); + PluginInstanceParent* i = InstCast(instance); + if (!i) + return false; + + return i->NPP_HandleEvent(event); } void PluginModuleParent::NPP_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData) { - PluginInstanceParent* i = PluginInstanceParent::Cast(instance); + PluginInstanceParent* i = InstCast(instance); if (!i) return; @@ -1377,16 +1132,10 @@ NPError PluginModuleParent::NPP_GetValue(NPP instance, NPPVariable variable, void *ret_value) { - // The rules are slightly different for this function. - // If there is a surrogate, we *always* use it. - PluginAsyncSurrogate* surrogate = nullptr; - PluginInstanceParent* i = PluginInstanceParent::Cast(instance, &surrogate); - if (surrogate) { - return surrogate->NPP_GetValue(variable, ret_value); - } - if (!i) { + PluginInstanceParent* i = InstCast(instance); + if (!i) return NPERR_GENERIC_ERROR; - } + return i->NPP_GetValue(variable, ret_value); } @@ -1394,7 +1143,11 @@ NPError PluginModuleParent::NPP_SetValue(NPP instance, NPNVariable variable, void *value) { - RESOLVE_AND_CALL(instance, NPP_SetValue(variable, value)); + PluginInstanceParent* i = InstCast(instance); + if (!i) + return NPERR_GENERIC_ERROR; + + return i->NPP_SetValue(variable, value); } bool @@ -1417,21 +1170,37 @@ void PluginModuleParent::NPP_URLRedirectNotify(NPP instance, const char* url, int32_t status, void* notifyData) { - PluginInstanceParent* i = PluginInstanceParent::Cast(instance); + PluginInstanceParent* i = InstCast(instance); if (!i) return; i->NPP_URLRedirectNotify(url, status, notifyData); } -BrowserStreamParent* -PluginModuleParent::StreamCast(NPP instance, NPStream* s, - PluginAsyncSurrogate** aSurrogate) +PluginInstanceParent* +PluginModuleParent::InstCast(NPP instance) { - PluginInstanceParent* ip = PluginInstanceParent::Cast(instance, aSurrogate); - if (!ip || (aSurrogate && *aSurrogate && ip->UseSurrogate())) { + PluginInstanceParent* ip = + static_cast(instance->pdata); + + // If the plugin crashed and the PluginInstanceParent was deleted, + // instance->pdata will be nullptr. + if (!ip) return nullptr; + + if (instance != ip->mNPP) { + NS_RUNTIMEABORT("Corrupted plugin data."); } + return ip; +} + +BrowserStreamParent* +PluginModuleParent::StreamCast(NPP instance, + NPStream* s) +{ + PluginInstanceParent* ip = InstCast(instance); + if (!ip) + return nullptr; BrowserStreamParent* sp = static_cast(static_cast(s->pdata)); @@ -1450,13 +1219,10 @@ PluginModuleParent::HasRequiredFunctions() nsresult PluginModuleParent::AsyncSetWindow(NPP instance, NPWindow* window) { - PluginAsyncSurrogate* surrogate = nullptr; - PluginInstanceParent* i = PluginInstanceParent::Cast(instance, &surrogate); - if (surrogate && (!i || i->UseSurrogate())) { - return surrogate->AsyncSetWindow(window); - } else if (!i) { + PluginInstanceParent* i = InstCast(instance); + if (!i) return NS_ERROR_FAILURE; - } + return i->AsyncSetWindow(window); } @@ -1464,7 +1230,7 @@ nsresult PluginModuleParent::GetImageContainer(NPP instance, mozilla::layers::ImageContainer** aContainer) { - PluginInstanceParent* i = PluginInstanceParent::Cast(instance); + PluginInstanceParent* i = InstCast(instance); return !i ? NS_ERROR_FAILURE : i->GetImageContainer(aContainer); } @@ -1472,14 +1238,14 @@ nsresult PluginModuleParent::GetImageSize(NPP instance, nsIntSize* aSize) { - PluginInstanceParent* i = PluginInstanceParent::Cast(instance); + PluginInstanceParent* i = InstCast(instance); return !i ? NS_ERROR_FAILURE : i->GetImageSize(aSize); } nsresult PluginModuleParent::SetBackgroundUnknown(NPP instance) { - PluginInstanceParent* i = PluginInstanceParent::Cast(instance); + PluginInstanceParent* i = InstCast(instance); if (!i) return NS_ERROR_FAILURE; @@ -1491,7 +1257,7 @@ PluginModuleParent::BeginUpdateBackground(NPP instance, const nsIntRect& aRect, gfxContext** aCtx) { - PluginInstanceParent* i = PluginInstanceParent::Cast(instance); + PluginInstanceParent* i = InstCast(instance); if (!i) return NS_ERROR_FAILURE; @@ -1503,28 +1269,13 @@ PluginModuleParent::EndUpdateBackground(NPP instance, gfxContext* aCtx, const nsIntRect& aRect) { - PluginInstanceParent* i = PluginInstanceParent::Cast(instance); + PluginInstanceParent* i = InstCast(instance); if (!i) return NS_ERROR_FAILURE; return i->EndUpdateBackground(aCtx, aRect); } -void -PluginModuleParent::OnInitFailure() -{ - if (GetIPCChannel()->CanSend()) { - Close(); - } - /* If we've failed then we need to enumerate any pending NPP_New calls - and clean them up. */ - uint32_t len = mSurrogateInstances.Length(); - for (uint32_t i = 0; i < len; ++i) { - mSurrogateInstances[i]->NotifyAsyncInitFailed(); - } - mSurrogateInstances.Clear(); -} - class OfflineObserver MOZ_FINAL : public nsIObserver { public: @@ -1639,106 +1390,28 @@ PluginModuleParent::NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs return NS_ERROR_FAILURE; } - SetPluginFuncs(pFuncs); - *error = NPERR_NO_ERROR; - return NS_OK; -} - -nsresult -PluginModuleChromeParent::NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs, NPError* error) -{ - PLUGIN_LOG_DEBUG_METHOD; - - mNPNIface = bFuncs; - - if (mShutdown) { - *error = NPERR_GENERIC_ERROR; - return NS_ERROR_FAILURE; - } - - mAsyncInitPluginFuncs = pFuncs; - - if (!mSubprocess->IsConnected()) { - // The subprocess isn't connected yet. Defer NP_Initialize until - // OnProcessLaunched is invoked. - mInitOnAsyncConnect = true; - *error = NPERR_NO_ERROR; - return NS_OK; - } - - if (mIsStartingAsync) { - PluginAsyncSurrogate::NP_GetEntryPoints(pFuncs); - } - - *error = NPERR_NO_ERROR; - - PluginSettings settings; - GetSettings(&settings); - - TimeStamp callNpInitStart = TimeStamp::Now(); - // Asynchronous case - if (mIsStartingAsync) { - if (!SendAsyncNP_Initialize(settings)) { + if (IsChrome()) { + PluginSettings settings; + GetSettings(&settings); + TimeStamp callNpInitStart = TimeStamp::Now(); + if (!CallNP_Initialize(settings, error)) { + Close(); return NS_ERROR_FAILURE; } + else if (*error != NPERR_NO_ERROR) { + Close(); + return NS_OK; + } TimeStamp callNpInitEnd = TimeStamp::Now(); mTimeBlocked += (callNpInitEnd - callNpInitStart); - return NS_PLUGIN_INIT_PENDING; } - // Synchronous case - if (!CallNP_Initialize(settings, error)) { - Close(); - return NS_ERROR_FAILURE; - } - else if (*error != NPERR_NO_ERROR) { - Close(); - return NS_OK; - } - TimeStamp callNpInitEnd = TimeStamp::Now(); - mTimeBlocked += (callNpInitEnd - callNpInitStart); - RecvNP_InitializeResult(*error); + SetPluginFuncs(pFuncs); return NS_OK; } - -bool -PluginModuleParent::RecvNP_InitializeResult(const NPError& aError) -{ - if (aError != NPERR_NO_ERROR) { - OnInitFailure(); - return true; - } - - SetPluginFuncs(mAsyncInitPluginFuncs); - InitAsyncSurrogates(); - - mNPInitialized = true; - return true; -} - -bool -PluginModuleChromeParent::RecvNP_InitializeResult(const NPError& aError) -{ - if (!mContentParent) { - return PluginModuleParent::RecvNP_InitializeResult(aError); - } - bool initOk = aError == NPERR_NO_ERROR; - if (initOk) { - SetPluginFuncs(mAsyncInitPluginFuncs); - if (SendAssociatePluginId()) { - PPluginModule::Bridge(mContentParent, this); - mNPInitialized = true; - } else { - initOk = false; - } - } - return mContentParent->SendLoadPluginResult(mPluginId, initOk); -} - #else - nsresult PluginModuleParent::NP_Initialize(NPNetscapeFuncs* bFuncs, NPError* error) { @@ -1762,123 +1435,39 @@ PluginModuleChromeParent::NP_Initialize(NPNetscapeFuncs* bFuncs, NPError* error) if (NS_FAILED(rv)) return rv; -#if defined(XP_MACOSX) - if (!mSubprocess->IsConnected()) { - // The subprocess isn't connected yet. Defer NP_Initialize until - // OnProcessLaunched is invoked. - mInitOnAsyncConnect = true; - *error = NPERR_NO_ERROR; - return NS_OK; - } -#else - if (mInitOnAsyncConnect) { - *error = NPERR_NO_ERROR; - return NS_OK; - } -#endif - PluginSettings settings; GetSettings(&settings); - TimeStamp callNpInitStart = TimeStamp::Now(); - if (mIsStartingAsync) { - if (!SendAsyncNP_Initialize(settings)) { - return NS_ERROR_FAILURE; - } - TimeStamp callNpInitEnd = TimeStamp::Now(); - mTimeBlocked += (callNpInitEnd - callNpInitStart); - return NS_PLUGIN_INIT_PENDING; - } - if (!CallNP_Initialize(settings, error)) { Close(); return NS_ERROR_FAILURE; } + if (*error != NPERR_NO_ERROR) { + Close(); + return NS_OK; + } TimeStamp callNpInitEnd = TimeStamp::Now(); mTimeBlocked += (callNpInitEnd - callNpInitStart); - RecvNP_InitializeResult(*error); - return NS_OK; -} -bool -PluginModuleParent::RecvNP_InitializeResult(const NPError& aError) -{ - if (aError != NPERR_NO_ERROR) { - OnInitFailure(); - return true; - } - - if (mIsStartingAsync) { -#if defined(XP_WIN) - SetPluginFuncs(mAsyncInitPluginFuncs); -#endif - InitAsyncSurrogates(); - } - - mNPInitialized = true; - return true; -} - -bool -PluginModuleChromeParent::RecvNP_InitializeResult(const NPError& aError) -{ - bool ok = true; - if (mContentParent) { - if ((ok = SendAssociatePluginId())) { - PPluginModule::Bridge(mContentParent, this); - ok = mContentParent->SendLoadPluginResult(mPluginId, - aError == NPERR_NO_ERROR); - } - } else if (aError == NPERR_NO_ERROR) { - // Initialization steps when e10s is disabled #if defined XP_WIN - if (mIsStartingAsync) { - SetPluginFuncs(mAsyncInitPluginFuncs); - } + // Send the info needed to join the chrome process's audio session to the + // plugin process + nsID id; + nsString sessionName; + nsString iconPath; - // Send the info needed to join the chrome process's audio session to the - // plugin process - nsID id; - nsString sessionName; - nsString iconPath; - - if (NS_SUCCEEDED(mozilla::widget::GetAudioSessionData(id, sessionName, - iconPath))) { - unused << SendSetAudioSessionData(id, sessionName, iconPath); - } + if (NS_SUCCEEDED(mozilla::widget::GetAudioSessionData(id, sessionName, + iconPath))) + unused << SendSetAudioSessionData(id, sessionName, iconPath); #endif #ifdef MOZ_CRASHREPORTER_INJECTOR - InitializeInjector(); -#endif - } - - return PluginModuleParent::RecvNP_InitializeResult(aError) && ok; -} - + InitializeInjector(); #endif -void -PluginModuleParent::InitAsyncSurrogates() -{ - uint32_t len = mSurrogateInstances.Length(); - for (uint32_t i = 0; i < len; ++i) { - NPError err; - mAsyncNewRv = mSurrogateInstances[i]->NPP_New(&err); - if (NS_FAILED(mAsyncNewRv)) { - mSurrogateInstances[i]->NotifyAsyncInitFailed(); - continue; - } - } - mSurrogateInstances.Clear(); -} - -bool -PluginModuleParent::RemovePendingSurrogate( - const nsRefPtr& aSurrogate) -{ - return mSurrogateInstances.RemoveElement(aSurrogate); + return NS_OK; } +#endif nsresult PluginModuleParent::NP_Shutdown(NPError* error) @@ -1931,54 +1520,25 @@ PluginModuleParent::NP_GetEntryPoints(NPPluginFuncs* pFuncs, NPError* error) { NS_ASSERTION(pFuncs, "Null pointer!"); - *error = NPERR_NO_ERROR; - if (mIsStartingAsync && !IsChrome()) { - PluginAsyncSurrogate::NP_GetEntryPoints(pFuncs); - mAsyncInitPluginFuncs = pFuncs; - } else { - SetPluginFuncs(pFuncs); - } - - return NS_OK; -} - -nsresult -PluginModuleChromeParent::NP_GetEntryPoints(NPPluginFuncs* pFuncs, NPError* error) -{ -#if defined(XP_MACOSX) - if (mInitOnAsyncConnect) { - PluginAsyncSurrogate::NP_GetEntryPoints(pFuncs); - mAsyncInitPluginFuncs = pFuncs; - *error = NPERR_NO_ERROR; - return NS_OK; - } -#else - if (mIsStartingAsync) { - PluginAsyncSurrogate::NP_GetEntryPoints(pFuncs); - } - if (!mSubprocess->IsConnected()) { - mAsyncInitPluginFuncs = pFuncs; - mInitOnAsyncConnect = true; - *error = NPERR_NO_ERROR; - return NS_OK; - } -#endif - // We need to have the plugin process update its function table here by // actually calling NP_GetEntryPoints. The parent's function table will // reflect nullptr entries in the child's table once SetPluginFuncs is // called. - if (!CallNP_GetEntryPoints(error)) { - return NS_ERROR_FAILURE; - } - else if (*error != NPERR_NO_ERROR) { - return NS_OK; + if (IsChrome()) { + if (!CallNP_GetEntryPoints(error)) { + return NS_ERROR_FAILURE; + } + else if (*error != NPERR_NO_ERROR) { + return NS_OK; + } } - return PluginModuleParent::NP_GetEntryPoints(pFuncs, error); + *error = NPERR_NO_ERROR; + SetPluginFuncs(pFuncs); + + return NS_OK; } - #endif nsresult @@ -1994,22 +1554,6 @@ PluginModuleParent::NPP_New(NPMIMEType pluginType, NPP instance, return NS_ERROR_FAILURE; } - if (mIsStartingAsync) { - if (!PluginAsyncSurrogate::Create(this, pluginType, instance, mode, - argc, argn, argv)) { - *error = NPERR_GENERIC_ERROR; - return NS_ERROR_FAILURE; - } - - if (!mNPInitialized) { - nsRefPtr surrogate = - PluginAsyncSurrogate::Cast(instance); - mSurrogateInstances.AppendElement(surrogate); - *error = NPERR_NO_ERROR; - return NS_PLUGIN_INIT_PENDING; - } - } - if (mPluginName.IsEmpty()) { GetPluginDetails(mPluginName, mPluginVersion); /** mTimeBlocked measures the time that the main thread has been blocked @@ -2033,21 +1577,6 @@ PluginModuleParent::NPP_New(NPMIMEType pluginType, NPP instance, values.AppendElement(NullableString(argv[i])); } - nsresult rv = NPP_NewInternal(pluginType, instance, mode, names, values, - saved, error); - if (NS_FAILED(rv) || !mIsStartingAsync) { - return rv; - } - return NS_PLUGIN_INIT_PENDING; -} - -nsresult -PluginModuleParent::NPP_NewInternal(NPMIMEType pluginType, NPP instance, - uint16_t mode, - InfallibleTArray& names, - InfallibleTArray& values, - NPSavedData* saved, NPError* error) -{ PluginInstanceParent* parentInstance = new PluginInstanceParent(this, instance, nsDependentCString(pluginType), mNPNIface); @@ -2057,49 +1586,27 @@ PluginModuleParent::NPP_NewInternal(NPMIMEType pluginType, NPP instance, return NS_ERROR_FAILURE; } - // Release the surrogate reference that was in pdata - nsRefPtr surrogate( - dont_AddRef(PluginAsyncSurrogate::Cast(instance))); - // Now replace it with the instance - instance->pdata = static_cast(parentInstance); - - if (!SendPPluginInstanceConstructor(parentInstance, - nsDependentCString(pluginType), mode, - names, values)) { - // |parentInstance| is automatically deleted. - instance->pdata = nullptr; - *error = NPERR_GENERIC_ERROR; - return NS_ERROR_FAILURE; - } + instance->pdata = parentInstance; { // Scope for timer Telemetry::AutoTimer timer(GetHistogramKey()); - if (mIsStartingAsync) { - MOZ_ASSERT(surrogate); - surrogate->AsyncCallDeparting(); - if (!SendAsyncNPP_New(parentInstance)) { + if (!CallPPluginInstanceConstructor(parentInstance, + nsDependentCString(pluginType), mode, + names, values, error)) { + // |parentInstance| is automatically deleted. + instance->pdata = nullptr; + // if IPC is down, we'll get an immediate "failed" return, but + // without *error being set. So make sure that the error + // condition is signaled to nsNPAPIPluginInstance + if (NPERR_NO_ERROR == *error) *error = NPERR_GENERIC_ERROR; - return NS_ERROR_FAILURE; - } - *error = NPERR_NO_ERROR; - } else { - if (!CallSyncNPP_New(parentInstance, error)) { - // if IPC is down, we'll get an immediate "failed" return, but - // without *error being set. So make sure that the error - // condition is signaled to nsNPAPIPluginInstance - if (NPERR_NO_ERROR == *error) { - *error = NPERR_GENERIC_ERROR; - } - return NS_ERROR_FAILURE; - } + return NS_ERROR_FAILURE; } } if (*error != NPERR_NO_ERROR) { - if (!mIsStartingAsync) { - NPP_Destroy(instance, 0); - } + NPP_Destroy(instance, 0); return NS_ERROR_FAILURE; } @@ -2153,7 +1660,7 @@ PluginModuleParent::NPP_GetSitesWithData(InfallibleTArray& result) nsresult PluginModuleParent::IsRemoteDrawingCoreAnimation(NPP instance, bool *aDrawing) { - PluginInstanceParent* i = PluginInstanceParent::Cast(instance); + PluginInstanceParent* i = InstCast(instance); if (!i) return NS_ERROR_FAILURE; @@ -2163,7 +1670,7 @@ PluginModuleParent::IsRemoteDrawingCoreAnimation(NPP instance, bool *aDrawing) nsresult PluginModuleParent::ContentsScaleFactorChanged(NPP instance, double aContentsScaleFactor) { - PluginInstanceParent* i = PluginInstanceParent::Cast(instance); + PluginInstanceParent* i = InstCast(instance); if (!i) return NS_ERROR_FAILURE; diff --git a/dom/plugins/ipc/PluginModuleParent.h b/dom/plugins/ipc/PluginModuleParent.h index c6cba7d49eb2..6ecae4907a69 100644 --- a/dom/plugins/ipc/PluginModuleParent.h +++ b/dom/plugins/ipc/PluginModuleParent.h @@ -40,7 +40,6 @@ namespace plugins { //----------------------------------------------------------------------------- class BrowserStreamParent; -class PluginAsyncSurrogate; class PluginInstanceParent; #ifdef XP_WIN @@ -80,8 +79,8 @@ protected: AllocPPluginInstanceParent(const nsCString& aMimeType, const uint16_t& aMode, const InfallibleTArray& aNames, - const InfallibleTArray& aValues) - MOZ_OVERRIDE; + const InfallibleTArray& aValues, + NPError* rv) MOZ_OVERRIDE; virtual bool DeallocPPluginInstanceParent(PPluginInstanceParent* aActor) MOZ_OVERRIDE; @@ -90,13 +89,6 @@ public: explicit PluginModuleParent(bool aIsChrome); virtual ~PluginModuleParent(); - bool RemovePendingSurrogate(const nsRefPtr& 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) MOZ_OVERRIDE @@ -116,8 +108,6 @@ public: void ProcessRemoteNativeEventsInInterruptCall(); - virtual bool WaitForIPCConnection() { return true; } - nsCString GetHistogramKey() const { return mPluginName + mPluginVersion; } @@ -169,11 +159,8 @@ protected: virtual bool RecvNPN_ReloadPlugins(const bool& aReloadPages) MOZ_OVERRIDE; - virtual bool - RecvNP_InitializeResult(const NPError& aError) MOZ_OVERRIDE; - - static BrowserStreamParent* StreamCast(NPP instance, NPStream* s, - PluginAsyncSurrogate** aSurrogate = nullptr); + static PluginInstanceParent* InstCast(NPP instance); + static BrowserStreamParent* StreamCast(NPP instance, NPStream* s); protected: virtual void UpdatePluginTimeout() {} @@ -182,11 +169,6 @@ protected: void SetPluginFuncs(NPPluginFuncs* aFuncs); - nsresult NPP_NewInternal(NPMIMEType pluginType, NPP instance, uint16_t mode, - InfallibleTArray& names, - InfallibleTArray& 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. @@ -253,11 +235,8 @@ protected: virtual nsresult ContentsScaleFactorChanged(NPP instance, double aContentsScaleFactor); #endif - void InitAsyncSurrogates(); - protected: void NotifyPluginCrashed(); - void OnInitFailure(); bool GetSetting(NPNVariable aVariable); void GetSettings(PluginSettings* aSettings); @@ -266,7 +245,7 @@ protected: bool mShutdown; bool mClearSiteDataSupported; bool mGetSitesWithDataSupported; - NPNetscapeFuncs* mNPNIface; + const NPNetscapeFuncs* mNPNIface; nsNPAPIPlugin* mPlugin; ScopedMethodFactory mTaskFactory; nsString mPluginDumpID; @@ -287,29 +266,18 @@ protected: GetPluginDetails(nsACString& aPluginName, nsACString& aPluginVersion); friend class mozilla::dom::CrashReporterParent; - friend class mozilla::plugins::PluginAsyncSurrogate; - - bool mIsStartingAsync; - bool mNPInitialized; - nsTArray> mSurrogateInstances; - nsresult mAsyncNewRv; - NPPluginFuncs* mAsyncInitPluginFuncs; }; 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); + static PluginModuleContentParent* Create(mozilla::ipc::Transport* aTransport, + base::ProcessId aOtherProcess); private: + explicit PluginModuleContentParent(); #ifdef MOZ_CRASHREPORTER_INJECTOR void OnCrash(DWORD processID) MOZ_OVERRIDE {} @@ -345,17 +313,6 @@ class PluginModuleChromeParent OnHangUIContinue(); #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(); private: @@ -384,14 +341,8 @@ private: 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) 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; +#if !defined(XP_UNIX) || defined(XP_MACOSX) || defined(MOZ_WIDGET_GONK) + virtual nsresult NP_Initialize(NPNetscapeFuncs* bFuncs, NPError* error); #endif virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE; @@ -470,45 +421,17 @@ private: #endif friend class mozilla::dom::CrashReporterParent; - friend class mozilla::plugins::PluginAsyncSurrogate; #ifdef MOZ_CRASHREPORTER_INJECTOR void InitializeInjector(); - + void OnCrash(DWORD processID) MOZ_OVERRIDE; DWORD mFlashProcess1; DWORD mFlashProcess2; #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 mOfflineObserver; - bool mIsFlashPlugin; }; } // namespace plugins diff --git a/dom/plugins/ipc/PluginProcessParent.cpp b/dom/plugins/ipc/PluginProcessParent.cpp index e304531717cf..d7fb2fde9743 100644 --- a/dom/plugins/ipc/PluginProcessParent.cpp +++ b/dom/plugins/ipc/PluginProcessParent.cpp @@ -12,7 +12,6 @@ #include "mozilla/ipc/BrowserProcessSubThread.h" #include "mozilla/plugins/PluginMessageUtils.h" #include "mozilla/Telemetry.h" -#include "nsThreadUtils.h" using std::vector; using std::string; @@ -31,9 +30,7 @@ struct RunnableMethodTraits PluginProcessParent::PluginProcessParent(const std::string& aPluginFilePath) : GeckoChildProcessHost(GeckoProcessType_Plugin), - mPluginFilePath(aPluginFilePath), - mMainMsgLoop(MessageLoop::current()), - mRunCompleteTaskImmediately(false) + mPluginFilePath(aPluginFilePath) { } @@ -42,7 +39,7 @@ PluginProcessParent::~PluginProcessParent() } bool -PluginProcessParent::Launch(UniquePtr aLaunchCompleteTask) +PluginProcessParent::Launch(int32_t timeoutMs) { ProcessArchitecture currentArchitecture = base::GetCurrentProcessArchitecture(); uint32_t containerArchitectures = GetSupportedArchitecturesForProcessType(GeckoProcessType_Plugin); @@ -77,16 +74,10 @@ PluginProcessParent::Launch(UniquePtr aLaunchCompleteTask) } } - mLaunchCompleteTask = Move(aLaunchCompleteTask); - vector args; args.push_back(MungePluginDsoPath(mPluginFilePath)); - - bool result = AsyncLaunch(args, selectedArchitecture); - if (!result) { - mLaunchCompleteTask = nullptr; - } - return result; + Telemetry::AutoTimer timer; + return SyncLaunch(args, timeoutMs, selectedArchitecture); } void @@ -103,50 +94,3 @@ PluginProcessParent::Delete() ioLoop->PostTask(FROM_HERE, NewRunnableMethod(this, &PluginProcessParent::Delete)); } - -void -PluginProcessParent::SetCallRunnableImmediately(bool aCallImmediately) -{ - mRunCompleteTaskImmediately = aCallImmediately; -} - -bool -PluginProcessParent::WaitUntilConnected(int32_t aTimeoutMs) -{ - bool result = GeckoChildProcessHost::WaitUntilConnected(aTimeoutMs); - if (mRunCompleteTaskImmediately && mLaunchCompleteTask) { - if (result) { - mLaunchCompleteTask->SetLaunchSucceeded(); - } - mLaunchCompleteTask->Run(); - mLaunchCompleteTask = nullptr; - } - return result; -} - -void -PluginProcessParent::OnChannelConnected(int32_t peer_pid) -{ - GeckoChildProcessHost::OnChannelConnected(peer_pid); - if (mLaunchCompleteTask && !mRunCompleteTaskImmediately) { - mLaunchCompleteTask->SetLaunchSucceeded(); - mMainMsgLoop->PostTask(FROM_HERE, mLaunchCompleteTask.release()); - } -} - -void -PluginProcessParent::OnChannelError() -{ - GeckoChildProcessHost::OnChannelError(); - if (mLaunchCompleteTask && !mRunCompleteTaskImmediately) { - mMainMsgLoop->PostTask(FROM_HERE, mLaunchCompleteTask.release()); - } -} - -bool -PluginProcessParent::IsConnected() -{ - mozilla::MonitorAutoLock lock(mMonitor); - return mProcessState == PROCESS_CONNECTED; -} - diff --git a/dom/plugins/ipc/PluginProcessParent.h b/dom/plugins/ipc/PluginProcessParent.h index d20dad348a90..fab54eda0ec3 100644 --- a/dom/plugins/ipc/PluginProcessParent.h +++ b/dom/plugins/ipc/PluginProcessParent.h @@ -11,32 +11,15 @@ #include "base/basictypes.h" #include "base/file_path.h" -#include "base/task.h" #include "base/thread.h" #include "base/waitable_event.h" #include "chrome/common/child_process_host.h" #include "mozilla/ipc/GeckoChildProcessHost.h" -#include "mozilla/UniquePtr.h" -#include "nsCOMPtr.h" -#include "nsIRunnable.h" namespace mozilla { namespace plugins { - -class LaunchCompleteTask : public Task -{ -public: - LaunchCompleteTask() - : mLaunchSucceeded(false) - { - } - - void SetLaunchSucceeded() { mLaunchSucceeded = true; } - -protected: - bool mLaunchSucceeded; -}; +//----------------------------------------------------------------------------- class PluginProcessParent : public mozilla::ipc::GeckoChildProcessHost { @@ -45,13 +28,10 @@ public: ~PluginProcessParent(); /** - * Launch the plugin process. If the process fails to launch, - * this method will return false. - * - * @param aLaunchCompleteTask Task that is executed on the main - * thread once the asynchonous launch has completed. + * Synchronously launch the plugin process. If the process fails to launch + * after timeoutMs, this method will return false. */ - bool Launch(UniquePtr aLaunchCompleteTask = UniquePtr()); + bool Launch(int32_t timeoutMs); void Delete(); @@ -65,19 +45,8 @@ public: using mozilla::ipc::GeckoChildProcessHost::GetShutDownEvent; using mozilla::ipc::GeckoChildProcessHost::GetChannel; - void SetCallRunnableImmediately(bool aCallImmediately); - virtual bool WaitUntilConnected(int32_t aTimeoutMs = 0) MOZ_OVERRIDE; - - virtual void OnChannelConnected(int32_t peer_pid) MOZ_OVERRIDE; - virtual void OnChannelError() MOZ_OVERRIDE; - - bool IsConnected(); - private: std::string mPluginFilePath; - UniquePtr mLaunchCompleteTask; - MessageLoop* mMainMsgLoop; - bool mRunCompleteTaskImmediately; DISALLOW_EVIL_CONSTRUCTORS(PluginProcessParent); }; diff --git a/dom/plugins/ipc/PluginScriptableObjectChild.cpp b/dom/plugins/ipc/PluginScriptableObjectChild.cpp index bd3f61eae2aa..471b95e0117d 100644 --- a/dom/plugins/ipc/PluginScriptableObjectChild.cpp +++ b/dom/plugins/ipc/PluginScriptableObjectChild.cpp @@ -1281,7 +1281,5 @@ PluginScriptableObjectChild::CollectForInstance(NPObjectData* d, void* userArg) PluginScriptableObjectChild::NotifyOfInstanceShutdown(PluginInstanceChild* aInstance) { AssertPluginThread(); - if (sObjectMap) { - sObjectMap->EnumerateEntries(CollectForInstance, aInstance); - } + sObjectMap->EnumerateEntries(CollectForInstance, aInstance); } diff --git a/dom/plugins/ipc/PluginScriptableObjectParent.cpp b/dom/plugins/ipc/PluginScriptableObjectParent.cpp index 60a5186e5689..3bbf3bc3e748 100644 --- a/dom/plugins/ipc/PluginScriptableObjectParent.cpp +++ b/dom/plugins/ipc/PluginScriptableObjectParent.cpp @@ -12,7 +12,6 @@ #include "mozilla/plugins/PluginTypes.h" #include "mozilla/unused.h" #include "nsNPAPIPlugin.h" -#include "PluginAsyncSurrogate.h" #include "PluginScriptableObjectUtils.h" using namespace mozilla; @@ -111,7 +110,6 @@ inline void ReleaseVariant(NPVariant& aVariant, PluginInstanceParent* aInstance) { - PushSurrogateAcceptCalls acceptCalls(aInstance); const NPNetscapeFuncs* npn = GetNetscapeFuncs(aInstance); if (npn) { npn->releasevariantvalue(&aVariant); @@ -645,7 +643,6 @@ PluginScriptableObjectParent::CreateProxyObject() NS_ASSERTION(mInstance, "Must have an instance!"); NS_ASSERTION(mType == Proxy, "Shouldn't call this for non-proxy object!"); - PushSurrogateAcceptCalls acceptCalls(mInstance); const NPNetscapeFuncs* npn = GetNetscapeFuncs(mInstance); NPObject* npobject = npn->createobject(mInstance->GetNPP(), @@ -764,7 +761,6 @@ PluginScriptableObjectParent::AnswerHasMethod(const PluginIdentifier& aId, return true; } - PushSurrogateAcceptCalls acceptCalls(instance); const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance); if (!npn) { NS_ERROR("No netscape funcs?!"); @@ -805,7 +801,6 @@ PluginScriptableObjectParent::AnswerInvoke(const PluginIdentifier& aId, return true; } - PushSurrogateAcceptCalls acceptCalls(instance); const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance); if (!npn) { NS_ERROR("No netscape funcs?!"); @@ -895,7 +890,6 @@ PluginScriptableObjectParent::AnswerInvokeDefault(const InfallibleTArray return true; } - PushSurrogateAcceptCalls acceptCalls(instance); const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance); if (!npn) { NS_WARNING("No netscape funcs?!"); @@ -1215,7 +1204,6 @@ PluginScriptableObjectParent::AnswerConstruct(const InfallibleTArray& a return true; } - PushSurrogateAcceptCalls acceptCalls(instance); const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance); if (!npn) { NS_ERROR("No netscape funcs?!"); @@ -1308,7 +1296,6 @@ PluginScriptableObjectParent::AnswerNPN_Evaluate(const nsCString& aScript, return true; } - PushSurrogateAcceptCalls acceptCalls(instance); const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance); if (!npn) { NS_ERROR("No netscape funcs?!"); diff --git a/dom/plugins/ipc/PluginScriptableObjectParent.h b/dom/plugins/ipc/PluginScriptableObjectParent.h index dfb67e99858c..1126f3d18663 100644 --- a/dom/plugins/ipc/PluginScriptableObjectParent.h +++ b/dom/plugins/ipc/PluginScriptableObjectParent.h @@ -16,7 +16,6 @@ namespace mozilla { namespace plugins { -class PluginAsyncSurrogate; class PluginInstanceParent; class PluginScriptableObjectParent; diff --git a/dom/plugins/ipc/moz.build b/dom/plugins/ipc/moz.build index f1f171efbf03..bdae35049fd3 100644 --- a/dom/plugins/ipc/moz.build +++ b/dom/plugins/ipc/moz.build @@ -21,9 +21,7 @@ EXPORTS.mozilla.plugins += [ 'NPEventOSX.h', 'NPEventUnix.h', 'NPEventWindows.h', - 'PluginAsyncSurrogate.h', 'PluginBridge.h', - 'PluginDataResolver.h', 'PluginInstanceChild.h', 'PluginInstanceParent.h', 'PluginMessageUtils.h', @@ -82,7 +80,6 @@ UNIFIED_SOURCES += [ 'BrowserStreamParent.cpp', 'ChildAsyncCall.cpp', 'ChildTimer.cpp', - 'PluginAsyncSurrogate.cpp', 'PluginBackgroundDestroyer.cpp', 'PluginInstanceParent.cpp', 'PluginMessageUtils.cpp', diff --git a/ipc/glue/GeckoChildProcessHost.cpp b/ipc/glue/GeckoChildProcessHost.cpp index 6e7733f24492..1460b07f5ceb 100644 --- a/ipc/glue/GeckoChildProcessHost.cpp +++ b/ipc/glue/GeckoChildProcessHost.cpp @@ -315,6 +315,8 @@ GeckoChildProcessHost::SyncLaunch(std::vector aExtraOpts, int aTime { PrepareLaunch(); + PRIntervalTime timeoutTicks = (aTimeoutMs > 0) ? + PR_MillisecondsToInterval(aTimeoutMs) : PR_INTERVAL_NO_TIMEOUT; MessageLoop* ioLoop = XRE_GetIOMessageLoop(); NS_ASSERTION(MessageLoop::current() != ioLoop, "sync launch from the IO thread NYI"); @@ -322,40 +324,8 @@ GeckoChildProcessHost::SyncLaunch(std::vector aExtraOpts, int aTime NewRunnableMethod(this, &GeckoChildProcessHost::RunPerformAsyncLaunch, aExtraOpts, arch)); - - return WaitUntilConnected(aTimeoutMs); -} - -bool -GeckoChildProcessHost::AsyncLaunch(std::vector aExtraOpts, - base::ProcessArchitecture arch) -{ - PrepareLaunch(); - - MessageLoop* ioLoop = XRE_GetIOMessageLoop(); - ioLoop->PostTask(FROM_HERE, - NewRunnableMethod(this, - &GeckoChildProcessHost::RunPerformAsyncLaunch, - aExtraOpts, arch)); - - // This may look like the sync launch wait, but we only delay as - // long as it takes to create the channel. - MonitorAutoLock lock(mMonitor); - while (mProcessState < CHANNEL_INITIALIZED) { - lock.Wait(); - } - - return true; -} - -bool -GeckoChildProcessHost::WaitUntilConnected(int32_t aTimeoutMs) -{ // NB: this uses a different mechanism than the chromium parent // class. - PRIntervalTime timeoutTicks = (aTimeoutMs > 0) ? - PR_MillisecondsToInterval(aTimeoutMs) : PR_INTERVAL_NO_TIMEOUT; - MonitorAutoLock lock(mMonitor); PRIntervalTime waitStart = PR_IntervalNow(); PRIntervalTime current; @@ -384,6 +354,27 @@ GeckoChildProcessHost::WaitUntilConnected(int32_t aTimeoutMs) return mProcessState == PROCESS_CONNECTED; } +bool +GeckoChildProcessHost::AsyncLaunch(std::vector aExtraOpts) +{ + PrepareLaunch(); + + MessageLoop* ioLoop = XRE_GetIOMessageLoop(); + ioLoop->PostTask(FROM_HERE, + NewRunnableMethod(this, + &GeckoChildProcessHost::RunPerformAsyncLaunch, + aExtraOpts, base::GetCurrentProcessArchitecture())); + + // This may look like the sync launch wait, but we only delay as + // long as it takes to create the channel. + MonitorAutoLock lock(mMonitor); + while (mProcessState < CHANNEL_INITIALIZED) { + lock.Wait(); + } + + return true; +} + bool GeckoChildProcessHost::LaunchAndWaitForProcessHandle(StringVector aExtraOpts) { diff --git a/ipc/glue/GeckoChildProcessHost.h b/ipc/glue/GeckoChildProcessHost.h index d5917de0197a..b7a8014b06fb 100644 --- a/ipc/glue/GeckoChildProcessHost.h +++ b/ipc/glue/GeckoChildProcessHost.h @@ -52,10 +52,7 @@ public: // Block until the IPC channel for our subprocess is initialized, // but no longer. The child process may or may not have been // created when this method returns. - bool AsyncLaunch(StringVector aExtraOpts=StringVector(), - base::ProcessArchitecture arch=base::GetCurrentProcessArchitecture()); - - virtual bool WaitUntilConnected(int32_t aTimeoutMs = 0); + bool AsyncLaunch(StringVector aExtraOpts=StringVector()); // Block until the IPC channel for our subprocess is initialized and // the OS process is created. The subprocess may or may not have diff --git a/ipc/glue/MessageChannel.cpp b/ipc/glue/MessageChannel.cpp index 93ff5553ff53..96c9187dc2c1 100644 --- a/ipc/glue/MessageChannel.cpp +++ b/ipc/glue/MessageChannel.cpp @@ -298,7 +298,6 @@ MessageChannel::MessageChannel(MessageListener *aListener) mRecvdErrors(0), mRemoteStackDepthGuess(false), mSawInterruptOutMsg(false), - mIsWaitingForIncoming(false), mAbortOnError(false), mBlockScripts(false), mFlags(REQUIRE_DEFAULT), @@ -665,8 +664,7 @@ MessageChannel::OnMessageReceivedFromLink(const Message& aMsg) } bool shouldWakeUp = AwaitingInterruptReply() || - (AwaitingSyncReply() && !ShouldDeferMessage(aMsg)) || - AwaitingIncomingMessage(); + (AwaitingSyncReply() && !ShouldDeferMessage(aMsg)); // There are three cases we're concerned about, relating to the state of the // main thread: @@ -989,35 +987,6 @@ MessageChannel::Call(Message* aMsg, Message* aReply) return true; } -bool -MessageChannel::WaitForIncomingMessage() -{ -#ifdef OS_WIN - SyncStackFrame frame(this, true); -#endif - - { // Scope for lock - MonitorAutoLock lock(*mMonitor); - AutoEnterWaitForIncoming waitingForIncoming(*this); - if (mChannelState != ChannelConnected) { - return false; - } - if (!HasPendingEvents()) { - return WaitForInterruptNotify(); - } - } - - return OnMaybeDequeueOne(); -} - -bool -MessageChannel::HasPendingEvents() -{ - AssertWorkerThread(); - mMonitor->AssertCurrentThreadOwns(); - return Connected() && !mPending.empty(); -} - bool MessageChannel::InterruptEventOccurred() { @@ -1577,7 +1546,7 @@ MessageChannel::OnChannelErrorFromLink() if (InterruptStackDepth() > 0) NotifyWorkerThread(); - if (AwaitingSyncReply() || AwaitingIncomingMessage()) + if (AwaitingSyncReply()) NotifyWorkerThread(); if (ChannelClosing != mChannelState) { diff --git a/ipc/glue/MessageChannel.h b/ipc/glue/MessageChannel.h index 894f075696a6..3c7def888cfb 100644 --- a/ipc/glue/MessageChannel.h +++ b/ipc/glue/MessageChannel.h @@ -124,9 +124,6 @@ class MessageChannel : HasResultCodes // Make an Interrupt call to the other side of the channel bool Call(Message* aMsg, Message* aReply); - // Wait until a message is received - bool WaitForIncomingMessage(); - bool CanSend() const; void SetReplyTimeoutMs(int32_t aTimeoutMs); @@ -217,7 +214,6 @@ class MessageChannel : HasResultCodes void DispatchOnChannelConnected(); bool InterruptEventOccurred(); - bool HasPendingEvents(); bool ProcessPendingRequest(const Message &aUrgent); @@ -323,30 +319,6 @@ class MessageChannel : HasResultCodes mMonitor->AssertCurrentThreadOwns(); return !mInterruptStack.empty(); } - bool AwaitingIncomingMessage() const { - mMonitor->AssertCurrentThreadOwns(); - return mIsWaitingForIncoming; - } - - class MOZ_STACK_CLASS AutoEnterWaitForIncoming - { - public: - explicit AutoEnterWaitForIncoming(MessageChannel& aChannel) - : mChannel(aChannel) - { - aChannel.mMonitor->AssertCurrentThreadOwns(); - aChannel.mIsWaitingForIncoming = true; - } - - ~AutoEnterWaitForIncoming() - { - mChannel.mIsWaitingForIncoming = false; - } - - private: - MessageChannel& mChannel; - }; - friend class AutoEnterWaitForIncoming; // Returns true if we're dispatching a sync message's callback. bool DispatchingSyncMessage() const { @@ -667,11 +639,6 @@ class MessageChannel : HasResultCodes // ExitedCxxStack(), from which this variable is reset. bool mSawInterruptOutMsg; - // Are we waiting on this channel for an incoming message? This is used - // to implement WaitForIncomingMessage(). Must only be accessed while owning - // mMonitor. - bool mIsWaitingForIncoming; - // Map of replies received "out of turn", because of Interrupt // in-calls racing with replies to outstanding in-calls. See // https://bugzilla.mozilla.org/show_bug.cgi?id=521929. diff --git a/ipc/glue/WindowsMessageLoop.cpp b/ipc/glue/WindowsMessageLoop.cpp index 59473c8a9800..8cda66fc8368 100644 --- a/ipc/glue/WindowsMessageLoop.cpp +++ b/ipc/glue/WindowsMessageLoop.cpp @@ -966,7 +966,7 @@ MessageChannel::WaitForInterruptNotify() return WaitForSyncNotify(); } - if (!InterruptStackDepth() && !AwaitingIncomingMessage()) { + if (!InterruptStackDepth()) { // There is currently no way to recover from this condition. NS_RUNTIMEABORT("StackDepth() is 0 in call to MessageChannel::WaitForNotify!"); } diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 238dbf917388..9d4ed667fff2 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -2369,8 +2369,6 @@ pref("dom.ipc.plugins.reportCrashURL", true); // Defaults to 30 seconds. pref("dom.ipc.plugins.unloadTimeoutSecs", 30); -pref("dom.ipc.plugins.asyncInit", false); - pref("dom.ipc.processCount", 1); // Enable caching of Moz2D Path objects for SVG geometry elements diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/telemetry/Histograms.json index fde9f213b3f0..3d38b7075ba8 100644 --- a/toolkit/components/telemetry/Histograms.json +++ b/toolkit/components/telemetry/Histograms.json @@ -7029,15 +7029,6 @@ "keyed": true, "description": "Time (ms) that the main thread has been blocked on NPP_NewStream in an IPC plugin" }, - "BLOCKED_ON_PLUGINASYNCSURROGATE_WAITFORINIT_MS": { - "expires_in_version": "40", - "kind": "exponential", - "high": "10000", - "n_buckets": 20, - "extended_statistics_ok": true, - "keyed": true, - "description": "Time (ms) that the main thread has been blocked on PluginAsyncSurrogate::WaitForInit in an IPC plugin" - }, "BLOCKED_ON_PLUGIN_INSTANCE_DESTROY_MS": { "expires_in_version": "40", "kind": "exponential", diff --git a/xpcom/base/ErrorList.h b/xpcom/base/ErrorList.h index 9f5e9354d622..334fa468d961 100644 --- a/xpcom/base/ErrorList.h +++ b/xpcom/base/ErrorList.h @@ -330,7 +330,6 @@ ERROR(NS_ERROR_PLUGIN_BLOCKLISTED, FAILURE(1002)), ERROR(NS_ERROR_PLUGIN_TIME_RANGE_NOT_SUPPORTED, FAILURE(1003)), ERROR(NS_ERROR_PLUGIN_CLICKTOPLAY, FAILURE(1004)), - ERROR(NS_PLUGIN_INIT_PENDING, SUCCESS(1005)), #undef MODULE