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 3// found in the LICENSE file. 4 5#include "content/browser/frame_host/cross_process_frame_connector.h" 6 7#include "content/browser/frame_host/render_frame_proxy_host.h" 8#include "content/browser/frame_host/render_widget_host_view_child_frame.h" 9#include "content/browser/renderer_host/render_view_host_impl.h" 10#include "content/browser/renderer_host/render_widget_host_impl.h" 11#include "content/common/frame_messages.h" 12#include "content/common/gpu/gpu_messages.h" 13#include "third_party/WebKit/public/web/WebInputEvent.h" 14 15namespace content { 16 17CrossProcessFrameConnector::CrossProcessFrameConnector( 18 RenderFrameProxyHost* frame_proxy_in_parent_renderer) 19 : frame_proxy_in_parent_renderer_(frame_proxy_in_parent_renderer), 20 view_(NULL), 21 device_scale_factor_(1) { 22} 23 24CrossProcessFrameConnector::~CrossProcessFrameConnector() { 25 if (view_) 26 view_->set_cross_process_frame_connector(NULL); 27} 28 29bool CrossProcessFrameConnector::OnMessageReceived(const IPC::Message& msg) { 30 bool handled = true; 31 32 IPC_BEGIN_MESSAGE_MAP(CrossProcessFrameConnector, msg) 33 IPC_MESSAGE_HANDLER(FrameHostMsg_CompositorFrameSwappedACK, 34 OnCompositorFrameSwappedACK) 35 IPC_MESSAGE_HANDLER(FrameHostMsg_ReclaimCompositorResources, 36 OnReclaimCompositorResources) 37 IPC_MESSAGE_HANDLER(FrameHostMsg_ForwardInputEvent, OnForwardInputEvent) 38 IPC_MESSAGE_HANDLER(FrameHostMsg_InitializeChildFrame, 39 OnInitializeChildFrame) 40 IPC_MESSAGE_UNHANDLED(handled = false) 41 IPC_END_MESSAGE_MAP() 42 43 return handled; 44} 45 46void CrossProcessFrameConnector::set_view( 47 RenderWidgetHostViewChildFrame* view) { 48 // Detach ourselves from the previous |view_|. 49 if (view_) 50 view_->set_cross_process_frame_connector(NULL); 51 52 view_ = view; 53 54 // Attach ourselves to the new view and size it appropriately. 55 if (view_) { 56 view_->set_cross_process_frame_connector(this); 57 SetDeviceScaleFactor(device_scale_factor_); 58 SetSize(child_frame_rect_); 59 } 60} 61 62void CrossProcessFrameConnector::RenderProcessGone() { 63 frame_proxy_in_parent_renderer_->Send(new FrameMsg_ChildFrameProcessGone( 64 frame_proxy_in_parent_renderer_->GetRoutingID())); 65} 66 67void CrossProcessFrameConnector::ChildFrameCompositorFrameSwapped( 68 uint32 output_surface_id, 69 int host_id, 70 int route_id, 71 scoped_ptr<cc::CompositorFrame> frame) { 72 FrameMsg_CompositorFrameSwapped_Params params; 73 frame->AssignTo(¶ms.frame); 74 params.output_surface_id = output_surface_id; 75 params.producing_route_id = route_id; 76 params.producing_host_id = host_id; 77 frame_proxy_in_parent_renderer_->Send(new FrameMsg_CompositorFrameSwapped( 78 frame_proxy_in_parent_renderer_->GetRoutingID(), params)); 79} 80 81void CrossProcessFrameConnector::OnCompositorFrameSwappedACK( 82 const FrameHostMsg_CompositorFrameSwappedACK_Params& params) { 83 RenderWidgetHostImpl::SendSwapCompositorFrameAck(params.producing_route_id, 84 params.output_surface_id, 85 params.producing_host_id, 86 params.ack); 87} 88 89void CrossProcessFrameConnector::OnReclaimCompositorResources( 90 const FrameHostMsg_ReclaimCompositorResources_Params& params) { 91 RenderWidgetHostImpl::SendReclaimCompositorResources(params.route_id, 92 params.output_surface_id, 93 params.renderer_host_id, 94 params.ack); 95} 96 97void CrossProcessFrameConnector::OnInitializeChildFrame(gfx::Rect frame_rect, 98 float scale_factor) { 99 if (scale_factor != device_scale_factor_) 100 SetDeviceScaleFactor(scale_factor); 101 102 if (!frame_rect.size().IsEmpty()) 103 SetSize(frame_rect); 104} 105 106gfx::Rect CrossProcessFrameConnector::ChildFrameRect() { 107 return child_frame_rect_; 108} 109 110void CrossProcessFrameConnector::OnForwardInputEvent( 111 const blink::WebInputEvent* event) { 112 if (!view_) 113 return; 114 115 RenderWidgetHostImpl* child_widget = 116 RenderWidgetHostImpl::From(view_->GetRenderWidgetHost()); 117 RenderWidgetHostImpl* parent_widget = 118 frame_proxy_in_parent_renderer_->GetRenderViewHost(); 119 120 if (blink::WebInputEvent::isKeyboardEventType(event->type)) { 121 if (!parent_widget->GetLastKeyboardEvent()) 122 return; 123 NativeWebKeyboardEvent keyboard_event( 124 *parent_widget->GetLastKeyboardEvent()); 125 child_widget->ForwardKeyboardEvent(keyboard_event); 126 return; 127 } 128 129 if (blink::WebInputEvent::isMouseEventType(event->type)) { 130 child_widget->ForwardMouseEvent( 131 *static_cast<const blink::WebMouseEvent*>(event)); 132 return; 133 } 134 135 if (event->type == blink::WebInputEvent::MouseWheel) { 136 child_widget->ForwardWheelEvent( 137 *static_cast<const blink::WebMouseWheelEvent*>(event)); 138 return; 139 } 140} 141 142void CrossProcessFrameConnector::SetDeviceScaleFactor(float scale_factor) { 143 device_scale_factor_ = scale_factor; 144 if (view_) { 145 RenderWidgetHostImpl* child_widget = 146 RenderWidgetHostImpl::From(view_->GetRenderWidgetHost()); 147 child_widget->NotifyScreenInfoChanged(); 148 } 149} 150 151void CrossProcessFrameConnector::SetSize(gfx::Rect frame_rect) { 152 child_frame_rect_ = frame_rect; 153 if (view_) 154 view_->SetSize(frame_rect.size()); 155} 156 157} // namespace content 158