Bug 1518919 - Propagate CSS visibility information to descendant documents via IPC call for fission. r=jwatt
authorHiroyuki Ikezoe <hikezoe@mozilla.com>
Mon, 13 May 2019 01:49:07 +0000
changeset 532382 d77d76d37d4dccf39c12fa81c970088b5388d0f1
parent 532381 02b3eb8a1a1388f91c73cce582ce1e2b972f11f7
child 532383 340b1a7c0c3ca75fc343d73c106db1b3ef8904e4
push id11265
push userffxbld-merge
push dateMon, 13 May 2019 10:53:39 +0000
treeherdermozilla-beta@77e0fe8dbdd3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjwatt
bugs1518919
milestone68.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 1518919 - Propagate CSS visibility information to descendant documents via IPC call for fission. r=jwatt Differential Revision: https://phabricator.services.mozilla.com/D30460
dom/base/nsFrameLoader.cpp
dom/base/nsFrameLoader.h
dom/ipc/BrowserBridgeChild.cpp
dom/ipc/BrowserBridgeChild.h
dom/ipc/BrowserBridgeParent.cpp
dom/ipc/BrowserBridgeParent.h
dom/ipc/BrowserChild.cpp
dom/ipc/BrowserChild.h
dom/ipc/PBrowser.ipdl
dom/ipc/PBrowserBridge.ipdl
layout/base/PresShell.cpp
layout/generic/nsSubDocumentFrame.cpp
--- a/dom/base/nsFrameLoader.cpp
+++ b/dom/base/nsFrameLoader.cpp
@@ -2513,16 +2513,26 @@ nsresult nsFrameLoader::UpdatePositionAn
       }
     }
     return NS_OK;
   }
   UpdateBaseWindowPositionAndSize(aIFrame);
   return NS_OK;
 }
 
+void nsFrameLoader::SendIsUnderHiddenEmbedderElement(
+    bool aIsUnderHiddenEmbedderElement) {
+  MOZ_ASSERT(IsRemoteFrame());
+
+  if (mBrowserBridgeChild) {
+    mBrowserBridgeChild->SetIsUnderHiddenEmbedderElement(
+        aIsUnderHiddenEmbedderElement);
+  }
+}
+
 void nsFrameLoader::UpdateBaseWindowPositionAndSize(
     nsSubDocumentFrame* aIFrame) {
   nsCOMPtr<nsIBaseWindow> baseWindow = GetDocShell(IgnoreErrors());
 
   // resize the sub document
   if (baseWindow) {
     int32_t x = 0;
     int32_t y = 0;
--- a/dom/base/nsFrameLoader.h
+++ b/dom/base/nsFrameLoader.h
@@ -123,16 +123,17 @@ class nsFrameLoader final : public nsStu
     return mBrowsingContext ? mBrowsingContext->GetDocShell() : nullptr;
   }
   mozilla::dom::InProcessBrowserChildMessageManager*
   GetBrowserChildMessageManager() const {
     return mChildMessageManager;
   }
   nsresult CreateStaticClone(nsFrameLoader* aDest);
   nsresult UpdatePositionAndSize(nsSubDocumentFrame* aIFrame);
+  void SendIsUnderHiddenEmbedderElement(bool aIsUnderHiddenEmbedderElement);
 
   // WebIDL methods
 
   nsDocShell* GetDocShell(mozilla::ErrorResult& aRv);
 
   already_AddRefed<nsIRemoteTab> GetRemoteTab();
 
   already_AddRefed<nsILoadContext> LoadContext();
--- a/dom/ipc/BrowserBridgeChild.cpp
+++ b/dom/ipc/BrowserBridgeChild.cpp
@@ -112,16 +112,21 @@ void BrowserBridgeChild::NavigateByKey(b
                                        bool aForDocumentNavigation) {
   Unused << SendNavigateByKey(aForward, aForDocumentNavigation);
 }
 
 void BrowserBridgeChild::Activate() { Unused << SendActivate(); }
 
 void BrowserBridgeChild::Deactivate() { Unused << SendDeactivate(); }
 
+void BrowserBridgeChild::SetIsUnderHiddenEmbedderElement(
+    bool aIsUnderHiddenEmbedderElement) {
+  Unused << SendSetIsUnderHiddenEmbedderElement(aIsUnderHiddenEmbedderElement);
+}
+
 /*static*/
 BrowserBridgeChild* BrowserBridgeChild::GetFrom(nsFrameLoader* aFrameLoader) {
   if (!aFrameLoader) {
     return nullptr;
   }
   return aFrameLoader->GetBrowserBridgeChild();
 }
 
--- a/dom/ipc/BrowserBridgeChild.h
+++ b/dom/ipc/BrowserBridgeChild.h
@@ -42,16 +42,18 @@ class BrowserBridgeChild : public PBrows
                         const mozilla::ScreenIntSize& aSize);
 
   void NavigateByKey(bool aForward, bool aForDocumentNavigation);
 
   void Activate();
 
   void Deactivate();
 
+  void SetIsUnderHiddenEmbedderElement(bool aIsUnderHiddenEmbedderElement);
+
   static BrowserBridgeChild* GetFrom(nsFrameLoader* aFrameLoader);
 
   static BrowserBridgeChild* GetFrom(nsIContent* aContent);
 
  protected:
   friend class PBrowserBridgeChild;
 
   mozilla::ipc::IPCResult RecvSetLayersId(
--- a/dom/ipc/BrowserBridgeParent.cpp
+++ b/dom/ipc/BrowserBridgeParent.cpp
@@ -187,15 +187,22 @@ IPCResult BrowserBridgeParent::RecvActiv
   return IPC_OK();
 }
 
 IPCResult BrowserBridgeParent::RecvDeactivate() {
   mBrowserParent->Deactivate();
   return IPC_OK();
 }
 
+IPCResult BrowserBridgeParent::RecvSetIsUnderHiddenEmbedderElement(
+    const bool& aIsUnderHiddenEmbedderElement) {
+  Unused << mBrowserParent->SendSetIsUnderHiddenEmbedderElement(
+      aIsUnderHiddenEmbedderElement);
+  return IPC_OK();
+}
+
 void BrowserBridgeParent::ActorDestroy(ActorDestroyReason aWhy) {
   mIPCOpen = false;
   Destroy();
 }
 
 }  // namespace dom
 }  // namespace mozilla
--- a/dom/ipc/BrowserBridgeParent.h
+++ b/dom/ipc/BrowserBridgeParent.h
@@ -58,16 +58,19 @@ class BrowserBridgeParent : public PBrow
 
   mozilla::ipc::IPCResult RecvDispatchSynthesizedMouseEvent(
       const WidgetMouseEvent& aEvent);
 
   mozilla::ipc::IPCResult RecvActivate();
 
   mozilla::ipc::IPCResult RecvDeactivate();
 
+  mozilla::ipc::IPCResult RecvSetIsUnderHiddenEmbedderElement(
+      const bool& aIsUnderHiddenEmbedderElement);
+
   void ActorDestroy(ActorDestroyReason aWhy) override;
 
  private:
   ~BrowserBridgeParent();
 
   RefPtr<BrowserParent> mBrowserParent;
   bool mIPCOpen;
 };
--- a/dom/ipc/BrowserChild.cpp
+++ b/dom/ipc/BrowserChild.cpp
@@ -1260,16 +1260,24 @@ mozilla::ipc::IPCResult BrowserChild::Re
 
 mozilla::ipc::IPCResult BrowserChild::RecvChildToParentMatrix(
     const mozilla::gfx::Matrix4x4& aMatrix) {
   mChildToParentConversionMatrix =
       Some(LayoutDeviceToLayoutDeviceMatrix4x4::FromUnknownMatrix(aMatrix));
   return IPC_OK();
 }
 
+mozilla::ipc::IPCResult BrowserChild::RecvSetIsUnderHiddenEmbedderElement(
+    const bool& aIsUnderHiddenEmbedderElement) {
+  if (RefPtr<PresShell> presShell = GetTopLevelPresShell()) {
+    presShell->SetIsUnderHiddenEmbedderElement(aIsUnderHiddenEmbedderElement);
+  }
+  return IPC_OK();
+}
+
 bool BrowserChild::UpdateFrame(const RepaintRequest& aRequest) {
   return BrowserChildBase::UpdateFrameHandler(aRequest);
 }
 
 mozilla::ipc::IPCResult BrowserChild::RecvSuppressDisplayport(
     const bool& aEnabled) {
   if (RefPtr<PresShell> presShell = GetTopLevelPresShell()) {
     presShell->SuppressDisplayport(aEnabled);
--- a/dom/ipc/BrowserChild.h
+++ b/dom/ipc/BrowserChild.h
@@ -410,16 +410,19 @@ class BrowserChild final : public Browse
       const mozilla::WidgetCompositionEvent& aEvent);
 
   mozilla::ipc::IPCResult RecvSelectionEvent(
       const mozilla::WidgetSelectionEvent& aEvent);
 
   mozilla::ipc::IPCResult RecvNormalPrioritySelectionEvent(
       const mozilla::WidgetSelectionEvent& aEvent);
 
+  mozilla::ipc::IPCResult RecvSetIsUnderHiddenEmbedderElement(
+      const bool& aIsUnderHiddenEmbedderElement);
+
   MOZ_CAN_RUN_SCRIPT_BOUNDARY
   mozilla::ipc::IPCResult RecvPasteTransferable(
       const IPCDataTransfer& aDataTransfer, const bool& aIsPrivateData,
       nsIPrincipal* aRequestingPrincipal, const uint32_t& aContentPolicyType);
 
   mozilla::ipc::IPCResult RecvActivateFrameEvent(const nsString& aType,
                                                  const bool& aCapture);
 
--- a/dom/ipc/PBrowser.ipdl
+++ b/dom/ipc/PBrowser.ipdl
@@ -656,16 +656,18 @@ child:
     async ResumeLoad(uint64_t pendingSwitchID, ShowInfo info);
 
     async UpdateDimensions(DimensionInfo dimensions) compressall;
 
     async SizeModeChanged(nsSizeMode sizeMode);
 
     async ChildToParentMatrix(Matrix4x4 aMatrix);
 
+    async SetIsUnderHiddenEmbedderElement(bool aIsUnderHiddenEmbedderElement);
+
     async ParentActivated(bool aActivated);
 
     async SetKeyboardIndicators(UIStateChangeType showAccelerators,
                                 UIStateChangeType showFocusRings);
 
     /**
      * StopIMEStateManagement() is called when the process loses focus and
      * should stop managing IME state.
--- a/dom/ipc/PBrowserBridge.ipdl
+++ b/dom/ipc/PBrowserBridge.ipdl
@@ -68,12 +68,13 @@ parent:
 
   /**
    * Sending an activate message moves focus to the iframe.
    */
   async Activate();
 
   async Deactivate();
 
+  async SetIsUnderHiddenEmbedderElement(bool aIsUnderHiddenEmbedderElement);
 };
 
 }  // namespace dom
 }  // namespace mozilla
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -10914,36 +10914,38 @@ void PresShell::SetIsUnderHiddenEmbedder
 
   mUnderHiddenEmbedderElement = aUnderHiddenEmbedderElement;
 
   if (nsCOMPtr<nsIDocShell> docShell = mPresContext->GetDocShell()) {
     BrowsingContext* bc = nsDocShell::Cast(docShell)->GetBrowsingContext();
 
     // Propagate to children.
     for (BrowsingContext* child : bc->GetChildren()) {
+      Element* embedderElement = child->GetEmbedderElement();
+      MOZ_ASSERT(embedderElement);
+
       bool embedderFrameIsHidden = true;
-      if (Element* embedderElement = bc->GetEmbedderElement()) {
-        if (auto embedderFrame = embedderElement->GetPrimaryFrame()) {
-          embedderFrameIsHidden =
-              !embedderFrame->StyleVisibility()->IsVisible();
-        }
+      if (auto embedderFrame = embedderElement->GetPrimaryFrame()) {
+        embedderFrameIsHidden =
+            !embedderFrame->StyleVisibility()->IsVisible();
       }
 
       if (nsIDocShell* childDocShell = child->GetDocShell()) {
         PresShell* presShell = childDocShell->GetPresShell();
         if (!presShell) {
           continue;
         }
-
         presShell->SetIsUnderHiddenEmbedderElement(
             aUnderHiddenEmbedderElement || embedderFrameIsHidden);
-      }
-      // FIXME: Bug 1518919 - In the case where the BrowsingContext has no
-      // docshell which means it's out-of-process iframe, we need to propagate
-      // the info via an IPC call.
+      } else {
+        BrowserBridgeChild* bridgeChild =
+            BrowserBridgeChild::GetFrom(embedderElement);
+        bridgeChild->SetIsUnderHiddenEmbedderElement(
+            aUnderHiddenEmbedderElement || embedderFrameIsHidden);
+      }
     }
   }
 }
 
 nsIContent* PresShell::EventHandler::GetOverrideClickTarget(
     WidgetGUIEvent* aGUIEvent, nsIFrame* aFrame) {
   if (aGUIEvent->mMessage != eMouseUp) {
     return nullptr;
--- a/layout/generic/nsSubDocumentFrame.cpp
+++ b/layout/generic/nsSubDocumentFrame.cpp
@@ -155,19 +155,21 @@ void nsSubDocumentFrame::Init(nsIContent
       PresShell()->IsUnderHiddenEmbedderElement() ||
       !StyleVisibility()->IsVisible());
 
   nsContentUtils::AddScriptRunner(new AsyncFrameInit(this));
 }
 
 void nsSubDocumentFrame::PropagateIsUnderHiddenEmbedderElementToSubView(
     bool aIsUnderHiddenEmbedderElement) {
-  // FIXME: Bug 1518919 - In the case where we have mFrameLoader and its
-  // IsRemoteFrame() is true, the iframe is out-of-process iframe, so we need
-  // to notify the change via nsFrameLoader.
+  if (mFrameLoader && mFrameLoader->IsRemoteFrame()) {
+    mFrameLoader->SendIsUnderHiddenEmbedderElement(
+        aIsUnderHiddenEmbedderElement);
+    return;
+  }
 
   if (!mInnerView) {
     return;
   }
 
   nsView* subdocView = mInnerView->GetFirstChild();
   while (subdocView) {
     if (mozilla::PresShell* presShell = subdocView->GetPresShell()) {