| 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(); |
| 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 |