Bug 1116478 - Open web content handlers in the proper tab in e10s. r=billm

--HG--
extra : rebase_source : 9ce04d3a3b30ecdcef4c4781639f0e5ea22d8b22
This commit is contained in:
Blake Kaplan 2015-12-03 15:04:28 -08:00
Родитель 65297a6d50
Коммит 0bb2b116eb
10 изменённых файлов: 114 добавлений и 5 удалений

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

@ -26,6 +26,7 @@ XPIDL_SOURCES += [
'nsIImageLoadingContent.idl',
'nsIMessageManager.idl',
'nsIObjectLoadingContent.idl',
'nsIRemoteWindowContext.idl',
'nsIScriptChannel.idl',
'nsIScriptLoaderObserver.idl',
'nsISelection.idl',

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

@ -0,0 +1,15 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=8 et tw=80 : */
/* 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
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
interface nsIURI;
[scriptable, builtinclass, uuid(94f4a92b-752e-4fd9-8345-11b069ca19f3)]
interface nsIRemoteWindowContext : nsISupports
{
void openURI(in nsIURI aURI, in uint32_t aFlags);
};

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

@ -139,6 +139,7 @@
#include "nsIMutable.h"
#include "nsIObserverService.h"
#include "nsIPresShell.h"
#include "nsIRemoteWindowContext.h"
#include "nsIScriptError.h"
#include "nsIScriptSecurityManager.h"
#include "nsISiteSecurityService.h"
@ -1690,6 +1691,47 @@ StaticAutoPtr<LinkedList<SystemMessageHandledListener> >
NS_IMPL_ISUPPORTS(SystemMessageHandledListener,
nsITimerCallback)
class RemoteWindowContext final : public nsIRemoteWindowContext
, public nsIInterfaceRequestor
{
public:
explicit RemoteWindowContext(TabParent* aTabParent)
: mTabParent(aTabParent)
{
}
NS_DECL_ISUPPORTS
NS_DECL_NSIINTERFACEREQUESTOR
NS_DECL_NSIREMOTEWINDOWCONTEXT
private:
~RemoteWindowContext();
RefPtr<TabParent> mTabParent;
};
NS_IMPL_ISUPPORTS(RemoteWindowContext, nsIRemoteWindowContext, nsIInterfaceRequestor)
RemoteWindowContext::~RemoteWindowContext()
{
}
NS_IMETHODIMP
RemoteWindowContext::GetInterface(const nsIID& aIID, void** aSink)
{
return QueryInterface(aIID, aSink);
}
NS_IMETHODIMP
RemoteWindowContext::OpenURI(nsIURI* aURI, uint32_t aFlags)
{
URIParams uri;
SerializeURI(aURI, uri);
Unused << mTabParent->SendOpenURI(uri, aFlags);
return NS_OK;
}
} // namespace
void
@ -4320,7 +4362,8 @@ ContentParent::RecvAccumulateMixedContentHSTS(const URIParams& aURI, const bool&
}
bool
ContentParent::RecvLoadURIExternal(const URIParams& uri)
ContentParent::RecvLoadURIExternal(const URIParams& uri,
PBrowserParent* windowContext)
{
nsCOMPtr<nsIExternalProtocolService> extProtService(do_GetService(NS_EXTERNALPROTOCOLSERVICE_CONTRACTID));
if (!extProtService) {
@ -4330,7 +4373,10 @@ ContentParent::RecvLoadURIExternal(const URIParams& uri)
if (!ourURI) {
return false;
}
extProtService->LoadURI(ourURI, nullptr);
RefPtr<RemoteWindowContext> context =
new RemoteWindowContext(static_cast<TabParent*>(windowContext));
extProtService->LoadURI(ourURI, context);
return true;
}

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

@ -798,7 +798,8 @@ private:
virtual bool RecvOpenNotificationSettings(const IPC::Principal& aPrincipal) override;
virtual bool RecvLoadURIExternal(const URIParams& uri) override;
virtual bool RecvLoadURIExternal(const URIParams& uri,
PBrowserParent* windowContext) override;
virtual bool RecvSyncMessage(const nsString& aMsg,
const ClonedMessageData& aData,

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

@ -556,6 +556,8 @@ child:
LoadURL(nsCString uri, BrowserConfiguration config, ShowInfo info);
OpenURI(URIParams uri, uint32_t flags);
CacheFileDescriptor(nsString path, FileDescriptor fd);
UpdateDimensions(CSSRect rect, CSSSize size, nsSizeMode sizeMode,

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

@ -852,7 +852,7 @@ parent:
async VisitURI(URIParams uri, OptionalURIParams referrer, uint32_t flags);
async SetURITitle(URIParams uri, nsString title);
async LoadURIExternal(URIParams uri);
async LoadURIExternal(URIParams uri, PBrowser windowContext);
// PrefService message
sync ReadPrefsArray() returns (PrefSetting[] prefs);

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

@ -23,6 +23,7 @@
#include "mozilla/plugins/PluginWidgetChild.h"
#include "mozilla/IMEStateManager.h"
#include "mozilla/ipc/DocumentRendererChild.h"
#include "mozilla/ipc/URIUtils.h"
#ifdef MOZ_NUWA_PROCESS
#include "ipc/Nuwa.h"
#endif
@ -101,6 +102,7 @@
#include "nsIAppsService.h"
#include "nsNetUtil.h"
#include "nsIPermissionManager.h"
#include "nsIURILoader.h"
#include "nsIScriptError.h"
#include "mozilla/EventForwards.h"
#include "nsDeviceContext.h"
@ -1263,6 +1265,31 @@ TabChild::RecvLoadURL(const nsCString& aURI,
return true;
}
bool
TabChild::RecvOpenURI(const URIParams& aURI, const uint32_t& aFlags)
{
nsCOMPtr<nsIURI> uri = DeserializeURI(aURI);
nsCOMPtr<nsIChannel> channel;
nsresult rv =
NS_NewChannel(getter_AddRefs(channel),
uri,
nsContentUtils::GetSystemPrincipal(),
nsILoadInfo::SEC_NORMAL,
nsIContentPolicy::TYPE_DOCUMENT);
if (NS_WARN_IF(NS_FAILED(rv))) {
return true;
}
nsCOMPtr<nsIURILoader> loader = do_GetService("@mozilla.org/uriloader;1");
if (NS_WARN_IF(!loader)) {
return true;
}
nsCOMPtr<nsIInterfaceRequestor> context(do_QueryInterface(WebNavigation()));
loader->OpenURI(channel, aFlags, context);
return true;
}
bool
TabChild::RecvCacheFileDescriptor(const nsString& aPath,
const FileDescriptor& aFileDescriptor)

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

@ -301,6 +301,8 @@ public:
virtual bool RecvLoadURL(const nsCString& aURI,
const BrowserConfiguration& aConfiguration,
const ShowInfo& aInfo) override;
virtual bool RecvOpenURI(const URIParams& aURI,
const uint32_t& aFlags) override;
virtual bool RecvCacheFileDescriptor(const nsString& aPath,
const FileDescriptor& aFileDescriptor)
override;

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

@ -1012,7 +1012,9 @@ nsExternalHelperAppService::LoadURI(nsIURI *aURI,
URIParams uri;
SerializeURI(aURI, uri);
mozilla::dom::ContentChild::GetSingleton()->SendLoadURIExternal(uri);
nsCOMPtr<nsITabChild> tabChild(do_GetInterface(aWindowContext));
mozilla::dom::ContentChild::GetSingleton()->
SendLoadURIExternal(uri, static_cast<dom::TabChild*>(tabChild.get()));
return NS_OK;
}

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

@ -80,6 +80,19 @@ nsWebHandlerApp.prototype = {
// if we have a window context, use the URI loader to load there
if (aWindowContext) {
try {
// getInterface throws if the object doesn't implement the given
// interface, so this try/catch statement is more of an if.
// If aWindowContext refers to a remote docshell, send the load
// request to the correct process.
aWindowContext.getInterface(Ci.nsIRemoteWindowContext)
.openURI(uriToSend, Ci.nsIURILoader.IS_CONTENT_PREFERRED);
return;
} catch (e) {
if (e.result != Cr.NS_NOINTERFACE) {
throw e;
}
}
// create a channel from this URI
var channel = ioService.newChannelFromURI2(uriToSend,