Add support for NPIdentifiers to oop plugins

This commit is contained in:
Ben Turner 2009-09-14 13:01:31 -07:00
Родитель 99033ae764
Коммит af82cf26df
4 изменённых файлов: 195 добавлений и 201 удалений

Просмотреть файл

@ -83,9 +83,8 @@ parent:
sync NPN_IdentifierIsString(NPRemoteIdentifier aId)
returns (bool aIsString);
sync NPN_GetStringIdentifiers()
returns (nsTArray<nsCString> aNames,
nsTArray<NPRemoteIdentifier> aIds);
sync NPN_GetStringIdentifiers(nsTArray<nsCString> aNames)
returns (nsTArray<NPRemoteIdentifier> aIds);
};
} // namespace plugins

Просмотреть файл

@ -43,7 +43,6 @@
#include <gtk/gtk.h>
#endif
#include "nsIFile.h"
#include "nsILocalFile.h"
#include "nsDebug.h"
@ -52,9 +51,13 @@
#include "mozilla/plugins/PluginInstanceChild.h"
namespace mozilla {
namespace plugins {
using mozilla::ipc::NPRemoteIdentifier;
using namespace mozilla::plugins;
namespace {
PluginModuleChild* gInstance = nsnull;
}
PluginModuleChild::PluginModuleChild() :
mLibrary(0),
@ -65,15 +68,19 @@ PluginModuleChild::PluginModuleChild() :
#endif
// ,mNextInstanceId(0)
{
NS_ASSERTION(!gInstance, "Bad news bears!");
memset(&mFunctions, 0, sizeof(mFunctions));
memset(&mSavedData, 0, sizeof(mSavedData));
gInstance = this;
}
PluginModuleChild::~PluginModuleChild()
{
NS_ASSERTION(gInstance == this, "Bad news bears!");
if (mLibrary) {
PR_UnloadLibrary(mLibrary);
}
gInstance = nsnull;
}
bool
@ -598,7 +605,15 @@ NPIdentifier NP_CALLBACK
_getstringidentifier(const NPUTF8* aName)
{
_MOZ_LOG(__FUNCTION__);
return 0;
NS_ASSERTION(gInstance, "No instance!");
NPRemoteIdentifier ident;
nsresult rv =
gInstance->SendNPN_GetStringIdentifier(nsDependentCString(aName),
&ident);
NS_ENSURE_SUCCESS(rv, 0);
return (NPIdentifier)ident;
}
void NP_CALLBACK
@ -607,34 +622,99 @@ _getstringidentifiers(const NPUTF8** aNames,
NPIdentifier* aIdentifiers)
{
_MOZ_LOG(__FUNCTION__);
NS_ASSERTION(gInstance, "No instance!");
if (!(aNames && aNameCount > 0 && aIdentifiers)) {
NS_RUNTIMEABORT("Bad input! Headed for a crash!");
}
nsAutoTArray<nsCString, 10> names;
nsAutoTArray<NPRemoteIdentifier, 10> ids;
PRBool ok = names.SetCapacity(aNameCount);
NS_WARN_IF_FALSE(ok, "Out of memory!");
if (ok) {
for (int32_t index = 0; index < aNameCount; index++) {
names.AppendElement(nsDependentCString(aNames[index]));
}
NS_ASSERTION(names.Length() == aNameCount, "Should equal here!");
nsresult rv = gInstance->SendNPN_GetStringIdentifiers(names, &ids);
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Failed to send message!");
if (NS_SUCCEEDED(rv)) {
NS_ASSERTION(ids.Length() == aNameCount, "Bad length!");
for (int32_t index = 0; index < aNameCount; index++) {
aIdentifiers[index] = (NPIdentifier)ids[index];
}
return;
}
}
// Something must have failed above.
for (int32_t index = 0; index < aNameCount; index++) {
aIdentifiers[index] = 0;
}
}
bool NP_CALLBACK
_identifierisstring(NPIdentifier aIdentifier)
{
_MOZ_LOG(__FUNCTION__);
return false;
NS_ASSERTION(gInstance, "No instance!");
bool isString;
nsresult rv =
gInstance->SendNPN_IdentifierIsString((NPRemoteIdentifier)aIdentifier,
&isString);
NS_ENSURE_SUCCESS(rv, false);
return isString;
}
NPIdentifier NP_CALLBACK
_getintidentifier(int32_t aIntId)
{
_MOZ_LOG(__FUNCTION__);
return 0;
NS_ASSERTION(gInstance, "No instance!");
NPRemoteIdentifier ident;
nsresult rv = gInstance->SendNPN_GetIntIdentifier(aIntId, &ident);
NS_ENSURE_SUCCESS(rv, 0);
return (NPIdentifier)ident;
}
NPUTF8* NP_CALLBACK
_utf8fromidentifier(NPIdentifier aIdentifier)
{
_MOZ_LOG(__FUNCTION__);
return 0;
NS_ASSERTION(gInstance, "No instance!");
nsCAutoString val;
nsresult rv =
gInstance->SendNPN_UTF8FromIdentifier((NPRemoteIdentifier)aIdentifier,
&val);
NS_ENSURE_SUCCESS(rv, 0);
return val.IsVoid() ? 0 : strdup(val.get());
}
int32_t NP_CALLBACK
_intfromidentifier(NPIdentifier aIdentifier)
{
_MOZ_LOG(__FUNCTION__);
return 0;
NS_ASSERTION(gInstance, "No instance!");
int32_t val;
nsresult rv =
gInstance->SendNPN_IntFromIdentifier((NPRemoteIdentifier)aIdentifier,
&val);
NS_ENSURE_SUCCESS(rv, 0);
return val;
}
NPObject* NP_CALLBACK
@ -978,7 +1058,3 @@ PluginModuleChild::PPluginInstanceDestructor(PPluginInstanceChild* actor,
return NS_OK;
}
} // namespace plugins
} // namespace mozilla

Просмотреть файл

@ -39,10 +39,15 @@
#include "mozilla/plugins/PluginModuleParent.h"
#include "mozilla/plugins/BrowserStreamParent.h"
#include "nsNPAPIPlugin.h"
using mozilla::SharedLibrary;
namespace mozilla {
namespace plugins {
using mozilla::ipc::NPRemoteIdentifier;
using namespace mozilla::plugins;
PR_STATIC_ASSERT(sizeof(NPIdentifier) == sizeof(void*));
// HACKS
PluginModuleParent* PluginModuleParent::Shim::HACK_target;
@ -67,6 +72,11 @@ PluginModuleParent::PluginModuleParent(const char* aFilePath) :
mSubprocess(aFilePath),
ALLOW_THIS_IN_INITIALIZER_LIST(mShim(new Shim(this)))
{
#ifdef DEBUG
PRBool ok =
#endif
mValidIdentifiers.Init();
NS_ASSERTION(ok, "Out of memory!");
}
PluginModuleParent::~PluginModuleParent()
@ -230,10 +240,15 @@ PluginModuleParent::NPP_Destroy(NPP instance,
return prv;
}
NPError
PluginModuleParent::NPP_SetWindow(NPP instance, NPWindow* window)
NPIdentifier
PluginModuleParent::GetValidNPIdentifier(NPRemoteIdentifier aRemoteIdentifier)
{
return InstCast(instance)->NPP_SetWindow(window);
NS_ASSERTION(mValidIdentifiers.IsInitialized(), "Not initialized!");
if (aRemoteIdentifier &&
mValidIdentifiers.GetEntry((NPIdentifier)aRemoteIdentifier)) {
return (NPIdentifier)aRemoteIdentifier;
}
return 0;
}
NPError
@ -245,6 +260,12 @@ PluginModuleParent::NPP_NewStream(NPP instance, NPMIMEType type,
stype);
}
NPError
PluginModuleParent::NPP_SetWindow(NPP instance, NPWindow* window)
{
return InstCast(instance)->NPP_SetWindow(window);
}
NPError
PluginModuleParent::NPP_DestroyStream(NPP instance,
NPStream* stream,
@ -315,42 +336,108 @@ nsresult
PluginModuleParent::RecvNPN_GetStringIdentifier(const nsCString& aString,
NPRemoteIdentifier* aId)
{
return NS_ERROR_NOT_IMPLEMENTED;
NS_ENSURE_ARG(!aString.IsVoid());
NPIdentifier ident = _getstringidentifier(aString.BeginReading());
NS_ENSURE_STATE(ident);
nsVoidPtrHashKey* newEntry = mValidIdentifiers.PutEntry(ident);
NS_ENSURE_TRUE(newEntry, NS_ERROR_OUT_OF_MEMORY);
*aId = (NPRemoteIdentifier)ident;
return NS_OK;
}
nsresult
PluginModuleParent::RecvNPN_GetIntIdentifier(const int32_t& aInt,
NPRemoteIdentifier* aId)
{
return NS_ERROR_NOT_IMPLEMENTED;
NPIdentifier ident = _getintidentifier(aInt);
NS_ENSURE_STATE(ident);
nsVoidPtrHashKey* newEntry = mValidIdentifiers.PutEntry(ident);
NS_ENSURE_TRUE(newEntry, NS_ERROR_OUT_OF_MEMORY);
*aId = (NPRemoteIdentifier)ident;
return NS_OK;
}
nsresult
PluginModuleParent::RecvNPN_UTF8FromIdentifier(const NPRemoteIdentifier& aId,
nsCString* aString)
{
return NS_ERROR_NOT_IMPLEMENTED;
NPIdentifier ident = GetValidNPIdentifier(aId);
NS_ENSURE_ARG(ident);
NPUTF8* val = _utf8fromidentifier(ident);
NS_ENSURE_STATE(val);
aString->Assign(val);
return NS_OK;
}
nsresult
PluginModuleParent::RecvNPN_IntFromIdentifier(const NPRemoteIdentifier& aId,
int32_t* aInt)
{
return NS_ERROR_NOT_IMPLEMENTED;
NPIdentifier ident = GetValidNPIdentifier(aId);
NS_ENSURE_ARG(ident);
*aInt = _intfromidentifier(ident);
return NS_OK;
}
nsresult
PluginModuleParent::RecvNPN_IdentifierIsString(const NPRemoteIdentifier& aId,
bool* aIsString)
{
return NS_ERROR_NOT_IMPLEMENTED;
NPIdentifier ident = GetValidNPIdentifier(aId);
NS_ENSURE_ARG(ident);
*aIsString = _identifierisstring(ident);
return NS_OK;
}
nsresult
PluginModuleParent::RecvNPN_GetStringIdentifiers(nsTArray<nsCString>* aNames,
PluginModuleParent::RecvNPN_GetStringIdentifiers(const nsTArray<nsCString>& aNames,
nsTArray<NPRemoteIdentifier>* aIds)
{
return NS_ERROR_NOT_IMPLEMENTED;
NS_ASSERTION(aIds->IsEmpty(), "Non-empty array!");
PRUint32 count = aNames.Length();
NS_ENSURE_ARG_MIN(count, 1);
nsAutoTArray<NPUTF8*, 10> buffers;
PRBool ok = buffers.SetLength(count);
NS_ENSURE_TRUE(ok, NS_ERROR_OUT_OF_MEMORY);
nsAutoTArray<NPIdentifier, 10> ids;
ok = ids.SetLength(count);
NS_ENSURE_TRUE(ok, NS_ERROR_OUT_OF_MEMORY);
ok = aIds->SetCapacity(count);
NS_ENSURE_TRUE(ok, NS_ERROR_OUT_OF_MEMORY);
for (PRUint32 index = 0; index < count; index++) {
buffers[index] = const_cast<NPUTF8*>(aNames[index].BeginReading());
NS_ASSERTION(buffers[index], "Null pointer should be impossible!");
}
_getstringidentifiers(const_cast<const NPUTF8**>(buffers.Elements()),
count, ids.Elements());
for (PRUint32 index = 0; index < count; index++) {
NPIdentifier& id = ids[index];
if (id) {
nsVoidPtrHashKey* newEntry = mValidIdentifiers.PutEntry(id);
NS_ENSURE_TRUE(ok, NS_ERROR_OUT_OF_MEMORY);
}
aIds->AppendElement((NPRemoteIdentifier)id);
}
return NS_OK;
}
PluginInstanceParent*
@ -377,5 +464,3 @@ PluginModuleParent::StreamCast(NPP instance,
return sp;
}
} // namespace plugins
} // namespace mozilla

Просмотреть файл

@ -57,6 +57,8 @@
#include "mozilla/plugins/PluginProcessParent.h"
#include "nsAutoPtr.h"
#include "nsTHashtable.h"
#include "nsHashKeys.h"
#undef _MOZ_LOG
#define _MOZ_LOG(s) printf("[PluginModuleParent] %s\n", s)
@ -125,7 +127,7 @@ public:
RecvNPN_IdentifierIsString(const NPRemoteIdentifier& aId,
bool* aIsString);
virtual nsresult
RecvNPN_GetStringIdentifiers(nsTArray<nsCString>* aNames,
RecvNPN_GetStringIdentifiers(const nsTArray<nsCString>& aNames,
nsTArray<NPRemoteIdentifier>* aIds);
private:
@ -202,170 +204,8 @@ private:
static NPError NPP_SetValue(NPP instance, NPNVariable variable,
void *value);
#if 0
// NPN-like API that IPC messages from the child process end up
// calling into. We make the "real" calls back into Gecko from
// here, then wrap up the responses and send them back to the
// child process.
NPIdentifier
NPN_GetIntIdentifier(int32_t aInt)
{
return mNPNIface->getintidentifier(aInt);
}
NPIdentifier
NPN_GetStringIdentifier(const NPUTF8* aName)
{
return mNPNIface->getstringidentifier(aName);
}
void
NPN_GetStringIdentifiers(const NPUTF8** aNames,
int32_t aNamesCount,
NPIdentifier* aIdentifiers)
{
return mNPNIface->getstringidentifiers(aNames,
aNamesCount,
aIdentifiers);
}
NPUTF8*
NPN_UTF8FromIdentifier(NPIdentifier aIdentifier)
{
return mNPNIface->utf8fromidentifier(aIdentifier);
}
int32_t
NPN_IntFromIdentifier(NPIdentifier aIdentifier)
{
return mNPNIface->intfromidentifier(aIdentifier);
}
// NPRuntime bindings from Gecko->child and child->Gecko.
static base::hash_map<int, PluginNPObject*> sNPObjects;
static int sNextNPObjectId = 0;
static NPObject*
ScriptableAllocate(NPP aNPP,
NPClass* aClass)
{
PluginNPObject* obj = (PluginNPObject*)NPN_MemAlloc(sizeof(PluginNPObject));
if (obj) {
obj->objectId = sNextNPObjectId++;
obj->classId = -1;
}
sNPObjects[obj->objectId] = obj;
return obj;
}
static void
ScriptableDeallocate(NPObject* aNPObj)
{
PluginNPObject* obj = static_cast<PluginNPObject*>(aNPObj);
base::hash_map<int, PluginNPObject*>::iterator iter =
sNPObjects.find(obj->objectId);
if (iter != sNPObjects.end()) {
sNPObjects.erase(iter);
}
NPN_MemFree(obj);
}
static void
ScriptableInvalidate(NPObject* aNPObj)
{
}
static bool
ScriptableHasMethod(NPObject* aNPObj,
NPIdentifier aName)
{
return false;
}
static bool
ScriptableInvoke(NPObject* aNPObj,
NPIdentifier aName,
const NPVariant* aArgs,
uint32_t aArgsCount,
NPVariant* aResult)
{
return false;
}
static bool
ScriptableInvokeDefault(NPObject* aNPObj,
const NPVariant* aArgs,
uint32_t aArgsCount,
NPVariant* aResult)
{
return false;
}
static bool
ScriptableHasProperty(NPObject* aNPObj,
NPIdentifier aName)
{
return false;
}
static bool
ScriptableGetProperty(NPObject* aNPObj,
NPIdentifier aName,
NPVariant* aResult)
{
return false;
}
static bool
ScriptableSetProperty(NPObject* aNPObj,
NPIdentifier aName,
const NPVariant* aValue)
{
return false;
}
static bool
ScriptableRemoveProperty(NPObject* aNPObj,
NPIdentifier aName)
{
return false;
}
static bool
ScriptableEnumerate(NPObject* aNPObj,
NPIdentifier** aIdentifier,
uint32_t* aCount)
{
return false;
}
static bool
ScriptableConstruct(NPObject* aNPObj,
const NPVariant* aArgs,
uint32_t aArgsCount,
NPVariant* aResult)
{
return false;
}
static NPClass sNPClass = {
NP_CLASS_STRUCT_VERSION,
ScriptableAllocate,
ScriptableDeallocate,
ScriptableInvalidate,
ScriptableHasMethod,
ScriptableInvoke,
ScriptableInvokeDefault,
ScriptableHasProperty,
ScriptableGetProperty,
ScriptableSetProperty,
ScriptableRemoveProperty,
ScriptableEnumerate,
ScriptableConstruct
};
#endif
NPIdentifier GetValidNPIdentifier(NPRemoteIdentifier aRemoteIdentifier);
private:
const char* mFilePath;
@ -374,14 +214,6 @@ private:
// NPObject interface
#if 0
struct PluginNPObject : NPObject
{
int objectId;
int classId;
};
#endif
/**
* I look like a shared library, but return functions that trampoline
* into my parent class.
@ -514,6 +346,8 @@ private:
friend class Shim;
Shim* mShim;
nsTHashtable<nsVoidPtrHashKey> mValidIdentifiers;
};
} // namespace plugins