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

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: Cleanup 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 c2ef320311620f6587e9483f41ed7abcb146846c..c94ce33e96601675bbb196dafbd43b20eb65def7 100644
--- a/content/browser/frame_host/render_frame_host_manager.cc
+++ b/content/browser/frame_host/render_frame_host_manager.cc
@@ -414,7 +414,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(),
Charlie Reis 2015/08/31 20:49:43 Looks like we can call this inside subframe RFHMs,
alexmos 2015/09/01 22:12:28 Please see my response on the DCHECK.
+ frame_tree_node_);
if (!InitRenderView(dest_render_frame_host->render_view_host(),
MSG_ROUTING_NONE,
frame_tree_node_->IsMainFrame()))
@@ -1039,7 +1040,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_);
Charlie Reis 2015/08/31 20:49:43 As above, I think this can happen in a subframe an
alexmos 2015/09/01 22:12:28 Please see my response on the DCHECK.
if (!InitRenderView(navigation_rfh->render_view_host(), MSG_ROUTING_NONE,
frame_tree_node_->IsMainFrame())) {
return nullptr;
@@ -1577,15 +1578,21 @@ void RenderFrameHostManager::CreateProxiesForNewRenderFrameHost(
int* create_render_frame_flags) {
// 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).
+ CreateOpenerProxies(new_instance, frame_tree_node_);
+ else if (SiteIsolationPolicy::AreCrossProcessFramesPossible()) {
Charlie Reis 2015/08/31 20:49:43 Style nit: The earlier if branch needs braces if t
alexmos 2015/09/01 22:12:28 Done.
+ // 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);
+ }
+
+ if (SiteIsolationPolicy::AreCrossProcessFramesPossible()) {
// RenderFrames in different processes from their parent RenderFrames
// in the frame tree require RenderWidgets for rendering and processing
// input events.
@@ -1876,9 +1883,6 @@ void RenderFrameHostManager::EnsureRenderViewInitialized(
if (render_view_host->IsRenderViewLive())
return;
- // Recreate the opener chain.
- CreateOpenerProxiesIfNeeded(instance);
alexmos 2015/08/25 22:38:08 I don't think this is actually needed. EnsureRend
Charlie Reis 2015/08/31 20:49:43 Acknowledged.
-
// If the proxy in |instance| doesn't exist, this RenderView is not swapped
// out and shouldn't be reinitialized here.
RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance);
@@ -2453,19 +2457,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) {
@@ -2481,7 +2472,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;
@@ -2495,7 +2488,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.
@@ -2522,39 +2515,46 @@ 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)
alexmos 2015/08/25 22:38:08 I've moved this logic to only be used when not in
Charlie Reis 2015/08/31 20:49:43 Acknowledged.
+ SiteInstance* instance,
+ FrameTreeNode* skip_this_node) {
+ DCHECK(frame_tree_node_->IsMainFrame());
Charlie Reis 2015/08/31 20:49:43 This doesn't look like it's true. There's a few c
alexmos 2015/09/01 22:12:27 Currently, CreateOpenerProxies always calls Create
Charlie Reis 2015/09/01 23:37:26 Oh, I see. Yes, that's a little subtle. I think
alexmos 2015/09/02 00:02:11 Thanks, I kept the check and added a comment above
+ 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()) {
alexmos 2015/08/25 22:38:08 I think we've been meaning to change this to AreCr
Charlie Reis 2015/08/31 20:49:43 Acknowledged.
+ // 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);
alexmos 2015/08/25 22:38:08 We were always passing nullptr here, assuming none
Charlie Reis 2015/08/31 20:49:43 Acknowledged.
} 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);
+ }
}
}

Powered by Google App Engine
This is Rietveld 408576698