frame_tree_node.cc revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
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 frame_routing_id) {
46  // Initialize the RenderFrameHost for the new node.  We always create child
47  // frames in the same SiteInstance as the current frame, and they can swap to
48  // a different one if they navigate away.
49  child->render_manager()->Init(
50      render_manager_.current_host()->GetSiteInstance()->GetBrowserContext(),
51      render_manager_.current_host()->GetSiteInstance(),
52      render_manager_.current_host()->GetRoutingID(),
53      frame_routing_id);
54  child->set_parent(this);
55  children_.push_back(child.release());
56}
57
58void FrameTreeNode::RemoveChild(FrameTreeNode* child) {
59  std::vector<FrameTreeNode*>::iterator iter;
60
61  for (iter = children_.begin(); iter != children_.end(); ++iter) {
62    if ((*iter) == child)
63      break;
64  }
65
66  if (iter != children_.end()) {
67    // Subtle: we need to make sure the node is gone from the tree before
68    // observers are notified of its deletion.
69    scoped_ptr<FrameTreeNode> node_to_delete(*iter);
70    children_.weak_erase(iter);
71    node_to_delete->set_parent(NULL);
72    node_to_delete.reset();
73  }
74}
75
76void FrameTreeNode::ResetForNewProcess() {
77  current_url_ = GURL();
78
79  // The RenderFrame no longer exists and will need to be created again.
80  current_frame_host()->set_render_frame_created(false);
81
82  // The children may not have been cleared if a cross-process navigation
83  // commits before the old process cleans everything up.  Make sure the child
84  // nodes get deleted before swapping to a new process.
85  ScopedVector<FrameTreeNode> old_children = children_.Pass();
86  old_children.clear();  // May notify observers.
87}
88
89}  // namespace content
90