Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |