Index: content/browser/frame_host/frame_tree.cc |
diff --git a/content/browser/frame_host/frame_tree.cc b/content/browser/frame_host/frame_tree.cc |
index 0cb9d5ecfa11e6089ed6fe332c1c47e51d13f23d..cb479c63a3c87aa4a5f3524a712f2a28d925a1d1 100644 |
--- a/content/browser/frame_host/frame_tree.cc |
+++ b/content/browser/frame_host/frame_tree.cc |
@@ -10,15 +10,18 @@ |
#include "base/callback.h" |
#include "content/browser/frame_host/frame_tree_node.h" |
#include "content/browser/frame_host/render_frame_host_impl.h" |
+#include "content/browser/renderer_host/render_view_host_factory.h" |
+#include "content/browser/renderer_host/render_view_host_impl.h" |
namespace content { |
namespace { |
// Used with FrameTree::ForEach() to search for the FrameTreeNode |
-// corresponding to |frame_id|. |
-bool FrameTreeNodeForId(int64 frame_id, FrameTreeNode** out_node, |
+// corresponding to |frame_tree_node_id|. |
+bool FrameTreeNodeForId(int64 frame_tree_node_id, |
+ FrameTreeNode** out_node, |
FrameTreeNode* node) { |
- if (node->frame_id() == frame_id) { |
+ if (node->frame_tree_node_id() == frame_tree_node_id) { |
*out_node = node; |
// Terminate iteration once the node has been found. |
return false; |
@@ -28,17 +31,26 @@ bool FrameTreeNodeForId(int64 frame_id, FrameTreeNode** out_node, |
} // namespace |
-FrameTree::FrameTree() |
- : root_(new FrameTreeNode(FrameTreeNode::kInvalidFrameId, std::string(), |
- scoped_ptr<RenderFrameHostImpl>())) { |
+int64 FrameTree::next_frame_tree_node_id_ = 1; |
+ |
+FrameTree::FrameTree(RenderViewHostDelegate* render_view_delegate, |
+ RenderWidgetHostDelegate* render_widget_delegate, |
+ RenderViewHostManager::Delegate* manager_delegate) |
+ : render_view_delegate_(render_view_delegate), |
+ render_widget_delegate_(render_widget_delegate), |
+ manager_delegate_(manager_delegate), |
+ root_(new FrameTreeNode(GetNextFrameTreeNodeID(), std::string(), |
+ render_view_delegate, |
+ render_widget_delegate, |
+ manager_delegate)) { |
} |
FrameTree::~FrameTree() { |
} |
-FrameTreeNode* FrameTree::FindByID(int64 frame_id) { |
+FrameTreeNode* FrameTree::FindByID(int64 frame_tree_node_id) { |
FrameTreeNode* node = NULL; |
- ForEach(base::Bind(&FrameTreeNodeForId, frame_id, &node)); |
+ ForEach(base::Bind(&FrameTreeNodeForId, frame_tree_node_id, &node)); |
return node; |
} |
@@ -58,27 +70,25 @@ void FrameTree::ForEach( |
} |
} |
-bool FrameTree::IsFirstNavigationAfterSwap() const { |
- return root_->frame_id() == FrameTreeNode::kInvalidFrameId; |
-} |
- |
-void FrameTree::OnFirstNavigationAfterSwap(int main_frame_id) { |
- root_->set_frame_id(main_frame_id); |
-} |
- |
-void FrameTree::AddFrame(int render_frame_host_id, int64 parent_frame_id, |
- int64 frame_id, const std::string& frame_name) { |
- FrameTreeNode* parent = FindByID(parent_frame_id); |
+void FrameTree::AddFrame(RenderViewHostImpl* parent_render_view_host, |
+ int render_frame_host_id, |
+ int64 parent_frame_id, |
+ int64 frame_id, |
+ const std::string& frame_name) { |
+ int64 parent_frame_tree_node_id = |
+ parent_render_view_host->GetFrameTreeNodeID(parent_frame_id); |
+ FrameTreeNode* parent = FindByID(parent_frame_tree_node_id); |
// TODO(ajwong): Should the renderer be killed here? Would there be a race on |
// shutdown that might make this case possible? |
if (!parent) |
return; |
parent->AddChild(CreateNode(frame_id, frame_name, render_frame_host_id, |
- parent->render_frame_host()->GetProcess())); |
+ parent_render_view_host)); |
} |
-void FrameTree::RemoveFrame(int64 parent_frame_id, int64 frame_id) { |
+void FrameTree::RemoveFrame(int64 parent_frame_tree_node_id, |
+ int64 frame_tree_node_id) { |
// If switches::kSitePerProcess is not specified, then the FrameTree only |
// contains a node for the root element. However, even in this case |
// frame detachments need to be broadcast outwards. |
@@ -86,10 +96,23 @@ void FrameTree::RemoveFrame(int64 parent_frame_id, int64 frame_id) { |
// TODO(ajwong): Move this below the |parent| check after the FrameTree is |
// guaranteed to be correctly populated even without the |
// switches::kSitePerProcess flag. |
- FrameTreeNode* parent = FindByID(parent_frame_id); |
+ FrameTreeNode* parent = FindByID(parent_frame_tree_node_id); |
if (!on_frame_removed_.is_null()) { |
on_frame_removed_.Run( |
- root_->render_frame_host()->render_view_host(), frame_id); |
+ root_->render_frame_host()->render_view_host(), frame_tree_node_id); |
+ } |
+ |
+ // Decrement the refcount of the frame's RenderViewHost, allowing it to shut |
+ // down if it is no longer needed. |
+ // TODO(creis): Is this the only way that RFHs can be deleted? If not, we |
+ // should listen for that instead of doing it here. |
+ FrameTreeNode* node = FindByID(frame_tree_node_id); |
+ RenderViewHostImpl* render_view_host = |
+ node->render_frame_host()->render_view_host(); |
+ rvh_refcounts_[render_view_host->GetRoutingID()]--; |
+ if (rvh_refcounts_[render_view_host->GetRoutingID()] <= 0) { |
+ rvh_refcounts_.erase(render_view_host->GetRoutingID()); |
+ render_view_host->Shutdown(); |
} |
// TODO(ajwong): Should the renderer be killed here? Would there be a race on |
@@ -97,11 +120,11 @@ void FrameTree::RemoveFrame(int64 parent_frame_id, int64 frame_id) { |
if (!parent) |
return; |
- parent->RemoveChild(frame_id); |
+ parent->RemoveChild(frame_tree_node_id); |
} |
-void FrameTree::SetFrameUrl(int64 frame_id, const GURL& url) { |
- FrameTreeNode* node = FindByID(frame_id); |
+void FrameTree::SetFrameUrl(int64 frame_tree_node_id, const GURL& url) { |
+ FrameTreeNode* node = FindByID(frame_tree_node_id); |
// TODO(ajwong): Should the renderer be killed here? Would there be a race on |
// shutdown that might make this case possible? |
if (!node) |
@@ -111,10 +134,6 @@ void FrameTree::SetFrameUrl(int64 frame_id, const GURL& url) { |
node->set_current_url(url); |
} |
-void FrameTree::SwapMainFrame(RenderFrameHostImpl* render_frame_host) { |
- return root_->ResetForMainFrame(render_frame_host); |
-} |
- |
RenderFrameHostImpl* FrameTree::GetMainFrame() const { |
return root_->render_frame_host(); |
} |
@@ -124,15 +143,52 @@ void FrameTree::SetFrameRemoveListener( |
on_frame_removed_ = on_frame_removed; |
} |
+RenderViewHostImpl* FrameTree::GetRenderViewHostForNewFrame( |
+ SiteInstance* site_instance, |
+ int routing_id, |
+ int main_frame_routing_id, |
+ bool swapped_out, |
+ bool hidden) { |
+ RenderViewHostMap::iterator iter = |
+ render_view_host_map_.find(site_instance->GetId()); |
+ RenderViewHostImpl* rvh = NULL; |
+ if (iter != render_view_host_map_.end()) { |
+ rvh = iter->second; |
+ } else { |
+ rvh = static_cast<RenderViewHostImpl*>( |
+ RenderViewHostFactory::Create(site_instance, |
+ render_view_delegate_, |
+ render_widget_delegate_, |
+ routing_id, |
+ main_frame_routing_id, |
+ swapped_out, |
+ hidden)); |
+ |
+ render_view_host_map_[site_instance->GetId()] = rvh; |
+ } |
+ rvh_refcounts_[rvh->GetRoutingID()]++; |
+ return rvh; |
+} |
+ |
scoped_ptr<FrameTreeNode> FrameTree::CreateNode( |
- int64 frame_id, const std::string& frame_name, int render_frame_host_id, |
- RenderProcessHost* render_process_host) { |
- scoped_ptr<RenderFrameHostImpl> render_frame_host( |
- new RenderFrameHostImpl(root_->render_frame_host()->render_view_host(), |
- this, render_frame_host_id, false)); |
- |
- return make_scoped_ptr(new FrameTreeNode(frame_id, frame_name, |
- render_frame_host.Pass())); |
+ int64 frame_id, |
+ const std::string& frame_name, |
+ int render_frame_host_id, |
+ RenderViewHostImpl* render_view_host) { |
+ // TODO(creis): Call Init on the RFHM. |
+ |
+ // Create the FrameTreeNode with a unique browser-wide ID, and make sure the |
+ // renderer-specific frame_id can be used to find it. |
+ int64 frame_tree_node_id = GetNextFrameTreeNodeID(); |
+ render_view_host->RegisterFrameTreeNodeID(frame_id, frame_tree_node_id); |
+ return make_scoped_ptr(new FrameTreeNode(frame_tree_node_id, frame_name, |
+ render_view_delegate_, |
+ render_widget_delegate_, |
+ manager_delegate_)); |
+} |
+ |
+int64 FrameTree::GetNextFrameTreeNodeID() { |
+ return next_frame_tree_node_id_++; |
} |
} // namespace content |