Bug 1298219 - Don't fire oop-browser-crashed event if the browser has already flipped remoteness and moved on. r=billm

We currently make the initial browser in a window remote by default. If early
on in the session, that one remote browser goes away (and the content process
was still booting), there's about 5 seconds before the shutdown kill timer
will take that content process out for not quitting fast enough.

There are some cases during startup where the content process is waiting
on information from the parent, so it cannot respond to the request to
quit in time. The parents shutdown kill timer goes off, and the shutdown
kill occurs.

In this bug, what's happening is that the initial browser flips remoteness
from remote to non-remote when it goes to about:sessionrestore. This starts
the shutdown kill timer. The content process runs out of time, and the
shutdown kill timer fires, killing the content process. The TabParent::ActorDestroy
method (which still exists, even though the browser is no longer remote),
interprets this as an abnormal shutdown, and bubbles the oop-browser-crashed
event to the associated <xul:browser>, which causes the page to browser to
about:tabcrashed, when it had already loaded about:sessionrestore.

This patch makes it so that the TabParent::ActorDestroy method first checks
to ensure that the associated remote frameloader is still the one that the
frameloader owner cares about. If not (because, say, the remoteness has
flipped and a new non-remote frameloader has been created), then the
event is not fired, since the user has moved on.

MozReview-Commit-ID: G4jmR6lMMFl

--HG--
extra : rebase_source : 7e752d9854d6c17b2b346cc986c0fbad00292848
This commit is contained in:
Mike Conley 2016-08-31 18:23:40 -04:00
Родитель 0c24d6390a
Коммит b56cf3f8af
1 изменённых файлов: 13 добавлений и 3 удалений

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

@ -618,9 +618,19 @@ TabParent::ActorDestroy(ActorDestroyReason why)
if (why == AbnormalShutdown && os) {
os->NotifyObservers(NS_ISUPPORTS_CAST(nsIFrameLoader*, frameLoader),
"oop-frameloader-crashed", nullptr);
nsContentUtils::DispatchTrustedEvent(frameElement->OwnerDoc(), frameElement,
NS_LITERAL_STRING("oop-browser-crashed"),
true, true);
nsCOMPtr<nsIFrameLoaderOwner> owner = do_QueryInterface(frameElement);
if (owner) {
RefPtr<nsFrameLoader> currentFrameLoader = owner->GetFrameLoader();
// It's possible that the frameloader owner has already moved on
// and created a new frameloader. If so, we don't fire the event,
// since the frameloader owner has clearly moved on.
if (currentFrameLoader == frameLoader) {
nsContentUtils::DispatchTrustedEvent(frameElement->OwnerDoc(), frameElement,
NS_LITERAL_STRING("oop-browser-crashed"),
true, true);
}
}
}
mFrameLoader = nullptr;