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

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: Charlie's comments 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 29 matching lines...) Expand all
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698