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 29 matching lines...) Expand all Loading... | |
| 40 #include "content/public/browser/render_widget_host_view.h" | 40 #include "content/public/browser/render_widget_host_view.h" | 
| 41 #include "content/public/browser/user_metrics.h" | 41 #include "content/public/browser/user_metrics.h" | 
| 42 #include "content/public/browser/web_ui_controller.h" | 42 #include "content/public/browser/web_ui_controller.h" | 
| 43 #include "content/public/common/browser_plugin_guest_mode.h" | 43 #include "content/public/common/browser_plugin_guest_mode.h" | 
| 44 #include "content/public/common/content_switches.h" | 44 #include "content/public/common/content_switches.h" | 
| 45 #include "content/public/common/referrer.h" | 45 #include "content/public/common/referrer.h" | 
| 46 #include "content/public/common/url_constants.h" | 46 #include "content/public/common/url_constants.h" | 
| 47 | 47 | 
| 48 namespace content { | 48 namespace content { | 
| 49 | 49 | 
| 50 namespace { | |
| 51 | |
| 52 // Helper function to add the FrameTree of the current node's opener to the | |
| 
 
Charlie Reis
2015/08/06 17:35:06
nit: s/current/given/
 
alexmos
2015/08/06 17:42:57
Done.
 
 | |
| 53 // list of |opener_trees|, if it doesn't exist there already. |visited_index| | |
| 54 // indicates which FrameTrees in |opener_trees| have already been visited | |
| 55 // (i.e., those at indices less than |visited_index|). |nodes_with_back_links| | |
| 56 // collects FrameTreeNodes with openers in FrameTrees that have already been | |
| 57 // visited (such as those with cycles). This function is intended to be used | |
| 58 // with FrameTree::ForEach, so it always returns true to visit all nodes in the | |
| 59 // tree. | |
| 60 bool OpenerForFrameTreeNode( | |
| 61 size_t visited_index, | |
| 62 std::vector<FrameTree*>* opener_trees, | |
| 63 base::hash_set<FrameTreeNode*>* nodes_with_back_links, | |
| 64 FrameTreeNode* node) { | |
| 65 if (!node->opener()) | |
| 66 return true; | |
| 67 | |
| 68 FrameTree* opener_tree = node->opener()->frame_tree(); | |
| 69 | |
| 70 const auto& existing_tree_it = | |
| 71 std::find(opener_trees->begin(), opener_trees->end(), opener_tree); | |
| 72 if (existing_tree_it == opener_trees->end()) { | |
| 73 // This is a new opener tree that we will need to process. | |
| 74 opener_trees->push_back(opener_tree); | |
| 75 } else { | |
| 76 // If this tree is already on our processing list *and* we have visited it, | |
| 77 // then this node's opener is a back link. This means the node will need | |
| 78 // special treatment to process its opener. | |
| 79 size_t position = std::distance(opener_trees->begin(), existing_tree_it); | |
| 80 if (position < visited_index) | |
| 81 nodes_with_back_links->insert(node); | |
| 82 } | |
| 83 return true; | |
| 84 } | |
| 85 | |
| 86 } // namespace | |
| 87 | |
| 50 // A helper class to hold all frame proxies and register as a | 88 // A helper class to hold all frame proxies and register as a | 
| 51 // RenderProcessHostObserver for them. | 89 // RenderProcessHostObserver for them. | 
| 52 class RenderFrameHostManager::RenderFrameProxyHostMap | 90 class RenderFrameHostManager::RenderFrameProxyHostMap | 
| 53 : public RenderProcessHostObserver { | 91 : public RenderProcessHostObserver { | 
| 54 public: | 92 public: | 
| 55 using MapType = base::hash_map<int32, RenderFrameProxyHost*>; | 93 using MapType = base::hash_map<int32, RenderFrameProxyHost*>; | 
| 56 | 94 | 
| 57 RenderFrameProxyHostMap(RenderFrameHostManager* manager); | 95 RenderFrameProxyHostMap(RenderFrameHostManager* manager); | 
| 58 ~RenderFrameProxyHostMap() override; | 96 ~RenderFrameProxyHostMap() override; | 
| 59 | 97 | 
| (...skipping 2331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2391 result.insert(proxy_hosts_->begin(), proxy_hosts_->end()); | 2429 result.insert(proxy_hosts_->begin(), proxy_hosts_->end()); | 
| 2392 return result; | 2430 return result; | 
| 2393 } | 2431 } | 
| 2394 | 2432 | 
| 2395 void RenderFrameHostManager::CreateOpenerProxiesIfNeeded( | 2433 void RenderFrameHostManager::CreateOpenerProxiesIfNeeded( | 
| 2396 SiteInstance* instance) { | 2434 SiteInstance* instance) { | 
| 2397 FrameTreeNode* opener = frame_tree_node_->opener(); | 2435 FrameTreeNode* opener = frame_tree_node_->opener(); | 
| 2398 if (!opener) | 2436 if (!opener) | 
| 2399 return; | 2437 return; | 
| 2400 | 2438 | 
| 2439 // TODO(alexmos): This should process all openers in the current frame tree, | |
| 2440 // not just current node's opener. | |
| 2441 | |
| 2401 // Create proxies for the opener chain. | 2442 // Create proxies for the opener chain. | 
| 2402 opener->render_manager()->CreateOpenerProxies(instance); | 2443 opener->render_manager()->CreateOpenerProxies(instance); | 
| 2403 } | 2444 } | 
| 2404 | 2445 | 
| 2446 void RenderFrameHostManager::CollectOpenerFrameTrees( | |
| 2447 std::vector<FrameTree*>* opener_frame_trees, | |
| 2448 base::hash_set<FrameTreeNode*>* nodes_with_back_links) { | |
| 2449 CHECK(opener_frame_trees); | |
| 2450 opener_frame_trees->push_back(frame_tree_node_->frame_tree()); | |
| 2451 | |
| 2452 size_t visited_index = 0; | |
| 2453 while (visited_index < opener_frame_trees->size()) { | |
| 2454 FrameTree* frame_tree = (*opener_frame_trees)[visited_index]; | |
| 2455 visited_index++; | |
| 2456 frame_tree->ForEach(base::Bind(&OpenerForFrameTreeNode, visited_index, | |
| 2457 opener_frame_trees, nodes_with_back_links)); | |
| 2458 } | |
| 2459 } | |
| 2460 | |
| 2405 void RenderFrameHostManager::CreateOpenerProxies(SiteInstance* instance) { | 2461 void RenderFrameHostManager::CreateOpenerProxies(SiteInstance* instance) { | 
| 2406 // If this tab has an opener, recursively create proxies for the nodes on its | 2462 std::vector<FrameTree*> opener_frame_trees; | 
| 2407 // frame tree. | 2463 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 | 2464 | 
| 2465 CollectOpenerFrameTrees(&opener_frame_trees, &nodes_with_back_links); | |
| 2466 | |
| 2467 // Create opener proxies for frame trees, processing furthest openers from | |
| 2468 // this node first and this node last. In the common case without cycles, | |
| 2469 // this will ensure that each tree's openers are created before the tree's | |
| 2470 // nodes need to reference them. | |
| 2471 for (int i = opener_frame_trees.size() - 1; i >= 0; i--) { | |
| 2472 opener_frame_trees[i] | |
| 2473 ->root() | |
| 2474 ->render_manager() | |
| 2475 ->CreateOpenerProxiesForFrameTree(instance); | |
| 2476 } | |
| 2477 | |
| 2478 // TODO(alexmos): Set openers for nodes in |nodes_with_back_links| in a | |
| 2479 // second pass. The proxies created at these FrameTreeNodes in | |
| 2480 // CreateOpenerProxiesForFrameTree won't have their opener routing ID | |
| 2481 // available when created due to cycles or back links in the opener chain. | |
| 2482 // They must have their openers updated as a separate step after proxy | |
| 2483 // creation. | |
| 2484 } | |
| 2485 | |
| 2486 void RenderFrameHostManager::CreateOpenerProxiesForFrameTree( | |
| 2487 SiteInstance* instance) { | |
| 2417 // If any of the RenderViewHosts (current, pending, or swapped out) for this | 2488 // If any of the RenderViewHosts (current, pending, or swapped out) for this | 
| 2418 // FrameTree has the same SiteInstance, then we can return early, since | 2489 // FrameTree has the same SiteInstance, then we can return early, since | 
| 2419 // proxies for other nodes in the tree should also exist (when in | 2490 // proxies for other nodes in the tree should also exist (when in | 
| 2420 // site-per-process mode). An exception is if we are in | 2491 // site-per-process mode). An exception is if we are in | 
| 2421 // IsSwappedOutStateForbidden mode and find a pending RenderViewHost: in this | 2492 // IsSwappedOutStateForbidden mode and find a pending RenderViewHost: in this | 
| 2422 // case, we should still create a proxy, which will allow communicating with | 2493 // case, we should still create a proxy, which will allow communicating with | 
| 2423 // the opener until the pending RenderView commits, or if the pending | 2494 // the opener until the pending RenderView commits, or if the pending | 
| 2424 // navigation is canceled. | 2495 // navigation is canceled. | 
| 2425 FrameTree* frame_tree = frame_tree_node_->frame_tree(); | 2496 FrameTree* frame_tree = frame_tree_node_->frame_tree(); | 
| 2426 RenderViewHostImpl* rvh = frame_tree->GetRenderViewHost(instance); | 2497 RenderViewHostImpl* rvh = frame_tree->GetRenderViewHost(instance); | 
| (...skipping 25 matching lines...) Expand all Loading... | |
| 2452 int RenderFrameHostManager::GetOpenerRoutingID(SiteInstance* instance) { | 2523 int RenderFrameHostManager::GetOpenerRoutingID(SiteInstance* instance) { | 
| 2453 if (!frame_tree_node_->opener()) | 2524 if (!frame_tree_node_->opener()) | 
| 2454 return MSG_ROUTING_NONE; | 2525 return MSG_ROUTING_NONE; | 
| 2455 | 2526 | 
| 2456 return frame_tree_node_->opener() | 2527 return frame_tree_node_->opener() | 
| 2457 ->render_manager() | 2528 ->render_manager() | 
| 2458 ->GetRoutingIdForSiteInstance(instance); | 2529 ->GetRoutingIdForSiteInstance(instance); | 
| 2459 } | 2530 } | 
| 2460 | 2531 | 
| 2461 } // namespace content | 2532 } // namespace content | 
| OLD | NEW |