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
3// found in the LICENSE file.
4
5#include "content/browser/frame_host/frame_tree_node.h"
6
7#include <queue>
8
9#include "base/stl_util.h"
10#include "content/browser/frame_host/frame_tree.h"
11#include "content/browser/frame_host/navigator.h"
12#include "content/browser/frame_host/render_frame_host_impl.h"
13#include "content/browser/renderer_host/render_view_host_impl.h"
14
15namespace content {
16
17int64 FrameTreeNode::next_frame_tree_node_id_ = 1;
18
19FrameTreeNode::FrameTreeNode(FrameTree* frame_tree,
20                             Navigator* navigator,
21                             RenderFrameHostDelegate* render_frame_delegate,
22                             RenderViewHostDelegate* render_view_delegate,
23                             RenderWidgetHostDelegate* render_widget_delegate,
24                             RenderFrameHostManager::Delegate* manager_delegate,
25                             const std::string& name)
26    : frame_tree_(frame_tree),
27      navigator_(navigator),
28      render_manager_(this,
29                      render_frame_delegate,
30                      render_view_delegate,
31                      render_widget_delegate,
32                      manager_delegate),
33      frame_tree_node_id_(next_frame_tree_node_id_++),
34      frame_name_(name),
35      parent_(NULL) {}
36
37FrameTreeNode::~FrameTreeNode() {
38}
39
40bool FrameTreeNode::IsMainFrame() const {
41  return frame_tree_->root() == this;
42}
43
44void FrameTreeNode::AddChild(scoped_ptr<FrameTreeNode> child,
45                             int process_id,
46                             int frame_routing_id) {
47  // Child frame must always be created in the same process as the parent.
48  CHECK_EQ(process_id, render_manager_.current_host()->GetProcess()->GetID());
49
50  // Initialize the RenderFrameHost for the new node.  We always create child
51  // frames in the same SiteInstance as the current frame, and they can swap to
52  // a different one if they navigate away.
53  child->render_manager()->Init(
54      render_manager_.current_host()->GetSiteInstance()->GetBrowserContext(),
55      render_manager_.current_host()->GetSiteInstance(),
56      render_manager_.current_host()->GetRoutingID(),
57      frame_routing_id);
58  child->set_parent(this);
59  children_.push_back(child.release());
60}
61
62void FrameTreeNode::RemoveChild(FrameTreeNode* child) {
63  std::vector<FrameTreeNode*>::iterator iter;
64
65  for (iter = children_.begin(); iter != children_.end(); ++iter) {
66    if ((*iter) == child)
67      break;
68  }
69
70  if (iter != children_.end()) {
71    // Subtle: we need to make sure the node is gone from the tree before
72    // observers are notified of its deletion.
73    scoped_ptr<FrameTreeNode> node_to_delete(*iter);
74    children_.weak_erase(iter);
75    node_to_delete->set_parent(NULL);
76    node_to_delete.reset();
77  }
78}
79
80void FrameTreeNode::ResetForNewProcess() {
81  current_url_ = GURL();
82
83  // The RenderFrame no longer exists and will need to be created again.
84  current_frame_host()->set_render_frame_created(false);
85
86  // The children may not have been cleared if a cross-process navigation
87  // commits before the old process cleans everything up.  Make sure the child
88  // nodes get deleted before swapping to a new process.
89  ScopedVector<FrameTreeNode> old_children = children_.Pass();
90  old_children.clear();  // May notify observers.
91}
92
93}  // namespace content
94