--- a/dom/plugins/base/nsNPAPIPluginInstance.h
+++ b/dom/plugins/base/nsNPAPIPluginInstance.h
@@ -26,16 +26,17 @@
#include "AndroidBridge.h"
#include <map>
class PluginEventRunnable;
class SharedPluginTexture;
#endif
#include "mozilla/TimeStamp.h"
#include "mozilla/PluginLibrary.h"
+#include "mozilla/WeakPtr.h"
class nsPluginStreamListenerPeer; // browser-initiated stream class
class nsNPAPIPluginStreamListener; // plugin-initiated stream class
class nsIPluginInstanceOwner;
class nsIOutputStream;
class nsPluginInstanceOwner;
#if defined(OS_WIN)
@@ -71,21 +72,23 @@ public:
uint32_t id;
nsCOMPtr<nsITimer> timer;
void (*callback)(NPP npp, uint32_t timerID);
bool inCallback;
bool needUnschedule;
};
class nsNPAPIPluginInstance final : public nsIAudioChannelAgentCallback
+ , public mozilla::SupportsWeakPtr<nsNPAPIPluginInstance>
{
private:
typedef mozilla::PluginLibrary PluginLibrary;
public:
+ MOZ_DECLARE_WEAKREFERENCE_TYPENAME(nsNPAPIPluginInstance)
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIAUDIOCHANNELAGENTCALLBACK
nsresult Initialize(nsNPAPIPlugin *aPlugin, nsPluginInstanceOwner* aOwner, const nsACString& aMIMEType);
nsresult Start();
nsresult Stop();
nsresult SetWindow(NPWindow* window);
nsresult NewStreamFromPlugin(const char* type, const char* target, nsIOutputStream* *result);
--- a/dom/plugins/ipc/PluginAsyncSurrogate.cpp
+++ b/dom/plugins/ipc/PluginAsyncSurrogate.cpp
@@ -96,17 +96,16 @@ 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)
, mDestroyPending(false)
, mAsyncCallsInFlight(0)
@@ -118,17 +117,20 @@ PluginAsyncSurrogate::~PluginAsyncSurrog
{
}
bool
PluginAsyncSurrogate::Init(NPMIMEType aPluginType, NPP aInstance, uint16_t aMode,
int16_t aArgc, char* aArgn[], char* aArgv[])
{
mMimeType = aPluginType;
- mInstance = aInstance;
+ nsNPAPIPluginInstance* instance =
+ static_cast<nsNPAPIPluginInstance*>(aInstance->ndata);
+ MOZ_ASSERT(instance);
+ mInstance = instance;
mMode = aMode;
for (int i = 0; i < aArgc; ++i) {
mNames.AppendElement(NullableString(aArgn[i]));
mValues.AppendElement(NullableString(aArgv[i]));
}
return true;
}
@@ -157,17 +159,21 @@ PluginAsyncSurrogate::Cast(NPP aInstance
return nullptr;
}
return resolver->GetAsyncSurrogate();
}
nsresult
PluginAsyncSurrogate::NPP_New(NPError* aError)
{
- nsresult rv = mParent->NPP_NewInternal(mMimeType.BeginWriting(), mInstance,
+ if (!mInstance) {
+ return NS_ERROR_NULL_POINTER;
+ }
+
+ nsresult rv = mParent->NPP_NewInternal(mMimeType.BeginWriting(), GetNPP(),
mMode, mNames, mValues, nullptr,
aError);
if (NS_FAILED(rv)) {
return rv;
}
return NS_OK;
}
@@ -194,61 +200,72 @@ PluginAsyncSurrogate::NotifyDestroyPendi
{
PluginAsyncSurrogate* surrogate = Cast(aInstance);
if (!surrogate) {
return;
}
surrogate->NotifyDestroyPending();
}
+NPP
+PluginAsyncSurrogate::GetNPP()
+{
+ MOZ_ASSERT(mInstance);
+ NPP npp;
+ DebugOnly<nsresult> rv = mInstance->GetNPP(&npp);
+ MOZ_ASSERT(NS_SUCCEEDED(rv));
+ return npp;
+}
+
void
PluginAsyncSurrogate::NotifyDestroyPending()
{
mDestroyPending = true;
- nsJSNPRuntime::OnPluginDestroyPending(mInstance);
+ nsJSNPRuntime::OnPluginDestroyPending(GetNPP());
}
NPError
PluginAsyncSurrogate::NPP_Destroy(NPSavedData** aSave)
{
NotifyDestroyPending();
if (!WaitForInit()) {
return NPERR_GENERIC_ERROR;
}
- return PluginModuleParent::NPP_Destroy(mInstance, aSave);
+ return PluginModuleParent::NPP_Destroy(GetNPP(), aSave);
}
NPError
PluginAsyncSurrogate::NPP_GetValue(NPPVariable aVariable, void* aRetval)
{
if (aVariable != NPPVpluginScriptableNPObject) {
if (!WaitForInit()) {
return NPERR_GENERIC_ERROR;
}
- PluginInstanceParent* instance = PluginInstanceParent::Cast(mInstance);
+
+ PluginInstanceParent* instance = PluginInstanceParent::Cast(GetNPP());
MOZ_ASSERT(instance);
return instance->NPP_GetValue(aVariable, aRetval);
}
- NPObject* npobject = parent::_createobject(mInstance,
+ NPObject* npobject = parent::_createobject(GetNPP(),
const_cast<NPClass*>(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);
+ return PluginModuleParent::NPP_SetValue(GetNPP(), aVariable, aValue);
}
NPError
PluginAsyncSurrogate::NPP_NewStream(NPMIMEType aType, NPStream* aStream,
NPBool aSeekable, uint16_t* aStype)
{
mPendingNewStreamCalls.AppendElement(PendingNewStreamCall(aType, aStream,
aSeekable));
@@ -424,17 +441,20 @@ void
PluginAsyncSurrogate::DestroyAsyncStream(NPStream* aStream)
{
MOZ_ASSERT(aStream);
nsNPAPIPluginStreamListener* streamListener = GetStreamListener(aStream);
MOZ_ASSERT(streamListener);
// streamListener was suspended during async init. We must resume the stream
// request prior to calling _destroystream for cleanup to work correctly.
streamListener->ResumeRequest();
- parent::_destroystream(mInstance, aStream, NPRES_DONE);
+ if (!mInstance) {
+ return;
+ }
+ parent::_destroystream(GetNPP(), aStream, NPRES_DONE);
}
/* static */ bool
PluginAsyncSurrogate::SetStreamType(NPStream* aStream, uint16_t aStreamType)
{
nsNPAPIPluginStreamListener* streamListener = GetStreamListener(aStream);
if (!streamListener) {
return false;
@@ -564,22 +584,20 @@ PluginAsyncSurrogate::NotifyAsyncInitFai
}
}
mPendingNewStreamCalls.Clear();
// Make sure that any WaitForInit calls on this surrogate will fail, or else
// we'll be perma-blocked
mInitCancelled = true;
- nsNPAPIPluginInstance* inst =
- static_cast<nsNPAPIPluginInstance*>(mInstance->ndata);
- if (!inst) {
+ if (!mInstance) {
return;
}
- nsPluginInstanceOwner* owner = inst->GetOwner();
+ nsPluginInstanceOwner* owner = mInstance->GetOwner();
if (owner) {
owner->NotifyHostAsyncInitFailed();
}
}
// static
NPObject*
PluginAsyncSurrogate::ScriptableAllocate(NPP aInstance, NPClass* aClass)
@@ -658,21 +676,21 @@ PluginAsyncSurrogate::ScriptableHasMetho
}
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,
+ NPError nperror = npn->getvalue(object->mSurrogate->GetNPP(),
NPNVPluginElementNPObject,
(void*)&pluginObject);
if (nperror == NPERR_NO_ERROR) {
- NPPAutoPusher nppPusher(object->mSurrogate->mInstance);
+ NPPAutoPusher nppPusher(object->mSurrogate->GetNPP());
result = pluginObject->_class->hasMethod(pluginObject, aName);
npn->releaseobject(pluginObject);
NPUTF8* idstr = npn->utf8fromidentifier(aName);
npn->memfree(idstr);
}
}
return result;
}
@@ -711,20 +729,20 @@ PluginAsyncSurrogate::GetPropertyHelper(
static_cast<ParentNPObject*>(realObject)->parent;
if (!actor) {
return false;
}
bool success = actor->GetPropertyHelper(aName, aHasProperty, aHasMethod, aResult);
if (!success) {
const NPNetscapeFuncs* npn = mParent->GetNetscapeFuncs();
NPObject* pluginObject = nullptr;
- NPError nperror = npn->getvalue(mInstance, NPNVPluginElementNPObject,
+ NPError nperror = npn->getvalue(GetNPP(), NPNVPluginElementNPObject,
(void*)&pluginObject);
if (nperror == NPERR_NO_ERROR) {
- NPPAutoPusher nppPusher(mInstance);
+ NPPAutoPusher nppPusher(GetNPP());
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);
@@ -819,21 +837,21 @@ PluginAsyncSurrogate::ScriptableHasPrope
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,
+ NPError nperror = npn->getvalue(object->mSurrogate->GetNPP(),
NPNVPluginElementNPObject,
(void*)&pluginObject);
if (nperror == NPERR_NO_ERROR) {
- NPPAutoPusher nppPusher(object->mSurrogate->mInstance);
+ NPPAutoPusher nppPusher(object->mSurrogate->GetNPP());
result = nsJSObjWrapper::HasOwnProperty(pluginObject, aName);
npn->releaseobject(pluginObject);
idstr = npn->utf8fromidentifier(aName);
npn->memfree(idstr);
}
}
return result;
}