Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(134)

Unified Diff: content/browser/frame_host/render_frame_host_manager.cc

Issue 1309043003: Handle frame openers in the same FrameTree when navigating subframes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@opener-cycle-detection
Patch Set: Add comment for the DCHECK Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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);
+ }
}
}
« no previous file with comments | « content/browser/frame_host/render_frame_host_manager.h ('k') | content/browser/frame_host/render_frame_proxy_host.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698