Bug 1525720, part 5 - Redirect nsIHttpChannel using content process ID instead of nsIRemoteTab. r=valentin

This code currently works for remote subframes assuming that nsIRemoteTab is implemented
by BrowserParent, but will break when nsIRemoteTab is only for a top-level BrowserParent.

What this code really wants is a content process ID to retarget the channel to. This
commit switches the interfaces to pass this around instead of nsIRemoteTab.

Differential Revision: https://phabricator.services.mozilla.com/D31435

--HG--
extra : rebase_source : be3303c2d38d704a6a1817fa45fd76700fae6287
extra : histedit_source : c7bf1e496f4328acc9ee70fcccdff98ea2cce5df
This commit is contained in:
Ryan Hunt 2019-05-15 12:33:42 -05:00
Родитель edf885fc82
Коммит 3621e207d9
9 изменённых файлов: 48 добавлений и 30 удалений

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

@ -2331,7 +2331,7 @@ var SessionStoreInternal = {
// Tell our caller to redirect the load into this newly created process.
let remoteTab = aBrowser.frameLoader.remoteTab;
debug(`[process-switch]: new tabID: ${remoteTab.tabId}`);
return remoteTab;
return remoteTab.contentProcessId;
},
/**

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

@ -35,7 +35,7 @@ interface WindowGlobalParent {
JSWindowActorParent getActor(DOMString name);
[Throws]
Promise<RemoteTab> changeFrameRemoteness(
Promise<unsigned long long> changeFrameRemoteness(
BrowsingContext? bc, DOMString remoteType,
unsigned long long pendingSwitchId);
};

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

@ -57,6 +57,8 @@ interface nsIRemoteTab : nsISupports
readonly attribute uint64_t tabId;
readonly attribute uint64_t contentProcessId;
/**
* The OS level process Id of the related child process.
*/

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

@ -3188,6 +3188,12 @@ BrowserParent::GetTabId(uint64_t* aId) {
return NS_OK;
}
NS_IMETHODIMP
BrowserParent::GetContentProcessId(uint64_t* aId) {
*aId = Manager()->GetChildID();
return NS_OK;
}
NS_IMETHODIMP
BrowserParent::GetOsPid(int32_t* aId) {
*aId = Manager()->Pid();

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

@ -277,12 +277,13 @@ already_AddRefed<Promise> WindowGlobalParent::ChangeFrameRemoteness(
}
// If we got a BrowserBridgeParent, the frame is out-of-process, so pull
// our target BrowserParent off of it. Otherwise, it's an in-process
// our target content process off of it. Otherwise, it's an in-process
// frame, so we can directly use ours.
if (bridge) {
promise->MaybeResolve(bridge->GetBrowserParent());
promise->MaybeResolve(
bridge->GetBrowserParent()->Manager()->ChildID());
} else {
promise->MaybeResolve(browserParent);
promise->MaybeResolve(browserParent->Manager()->ChildID());
}
};

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

@ -8,6 +8,8 @@
#include "HttpLog.h"
#include "HttpChannelParentListener.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/ContentProcessManager.h"
#include "mozilla/dom/ServiceWorkerInterceptController.h"
#include "mozilla/dom/ServiceWorkerUtils.h"
#include "mozilla/net/HttpChannelParent.h"
@ -158,13 +160,14 @@ nsresult HttpChannelParentListener::TriggerCrossProcessRedirect(
nsCOMPtr<nsIChannel> channel = aChannel;
RefPtr<nsHttpChannel> httpChannel = do_QueryObject(channel);
RefPtr<nsHttpChannel::TabPromise> p = httpChannel->TakeRedirectTabPromise();
RefPtr<nsHttpChannel::ContentProcessIdPromise> p =
httpChannel->TakeRedirectContentProcessIdPromise();
nsCOMPtr<nsILoadInfo> loadInfo = aLoadInfo;
RefPtr<HttpChannelParentListener> self = this;
p->Then(
GetMainThreadSerialEventTarget(), __func__,
[=](nsCOMPtr<nsIRemoteTab> tp) {
[=](uint64_t cpId) {
nsresult rv;
// Register the new channel and obtain id for it
@ -199,8 +202,13 @@ nsresult HttpChannelParentListener::TriggerCrossProcessRedirect(
MOZ_ALWAYS_SUCCEEDS(internalChannel->GetRedirectMode(&redirectMode));
}
dom::BrowserParent* browserParent = dom::BrowserParent::GetFrom(tp);
auto result = browserParent->Manager()->SendCrossProcessRedirect(
dom::ContentParent* cp =
dom::ContentProcessManager::GetSingleton()->GetContentProcessById(
ContentParentId{cpId});
if (!cp) {
return NS_ERROR_UNEXPECTED;
}
auto result = cp->SendCrossProcessRedirect(
self->mRedirectChannelId, uri, newLoadFlags, loadInfoArgs,
channelId, originalURI, aIdentifier, redirectMode);

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

@ -128,6 +128,7 @@
#include "HttpTrafficAnalyzer.h"
#include "mozilla/dom/CanonicalBrowsingContext.h"
#include "mozilla/dom/WindowGlobalParent.h"
#include "js/Conversions.h"
#ifdef MOZ_TASK_TRACER
# include "GeckoTaskTracer.h"
@ -2569,7 +2570,7 @@ nsresult nsHttpChannel::ContinueProcessResponse1() {
// notify "http-on-may-change-process" observers
gHttpHandler->OnMayChangeProcess(this);
if (mRedirectTabPromise) {
if (mRedirectContentProcessIdPromise) {
MOZ_ASSERT(!mOnStartRequestCalled);
PushRedirectAsyncFunc(&nsHttpChannel::ContinueProcessResponse2);
@ -7244,10 +7245,11 @@ nsHttpChannel::GetRequestMethod(nsACString& aMethod) {
class DomPromiseListener final : dom::PromiseNativeHandler {
NS_DECL_ISUPPORTS
static RefPtr<nsHttpChannel::TabPromise> Create(dom::Promise* aDOMPromise) {
static RefPtr<nsHttpChannel::ContentProcessIdPromise> Create(
dom::Promise* aDOMPromise) {
MOZ_ASSERT(aDOMPromise);
RefPtr<DomPromiseListener> handler = new DomPromiseListener();
RefPtr<nsHttpChannel::TabPromise> promise =
RefPtr<nsHttpChannel::ContentProcessIdPromise> promise =
handler->mPromiseHolder.Ensure(__func__);
aDOMPromise->AppendNativeHandler(handler);
return promise;
@ -7255,15 +7257,12 @@ class DomPromiseListener final : dom::PromiseNativeHandler {
virtual void ResolvedCallback(JSContext* aCx,
JS::Handle<JS::Value> aValue) override {
nsCOMPtr<nsIRemoteTab> browserParent;
JS::Rooted<JSObject*> obj(aCx, &aValue.toObject());
nsresult rv =
UnwrapArg<nsIRemoteTab>(aCx, obj, getter_AddRefs(browserParent));
if (NS_FAILED(rv)) {
mPromiseHolder.Reject(rv, __func__);
uint64_t cpId;
if (!JS::ToUint64(aCx, aValue, &cpId)) {
mPromiseHolder.Reject(NS_ERROR_FAILURE, __func__);
return;
}
mPromiseHolder.Resolve(browserParent, __func__);
mPromiseHolder.Resolve(cpId, __func__);
}
virtual void RejectedCallback(JSContext* aCx,
@ -7278,15 +7277,15 @@ class DomPromiseListener final : dom::PromiseNativeHandler {
private:
DomPromiseListener() = default;
~DomPromiseListener() = default;
MozPromiseHolder<nsHttpChannel::TabPromise> mPromiseHolder;
MozPromiseHolder<nsHttpChannel::ContentProcessIdPromise> mPromiseHolder;
};
NS_IMPL_ISUPPORTS0(DomPromiseListener)
NS_IMETHODIMP nsHttpChannel::SwitchProcessTo(dom::Promise* aTabPromise,
uint64_t aIdentifier) {
NS_IMETHODIMP nsHttpChannel::SwitchProcessTo(
dom::Promise* aContentProcessIdPromise, uint64_t aIdentifier) {
MOZ_ASSERT(NS_IsMainThread());
NS_ENSURE_ARG(aTabPromise);
NS_ENSURE_ARG(aContentProcessIdPromise);
LOG(("nsHttpChannel::SwitchProcessTo [this=%p]", this));
LogCallingScriptLocation(this);
@ -7294,7 +7293,8 @@ NS_IMETHODIMP nsHttpChannel::SwitchProcessTo(dom::Promise* aTabPromise,
// We cannot do this after OnStartRequest of the listener has been called.
NS_ENSURE_FALSE(mOnStartRequestCalled, NS_ERROR_NOT_AVAILABLE);
mRedirectTabPromise = DomPromiseListener::Create(aTabPromise);
mRedirectContentProcessIdPromise =
DomPromiseListener::Create(aContentProcessIdPromise);
mCrossProcessRedirectIdentifier = aIdentifier;
return NS_OK;
}
@ -7645,7 +7645,7 @@ nsHttpChannel::OnStartRequest(nsIRequest* request) {
// notify "http-on-may-change-process" observers
gHttpHandler->OnMayChangeProcess(this);
if (mRedirectTabPromise) {
if (mRedirectContentProcessIdPromise) {
PushRedirectAsyncFunc(&nsHttpChannel::ContinueOnStartRequest1);
rv = StartCrossProcessRedirect();
if (NS_SUCCEEDED(rv)) {

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

@ -286,9 +286,10 @@ class nsHttpChannel final : public HttpBaseChannel,
}
TransactionObserver* GetTransactionObserver() { return mTransactionObserver; }
typedef MozPromise<nsCOMPtr<nsIRemoteTab>, nsresult, false> TabPromise;
already_AddRefed<TabPromise> TakeRedirectTabPromise() {
return mRedirectTabPromise.forget();
typedef MozPromise<uint64_t, nsresult, false> ContentProcessIdPromise;
already_AddRefed<ContentProcessIdPromise>
TakeRedirectContentProcessIdPromise() {
return mRedirectContentProcessIdPromise.forget();
}
uint64_t CrossProcessRedirectIdentifier() {
return mCrossProcessRedirectIdentifier;
@ -576,7 +577,7 @@ class nsHttpChannel final : public HttpBaseChannel,
// The associated childChannel is getting relocated to another process.
// This promise will be resolved when that process is set up.
RefPtr<TabPromise> mRedirectTabPromise;
RefPtr<ContentProcessIdPromise> mRedirectContentProcessIdPromise;
// This identifier is passed to the childChannel in order to identify it.
uint64_t mCrossProcessRedirectIdentifier = 0;

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

@ -70,7 +70,7 @@ ProcessChooser.prototype = {
// Can asyncly create a tab, or can resolve with a tab that was
// previously created.
info("resolving");
resolve(self.remoteTab);
resolve(self.remoteTab.contentProcessId);
});
info("calling switchprocessto");