зеркало из https://github.com/mozilla/gecko-dev.git
Implement CPOW support in MessageManager (bug 870180, r=smaug,billm).
This commit is contained in:
Родитель
614d2bf88c
Коммит
5f0258f3c3
|
@ -162,9 +162,8 @@ interface nsIMessageListener : nsISupports
|
||||||
* sync: %true or false%.
|
* sync: %true or false%.
|
||||||
* data: %structured clone of the sent message data%,
|
* data: %structured clone of the sent message data%,
|
||||||
* json: %same as .data, deprecated%,
|
* json: %same as .data, deprecated%,
|
||||||
* objects: %array of handles or null, always null if sync is false%
|
* objects: %named table of jsvals/objects, or null%
|
||||||
* }
|
* }
|
||||||
* @note objects property isn't implemented yet.
|
|
||||||
*
|
*
|
||||||
* Each listener is invoked with its own copy of the message
|
* Each listener is invoked with its own copy of the message
|
||||||
* parameter.
|
* parameter.
|
||||||
|
@ -232,7 +231,8 @@ interface nsIMessageSender : nsIMessageListenerManager
|
||||||
*/
|
*/
|
||||||
[implicit_jscontext, optional_argc]
|
[implicit_jscontext, optional_argc]
|
||||||
void sendAsyncMessage([optional] in AString messageName,
|
void sendAsyncMessage([optional] in AString messageName,
|
||||||
[optional] in jsval obj);
|
[optional] in jsval obj,
|
||||||
|
[optional] in jsval objects);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -255,7 +255,8 @@ interface nsIMessageBroadcaster : nsIMessageListenerManager
|
||||||
*/
|
*/
|
||||||
[implicit_jscontext, optional_argc]
|
[implicit_jscontext, optional_argc]
|
||||||
void broadcastAsyncMessage([optional] in AString messageName,
|
void broadcastAsyncMessage([optional] in AString messageName,
|
||||||
[optional] in jsval obj);
|
[optional] in jsval obj,
|
||||||
|
[optional] in jsval objects);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of subordinate message managers.
|
* Number of subordinate message managers.
|
||||||
|
@ -278,7 +279,8 @@ interface nsISyncMessageSender : nsIMessageSender
|
||||||
*/
|
*/
|
||||||
[implicit_jscontext, optional_argc]
|
[implicit_jscontext, optional_argc]
|
||||||
jsval sendSyncMessage([optional] in AString messageName,
|
jsval sendSyncMessage([optional] in AString messageName,
|
||||||
[optional] in jsval obj);
|
[optional] in jsval obj,
|
||||||
|
[optional] in jsval objects);
|
||||||
};
|
};
|
||||||
|
|
||||||
[scriptable, builtinclass, uuid(894ff2d4-39a3-4df8-9d76-8ee329975488)]
|
[scriptable, builtinclass, uuid(894ff2d4-39a3-4df8-9d76-8ee329975488)]
|
||||||
|
|
|
@ -50,6 +50,7 @@ LOCAL_INCLUDES += \
|
||||||
-I$(topsrcdir)/content/xul/document/src \
|
-I$(topsrcdir)/content/xul/document/src \
|
||||||
-I$(topsrcdir)/dom/base \
|
-I$(topsrcdir)/dom/base \
|
||||||
-I$(topsrcdir)/dom/ipc \
|
-I$(topsrcdir)/dom/ipc \
|
||||||
|
-I$(topsrcdir)/js/ipc \
|
||||||
-I$(topsrcdir)/image/src \
|
-I$(topsrcdir)/image/src \
|
||||||
-I$(topsrcdir)/js/xpconnect/src \
|
-I$(topsrcdir)/js/xpconnect/src \
|
||||||
-I$(topsrcdir)/layout/base \
|
-I$(topsrcdir)/layout/base \
|
||||||
|
|
|
@ -87,6 +87,7 @@
|
||||||
#include "jsapi.h"
|
#include "jsapi.h"
|
||||||
#include "mozilla/dom/HTMLIFrameElement.h"
|
#include "mozilla/dom/HTMLIFrameElement.h"
|
||||||
#include "nsSandboxFlags.h"
|
#include "nsSandboxFlags.h"
|
||||||
|
#include "JavaScriptParent.h"
|
||||||
|
|
||||||
#include "mozilla/dom/StructuredCloneUtils.h"
|
#include "mozilla/dom/StructuredCloneUtils.h"
|
||||||
|
|
||||||
|
@ -2202,17 +2203,29 @@ nsFrameLoader::DoLoadFrameScript(const nsAString& aURL)
|
||||||
class nsAsyncMessageToChild : public nsRunnable
|
class nsAsyncMessageToChild : public nsRunnable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
nsAsyncMessageToChild(nsFrameLoader* aFrameLoader,
|
nsAsyncMessageToChild(JSContext* aCx,
|
||||||
|
nsFrameLoader* aFrameLoader,
|
||||||
const nsAString& aMessage,
|
const nsAString& aMessage,
|
||||||
const StructuredCloneData& aData)
|
const StructuredCloneData& aData,
|
||||||
: mFrameLoader(aFrameLoader), mMessage(aMessage)
|
JS::Handle<JSObject *> aCpows)
|
||||||
|
: mRuntime(js::GetRuntime(aCx)), mFrameLoader(aFrameLoader), mMessage(aMessage), mCpows(aCpows)
|
||||||
{
|
{
|
||||||
if (aData.mDataLength && !mData.copy(aData.mData, aData.mDataLength)) {
|
if (aData.mDataLength && !mData.copy(aData.mData, aData.mDataLength)) {
|
||||||
NS_RUNTIMEABORT("OOM");
|
NS_RUNTIMEABORT("OOM");
|
||||||
}
|
}
|
||||||
|
if (mCpows && !js_AddObjectRoot(mRuntime, &mCpows)) {
|
||||||
|
NS_RUNTIMEABORT("OOM");
|
||||||
|
}
|
||||||
mClosure = aData.mClosure;
|
mClosure = aData.mClosure;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~nsAsyncMessageToChild()
|
||||||
|
{
|
||||||
|
if (mCpows) {
|
||||||
|
JS_RemoveObjectRootRT(mRuntime, &mCpows);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHOD Run()
|
NS_IMETHOD Run()
|
||||||
{
|
{
|
||||||
nsInProcessTabChildGlobal* tabChild =
|
nsInProcessTabChildGlobal* tabChild =
|
||||||
|
@ -2224,21 +2237,27 @@ public:
|
||||||
data.mDataLength = mData.nbytes();
|
data.mDataLength = mData.nbytes();
|
||||||
data.mClosure = mClosure;
|
data.mClosure = mClosure;
|
||||||
|
|
||||||
|
SameProcessCpowHolder cpows(mRuntime, JS::Handle<JSObject *>::fromMarkedLocation(&mCpows));
|
||||||
|
|
||||||
nsRefPtr<nsFrameMessageManager> mm = tabChild->GetInnerManager();
|
nsRefPtr<nsFrameMessageManager> mm = tabChild->GetInnerManager();
|
||||||
mm->ReceiveMessage(static_cast<EventTarget*>(tabChild), mMessage,
|
mm->ReceiveMessage(static_cast<EventTarget*>(tabChild), mMessage,
|
||||||
false, &data, JS::NullPtr(), nullptr);
|
false, &data, &cpows, nullptr);
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
JSRuntime* mRuntime;
|
||||||
nsRefPtr<nsFrameLoader> mFrameLoader;
|
nsRefPtr<nsFrameLoader> mFrameLoader;
|
||||||
nsString mMessage;
|
nsString mMessage;
|
||||||
JSAutoStructuredCloneBuffer mData;
|
JSAutoStructuredCloneBuffer mData;
|
||||||
StructuredCloneClosure mClosure;
|
StructuredCloneClosure mClosure;
|
||||||
|
JSObject* mCpows;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool
|
bool
|
||||||
nsFrameLoader::DoSendAsyncMessage(const nsAString& aMessage,
|
nsFrameLoader::DoSendAsyncMessage(JSContext* aCx,
|
||||||
const StructuredCloneData& aData)
|
const nsAString& aMessage,
|
||||||
|
const StructuredCloneData& aData,
|
||||||
|
JS::Handle<JSObject *> aCpows)
|
||||||
{
|
{
|
||||||
TabParent* tabParent = mRemoteBrowser;
|
TabParent* tabParent = mRemoteBrowser;
|
||||||
if (tabParent) {
|
if (tabParent) {
|
||||||
|
@ -2247,11 +2266,15 @@ nsFrameLoader::DoSendAsyncMessage(const nsAString& aMessage,
|
||||||
if (!BuildClonedMessageDataForParent(cp, aData, data)) {
|
if (!BuildClonedMessageDataForParent(cp, aData, data)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return tabParent->SendAsyncMessage(nsString(aMessage), data);
|
InfallibleTArray<mozilla::jsipc::CpowEntry> cpows;
|
||||||
|
if (aCpows && !cp->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return tabParent->SendAsyncMessage(nsString(aMessage), data, cpows);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mChildMessageManager) {
|
if (mChildMessageManager) {
|
||||||
nsRefPtr<nsIRunnable> ev = new nsAsyncMessageToChild(this, aMessage, aData);
|
nsRefPtr<nsIRunnable> ev = new nsAsyncMessageToChild(aCx, this, aMessage, aData, aCpows);
|
||||||
NS_DispatchToCurrentThread(ev);
|
NS_DispatchToCurrentThread(ev);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -186,8 +186,10 @@ public:
|
||||||
* MessageManagerCallback methods that we override.
|
* MessageManagerCallback methods that we override.
|
||||||
*/
|
*/
|
||||||
virtual bool DoLoadFrameScript(const nsAString& aURL) MOZ_OVERRIDE;
|
virtual bool DoLoadFrameScript(const nsAString& aURL) MOZ_OVERRIDE;
|
||||||
virtual bool DoSendAsyncMessage(const nsAString& aMessage,
|
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||||
const mozilla::dom::StructuredCloneData& aData) MOZ_OVERRIDE;
|
const nsAString& aMessage,
|
||||||
|
const mozilla::dom::StructuredCloneData& aData,
|
||||||
|
JS::Handle<JSObject *> aCpows);
|
||||||
virtual bool CheckPermission(const nsAString& aPermission) MOZ_OVERRIDE;
|
virtual bool CheckPermission(const nsAString& aPermission) MOZ_OVERRIDE;
|
||||||
virtual bool CheckManifestURL(const nsAString& aManifestURL) MOZ_OVERRIDE;
|
virtual bool CheckManifestURL(const nsAString& aManifestURL) MOZ_OVERRIDE;
|
||||||
virtual bool CheckAppHasPermission(const nsAString& aPermission) MOZ_OVERRIDE;
|
virtual bool CheckAppHasPermission(const nsAString& aPermission) MOZ_OVERRIDE;
|
||||||
|
|
|
@ -31,6 +31,8 @@
|
||||||
#include "xpcpublic.h"
|
#include "xpcpublic.h"
|
||||||
#include "mozilla/Preferences.h"
|
#include "mozilla/Preferences.h"
|
||||||
#include "mozilla/dom/StructuredCloneUtils.h"
|
#include "mozilla/dom/StructuredCloneUtils.h"
|
||||||
|
#include "JavaScriptChild.h"
|
||||||
|
#include "JavaScriptParent.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#ifdef ANDROID
|
#ifdef ANDROID
|
||||||
|
@ -220,6 +222,18 @@ mozilla::dom::ipc::UnpackClonedMessageDataForChild(const ClonedMessageData& aDat
|
||||||
return UnpackClonedMessageData<Child>(aData);
|
return UnpackClonedMessageData<Child>(aData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
SameProcessCpowHolder::ToObject(JSContext* aCx, JSObject** aObjp)
|
||||||
|
{
|
||||||
|
*aObjp = mObj;
|
||||||
|
|
||||||
|
if (!mObj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return JS_WrapObject(aCx, aObjp);
|
||||||
|
}
|
||||||
|
|
||||||
// nsIMessageListenerManager
|
// nsIMessageListenerManager
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -311,11 +325,11 @@ JSONCreator(const jschar* aBuf, uint32_t aLen, void* aData)
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
GetParamsForMessage(JSContext* aCx,
|
GetParamsForMessage(JSContext* aCx,
|
||||||
const JS::Value& aObject,
|
const JS::Value& aJSON,
|
||||||
JSAutoStructuredCloneBuffer& aBuffer,
|
JSAutoStructuredCloneBuffer& aBuffer,
|
||||||
StructuredCloneClosure& aClosure)
|
StructuredCloneClosure& aClosure)
|
||||||
{
|
{
|
||||||
if (WriteStructuredClone(aCx, aObject, aBuffer, aClosure)) {
|
if (WriteStructuredClone(aCx, aJSON, aBuffer, aClosure)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
JS_ClearPendingException(aCx);
|
JS_ClearPendingException(aCx);
|
||||||
|
@ -325,7 +339,7 @@ GetParamsForMessage(JSContext* aCx,
|
||||||
// properly cases when interface is implemented in JS and used
|
// properly cases when interface is implemented in JS and used
|
||||||
// as a dictionary.
|
// as a dictionary.
|
||||||
nsAutoString json;
|
nsAutoString json;
|
||||||
JS::Rooted<JS::Value> v(aCx, aObject);
|
JS::Rooted<JS::Value> v(aCx, aJSON);
|
||||||
NS_ENSURE_TRUE(JS_Stringify(aCx, v.address(), nullptr, JSVAL_NULL,
|
NS_ENSURE_TRUE(JS_Stringify(aCx, v.address(), nullptr, JSVAL_NULL,
|
||||||
JSONCreator, &json), false);
|
JSONCreator, &json), false);
|
||||||
NS_ENSURE_TRUE(!json.IsEmpty(), false);
|
NS_ENSURE_TRUE(!json.IsEmpty(), false);
|
||||||
|
@ -342,7 +356,8 @@ GetParamsForMessage(JSContext* aCx,
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsFrameMessageManager::SendSyncMessage(const nsAString& aMessageName,
|
nsFrameMessageManager::SendSyncMessage(const nsAString& aMessageName,
|
||||||
const JS::Value& aObject,
|
const JS::Value& aJSON,
|
||||||
|
const JS::Value& aObjects,
|
||||||
JSContext* aCx,
|
JSContext* aCx,
|
||||||
uint8_t aArgc,
|
uint8_t aArgc,
|
||||||
JS::Value* aRetval)
|
JS::Value* aRetval)
|
||||||
|
@ -357,14 +372,19 @@ nsFrameMessageManager::SendSyncMessage(const nsAString& aMessageName,
|
||||||
StructuredCloneData data;
|
StructuredCloneData data;
|
||||||
JSAutoStructuredCloneBuffer buffer;
|
JSAutoStructuredCloneBuffer buffer;
|
||||||
if (aArgc >= 2 &&
|
if (aArgc >= 2 &&
|
||||||
!GetParamsForMessage(aCx, aObject, buffer, data.mClosure)) {
|
!GetParamsForMessage(aCx, aJSON, buffer, data.mClosure)) {
|
||||||
return NS_ERROR_DOM_DATA_CLONE_ERR;
|
return NS_ERROR_DOM_DATA_CLONE_ERR;
|
||||||
}
|
}
|
||||||
data.mData = buffer.data();
|
data.mData = buffer.data();
|
||||||
data.mDataLength = buffer.nbytes();
|
data.mDataLength = buffer.nbytes();
|
||||||
|
|
||||||
|
JS::RootedObject objects(aCx);
|
||||||
|
if (aArgc >= 3 && aObjects.isObject()) {
|
||||||
|
objects = &aObjects.toObject();
|
||||||
|
}
|
||||||
|
|
||||||
InfallibleTArray<nsString> retval;
|
InfallibleTArray<nsString> retval;
|
||||||
if (mCallback->DoSendSyncMessage(aMessageName, data, &retval)) {
|
if (mCallback->DoSendSyncMessage(aCx, aMessageName, data, objects, &retval)) {
|
||||||
uint32_t len = retval.Length();
|
uint32_t len = retval.Length();
|
||||||
JS::Rooted<JSObject*> dataArray(aCx, JS_NewArrayObject(aCx, len, nullptr));
|
JS::Rooted<JSObject*> dataArray(aCx, JS_NewArrayObject(aCx, len, nullptr));
|
||||||
NS_ENSURE_TRUE(dataArray, NS_ERROR_OUT_OF_MEMORY);
|
NS_ENSURE_TRUE(dataArray, NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
@ -389,20 +409,22 @@ nsFrameMessageManager::SendSyncMessage(const nsAString& aMessageName,
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsFrameMessageManager::DispatchAsyncMessageInternal(const nsAString& aMessage,
|
nsFrameMessageManager::DispatchAsyncMessageInternal(JSContext* aCx,
|
||||||
const StructuredCloneData& aData)
|
const nsAString& aMessage,
|
||||||
|
const StructuredCloneData& aData,
|
||||||
|
JS::Handle<JSObject *> aCpows)
|
||||||
{
|
{
|
||||||
if (mIsBroadcaster) {
|
if (mIsBroadcaster) {
|
||||||
int32_t len = mChildManagers.Count();
|
int32_t len = mChildManagers.Count();
|
||||||
for (int32_t i = 0; i < len; ++i) {
|
for (int32_t i = 0; i < len; ++i) {
|
||||||
static_cast<nsFrameMessageManager*>(mChildManagers[i])->
|
static_cast<nsFrameMessageManager*>(mChildManagers[i])->
|
||||||
DispatchAsyncMessageInternal(aMessage, aData);
|
DispatchAsyncMessageInternal(aCx, aMessage, aData, aCpows);
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_ENSURE_TRUE(mCallback, NS_ERROR_NOT_INITIALIZED);
|
NS_ENSURE_TRUE(mCallback, NS_ERROR_NOT_INITIALIZED);
|
||||||
if (!mCallback->DoSendAsyncMessage(aMessage, aData)) {
|
if (!mCallback->DoSendAsyncMessage(aCx, aMessage, aData, aCpows)) {
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
@ -410,7 +432,8 @@ nsFrameMessageManager::DispatchAsyncMessageInternal(const nsAString& aMessage,
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsFrameMessageManager::DispatchAsyncMessage(const nsAString& aMessageName,
|
nsFrameMessageManager::DispatchAsyncMessage(const nsAString& aMessageName,
|
||||||
const JS::Value& aObject,
|
const JS::Value& aJSON,
|
||||||
|
const JS::Value& aObjects,
|
||||||
JSContext* aCx,
|
JSContext* aCx,
|
||||||
uint8_t aArgc)
|
uint8_t aArgc)
|
||||||
{
|
{
|
||||||
|
@ -418,14 +441,19 @@ nsFrameMessageManager::DispatchAsyncMessage(const nsAString& aMessageName,
|
||||||
JSAutoStructuredCloneBuffer buffer;
|
JSAutoStructuredCloneBuffer buffer;
|
||||||
|
|
||||||
if (aArgc >= 2 &&
|
if (aArgc >= 2 &&
|
||||||
!GetParamsForMessage(aCx, aObject, buffer, data.mClosure)) {
|
!GetParamsForMessage(aCx, aJSON, buffer, data.mClosure)) {
|
||||||
return NS_ERROR_DOM_DATA_CLONE_ERR;
|
return NS_ERROR_DOM_DATA_CLONE_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JS::RootedObject objects(aCx);
|
||||||
|
if (aArgc >= 3 && aObjects.isObject()) {
|
||||||
|
objects = &aObjects.toObject();
|
||||||
|
}
|
||||||
|
|
||||||
data.mData = buffer.data();
|
data.mData = buffer.data();
|
||||||
data.mDataLength = buffer.nbytes();
|
data.mDataLength = buffer.nbytes();
|
||||||
|
|
||||||
return DispatchAsyncMessageInternal(aMessageName, data);
|
return DispatchAsyncMessageInternal(aCx, aMessageName, data, objects);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -433,11 +461,12 @@ nsFrameMessageManager::DispatchAsyncMessage(const nsAString& aMessageName,
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsFrameMessageManager::SendAsyncMessage(const nsAString& aMessageName,
|
nsFrameMessageManager::SendAsyncMessage(const nsAString& aMessageName,
|
||||||
const JS::Value& aObject,
|
const JS::Value& aJSON,
|
||||||
|
const JS::Value& aObjects,
|
||||||
JSContext* aCx,
|
JSContext* aCx,
|
||||||
uint8_t aArgc)
|
uint8_t aArgc)
|
||||||
{
|
{
|
||||||
return DispatchAsyncMessage(aMessageName, aObject, aCx, aArgc);
|
return DispatchAsyncMessage(aMessageName, aJSON, aObjects, aCx, aArgc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -445,11 +474,12 @@ nsFrameMessageManager::SendAsyncMessage(const nsAString& aMessageName,
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsFrameMessageManager::BroadcastAsyncMessage(const nsAString& aMessageName,
|
nsFrameMessageManager::BroadcastAsyncMessage(const nsAString& aMessageName,
|
||||||
const JS::Value& aObject,
|
const JS::Value& aJSON,
|
||||||
|
const JS::Value& aObjects,
|
||||||
JSContext* aCx,
|
JSContext* aCx,
|
||||||
uint8_t aArgc)
|
uint8_t aArgc)
|
||||||
{
|
{
|
||||||
return DispatchAsyncMessage(aMessageName, aObject, aCx, aArgc);
|
return DispatchAsyncMessage(aMessageName, aJSON, aObjects, aCx, aArgc);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -631,11 +661,10 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
|
||||||
const nsAString& aMessage,
|
const nsAString& aMessage,
|
||||||
bool aSync,
|
bool aSync,
|
||||||
const StructuredCloneData* aCloneData,
|
const StructuredCloneData* aCloneData,
|
||||||
JS::Handle<JSObject*> aObjectsArray,
|
CpowHolder* aCpows,
|
||||||
InfallibleTArray<nsString>* aJSONRetVal)
|
InfallibleTArray<nsString>* aJSONRetVal)
|
||||||
{
|
{
|
||||||
AutoSafeJSContext ctx;
|
AutoSafeJSContext ctx;
|
||||||
JS::Rooted<JSObject*> objectsArray(ctx, aObjectsArray);
|
|
||||||
if (mListeners.Length()) {
|
if (mListeners.Length()) {
|
||||||
nsCOMPtr<nsIAtom> name = do_GetAtom(aMessage);
|
nsCOMPtr<nsIAtom> name = do_GetAtom(aMessage);
|
||||||
MMListenerRemover lr(this);
|
MMListenerRemover lr(this);
|
||||||
|
@ -663,20 +692,21 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
|
||||||
nsContentUtils::WrapNative(ctx, global, aTarget, targetv.address(),
|
nsContentUtils::WrapNative(ctx, global, aTarget, targetv.address(),
|
||||||
nullptr, true);
|
nullptr, true);
|
||||||
|
|
||||||
// To keep compatibility with e10s message manager,
|
JS::RootedObject cpows(ctx);
|
||||||
// define empty objects array.
|
if (aCpows) {
|
||||||
if (!objectsArray) {
|
if (!aCpows->ToObject(ctx, cpows.address())) {
|
||||||
// Because we want JS messages to have always the same properties,
|
return NS_ERROR_UNEXPECTED;
|
||||||
// create array even if len == 0.
|
|
||||||
objectsArray = JS_NewArrayObject(ctx, 0, nullptr);
|
|
||||||
if (!objectsArray) {
|
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
JS::Rooted<JS::Value> objectsv(ctx, JS::ObjectValue(*objectsArray));
|
if (!cpows) {
|
||||||
if (!JS_WrapValue(ctx, objectsv.address()))
|
cpows = JS_NewObject(ctx, nullptr, nullptr, nullptr);
|
||||||
|
if (!cpows) {
|
||||||
return NS_ERROR_UNEXPECTED;
|
return NS_ERROR_UNEXPECTED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
JS::RootedValue cpowsv(ctx, JS::ObjectValue(*cpows));
|
||||||
|
|
||||||
JS::Rooted<JS::Value> json(ctx, JS::NullValue());
|
JS::Rooted<JS::Value> json(ctx, JS::NullValue());
|
||||||
if (aCloneData && aCloneData->mDataLength &&
|
if (aCloneData && aCloneData->mDataLength &&
|
||||||
|
@ -696,7 +726,7 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
|
||||||
BOOLEAN_TO_JSVAL(aSync), nullptr, nullptr, JSPROP_ENUMERATE);
|
BOOLEAN_TO_JSVAL(aSync), nullptr, nullptr, JSPROP_ENUMERATE);
|
||||||
JS_DefineProperty(ctx, param, "json", json, nullptr, nullptr, JSPROP_ENUMERATE); // deprecated
|
JS_DefineProperty(ctx, param, "json", json, nullptr, nullptr, JSPROP_ENUMERATE); // deprecated
|
||||||
JS_DefineProperty(ctx, param, "data", json, nullptr, nullptr, JSPROP_ENUMERATE);
|
JS_DefineProperty(ctx, param, "data", json, nullptr, nullptr, JSPROP_ENUMERATE);
|
||||||
JS_DefineProperty(ctx, param, "objects", objectsv, nullptr, nullptr, JSPROP_ENUMERATE);
|
JS_DefineProperty(ctx, param, "objects", cpowsv, nullptr, nullptr, JSPROP_ENUMERATE);
|
||||||
|
|
||||||
JS::Rooted<JS::Value> thisValue(ctx, JS::UndefinedValue());
|
JS::Rooted<JS::Value> thisValue(ctx, JS::UndefinedValue());
|
||||||
|
|
||||||
|
@ -754,7 +784,7 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
|
||||||
nsRefPtr<nsFrameMessageManager> kungfuDeathGrip = mParentManager;
|
nsRefPtr<nsFrameMessageManager> kungfuDeathGrip = mParentManager;
|
||||||
return mParentManager ? mParentManager->ReceiveMessage(aTarget, aMessage,
|
return mParentManager ? mParentManager->ReceiveMessage(aTarget, aMessage,
|
||||||
aSync, aCloneData,
|
aSync, aCloneData,
|
||||||
objectsArray,
|
aCpows,
|
||||||
aJSONRetVal) : NS_OK;
|
aJSONRetVal) : NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1040,20 +1070,33 @@ nsFrameMessageManager* nsFrameMessageManager::sParentProcessManager = nullptr;
|
||||||
nsFrameMessageManager* nsFrameMessageManager::sSameProcessParentManager = nullptr;
|
nsFrameMessageManager* nsFrameMessageManager::sSameProcessParentManager = nullptr;
|
||||||
nsTArray<nsCOMPtr<nsIRunnable> >* nsFrameMessageManager::sPendingSameProcessAsyncMessages = nullptr;
|
nsTArray<nsCOMPtr<nsIRunnable> >* nsFrameMessageManager::sPendingSameProcessAsyncMessages = nullptr;
|
||||||
|
|
||||||
|
|
||||||
class nsAsyncMessageToSameProcessChild : public nsRunnable
|
class nsAsyncMessageToSameProcessChild : public nsRunnable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
nsAsyncMessageToSameProcessChild(const nsAString& aMessage,
|
nsAsyncMessageToSameProcessChild(JSContext* aCx,
|
||||||
const StructuredCloneData& aData)
|
const nsAString& aMessage,
|
||||||
: mMessage(aMessage)
|
const StructuredCloneData& aData,
|
||||||
|
JS::Handle<JSObject *> aCpows)
|
||||||
|
: mRuntime(js::GetRuntime(aCx)),
|
||||||
|
mMessage(aMessage),
|
||||||
|
mCpows(aCpows)
|
||||||
{
|
{
|
||||||
if (aData.mDataLength && !mData.copy(aData.mData, aData.mDataLength)) {
|
if (aData.mDataLength && !mData.copy(aData.mData, aData.mDataLength)) {
|
||||||
NS_RUNTIMEABORT("OOM");
|
NS_RUNTIMEABORT("OOM");
|
||||||
}
|
}
|
||||||
|
if (mCpows && !js_AddObjectRoot(mRuntime, &mCpows)) {
|
||||||
|
NS_RUNTIMEABORT("OOM");
|
||||||
|
}
|
||||||
mClosure = aData.mClosure;
|
mClosure = aData.mClosure;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~nsAsyncMessageToSameProcessChild()
|
||||||
|
{
|
||||||
|
if (mCpows) {
|
||||||
|
JS_RemoveObjectRootRT(mRuntime, &mCpows);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHOD Run()
|
NS_IMETHOD Run()
|
||||||
{
|
{
|
||||||
if (nsFrameMessageManager::sChildProcessManager) {
|
if (nsFrameMessageManager::sChildProcessManager) {
|
||||||
|
@ -1062,15 +1105,19 @@ public:
|
||||||
data.mDataLength = mData.nbytes();
|
data.mDataLength = mData.nbytes();
|
||||||
data.mClosure = mClosure;
|
data.mClosure = mClosure;
|
||||||
|
|
||||||
|
SameProcessCpowHolder cpows(mRuntime, JS::Handle<JSObject *>::fromMarkedLocation(&mCpows));
|
||||||
|
|
||||||
nsRefPtr<nsFrameMessageManager> ppm = nsFrameMessageManager::sChildProcessManager;
|
nsRefPtr<nsFrameMessageManager> ppm = nsFrameMessageManager::sChildProcessManager;
|
||||||
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()), mMessage,
|
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()), mMessage,
|
||||||
false, &data, JS::NullPtr(), nullptr);
|
false, &data, &cpows, nullptr);
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
JSRuntime* mRuntime;
|
||||||
nsString mMessage;
|
nsString mMessage;
|
||||||
JSAutoStructuredCloneBuffer mData;
|
JSAutoStructuredCloneBuffer mData;
|
||||||
StructuredCloneClosure mClosure;
|
StructuredCloneClosure mClosure;
|
||||||
|
JSObject* mCpows;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1089,11 +1136,13 @@ public:
|
||||||
MOZ_COUNT_DTOR(SameParentProcessMessageManagerCallback);
|
MOZ_COUNT_DTOR(SameParentProcessMessageManagerCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool DoSendAsyncMessage(const nsAString& aMessage,
|
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||||
const StructuredCloneData& aData)
|
const nsAString& aMessage,
|
||||||
|
const StructuredCloneData& aData,
|
||||||
|
JS::Handle<JSObject *> aCpows)
|
||||||
{
|
{
|
||||||
nsRefPtr<nsIRunnable> ev =
|
nsRefPtr<nsIRunnable> ev =
|
||||||
new nsAsyncMessageToSameProcessChild(aMessage, aData);
|
new nsAsyncMessageToSameProcessChild(aCx, aMessage, aData, aCpows);
|
||||||
NS_DispatchToCurrentThread(ev);
|
NS_DispatchToCurrentThread(ev);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1133,8 +1182,10 @@ public:
|
||||||
MOZ_COUNT_DTOR(ChildProcessMessageManagerCallback);
|
MOZ_COUNT_DTOR(ChildProcessMessageManagerCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool DoSendSyncMessage(const nsAString& aMessage,
|
virtual bool DoSendSyncMessage(JSContext* aCx,
|
||||||
|
const nsAString& aMessage,
|
||||||
const mozilla::dom::StructuredCloneData& aData,
|
const mozilla::dom::StructuredCloneData& aData,
|
||||||
|
JS::Handle<JSObject *> aCpows,
|
||||||
InfallibleTArray<nsString>* aJSONRetVal)
|
InfallibleTArray<nsString>* aJSONRetVal)
|
||||||
{
|
{
|
||||||
mozilla::dom::ContentChild* cc =
|
mozilla::dom::ContentChild* cc =
|
||||||
|
@ -1146,11 +1197,17 @@ public:
|
||||||
if (!BuildClonedMessageDataForChild(cc, aData, data)) {
|
if (!BuildClonedMessageDataForChild(cc, aData, data)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return cc->SendSyncMessage(nsString(aMessage), data, aJSONRetVal);
|
InfallibleTArray<mozilla::jsipc::CpowEntry> cpows;
|
||||||
|
if (!cc->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return cc->SendSyncMessage(nsString(aMessage), data, cpows, aJSONRetVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool DoSendAsyncMessage(const nsAString& aMessage,
|
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||||
const mozilla::dom::StructuredCloneData& aData)
|
const nsAString& aMessage,
|
||||||
|
const mozilla::dom::StructuredCloneData& aData,
|
||||||
|
JS::Handle<JSObject *> aCpows)
|
||||||
{
|
{
|
||||||
mozilla::dom::ContentChild* cc =
|
mozilla::dom::ContentChild* cc =
|
||||||
mozilla::dom::ContentChild::GetSingleton();
|
mozilla::dom::ContentChild::GetSingleton();
|
||||||
|
@ -1161,7 +1218,11 @@ public:
|
||||||
if (!BuildClonedMessageDataForChild(cc, aData, data)) {
|
if (!BuildClonedMessageDataForChild(cc, aData, data)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return cc->SendAsyncMessage(nsString(aMessage), data);
|
InfallibleTArray<mozilla::jsipc::CpowEntry> cpows;
|
||||||
|
if (!cc->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return cc->SendAsyncMessage(nsString(aMessage), data, cpows);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -1170,16 +1231,30 @@ public:
|
||||||
class nsAsyncMessageToSameProcessParent : public nsRunnable
|
class nsAsyncMessageToSameProcessParent : public nsRunnable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
nsAsyncMessageToSameProcessParent(const nsAString& aMessage,
|
nsAsyncMessageToSameProcessParent(JSContext* aCx,
|
||||||
const StructuredCloneData& aData)
|
const nsAString& aMessage,
|
||||||
: mMessage(aMessage)
|
const StructuredCloneData& aData,
|
||||||
|
JS::Handle<JSObject *> aCpows)
|
||||||
|
: mRuntime(js::GetRuntime(aCx)),
|
||||||
|
mMessage(aMessage),
|
||||||
|
mCpows(aCpows)
|
||||||
{
|
{
|
||||||
if (aData.mDataLength && !mData.copy(aData.mData, aData.mDataLength)) {
|
if (aData.mDataLength && !mData.copy(aData.mData, aData.mDataLength)) {
|
||||||
NS_RUNTIMEABORT("OOM");
|
NS_RUNTIMEABORT("OOM");
|
||||||
}
|
}
|
||||||
|
if (mCpows && !js_AddObjectRoot(mRuntime, &mCpows)) {
|
||||||
|
NS_RUNTIMEABORT("OOM");
|
||||||
|
}
|
||||||
mClosure = aData.mClosure;
|
mClosure = aData.mClosure;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~nsAsyncMessageToSameProcessParent()
|
||||||
|
{
|
||||||
|
if (mCpows) {
|
||||||
|
JS_RemoveObjectRootRT(mRuntime, &mCpows);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHOD Run()
|
NS_IMETHOD Run()
|
||||||
{
|
{
|
||||||
if (nsFrameMessageManager::sPendingSameProcessAsyncMessages) {
|
if (nsFrameMessageManager::sPendingSameProcessAsyncMessages) {
|
||||||
|
@ -1191,16 +1266,20 @@ public:
|
||||||
data.mDataLength = mData.nbytes();
|
data.mDataLength = mData.nbytes();
|
||||||
data.mClosure = mClosure;
|
data.mClosure = mClosure;
|
||||||
|
|
||||||
|
SameProcessCpowHolder cpows(mRuntime, JS::Handle<JSObject *>::fromMarkedLocation(&mCpows));
|
||||||
|
|
||||||
nsRefPtr<nsFrameMessageManager> ppm =
|
nsRefPtr<nsFrameMessageManager> ppm =
|
||||||
nsFrameMessageManager::sSameProcessParentManager;
|
nsFrameMessageManager::sSameProcessParentManager;
|
||||||
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()),
|
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()),
|
||||||
mMessage, false, &data, JS::NullPtr(), nullptr);
|
mMessage, false, &data, &cpows, nullptr);
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
JSRuntime* mRuntime;
|
||||||
nsString mMessage;
|
nsString mMessage;
|
||||||
JSAutoStructuredCloneBuffer mData;
|
JSAutoStructuredCloneBuffer mData;
|
||||||
StructuredCloneClosure mClosure;
|
StructuredCloneClosure mClosure;
|
||||||
|
JSObject* mCpows;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1218,8 +1297,10 @@ public:
|
||||||
MOZ_COUNT_DTOR(SameChildProcessMessageManagerCallback);
|
MOZ_COUNT_DTOR(SameChildProcessMessageManagerCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool DoSendSyncMessage(const nsAString& aMessage,
|
virtual bool DoSendSyncMessage(JSContext* aCx,
|
||||||
|
const nsAString& aMessage,
|
||||||
const mozilla::dom::StructuredCloneData& aData,
|
const mozilla::dom::StructuredCloneData& aData,
|
||||||
|
JS::Handle<JSObject *> aCpows,
|
||||||
InfallibleTArray<nsString>* aJSONRetVal)
|
InfallibleTArray<nsString>* aJSONRetVal)
|
||||||
{
|
{
|
||||||
nsTArray<nsCOMPtr<nsIRunnable> > asyncMessages;
|
nsTArray<nsCOMPtr<nsIRunnable> > asyncMessages;
|
||||||
|
@ -1232,21 +1313,24 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (nsFrameMessageManager::sSameProcessParentManager) {
|
if (nsFrameMessageManager::sSameProcessParentManager) {
|
||||||
|
SameProcessCpowHolder cpows(js::GetRuntime(aCx), aCpows);
|
||||||
nsRefPtr<nsFrameMessageManager> ppm = nsFrameMessageManager::sSameProcessParentManager;
|
nsRefPtr<nsFrameMessageManager> ppm = nsFrameMessageManager::sSameProcessParentManager;
|
||||||
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()), aMessage,
|
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()), aMessage,
|
||||||
true, &aData, JS::NullPtr(), aJSONRetVal);
|
true, &aData, &cpows, aJSONRetVal);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool DoSendAsyncMessage(const nsAString& aMessage,
|
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||||
const mozilla::dom::StructuredCloneData& aData)
|
const nsAString& aMessage,
|
||||||
|
const mozilla::dom::StructuredCloneData& aData,
|
||||||
|
JS::Handle<JSObject *> aCpows)
|
||||||
{
|
{
|
||||||
if (!nsFrameMessageManager::sPendingSameProcessAsyncMessages) {
|
if (!nsFrameMessageManager::sPendingSameProcessAsyncMessages) {
|
||||||
nsFrameMessageManager::sPendingSameProcessAsyncMessages = new nsTArray<nsCOMPtr<nsIRunnable> >;
|
nsFrameMessageManager::sPendingSameProcessAsyncMessages = new nsTArray<nsCOMPtr<nsIRunnable> >;
|
||||||
}
|
}
|
||||||
nsCOMPtr<nsIRunnable> ev =
|
nsCOMPtr<nsIRunnable> ev =
|
||||||
new nsAsyncMessageToSameProcessParent(aMessage, aData);
|
new nsAsyncMessageToSameProcessParent(aCx, aMessage, aData, aCpows);
|
||||||
nsFrameMessageManager::sPendingSameProcessAsyncMessages->AppendElement(ev);
|
nsFrameMessageManager::sPendingSameProcessAsyncMessages->AppendElement(ev);
|
||||||
NS_DispatchToCurrentThread(ev);
|
NS_DispatchToCurrentThread(ev);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
/* -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
/* -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set ts=8 sts=4 sw=4 tw=99 et: */
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
/* 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
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
@ -51,15 +52,19 @@ public:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool DoSendSyncMessage(const nsAString& aMessage,
|
virtual bool DoSendSyncMessage(JSContext* aCx,
|
||||||
|
const nsAString& aMessage,
|
||||||
const mozilla::dom::StructuredCloneData& aData,
|
const mozilla::dom::StructuredCloneData& aData,
|
||||||
|
JS::Handle<JSObject *> aCpows,
|
||||||
InfallibleTArray<nsString>* aJSONRetVal)
|
InfallibleTArray<nsString>* aJSONRetVal)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool DoSendAsyncMessage(const nsAString& aMessage,
|
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||||
const mozilla::dom::StructuredCloneData& aData)
|
const nsAString& aMessage,
|
||||||
|
const mozilla::dom::StructuredCloneData& aData,
|
||||||
|
JS::Handle<JSObject *> aCpows)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -86,11 +91,11 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool BuildClonedMessageDataForParent(ContentParent* aParent,
|
bool BuildClonedMessageDataForParent(ContentParent* aParent,
|
||||||
const StructuredCloneData& aData,
|
const StructuredCloneData& aData,
|
||||||
ClonedMessageData& aClonedData);
|
ClonedMessageData& aClonedData);
|
||||||
bool BuildClonedMessageDataForChild(ContentChild* aChild,
|
bool BuildClonedMessageDataForChild(ContentChild* aChild,
|
||||||
const StructuredCloneData& aData,
|
const StructuredCloneData& aData,
|
||||||
ClonedMessageData& aClonedData);
|
ClonedMessageData& aClonedData);
|
||||||
};
|
};
|
||||||
|
|
||||||
StructuredCloneData UnpackClonedMessageDataForParent(const ClonedMessageData& aData);
|
StructuredCloneData UnpackClonedMessageDataForParent(const ClonedMessageData& aData);
|
||||||
|
@ -110,6 +115,25 @@ struct nsMessageListenerInfo
|
||||||
nsCOMPtr<nsIAtom> mMessage;
|
nsCOMPtr<nsIAtom> mMessage;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CpowHolder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual bool ToObject(JSContext* cx, JSObject** objp) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MOZ_STACK_CLASS SameProcessCpowHolder : public CpowHolder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SameProcessCpowHolder(JSRuntime *aRuntime, JS::Handle<JSObject *> aObj)
|
||||||
|
: mObj(aRuntime, aObj)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ToObject(JSContext* aCx, JSObject** aObjp);
|
||||||
|
|
||||||
|
private:
|
||||||
|
JS::RootedObject mObj;
|
||||||
|
};
|
||||||
|
|
||||||
class nsFrameMessageManager MOZ_FINAL : public nsIContentFrameMessageManager,
|
class nsFrameMessageManager MOZ_FINAL : public nsIContentFrameMessageManager,
|
||||||
public nsIMessageBroadcaster,
|
public nsIMessageBroadcaster,
|
||||||
|
@ -183,7 +207,7 @@ public:
|
||||||
|
|
||||||
nsresult ReceiveMessage(nsISupports* aTarget, const nsAString& aMessage,
|
nsresult ReceiveMessage(nsISupports* aTarget, const nsAString& aMessage,
|
||||||
bool aSync, const StructuredCloneData* aCloneData,
|
bool aSync, const StructuredCloneData* aCloneData,
|
||||||
JS::Handle<JSObject*> aObjectsArray,
|
CpowHolder* aCpows,
|
||||||
InfallibleTArray<nsString>* aJSONRetVal);
|
InfallibleTArray<nsString>* aJSONRetVal);
|
||||||
|
|
||||||
void AddChildManager(nsFrameMessageManager* aManager,
|
void AddChildManager(nsFrameMessageManager* aManager,
|
||||||
|
@ -202,11 +226,14 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult DispatchAsyncMessage(const nsAString& aMessageName,
|
nsresult DispatchAsyncMessage(const nsAString& aMessageName,
|
||||||
const JS::Value& aObject,
|
const JS::Value& aJSON,
|
||||||
|
const JS::Value& aObjects,
|
||||||
JSContext* aCx,
|
JSContext* aCx,
|
||||||
uint8_t aArgc);
|
uint8_t aArgc);
|
||||||
nsresult DispatchAsyncMessageInternal(const nsAString& aMessage,
|
nsresult DispatchAsyncMessageInternal(JSContext* aCx,
|
||||||
const StructuredCloneData& aData);
|
const nsAString& aMessage,
|
||||||
|
const StructuredCloneData& aData,
|
||||||
|
JS::Handle<JSObject *> aCpows);
|
||||||
void RemoveFromParent();
|
void RemoveFromParent();
|
||||||
nsFrameMessageManager* GetParentManager() { return mParentManager; }
|
nsFrameMessageManager* GetParentManager() { return mParentManager; }
|
||||||
void SetParentManager(nsFrameMessageManager* aParent)
|
void SetParentManager(nsFrameMessageManager* aParent)
|
||||||
|
|
|
@ -25,8 +25,10 @@ using mozilla::dom::StructuredCloneData;
|
||||||
using mozilla::dom::StructuredCloneClosure;
|
using mozilla::dom::StructuredCloneClosure;
|
||||||
|
|
||||||
bool
|
bool
|
||||||
nsInProcessTabChildGlobal::DoSendSyncMessage(const nsAString& aMessage,
|
nsInProcessTabChildGlobal::DoSendSyncMessage(JSContext* aCx,
|
||||||
const StructuredCloneData& aData,
|
const nsAString& aMessage,
|
||||||
|
const mozilla::dom::StructuredCloneData& aData,
|
||||||
|
JS::Handle<JSObject *> aCpows,
|
||||||
InfallibleTArray<nsString>* aJSONRetVal)
|
InfallibleTArray<nsString>* aJSONRetVal)
|
||||||
{
|
{
|
||||||
nsTArray<nsCOMPtr<nsIRunnable> > asyncMessages;
|
nsTArray<nsCOMPtr<nsIRunnable> > asyncMessages;
|
||||||
|
@ -37,9 +39,9 @@ nsInProcessTabChildGlobal::DoSendSyncMessage(const nsAString& aMessage,
|
||||||
async->Run();
|
async->Run();
|
||||||
}
|
}
|
||||||
if (mChromeMessageManager) {
|
if (mChromeMessageManager) {
|
||||||
|
SameProcessCpowHolder cpows(js::GetRuntime(aCx), aCpows);
|
||||||
nsRefPtr<nsFrameMessageManager> mm = mChromeMessageManager;
|
nsRefPtr<nsFrameMessageManager> mm = mChromeMessageManager;
|
||||||
mm->ReceiveMessage(mOwner, aMessage, true, &aData, JS::NullPtr(),
|
mm->ReceiveMessage(mOwner, aMessage, true, &aData, &cpows, aJSONRetVal);
|
||||||
aJSONRetVal);
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -47,17 +49,33 @@ nsInProcessTabChildGlobal::DoSendSyncMessage(const nsAString& aMessage,
|
||||||
class nsAsyncMessageToParent : public nsRunnable
|
class nsAsyncMessageToParent : public nsRunnable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
nsAsyncMessageToParent(nsInProcessTabChildGlobal* aTabChild,
|
nsAsyncMessageToParent(JSContext* aCx,
|
||||||
|
nsInProcessTabChildGlobal* aTabChild,
|
||||||
const nsAString& aMessage,
|
const nsAString& aMessage,
|
||||||
const StructuredCloneData& aData)
|
const StructuredCloneData& aData,
|
||||||
: mTabChild(aTabChild), mMessage(aMessage), mRun(false)
|
JS::Handle<JSObject *> aCpows)
|
||||||
|
: mRuntime(js::GetRuntime(aCx)),
|
||||||
|
mTabChild(aTabChild),
|
||||||
|
mMessage(aMessage),
|
||||||
|
mCpows(aCpows),
|
||||||
|
mRun(false)
|
||||||
{
|
{
|
||||||
if (aData.mDataLength && !mData.copy(aData.mData, aData.mDataLength)) {
|
if (aData.mDataLength && !mData.copy(aData.mData, aData.mDataLength)) {
|
||||||
NS_RUNTIMEABORT("OOM");
|
NS_RUNTIMEABORT("OOM");
|
||||||
}
|
}
|
||||||
|
if (mCpows && !js_AddObjectRoot(mRuntime, &mCpows)) {
|
||||||
|
NS_RUNTIMEABORT("OOM");
|
||||||
|
}
|
||||||
mClosure = aData.mClosure;
|
mClosure = aData.mClosure;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~nsAsyncMessageToParent()
|
||||||
|
{
|
||||||
|
if (mCpows) {
|
||||||
|
JS_RemoveObjectRootRT(mRuntime, &mCpows);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHOD Run()
|
NS_IMETHOD Run()
|
||||||
{
|
{
|
||||||
if (mRun) {
|
if (mRun) {
|
||||||
|
@ -72,27 +90,32 @@ public:
|
||||||
data.mDataLength = mData.nbytes();
|
data.mDataLength = mData.nbytes();
|
||||||
data.mClosure = mClosure;
|
data.mClosure = mClosure;
|
||||||
|
|
||||||
|
SameProcessCpowHolder cpows(mRuntime, JS::Handle<JSObject *>::fromMarkedLocation(&mCpows));
|
||||||
|
|
||||||
nsRefPtr<nsFrameMessageManager> mm = mTabChild->mChromeMessageManager;
|
nsRefPtr<nsFrameMessageManager> mm = mTabChild->mChromeMessageManager;
|
||||||
mm->ReceiveMessage(mTabChild->mOwner, mMessage, false, &data,
|
mm->ReceiveMessage(mTabChild->mOwner, mMessage, false, &data, &cpows, nullptr);
|
||||||
JS::NullPtr(), nullptr);
|
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
JSRuntime* mRuntime;
|
||||||
nsRefPtr<nsInProcessTabChildGlobal> mTabChild;
|
nsRefPtr<nsInProcessTabChildGlobal> mTabChild;
|
||||||
nsString mMessage;
|
nsString mMessage;
|
||||||
JSAutoStructuredCloneBuffer mData;
|
JSAutoStructuredCloneBuffer mData;
|
||||||
StructuredCloneClosure mClosure;
|
StructuredCloneClosure mClosure;
|
||||||
|
JSObject* mCpows;
|
||||||
// True if this runnable has already been called. This can happen if DoSendSyncMessage
|
// True if this runnable has already been called. This can happen if DoSendSyncMessage
|
||||||
// is called while waiting for an asynchronous message send.
|
// is called while waiting for an asynchronous message send.
|
||||||
bool mRun;
|
bool mRun;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool
|
bool
|
||||||
nsInProcessTabChildGlobal::DoSendAsyncMessage(const nsAString& aMessage,
|
nsInProcessTabChildGlobal::DoSendAsyncMessage(JSContext* aCx,
|
||||||
const StructuredCloneData& aData)
|
const nsAString& aMessage,
|
||||||
|
const StructuredCloneData& aData,
|
||||||
|
JS::Handle<JSObject *> aCpows)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIRunnable> ev =
|
nsCOMPtr<nsIRunnable> ev =
|
||||||
new nsAsyncMessageToParent(this, aMessage, aData);
|
new nsAsyncMessageToParent(aCx, this, aMessage, aData, aCpows);
|
||||||
mASyncMessages.AppendElement(ev);
|
mASyncMessages.AppendElement(ev);
|
||||||
NS_DispatchToCurrentThread(ev);
|
NS_DispatchToCurrentThread(ev);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -41,12 +41,13 @@ public:
|
||||||
NS_FORWARD_SAFE_NSIMESSAGESENDER(mMessageManager)
|
NS_FORWARD_SAFE_NSIMESSAGESENDER(mMessageManager)
|
||||||
NS_IMETHOD SendSyncMessage(const nsAString& aMessageName,
|
NS_IMETHOD SendSyncMessage(const nsAString& aMessageName,
|
||||||
const JS::Value& aObject,
|
const JS::Value& aObject,
|
||||||
|
const JS::Value& aRemote,
|
||||||
JSContext* aCx,
|
JSContext* aCx,
|
||||||
uint8_t aArgc,
|
uint8_t aArgc,
|
||||||
JS::Value* aRetval)
|
JS::Value* aRetval)
|
||||||
{
|
{
|
||||||
return mMessageManager
|
return mMessageManager
|
||||||
? mMessageManager->SendSyncMessage(aMessageName, aObject, aCx, aArgc, aRetval)
|
? mMessageManager->SendSyncMessage(aMessageName, aObject, aRemote, aCx, aArgc, aRetval)
|
||||||
: NS_ERROR_NULL_POINTER;
|
: NS_ERROR_NULL_POINTER;
|
||||||
}
|
}
|
||||||
NS_IMETHOD GetContent(nsIDOMWindow** aContent) MOZ_OVERRIDE;
|
NS_IMETHOD GetContent(nsIDOMWindow** aContent) MOZ_OVERRIDE;
|
||||||
|
@ -66,11 +67,15 @@ public:
|
||||||
/**
|
/**
|
||||||
* MessageManagerCallback methods that we override.
|
* MessageManagerCallback methods that we override.
|
||||||
*/
|
*/
|
||||||
virtual bool DoSendSyncMessage(const nsAString& aMessage,
|
virtual bool DoSendSyncMessage(JSContext* aCx,
|
||||||
|
const nsAString& aMessage,
|
||||||
const mozilla::dom::StructuredCloneData& aData,
|
const mozilla::dom::StructuredCloneData& aData,
|
||||||
|
JS::Handle<JSObject *> aCpows,
|
||||||
InfallibleTArray<nsString>* aJSONRetVal) MOZ_OVERRIDE;
|
InfallibleTArray<nsString>* aJSONRetVal) MOZ_OVERRIDE;
|
||||||
virtual bool DoSendAsyncMessage(const nsAString& aMessage,
|
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||||
const mozilla::dom::StructuredCloneData& aData) MOZ_OVERRIDE;
|
const nsAString& aMessage,
|
||||||
|
const mozilla::dom::StructuredCloneData& aData,
|
||||||
|
JS::Handle<JSObject *> aCpows);
|
||||||
|
|
||||||
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor) MOZ_OVERRIDE;
|
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor) MOZ_OVERRIDE;
|
||||||
NS_IMETHOD AddEventListener(const nsAString& aType,
|
NS_IMETHOD AddEventListener(const nsAString& aType,
|
||||||
|
|
|
@ -61,6 +61,9 @@ MOCHITEST_CHROME_FILES = \
|
||||||
host_bug814638.xul \
|
host_bug814638.xul \
|
||||||
test_document_register.xul \
|
test_document_register.xul \
|
||||||
frame_bug814638.xul \
|
frame_bug814638.xul \
|
||||||
|
test_cpows.xul \
|
||||||
|
cpows_parent.xul \
|
||||||
|
cpows_child.js \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
include $(topsrcdir)/config/rules.mk
|
include $(topsrcdir)/config/rules.mk
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
dump('loaded child cpow test\n');
|
||||||
|
|
||||||
|
content.document.title = "Hello, Kitty";
|
||||||
|
|
||||||
|
(function start() {
|
||||||
|
sync_test();
|
||||||
|
async_test();
|
||||||
|
sendAsyncMessage("cpows:done", {});
|
||||||
|
}
|
||||||
|
)();
|
||||||
|
|
||||||
|
function ok(condition, message) {
|
||||||
|
dump('condition: ' + condition + ', ' + message + '\n');
|
||||||
|
if (!condition) {
|
||||||
|
sendAsyncMessage("cpows:fail", { message: message });
|
||||||
|
throw 'failed check: ' + message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var sync_obj;
|
||||||
|
var async_obj;
|
||||||
|
|
||||||
|
function make_object()
|
||||||
|
{
|
||||||
|
let o = { };
|
||||||
|
o.i = 5;
|
||||||
|
o.b = true;
|
||||||
|
o.s = "hello";
|
||||||
|
o.x = { i: 10 };
|
||||||
|
o.f = function () { return 99; }
|
||||||
|
return { "data": o,
|
||||||
|
"document": content.document
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function make_json()
|
||||||
|
{
|
||||||
|
return { check: "ok" };
|
||||||
|
}
|
||||||
|
|
||||||
|
function sync_test()
|
||||||
|
{
|
||||||
|
dump('beginning cpow sync test\n');
|
||||||
|
sync_obj = make_object();
|
||||||
|
sendSyncMessage("cpows:sync",
|
||||||
|
make_json(),
|
||||||
|
make_object());
|
||||||
|
}
|
||||||
|
|
||||||
|
function async_test()
|
||||||
|
{
|
||||||
|
dump('beginning cpow async test\n');
|
||||||
|
async_obj = make_object();
|
||||||
|
sendAsyncMessage("cpows:async",
|
||||||
|
make_json(),
|
||||||
|
async_obj);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||||
|
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||||
|
type="text/css"?>
|
||||||
|
<window title="MessageManager CPOW tests"
|
||||||
|
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||||
|
onload="start()">
|
||||||
|
|
||||||
|
<!-- test results are displayed in the html:body -->
|
||||||
|
<label value="CPOWs"/>
|
||||||
|
|
||||||
|
<script type="application/javascript"><![CDATA[
|
||||||
|
var test_state = "remote";
|
||||||
|
var test_node = null;
|
||||||
|
|
||||||
|
function ok(condition, message) {
|
||||||
|
return opener.wrappedJSObject.ok(condition, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testCpowMessage(message) {
|
||||||
|
ok(message.json.check == "ok", "correct json");
|
||||||
|
|
||||||
|
let data = message.objects.data;
|
||||||
|
let document = message.objects.document;
|
||||||
|
ok(data.i === 5, "integer property");
|
||||||
|
ok(data.b === true, "boolean property");
|
||||||
|
ok(data.s === "hello", "string property");
|
||||||
|
ok(data.x.i === 10, "nested property");
|
||||||
|
ok(data.f() === 99, "function call");
|
||||||
|
ok(document.title === "Hello, Kitty", "document node");
|
||||||
|
|
||||||
|
data.i = 6;
|
||||||
|
data.b = false;
|
||||||
|
data.s = "bye";
|
||||||
|
data.x = null;
|
||||||
|
ok(data.i === 6, "integer property");
|
||||||
|
ok(data.b === false, "boolean property");
|
||||||
|
ok(data.s === "bye", "string property");
|
||||||
|
ok(data.x === null, "nested property");
|
||||||
|
}
|
||||||
|
|
||||||
|
function recvAsyncMessage(message) {
|
||||||
|
testCpowMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
function recvSyncMessage(message) {
|
||||||
|
testCpowMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
function recvFailMessage(message) {
|
||||||
|
ok(false, message.json.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
function recvDoneMessage(message) {
|
||||||
|
if (test_state == "remote") {
|
||||||
|
test_node.parentNode.removeChild(test_node);
|
||||||
|
run_tests("inprocess");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
function run_tests(type) {
|
||||||
|
var node = document.getElementById('cpowbrowser_' + type);
|
||||||
|
|
||||||
|
test_state = type;
|
||||||
|
test_node = node;
|
||||||
|
|
||||||
|
var mm = node.messageManager;
|
||||||
|
mm.addMessageListener("cpows:async", recvAsyncMessage);
|
||||||
|
mm.addMessageListener("cpows:sync", recvSyncMessage);
|
||||||
|
mm.addMessageListener("cpows:done", recvDoneMessage);
|
||||||
|
mm.addMessageListener("cpows:fail", recvFailMessage);
|
||||||
|
mm.loadFrameScript("chrome://mochitests/content/chrome/content/base/test/chrome/cpows_child.js", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function start() {
|
||||||
|
run_tests('remote');
|
||||||
|
}
|
||||||
|
|
||||||
|
function finish() {
|
||||||
|
opener.setTimeout("done()", 0);
|
||||||
|
window.close();
|
||||||
|
}
|
||||||
|
]]></script>
|
||||||
|
|
||||||
|
<browser type="content" src="about:blank" id="cpowbrowser_remote" remote="true"/>
|
||||||
|
<browser type="content" src="about:blank" id="cpowbrowser_inprocess"/>
|
||||||
|
</window>
|
|
@ -0,0 +1,27 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||||
|
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||||
|
type="text/css"?>
|
||||||
|
<window title="Test CPOWs"
|
||||||
|
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||||
|
<script type="application/javascript"
|
||||||
|
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
|
|
||||||
|
<!-- test results are displayed in the html:body -->
|
||||||
|
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
</body>
|
||||||
|
|
||||||
|
<!-- test code goes here -->
|
||||||
|
<script type="application/javascript"><![CDATA[
|
||||||
|
|
||||||
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
|
||||||
|
function done() {
|
||||||
|
SimpleTest.finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
addLoadEvent(function() {
|
||||||
|
window.open("cpows_parent.xul", "", "chrome");
|
||||||
|
});
|
||||||
|
]]></script>
|
||||||
|
</window>
|
|
@ -321,6 +321,8 @@ ContentChild::Init(MessageLoop* aIOLoop,
|
||||||
|
|
||||||
SendGetProcessAttributes(&mID, &mIsForApp, &mIsForBrowser);
|
SendGetProcessAttributes(&mID, &mIsForApp, &mIsForBrowser);
|
||||||
|
|
||||||
|
GetCPOWManager();
|
||||||
|
|
||||||
if (mIsForApp && !mIsForBrowser) {
|
if (mIsForApp && !mIsForBrowser) {
|
||||||
SetProcessName(NS_LITERAL_STRING("(Preallocated app)"));
|
SetProcessName(NS_LITERAL_STRING("(Preallocated app)"));
|
||||||
} else {
|
} else {
|
||||||
|
@ -1059,13 +1061,15 @@ ContentChild::RecvNotifyVisited(const URIParams& aURI)
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ContentChild::RecvAsyncMessage(const nsString& aMsg,
|
ContentChild::RecvAsyncMessage(const nsString& aMsg,
|
||||||
const ClonedMessageData& aData)
|
const ClonedMessageData& aData,
|
||||||
|
const InfallibleTArray<CpowEntry>& aCpows)
|
||||||
{
|
{
|
||||||
nsRefPtr<nsFrameMessageManager> cpm = nsFrameMessageManager::sChildProcessManager;
|
nsRefPtr<nsFrameMessageManager> cpm = nsFrameMessageManager::sChildProcessManager;
|
||||||
if (cpm) {
|
if (cpm) {
|
||||||
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForChild(aData);
|
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForChild(aData);
|
||||||
|
CpowIdHolder cpows(GetCPOWManager(), aCpows);
|
||||||
cpm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(cpm.get()),
|
cpm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(cpm.get()),
|
||||||
aMsg, false, &cloneData, JS::NullPtr(), nullptr);
|
aMsg, false, &cloneData, &cpows, nullptr);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -178,7 +178,8 @@ public:
|
||||||
virtual bool RecvNotifyAlertsObserver(const nsCString& aType, const nsString& aData);
|
virtual bool RecvNotifyAlertsObserver(const nsCString& aType, const nsString& aData);
|
||||||
|
|
||||||
virtual bool RecvAsyncMessage(const nsString& aMsg,
|
virtual bool RecvAsyncMessage(const nsString& aMsg,
|
||||||
const ClonedMessageData& aData);
|
const ClonedMessageData& aData,
|
||||||
|
const InfallibleTArray<CpowEntry>& aCpows);
|
||||||
|
|
||||||
virtual bool RecvGeolocationUpdate(const GeoPosition& somewhere);
|
virtual bool RecvGeolocationUpdate(const GeoPosition& somewhere);
|
||||||
|
|
||||||
|
|
|
@ -868,7 +868,7 @@ ContentParent::ActorDestroy(ActorDestroyReason why)
|
||||||
if (ppm) {
|
if (ppm) {
|
||||||
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()),
|
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()),
|
||||||
CHILD_PROCESS_SHUTDOWN_MESSAGE, false,
|
CHILD_PROCESS_SHUTDOWN_MESSAGE, false,
|
||||||
nullptr, JS::NullPtr(), nullptr);
|
nullptr, nullptr, nullptr);
|
||||||
}
|
}
|
||||||
nsCOMPtr<nsIThreadObserver>
|
nsCOMPtr<nsIThreadObserver>
|
||||||
kungFuDeathGrip(static_cast<nsIThreadObserver*>(this));
|
kungFuDeathGrip(static_cast<nsIThreadObserver*>(this));
|
||||||
|
@ -2308,26 +2308,30 @@ ContentParent::RecvTestPermissionFromPrincipal(const IPC::Principal& aPrincipal,
|
||||||
bool
|
bool
|
||||||
ContentParent::RecvSyncMessage(const nsString& aMsg,
|
ContentParent::RecvSyncMessage(const nsString& aMsg,
|
||||||
const ClonedMessageData& aData,
|
const ClonedMessageData& aData,
|
||||||
|
const InfallibleTArray<CpowEntry>& aCpows,
|
||||||
InfallibleTArray<nsString>* aRetvals)
|
InfallibleTArray<nsString>* aRetvals)
|
||||||
{
|
{
|
||||||
nsRefPtr<nsFrameMessageManager> ppm = mMessageManager;
|
nsRefPtr<nsFrameMessageManager> ppm = mMessageManager;
|
||||||
if (ppm) {
|
if (ppm) {
|
||||||
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
|
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
|
||||||
|
CpowIdHolder cpows(GetCPOWManager(), aCpows);
|
||||||
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()),
|
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()),
|
||||||
aMsg, true, &cloneData, JS::NullPtr(), aRetvals);
|
aMsg, true, &cloneData, &cpows, aRetvals);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ContentParent::RecvAsyncMessage(const nsString& aMsg,
|
ContentParent::RecvAsyncMessage(const nsString& aMsg,
|
||||||
const ClonedMessageData& aData)
|
const ClonedMessageData& aData,
|
||||||
|
const InfallibleTArray<CpowEntry>& aCpows)
|
||||||
{
|
{
|
||||||
nsRefPtr<nsFrameMessageManager> ppm = mMessageManager;
|
nsRefPtr<nsFrameMessageManager> ppm = mMessageManager;
|
||||||
if (ppm) {
|
if (ppm) {
|
||||||
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
|
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
|
||||||
|
CpowIdHolder cpows(GetCPOWManager(), aCpows);
|
||||||
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()),
|
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()),
|
||||||
aMsg, false, &cloneData, JS::NullPtr(), nullptr);
|
aMsg, false, &cloneData, &cpows, nullptr);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -2531,14 +2535,20 @@ ContentParent::RecvPrivateDocShellsExist(const bool& aExist)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ContentParent::DoSendAsyncMessage(const nsAString& aMessage,
|
ContentParent::DoSendAsyncMessage(JSContext* aCx,
|
||||||
const mozilla::dom::StructuredCloneData& aData)
|
const nsAString& aMessage,
|
||||||
|
const mozilla::dom::StructuredCloneData& aData,
|
||||||
|
JS::Handle<JSObject *> aCpows)
|
||||||
{
|
{
|
||||||
ClonedMessageData data;
|
ClonedMessageData data;
|
||||||
if (!BuildClonedMessageDataForParent(this, aData, data)) {
|
if (!BuildClonedMessageDataForParent(this, aData, data)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return SendAsyncMessage(nsString(aMessage), data);
|
InfallibleTArray<CpowEntry> cpows;
|
||||||
|
if (!GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return SendAsyncMessage(nsString(aMessage), data, cpows);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -114,8 +114,10 @@ public:
|
||||||
/**
|
/**
|
||||||
* MessageManagerCallback methods that we override.
|
* MessageManagerCallback methods that we override.
|
||||||
*/
|
*/
|
||||||
virtual bool DoSendAsyncMessage(const nsAString& aMessage,
|
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||||
const mozilla::dom::StructuredCloneData& aData) MOZ_OVERRIDE;
|
const nsAString& aMessage,
|
||||||
|
const mozilla::dom::StructuredCloneData& aData,
|
||||||
|
JS::Handle<JSObject *> aCpows) MOZ_OVERRIDE;
|
||||||
virtual bool CheckPermission(const nsAString& aPermission) MOZ_OVERRIDE;
|
virtual bool CheckPermission(const nsAString& aPermission) MOZ_OVERRIDE;
|
||||||
virtual bool CheckManifestURL(const nsAString& aManifestURL) MOZ_OVERRIDE;
|
virtual bool CheckManifestURL(const nsAString& aManifestURL) MOZ_OVERRIDE;
|
||||||
virtual bool CheckAppHasPermission(const nsAString& aPermission) MOZ_OVERRIDE;
|
virtual bool CheckAppHasPermission(const nsAString& aPermission) MOZ_OVERRIDE;
|
||||||
|
@ -199,7 +201,6 @@ private:
|
||||||
// using them.
|
// using them.
|
||||||
using PContentParent::SendPBrowserConstructor;
|
using PContentParent::SendPBrowserConstructor;
|
||||||
using PContentParent::SendPTestShellConstructor;
|
using PContentParent::SendPTestShellConstructor;
|
||||||
using PContentParent::SendPJavaScriptConstructor;
|
|
||||||
|
|
||||||
// No more than one of !!aApp, aIsForBrowser, and aIsForPreallocated may be
|
// No more than one of !!aApp, aIsForBrowser, and aIsForPreallocated may be
|
||||||
// true.
|
// true.
|
||||||
|
@ -372,9 +373,11 @@ private:
|
||||||
|
|
||||||
virtual bool RecvSyncMessage(const nsString& aMsg,
|
virtual bool RecvSyncMessage(const nsString& aMsg,
|
||||||
const ClonedMessageData& aData,
|
const ClonedMessageData& aData,
|
||||||
|
const InfallibleTArray<CpowEntry>& aCpows,
|
||||||
InfallibleTArray<nsString>* aRetvals);
|
InfallibleTArray<nsString>* aRetvals);
|
||||||
virtual bool RecvAsyncMessage(const nsString& aMsg,
|
virtual bool RecvAsyncMessage(const nsString& aMsg,
|
||||||
const ClonedMessageData& aData);
|
const ClonedMessageData& aData,
|
||||||
|
const InfallibleTArray<CpowEntry>& aCpows);
|
||||||
|
|
||||||
virtual bool RecvFilePathUpdateNotify(const nsString& aType,
|
virtual bool RecvFilePathUpdateNotify(const nsString& aType,
|
||||||
const nsString& aStorageName,
|
const nsString& aStorageName,
|
||||||
|
|
|
@ -14,6 +14,7 @@ include protocol PRenderFrame;
|
||||||
include protocol POfflineCacheUpdate;
|
include protocol POfflineCacheUpdate;
|
||||||
include protocol PIndexedDB;
|
include protocol PIndexedDB;
|
||||||
include DOMTypes;
|
include DOMTypes;
|
||||||
|
include JavaScriptTypes;
|
||||||
include URIParams;
|
include URIParams;
|
||||||
|
|
||||||
include "gfxMatrix.h";
|
include "gfxMatrix.h";
|
||||||
|
@ -67,7 +68,7 @@ rpc protocol PBrowser
|
||||||
manages PIndexedDB;
|
manages PIndexedDB;
|
||||||
|
|
||||||
both:
|
both:
|
||||||
AsyncMessage(nsString aMessage, ClonedMessageData aData);
|
AsyncMessage(nsString aMessage, ClonedMessageData aData, CpowEntry[] aCpows);
|
||||||
|
|
||||||
parent:
|
parent:
|
||||||
/**
|
/**
|
||||||
|
@ -80,7 +81,7 @@ parent:
|
||||||
|
|
||||||
rpc CreateWindow() returns (PBrowser window);
|
rpc CreateWindow() returns (PBrowser window);
|
||||||
|
|
||||||
sync SyncMessage(nsString aMessage, ClonedMessageData aData)
|
sync SyncMessage(nsString aMessage, ClonedMessageData aData, CpowEntry[] aCpows)
|
||||||
returns (nsString[] retval);
|
returns (nsString[] retval);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -22,6 +22,7 @@ include protocol PStorage;
|
||||||
include protocol PTestShell;
|
include protocol PTestShell;
|
||||||
include protocol PJavaScript;
|
include protocol PJavaScript;
|
||||||
include DOMTypes;
|
include DOMTypes;
|
||||||
|
include JavaScriptTypes;
|
||||||
include InputStreamParams;
|
include InputStreamParams;
|
||||||
include PTabContext;
|
include PTabContext;
|
||||||
include URIParams;
|
include URIParams;
|
||||||
|
@ -190,7 +191,7 @@ both:
|
||||||
|
|
||||||
async PBlob(BlobConstructorParams params);
|
async PBlob(BlobConstructorParams params);
|
||||||
|
|
||||||
PJavaScript();
|
async PJavaScript();
|
||||||
|
|
||||||
child:
|
child:
|
||||||
/**
|
/**
|
||||||
|
@ -329,7 +330,7 @@ parent:
|
||||||
|
|
||||||
sync ReadFontList() returns (FontListEntry[] retValue);
|
sync ReadFontList() returns (FontListEntry[] retValue);
|
||||||
|
|
||||||
sync SyncMessage(nsString aMessage, ClonedMessageData aData)
|
sync SyncMessage(nsString aMessage, ClonedMessageData aData, CpowEntry[] aCpows)
|
||||||
returns (nsString[] retval);
|
returns (nsString[] retval);
|
||||||
|
|
||||||
ShowAlertNotification(nsString imageUrl,
|
ShowAlertNotification(nsString imageUrl,
|
||||||
|
@ -427,7 +428,7 @@ parent:
|
||||||
async SetFakeVolumeState(nsString fsName, int32_t fsState);
|
async SetFakeVolumeState(nsString fsName, int32_t fsState);
|
||||||
|
|
||||||
both:
|
both:
|
||||||
AsyncMessage(nsString aMessage, ClonedMessageData aData);
|
AsyncMessage(nsString aMessage, ClonedMessageData aData, CpowEntry[] aCpows);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,6 +84,7 @@
|
||||||
#include "StructuredCloneUtils.h"
|
#include "StructuredCloneUtils.h"
|
||||||
#include "xpcpublic.h"
|
#include "xpcpublic.h"
|
||||||
#include "nsViewportInfo.h"
|
#include "nsViewportInfo.h"
|
||||||
|
#include "JavaScriptChild.h"
|
||||||
|
|
||||||
#define BROWSER_ELEMENT_CHILD_SCRIPT \
|
#define BROWSER_ELEMENT_CHILD_SCRIPT \
|
||||||
NS_LITERAL_STRING("chrome://global/content/BrowserElementChild.js")
|
NS_LITERAL_STRING("chrome://global/content/BrowserElementChild.js")
|
||||||
|
@ -97,6 +98,7 @@ using namespace mozilla::layout;
|
||||||
using namespace mozilla::docshell;
|
using namespace mozilla::docshell;
|
||||||
using namespace mozilla::dom::indexedDB;
|
using namespace mozilla::dom::indexedDB;
|
||||||
using namespace mozilla::widget;
|
using namespace mozilla::widget;
|
||||||
|
using namespace mozilla::jsipc;
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS1(ContentListener, nsIDOMEventListener)
|
NS_IMPL_ISUPPORTS1(ContentListener, nsIDOMEventListener)
|
||||||
|
|
||||||
|
@ -1454,7 +1456,7 @@ TabChild::DispatchMessageManagerMessage(const nsAString& aMessageName,
|
||||||
nsRefPtr<nsFrameMessageManager> mm =
|
nsRefPtr<nsFrameMessageManager> mm =
|
||||||
static_cast<nsFrameMessageManager*>(mTabChildGlobal->mMessageManager.get());
|
static_cast<nsFrameMessageManager*>(mTabChildGlobal->mMessageManager.get());
|
||||||
mm->ReceiveMessage(static_cast<EventTarget*>(mTabChildGlobal),
|
mm->ReceiveMessage(static_cast<EventTarget*>(mTabChildGlobal),
|
||||||
aMessageName, false, &cloneData, JS::NullPtr(), nullptr);
|
aMessageName, false, &cloneData, nullptr, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -2030,15 +2032,17 @@ TabChild::RecvLoadRemoteScript(const nsString& aURL)
|
||||||
|
|
||||||
bool
|
bool
|
||||||
TabChild::RecvAsyncMessage(const nsString& aMessage,
|
TabChild::RecvAsyncMessage(const nsString& aMessage,
|
||||||
const ClonedMessageData& aData)
|
const ClonedMessageData& aData,
|
||||||
|
const InfallibleTArray<CpowEntry>& aCpows)
|
||||||
{
|
{
|
||||||
if (mTabChildGlobal) {
|
if (mTabChildGlobal) {
|
||||||
nsCOMPtr<nsIXPConnectJSObjectHolder> kungFuDeathGrip(GetGlobal());
|
nsCOMPtr<nsIXPConnectJSObjectHolder> kungFuDeathGrip(GetGlobal());
|
||||||
StructuredCloneData cloneData = UnpackClonedMessageDataForChild(aData);
|
StructuredCloneData cloneData = UnpackClonedMessageDataForChild(aData);
|
||||||
nsRefPtr<nsFrameMessageManager> mm =
|
nsRefPtr<nsFrameMessageManager> mm =
|
||||||
static_cast<nsFrameMessageManager*>(mTabChildGlobal->mMessageManager.get());
|
static_cast<nsFrameMessageManager*>(mTabChildGlobal->mMessageManager.get());
|
||||||
|
CpowIdHolder cpows(static_cast<ContentChild*>(Manager())->GetCPOWManager(), aCpows);
|
||||||
mm->ReceiveMessage(static_cast<EventTarget*>(mTabChildGlobal),
|
mm->ReceiveMessage(static_cast<EventTarget*>(mTabChildGlobal),
|
||||||
aMessage, false, &cloneData, JS::NullPtr(), nullptr);
|
aMessage, false, &cloneData, &cpows, nullptr);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -2332,8 +2336,10 @@ TabChild::DeallocPIndexedDBChild(PIndexedDBChild* aActor)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
TabChild::DoSendSyncMessage(const nsAString& aMessage,
|
TabChild::DoSendSyncMessage(JSContext* aCx,
|
||||||
|
const nsAString& aMessage,
|
||||||
const StructuredCloneData& aData,
|
const StructuredCloneData& aData,
|
||||||
|
JS::Handle<JSObject *> aCpows,
|
||||||
InfallibleTArray<nsString>* aJSONRetVal)
|
InfallibleTArray<nsString>* aJSONRetVal)
|
||||||
{
|
{
|
||||||
ContentChild* cc = Manager();
|
ContentChild* cc = Manager();
|
||||||
|
@ -2341,19 +2347,29 @@ TabChild::DoSendSyncMessage(const nsAString& aMessage,
|
||||||
if (!BuildClonedMessageDataForChild(cc, aData, data)) {
|
if (!BuildClonedMessageDataForChild(cc, aData, data)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return SendSyncMessage(nsString(aMessage), data, aJSONRetVal);
|
InfallibleTArray<CpowEntry> cpows;
|
||||||
|
if (!cc->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return SendSyncMessage(nsString(aMessage), data, cpows, aJSONRetVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
TabChild::DoSendAsyncMessage(const nsAString& aMessage,
|
TabChild::DoSendAsyncMessage(JSContext* aCx,
|
||||||
const StructuredCloneData& aData)
|
const nsAString& aMessage,
|
||||||
|
const StructuredCloneData& aData,
|
||||||
|
JS::Handle<JSObject *> aCpows)
|
||||||
{
|
{
|
||||||
ContentChild* cc = Manager();
|
ContentChild* cc = Manager();
|
||||||
ClonedMessageData data;
|
ClonedMessageData data;
|
||||||
if (!BuildClonedMessageDataForChild(cc, aData, data)) {
|
if (!BuildClonedMessageDataForChild(cc, aData, data)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return SendAsyncMessage(nsString(aMessage), data);
|
InfallibleTArray<CpowEntry> cpows;
|
||||||
|
if (!cc->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return SendAsyncMessage(nsString(aMessage), data, cpows);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -78,12 +78,13 @@ public:
|
||||||
NS_FORWARD_SAFE_NSIMESSAGESENDER(mMessageManager)
|
NS_FORWARD_SAFE_NSIMESSAGESENDER(mMessageManager)
|
||||||
NS_IMETHOD SendSyncMessage(const nsAString& aMessageName,
|
NS_IMETHOD SendSyncMessage(const nsAString& aMessageName,
|
||||||
const JS::Value& aObject,
|
const JS::Value& aObject,
|
||||||
|
const JS::Value& aRemote,
|
||||||
JSContext* aCx,
|
JSContext* aCx,
|
||||||
uint8_t aArgc,
|
uint8_t aArgc,
|
||||||
JS::Value* aRetval)
|
JS::Value* aRetval)
|
||||||
{
|
{
|
||||||
return mMessageManager
|
return mMessageManager
|
||||||
? mMessageManager->SendSyncMessage(aMessageName, aObject, aCx, aArgc, aRetval)
|
? mMessageManager->SendSyncMessage(aMessageName, aObject, aRemote, aCx, aArgc, aRetval)
|
||||||
: NS_ERROR_NULL_POINTER;
|
: NS_ERROR_NULL_POINTER;
|
||||||
}
|
}
|
||||||
NS_IMETHOD GetContent(nsIDOMWindow** aContent) MOZ_OVERRIDE;
|
NS_IMETHOD GetContent(nsIDOMWindow** aContent) MOZ_OVERRIDE;
|
||||||
|
@ -187,11 +188,15 @@ public:
|
||||||
/**
|
/**
|
||||||
* MessageManagerCallback methods that we override.
|
* MessageManagerCallback methods that we override.
|
||||||
*/
|
*/
|
||||||
virtual bool DoSendSyncMessage(const nsAString& aMessage,
|
virtual bool DoSendSyncMessage(JSContext* aCx,
|
||||||
|
const nsAString& aMessage,
|
||||||
const mozilla::dom::StructuredCloneData& aData,
|
const mozilla::dom::StructuredCloneData& aData,
|
||||||
|
JS::Handle<JSObject *> aCpows,
|
||||||
InfallibleTArray<nsString>* aJSONRetVal);
|
InfallibleTArray<nsString>* aJSONRetVal);
|
||||||
virtual bool DoSendAsyncMessage(const nsAString& aMessage,
|
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||||
const mozilla::dom::StructuredCloneData& aData);
|
const nsAString& aMessage,
|
||||||
|
const mozilla::dom::StructuredCloneData& aData,
|
||||||
|
JS::Handle<JSObject *> aCpows);
|
||||||
|
|
||||||
virtual bool RecvLoadURL(const nsCString& uri);
|
virtual bool RecvLoadURL(const nsCString& uri);
|
||||||
virtual bool RecvCacheFileDescriptor(const nsString& aPath,
|
virtual bool RecvCacheFileDescriptor(const nsString& aPath,
|
||||||
|
@ -228,7 +233,8 @@ public:
|
||||||
virtual bool RecvActivateFrameEvent(const nsString& aType, const bool& capture);
|
virtual bool RecvActivateFrameEvent(const nsString& aType, const bool& capture);
|
||||||
virtual bool RecvLoadRemoteScript(const nsString& aURL);
|
virtual bool RecvLoadRemoteScript(const nsString& aURL);
|
||||||
virtual bool RecvAsyncMessage(const nsString& aMessage,
|
virtual bool RecvAsyncMessage(const nsString& aMessage,
|
||||||
const ClonedMessageData& aData);
|
const ClonedMessageData& aData,
|
||||||
|
const InfallibleTArray<CpowEntry>& aCpows);
|
||||||
|
|
||||||
virtual PDocumentRendererChild*
|
virtual PDocumentRendererChild*
|
||||||
AllocPDocumentRendererChild(const nsRect& documentRect, const gfxMatrix& transform,
|
AllocPDocumentRendererChild(const nsRect& documentRect, const gfxMatrix& transform,
|
||||||
|
|
|
@ -52,6 +52,7 @@
|
||||||
#include "nsThreadUtils.h"
|
#include "nsThreadUtils.h"
|
||||||
#include "private/pprio.h"
|
#include "private/pprio.h"
|
||||||
#include "StructuredCloneUtils.h"
|
#include "StructuredCloneUtils.h"
|
||||||
|
#include "JavaScriptParent.h"
|
||||||
#include "TabChild.h"
|
#include "TabChild.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
@ -62,6 +63,7 @@ using namespace mozilla::layout;
|
||||||
using namespace mozilla::services;
|
using namespace mozilla::services;
|
||||||
using namespace mozilla::widget;
|
using namespace mozilla::widget;
|
||||||
using namespace mozilla::dom::indexedDB;
|
using namespace mozilla::dom::indexedDB;
|
||||||
|
using namespace mozilla::jsipc;
|
||||||
|
|
||||||
// The flags passed by the webProgress notifications are 16 bits shifted
|
// The flags passed by the webProgress notifications are 16 bits shifted
|
||||||
// from the ones registered by webProgressListeners.
|
// from the ones registered by webProgressListeners.
|
||||||
|
@ -708,18 +710,22 @@ TabParent::TryCapture(const nsGUIEvent& aEvent)
|
||||||
bool
|
bool
|
||||||
TabParent::RecvSyncMessage(const nsString& aMessage,
|
TabParent::RecvSyncMessage(const nsString& aMessage,
|
||||||
const ClonedMessageData& aData,
|
const ClonedMessageData& aData,
|
||||||
|
const InfallibleTArray<CpowEntry>& aCpows,
|
||||||
InfallibleTArray<nsString>* aJSONRetVal)
|
InfallibleTArray<nsString>* aJSONRetVal)
|
||||||
{
|
{
|
||||||
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
|
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
|
||||||
return ReceiveMessage(aMessage, true, &cloneData, aJSONRetVal);
|
CpowIdHolder cpows(static_cast<ContentParent*>(Manager())->GetCPOWManager(), aCpows);
|
||||||
|
return ReceiveMessage(aMessage, true, &cloneData, &cpows, aJSONRetVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
TabParent::RecvAsyncMessage(const nsString& aMessage,
|
TabParent::RecvAsyncMessage(const nsString& aMessage,
|
||||||
const ClonedMessageData& aData)
|
const ClonedMessageData& aData,
|
||||||
|
const InfallibleTArray<CpowEntry>& aCpows)
|
||||||
{
|
{
|
||||||
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
|
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
|
||||||
return ReceiveMessage(aMessage, false, &cloneData, nullptr);
|
CpowIdHolder cpows(static_cast<ContentParent*>(Manager())->GetCPOWManager(), aCpows);
|
||||||
|
return ReceiveMessage(aMessage, false, &cloneData, &cpows, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -1084,26 +1090,19 @@ bool
|
||||||
TabParent::ReceiveMessage(const nsString& aMessage,
|
TabParent::ReceiveMessage(const nsString& aMessage,
|
||||||
bool aSync,
|
bool aSync,
|
||||||
const StructuredCloneData* aCloneData,
|
const StructuredCloneData* aCloneData,
|
||||||
|
CpowHolder* aCpows,
|
||||||
InfallibleTArray<nsString>* aJSONRetVal)
|
InfallibleTArray<nsString>* aJSONRetVal)
|
||||||
{
|
{
|
||||||
nsRefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
|
nsRefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
|
||||||
if (frameLoader && frameLoader->GetFrameMessageManager()) {
|
if (frameLoader && frameLoader->GetFrameMessageManager()) {
|
||||||
nsRefPtr<nsFrameMessageManager> manager =
|
nsRefPtr<nsFrameMessageManager> manager =
|
||||||
frameLoader->GetFrameMessageManager();
|
frameLoader->GetFrameMessageManager();
|
||||||
AutoSafeJSContext ctx;
|
|
||||||
uint32_t len = 0; //TODO: obtain a real value in bug 572685
|
|
||||||
// Because we want JS messages to have always the same properties,
|
|
||||||
// create array even if len == 0.
|
|
||||||
JS::Rooted<JSObject*> objectsArray(ctx, JS_NewArrayObject(ctx, len, NULL));
|
|
||||||
if (!objectsArray) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
manager->ReceiveMessage(mFrameElement,
|
manager->ReceiveMessage(mFrameElement,
|
||||||
aMessage,
|
aMessage,
|
||||||
aSync,
|
aSync,
|
||||||
aCloneData,
|
aCloneData,
|
||||||
objectsArray,
|
aCpows,
|
||||||
aJSONRetVal);
|
aJSONRetVal);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -30,6 +30,7 @@ class mozIApplication;
|
||||||
class nsFrameLoader;
|
class nsFrameLoader;
|
||||||
class nsIDOMElement;
|
class nsIDOMElement;
|
||||||
class nsIURI;
|
class nsIURI;
|
||||||
|
class CpowHolder;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
|
@ -122,9 +123,11 @@ public:
|
||||||
virtual bool AnswerCreateWindow(PBrowserParent** retval);
|
virtual bool AnswerCreateWindow(PBrowserParent** retval);
|
||||||
virtual bool RecvSyncMessage(const nsString& aMessage,
|
virtual bool RecvSyncMessage(const nsString& aMessage,
|
||||||
const ClonedMessageData& aData,
|
const ClonedMessageData& aData,
|
||||||
|
const InfallibleTArray<CpowEntry>& aCpows,
|
||||||
InfallibleTArray<nsString>* aJSONRetVal);
|
InfallibleTArray<nsString>* aJSONRetVal);
|
||||||
virtual bool RecvAsyncMessage(const nsString& aMessage,
|
virtual bool RecvAsyncMessage(const nsString& aMessage,
|
||||||
const ClonedMessageData& aData);
|
const ClonedMessageData& aData,
|
||||||
|
const InfallibleTArray<CpowEntry>& aCpows);
|
||||||
virtual bool RecvNotifyIMEFocus(const bool& aFocus,
|
virtual bool RecvNotifyIMEFocus(const bool& aFocus,
|
||||||
nsIMEUpdatePreference* aPreference,
|
nsIMEUpdatePreference* aPreference,
|
||||||
uint32_t* aSeqno);
|
uint32_t* aSeqno);
|
||||||
|
@ -233,6 +236,7 @@ protected:
|
||||||
bool ReceiveMessage(const nsString& aMessage,
|
bool ReceiveMessage(const nsString& aMessage,
|
||||||
bool aSync,
|
bool aSync,
|
||||||
const StructuredCloneData* aCloneData,
|
const StructuredCloneData* aCloneData,
|
||||||
|
CpowHolder* aCpows,
|
||||||
InfallibleTArray<nsString>* aJSONRetVal = nullptr);
|
InfallibleTArray<nsString>* aJSONRetVal = nullptr);
|
||||||
|
|
||||||
virtual bool Recv__delete__() MOZ_OVERRIDE;
|
virtual bool Recv__delete__() MOZ_OVERRIDE;
|
||||||
|
|
|
@ -197,6 +197,10 @@ JavaScriptChild::AnswerGet(const ObjectId &objId, const ObjectId &receiverId,
|
||||||
AutoSafeJSContext cx;
|
AutoSafeJSContext cx;
|
||||||
JSAutoRequest request(cx);
|
JSAutoRequest request(cx);
|
||||||
|
|
||||||
|
// The outparam will be written to the buffer, so it must be set even if
|
||||||
|
// the parent won't read it.
|
||||||
|
*result = void_t();
|
||||||
|
|
||||||
RootedObject obj(cx, findObject(objId));
|
RootedObject obj(cx, findObject(objId));
|
||||||
if (!obj)
|
if (!obj)
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -455,14 +455,11 @@ CPOWProxyHandler::finalize(JSFreeOp *fop, JSObject *proxy)
|
||||||
void
|
void
|
||||||
JavaScriptParent::drop(JSObject *obj)
|
JavaScriptParent::drop(JSObject *obj)
|
||||||
{
|
{
|
||||||
if (inactive_)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ObjectId objId = idOf(obj);
|
ObjectId objId = idOf(obj);
|
||||||
|
|
||||||
objects_.remove(objId);
|
objects_.remove(objId);
|
||||||
if (!SendDropObject(objId))
|
if (!inactive_ && !SendDropObject(objId))
|
||||||
MOZ_CRASH();
|
(void)0;
|
||||||
decref();
|
decref();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -395,3 +395,78 @@ JavaScriptShared::toDescriptor(JSContext *cx, const PPropertyDescriptor &in, JSP
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CpowIdHolder::ToObject(JSContext *cx, JSObject **objp)
|
||||||
|
{
|
||||||
|
return js_->Unwrap(cx, cpows_, objp);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
JavaScriptShared::Unwrap(JSContext *cx, const InfallibleTArray<CpowEntry> &aCpows, JSObject **objp)
|
||||||
|
{
|
||||||
|
*objp = NULL;
|
||||||
|
|
||||||
|
if (!aCpows.Length())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
RootedObject obj(cx, JS_NewObject(cx, NULL, NULL, NULL));
|
||||||
|
if (!obj)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
RootedValue v(cx);
|
||||||
|
RootedString str(cx);
|
||||||
|
for (size_t i = 0; i < aCpows.Length(); i++) {
|
||||||
|
const nsString &name = aCpows[i].name();
|
||||||
|
|
||||||
|
if (!toValue(cx, aCpows[i].value(), &v))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!JS_DefineUCProperty(cx,
|
||||||
|
obj,
|
||||||
|
name.BeginReading(),
|
||||||
|
name.Length(),
|
||||||
|
v,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
JSPROP_ENUMERATE))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*objp = obj;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
JavaScriptShared::Wrap(JSContext *cx, HandleObject aObj, InfallibleTArray<CpowEntry> *outCpows)
|
||||||
|
{
|
||||||
|
if (!aObj)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
AutoIdArray ids(cx, JS_Enumerate(cx, aObj));
|
||||||
|
if (!ids)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
RootedId id(cx);
|
||||||
|
RootedValue v(cx);
|
||||||
|
for (size_t i = 0; i < ids.length(); i++) {
|
||||||
|
id = ids[i];
|
||||||
|
|
||||||
|
nsString str;
|
||||||
|
if (!convertIdToGeckoString(cx, id, &str))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!JS_GetPropertyById(cx, aObj, id, v.address()))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
JSVariant var;
|
||||||
|
if (!toVariant(cx, v, &var))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
outCpows->AppendElement(CpowEntry(str, var));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,24 @@ namespace jsipc {
|
||||||
|
|
||||||
typedef uint64_t ObjectId;
|
typedef uint64_t ObjectId;
|
||||||
|
|
||||||
|
class JavaScriptShared;
|
||||||
|
|
||||||
|
class CpowIdHolder : public CpowHolder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CpowIdHolder(JavaScriptShared *js, const InfallibleTArray<CpowEntry> &cpows)
|
||||||
|
: js_(js),
|
||||||
|
cpows_(cpows)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ToObject(JSContext *cx, JSObject **objp);
|
||||||
|
|
||||||
|
private:
|
||||||
|
JavaScriptShared *js_;
|
||||||
|
const InfallibleTArray<CpowEntry> &cpows_;
|
||||||
|
};
|
||||||
|
|
||||||
// Map ids -> JSObjects
|
// Map ids -> JSObjects
|
||||||
class ObjectStore
|
class ObjectStore
|
||||||
{
|
{
|
||||||
|
@ -70,6 +88,9 @@ class JavaScriptShared
|
||||||
static const uint32_t OBJECT_EXTRA_BITS = 1;
|
static const uint32_t OBJECT_EXTRA_BITS = 1;
|
||||||
static const uint32_t OBJECT_IS_CALLABLE = (1 << 0);
|
static const uint32_t OBJECT_IS_CALLABLE = (1 << 0);
|
||||||
|
|
||||||
|
bool Unwrap(JSContext *cx, const InfallibleTArray<CpowEntry> &aCpows, JSObject **objp);
|
||||||
|
bool Wrap(JSContext *cx, JS::HandleObject aObj, InfallibleTArray<CpowEntry> *outCpows);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool toVariant(JSContext *cx, jsval from, JSVariant *to);
|
bool toVariant(JSContext *cx, jsval from, JSVariant *to);
|
||||||
bool toValue(JSContext *cx, const JSVariant &from, JS::MutableHandleValue to);
|
bool toValue(JSContext *cx, const JSVariant &from, JS::MutableHandleValue to);
|
||||||
|
|
|
@ -139,6 +139,12 @@ js_ObjectClassIs(JSContext *cx, JS::HandleObject obj, js::ESClassValue classValu
|
||||||
JS_FRIEND_API(const char *)
|
JS_FRIEND_API(const char *)
|
||||||
js_ObjectClassName(JSContext *cx, JS::HandleObject obj);
|
js_ObjectClassName(JSContext *cx, JS::HandleObject obj);
|
||||||
|
|
||||||
|
JS_FRIEND_API(bool)
|
||||||
|
js_AddObjectRoot(JSRuntime *rt, JSObject **objp);
|
||||||
|
|
||||||
|
JS_FRIEND_API(void)
|
||||||
|
js_RemoveObjectRoot(JSRuntime *rt, JSObject **objp);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1084,6 +1084,18 @@ js::AddScriptRoot(JSContext *cx, JSScript **rp, const char *name)
|
||||||
return AddRoot(cx, rp, name, JS_GC_ROOT_SCRIPT_PTR);
|
return AddRoot(cx, rp, name, JS_GC_ROOT_SCRIPT_PTR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern JS_FRIEND_API(bool)
|
||||||
|
js_AddObjectRoot(JSRuntime *rt, JSObject **objp)
|
||||||
|
{
|
||||||
|
return AddRoot(rt, objp, NULL, JS_GC_ROOT_OBJECT_PTR);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern JS_FRIEND_API(void)
|
||||||
|
js_RemoveObjectRoot(JSRuntime *rt, JSObject **objp)
|
||||||
|
{
|
||||||
|
js_RemoveRoot(rt, objp);
|
||||||
|
}
|
||||||
|
|
||||||
JS_FRIEND_API(void)
|
JS_FRIEND_API(void)
|
||||||
js_RemoveRoot(JSRuntime *rt, void *rp)
|
js_RemoveRoot(JSRuntime *rt, void *rp)
|
||||||
{
|
{
|
||||||
|
|
Загрузка…
Ссылка в новой задаче