De-duplicate visibility handling code in WebContentsImpl
This is a cleanup in prepration for performing the changes laid out in
crbug.com/995131#c24
Bug: 995131
Change-Id: I177069c21782ccd38231c483da5469bc47932158
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1891119
Commit-Queue: Collin Baker <[email protected]>
Reviewed-by: Avi Drissman <[email protected]>
Cr-Commit-Position: refs/heads/master@{#711576}
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 7b3bb6a..dafbbbc 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -1456,28 +1456,8 @@
OnPreferredSizeChanged(preferred_size_);
}
- if (GetVisibility() != Visibility::VISIBLE && !was_captured) {
- // TODO: Share code with WasShown().
- SendPageMessage(new PageMsg_WasShown(MSG_ROUTING_NONE));
-
- if (auto* view = GetRenderWidgetHostView()) {
- view->Show();
-#if defined(OS_MACOSX)
- view->SetActive(true);
-#endif
- }
-
- if (!ShowingInterstitialPage())
- SetVisibilityForChildViews(true);
-
- for (FrameTreeNode* node : frame_tree_.Nodes()) {
- RenderFrameProxyHost* parent = node->render_manager()->GetProxyToParent();
- if (!parent)
- continue;
-
- parent->cross_process_frame_connector()->DelegateWasShown();
- }
- }
+ if (!was_captured)
+ UpdateVisibilityAndNotifyPageAndView(GetVisibility());
}
void WebContentsImpl::DecrementCapturerCount() {
@@ -1493,13 +1473,7 @@
const gfx::Size old_size = preferred_size_for_capture_;
preferred_size_for_capture_ = gfx::Size();
OnPreferredSizeChanged(old_size);
-
- if (visibility_ == Visibility::HIDDEN) {
- DVLOG(1) << "Executing delayed WasHidden().";
- WasHidden();
- } else if (visibility_ == Visibility::OCCLUDED) {
- WasOccluded();
- }
+ UpdateVisibilityAndNotifyPageAndView(GetVisibility());
}
}
@@ -1694,67 +1668,11 @@
}
void WebContentsImpl::WasShown() {
- controller_.SetActive(true);
-
- // This shows the Page before showing the individual RenderWidgets, as
- // RenderWidgets will work to produce compositor frames and handle input
- // as soon as they are shown. But the Page and other classes do not expect to
- // be producing frames when the Page is hidden. So we make sure the Page is
- // shown first.
- SendPageMessage(new PageMsg_WasShown(MSG_ROUTING_NONE));
-
- if (auto* view = GetRenderWidgetHostView()) {
- view->Show();
-#if defined(OS_MACOSX)
- view->SetActive(true);
-#endif
- }
-
- if (!ShowingInterstitialPage())
- SetVisibilityForChildViews(true);
-
- last_active_time_ = base::TimeTicks::Now();
- SetVisibility(Visibility::VISIBLE);
-
- for (FrameTreeNode* node : frame_tree_.Nodes()) {
- RenderFrameProxyHost* parent = node->render_manager()->GetProxyToParent();
- if (!parent)
- continue;
-
- parent->cross_process_frame_connector()->DelegateWasShown();
- }
+ UpdateVisibilityAndNotifyPageAndView(Visibility::VISIBLE);
}
void WebContentsImpl::WasHidden() {
- // If there are entities capturing screenshots or video (e.g. mirroring),
- // or in Picture-in-Picture mode, don't activate the "disable rendering"
- // optimization.
- if (!IsBeingCaptured() && !HasPictureInPictureVideo()) {
- // This hides the individual RenderWidgets before hiding the Page, as
- // RenderWidgets will work to produce compositor frames and handle input
- // until they are hidden. But the Page and other classes do not expect to
- // be producing frames when the Page is hidden. So we stop the widgets,
- // then hide the Page.
- //
- // |GetRenderViewHost()| can be NULL if the user middle clicks a link to
- // open a tab in the background, then closes the tab before selecting it.
- // This is because closing the tab calls WebContentsImpl::Destroy(), which
- // removes the |GetRenderViewHost()|; then when we actually destroy the
- // window, OnWindowPosChanged() notices and calls WasHidden() (which
- // calls us).
- if (auto* view = GetRenderWidgetHostView())
- view->Hide();
-
- if (!ShowingInterstitialPage())
- SetVisibilityForChildViews(false);
- }
-
- // Inform the renderer that the page was hidden if there are no entities
- // capturing screenshots or video (e.g. mirroring).
- if (!IsBeingCaptured())
- SendPageMessage(new PageMsg_WasHidden(MSG_ROUTING_NONE));
-
- SetVisibility(Visibility::HIDDEN);
+ UpdateVisibilityAndNotifyPageAndView(Visibility::HIDDEN);
}
bool WebContentsImpl::HasRecentInteractiveInputEvent() {
@@ -1785,25 +1703,7 @@
#endif
void WebContentsImpl::WasOccluded() {
- // If there are entities capturing screenshots or video (e.g. mirroring),
- // or in Picture-in-Picture mode, don't activate the "disable rendering"
- // optimization.
- if (!IsBeingCaptured() && !HasPictureInPictureVideo()) {
- if (auto* main_view = GetRenderWidgetHostView())
- main_view->WasOccluded();
- if (!ShowingInterstitialPage()) {
- // Occluding child view is treated as hiding the view
- // (https://crbug.com/903455).
- SetVisibilityForChildViews(false);
- }
- }
-
- // Inform the renderer that the page was hidden if there are no entities
- // capturing screenshots or video (e.g. mirroring).
- if (!IsBeingCaptured())
- SendPageMessage(new PageMsg_WasHidden(MSG_ROUTING_NONE));
-
- SetVisibility(Visibility::OCCLUDED);
+ UpdateVisibilityAndNotifyPageAndView(Visibility::OCCLUDED);
}
Visibility WebContentsImpl::GetVisibility() {
@@ -2618,6 +2518,74 @@
display_cutout_host_impl_->DidAcquireFullscreen(new_fullscreen_frame);
}
+void WebContentsImpl::UpdateVisibilityAndNotifyPageAndView(
+ Visibility new_visibility) {
+ if (new_visibility == Visibility::VISIBLE)
+ controller_.SetActive(true);
+
+ // Only hide the page if there are no entities capturing screenshots
+ // or video (e.g. mirroring).
+ const bool page_is_visible =
+ new_visibility == Visibility::VISIBLE || IsBeingCaptured();
+ // If there are entities in Picture-in-Picture mode, don't activate
+ // the "disable rendering" optimization.
+ const bool view_is_visible = page_is_visible || HasPictureInPictureVideo();
+
+ // This shows the Page before showing the individual RenderWidgets, as
+ // RenderWidgets will work to produce compositor frames and handle input
+ // as soon as they are shown. But the Page and other classes do not expect to
+ // be producing frames when the Page is hidden. So we make sure the Page is
+ // shown first.
+ if (page_is_visible)
+ SendPageMessage(new PageMsg_WasShown(MSG_ROUTING_NONE));
+
+ // |GetRenderWidgetHostView()| can be null if the user middle clicks a link to
+ // open a tab in the background, then closes the tab before selecting it.
+ // This is because closing the tab calls WebContentsImpl::Destroy(), which
+ // removes the |GetRenderViewHost()|; then when we actually destroy the
+ // window, OnWindowPosChanged() notices and calls WasHidden() (which
+ // calls us).
+ if (auto* view = GetRenderWidgetHostView()) {
+ if (view_is_visible) {
+ view->Show();
+#if defined(OS_MACOSX)
+ view->SetActive(true);
+#endif
+ } else if (new_visibility == Visibility::HIDDEN) {
+ view->Hide();
+ } else {
+ view->WasOccluded();
+ }
+ }
+
+ if (!ShowingInterstitialPage())
+ SetVisibilityForChildViews(view_is_visible);
+
+ // Make sure to call SetVisibilityAndNotifyObservers(VISIBLE) before notifying
+ // the CrossProcessFrameConnector.
+ if (new_visibility == Visibility::VISIBLE) {
+ last_active_time_ = base::TimeTicks::Now();
+ SetVisibilityAndNotifyObservers(new_visibility);
+ }
+
+ if (!page_is_visible) {
+ // Similar to when showing the page, we only hide the page after
+ // hiding the individual RenderWidgets.
+ SendPageMessage(new PageMsg_WasHidden(MSG_ROUTING_NONE));
+ } else {
+ for (FrameTreeNode* node : frame_tree_.Nodes()) {
+ RenderFrameProxyHost* parent = node->render_manager()->GetProxyToParent();
+ if (!parent)
+ continue;
+
+ parent->cross_process_frame_connector()->DelegateWasShown();
+ }
+ }
+
+ if (new_visibility != Visibility::VISIBLE)
+ SetVisibilityAndNotifyObservers(new_visibility);
+}
+
#if defined(OS_ANDROID)
void WebContentsImpl::UpdateUserGestureCarryoverInfo() {
if (delegate_)
@@ -4084,7 +4052,7 @@
}
}
-void WebContentsImpl::SetVisibility(Visibility visibility) {
+void WebContentsImpl::SetVisibilityAndNotifyObservers(Visibility visibility) {
const Visibility previous_visibility = visibility_;
visibility_ = visibility;
@@ -7250,12 +7218,7 @@
if (visibility == visibility_)
return;
- if (visibility == Visibility::VISIBLE)
- WasShown();
- else if (visibility == Visibility::OCCLUDED)
- WasOccluded();
- else
- WasHidden();
+ UpdateVisibilityAndNotifyPageAndView(visibility);
}
void WebContentsImpl::UpdateOverridingUserAgent() {