Index: content/browser/frame_host/render_frame_proxy_host.cc |
diff --git a/content/browser/frame_host/render_frame_proxy_host.cc b/content/browser/frame_host/render_frame_proxy_host.cc |
index 988f9e876b4bdc989331f534aed27ff9014d36f5..1198ddef1a9b1db7a02181bc33529033e4555201 100644 |
--- a/content/browser/frame_host/render_frame_proxy_host.cc |
+++ b/content/browser/frame_host/render_frame_proxy_host.cc |
@@ -8,8 +8,10 @@ |
#include "content/browser/frame_host/cross_process_frame_connector.h" |
#include "content/browser/frame_host/frame_tree.h" |
#include "content/browser/frame_host/frame_tree_node.h" |
+#include "content/browser/frame_host/render_frame_host_delegate.h" |
#include "content/browser/frame_host/render_frame_host_impl.h" |
#include "content/browser/frame_host/render_widget_host_view_child_frame.h" |
+#include "content/browser/message_port_message_filter.h" |
#include "content/browser/renderer_host/render_view_host_impl.h" |
#include "content/browser/renderer_host/render_widget_host_view_base.h" |
#include "content/browser/site_instance_impl.h" |
@@ -117,6 +119,7 @@ bool RenderFrameProxyHost::OnMessageReceived(const IPC::Message& msg) { |
bool handled = true; |
IPC_BEGIN_MESSAGE_MAP(RenderFrameProxyHost, msg) |
IPC_MESSAGE_HANDLER(FrameHostMsg_OpenURL, OnOpenURL) |
+ IPC_MESSAGE_HANDLER(FrameHostMsg_RouteMessageEvent, OnRouteMessageEvent) |
IPC_MESSAGE_UNHANDLED(handled = false) |
IPC_END_MESSAGE_MAP() |
return handled; |
@@ -162,4 +165,81 @@ void RenderFrameProxyHost::OnOpenURL( |
frame_tree_node_->current_frame_host()->OpenURL(params, site_instance_.get()); |
} |
+void RenderFrameProxyHost::OnRouteMessageEvent( |
+ const FrameMsg_PostMessage_Params& params) { |
+ RenderFrameHostImpl* target_rfh = frame_tree_node()->current_frame_host(); |
+ |
+ // TODO(alexmos, lazyboy): The reason this check needs to be in the delegate |
+ // is <webview> support, since postMessages need to be allowed when the |
+ // target WebContents is dedicated to a browser plugin guest. This check |
+ // should be refactored and performed here once OOPIF support in <webview> |
+ // is further along. |
+ if (!target_rfh->delegate()->ShouldRouteMessageEvent(target_rfh, |
+ GetSiteInstance())) |
+ return; |
+ |
+ FrameMsg_PostMessage_Params new_params(params); |
+ |
+ // If there is a source_routing_id, translate it to the routing ID of the |
+ // equivalent RenderFrameProxyHost in the target process. |
+ if (new_params.source_routing_id != MSG_ROUTING_NONE) { |
+ RenderFrameHostImpl* source_rfh = RenderFrameHostImpl::FromID( |
+ GetProcess()->GetID(), new_params.source_routing_id); |
+ if (!source_rfh) { |
+ new_params.source_routing_id = MSG_ROUTING_NONE; |
+ } else { |
+ // Ensure that we have a swapped-out RVH and proxy for the source frame. |
+ // If it doesn't exist, create it on demand and also create its opener |
+ // chain, since those will also be accessible to the target page. |
+ // |
+ // TODO(alexmos): This currently only works for top-level frames and |
+ // won't create the right proxy if the message source is a subframe on a |
+ // cross-process tab. This will be cleaned up as part of moving opener |
+ // tracking to FrameTreeNode (https://crbug.com/225940). For now, if the |
+ // message is sent from a subframe on a cross-process tab, set the source |
+ // routing ID to the main frame of the source tab, which matches legacy |
+ // postMessage behavior prior to --site-per-process. |
+ int source_view_routing_id = |
+ target_rfh->delegate()->EnsureOpenerRenderViewsExist(source_rfh); |
+ |
+ RenderFrameProxyHost* source_proxy_in_target_site_instance = |
+ source_rfh->frame_tree_node() |
+ ->render_manager() |
+ ->GetRenderFrameProxyHost(target_rfh->GetSiteInstance()); |
+ if (source_proxy_in_target_site_instance) { |
+ new_params.source_routing_id = |
+ source_proxy_in_target_site_instance->GetRoutingID(); |
+ } else if (source_view_routing_id != MSG_ROUTING_NONE) { |
+ RenderViewHostImpl* source_rvh = RenderViewHostImpl::FromID( |
+ target_rfh->GetProcess()->GetID(), source_view_routing_id); |
+ CHECK(source_rvh); |
+ 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.
|
+ } else { |
+ new_params.source_routing_id = MSG_ROUTING_NONE; |
+ } |
+ } |
+ } |
+ |
+ if (!params.message_ports.empty()) { |
+ // Updating the message port information has to be done in the IO thread; |
+ // MessagePortMessageFilter::RouteMessageEventWithMessagePorts will send |
+ // FrameMsg_PostMessageEvent after it's done. Note that a trivial solution |
+ // would've been to post a task on the IO thread to do the IO-thread-bound |
+ // work, and make that post a task back to WebContentsImpl in the UI |
+ // thread. But we cannot do that, since there's nothing to guarantee that |
+ // WebContentsImpl stays alive during the round trip. |
+ scoped_refptr<MessagePortMessageFilter> message_port_message_filter( |
+ static_cast<RenderProcessHostImpl*>(target_rfh->GetProcess()) |
+ ->message_port_message_filter()); |
+ BrowserThread::PostTask( |
+ BrowserThread::IO, FROM_HERE, |
+ base::Bind(&MessagePortMessageFilter::RouteMessageEventWithMessagePorts, |
+ message_port_message_filter, target_rfh->GetRoutingID(), |
+ new_params)); |
+ } else { |
+ target_rfh->Send( |
+ new FrameMsg_PostMessageEvent(target_rfh->GetRoutingID(), new_params)); |
+ } |
+} |
+ |
} // namespace content |