Commit da90ece8 authored by Arthur Sonzogni's avatar Arthur Sonzogni Committed by Commit Bot

Update GetRootRenderWidgetHostView() to explore the tree using RFH.

GetRootRenderWidgetHostView() and GetParentRenderWidget() explore the
FrameTree using FrameTreeNode. Once it is done, it returns the
RenderWidgetHostView associated with the current RenderFrameHost on
that FrameTreeNode.
The issue: there is no 1:1 association between the FrameTreeNode and the
RenderFrameHost. A FrameTreeNode, contains several RenderframeHost:
 * The current one.
 * The pending one, not displayed and used for loading a new document,
   but this one has still not committed.
 * The ones in pending deletion. Those are no more displayed and are
   in progress executing their javascript unload handlers.

Instead of exploring the tree using FrameTreeNode::parent(), explore the
tree using RenderFrameHost::GetParent(). That way, it is guaranteed the
functions will always returns the same object.

Bug: 609963
Change-Id: Ic8972180b94763bd6a831f2754d1e3c661c0bbc4
Reviewed-on: https://chromium-review.googlesource.com/1210942Reviewed-by: default avatarKen Buchanan <kenrb@chromium.org>
Reviewed-by: default avatarAlex Moshchuk <alexmos@chromium.org>
Reviewed-by: default avatarLucas Gadani <lfg@chromium.org>
Commit-Queue: Arthur Sonzogni <arthursonzogni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#593130}
parent 2075b0d4
...@@ -34,6 +34,37 @@ ...@@ -34,6 +34,37 @@
namespace content { namespace content {
namespace {
// If |frame| is an iframe or a GuestView, returns its parent, null otherwise.
RenderFrameHostImpl* ParentRenderFrameHost(RenderFrameHostImpl* frame) {
// Find the parent in the FrameTree (iframe).
if (frame->GetParent())
return frame->GetParent();
// Find the parent in the WebContentsTree (GuestView).
FrameTreeNode* frame_in_embedder =
frame->frame_tree_node()->render_manager()->GetOuterDelegateNode();
if (frame_in_embedder)
return frame_in_embedder->current_frame_host()->GetParent();
// No parent found.
return nullptr;
}
// Return the root RenderFrameHost in the outermost WebContents.
RenderFrameHostImpl* RootRenderFrameHost(RenderFrameHostImpl* frame) {
RenderFrameHostImpl* current = frame;
while (true) {
RenderFrameHostImpl* parent = ParentRenderFrameHost(current);
if (!parent)
return current;
current = parent;
};
}
} // namespace
CrossProcessFrameConnector::CrossProcessFrameConnector( CrossProcessFrameConnector::CrossProcessFrameConnector(
RenderFrameProxyHost* frame_proxy_in_parent_renderer) RenderFrameProxyHost* frame_proxy_in_parent_renderer)
: FrameConnectorDelegate(IsUseZoomForDSFEnabled()), : FrameConnectorDelegate(IsUseZoomForDSFEnabled()),
...@@ -393,40 +424,19 @@ CrossProcessFrameConnector::GetRootRenderWidgetHostView() { ...@@ -393,40 +424,19 @@ CrossProcessFrameConnector::GetRootRenderWidgetHostView() {
if (!frame_proxy_in_parent_renderer_) if (!frame_proxy_in_parent_renderer_)
return nullptr; return nullptr;
RenderFrameHostImpl* top_host = frame_proxy_in_parent_renderer_-> RenderFrameHostImpl* current =
frame_tree_node()->frame_tree()->root()->current_frame_host(); frame_proxy_in_parent_renderer_->frame_tree_node()->current_frame_host();
RenderFrameHostImpl* root = RootRenderFrameHost(current);
// This method should return the root RWHV from the top-level WebContents, return static_cast<RenderWidgetHostViewBase*>(root->GetView());
// in the case of nested WebContents.
while (top_host->frame_tree_node()->render_manager()->ForInnerDelegate()) {
top_host = top_host->frame_tree_node()->render_manager()->
GetOuterDelegateNode()->frame_tree()->root()->current_frame_host();
}
return static_cast<RenderWidgetHostViewBase*>(top_host->GetView());
} }
RenderWidgetHostViewBase* RenderWidgetHostViewBase*
CrossProcessFrameConnector::GetParentRenderWidgetHostView() { CrossProcessFrameConnector::GetParentRenderWidgetHostView() {
FrameTreeNode* parent = RenderFrameHostImpl* current =
frame_proxy_in_parent_renderer_->frame_tree_node()->parent(); frame_proxy_in_parent_renderer_->frame_tree_node()->current_frame_host();
RenderFrameHostImpl* parent = ParentRenderFrameHost(current);
if (!parent && return parent ? static_cast<RenderWidgetHostViewBase*>(parent->GetView())
frame_proxy_in_parent_renderer_->frame_tree_node() : nullptr;
->render_manager()
->GetOuterDelegateNode()) {
parent = frame_proxy_in_parent_renderer_->frame_tree_node()
->render_manager()
->GetOuterDelegateNode()
->parent();
}
if (parent) {
return static_cast<RenderWidgetHostViewBase*>(
parent->current_frame_host()->GetView());
}
return nullptr;
} }
void CrossProcessFrameConnector::EnableAutoResize(const gfx::Size& min_size, void CrossProcessFrameConnector::EnableAutoResize(const gfx::Size& min_size,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment