cross_process_frame_connector.cc revision 6d86b77056ed63eb6871182f42a9fd5f07550f90
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_BuffersSwappedACK, OnBuffersSwappedACK)
34    IPC_MESSAGE_HANDLER(FrameHostMsg_CompositorFrameSwappedACK,
35                        OnCompositorFrameSwappedACK)
36    IPC_MESSAGE_HANDLER(FrameHostMsg_ReclaimCompositorResources,
37                        OnReclaimCompositorResources)
38    IPC_MESSAGE_HANDLER(FrameHostMsg_ForwardInputEvent, OnForwardInputEvent)
39    IPC_MESSAGE_HANDLER(FrameHostMsg_InitializeChildFrame,
40                        OnInitializeChildFrame)
41    IPC_MESSAGE_UNHANDLED(handled = false)
42  IPC_END_MESSAGE_MAP()
43
44  return handled;
45}
46
47void CrossProcessFrameConnector::set_view(
48    RenderWidgetHostViewChildFrame* view) {
49  // Detach ourselves from the previous |view_|.
50  if (view_)
51    view_->set_cross_process_frame_connector(NULL);
52
53  view_ = view;
54
55  // Attach ourselves to the new view and size it appropriately.
56  if (view_) {
57    view_->set_cross_process_frame_connector(this);
58    SetDeviceScaleFactor(device_scale_factor_);
59    SetSize(child_frame_rect_);
60  }
61}
62
63void CrossProcessFrameConnector::RenderProcessGone() {
64  frame_proxy_in_parent_renderer_->Send(new FrameMsg_ChildFrameProcessGone(
65      frame_proxy_in_parent_renderer_->GetRoutingID()));
66}
67
68void CrossProcessFrameConnector::ChildFrameBuffersSwapped(
69    const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& gpu_params,
70    int gpu_host_id) {
71
72  FrameMsg_BuffersSwapped_Params params;
73  params.size = gpu_params.size;
74  params.mailbox = gpu_params.mailbox;
75  params.gpu_route_id = gpu_params.route_id;
76  params.gpu_host_id = gpu_host_id;
77
78  frame_proxy_in_parent_renderer_->Send(new FrameMsg_BuffersSwapped(
79      frame_proxy_in_parent_renderer_->GetRoutingID(), params));
80}
81
82void CrossProcessFrameConnector::ChildFrameCompositorFrameSwapped(
83    uint32 output_surface_id,
84    int host_id,
85    int route_id,
86    scoped_ptr<cc::CompositorFrame> frame) {
87  FrameMsg_CompositorFrameSwapped_Params params;
88  frame->AssignTo(&params.frame);
89  params.output_surface_id = output_surface_id;
90  params.producing_route_id = route_id;
91  params.producing_host_id = host_id;
92  frame_proxy_in_parent_renderer_->Send(new FrameMsg_CompositorFrameSwapped(
93      frame_proxy_in_parent_renderer_->GetRoutingID(), params));
94}
95
96void CrossProcessFrameConnector::OnBuffersSwappedACK(
97    const FrameHostMsg_BuffersSwappedACK_Params& params) {
98  AcceleratedSurfaceMsg_BufferPresented_Params ack_params;
99  ack_params.mailbox = params.mailbox;
100  ack_params.sync_point = params.sync_point;
101  RenderWidgetHostImpl::AcknowledgeBufferPresent(params.gpu_route_id,
102                                                 params.gpu_host_id,
103                                                 ack_params);
104
105  // TODO(kenrb): Special case stuff for Win + Mac.
106}
107
108void CrossProcessFrameConnector::OnCompositorFrameSwappedACK(
109    const FrameHostMsg_CompositorFrameSwappedACK_Params& params) {
110  RenderWidgetHostImpl::SendSwapCompositorFrameAck(params.producing_route_id,
111                                                   params.output_surface_id,
112                                                   params.producing_host_id,
113                                                   params.ack);
114}
115
116void CrossProcessFrameConnector::OnReclaimCompositorResources(
117    const FrameHostMsg_ReclaimCompositorResources_Params& params) {
118  RenderWidgetHostImpl::SendReclaimCompositorResources(params.route_id,
119                                                       params.output_surface_id,
120                                                       params.renderer_host_id,
121                                                       params.ack);
122}
123
124void CrossProcessFrameConnector::OnInitializeChildFrame(gfx::Rect frame_rect,
125                                                        float scale_factor) {
126  if (scale_factor != device_scale_factor_)
127    SetDeviceScaleFactor(scale_factor);
128
129  if (!frame_rect.size().IsEmpty())
130    SetSize(frame_rect);
131}
132
133gfx::Rect CrossProcessFrameConnector::ChildFrameRect() {
134  return child_frame_rect_;
135}
136
137void CrossProcessFrameConnector::OnForwardInputEvent(
138    const blink::WebInputEvent* event) {
139  if (!view_)
140    return;
141
142  RenderWidgetHostImpl* child_widget =
143      RenderWidgetHostImpl::From(view_->GetRenderWidgetHost());
144  RenderWidgetHostImpl* parent_widget =
145      frame_proxy_in_parent_renderer_->GetRenderViewHost();
146
147  if (blink::WebInputEvent::isKeyboardEventType(event->type)) {
148    if (!parent_widget->GetLastKeyboardEvent())
149      return;
150    NativeWebKeyboardEvent keyboard_event(
151        *parent_widget->GetLastKeyboardEvent());
152    child_widget->ForwardKeyboardEvent(keyboard_event);
153    return;
154  }
155
156  if (blink::WebInputEvent::isMouseEventType(event->type)) {
157    child_widget->ForwardMouseEvent(
158        *static_cast<const blink::WebMouseEvent*>(event));
159    return;
160  }
161
162  if (event->type == blink::WebInputEvent::MouseWheel) {
163    child_widget->ForwardWheelEvent(
164        *static_cast<const blink::WebMouseWheelEvent*>(event));
165    return;
166  }
167}
168
169void CrossProcessFrameConnector::SetDeviceScaleFactor(float scale_factor) {
170  device_scale_factor_ = scale_factor;
171  if (view_) {
172    RenderWidgetHostImpl* child_widget =
173        RenderWidgetHostImpl::From(view_->GetRenderWidgetHost());
174    child_widget->NotifyScreenInfoChanged();
175  }
176}
177
178void CrossProcessFrameConnector::SetSize(gfx::Rect frame_rect) {
179  child_frame_rect_ = frame_rect;
180  if (view_)
181    view_->SetSize(frame_rect.size());
182}
183
184}  // namespace content
185