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

Side by Side Diff: content/browser/frame_host/render_frame_host_manager.cc

Issue 1268153002: Refactor CreateOpenerProxies to support updates to frame openers. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: 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 unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/frame_host/render_frame_host_manager.h" 5 #include "content/browser/frame_host/render_frame_host_manager.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 int exit_code) { 162 int exit_code) {
163 manager_->RendererProcessClosing(host); 163 manager_->RendererProcessClosing(host);
164 } 164 }
165 165
166 // static 166 // static
167 bool RenderFrameHostManager::ClearRFHsPendingShutdown(FrameTreeNode* node) { 167 bool RenderFrameHostManager::ClearRFHsPendingShutdown(FrameTreeNode* node) {
168 node->render_manager()->pending_delete_hosts_.clear(); 168 node->render_manager()->pending_delete_hosts_.clear();
169 return true; 169 return true;
170 } 170 }
171 171
172 namespace {
Charlie Reis 2015/08/05 23:59:09 Nit: This should go above the RFHM:: stuff above.
alexmos 2015/08/06 17:05:39 Done.
173
174 // Helper function to add the FrameTree of the current node's opener
Charlie Reis 2015/08/05 23:59:09 s/current/given/
alexmos 2015/08/06 17:05:39 Done.
175 // to the list of |opener_trees|, if it doesn't exist there already.
176 // |visited_index| indicates which FrameTrees in |opener_trees| have already
177 // been visited (those at indexes less than |visited_index|).
Charlie Reis 2015/08/05 23:59:09 nit: (i.e., those at indices...
alexmos 2015/08/06 17:05:39 Done.
178 // |nodes_with_back_links|, if not null, collects FrameTreeNodes with openers
Charlie Reis 2015/08/05 23:59:09 Why would it be null? I don't see a case where th
alexmos 2015/08/06 17:05:39 Removed from description and the if statement belo
179 // that point to FrameTrees that have already been visited (such as those with
Charlie Reis 2015/08/05 23:59:09 nit: with openers in FrameTrees that...
alexmos 2015/08/06 17:05:39 Done.
180 // cycles).
181 bool OpenerForFrameTreeNode(
Charlie Reis 2015/08/05 23:59:09 Does this need to return a bool? Looks like it al
alexmos 2015/08/06 17:05:39 Done. Yes, it's returning true just so it visits
182 size_t visited_index,
183 std::vector<FrameTree*>* opener_trees,
184 base::hash_set<FrameTreeNode*>* nodes_with_back_links,
185 FrameTreeNode* node) {
Charlie Reis 2015/08/05 23:59:09 nit: Let's list |node| first, since it's the main
alexmos 2015/08/06 17:05:39 Hmm, I can't do that given how FrameTree::ForEach
Charlie Reis 2015/08/06 17:35:06 Acknowledged.
186 if (!node->opener())
187 return true;
188
189 FrameTree* opener_tree = node->opener()->frame_tree();
190
191 const auto& existing_tree_it =
192 std::find(opener_trees->begin(), opener_trees->end(), opener_tree);
193 if (existing_tree_it == opener_trees->end()) {
194 // This is a new opener tree that we will need to process.
195 opener_trees->push_back(opener_tree);
196 } else if (nodes_with_back_links) {
197 // If this tree is already on our processing list *and* we have visited it,
198 // then this node's opener is a back link. This means the node will need
199 // special treatment to process its opener.
200 size_t position = std::distance(opener_trees->begin(), existing_tree_it);
201 if (position < visited_index)
202 nodes_with_back_links->insert(node);
203 }
204 return true;
205 }
206
207 } // namespace
208
172 RenderFrameHostManager::RenderFrameHostManager( 209 RenderFrameHostManager::RenderFrameHostManager(
173 FrameTreeNode* frame_tree_node, 210 FrameTreeNode* frame_tree_node,
174 RenderFrameHostDelegate* render_frame_delegate, 211 RenderFrameHostDelegate* render_frame_delegate,
175 RenderViewHostDelegate* render_view_delegate, 212 RenderViewHostDelegate* render_view_delegate,
176 RenderWidgetHostDelegate* render_widget_delegate, 213 RenderWidgetHostDelegate* render_widget_delegate,
177 Delegate* delegate) 214 Delegate* delegate)
178 : frame_tree_node_(frame_tree_node), 215 : frame_tree_node_(frame_tree_node),
179 delegate_(delegate), 216 delegate_(delegate),
180 render_frame_delegate_(render_frame_delegate), 217 render_frame_delegate_(render_frame_delegate),
181 render_view_delegate_(render_view_delegate), 218 render_view_delegate_(render_view_delegate),
(...skipping 2209 matching lines...) Expand 10 before | Expand all | Expand 10 after
2391 result.insert(proxy_hosts_->begin(), proxy_hosts_->end()); 2428 result.insert(proxy_hosts_->begin(), proxy_hosts_->end());
2392 return result; 2429 return result;
2393 } 2430 }
2394 2431
2395 void RenderFrameHostManager::CreateOpenerProxiesIfNeeded( 2432 void RenderFrameHostManager::CreateOpenerProxiesIfNeeded(
2396 SiteInstance* instance) { 2433 SiteInstance* instance) {
2397 FrameTreeNode* opener = frame_tree_node_->opener(); 2434 FrameTreeNode* opener = frame_tree_node_->opener();
2398 if (!opener) 2435 if (!opener)
2399 return; 2436 return;
2400 2437
2438 // TODO(alexmos): This should process all openers in the current frame tree,
2439 // not just current node's opener.
alexmos 2015/08/05 17:45:05 I noticed that this actually has a bug today: if A
Charlie Reis 2015/08/05 23:59:09 Nice catch. Yes, a separate CL is fine, either be
alexmos 2015/08/06 17:05:39 OK, will do in a later CL.
2440
2401 // Create proxies for the opener chain. 2441 // Create proxies for the opener chain.
2402 opener->render_manager()->CreateOpenerProxies(instance); 2442 opener->render_manager()->CreateOpenerProxies(instance);
2403 } 2443 }
2404 2444
2445 void RenderFrameHostManager::CollectOpenerFrameTrees(
2446 std::vector<FrameTree*>* opener_frame_trees,
2447 base::hash_set<FrameTreeNode*>* nodes_with_back_links) {
2448 CHECK(opener_frame_trees);
2449 opener_frame_trees->push_back(frame_tree_node_->frame_tree());
2450
2451 size_t visited_index = 0;
2452 while (visited_index < opener_frame_trees->size()) {
2453 FrameTree* frame_tree = (*opener_frame_trees)[visited_index];
2454 visited_index++;
2455 frame_tree->ForEach(base::Bind(&OpenerForFrameTreeNode, visited_index,
2456 opener_frame_trees, nodes_with_back_links));
2457 }
2458 }
2459
2405 void RenderFrameHostManager::CreateOpenerProxies(SiteInstance* instance) { 2460 void RenderFrameHostManager::CreateOpenerProxies(SiteInstance* instance) {
2406 // If this tab has an opener, recursively create proxies for the nodes on its 2461 std::vector<FrameTree*> opener_frame_trees;
2407 // frame tree. 2462 base::hash_set<FrameTreeNode*> nodes_with_back_links;
2408 // TODO(alexmos): Once we allow frame openers to be updated (which can happen
2409 // via window.open(url, "target_frame")), this will need to be resilient to
2410 // cycles. It will also need to handle tabs that have multiple openers (e.g.,
2411 // main frame and subframe could have different openers, each of which must
2412 // be traversed).
2413 FrameTreeNode* opener = frame_tree_node_->opener();
2414 if (opener)
2415 opener->render_manager()->CreateOpenerProxies(instance);
2416 2463
2464 CollectOpenerFrameTrees(&opener_frame_trees, &nodes_with_back_links);
2465
2466 // Create opener proxies for frame trees, processing furthest openers from
2467 // this node first and this node last. In the common case without cycles,
2468 // this will ensure that each tree's openers are created before the tree's
2469 // nodes need to reference them.
2470 for (int i = opener_frame_trees.size() - 1; i >= 0; i--) {
2471 opener_frame_trees[i]
2472 ->root()
2473 ->render_manager()
2474 ->CreateOpenerProxiesForFrameTree(instance);
2475 }
2476
2477 // TODO(alexmos): Set openers for nodes in |nodes_with_back_links| in a
2478 // second pass. The proxies created at these FrameTreeNodes in
2479 // CreateOpenerProxiesForFrameTree won't have their opener routing ID
2480 // available when created due to cycles or back links in the opener chain.
2481 // They must have their openers updated as a separate step after proxy
2482 // creation.
2483 }
2484
2485 void RenderFrameHostManager::CreateOpenerProxiesForFrameTree(
2486 SiteInstance* instance) {
2417 // If any of the RenderViewHosts (current, pending, or swapped out) for this 2487 // If any of the RenderViewHosts (current, pending, or swapped out) for this
2418 // FrameTree has the same SiteInstance, then we can return early, since 2488 // FrameTree has the same SiteInstance, then we can return early, since
2419 // proxies for other nodes in the tree should also exist (when in 2489 // proxies for other nodes in the tree should also exist (when in
2420 // site-per-process mode). An exception is if we are in 2490 // site-per-process mode). An exception is if we are in
2421 // IsSwappedOutStateForbidden mode and find a pending RenderViewHost: in this 2491 // IsSwappedOutStateForbidden mode and find a pending RenderViewHost: in this
2422 // case, we should still create a proxy, which will allow communicating with 2492 // case, we should still create a proxy, which will allow communicating with
2423 // the opener until the pending RenderView commits, or if the pending 2493 // the opener until the pending RenderView commits, or if the pending
2424 // navigation is canceled. 2494 // navigation is canceled.
2425 FrameTree* frame_tree = frame_tree_node_->frame_tree(); 2495 FrameTree* frame_tree = frame_tree_node_->frame_tree();
2426 RenderViewHostImpl* rvh = frame_tree->GetRenderViewHost(instance); 2496 RenderViewHostImpl* rvh = frame_tree->GetRenderViewHost(instance);
(...skipping 25 matching lines...) Expand all
2452 int RenderFrameHostManager::GetOpenerRoutingID(SiteInstance* instance) { 2522 int RenderFrameHostManager::GetOpenerRoutingID(SiteInstance* instance) {
2453 if (!frame_tree_node_->opener()) 2523 if (!frame_tree_node_->opener())
2454 return MSG_ROUTING_NONE; 2524 return MSG_ROUTING_NONE;
2455 2525
2456 return frame_tree_node_->opener() 2526 return frame_tree_node_->opener()
2457 ->render_manager() 2527 ->render_manager()
2458 ->GetRoutingIdForSiteInstance(instance); 2528 ->GetRoutingIdForSiteInstance(instance);
2459 } 2529 }
2460 2530
2461 } // namespace content 2531 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698