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 // TODO(alexmos, lazyboy): The reason this check needs to be in the delegate | |
173 // is <webview> support, since postMessages need to be allowed when the | |
174 // target WebContents is dedicated to a browser plugin guest. This check | |
175 // should be refactored and performed here once OOPIF support in <webview> | |
176 // is further along. | |
177 if (!target_rfh->delegate()->ShouldRouteMessageEvent(target_rfh, | |
178 GetSiteInstance())) | |
179 return; | |
180 | |
181 FrameMsg_PostMessage_Params new_params(params); | |
182 | |
183 // If there is a source_routing_id, translate it to the routing ID of the | |
184 // equivalent RenderFrameProxyHost in the target process. | |
185 if (new_params.source_routing_id != MSG_ROUTING_NONE) { | |
186 RenderFrameHostImpl* source_rfh = RenderFrameHostImpl::FromID( | |
187 GetProcess()->GetID(), new_params.source_routing_id); | |
188 if (!source_rfh) { | |
189 new_params.source_routing_id = MSG_ROUTING_NONE; | |
190 } else { | |
191 // Ensure that we have a swapped-out RVH and proxy for the source frame. | |
192 // If it doesn't exist, create it on demand and also create its opener | |
193 // chain, since those will also be accessible to the target page. | |
194 // | |
195 // TODO(alexmos): This currently only works for top-level frames and | |
196 // won't create the right proxy if the message source is a subframe on a | |
197 // cross-process tab. This will be cleaned up as part of moving opener | |
198 // tracking to FrameTreeNode (https://crbug.com/225940). For now, if the | |
199 // message is sent from a subframe on a cross-process tab, set the source | |
200 // routing ID to the main frame of the source tab, which matches legacy | |
201 // postMessage behavior prior to --site-per-process. | |
202 int source_view_routing_id = | |
203 target_rfh->delegate()->EnsureOpenerRenderViewsExist(source_rfh); | |
204 | |
205 RenderFrameProxyHost* source_proxy_in_target_site_instance = | |
206 source_rfh->frame_tree_node() | |
207 ->render_manager() | |
208 ->GetRenderFrameProxyHost(target_rfh->GetSiteInstance()); | |
209 if (source_proxy_in_target_site_instance) { | |
210 new_params.source_routing_id = | |
211 source_proxy_in_target_site_instance->GetRoutingID(); | |
212 } else if (source_view_routing_id != MSG_ROUTING_NONE) { | |
213 RenderViewHostImpl* source_rvh = RenderViewHostImpl::FromID( | |
214 target_rfh->GetProcess()->GetID(), source_view_routing_id); | |
215 CHECK(source_rvh); | |
216 new_params.source_routing_id = source_rvh->main_frame_routing_id(); | |
alexmos
2015/04/02 23:17:00
The test that fails without this path is MimeHandl
Charlie Reis
2015/04/06 16:18:55
Acknowledged.
| |
217 } else { | |
218 new_params.source_routing_id = MSG_ROUTING_NONE; | |
219 } | |
220 } | |
221 } | |
222 | |
223 if (!params.message_ports.empty()) { | |
224 // Updating the message port information has to be done in the IO thread; | |
225 // MessagePortMessageFilter::RouteMessageEventWithMessagePorts will send | |
226 // FrameMsg_PostMessageEvent after it's done. Note that a trivial solution | |
227 // would've been to post a task on the IO thread to do the IO-thread-bound | |
228 // work, and make that post a task back to WebContentsImpl in the UI | |
229 // thread. But we cannot do that, since there's nothing to guarantee that | |
230 // WebContentsImpl stays alive during the round trip. | |
231 scoped_refptr<MessagePortMessageFilter> message_port_message_filter( | |
232 static_cast<RenderProcessHostImpl*>(target_rfh->GetProcess()) | |
233 ->message_port_message_filter()); | |
234 BrowserThread::PostTask( | |
235 BrowserThread::IO, FROM_HERE, | |
236 base::Bind(&MessagePortMessageFilter::RouteMessageEventWithMessagePorts, | |
237 message_port_message_filter, target_rfh->GetRoutingID(), | |
238 new_params)); | |
239 } else { | |
240 target_rfh->Send( | |
241 new FrameMsg_PostMessageEvent(target_rfh->GetRoutingID(), new_params)); | |
242 } | |
243 } | |
244 | |
165 } // namespace content | 245 } // namespace content |
OLD | NEW |