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