blob: 709cc26487b4005cded07a2632027f02848ff3a7 [file] [log] [blame]
[email protected]9b159a52013-10-03 17:24:551// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]d4a8ca482013-10-30 21:06:405#include "content/browser/frame_host/frame_tree_node.h"
[email protected]9b159a52013-10-03 17:24:556
7#include <queue>
8
clamy71a42ec2014-10-02 18:43:229#include "base/command_line.h"
[email protected]9b159a52013-10-03 17:24:5510#include "base/stl_util.h"
[email protected]94d0cc12013-12-18 00:07:4111#include "content/browser/frame_host/frame_tree.h"
[email protected]190b8c52013-11-09 01:35:4412#include "content/browser/frame_host/navigator.h"
[email protected]d4a8ca482013-10-30 21:06:4013#include "content/browser/frame_host/render_frame_host_impl.h"
[email protected]94d0cc12013-12-18 00:07:4114#include "content/browser/renderer_host/render_view_host_impl.h"
clamy71a42ec2014-10-02 18:43:2215#include "content/public/common/content_switches.h"
[email protected]9b159a52013-10-03 17:24:5516
17namespace content {
18
[email protected]741fd682013-11-08 08:26:5519int64 FrameTreeNode::next_frame_tree_node_id_ = 1;
[email protected]9b159a52013-10-03 17:24:5520
[email protected]94d0cc12013-12-18 00:07:4121FrameTreeNode::FrameTreeNode(FrameTree* frame_tree,
22 Navigator* navigator,
[email protected]92404c62013-12-04 16:40:4623 RenderFrameHostDelegate* render_frame_delegate,
[email protected]fa944cb82013-11-15 17:51:2124 RenderViewHostDelegate* render_view_delegate,
25 RenderWidgetHostDelegate* render_widget_delegate,
[email protected]b0936d22013-11-28 06:47:3626 RenderFrameHostManager::Delegate* manager_delegate,
[email protected]52913802013-12-10 05:52:1827 const std::string& name)
[email protected]bffc8302014-01-23 20:52:1628 : frame_tree_(frame_tree),
29 navigator_(navigator),
30 render_manager_(this,
31 render_frame_delegate,
32 render_view_delegate,
33 render_widget_delegate,
34 manager_delegate),
35 frame_tree_node_id_(next_frame_tree_node_id_++),
naskoa7064ad6e2015-01-15 18:44:5636 parent_(NULL),
alexmos6b294562015-03-05 19:24:1037 replication_state_(name),
38 effective_sandbox_flags_(SandboxFlags::NONE) {
alexmos998581d2015-01-22 01:01:5939}
[email protected]9b159a52013-10-03 17:24:5540
41FrameTreeNode::~FrameTreeNode() {
avi83883c82014-12-23 00:08:4942 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
43 switches::kEnableBrowserSideNavigation)) {
clamy71a42ec2014-10-02 18:43:2244 navigator_->CancelNavigation(this);
45 }
[email protected]9b159a52013-10-03 17:24:5546}
47
[email protected]94d0cc12013-12-18 00:07:4148bool FrameTreeNode::IsMainFrame() const {
49 return frame_tree_->root() == this;
50}
51
52void FrameTreeNode::AddChild(scoped_ptr<FrameTreeNode> child,
dgroganfb22f9a2014-10-20 21:32:3253 int process_id,
[email protected]94d0cc12013-12-18 00:07:4154 int frame_routing_id) {
dgroganfb22f9a2014-10-20 21:32:3255 // Child frame must always be created in the same process as the parent.
56 CHECK_EQ(process_id, render_manager_.current_host()->GetProcess()->GetID());
57
[email protected]94d0cc12013-12-18 00:07:4158 // Initialize the RenderFrameHost for the new node. We always create child
59 // frames in the same SiteInstance as the current frame, and they can swap to
60 // a different one if they navigate away.
61 child->render_manager()->Init(
62 render_manager_.current_host()->GetSiteInstance()->GetBrowserContext(),
63 render_manager_.current_host()->GetSiteInstance(),
64 render_manager_.current_host()->GetRoutingID(),
65 frame_routing_id);
[email protected]bffc8302014-01-23 20:52:1666 child->set_parent(this);
[email protected]9b159a52013-10-03 17:24:5567 children_.push_back(child.release());
68}
69
[email protected]741fd682013-11-08 08:26:5570void FrameTreeNode::RemoveChild(FrameTreeNode* child) {
[email protected]9b159a52013-10-03 17:24:5571 std::vector<FrameTreeNode*>::iterator iter;
72
73 for (iter = children_.begin(); iter != children_.end(); ++iter) {
[email protected]741fd682013-11-08 08:26:5574 if ((*iter) == child)
[email protected]9b159a52013-10-03 17:24:5575 break;
76 }
77
[email protected]bffc8302014-01-23 20:52:1678 if (iter != children_.end()) {
[email protected]14266072014-04-19 00:35:2079 // Subtle: we need to make sure the node is gone from the tree before
80 // observers are notified of its deletion.
81 scoped_ptr<FrameTreeNode> node_to_delete(*iter);
82 children_.weak_erase(iter);
83 node_to_delete->set_parent(NULL);
84 node_to_delete.reset();
[email protected]bffc8302014-01-23 20:52:1685 }
[email protected]9b159a52013-10-03 17:24:5586}
87
[email protected]81c6c5e2014-02-13 20:20:0788void FrameTreeNode::ResetForNewProcess() {
[email protected]9b159a52013-10-03 17:24:5589 current_url_ = GURL();
[email protected]482ce3c2013-11-27 18:17:0990
[email protected]482ce3c2013-11-27 18:17:0991 // The children may not have been cleared if a cross-process navigation
92 // commits before the old process cleans everything up. Make sure the child
[email protected]81c6c5e2014-02-13 20:20:0793 // nodes get deleted before swapping to a new process.
[email protected]14266072014-04-19 00:35:2094 ScopedVector<FrameTreeNode> old_children = children_.Pass();
naskoaeca57b2015-02-13 00:50:4695
96 // Loop over all children removing them from the FrameTree. This will ensure
97 // that nodes are properly removed from the tree and notifications are sent.
98 // Note: since the |children_| vector is now empty, the calls into RemoveChild
99 // will be a noop and will not result in repeatedly traversing the list.
100 for (const auto& child : old_children)
101 frame_tree_->RemoveFrame(child);
102
[email protected]14266072014-04-19 00:35:20103 old_children.clear(); // May notify observers.
[email protected]9b159a52013-10-03 17:24:55104}
105
mlamouria85eb3f2015-01-26 17:36:27106bool FrameTreeNode::IsDescendantOf(FrameTreeNode* other) const {
107 if (!other || !other->child_count())
108 return false;
109
110 for (FrameTreeNode* node = parent(); node; node = node->parent()) {
111 if (node == other)
112 return true;
113 }
114
115 return false;
116}
117
fdegansbda82dd2015-03-05 17:00:08118bool FrameTreeNode::IsLoading() const {
119 RenderFrameHostImpl* current_frame_host =
120 render_manager_.current_frame_host();
121 RenderFrameHostImpl* pending_frame_host =
122 render_manager_.pending_frame_host();
123
124 DCHECK(current_frame_host);
125 // TODO(fdegans): Change the implementation logic for PlzNavigate once
126 // DidStartLoading and DidStopLoading are properly called.
127 if (pending_frame_host && pending_frame_host->is_loading())
128 return true;
129 return current_frame_host->is_loading();
130}
131
132double FrameTreeNode::GetLoadingProgress() const {
133 RenderFrameHostImpl* current_frame_host =
134 render_manager_.current_frame_host();
135
136 DCHECK(current_frame_host);
137 return current_frame_host->loading_progress();
138}
139
alexmos6b294562015-03-05 19:24:10140bool FrameTreeNode::CommitPendingSandboxFlags() {
141 bool did_change_flags =
142 effective_sandbox_flags_ != replication_state_.sandbox_flags;
143 effective_sandbox_flags_ = replication_state_.sandbox_flags;
144 return did_change_flags;
145}
146
[email protected]9b159a52013-10-03 17:24:55147} // namespace content