| Index: content/browser/frame_host/render_frame_host_manager.cc
|
| diff --git a/content/browser/frame_host/render_frame_host_manager.cc b/content/browser/frame_host/render_frame_host_manager.cc
|
| index 1920847871588a0004b594628793174dae26c412..6fa4362a1acaffa03f3d6b7bcea3f04c9fe6eb53 100644
|
| --- a/content/browser/frame_host/render_frame_host_manager.cc
|
| +++ b/content/browser/frame_host/render_frame_host_manager.cc
|
| @@ -418,7 +418,8 @@ RenderFrameHostImpl* RenderFrameHostManager::Navigate(
|
| dest_render_frame_host->SetUpMojoIfNeeded();
|
|
|
| // Recreate the opener chain.
|
| - CreateOpenerProxiesIfNeeded(dest_render_frame_host->GetSiteInstance());
|
| + CreateOpenerProxies(dest_render_frame_host->GetSiteInstance(),
|
| + frame_tree_node_);
|
| if (!InitRenderView(dest_render_frame_host->render_view_host(),
|
| MSG_ROUTING_NONE,
|
| frame_tree_node_->IsMainFrame()))
|
| @@ -1043,7 +1044,7 @@ RenderFrameHostImpl* RenderFrameHostManager::GetFrameHostForNavigation(
|
| // created or has crashed), initialize it.
|
| if (!navigation_rfh->IsRenderFrameLive()) {
|
| // Recreate the opener chain.
|
| - CreateOpenerProxiesIfNeeded(navigation_rfh->GetSiteInstance());
|
| + CreateOpenerProxies(navigation_rfh->GetSiteInstance(), frame_tree_node_);
|
| if (!InitRenderView(navigation_rfh->render_view_host(), MSG_ROUTING_NONE,
|
| frame_tree_node_->IsMainFrame())) {
|
| return nullptr;
|
| @@ -1578,14 +1579,17 @@ void RenderFrameHostManager::CreateProxiesForNewRenderFrameHost(
|
| SiteInstance* old_instance,
|
| SiteInstance* new_instance) {
|
| // Only create opener proxies if they are in the same BrowsingInstance.
|
| - if (new_instance->IsRelatedSiteInstance(old_instance))
|
| - CreateOpenerProxiesIfNeeded(new_instance);
|
| - if (SiteIsolationPolicy::AreCrossProcessFramesPossible()) {
|
| - // Ensure that the frame tree has RenderFrameProxyHosts for the new
|
| - // SiteInstance in all nodes except the current one. We do this for all
|
| - // frames in the tree, whether they are in the same BrowsingInstance or not.
|
| - // We will still check whether two frames are in the same BrowsingInstance
|
| - // before we allow them to interact (e.g., postMessage).
|
| + if (new_instance->IsRelatedSiteInstance(old_instance)) {
|
| + CreateOpenerProxies(new_instance, frame_tree_node_);
|
| + } else if (SiteIsolationPolicy::AreCrossProcessFramesPossible()) {
|
| + // Ensure that the frame tree has RenderFrameProxyHosts for the
|
| + // new SiteInstance in all nodes except the current one. We do this for
|
| + // all frames in the tree, whether they are in the same BrowsingInstance or
|
| + // not. If |new_instance| is in the same BrowsingInstance as
|
| + // |old_instance|, this will be done as part of CreateOpenerProxies above;
|
| + // otherwise, we do this here. We will still check whether two frames are
|
| + // in the same BrowsingInstance before we allow them to interact (e.g.,
|
| + // postMessage).
|
| frame_tree_node_->frame_tree()->CreateProxiesForSiteInstance(
|
| frame_tree_node_, new_instance);
|
| }
|
| @@ -1883,9 +1887,6 @@ void RenderFrameHostManager::EnsureRenderViewInitialized(
|
| if (render_view_host->IsRenderViewLive())
|
| return;
|
|
|
| - // Recreate the opener chain.
|
| - CreateOpenerProxiesIfNeeded(instance);
|
| -
|
| // If the proxy in |instance| doesn't exist, this RenderView is not swapped
|
| // out and shouldn't be reinitialized here.
|
| RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance);
|
| @@ -2460,19 +2461,6 @@ RenderFrameHostManager::GetAllProxyHostsForTesting() {
|
| return result;
|
| }
|
|
|
| -void RenderFrameHostManager::CreateOpenerProxiesIfNeeded(
|
| - SiteInstance* instance) {
|
| - FrameTreeNode* opener = frame_tree_node_->opener();
|
| - if (!opener)
|
| - return;
|
| -
|
| - // TODO(alexmos): This should process all openers in the current frame tree,
|
| - // not just current node's opener.
|
| -
|
| - // Create proxies for the opener chain.
|
| - opener->render_manager()->CreateOpenerProxies(instance);
|
| -}
|
| -
|
| void RenderFrameHostManager::CollectOpenerFrameTrees(
|
| std::vector<FrameTree*>* opener_frame_trees,
|
| base::hash_set<FrameTreeNode*>* nodes_with_back_links) {
|
| @@ -2488,7 +2476,9 @@ void RenderFrameHostManager::CollectOpenerFrameTrees(
|
| }
|
| }
|
|
|
| -void RenderFrameHostManager::CreateOpenerProxies(SiteInstance* instance) {
|
| +void RenderFrameHostManager::CreateOpenerProxies(
|
| + SiteInstance* instance,
|
| + FrameTreeNode* skip_this_node) {
|
| std::vector<FrameTree*> opener_frame_trees;
|
| base::hash_set<FrameTreeNode*> nodes_with_back_links;
|
|
|
| @@ -2502,7 +2492,7 @@ void RenderFrameHostManager::CreateOpenerProxies(SiteInstance* instance) {
|
| opener_frame_trees[i]
|
| ->root()
|
| ->render_manager()
|
| - ->CreateOpenerProxiesForFrameTree(instance);
|
| + ->CreateOpenerProxiesForFrameTree(instance, skip_this_node);
|
| }
|
|
|
| // Set openers for nodes in |nodes_with_back_links| in a second pass.
|
| @@ -2529,39 +2519,50 @@ void RenderFrameHostManager::CreateOpenerProxies(SiteInstance* instance) {
|
| }
|
|
|
| void RenderFrameHostManager::CreateOpenerProxiesForFrameTree(
|
| - SiteInstance* instance) {
|
| - // If any of the RenderViewHosts (current, pending, or swapped out) for this
|
| - // FrameTree has the same SiteInstance, then we can return early, since
|
| - // proxies for other nodes in the tree should also exist (when in
|
| - // site-per-process mode). An exception is if we are in
|
| - // IsSwappedOutStateForbidden mode and find a pending RenderViewHost: in this
|
| - // case, we should still create a proxy, which will allow communicating with
|
| - // the opener until the pending RenderView commits, or if the pending
|
| - // navigation is canceled.
|
| - FrameTree* frame_tree = frame_tree_node_->frame_tree();
|
| - RenderViewHostImpl* rvh = frame_tree->GetRenderViewHost(instance);
|
| - bool need_proxy_for_pending_rvh =
|
| - SiteIsolationPolicy::IsSwappedOutStateForbidden() &&
|
| - (rvh == pending_render_view_host());
|
| - if (rvh && rvh->IsRenderViewLive() && !need_proxy_for_pending_rvh)
|
| + SiteInstance* instance,
|
| + FrameTreeNode* skip_this_node) {
|
| + // Currently, this function is only called on main frames. It should
|
| + // actually work correctly for subframes as well, so if that need ever
|
| + // arises, it should be sufficient to remove this DCHECK.
|
| + DCHECK(frame_tree_node_->IsMainFrame());
|
| +
|
| + if (frame_tree_node_ == skip_this_node)
|
| return;
|
|
|
| - if (SiteIsolationPolicy::IsSwappedOutStateForbidden()) {
|
| - // Ensure that all the nodes in the opener's frame tree have
|
| - // RenderFrameProxyHosts for the new SiteInstance.
|
| - frame_tree->CreateProxiesForSiteInstance(nullptr, instance);
|
| - } else if (rvh && !rvh->IsRenderViewLive()) {
|
| - EnsureRenderViewInitialized(rvh, instance);
|
| + FrameTree* frame_tree = frame_tree_node_->frame_tree();
|
| + if (SiteIsolationPolicy::AreCrossProcessFramesPossible()) {
|
| + // Ensure that all the nodes in the opener's FrameTree have
|
| + // RenderFrameProxyHosts for the new SiteInstance. Only pass the node to
|
| + // be skipped if it's in the same FrameTree.
|
| + if (skip_this_node && skip_this_node->frame_tree() != frame_tree)
|
| + skip_this_node = nullptr;
|
| + frame_tree->CreateProxiesForSiteInstance(skip_this_node, instance);
|
| } else {
|
| - // Create a swapped out RenderView in the given SiteInstance if none exists,
|
| - // setting its opener to the given route_id. Since the opener can point to
|
| - // a subframe, do this on the root frame of the opener's frame tree.
|
| - // Return the new view's route_id.
|
| - frame_tree->root()->render_manager()->
|
| - CreateRenderFrame(instance, nullptr,
|
| - CREATE_RF_FOR_MAIN_FRAME_NAVIGATION |
|
| - CREATE_RF_SWAPPED_OUT | CREATE_RF_HIDDEN,
|
| - nullptr);
|
| + // If any of the RenderViewHosts (current, pending, or swapped out) for this
|
| + // FrameTree has the same SiteInstance, then we can return early and reuse
|
| + // them. An exception is if we are in IsSwappedOutStateForbidden mode and
|
| + // find a pending RenderViewHost: in this case, we should still create a
|
| + // proxy, which will allow communicating with the opener until the pending
|
| + // RenderView commits, or if the pending navigation is canceled.
|
| + RenderViewHostImpl* rvh = frame_tree->GetRenderViewHost(instance);
|
| + bool need_proxy_for_pending_rvh =
|
| + SiteIsolationPolicy::IsSwappedOutStateForbidden() &&
|
| + (rvh == pending_render_view_host());
|
| + if (rvh && rvh->IsRenderViewLive() && !need_proxy_for_pending_rvh)
|
| + return;
|
| +
|
| + if (rvh && !rvh->IsRenderViewLive()) {
|
| + EnsureRenderViewInitialized(rvh, instance);
|
| + } else {
|
| + // Create a swapped out RenderView in the given SiteInstance if none
|
| + // exists. Since an opener can point to a subframe, do this on the root
|
| + // frame of the current opener's frame tree.
|
| + frame_tree->root()->render_manager()->
|
| + CreateRenderFrame(instance, nullptr,
|
| + CREATE_RF_FOR_MAIN_FRAME_NAVIGATION |
|
| + CREATE_RF_SWAPPED_OUT | CREATE_RF_HIDDEN,
|
| + nullptr);
|
| + }
|
| }
|
| }
|
|
|
|
|