Bug 1126245 - [e10s] Don't crash when opening new tabs from closed windows (r=bent)

This commit is contained in:
Bill McCloskey 2015-02-03 09:20:46 -08:00
parent 5065c02959
commit eddccb3475

View File

@ -38,6 +38,7 @@
#include "nsIContent.h"
#include "nsIDocShell.h"
#include "nsIDocShellTreeOwner.h"
#include "nsIDOMChromeWindow.h"
#include "nsIDOMElement.h"
#include "nsIDOMEvent.h"
#include "nsIDOMWindow.h"
@ -53,6 +54,7 @@
#include "nsIRemoteBrowser.h"
#include "nsViewManager.h"
#include "nsIWidget.h"
#include "nsIWindowMediator.h"
#include "nsIWindowWatcher.h"
#include "nsOpenURIInFrameParams.h"
#include "nsPIDOMWindow.h"
@ -492,6 +494,35 @@ private:
nsCString* mURLToLoad;
};
static already_AddRefed<nsIDOMWindow>
FindMostRecentOpenWindow()
{
nsCOMPtr<nsIWindowMediator> windowMediator =
do_GetService(NS_WINDOWMEDIATOR_CONTRACTID);
nsCOMPtr<nsISimpleEnumerator> windowEnumerator;
windowMediator->GetEnumerator(MOZ_UTF16("navigator:browser"),
getter_AddRefs(windowEnumerator));
nsCOMPtr<nsIDOMWindow> latest;
bool hasMore = false;
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(windowEnumerator->HasMoreElements(&hasMore)));
while (hasMore) {
nsCOMPtr<nsISupports> item;
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(windowEnumerator->GetNext(getter_AddRefs(item))));
nsCOMPtr<nsIDOMWindow> window = do_QueryInterface(item);
bool isClosed;
if (window && NS_SUCCEEDED(window->GetClosed(&isClosed)) && !isClosed) {
latest = window;
}
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(windowEnumerator->HasMoreElements(&hasMore)));
}
return latest.forget();
}
bool
TabParent::RecvCreateWindow(PBrowserParent* aNewTab,
const uint32_t& aChromeFlags,
@ -521,10 +552,36 @@ TabParent::RecvCreateWindow(PBrowserParent* aNewTab,
TabParent* newTab = static_cast<TabParent*>(aNewTab);
nsCOMPtr<nsIContent> frame(do_QueryInterface(mFrameElement));
NS_ENSURE_TRUE(frame, false);
nsCOMPtr<nsIDOMWindow> parent = do_QueryInterface(frame->OwnerDoc()->GetWindow());
NS_ENSURE_TRUE(parent, false);
nsCOMPtr<nsIDOMWindow> parent;
if (frame) {
parent = do_QueryInterface(frame->OwnerDoc()->GetWindow());
// If our chrome window is in the process of closing, don't try to open a
// new tab in it.
if (parent) {
bool isClosed;
if (NS_SUCCEEDED(parent->GetClosed(&isClosed)) && isClosed) {
parent = nullptr;
}
}
}
nsCOMPtr<nsIBrowserDOMWindow> browserDOMWin = mBrowserDOMWindow;
// If we haven't found a chrome window to open in, just use the most recently
// opened one.
if (!parent) {
parent = FindMostRecentOpenWindow();
if (!parent) {
return false;
}
nsCOMPtr<nsIDOMChromeWindow> rootChromeWin = do_QueryInterface(parent);
if (rootChromeWin) {
rootChromeWin->GetBrowserDOMWindow(getter_AddRefs(browserDOMWin));
}
}
int32_t openLocation =
nsWindowWatcher::GetWindowOpenLocation(parent, aChromeFlags, aCalledFromJS,
@ -535,7 +592,7 @@ TabParent::RecvCreateWindow(PBrowserParent* aNewTab,
// Opening new tabs is the easy case...
if (openLocation == nsIBrowserDOMWindow::OPEN_NEWTAB) {
NS_ENSURE_TRUE(mBrowserDOMWindow, false);
NS_ENSURE_TRUE(browserDOMWin, false);
bool isPrivate;
nsCOMPtr<nsILoadContext> loadContext = GetLoadContext();
@ -548,10 +605,10 @@ TabParent::RecvCreateWindow(PBrowserParent* aNewTab,
AutoUseNewTab aunt(newTab, aWindowIsNew, aURLToLoad);
nsCOMPtr<nsIFrameLoaderOwner> frameLoaderOwner;
mBrowserDOMWindow->OpenURIInFrame(nullptr, params,
openLocation,
nsIBrowserDOMWindow::OPEN_NEW,
getter_AddRefs(frameLoaderOwner));
browserDOMWin->OpenURIInFrame(nullptr, params,
openLocation,
nsIBrowserDOMWindow::OPEN_NEW,
getter_AddRefs(frameLoaderOwner));
if (!frameLoaderOwner) {
*aWindowIsNew = false;
}