Home | History | Annotate | Download | only in frame_host
      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 
     15 namespace content {
     16 
     17 CrossProcessFrameConnector::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 
     24 CrossProcessFrameConnector::~CrossProcessFrameConnector() {
     25   if (view_)
     26     view_->set_cross_process_frame_connector(NULL);
     27 }
     28 
     29 bool 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 
     47 void 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 
     63 void CrossProcessFrameConnector::RenderProcessGone() {
     64   frame_proxy_in_parent_renderer_->Send(new FrameMsg_ChildFrameProcessGone(
     65       frame_proxy_in_parent_renderer_->GetRoutingID()));
     66 }
     67 
     68 void 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 
     82 void 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 
     96 void 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 
    108 void 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 
    116 void 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 
    124 void 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 
    133 gfx::Rect CrossProcessFrameConnector::ChildFrameRect() {
    134   return child_frame_rect_;
    135 }
    136 
    137 void 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 
    169 void 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 
    178 void 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