Bug 1155224 - Add targetFrameLoader property to messages (r=smaug)

This commit is contained in:
Bill McCloskey 2015-04-16 08:17:54 -07:00
parent bf70f01467
commit 7303c795ef
15 changed files with 112 additions and 21 deletions

View File

@ -1389,6 +1389,9 @@ nsFrameLoader::StartDestroy()
if (mRemoteBrowser) {
mRemoteBrowser->CacheFrameLoader(this);
}
if (mChildMessageManager) {
mChildMessageManager->CacheFrameLoader(this);
}
}
// If the TabParent has installed any event listeners on the window, this is
@ -1532,6 +1535,9 @@ nsFrameLoader::DestroyComplete()
if (mRemoteBrowser) {
mRemoteBrowser->CacheFrameLoader(nullptr);
}
if (mChildMessageManager) {
mChildMessageManager->CacheFrameLoader(nullptr);
}
}
// Call TabParent::Destroy if we haven't already (in case of a crash).
@ -2443,7 +2449,7 @@ public:
static_cast<nsInProcessTabChildGlobal*>(mFrameLoader->mChildMessageManager.get());
if (tabChild && tabChild->GetInnerManager()) {
nsCOMPtr<nsIXPConnectJSObjectHolder> kungFuDeathGrip(tabChild->GetGlobal());
ReceiveMessage(static_cast<EventTarget*>(tabChild),
ReceiveMessage(static_cast<EventTarget*>(tabChild), mFrameLoader,
tabChild->GetInnerManager());
}
return NS_OK;

View File

@ -995,6 +995,7 @@ public:
nsresult
nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
nsIFrameLoader* aTargetFrameLoader,
const nsAString& aMessage,
bool aIsSync,
const StructuredCloneData* aCloneData,
@ -1002,12 +1003,13 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
nsIPrincipal* aPrincipal,
InfallibleTArray<nsString>* aJSONRetVal)
{
return ReceiveMessage(aTarget, mClosed, aMessage, aIsSync,
return ReceiveMessage(aTarget, aTargetFrameLoader, mClosed, aMessage, aIsSync,
aCloneData, aCpows, aPrincipal, aJSONRetVal);
}
nsresult
nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
nsIFrameLoader* aTargetFrameLoader,
bool aTargetClosed,
const nsAString& aMessage,
bool aIsSync,
@ -1114,6 +1116,16 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
JS_DefineProperty(cx, param, "objects", cpowsv, JSPROP_ENUMERATE);
NS_ENSURE_TRUE(ok, NS_ERROR_UNEXPECTED);
if (aTargetFrameLoader) {
JS::Rooted<JS::Value> targetFrameLoaderv(cx);
nsresult rv = nsContentUtils::WrapNative(cx, aTargetFrameLoader, &targetFrameLoaderv);
NS_ENSURE_SUCCESS(rv, rv);
ok = JS_DefineProperty(cx, param, "targetFrameLoader", targetFrameLoaderv,
JSPROP_ENUMERATE);
NS_ENSURE_TRUE(ok, NS_ERROR_UNEXPECTED);
}
// message.principal == null
if (!aPrincipal) {
bool ok = JS_DefineProperty(cx, param, "principal",
@ -1190,7 +1202,8 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
}
}
nsRefPtr<nsFrameMessageManager> kungfuDeathGrip = mParentManager;
return mParentManager ? mParentManager->ReceiveMessage(aTarget, aTargetClosed, aMessage,
return mParentManager ? mParentManager->ReceiveMessage(aTarget, aTargetFrameLoader,
aTargetClosed, aMessage,
aIsSync, aCloneData,
aCpows, aPrincipal,
aJSONRetVal) : NS_OK;
@ -1769,7 +1782,7 @@ public:
NS_IMETHOD Run()
{
nsFrameMessageManager* ppm = nsFrameMessageManager::GetChildProcessManager();
ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm), ppm);
ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm), nullptr, ppm);
return NS_OK;
}
};
@ -1924,7 +1937,7 @@ public:
virtual nsresult HandleMessage() override
{
nsFrameMessageManager* ppm = nsFrameMessageManager::sSameProcessParentManager;
ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm), ppm);
ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm), nullptr, ppm);
return NS_OK;
}
};
@ -1958,7 +1971,7 @@ public:
if (nsFrameMessageManager::sSameProcessParentManager) {
SameProcessCpowHolder cpows(js::GetRuntime(aCx), aCpows);
nsRefPtr<nsFrameMessageManager> ppm = nsFrameMessageManager::sSameProcessParentManager;
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()), aMessage,
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()), nullptr, aMessage,
true, &aData, &cpows, aPrincipal, aJSONRetVal);
}
return true;
@ -2089,6 +2102,7 @@ nsSameProcessAsyncMessageBase::nsSameProcessAsyncMessageBase(JSContext* aCx,
void
nsSameProcessAsyncMessageBase::ReceiveMessage(nsISupports* aTarget,
nsIFrameLoader* aTargetFrameLoader,
nsFrameMessageManager* aManager)
{
if (aManager) {
@ -2100,7 +2114,7 @@ nsSameProcessAsyncMessageBase::ReceiveMessage(nsISupports* aTarget,
SameProcessCpowHolder cpows(mRuntime, mCpows);
nsRefPtr<nsFrameMessageManager> mm = aManager;
mm->ReceiveMessage(aTarget, mMessage, false, &data, &cpows,
mm->ReceiveMessage(aTarget, aTargetFrameLoader, mMessage, false, &data, &cpows,
mPrincipal, nullptr);
}
}

View File

@ -31,6 +31,8 @@
#include "mozilla/dom/StructuredCloneUtils.h"
#include "mozilla/jsipc/CpowHolder.h"
class nsIFrameLoader;
namespace mozilla {
namespace dom {
@ -229,7 +231,8 @@ public:
static nsFrameMessageManager*
NewProcessMessageManager(bool aIsRemote);
nsresult ReceiveMessage(nsISupports* aTarget, const nsAString& aMessage,
nsresult ReceiveMessage(nsISupports* aTarget, nsIFrameLoader* aTargetFrameLoader,
const nsAString& aMessage,
bool aIsSync, const StructuredCloneData* aCloneData,
mozilla::jsipc::CpowHolder* aCpows, nsIPrincipal* aPrincipal,
InfallibleTArray<nsString>* aJSONRetVal);
@ -293,7 +296,8 @@ private:
JS::MutableHandle<JS::Value> aRetval,
bool aIsSync);
nsresult ReceiveMessage(nsISupports* aTarget, bool aTargetClosed, const nsAString& aMessage,
nsresult ReceiveMessage(nsISupports* aTarget, nsIFrameLoader* aTargetFrameLoader,
bool aTargetClosed, const nsAString& aMessage,
bool aIsSync, const StructuredCloneData* aCloneData,
mozilla::jsipc::CpowHolder* aCpows, nsIPrincipal* aPrincipal,
InfallibleTArray<nsString>* aJSONRetVal);
@ -369,7 +373,8 @@ public:
JS::Handle<JSObject*> aCpows,
nsIPrincipal* aPrincipal);
void ReceiveMessage(nsISupports* aTarget, nsFrameMessageManager* aManager);
void ReceiveMessage(nsISupports* aTarget, nsIFrameLoader* aTargetFrameLoader,
nsFrameMessageManager* aManager);
private:
nsSameProcessAsyncMessageBase(const nsSameProcessAsyncMessageBase&);

View File

@ -8,6 +8,7 @@
interface nsIDOMWindow;
interface nsIDocShell;
interface nsIContent;
interface nsIFrameLoader;
interface nsIPrincipal;
/**
@ -383,10 +384,11 @@ interface nsIContentFrameMessageManager : nsIMessageManagerGlobal
readonly attribute nsIDocShell docShell;
};
[uuid(a9e07e89-7125-48e3-bf73-2cbae7fc5b1c)]
[uuid(9c6bd4d7-88d2-46d6-8606-f2d57d46f051)]
interface nsIInProcessContentFrameMessageManager : nsIContentFrameMessageManager
{
[notxpcom] nsIContent getOwnerContent();
[notxpcom] void cacheFrameLoader(in nsIFrameLoader aFrameLoader);
};
[scriptable, builtinclass, uuid(d0c799a2-d5ff-4a75-acbb-b8c8347944a6)]

View File

@ -42,7 +42,8 @@ nsInProcessTabChildGlobal::DoSendBlockingMessage(JSContext* aCx,
if (mChromeMessageManager) {
SameProcessCpowHolder cpows(js::GetRuntime(aCx), aCpows);
nsRefPtr<nsFrameMessageManager> mm = mChromeMessageManager;
mm->ReceiveMessage(mOwner, aMessage, true, &aData, &cpows, aPrincipal,
nsCOMPtr<nsIFrameLoader> fl = GetFrameLoader();
mm->ReceiveMessage(mOwner, fl, aMessage, true, &aData, &cpows, aPrincipal,
aJSONRetVal);
}
return true;
@ -65,7 +66,8 @@ public:
virtual nsresult HandleMessage() override
{
ReceiveMessage(mTabChild->mOwner, mTabChild->mChromeMessageManager);
nsCOMPtr<nsIFrameLoader> fl = mTabChild->GetFrameLoader();
ReceiveMessage(mTabChild->mOwner, fl, mTabChild->mChromeMessageManager);
return NS_OK;
}
nsRefPtr<nsInProcessTabChildGlobal> mTabChild;
@ -175,6 +177,12 @@ NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
NS_IMPL_ADDREF_INHERITED(nsInProcessTabChildGlobal, DOMEventTargetHelper)
NS_IMPL_RELEASE_INHERITED(nsInProcessTabChildGlobal, DOMEventTargetHelper)
void
nsInProcessTabChildGlobal::CacheFrameLoader(nsIFrameLoader* aFrameLoader)
{
mFrameLoader = aFrameLoader;
}
NS_IMETHODIMP
nsInProcessTabChildGlobal::GetContent(nsIDOMWindow** aContent)
{
@ -336,3 +344,14 @@ nsInProcessTabChildGlobal::LoadFrameScript(const nsAString& aURL, bool aRunInGlo
LoadScriptInternal(aURL, aRunInGlobalScope);
mLoadingScript = tmp;
}
already_AddRefed<nsIFrameLoader>
nsInProcessTabChildGlobal::GetFrameLoader()
{
nsCOMPtr<nsIFrameLoaderOwner> owner = do_QueryInterface(mOwner);
nsCOMPtr<nsIFrameLoader> fl = owner ? owner->GetFrameLoader() : nullptr;
if (!fl) {
fl = mFrameLoader;
}
return fl.forget();
}

View File

@ -150,6 +150,9 @@ public:
{
MOZ_CRASH("nsInProcessTabChildGlobal doesn't use DOM bindings!");
}
already_AddRefed<nsIFrameLoader> GetFrameLoader();
protected:
virtual ~nsInProcessTabChildGlobal();
@ -165,6 +168,11 @@ protected:
// PreHandleEvent.
bool mIsBrowserOrAppFrame;
bool mPreventEventsEscaping;
// We keep a strong reference to the frameloader after we've started
// teardown. This allows us to dispatch message manager messages during this
// time.
nsCOMPtr<nsIFrameLoader> mFrameLoader;
public:
nsIContent* mOwner;
nsFrameMessageManager* mChromeMessageManager;

View File

@ -7,6 +7,7 @@ skip-if = e10s # Bug ?????? - test directly touches content (contentWindow.ifram
[browser_bug902350.js]
skip-if = e10s # Bug ?????? - test e10s utils don't support load events from iframe etc, which this test relies on.
[browser_messagemanager_loadprocessscript.js]
[browser_messagemanager_targetframeloader.js]
[browser_pagehide_on_tab_close.js]
skip-if = e10s # this tests non-e10s behavior. it's not expected to work in e10s.
[browser_messagemanager_unload.js]

View File

@ -0,0 +1,31 @@
function frameScript()
{
sendSyncMessage("Test:Message");
sendAsyncMessage("Test:Message");
sendAsyncMessage("Test:Done");
}
function test() {
waitForExplicitFinish();
var newTab = gBrowser.addTab("about:blank");
gBrowser.selectedTab = newTab;
let browser = newTab.linkedBrowser;
let frameLoader = browser.frameLoader;
ok(frameLoader !== null, "frameLoader looks okay");
browser.messageManager.loadFrameScript("data:,(" + frameScript.toString() + ")()", false);
browser.messageManager.addMessageListener("Test:Message", (msg) => {
ok(msg.target === browser, "<browser> is correct");
ok(msg.targetFrameLoader === frameLoader, "frameLoader is correct");
ok(browser.frameLoader === msg.targetFrameLoader, "browser frameloader is correct");
});
browser.messageManager.addMessageListener("Test:Done", () => {
info("Finished");
gBrowser.removeCurrentTab();
finish();
});
}

View File

@ -70,6 +70,8 @@ function test() {
gBrowser.selectedTab = newTab;
let browser = newTab.linkedBrowser;
let frameLoader = browser.frameLoader;
ok(frameLoader !== null, "frameLoader looks okay");
browser.messageManager.loadFrameScript("data:,(" + frameScript.toString() + ")()", false);
@ -80,6 +82,8 @@ function test() {
let index = 0;
browser.messageManager.addMessageListener("Test:Event", (msg) => {
ok(msg.target === browser, "<browser> is correct");
ok(msg.targetFrameLoader === frameLoader, "frameLoader is correct");
ok(browser.frameLoader === null, "browser frameloader null during teardown");
info(JSON.stringify(msg.data));

View File

@ -2019,7 +2019,7 @@ ContentChild::RecvAsyncMessage(const nsString& aMsg,
if (cpm) {
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForChild(aData);
CrossProcessCpowHolder cpows(this, aCpows);
cpm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(cpm.get()),
cpm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(cpm.get()), nullptr,
aMsg, false, &cloneData, &cpows, aPrincipal, nullptr);
}
return true;

View File

@ -1703,7 +1703,7 @@ ContentParent::ShutDownMessageManager()
}
mMessageManager->ReceiveMessage(
static_cast<nsIContentFrameMessageManager*>(mMessageManager.get()),
static_cast<nsIContentFrameMessageManager*>(mMessageManager.get()), nullptr,
CHILD_PROCESS_SHUTDOWN_MESSAGE, false,
nullptr, nullptr, nullptr, nullptr);

View File

@ -496,7 +496,7 @@ TabChildBase::DispatchMessageManagerMessage(const nsAString& aMessageName,
// content manipulate the frame state.
nsRefPtr<nsFrameMessageManager> mm =
static_cast<nsFrameMessageManager*>(mTabChildGlobal->mMessageManager.get());
mm->ReceiveMessage(static_cast<EventTarget*>(mTabChildGlobal),
mm->ReceiveMessage(static_cast<EventTarget*>(mTabChildGlobal), nullptr,
aMessageName, false, &cloneData, nullptr, nullptr, nullptr);
}
@ -2689,7 +2689,7 @@ TabChild::RecvAsyncMessage(const nsString& aMessage,
nsRefPtr<nsFrameMessageManager> mm =
static_cast<nsFrameMessageManager*>(mTabChildGlobal->mMessageManager.get());
CrossProcessCpowHolder cpows(Manager(), aCpows);
mm->ReceiveMessage(static_cast<EventTarget*>(mTabChildGlobal),
mm->ReceiveMessage(static_cast<EventTarget*>(mTabChildGlobal), nullptr,
aMessage, false, &cloneData, &cpows, aPrincipal, nullptr);
}
return true;

View File

@ -2484,6 +2484,7 @@ TabParent::ReceiveMessage(const nsString& aMessage,
frameLoader->GetFrameMessageManager();
manager->ReceiveMessage(mFrameElement,
frameLoader,
aMessage,
aSync,
aCloneData,

View File

@ -117,7 +117,7 @@ nsIContentChild::RecvAsyncMessage(const nsString& aMsg,
if (cpm) {
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForChild(aData);
CrossProcessCpowHolder cpows(this, aCpows);
cpm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(cpm.get()),
cpm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(cpm.get()), nullptr,
aMsg, false, &cloneData, &cpows, aPrincipal, nullptr);
}
return true;

View File

@ -194,7 +194,7 @@ nsIContentParent::RecvSyncMessage(const nsString& aMsg,
if (ppm) {
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
CrossProcessCpowHolder cpows(this, aCpows);
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()),
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()), nullptr,
aMsg, true, &cloneData, &cpows, aPrincipal, aRetvals);
}
return true;
@ -221,7 +221,7 @@ nsIContentParent::RecvRpcMessage(const nsString& aMsg,
if (ppm) {
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
CrossProcessCpowHolder cpows(this, aCpows);
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()),
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()), nullptr,
aMsg, true, &cloneData, &cpows, aPrincipal, aRetvals);
}
return true;
@ -247,7 +247,7 @@ nsIContentParent::RecvAsyncMessage(const nsString& aMsg,
if (ppm) {
StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
CrossProcessCpowHolder cpows(this, aCpows);
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()),
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()), nullptr,
aMsg, false, &cloneData, &cpows, aPrincipal, nullptr);
}
return true;