| 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 given node's opener to the list | 
 |    53 // 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 |