Bug 1525720, part 10 - Link BrowserParent and BrowserHost on creation. r=nika
authorRyan Hunt <rhunt@eqrion.net>
Wed, 15 May 2019 10:34:03 -0500
changeset 475153 9d7151b26a9eb72d363b4a309f179c15452dc2bc
parent 475152 0c53638d28a9d1468e047136db7680394fa39b92
child 475154 4cf9a1ce9e92dbcc022c1d8d7d6ac8ed185dc082
push id36055
push userdvarga@mozilla.com
push dateThu, 23 May 2019 15:55:11 +0000
treeherdermozilla-central@5a63f841eacb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnika
bugs1525720
milestone69.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1525720, part 10 - Link BrowserParent and BrowserHost on creation. r=nika This commit adds a link from BrowserParent to it's owning BrowserHost if it is the root BrowserParent. Differential Revision: https://phabricator.services.mozilla.com/D31441
dom/ipc/BrowserBridgeParent.cpp
dom/ipc/BrowserHost.cpp
dom/ipc/BrowserParent.cpp
dom/ipc/BrowserParent.h
--- a/dom/ipc/BrowserBridgeParent.cpp
+++ b/dom/ipc/BrowserBridgeParent.cpp
@@ -56,19 +56,19 @@ nsresult BrowserBridgeParent::Init(const
 
   ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
   TabId tabId(nsContentUtils::GenerateTabId());
   cpm->RegisterRemoteFrame(tabId, ContentParentId(0), TabId(0),
                            tabContext.AsIPCTabContext(),
                            constructorSender->ChildID());
 
   // Construct the BrowserParent object for our subframe.
-  RefPtr<BrowserParent> browserParent(
-      new BrowserParent(constructorSender, tabId, tabContext, aBrowsingContext,
-                        aChromeFlags, this));
+  RefPtr<BrowserParent> browserParent(new BrowserParent(
+      constructorSender, tabId, tabContext, aBrowsingContext, aChromeFlags));
+  browserParent->SetBrowserBridgeParent(this);
 
   // Open a remote endpoint for our PBrowser actor. DeallocPBrowserParent
   // releases the ref taken.
   ManagedEndpoint<PBrowserChild> childEp =
       constructorSender->OpenPBrowserEndpoint(do_AddRef(browserParent).take());
   if (NS_WARN_IF(!childEp.IsValid())) {
     MOZ_ASSERT(false, "Browser Open Endpoint Failed");
     return NS_ERROR_FAILURE;
--- a/dom/ipc/BrowserHost.cpp
+++ b/dom/ipc/BrowserHost.cpp
@@ -7,17 +7,19 @@
 #include "mozilla/dom/BrowserHost.h"
 
 #include "mozilla/dom/CancelContentJSOptionsBinding.h"
 #include "mozilla/dom/WindowGlobalParent.h"
 
 namespace mozilla {
 namespace dom {
 
-BrowserHost::BrowserHost(BrowserParent* aParent) : mRoot(aParent) {}
+BrowserHost::BrowserHost(BrowserParent* aParent) : mRoot(aParent) {
+  mRoot->SetBrowserHost(this);
+}
 
 mozilla::layers::LayersId BrowserHost::GetLayersId() const {
   return mRoot->GetRenderFrame()->GetLayersId();
 }
 
 BrowsingContext* BrowserHost::GetBrowsingContext() const {
   return mRoot->GetBrowsingContext();
 }
--- a/dom/ipc/BrowserParent.cpp
+++ b/dom/ipc/BrowserParent.cpp
@@ -168,28 +168,28 @@ NS_INTERFACE_MAP_END
 NS_IMPL_CYCLE_COLLECTION(BrowserParent, mFrameElement, mBrowserDOMWindow,
                          mLoadContext, mFrameLoader, mBrowsingContext)
 NS_IMPL_CYCLE_COLLECTING_ADDREF(BrowserParent)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(BrowserParent)
 
 BrowserParent::BrowserParent(ContentParent* aManager, const TabId& aTabId,
                              const TabContext& aContext,
                              CanonicalBrowsingContext* aBrowsingContext,
-                             uint32_t aChromeFlags,
-                             BrowserBridgeParent* aBrowserBridgeParent)
+                             uint32_t aChromeFlags)
     : TabContext(aContext),
       mTabId(aTabId),
       mManager(aManager),
       mBrowsingContext(aBrowsingContext),
       mLoadContext(nullptr),
       mFrameElement(nullptr),
       mBrowserDOMWindow(nullptr),
       mFrameLoader(nullptr),
       mChromeFlags(aChromeFlags),
-      mBrowserBridgeParent(aBrowserBridgeParent),
+      mBrowserBridgeParent(nullptr),
+      mBrowserHost(nullptr),
       mContentCache(*this),
       mRenderFrame{},
       mLayerTreeEpoch{1},
       mChildToParentConversionMatrix{},
       mRect(0, 0, 0, 0),
       mDimensions(0, 0),
       mOrientation(0),
       mDPI(0),
@@ -437,16 +437,22 @@ a11y::DocAccessibleParent* BrowserParent
 
 RenderFrame* BrowserParent::GetRenderFrame() {
   if (!mRenderFrame.IsInitialized()) {
     return nullptr;
   }
   return &mRenderFrame;
 }
 
+BrowserBridgeParent* BrowserParent::GetBrowserBridgeParent() const {
+  return mBrowserBridgeParent;
+}
+
+BrowserHost* BrowserParent::GetBrowserHost() const { return mBrowserHost; }
+
 ShowInfo BrowserParent::GetShowInfo() {
   TryCacheDPIAndScale();
   if (mFrameElement) {
     nsAutoString name;
     mFrameElement->GetAttr(kNameSpaceID_None, nsGkAtoms::name, name);
     bool allowFullscreen =
         mFrameElement->HasAttr(kNameSpaceID_None, nsGkAtoms::allowfullscreen) ||
         mFrameElement->HasAttr(kNameSpaceID_None,
@@ -3822,16 +3828,34 @@ mozilla::ipc::IPCResult BrowserParent::R
   return IPC_FAIL(this, "QueryVisitedState is Android-only");
 #endif
 }
 
 void BrowserParent::LiveResizeStarted() { SuppressDisplayport(true); }
 
 void BrowserParent::LiveResizeStopped() { SuppressDisplayport(false); }
 
+void BrowserParent::SetBrowserBridgeParent(BrowserBridgeParent* aBrowser) {
+  // We should not have either a browser bridge or browser host yet
+  MOZ_ASSERT(!mBrowserBridgeParent);
+  MOZ_ASSERT(!mBrowserHost);
+  // We should not have owner content yet
+  MOZ_ASSERT(!mFrameElement);
+  mBrowserBridgeParent = aBrowser;
+}
+
+void BrowserParent::SetBrowserHost(BrowserHost* aBrowser) {
+  // We should not have either a browser bridge or browser host yet
+  MOZ_ASSERT(!mBrowserBridgeParent);
+  MOZ_ASSERT(!mBrowserHost);
+  // We should not have owner content yet
+  MOZ_ASSERT(!mFrameElement);
+  mBrowserHost = aBrowser;
+}
+
 /* static */
 size_t BrowserParent::gNumActiveRecordReplayTabs;
 
 void BrowserParent::SetIsActiveRecordReplayTab(bool aIsActive) {
   if (aIsActive != mIsActiveRecordReplayTab) {
     gNumActiveRecordReplayTabs += aIsActive ? 1 : -1;
     mIsActiveRecordReplayTab = aIsActive;
   }
--- a/dom/ipc/BrowserParent.h
+++ b/dom/ipc/BrowserParent.h
@@ -68,16 +68,18 @@ class DataSourceSurface;
 
 namespace dom {
 
 class CanonicalBrowsingContext;
 class ClonedMessageData;
 class ContentParent;
 class Element;
 class DataTransfer;
+class BrowserHost;
+class BrowserBridgeParent;
 
 namespace ipc {
 class StructuredCloneData;
 }  // namespace ipc
 
 /**
  * BrowserParent implements the parent actor part of the PBrowser protocol. See
  * PBrowser for more information.
@@ -88,17 +90,16 @@ class BrowserParent final : public PBrow
                             public nsIAuthPromptProvider,
                             public nsIKeyEventInPluginCallback,
                             public nsSupportsWeakReference,
                             public TabContext,
                             public LiveResizeListener {
   typedef mozilla::dom::ClonedMessageData ClonedMessageData;
 
   friend class PBrowserParent;
-  friend class BrowserBridgeParent;  // for clearing mBrowserBridgeParent
 
   virtual ~BrowserParent();
 
  public:
   // Helper class for ContentParent::RecvCreateWindow.
   struct AutoUseNewTab;
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
@@ -108,18 +109,17 @@ class BrowserParent final : public PBrow
   // nsIDOMEventListener interfaces
   NS_DECL_NSIDOMEVENTLISTENER
 
   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(BrowserParent, nsIRemoteTab)
 
   BrowserParent(ContentParent* aManager, const TabId& aTabId,
                 const TabContext& aContext,
                 CanonicalBrowsingContext* aBrowsingContext,
-                uint32_t aChromeFlags,
-                BrowserBridgeParent* aBrowserBridgeParent = nullptr);
+                uint32_t aChromeFlags);
 
   // Call from LayoutStatics only
   static void InitializeStatics();
 
   /**
    * Returns the focused BrowserParent or nullptr if chrome or another app
    * is focused.
    */
@@ -149,22 +149,16 @@ class BrowserParent final : public PBrow
   CanonicalBrowsingContext* GetBrowsingContext() { return mBrowsingContext; }
 
   already_AddRefed<nsILoadContext> GetLoadContext();
 
   Element* GetOwnerElement() const { return mFrameElement; }
 
   nsIBrowserDOMWindow* GetBrowserDOMWindow() const { return mBrowserDOMWindow; }
 
-  // Returns the BrowserBridgeParent if this BrowserParent is for an
-  // out-of-process iframe and nullptr otherwise.
-  BrowserBridgeParent* GetBrowserBridgeParent() const {
-    return mBrowserBridgeParent;
-  }
-
   already_AddRefed<nsPIDOMWindowOuter> GetParentWindowOuter();
 
   already_AddRefed<nsIWidget> GetTopLevelWidget();
 
   // Returns the closest widget for our frameloader's content.
   already_AddRefed<nsIWidget> GetWidget() const;
 
   // Returns the top-level widget for our frameloader's document.
@@ -174,16 +168,24 @@ class BrowserParent final : public PBrow
 
   /**
    * Return the top level doc accessible parent for this tab.
    */
   a11y::DocAccessibleParent* GetTopLevelDocAccessible() const;
 
   layout::RenderFrame* GetRenderFrame();
 
+  // Returns the BrowserBridgeParent if this BrowserParent is for an
+  // out-of-process iframe and nullptr otherwise.
+  BrowserBridgeParent* GetBrowserBridgeParent() const;
+
+  // Returns the BrowserHost if this BrowserParent is for a top-level browser
+  // and nullptr otherwise.
+  BrowserHost* GetBrowserHost() const;
+
   ShowInfo GetShowInfo();
 
   /**
    * Let managees query if Destroy() is already called so they don't send out
    * messages when the PBrowser actor is being destroyed.
    */
   bool IsDestroyed() const { return mIsDestroyed; }
 
@@ -672,16 +674,22 @@ class BrowserParent final : public PBrow
   void SetReadyToHandleInputEvents() { mIsReadyToHandleInputEvents = true; }
   bool IsReadyToHandleInputEvents() { return mIsReadyToHandleInputEvents; }
 
   void NavigateByKey(bool aForward, bool aForDocumentNavigation);
 
   void SkipBrowsingContextDetach();
 
  protected:
+  friend BrowserBridgeParent;
+  friend BrowserHost;
+
+  void SetBrowserBridgeParent(BrowserBridgeParent* aBrowser);
+  void SetBrowserHost(BrowserHost* aBrowser);
+
   bool ReceiveMessage(
       const nsString& aMessage, bool aSync, ipc::StructuredCloneData* aData,
       mozilla::jsipc::CpowHolder* aCpows, nsIPrincipal* aPrincipal,
       nsTArray<ipc::StructuredCloneData>* aJSONRetVal = nullptr);
 
   mozilla::ipc::IPCResult RecvAsyncAuthPrompt(const nsCString& aUri,
                                               const nsString& aRealm,
                                               const uint64_t& aCallbackId);
@@ -782,16 +790,20 @@ class BrowserParent final : public PBrow
   RefPtr<nsFrameLoader> mFrameLoader;
   uint32_t mChromeFlags;
 
   // Pointer back to BrowserBridgeParent if there is one associated with
   // this BrowserParent. This is non-owning to avoid cycles and is managed
   // by the BrowserBridgeParent instance, which has the strong reference
   // to this BrowserParent.
   BrowserBridgeParent* mBrowserBridgeParent;
+  // Pointer to the BrowserHost that owns us, if any. This is mutually
+  // exclusive with mBrowserBridgeParent, and one is guaranteed to be
+  // non-null.
+  BrowserHost* mBrowserHost;
 
   ContentCacheInParent mContentCache;
 
   layout::RenderFrame mRenderFrame;
   LayersObserverEpoch mLayerTreeEpoch;
 
   Maybe<LayoutDeviceToLayoutDeviceMatrix4x4> mChildToParentConversionMatrix;