Make RenderFrameHostManager swap RenderFrameHosts, not RenderViewHosts.

We still only have a RFHM for the main frame and not subframes, unless
the --site-per-process flag is passed. To external callers, RFHM is
still effectively swapping RenderViewHosts.

RenderFrameHosts now indirectly keep their RenderViewHosts alive.

Second attempt, after fixing memory leak from http://crrev.com/241151.

[email protected]
[email protected]
BUG=314791
TEST=No visible behavior change.

Review URL: https://codereview.chromium.org/117693002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@241423 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/content/browser/frame_host/frame_tree_node.cc b/content/browser/frame_host/frame_tree_node.cc
index 37b61b4f..cca17fd 100644
--- a/content/browser/frame_host/frame_tree_node.cc
+++ b/content/browser/frame_host/frame_tree_node.cc
@@ -7,39 +7,53 @@
 #include <queue>
 
 #include "base/stl_util.h"
+#include "content/browser/frame_host/frame_tree.h"
 #include "content/browser/frame_host/navigator.h"
 #include "content/browser/frame_host/render_frame_host_impl.h"
+#include "content/browser/renderer_host/render_view_host_impl.h"
 
 namespace content {
 
 const int64 FrameTreeNode::kInvalidFrameId = -1;
 int64 FrameTreeNode::next_frame_tree_node_id_ = 1;
 
-FrameTreeNode::FrameTreeNode(Navigator* navigator,
+FrameTreeNode::FrameTreeNode(FrameTree* frame_tree,
+                             Navigator* navigator,
                              RenderFrameHostDelegate* render_frame_delegate,
                              RenderViewHostDelegate* render_view_delegate,
                              RenderWidgetHostDelegate* render_widget_delegate,
                              RenderFrameHostManager::Delegate* manager_delegate,
                              int64 frame_id,
                              const std::string& name)
-  : navigator_(navigator),
-    render_manager_(render_frame_delegate,
+  : frame_tree_(frame_tree),
+    navigator_(navigator),
+    render_manager_(this,
+                    render_frame_delegate,
                     render_view_delegate,
                     render_widget_delegate,
                     manager_delegate),
     frame_tree_node_id_(next_frame_tree_node_id_++),
     frame_id_(frame_id),
-    frame_name_(name),
-    owns_render_frame_host_(true),
-    render_frame_host_(NULL) {
+    frame_name_(name) {
 }
 
 FrameTreeNode::~FrameTreeNode() {
-  if (owns_render_frame_host_)
-    delete render_frame_host_;
 }
 
-void FrameTreeNode::AddChild(scoped_ptr<FrameTreeNode> child) {
+bool FrameTreeNode::IsMainFrame() const {
+  return frame_tree_->root() == this;
+}
+
+void FrameTreeNode::AddChild(scoped_ptr<FrameTreeNode> child,
+                             int frame_routing_id) {
+  // Initialize the RenderFrameHost for the new node.  We always create child
+  // frames in the same SiteInstance as the current frame, and they can swap to
+  // a different one if they navigate away.
+  child->render_manager()->Init(
+      render_manager_.current_host()->GetSiteInstance()->GetBrowserContext(),
+      render_manager_.current_host()->GetSiteInstance(),
+      render_manager_.current_host()->GetRoutingID(),
+      frame_routing_id);
   children_.push_back(child.release());
 }
 
@@ -55,9 +69,7 @@
     children_.erase(iter);
 }
 
-void FrameTreeNode::ResetForMainFrame(
-    RenderFrameHostImpl* new_render_frame_host) {
-  owns_render_frame_host_ = false;
+void FrameTreeNode::ResetForMainFrameSwap() {
   frame_id_ = kInvalidFrameId;
   current_url_ = GURL();
 
@@ -65,8 +77,6 @@
   // commits before the old process cleans everything up.  Make sure the child
   // nodes get deleted.
   children_.clear();
-
-  render_frame_host_ = new_render_frame_host;
 }
 
 }  // namespace content