Commit aa9b1db7 authored by Nika Layzell's avatar Nika Layzell
Browse files

Bug 1650089 - Part 3: Rework DocumentChannel-triggered process switches to...

Bug 1650089 - Part 3: Rework DocumentChannel-triggered process switches to support null principals, r=annyG,kmag

This is a large refactoring of the DocumentChannel process switch codepath,
with the end goal of being better able to support future process switch
requirements such as dynamic isolation on android, as well as the immediate
requirement of null principal handling.

The major changes include:
1. The logic is in C++ and has less failure cases, meaning it should be harder
   for us to error out unexpectedly and not process switch.
2. Process selection decisions are more explicit, and tend to rely less on
   state such as the current remoteType when possible. This makes reasoning
   about where a specific load will complete easier.
3. Additional checks are made after a "WebContent" behavior is selected to
   ensure that if an existing document in the same BCG is found, the load will
   finish in the required content process. This should make dynamic checks such
   as Android's logged-in site isolation easier to implement.
4. ProcessIsolation logging is split out from DocumentChannel so that it's
   easier to log just the information related to process selection when
   debugging.
5. Null result principal precursors are considered when performing process
   selection.

Other uses of E10SUtils for process selection have not yet been migrated to the
new design as they have slightly different requirements. This will be done in
follow-up bugs.

Differential Revision: https://phabricator.services.mozilla.com/D120673
parent 0ebcf696
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -279,7 +279,7 @@ void CanonicalBrowsingContext::MaybeAddAsProgressListener(

void CanonicalBrowsingContext::ReplacedBy(
    CanonicalBrowsingContext* aNewContext,
    const RemotenessChangeOptions& aRemotenessOptions) {
    const NavigationIsolationOptions& aRemotenessOptions) {
  MOZ_ASSERT(!aNewContext->mWebProgress);
  MOZ_ASSERT(!aNewContext->mSessionHistory);
  MOZ_ASSERT(IsTop() && aNewContext->IsTop());
@@ -1696,7 +1696,7 @@ void CanonicalBrowsingContext::PendingRemotenessChange::Clear() {

CanonicalBrowsingContext::PendingRemotenessChange::PendingRemotenessChange(
    CanonicalBrowsingContext* aTarget, RemotenessPromise::Private* aPromise,
    uint64_t aPendingSwitchId, const RemotenessChangeOptions& aOptions)
    uint64_t aPendingSwitchId, const NavigationIsolationOptions& aOptions)
    : mTarget(aTarget),
      mPromise(aPromise),
      mPendingSwitchId(aPendingSwitchId),
@@ -1732,7 +1732,7 @@ void CanonicalBrowsingContext::SetCurrentBrowserParent(

RefPtr<CanonicalBrowsingContext::RemotenessPromise>
CanonicalBrowsingContext::ChangeRemoteness(
    const RemotenessChangeOptions& aOptions, uint64_t aPendingSwitchId) {
    const NavigationIsolationOptions& aOptions, uint64_t aPendingSwitchId) {
  MOZ_DIAGNOSTIC_ASSERT(IsContent(),
                        "cannot change the process of chrome contexts");
  MOZ_DIAGNOSTIC_ASSERT(
@@ -2539,7 +2539,7 @@ void CanonicalBrowsingContext::RemovePageAwakeRequest() {
void CanonicalBrowsingContext::CloneDocumentTreeInto(
    CanonicalBrowsingContext* aSource, const nsACString& aRemoteType,
    embedding::PrintData&& aPrintData) {
  RemotenessChangeOptions options;
  NavigationIsolationOptions options;
  options.mRemoteType = aRemoteType;

  mClonePromise =
+5 −14
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@
#include "mozilla/dom/BrowsingContext.h"
#include "mozilla/dom/MediaControlKeySource.h"
#include "mozilla/dom/BrowsingContextWebProgress.h"
#include "mozilla/dom/ProcessIsolation.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/SessionHistoryEntry.h"
#include "mozilla/dom/SessionStoreRestoreData.h"
@@ -55,16 +56,6 @@ struct LoadingSessionHistoryInfo;
class SSCacheCopy;
class WindowGlobalParent;

// RemotenessChangeOptions is passed through the methods to store the state
// of the possible remoteness change.
struct RemotenessChangeOptions {
  nsCString mRemoteType;
  bool mReplaceBrowsingContext = false;
  uint64_t mSpecificGroupId = 0;
  bool mTryUseBFCache = false;
  RefPtr<SessionHistoryEntry> mActiveSessionHistoryEntry;
};

// CanonicalBrowsingContext is a BrowsingContext living in the parent
// process, with whatever extra data that a BrowsingContext in the
// parent needs.
@@ -233,7 +224,7 @@ class CanonicalBrowsingContext final : public BrowsingContext {
  // the parent process, and the method will resolve with a null BrowserParent.
  using RemotenessPromise = MozPromise<RefPtr<BrowserParent>, nsresult, false>;
  RefPtr<RemotenessPromise> ChangeRemoteness(
      const RemotenessChangeOptions& aOptions, uint64_t aPendingSwitchId);
      const NavigationIsolationOptions& aOptions, uint64_t aPendingSwitchId);

  // Return a media controller from the top-level browsing context that can
  // control all media belonging to this browsing context tree. Return nullptr
@@ -272,7 +263,7 @@ class CanonicalBrowsingContext final : public BrowsingContext {
  // aNewContext is the newly created BrowsingContext that is replacing
  // us.
  void ReplacedBy(CanonicalBrowsingContext* aNewContext,
                  const RemotenessChangeOptions& aRemotenessOptions);
                  const NavigationIsolationOptions& aRemotenessOptions);

  bool HasHistoryEntry(nsISHEntry* aEntry);

@@ -388,7 +379,7 @@ class CanonicalBrowsingContext final : public BrowsingContext {
    PendingRemotenessChange(CanonicalBrowsingContext* aTarget,
                            RemotenessPromise::Private* aPromise,
                            uint64_t aPendingSwitchId,
                            const RemotenessChangeOptions& aOptions);
                            const NavigationIsolationOptions& aOptions);

    void Cancel(nsresult aRv);

@@ -411,7 +402,7 @@ class CanonicalBrowsingContext final : public BrowsingContext {
    RefPtr<BrowsingContextGroup> mSpecificGroup;

    uint64_t mPendingSwitchId;
    RemotenessChangeOptions mOptions;
    NavigationIsolationOptions mOptions;
  };

  struct RestoreState {
+1 −1
Original line number Diff line number Diff line
@@ -1244,7 +1244,7 @@ static void FinishRestore(CanonicalBrowsingContext* aBrowsingContext,
    // ReplacedBy will swap the entry back.
    aBrowsingContext->SetActiveSessionHistoryEntry(aEntry);
    loadingBC->SetActiveSessionHistoryEntry(nullptr);
    RemotenessChangeOptions options;
    NavigationIsolationOptions options;
    aBrowsingContext->ReplacedBy(loadingBC, options);

    // Assuming we still have the session history, update the index.
+1 −1
Original line number Diff line number Diff line
@@ -481,7 +481,7 @@ already_AddRefed<nsFrameLoader> nsFrameLoader::Create(
already_AddRefed<nsFrameLoader> nsFrameLoader::Recreate(
    mozilla::dom::Element* aOwner, BrowsingContext* aContext,
    BrowsingContextGroup* aSpecificGroup,
    const RemotenessChangeOptions& aRemotenessOptions, bool aIsRemote,
    const NavigationIsolationOptions& aRemotenessOptions, bool aIsRemote,
    bool aNetworkCreated, bool aPreserveContext) {
  NS_ENSURE_TRUE(aOwner, nullptr);

+2 −2
Original line number Diff line number Diff line
@@ -72,7 +72,7 @@ class MutableTabContext;
class BrowserBridgeChild;
class RemoteBrowser;
struct RemotenessOptions;
struct RemotenessChangeOptions;
struct NavigationIsolationOptions;
class SessionStoreChangeListener;

namespace ipc {
@@ -123,7 +123,7 @@ class nsFrameLoader final : public nsStubMutationObserver,
  // FrameLoaders.
  static already_AddRefed<nsFrameLoader> Recreate(
      Element* aOwner, BrowsingContext* aContext, BrowsingContextGroup* aGroup,
      const mozilla::dom::RemotenessChangeOptions& aRemotenessOptions,
      const mozilla::dom::NavigationIsolationOptions& aRemotenessOptions,
      bool aIsRemote, bool aNetworkCreated, bool aPreserveContext);

  NS_DECLARE_STATIC_IID_ACCESSOR(NS_FRAMELOADER_IID)
Loading