Update renderer visibility state using IPC from the browser process
Currently, RenderThreadImpl::RendererIsHidden() is implemented by
keeping track of the total number and the number of hidden RenderWidgets
in a renderer. If there is a non-zero amount of RenderWidgets and the
two numbers are equal, RendererIsHidden() will return true.
However, the current implementation is broken, as it does not account
for the existence of inactive RenderWidgets. Inactive widgets refer to
widgets that are created to support out-of-process iframes, but that do
not represent actual widgets. These widgets exist with the sole purpose
of maintaining state. Consequently, this widgets are never explicitly
marked as hidden or visible, they are simply considered "frozen". This
behaviour effects the implementation of RendererIsHidden(), as each time
an inactive RenderWidget is created, the total number of RenderWidgets
is incremented. However, those widgets will never be marked as hidden,
and there will always be a difference between the total number and the
number of hidden widgets. As a result, renderers that contain inactive
widgets are incorrectly considered visible.
Note that RenderProcessHostImpl already has information regarding a
renderer's backgrounded and visibility state, using
ChildProcessLauncherPriority. Rather than computing this information
twice, we can forward the information from the browser process to the
renderer process. The existing SetProcessBackgrounded IPC was modified
to SetProcessState, now taking a RenderProcessState enum as a parameter.
The process can be marked visible, hidden or backgrounded. Depending on
the state transition, RenderThreadImpl calls OnRendererHidden,
OnRendererVisible, OnRendererBackgrounded and OnRendererForegrounded at
the appropriately.
The new approach resolves a flaw in the current approach to determine
renderer visibility and ensures that we have a single source of truth
regarding a renderer's backgrounded and visibility state.
Bug: 927440
Change-Id: Ib5aa60cd515443e17a0be691c211721caaf573ac
Reviewed-on: https://chromium-review.googlesource.com/c/1448742
Commit-Queue: Aditya Keerthi <[email protected]>
Reviewed-by: Daniel Cheng <[email protected]>
Reviewed-by: Alexander Timin <[email protected]>
Reviewed-by: François Doray <[email protected]>
Reviewed-by: Alex Moshchuk <[email protected]>
Reviewed-by: Gabriel Charette <[email protected]>
Cr-Commit-Position: refs/heads/master@{#635182}
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc
index 846a66c..82907ab 100644
--- a/content/renderer/render_widget.cc
+++ b/content/renderer/render_widget.cc
@@ -581,11 +581,6 @@
// Take a reference on behalf of the RenderThread. This will be balanced
// when we receive WidgetMsg_Close.
AddRef();
- if (RenderThreadImpl::current()) {
- RenderThreadImpl::current()->WidgetCreated();
- if (is_hidden_)
- RenderThreadImpl::current()->WidgetHidden();
- }
}
void RenderWidget::ApplyEmulatedScreenMetricsForPopupWidget(
@@ -721,15 +716,6 @@
if (routing_id_ != MSG_ROUTING_NONE) {
RenderThread::Get()->RemoveRoute(routing_id_);
g_routing_id_widget_map.Get().erase(routing_id_);
- if (RenderThreadImpl::current()) {
- // RenderWidgets may be hidden when they are closed. If we were previously
- // hidden, we are being counted as such in RenderThreadImpl. Thus we
- // remove that count here by calling WidgetRestored() even though we're
- // clearly not becoming visible here.
- if (is_hidden_)
- RenderThreadImpl::current()->WidgetRestored();
- RenderThreadImpl::current()->WidgetDestroyed();
- }
}
// Stop handling main thread input events immediately so we don't have them
@@ -2486,14 +2472,8 @@
RendererWindowTreeClient::Get(routing_id_)->SetVisible(!hidden);
#endif
- // RenderThreadImpl::current() could be null in tests.
- if (RenderThreadImpl::current()) {
- if (is_hidden_) {
- RenderThreadImpl::current()->WidgetHidden();
- first_update_visual_state_after_hidden_ = true;
- } else {
- RenderThreadImpl::current()->WidgetRestored();
- }
+ if (is_hidden_) {
+ first_update_visual_state_after_hidden_ = true;
}
if (render_widget_scheduling_state_)