render_frame_proxy_host.cc revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
17dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 27dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 37dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// found in the LICENSE file. 47dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 57dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "content/browser/frame_host/render_frame_proxy_host.h" 67dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 77dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/lazy_instance.h" 87dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "content/browser/frame_host/cross_process_frame_connector.h" 97dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "content/browser/frame_host/frame_tree.h" 107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "content/browser/frame_host/frame_tree_node.h" 117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "content/browser/frame_host/render_frame_host_impl.h" 127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "content/browser/frame_host/render_widget_host_view_child_frame.h" 137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "content/browser/renderer_host/render_view_host_impl.h" 147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "content/browser/renderer_host/render_widget_host_view_base.h" 157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "content/browser/site_instance_impl.h" 167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "content/common/frame_messages.h" 177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "content/public/browser/browser_thread.h" 187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "ipc/ipc_message.h" 197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochnamespace content { 217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochnamespace { 237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// The (process id, routing id) pair that identifies one RenderFrameProxy. 257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochtypedef std::pair<int32, int32> RenderFrameProxyHostID; 267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochtypedef base::hash_map<RenderFrameProxyHostID, RenderFrameProxyHost*> 277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch RoutingIDFrameProxyMap; 287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbase::LazyInstance<RoutingIDFrameProxyMap> g_routing_id_frame_proxy_map = 297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch LAZY_INSTANCE_INITIALIZER; 307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// static 347dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochRenderFrameProxyHost* RenderFrameProxyHost::FromID(int process_id, 357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int routing_id) { 367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch RoutingIDFrameProxyMap* frames = g_routing_id_frame_proxy_map.Pointer(); 387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch RoutingIDFrameProxyMap::iterator it = frames->find( 397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch RenderFrameProxyHostID(process_id, routing_id)); 407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return it == frames->end() ? NULL : it->second; 417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 437dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochRenderFrameProxyHost::RenderFrameProxyHost(SiteInstance* site_instance, 447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch FrameTreeNode* frame_tree_node) 457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch : routing_id_(site_instance->GetProcess()->GetNextRoutingID()), 467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch site_instance_(site_instance), 477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch frame_tree_node_(frame_tree_node) { 487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch GetProcess()->AddRoute(routing_id_, this); 497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CHECK(g_routing_id_frame_proxy_map.Get().insert( 507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::make_pair( 517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch RenderFrameProxyHostID(GetProcess()->GetID(), routing_id_), 527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch this)).second); 537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!frame_tree_node_->IsMainFrame() && 557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch frame_tree_node_->parent() 56 ->render_manager() 57 ->current_frame_host() 58 ->GetSiteInstance() == site_instance) { 59 // The RenderFrameHost navigating cross-process is destroyed and a proxy for 60 // it is created in the parent's process. CrossProcessFrameConnector 61 // initialization only needs to happen on an initial cross-process 62 // navigation, when the RenderFrameHost leaves the same process as its 63 // parent. The same CrossProcessFrameConnector is used for subsequent cross- 64 // process navigations, but it will be destroyed if the frame is 65 // navigated back to the same SiteInstance as its parent. 66 cross_process_frame_connector_.reset(new CrossProcessFrameConnector(this)); 67 } 68} 69 70RenderFrameProxyHost::~RenderFrameProxyHost() { 71 if (GetProcess()->HasConnection()) 72 Send(new FrameMsg_DeleteProxy(routing_id_)); 73 74 GetProcess()->RemoveRoute(routing_id_); 75 g_routing_id_frame_proxy_map.Get().erase( 76 RenderFrameProxyHostID(GetProcess()->GetID(), routing_id_)); 77} 78 79void RenderFrameProxyHost::SetChildRWHView(RenderWidgetHostView* view) { 80 cross_process_frame_connector_->set_view( 81 static_cast<RenderWidgetHostViewChildFrame*>(view)); 82} 83 84RenderViewHostImpl* RenderFrameProxyHost::GetRenderViewHost() { 85 return frame_tree_node_->frame_tree()->GetRenderViewHost( 86 site_instance_.get()); 87} 88 89scoped_ptr<RenderFrameHostImpl> RenderFrameProxyHost::PassFrameHostOwnership() { 90 render_frame_host_->set_render_frame_proxy_host(NULL); 91 return render_frame_host_.Pass(); 92} 93 94bool RenderFrameProxyHost::Send(IPC::Message *msg) { 95 // TODO(nasko): For now, RenderFrameHost uses this object to send IPC messages 96 // while swapped out. This can be removed once we don't have a swapped out 97 // state on RenderFrameHosts. See https://crbug.com/357747. 98 msg->set_routing_id(routing_id_); 99 return GetProcess()->Send(msg); 100} 101 102bool RenderFrameProxyHost::OnMessageReceived(const IPC::Message& msg) { 103 if (cross_process_frame_connector_.get() && 104 cross_process_frame_connector_->OnMessageReceived(msg)) 105 return true; 106 107 // TODO(nasko): This can be removed once we don't have a swapped out state on 108 // RenderFrameHosts. See https://crbug.com/357747. 109 if (render_frame_host_.get()) 110 return render_frame_host_->OnMessageReceived(msg); 111 112 return false; 113} 114 115bool RenderFrameProxyHost::InitRenderFrameProxy() { 116 // The process may (if we're sharing a process with another host that already 117 // initialized it) or may not (we have our own process or the old process 118 // crashed) have been initialized. Calling Init multiple times will be 119 // ignored, so this is safe. 120 if (!site_instance_->GetProcess()->Init()) 121 return false; 122 123 DCHECK(GetProcess()->HasConnection()); 124 125 int parent_routing_id = MSG_ROUTING_NONE; 126 if (frame_tree_node_->parent()) { 127 parent_routing_id = frame_tree_node_->parent() 128 ->render_manager() 129 ->GetRoutingIdForSiteInstance(site_instance_.get()); 130 CHECK_NE(parent_routing_id, MSG_ROUTING_NONE); 131 } 132 133 Send(new FrameMsg_NewFrameProxy(routing_id_, 134 parent_routing_id, 135 frame_tree_node_->frame_tree() 136 ->GetRenderViewHost(site_instance_.get()) 137 ->GetRoutingID())); 138 139 return true; 140} 141 142void RenderFrameProxyHost::DisownOpener() { 143 Send(new FrameMsg_DisownOpener(GetRoutingID())); 144} 145 146} // namespace content 147