OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/frame_host/render_frame_proxy_host.h" | 5 #include "content/browser/frame_host/render_frame_proxy_host.h" |
6 | 6 |
7 #include "base/lazy_instance.h" | 7 #include "base/lazy_instance.h" |
8 #include "content/browser/frame_host/cross_process_frame_connector.h" | 8 #include "content/browser/frame_host/cross_process_frame_connector.h" |
9 #include "content/browser/frame_host/frame_tree.h" | 9 #include "content/browser/frame_host/frame_tree.h" |
10 #include "content/browser/frame_host/frame_tree_node.h" | 10 #include "content/browser/frame_host/frame_tree_node.h" |
| 11 #include "content/browser/frame_host/render_frame_host_delegate.h" |
11 #include "content/browser/frame_host/render_frame_host_impl.h" | 12 #include "content/browser/frame_host/render_frame_host_impl.h" |
12 #include "content/browser/frame_host/render_widget_host_view_child_frame.h" | 13 #include "content/browser/frame_host/render_widget_host_view_child_frame.h" |
| 14 #include "content/browser/message_port_message_filter.h" |
13 #include "content/browser/renderer_host/render_view_host_impl.h" | 15 #include "content/browser/renderer_host/render_view_host_impl.h" |
14 #include "content/browser/renderer_host/render_widget_host_view_base.h" | 16 #include "content/browser/renderer_host/render_widget_host_view_base.h" |
15 #include "content/browser/site_instance_impl.h" | 17 #include "content/browser/site_instance_impl.h" |
16 #include "content/common/frame_messages.h" | 18 #include "content/common/frame_messages.h" |
17 #include "content/public/browser/browser_thread.h" | 19 #include "content/public/browser/browser_thread.h" |
18 #include "ipc/ipc_message.h" | 20 #include "ipc/ipc_message.h" |
19 | 21 |
20 namespace content { | 22 namespace content { |
21 | 23 |
22 namespace { | 24 namespace { |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
110 } | 112 } |
111 | 113 |
112 bool RenderFrameProxyHost::OnMessageReceived(const IPC::Message& msg) { | 114 bool RenderFrameProxyHost::OnMessageReceived(const IPC::Message& msg) { |
113 if (cross_process_frame_connector_.get() && | 115 if (cross_process_frame_connector_.get() && |
114 cross_process_frame_connector_->OnMessageReceived(msg)) | 116 cross_process_frame_connector_->OnMessageReceived(msg)) |
115 return true; | 117 return true; |
116 | 118 |
117 bool handled = true; | 119 bool handled = true; |
118 IPC_BEGIN_MESSAGE_MAP(RenderFrameProxyHost, msg) | 120 IPC_BEGIN_MESSAGE_MAP(RenderFrameProxyHost, msg) |
119 IPC_MESSAGE_HANDLER(FrameHostMsg_OpenURL, OnOpenURL) | 121 IPC_MESSAGE_HANDLER(FrameHostMsg_OpenURL, OnOpenURL) |
| 122 IPC_MESSAGE_HANDLER(FrameHostMsg_RouteMessageEvent, OnRouteMessageEvent) |
120 IPC_MESSAGE_UNHANDLED(handled = false) | 123 IPC_MESSAGE_UNHANDLED(handled = false) |
121 IPC_END_MESSAGE_MAP() | 124 IPC_END_MESSAGE_MAP() |
122 return handled; | 125 return handled; |
123 } | 126 } |
124 | 127 |
125 bool RenderFrameProxyHost::InitRenderFrameProxy() { | 128 bool RenderFrameProxyHost::InitRenderFrameProxy() { |
126 DCHECK(!render_frame_proxy_created_); | 129 DCHECK(!render_frame_proxy_created_); |
127 // The process may (if we're sharing a process with another host that already | 130 // The process may (if we're sharing a process with another host that already |
128 // initialized it) or may not (we have our own process or the old process | 131 // initialized it) or may not (we have our own process or the old process |
129 // crashed) have been initialized. Calling Init multiple times will be | 132 // crashed) have been initialized. Calling Init multiple times will be |
(...skipping 25 matching lines...) Expand all Loading... |
155 | 158 |
156 void RenderFrameProxyHost::DisownOpener() { | 159 void RenderFrameProxyHost::DisownOpener() { |
157 Send(new FrameMsg_DisownOpener(GetRoutingID())); | 160 Send(new FrameMsg_DisownOpener(GetRoutingID())); |
158 } | 161 } |
159 | 162 |
160 void RenderFrameProxyHost::OnOpenURL( | 163 void RenderFrameProxyHost::OnOpenURL( |
161 const FrameHostMsg_OpenURL_Params& params) { | 164 const FrameHostMsg_OpenURL_Params& params) { |
162 frame_tree_node_->current_frame_host()->OpenURL(params, site_instance_.get()); | 165 frame_tree_node_->current_frame_host()->OpenURL(params, site_instance_.get()); |
163 } | 166 } |
164 | 167 |
| 168 void RenderFrameProxyHost::OnRouteMessageEvent( |
| 169 const FrameMsg_PostMessage_Params& params) { |
| 170 RenderFrameHostImpl* target_rfh = frame_tree_node()->current_frame_host(); |
| 171 |
| 172 // Only deliver the message if the request came from a RenderFrameHost in the |
| 173 // same BrowsingInstance or if this WebContents is dedicated to a browser |
| 174 // plugin guest. |
| 175 // |
| 176 // TODO(alexmos, lazyboy): The check for browser plugin guest currently |
| 177 // requires going through the delegate. It should be refactored and |
| 178 // performed here once OOPIF support in <webview> is further along. |
| 179 SiteInstance* target_site_instance = target_rfh->GetSiteInstance(); |
| 180 if (!target_site_instance->IsRelatedSiteInstance(GetSiteInstance()) && |
| 181 !target_rfh->delegate()->ShouldRouteMessageEvent(target_rfh, |
| 182 GetSiteInstance())) |
| 183 return; |
| 184 |
| 185 FrameMsg_PostMessage_Params new_params(params); |
| 186 |
| 187 // If there is a source_routing_id, translate it to the routing ID of the |
| 188 // equivalent RenderFrameProxyHost in the target process. |
| 189 if (new_params.source_routing_id != MSG_ROUTING_NONE) { |
| 190 RenderFrameHostImpl* source_rfh = RenderFrameHostImpl::FromID( |
| 191 GetProcess()->GetID(), new_params.source_routing_id); |
| 192 if (!source_rfh) { |
| 193 new_params.source_routing_id = MSG_ROUTING_NONE; |
| 194 } else { |
| 195 // Ensure that we have a swapped-out RVH and proxy for the source frame. |
| 196 // If it doesn't exist, create it on demand and also create its opener |
| 197 // chain, since those will also be accessible to the target page. |
| 198 // |
| 199 // TODO(alexmos): This currently only works for top-level frames and |
| 200 // won't create the right proxy if the message source is a subframe on a |
| 201 // cross-process tab. This will be cleaned up as part of moving opener |
| 202 // tracking to FrameTreeNode (https://crbug.com/225940). For now, if the |
| 203 // message is sent from a subframe on a cross-process tab, set the source |
| 204 // routing ID to the main frame of the source tab, which matches legacy |
| 205 // postMessage behavior prior to --site-per-process. |
| 206 int source_view_routing_id = |
| 207 target_rfh->delegate()->EnsureOpenerRenderViewsExist(source_rfh); |
| 208 |
| 209 RenderFrameProxyHost* source_proxy_in_target_site_instance = |
| 210 source_rfh->frame_tree_node() |
| 211 ->render_manager() |
| 212 ->GetRenderFrameProxyHost(target_rfh->GetSiteInstance()); |
| 213 if (source_proxy_in_target_site_instance) { |
| 214 new_params.source_routing_id = |
| 215 source_proxy_in_target_site_instance->GetRoutingID(); |
| 216 } else if (source_view_routing_id != MSG_ROUTING_NONE) { |
| 217 RenderViewHostImpl* source_rvh = RenderViewHostImpl::FromID( |
| 218 target_rfh->GetProcess()->GetID(), source_view_routing_id); |
| 219 CHECK(source_rvh); |
| 220 new_params.source_routing_id = source_rvh->main_frame_routing_id(); |
| 221 } else { |
| 222 new_params.source_routing_id = MSG_ROUTING_NONE; |
| 223 } |
| 224 } |
| 225 } |
| 226 |
| 227 if (!params.message_ports.empty()) { |
| 228 // Updating the message port information has to be done in the IO thread; |
| 229 // MessagePortMessageFilter::RouteMessageEventWithMessagePorts will send |
| 230 // FrameMsg_PostMessageEvent after it's done. Note that a trivial solution |
| 231 // would've been to post a task on the IO thread to do the IO-thread-bound |
| 232 // work, and make that post a task back to WebContentsImpl in the UI |
| 233 // thread. But we cannot do that, since there's nothing to guarantee that |
| 234 // WebContentsImpl stays alive during the round trip. |
| 235 scoped_refptr<MessagePortMessageFilter> message_port_message_filter( |
| 236 static_cast<RenderProcessHostImpl*>(target_rfh->GetProcess()) |
| 237 ->message_port_message_filter()); |
| 238 BrowserThread::PostTask( |
| 239 BrowserThread::IO, FROM_HERE, |
| 240 base::Bind(&MessagePortMessageFilter::RouteMessageEventWithMessagePorts, |
| 241 message_port_message_filter, target_rfh->GetRoutingID(), |
| 242 new_params)); |
| 243 } else { |
| 244 target_rfh->Send( |
| 245 new FrameMsg_PostMessageEvent(target_rfh->GetRoutingID(), new_params)); |
| 246 } |
| 247 } |
| 248 |
165 } // namespace content | 249 } // namespace content |
OLD | NEW |