Home | History | Annotate | Download | only in renderer_host
      1 // Copyright (c) 2012 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/renderer_host/render_widget_host_impl.h"
      6 
      7 #include <math.h>
      8 #include <set>
      9 #include <utility>
     10 
     11 #include "base/auto_reset.h"
     12 #include "base/bind.h"
     13 #include "base/command_line.h"
     14 #include "base/containers/hash_tables.h"
     15 #include "base/debug/trace_event.h"
     16 #include "base/i18n/rtl.h"
     17 #include "base/lazy_instance.h"
     18 #include "base/message_loop/message_loop.h"
     19 #include "base/metrics/field_trial.h"
     20 #include "base/metrics/histogram.h"
     21 #include "base/strings/string_number_conversions.h"
     22 #include "base/strings/utf_string_conversions.h"
     23 #include "base/thread_task_runner_handle.h"
     24 #include "cc/base/switches.h"
     25 #include "cc/output/compositor_frame.h"
     26 #include "cc/output/compositor_frame_ack.h"
     27 #include "content/browser/accessibility/accessibility_mode_helper.h"
     28 #include "content/browser/accessibility/browser_accessibility_state_impl.h"
     29 #include "content/browser/browser_plugin/browser_plugin_guest.h"
     30 #include "content/browser/gpu/compositor_util.h"
     31 #include "content/browser/gpu/gpu_process_host.h"
     32 #include "content/browser/gpu/gpu_process_host_ui_shim.h"
     33 #include "content/browser/gpu/gpu_surface_tracker.h"
     34 #include "content/browser/renderer_host/dip_util.h"
     35 #include "content/browser/renderer_host/input/input_router_config_helper.h"
     36 #include "content/browser/renderer_host/input/input_router_impl.h"
     37 #include "content/browser/renderer_host/input/synthetic_gesture.h"
     38 #include "content/browser/renderer_host/input/synthetic_gesture_controller.h"
     39 #include "content/browser/renderer_host/input/synthetic_gesture_target.h"
     40 #include "content/browser/renderer_host/input/timeout_monitor.h"
     41 #include "content/browser/renderer_host/input/touch_emulator.h"
     42 #include "content/browser/renderer_host/render_process_host_impl.h"
     43 #include "content/browser/renderer_host/render_view_host_impl.h"
     44 #include "content/browser/renderer_host/render_widget_helper.h"
     45 #include "content/browser/renderer_host/render_widget_host_delegate.h"
     46 #include "content/browser/renderer_host/render_widget_host_view_base.h"
     47 #include "content/common/accessibility_messages.h"
     48 #include "content/common/content_constants_internal.h"
     49 #include "content/common/cursors/webcursor.h"
     50 #include "content/common/gpu/gpu_messages.h"
     51 #include "content/common/host_shared_bitmap_manager.h"
     52 #include "content/common/input_messages.h"
     53 #include "content/common/view_messages.h"
     54 #include "content/public/browser/native_web_keyboard_event.h"
     55 #include "content/public/browser/notification_service.h"
     56 #include "content/public/browser/notification_types.h"
     57 #include "content/public/browser/render_widget_host_iterator.h"
     58 #include "content/public/browser/user_metrics.h"
     59 #include "content/public/common/content_constants.h"
     60 #include "content/public/common/content_switches.h"
     61 #include "content/public/common/result_codes.h"
     62 #include "skia/ext/image_operations.h"
     63 #include "skia/ext/platform_canvas.h"
     64 #include "third_party/WebKit/public/web/WebCompositionUnderline.h"
     65 #include "ui/events/event.h"
     66 #include "ui/events/keycodes/keyboard_codes.h"
     67 #include "ui/gfx/size_conversions.h"
     68 #include "ui/gfx/skbitmap_operations.h"
     69 #include "ui/gfx/vector2d_conversions.h"
     70 #include "ui/snapshot/snapshot.h"
     71 #include "webkit/common/webpreferences.h"
     72 
     73 #if defined(OS_WIN)
     74 #include "content/common/plugin_constants_win.h"
     75 #endif
     76 
     77 using base::Time;
     78 using base::TimeDelta;
     79 using base::TimeTicks;
     80 using blink::WebGestureEvent;
     81 using blink::WebInputEvent;
     82 using blink::WebKeyboardEvent;
     83 using blink::WebMouseEvent;
     84 using blink::WebMouseWheelEvent;
     85 using blink::WebTextDirection;
     86 
     87 namespace content {
     88 namespace {
     89 
     90 bool g_check_for_pending_resize_ack = true;
     91 
     92 // How long to (synchronously) wait for the renderer to respond with a
     93 // PaintRect message, when our backing-store is invalid, before giving up and
     94 // returning a null or incorrectly sized backing-store from GetBackingStore.
     95 // This timeout impacts the "choppiness" of our window resize perf.
     96 const int kPaintMsgTimeoutMS = 50;
     97 
     98 typedef std::pair<int32, int32> RenderWidgetHostID;
     99 typedef base::hash_map<RenderWidgetHostID, RenderWidgetHostImpl*>
    100     RoutingIDWidgetMap;
    101 base::LazyInstance<RoutingIDWidgetMap> g_routing_id_widget_map =
    102     LAZY_INSTANCE_INITIALIZER;
    103 
    104 int GetInputRouterViewFlagsFromCompositorFrameMetadata(
    105     const cc::CompositorFrameMetadata metadata) {
    106   int view_flags = InputRouter::VIEW_FLAGS_NONE;
    107 
    108   if (metadata.min_page_scale_factor == metadata.max_page_scale_factor)
    109     view_flags |= InputRouter::FIXED_PAGE_SCALE;
    110 
    111   const float window_width_dip =
    112       std::ceil(metadata.page_scale_factor * metadata.viewport_size.width());
    113   const float content_width_css = metadata.root_layer_size.width();
    114   if (content_width_css <= window_width_dip)
    115     view_flags |= InputRouter::MOBILE_VIEWPORT;
    116 
    117   return view_flags;
    118 }
    119 
    120 // Implements the RenderWidgetHostIterator interface. It keeps a list of
    121 // RenderWidgetHosts, and makes sure it returns a live RenderWidgetHost at each
    122 // iteration (or NULL if there isn't any left).
    123 class RenderWidgetHostIteratorImpl : public RenderWidgetHostIterator {
    124  public:
    125   RenderWidgetHostIteratorImpl()
    126       : current_index_(0) {
    127   }
    128 
    129   virtual ~RenderWidgetHostIteratorImpl() {
    130   }
    131 
    132   void Add(RenderWidgetHost* host) {
    133     hosts_.push_back(RenderWidgetHostID(host->GetProcess()->GetID(),
    134                                         host->GetRoutingID()));
    135   }
    136 
    137   // RenderWidgetHostIterator:
    138   virtual RenderWidgetHost* GetNextHost() OVERRIDE {
    139     RenderWidgetHost* host = NULL;
    140     while (current_index_ < hosts_.size() && !host) {
    141       RenderWidgetHostID id = hosts_[current_index_];
    142       host = RenderWidgetHost::FromID(id.first, id.second);
    143       ++current_index_;
    144     }
    145     return host;
    146   }
    147 
    148  private:
    149   std::vector<RenderWidgetHostID> hosts_;
    150   size_t current_index_;
    151 
    152   DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostIteratorImpl);
    153 };
    154 
    155 }  // namespace
    156 
    157 ///////////////////////////////////////////////////////////////////////////////
    158 // RenderWidgetHostImpl
    159 
    160 RenderWidgetHostImpl::RenderWidgetHostImpl(RenderWidgetHostDelegate* delegate,
    161                                            RenderProcessHost* process,
    162                                            int routing_id,
    163                                            bool hidden)
    164     : view_(NULL),
    165       renderer_initialized_(false),
    166       hung_renderer_delay_ms_(kHungRendererDelayMs),
    167       delegate_(delegate),
    168       process_(process),
    169       routing_id_(routing_id),
    170       surface_id_(0),
    171       is_loading_(false),
    172       is_hidden_(hidden),
    173       is_fullscreen_(false),
    174       repaint_ack_pending_(false),
    175       resize_ack_pending_(false),
    176       screen_info_out_of_date_(false),
    177       overdraw_bottom_height_(0.f),
    178       should_auto_resize_(false),
    179       waiting_for_screen_rects_ack_(false),
    180       accessibility_mode_(AccessibilityModeOff),
    181       needs_repainting_on_restore_(false),
    182       is_unresponsive_(false),
    183       in_flight_event_count_(0),
    184       in_get_backing_store_(false),
    185       ignore_input_events_(false),
    186       input_method_active_(false),
    187       text_direction_updated_(false),
    188       text_direction_(blink::WebTextDirectionLeftToRight),
    189       text_direction_canceled_(false),
    190       suppress_next_char_events_(false),
    191       pending_mouse_lock_request_(false),
    192       allow_privileged_mouse_lock_(false),
    193       has_touch_handler_(false),
    194       weak_factory_(this),
    195       last_input_number_(static_cast<int64>(GetProcess()->GetID()) << 32) {
    196   CHECK(delegate_);
    197   if (routing_id_ == MSG_ROUTING_NONE) {
    198     routing_id_ = process_->GetNextRoutingID();
    199     surface_id_ = GpuSurfaceTracker::Get()->AddSurfaceForRenderer(
    200         process_->GetID(),
    201         routing_id_);
    202   } else {
    203     // TODO(piman): This is a O(N) lookup, where we could forward the
    204     // information from the RenderWidgetHelper. The problem is that doing so
    205     // currently leaks outside of content all the way to chrome classes, and
    206     // would be a layering violation. Since we don't expect more than a few
    207     // hundreds of RWH, this seems acceptable. Revisit if performance become a
    208     // problem, for example by tracking in the RenderWidgetHelper the routing id
    209     // (and surface id) that have been created, but whose RWH haven't yet.
    210     surface_id_ = GpuSurfaceTracker::Get()->LookupSurfaceForRenderer(
    211         process_->GetID(),
    212         routing_id_);
    213     DCHECK(surface_id_);
    214   }
    215 
    216   std::pair<RoutingIDWidgetMap::iterator, bool> result =
    217       g_routing_id_widget_map.Get().insert(std::make_pair(
    218           RenderWidgetHostID(process->GetID(), routing_id_), this));
    219   CHECK(result.second) << "Inserting a duplicate item!";
    220   process_->AddRoute(routing_id_, this);
    221 
    222   // If we're initially visible, tell the process host that we're alive.
    223   // Otherwise we'll notify the process host when we are first shown.
    224   if (!hidden)
    225     process_->WidgetRestored();
    226 
    227   accessibility_mode_ =
    228       BrowserAccessibilityStateImpl::GetInstance()->accessibility_mode();
    229 
    230   input_router_.reset(new InputRouterImpl(
    231       process_, this, this, routing_id_, GetInputRouterConfigForPlatform()));
    232 
    233   touch_emulator_.reset();
    234 
    235   RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>(
    236       IsRenderView() ? RenderViewHost::From(this) : NULL);
    237   if (BrowserPluginGuest::IsGuest(rvh) ||
    238       !CommandLine::ForCurrentProcess()->HasSwitch(
    239           switches::kDisableHangMonitor)) {
    240     hang_monitor_timeout_.reset(new TimeoutMonitor(
    241         base::Bind(&RenderWidgetHostImpl::RendererIsUnresponsive,
    242                    weak_factory_.GetWeakPtr())));
    243   }
    244 }
    245 
    246 RenderWidgetHostImpl::~RenderWidgetHostImpl() {
    247   SetView(NULL);
    248 
    249   GpuSurfaceTracker::Get()->RemoveSurface(surface_id_);
    250   surface_id_ = 0;
    251 
    252   process_->RemoveRoute(routing_id_);
    253   g_routing_id_widget_map.Get().erase(
    254       RenderWidgetHostID(process_->GetID(), routing_id_));
    255 
    256   if (delegate_)
    257     delegate_->RenderWidgetDeleted(this);
    258 }
    259 
    260 // static
    261 RenderWidgetHost* RenderWidgetHost::FromID(
    262     int32 process_id,
    263     int32 routing_id) {
    264   return RenderWidgetHostImpl::FromID(process_id, routing_id);
    265 }
    266 
    267 // static
    268 RenderWidgetHostImpl* RenderWidgetHostImpl::FromID(
    269     int32 process_id,
    270     int32 routing_id) {
    271   DCHECK_CURRENTLY_ON(BrowserThread::UI);
    272   RoutingIDWidgetMap* widgets = g_routing_id_widget_map.Pointer();
    273   RoutingIDWidgetMap::iterator it = widgets->find(
    274       RenderWidgetHostID(process_id, routing_id));
    275   return it == widgets->end() ? NULL : it->second;
    276 }
    277 
    278 // static
    279 scoped_ptr<RenderWidgetHostIterator> RenderWidgetHost::GetRenderWidgetHosts() {
    280   RenderWidgetHostIteratorImpl* hosts = new RenderWidgetHostIteratorImpl();
    281   RoutingIDWidgetMap* widgets = g_routing_id_widget_map.Pointer();
    282   for (RoutingIDWidgetMap::const_iterator it = widgets->begin();
    283        it != widgets->end();
    284        ++it) {
    285     RenderWidgetHost* widget = it->second;
    286 
    287     if (!widget->IsRenderView()) {
    288       hosts->Add(widget);
    289       continue;
    290     }
    291 
    292     // Add only active RenderViewHosts.
    293     RenderViewHost* rvh = RenderViewHost::From(widget);
    294     if (RenderViewHostImpl::IsRVHStateActive(
    295             static_cast<RenderViewHostImpl*>(rvh)->rvh_state()))
    296       hosts->Add(widget);
    297   }
    298 
    299   return scoped_ptr<RenderWidgetHostIterator>(hosts);
    300 }
    301 
    302 // static
    303 scoped_ptr<RenderWidgetHostIterator>
    304 RenderWidgetHostImpl::GetAllRenderWidgetHosts() {
    305   RenderWidgetHostIteratorImpl* hosts = new RenderWidgetHostIteratorImpl();
    306   RoutingIDWidgetMap* widgets = g_routing_id_widget_map.Pointer();
    307   for (RoutingIDWidgetMap::const_iterator it = widgets->begin();
    308        it != widgets->end();
    309        ++it) {
    310     hosts->Add(it->second);
    311   }
    312 
    313   return scoped_ptr<RenderWidgetHostIterator>(hosts);
    314 }
    315 
    316 // static
    317 RenderWidgetHostImpl* RenderWidgetHostImpl::From(RenderWidgetHost* rwh) {
    318   return rwh->AsRenderWidgetHostImpl();
    319 }
    320 
    321 void RenderWidgetHostImpl::SetView(RenderWidgetHostViewBase* view) {
    322   view_ = view;
    323 
    324   GpuSurfaceTracker::Get()->SetSurfaceHandle(
    325       surface_id_, GetCompositingSurface());
    326 
    327   synthetic_gesture_controller_.reset();
    328 }
    329 
    330 RenderProcessHost* RenderWidgetHostImpl::GetProcess() const {
    331   return process_;
    332 }
    333 
    334 int RenderWidgetHostImpl::GetRoutingID() const {
    335   return routing_id_;
    336 }
    337 
    338 RenderWidgetHostView* RenderWidgetHostImpl::GetView() const {
    339   return view_;
    340 }
    341 
    342 RenderWidgetHostImpl* RenderWidgetHostImpl::AsRenderWidgetHostImpl() {
    343   return this;
    344 }
    345 
    346 gfx::NativeViewId RenderWidgetHostImpl::GetNativeViewId() const {
    347   if (view_)
    348     return view_->GetNativeViewId();
    349   return 0;
    350 }
    351 
    352 gfx::GLSurfaceHandle RenderWidgetHostImpl::GetCompositingSurface() {
    353   if (view_)
    354     return view_->GetCompositingSurface();
    355   return gfx::GLSurfaceHandle();
    356 }
    357 
    358 void RenderWidgetHostImpl::ResetSizeAndRepaintPendingFlags() {
    359   resize_ack_pending_ = false;
    360   if (repaint_ack_pending_) {
    361     TRACE_EVENT_ASYNC_END0(
    362         "renderer_host", "RenderWidgetHostImpl::repaint_ack_pending_", this);
    363   }
    364   repaint_ack_pending_ = false;
    365   last_requested_size_.SetSize(0, 0);
    366 }
    367 
    368 void RenderWidgetHostImpl::SendScreenRects() {
    369   if (!renderer_initialized_ || waiting_for_screen_rects_ack_)
    370     return;
    371 
    372   if (is_hidden_) {
    373     // On GTK, this comes in for backgrounded tabs. Ignore, to match what
    374     // happens on Win & Mac, and when the view is shown it'll call this again.
    375     return;
    376   }
    377 
    378   if (!view_)
    379     return;
    380 
    381   last_view_screen_rect_ = view_->GetViewBounds();
    382   last_window_screen_rect_ = view_->GetBoundsInRootWindow();
    383   Send(new ViewMsg_UpdateScreenRects(
    384       GetRoutingID(), last_view_screen_rect_, last_window_screen_rect_));
    385   if (delegate_)
    386     delegate_->DidSendScreenRects(this);
    387   waiting_for_screen_rects_ack_ = true;
    388 }
    389 
    390 void RenderWidgetHostImpl::SuppressNextCharEvents() {
    391   suppress_next_char_events_ = true;
    392 }
    393 
    394 void RenderWidgetHostImpl::FlushInput() {
    395   input_router_->Flush();
    396   if (synthetic_gesture_controller_)
    397     synthetic_gesture_controller_->Flush(base::TimeTicks::Now());
    398 }
    399 
    400 void RenderWidgetHostImpl::SetNeedsFlush() {
    401   if (view_)
    402     view_->OnSetNeedsFlushInput();
    403 }
    404 
    405 void RenderWidgetHostImpl::Init() {
    406   DCHECK(process_->HasConnection());
    407 
    408   renderer_initialized_ = true;
    409 
    410   GpuSurfaceTracker::Get()->SetSurfaceHandle(
    411       surface_id_, GetCompositingSurface());
    412 
    413   // Send the ack along with the information on placement.
    414   Send(new ViewMsg_CreatingNew_ACK(routing_id_));
    415   GetProcess()->ResumeRequestsForView(routing_id_);
    416 
    417   WasResized();
    418 }
    419 
    420 void RenderWidgetHostImpl::Shutdown() {
    421   RejectMouseLockOrUnlockIfNecessary();
    422 
    423   if (process_->HasConnection()) {
    424     // Tell the renderer object to close.
    425     bool rv = Send(new ViewMsg_Close(routing_id_));
    426     DCHECK(rv);
    427   }
    428 
    429   Destroy();
    430 }
    431 
    432 bool RenderWidgetHostImpl::IsLoading() const {
    433   return is_loading_;
    434 }
    435 
    436 bool RenderWidgetHostImpl::IsRenderView() const {
    437   return false;
    438 }
    439 
    440 bool RenderWidgetHostImpl::OnMessageReceived(const IPC::Message &msg) {
    441   bool handled = true;
    442   IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostImpl, msg)
    443     IPC_MESSAGE_HANDLER(InputHostMsg_QueueSyntheticGesture,
    444                         OnQueueSyntheticGesture)
    445     IPC_MESSAGE_HANDLER(ViewHostMsg_RenderViewReady, OnRenderViewReady)
    446     IPC_MESSAGE_HANDLER(ViewHostMsg_RenderProcessGone, OnRenderProcessGone)
    447     IPC_MESSAGE_HANDLER(ViewHostMsg_Close, OnClose)
    448     IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateScreenRects_ACK,
    449                         OnUpdateScreenRectsAck)
    450     IPC_MESSAGE_HANDLER(ViewHostMsg_RequestMove, OnRequestMove)
    451     IPC_MESSAGE_HANDLER(ViewHostMsg_SetTooltipText, OnSetTooltipText)
    452     IPC_MESSAGE_HANDLER_GENERIC(ViewHostMsg_SwapCompositorFrame,
    453                                 OnSwapCompositorFrame(msg))
    454     IPC_MESSAGE_HANDLER(ViewHostMsg_DidStopFlinging, OnFlingingStopped)
    455     IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateRect, OnUpdateRect)
    456     IPC_MESSAGE_HANDLER(ViewHostMsg_Focus, OnFocus)
    457     IPC_MESSAGE_HANDLER(ViewHostMsg_Blur, OnBlur)
    458     IPC_MESSAGE_HANDLER(ViewHostMsg_SetCursor, OnSetCursor)
    459     IPC_MESSAGE_HANDLER(ViewHostMsg_SetTouchEventEmulationEnabled,
    460                         OnSetTouchEventEmulationEnabled)
    461     IPC_MESSAGE_HANDLER(ViewHostMsg_TextInputStateChanged,
    462                         OnTextInputStateChanged)
    463     IPC_MESSAGE_HANDLER(ViewHostMsg_ImeCancelComposition,
    464                         OnImeCancelComposition)
    465     IPC_MESSAGE_HANDLER(ViewHostMsg_LockMouse, OnLockMouse)
    466     IPC_MESSAGE_HANDLER(ViewHostMsg_UnlockMouse, OnUnlockMouse)
    467     IPC_MESSAGE_HANDLER(ViewHostMsg_ShowDisambiguationPopup,
    468                         OnShowDisambiguationPopup)
    469     IPC_MESSAGE_HANDLER(ViewHostMsg_SelectionChanged, OnSelectionChanged)
    470     IPC_MESSAGE_HANDLER(ViewHostMsg_SelectionBoundsChanged,
    471                         OnSelectionBoundsChanged)
    472 #if defined(OS_WIN)
    473     IPC_MESSAGE_HANDLER(ViewHostMsg_WindowlessPluginDummyWindowCreated,
    474                         OnWindowlessPluginDummyWindowCreated)
    475     IPC_MESSAGE_HANDLER(ViewHostMsg_WindowlessPluginDummyWindowDestroyed,
    476                         OnWindowlessPluginDummyWindowDestroyed)
    477 #endif
    478 #if defined(OS_MACOSX)
    479     IPC_MESSAGE_HANDLER(ViewHostMsg_CompositorSurfaceBuffersSwapped,
    480                         OnCompositorSurfaceBuffersSwapped)
    481 #endif
    482 #if defined(OS_MACOSX) || defined(USE_AURA)
    483     IPC_MESSAGE_HANDLER(ViewHostMsg_ImeCompositionRangeChanged,
    484                         OnImeCompositionRangeChanged)
    485 #endif
    486     IPC_MESSAGE_UNHANDLED(handled = false)
    487   IPC_END_MESSAGE_MAP()
    488 
    489   if (!handled && input_router_ && input_router_->OnMessageReceived(msg))
    490     return true;
    491 
    492   if (!handled && view_ && view_->OnMessageReceived(msg))
    493     return true;
    494 
    495   return handled;
    496 }
    497 
    498 bool RenderWidgetHostImpl::Send(IPC::Message* msg) {
    499   if (IPC_MESSAGE_ID_CLASS(msg->type()) == InputMsgStart)
    500     return input_router_->SendInput(make_scoped_ptr(msg));
    501 
    502   return process_->Send(msg);
    503 }
    504 
    505 void RenderWidgetHostImpl::WasHidden() {
    506   if (is_hidden_)
    507     return;
    508 
    509   is_hidden_ = true;
    510 
    511   // Don't bother reporting hung state when we aren't active.
    512   StopHangMonitorTimeout();
    513 
    514   // If we have a renderer, then inform it that we are being hidden so it can
    515   // reduce its resource utilization.
    516   Send(new ViewMsg_WasHidden(routing_id_));
    517 
    518   // Tell the RenderProcessHost we were hidden.
    519   process_->WidgetHidden();
    520 
    521   bool is_visible = false;
    522   NotificationService::current()->Notify(
    523       NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED,
    524       Source<RenderWidgetHost>(this),
    525       Details<bool>(&is_visible));
    526 }
    527 
    528 void RenderWidgetHostImpl::WasShown() {
    529   if (!is_hidden_)
    530     return;
    531   is_hidden_ = false;
    532 
    533   SendScreenRects();
    534 
    535   // Always repaint on restore.
    536   bool needs_repainting = true;
    537   needs_repainting_on_restore_ = false;
    538   Send(new ViewMsg_WasShown(routing_id_, needs_repainting));
    539 
    540   process_->WidgetRestored();
    541 
    542   bool is_visible = true;
    543   NotificationService::current()->Notify(
    544       NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED,
    545       Source<RenderWidgetHost>(this),
    546       Details<bool>(&is_visible));
    547 
    548   // It's possible for our size to be out of sync with the renderer. The
    549   // following is one case that leads to this:
    550   // 1. WasResized -> Send ViewMsg_Resize to render
    551   // 2. WasResized -> do nothing as resize_ack_pending_ is true
    552   // 3. WasHidden
    553   // 4. OnUpdateRect from (1) processed. Does NOT invoke WasResized as view
    554   //    is hidden. Now renderer/browser out of sync with what they think size
    555   //    is.
    556   // By invoking WasResized the renderer is updated as necessary. WasResized
    557   // does nothing if the sizes are already in sync.
    558   //
    559   // TODO: ideally ViewMsg_WasShown would take a size. This way, the renderer
    560   // could handle both the restore and resize at once. This isn't that big a
    561   // deal as RenderWidget::WasShown delays updating, so that the resize from
    562   // WasResized is usually processed before the renderer is painted.
    563   WasResized();
    564 }
    565 
    566 void RenderWidgetHostImpl::WasResized() {
    567   // Skip if the |delegate_| has already been detached because
    568   // it's web contents is being deleted.
    569   if (resize_ack_pending_ || !process_->HasConnection() || !view_ ||
    570       !renderer_initialized_ || should_auto_resize_ || !delegate_) {
    571     return;
    572   }
    573 
    574   gfx::Size new_size(view_->GetRequestedRendererSize());
    575 
    576   gfx::Size old_physical_backing_size = physical_backing_size_;
    577   physical_backing_size_ = view_->GetPhysicalBackingSize();
    578   bool was_fullscreen = is_fullscreen_;
    579   is_fullscreen_ = IsFullscreen();
    580   float old_overdraw_bottom_height = overdraw_bottom_height_;
    581   overdraw_bottom_height_ = view_->GetOverdrawBottomHeight();
    582   gfx::Size old_visible_viewport_size = visible_viewport_size_;
    583   visible_viewport_size_ = view_->GetVisibleViewportSize();
    584 
    585   bool size_changed = new_size != last_requested_size_;
    586   bool side_payload_changed =
    587       screen_info_out_of_date_ ||
    588       old_physical_backing_size != physical_backing_size_ ||
    589       was_fullscreen != is_fullscreen_ ||
    590       old_overdraw_bottom_height != overdraw_bottom_height_ ||
    591       old_visible_viewport_size != visible_viewport_size_;
    592 
    593   if (!size_changed && !side_payload_changed)
    594     return;
    595 
    596   if (!screen_info_) {
    597     screen_info_.reset(new blink::WebScreenInfo);
    598     GetWebScreenInfo(screen_info_.get());
    599   }
    600 
    601   // We don't expect to receive an ACK when the requested size or the physical
    602   // backing size is empty, or when the main viewport size didn't change.
    603   if (!new_size.IsEmpty() && !physical_backing_size_.IsEmpty() && size_changed)
    604     resize_ack_pending_ = g_check_for_pending_resize_ack;
    605 
    606   ViewMsg_Resize_Params params;
    607   params.screen_info = *screen_info_;
    608   params.new_size = new_size;
    609   params.physical_backing_size = physical_backing_size_;
    610   params.overdraw_bottom_height = overdraw_bottom_height_;
    611   params.visible_viewport_size = visible_viewport_size_;
    612   params.resizer_rect = GetRootWindowResizerRect();
    613   params.is_fullscreen = is_fullscreen_;
    614   if (!Send(new ViewMsg_Resize(routing_id_, params))) {
    615     resize_ack_pending_ = false;
    616   } else {
    617     last_requested_size_ = new_size;
    618   }
    619 }
    620 
    621 void RenderWidgetHostImpl::ResizeRectChanged(const gfx::Rect& new_rect) {
    622   Send(new ViewMsg_ChangeResizeRect(routing_id_, new_rect));
    623 }
    624 
    625 void RenderWidgetHostImpl::GotFocus() {
    626   Focus();
    627 }
    628 
    629 void RenderWidgetHostImpl::Focus() {
    630   Send(new InputMsg_SetFocus(routing_id_, true));
    631 }
    632 
    633 void RenderWidgetHostImpl::Blur() {
    634   // If there is a pending mouse lock request, we don't want to reject it at
    635   // this point. The user can switch focus back to this view and approve the
    636   // request later.
    637   if (IsMouseLocked())
    638     view_->UnlockMouse();
    639 
    640   if (touch_emulator_)
    641     touch_emulator_->CancelTouch();
    642 
    643   Send(new InputMsg_SetFocus(routing_id_, false));
    644 }
    645 
    646 void RenderWidgetHostImpl::LostCapture() {
    647   if (touch_emulator_)
    648     touch_emulator_->CancelTouch();
    649 
    650   Send(new InputMsg_MouseCaptureLost(routing_id_));
    651 }
    652 
    653 void RenderWidgetHostImpl::SetActive(bool active) {
    654   Send(new ViewMsg_SetActive(routing_id_, active));
    655 }
    656 
    657 void RenderWidgetHostImpl::LostMouseLock() {
    658   Send(new ViewMsg_MouseLockLost(routing_id_));
    659 }
    660 
    661 void RenderWidgetHostImpl::ViewDestroyed() {
    662   RejectMouseLockOrUnlockIfNecessary();
    663 
    664   // TODO(evanm): tracking this may no longer be necessary;
    665   // eliminate this function if so.
    666   SetView(NULL);
    667 }
    668 
    669 void RenderWidgetHostImpl::SetIsLoading(bool is_loading) {
    670   is_loading_ = is_loading;
    671   if (!view_)
    672     return;
    673   view_->SetIsLoading(is_loading);
    674 }
    675 
    676 void RenderWidgetHostImpl::CopyFromBackingStore(
    677     const gfx::Rect& src_subrect,
    678     const gfx::Size& accelerated_dst_size,
    679     const base::Callback<void(bool, const SkBitmap&)>& callback,
    680     const SkBitmap::Config& bitmap_config) {
    681   if (view_) {
    682     TRACE_EVENT0("browser",
    683         "RenderWidgetHostImpl::CopyFromBackingStore::FromCompositingSurface");
    684     gfx::Rect accelerated_copy_rect = src_subrect.IsEmpty() ?
    685         gfx::Rect(view_->GetViewBounds().size()) : src_subrect;
    686     view_->CopyFromCompositingSurface(
    687         accelerated_copy_rect, accelerated_dst_size, callback, bitmap_config);
    688     return;
    689   }
    690 
    691   callback.Run(false, SkBitmap());
    692 }
    693 
    694 bool RenderWidgetHostImpl::CanCopyFromBackingStore() {
    695   if (view_)
    696     return view_->IsSurfaceAvailableForCopy();
    697   return false;
    698 }
    699 
    700 #if defined(OS_ANDROID)
    701 void RenderWidgetHostImpl::LockBackingStore() {
    702   if (view_)
    703     view_->LockCompositingSurface();
    704 }
    705 
    706 void RenderWidgetHostImpl::UnlockBackingStore() {
    707   if (view_)
    708     view_->UnlockCompositingSurface();
    709 }
    710 #endif
    711 
    712 void RenderWidgetHostImpl::PauseForPendingResizeOrRepaints() {
    713   TRACE_EVENT0("browser",
    714       "RenderWidgetHostImpl::PauseForPendingResizeOrRepaints");
    715 
    716   if (!CanPauseForPendingResizeOrRepaints())
    717     return;
    718 
    719   WaitForSurface();
    720 }
    721 
    722 bool RenderWidgetHostImpl::CanPauseForPendingResizeOrRepaints() {
    723   // Do not pause if the view is hidden.
    724   if (is_hidden())
    725     return false;
    726 
    727   // Do not pause if there is not a paint or resize already coming.
    728   if (!repaint_ack_pending_ && !resize_ack_pending_)
    729     return false;
    730 
    731   return true;
    732 }
    733 
    734 void RenderWidgetHostImpl::WaitForSurface() {
    735   TRACE_EVENT0("browser", "RenderWidgetHostImpl::WaitForSurface");
    736 
    737   if (!view_)
    738     return;
    739 
    740   // The view_size will be current_size_ for auto-sized views and otherwise the
    741   // size of the view_. (For auto-sized views, current_size_ is updated during
    742   // UpdateRect messages.)
    743   gfx::Size view_size = current_size_;
    744   if (!should_auto_resize_) {
    745     // Get the desired size from the current view bounds.
    746     gfx::Rect view_rect = view_->GetViewBounds();
    747     if (view_rect.IsEmpty())
    748       return;
    749     view_size = view_rect.size();
    750   }
    751 
    752   TRACE_EVENT2("renderer_host",
    753                "RenderWidgetHostImpl::WaitForBackingStore",
    754                "width",
    755                base::IntToString(view_size.width()),
    756                "height",
    757                base::IntToString(view_size.height()));
    758 
    759   // We should not be asked to paint while we are hidden.  If we are hidden,
    760   // then it means that our consumer failed to call WasShown. If we're not
    761   // force creating the backing store, it's OK since we can feel free to give
    762   // out our cached one if we have it.
    763   DCHECK(!is_hidden_) << "WaitForSurface called while hidden!";
    764 
    765   // We should never be called recursively; this can theoretically lead to
    766   // infinite recursion and almost certainly leads to lower performance.
    767   DCHECK(!in_get_backing_store_) << "WaitForSurface called recursively!";
    768   base::AutoReset<bool> auto_reset_in_get_backing_store(
    769       &in_get_backing_store_, true);
    770 
    771   // We might have a surface that we can use!
    772   if (view_->HasAcceleratedSurface(view_size))
    773     return;
    774 
    775   // We do not have a suitable backing store in the cache, so send out a
    776   // request to the renderer to paint the view if required.
    777   if (!repaint_ack_pending_ && !resize_ack_pending_) {
    778     repaint_start_time_ = TimeTicks::Now();
    779     repaint_ack_pending_ = true;
    780     TRACE_EVENT_ASYNC_BEGIN0(
    781         "renderer_host", "RenderWidgetHostImpl::repaint_ack_pending_", this);
    782     Send(new ViewMsg_Repaint(routing_id_, view_size));
    783   }
    784 
    785   TimeDelta max_delay = TimeDelta::FromMilliseconds(kPaintMsgTimeoutMS);
    786   TimeTicks end_time = TimeTicks::Now() + max_delay;
    787   do {
    788     TRACE_EVENT0("renderer_host", "WaitForSurface::WaitForUpdate");
    789 
    790     // When we have asked the RenderWidget to resize, and we are still waiting
    791     // on a response, block for a little while to see if we can't get a response
    792     // before returning the old (incorrectly sized) backing store.
    793     IPC::Message msg;
    794     if (process_->WaitForBackingStoreMsg(routing_id_, max_delay, &msg)) {
    795       OnMessageReceived(msg);
    796 
    797       // For auto-resized views, current_size_ determines the view_size and it
    798       // may have changed during the handling of an UpdateRect message.
    799       if (should_auto_resize_)
    800         view_size = current_size_;
    801 
    802       // Break now if we got a backing store or accelerated surface of the
    803       // correct size.
    804       if (view_->HasAcceleratedSurface(view_size))
    805         return;
    806     } else {
    807       TRACE_EVENT0("renderer_host", "WaitForSurface::Timeout");
    808       break;
    809     }
    810 
    811     // Loop if we still have time left and haven't gotten a properly sized
    812     // BackingStore yet. This is necessary to support the GPU path which
    813     // typically has multiple frames pipelined -- we may need to skip one or two
    814     // BackingStore messages to get to the latest.
    815     max_delay = end_time - TimeTicks::Now();
    816   } while (max_delay > TimeDelta::FromSeconds(0));
    817 }
    818 
    819 bool RenderWidgetHostImpl::ScheduleComposite() {
    820   if (is_hidden_ || current_size_.IsEmpty() || repaint_ack_pending_ ||
    821       resize_ack_pending_) {
    822     return false;
    823   }
    824 
    825   // Send out a request to the renderer to paint the view if required.
    826   repaint_start_time_ = TimeTicks::Now();
    827   repaint_ack_pending_ = true;
    828   TRACE_EVENT_ASYNC_BEGIN0(
    829       "renderer_host", "RenderWidgetHostImpl::repaint_ack_pending_", this);
    830   Send(new ViewMsg_Repaint(routing_id_, current_size_));
    831   return true;
    832 }
    833 
    834 void RenderWidgetHostImpl::StartHangMonitorTimeout(base::TimeDelta delay) {
    835   if (hang_monitor_timeout_)
    836     hang_monitor_timeout_->Start(delay);
    837 }
    838 
    839 void RenderWidgetHostImpl::RestartHangMonitorTimeout() {
    840   if (hang_monitor_timeout_)
    841     hang_monitor_timeout_->Restart(
    842         base::TimeDelta::FromMilliseconds(hung_renderer_delay_ms_));
    843 }
    844 
    845 void RenderWidgetHostImpl::StopHangMonitorTimeout() {
    846   if (hang_monitor_timeout_)
    847     hang_monitor_timeout_->Stop();
    848   RendererIsResponsive();
    849 }
    850 
    851 void RenderWidgetHostImpl::EnableFullAccessibilityMode() {
    852   AddAccessibilityMode(AccessibilityModeComplete);
    853 }
    854 
    855 bool RenderWidgetHostImpl::IsFullAccessibilityModeForTesting() {
    856   return accessibility_mode() == AccessibilityModeComplete;
    857 }
    858 
    859 void RenderWidgetHostImpl::EnableTreeOnlyAccessibilityMode() {
    860   AddAccessibilityMode(AccessibilityModeTreeOnly);
    861 }
    862 
    863 bool RenderWidgetHostImpl::IsTreeOnlyAccessibilityModeForTesting() {
    864   return accessibility_mode() == AccessibilityModeTreeOnly;
    865 }
    866 
    867 void RenderWidgetHostImpl::ForwardMouseEvent(const WebMouseEvent& mouse_event) {
    868   ForwardMouseEventWithLatencyInfo(mouse_event, ui::LatencyInfo());
    869 }
    870 
    871 void RenderWidgetHostImpl::ForwardMouseEventWithLatencyInfo(
    872       const blink::WebMouseEvent& mouse_event,
    873       const ui::LatencyInfo& ui_latency) {
    874   TRACE_EVENT2("input", "RenderWidgetHostImpl::ForwardMouseEvent",
    875                "x", mouse_event.x, "y", mouse_event.y);
    876 
    877   ui::LatencyInfo latency_info =
    878       CreateRWHLatencyInfoIfNotExist(&ui_latency, mouse_event.type);
    879 
    880   for (size_t i = 0; i < mouse_event_callbacks_.size(); ++i) {
    881     if (mouse_event_callbacks_[i].Run(mouse_event))
    882       return;
    883   }
    884 
    885   if (IgnoreInputEvents())
    886     return;
    887 
    888   if (touch_emulator_ && touch_emulator_->HandleMouseEvent(mouse_event))
    889     return;
    890 
    891   input_router_->SendMouseEvent(MouseEventWithLatencyInfo(mouse_event,
    892                                                           latency_info));
    893 }
    894 
    895 void RenderWidgetHostImpl::OnPointerEventActivate() {
    896 }
    897 
    898 void RenderWidgetHostImpl::ForwardWheelEvent(
    899     const WebMouseWheelEvent& wheel_event) {
    900   ForwardWheelEventWithLatencyInfo(wheel_event, ui::LatencyInfo());
    901 }
    902 
    903 void RenderWidgetHostImpl::ForwardWheelEventWithLatencyInfo(
    904       const blink::WebMouseWheelEvent& wheel_event,
    905       const ui::LatencyInfo& ui_latency) {
    906   TRACE_EVENT0("input", "RenderWidgetHostImpl::ForwardWheelEvent");
    907 
    908   ui::LatencyInfo latency_info =
    909       CreateRWHLatencyInfoIfNotExist(&ui_latency, wheel_event.type);
    910 
    911   if (IgnoreInputEvents())
    912     return;
    913 
    914   if (touch_emulator_ && touch_emulator_->HandleMouseWheelEvent(wheel_event))
    915     return;
    916 
    917   input_router_->SendWheelEvent(MouseWheelEventWithLatencyInfo(wheel_event,
    918                                                                latency_info));
    919 }
    920 
    921 void RenderWidgetHostImpl::ForwardGestureEvent(
    922     const blink::WebGestureEvent& gesture_event) {
    923   ForwardGestureEventWithLatencyInfo(gesture_event, ui::LatencyInfo());
    924 }
    925 
    926 void RenderWidgetHostImpl::ForwardGestureEventWithLatencyInfo(
    927     const blink::WebGestureEvent& gesture_event,
    928     const ui::LatencyInfo& ui_latency) {
    929   TRACE_EVENT0("input", "RenderWidgetHostImpl::ForwardGestureEvent");
    930   // Early out if necessary, prior to performing latency logic.
    931   if (IgnoreInputEvents())
    932     return;
    933 
    934   if (delegate_->PreHandleGestureEvent(gesture_event))
    935     return;
    936 
    937   ui::LatencyInfo latency_info =
    938       CreateRWHLatencyInfoIfNotExist(&ui_latency, gesture_event.type);
    939 
    940   if (gesture_event.type == blink::WebInputEvent::GestureScrollUpdate) {
    941     latency_info.AddLatencyNumber(
    942         ui::INPUT_EVENT_LATENCY_SCROLL_UPDATE_RWH_COMPONENT,
    943         GetLatencyComponentId(),
    944         ++last_input_number_);
    945 
    946     // Make a copy of the INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT with a
    947     // different name INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT.
    948     // So we can track the latency specifically for scroll update events.
    949     ui::LatencyInfo::LatencyComponent original_component;
    950     if (latency_info.FindLatency(ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT,
    951                                  0,
    952                                  &original_component)) {
    953       latency_info.AddLatencyNumberWithTimestamp(
    954           ui::INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT,
    955           GetLatencyComponentId(),
    956           original_component.sequence_number,
    957           original_component.event_time,
    958           original_component.event_count);
    959     }
    960   }
    961 
    962   GestureEventWithLatencyInfo gesture_with_latency(gesture_event, latency_info);
    963   input_router_->SendGestureEvent(gesture_with_latency);
    964 }
    965 
    966 void RenderWidgetHostImpl::ForwardTouchEvent(
    967       const blink::WebTouchEvent& touch_event) {
    968   ForwardTouchEventWithLatencyInfo(touch_event, ui::LatencyInfo());
    969 }
    970 
    971 void RenderWidgetHostImpl::ForwardTouchEventWithLatencyInfo(
    972       const blink::WebTouchEvent& touch_event,
    973       const ui::LatencyInfo& ui_latency) {
    974   TRACE_EVENT0("input", "RenderWidgetHostImpl::ForwardTouchEvent");
    975 
    976   // Always forward TouchEvents for touch stream consistency. They will be
    977   // ignored if appropriate in FilterInputEvent().
    978 
    979   ui::LatencyInfo latency_info =
    980       CreateRWHLatencyInfoIfNotExist(&ui_latency, touch_event.type);
    981   TouchEventWithLatencyInfo touch_with_latency(touch_event, latency_info);
    982   input_router_->SendTouchEvent(touch_with_latency);
    983 }
    984 
    985 void RenderWidgetHostImpl::ForwardKeyboardEvent(
    986     const NativeWebKeyboardEvent& key_event) {
    987   TRACE_EVENT0("input", "RenderWidgetHostImpl::ForwardKeyboardEvent");
    988   if (IgnoreInputEvents())
    989     return;
    990 
    991   if (!process_->HasConnection())
    992     return;
    993 
    994   // First, let keypress listeners take a shot at handling the event.  If a
    995   // listener handles the event, it should not be propagated to the renderer.
    996   if (KeyPressListenersHandleEvent(key_event)) {
    997     // Some keypresses that are accepted by the listener might have follow up
    998     // char events, which should be ignored.
    999     if (key_event.type == WebKeyboardEvent::RawKeyDown)
   1000       suppress_next_char_events_ = true;
   1001     return;
   1002   }
   1003 
   1004   if (key_event.type == WebKeyboardEvent::Char &&
   1005       (key_event.windowsKeyCode == ui::VKEY_RETURN ||
   1006        key_event.windowsKeyCode == ui::VKEY_SPACE)) {
   1007     OnUserGesture();
   1008   }
   1009 
   1010   // Double check the type to make sure caller hasn't sent us nonsense that
   1011   // will mess up our key queue.
   1012   if (!WebInputEvent::isKeyboardEventType(key_event.type))
   1013     return;
   1014 
   1015   if (suppress_next_char_events_) {
   1016     // If preceding RawKeyDown event was handled by the browser, then we need
   1017     // suppress all Char events generated by it. Please note that, one
   1018     // RawKeyDown event may generate multiple Char events, so we can't reset
   1019     // |suppress_next_char_events_| until we get a KeyUp or a RawKeyDown.
   1020     if (key_event.type == WebKeyboardEvent::Char)
   1021       return;
   1022     // We get a KeyUp or a RawKeyDown event.
   1023     suppress_next_char_events_ = false;
   1024   }
   1025 
   1026   bool is_shortcut = false;
   1027 
   1028   // Only pre-handle the key event if it's not handled by the input method.
   1029   if (delegate_ && !key_event.skip_in_browser) {
   1030     // We need to set |suppress_next_char_events_| to true if
   1031     // PreHandleKeyboardEvent() returns true, but |this| may already be
   1032     // destroyed at that time. So set |suppress_next_char_events_| true here,
   1033     // then revert it afterwards when necessary.
   1034     if (key_event.type == WebKeyboardEvent::RawKeyDown)
   1035       suppress_next_char_events_ = true;
   1036 
   1037     // Tab switching/closing accelerators aren't sent to the renderer to avoid
   1038     // a hung/malicious renderer from interfering.
   1039     if (delegate_->PreHandleKeyboardEvent(key_event, &is_shortcut))
   1040       return;
   1041 
   1042     if (key_event.type == WebKeyboardEvent::RawKeyDown)
   1043       suppress_next_char_events_ = false;
   1044   }
   1045 
   1046   if (touch_emulator_ && touch_emulator_->HandleKeyboardEvent(key_event))
   1047     return;
   1048 
   1049   input_router_->SendKeyboardEvent(
   1050       key_event,
   1051       CreateRWHLatencyInfoIfNotExist(NULL, key_event.type),
   1052       is_shortcut);
   1053 }
   1054 
   1055 void RenderWidgetHostImpl::QueueSyntheticGesture(
   1056     scoped_ptr<SyntheticGesture> synthetic_gesture,
   1057     const base::Callback<void(SyntheticGesture::Result)>& on_complete) {
   1058   if (!synthetic_gesture_controller_ && view_) {
   1059     synthetic_gesture_controller_.reset(
   1060         new SyntheticGestureController(
   1061             view_->CreateSyntheticGestureTarget().Pass()));
   1062   }
   1063   if (synthetic_gesture_controller_) {
   1064     synthetic_gesture_controller_->QueueSyntheticGesture(
   1065         synthetic_gesture.Pass(), on_complete);
   1066   }
   1067 }
   1068 
   1069 void RenderWidgetHostImpl::SetCursor(const WebCursor& cursor) {
   1070   if (!view_)
   1071     return;
   1072   view_->UpdateCursor(cursor);
   1073 }
   1074 
   1075 void RenderWidgetHostImpl::ShowContextMenuAtPoint(const gfx::Point& point) {
   1076   Send(new ViewMsg_ShowContextMenu(
   1077       GetRoutingID(), ui::MENU_SOURCE_MOUSE, point));
   1078 }
   1079 
   1080 void RenderWidgetHostImpl::SendCursorVisibilityState(bool is_visible) {
   1081   Send(new InputMsg_CursorVisibilityChange(GetRoutingID(), is_visible));
   1082 }
   1083 
   1084 int64 RenderWidgetHostImpl::GetLatencyComponentId() {
   1085   return GetRoutingID() | (static_cast<int64>(GetProcess()->GetID()) << 32);
   1086 }
   1087 
   1088 // static
   1089 void RenderWidgetHostImpl::DisableResizeAckCheckForTesting() {
   1090   g_check_for_pending_resize_ack = false;
   1091 }
   1092 
   1093 ui::LatencyInfo RenderWidgetHostImpl::CreateRWHLatencyInfoIfNotExist(
   1094     const ui::LatencyInfo* original, WebInputEvent::Type type) {
   1095   ui::LatencyInfo info;
   1096   if (original)
   1097     info = *original;
   1098   // In Aura, gesture event will already carry its original touch event's
   1099   // INPUT_EVENT_LATENCY_RWH_COMPONENT.
   1100   if (!info.FindLatency(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
   1101                         GetLatencyComponentId(),
   1102                         NULL)) {
   1103     info.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
   1104                           GetLatencyComponentId(),
   1105                           ++last_input_number_);
   1106     info.TraceEventType(WebInputEventTraits::GetName(type));
   1107   }
   1108   return info;
   1109 }
   1110 
   1111 
   1112 void RenderWidgetHostImpl::AddKeyPressEventCallback(
   1113     const KeyPressEventCallback& callback) {
   1114   key_press_event_callbacks_.push_back(callback);
   1115 }
   1116 
   1117 void RenderWidgetHostImpl::RemoveKeyPressEventCallback(
   1118     const KeyPressEventCallback& callback) {
   1119   for (size_t i = 0; i < key_press_event_callbacks_.size(); ++i) {
   1120     if (key_press_event_callbacks_[i].Equals(callback)) {
   1121       key_press_event_callbacks_.erase(
   1122           key_press_event_callbacks_.begin() + i);
   1123       return;
   1124     }
   1125   }
   1126 }
   1127 
   1128 void RenderWidgetHostImpl::AddMouseEventCallback(
   1129     const MouseEventCallback& callback) {
   1130   mouse_event_callbacks_.push_back(callback);
   1131 }
   1132 
   1133 void RenderWidgetHostImpl::RemoveMouseEventCallback(
   1134     const MouseEventCallback& callback) {
   1135   for (size_t i = 0; i < mouse_event_callbacks_.size(); ++i) {
   1136     if (mouse_event_callbacks_[i].Equals(callback)) {
   1137       mouse_event_callbacks_.erase(mouse_event_callbacks_.begin() + i);
   1138       return;
   1139     }
   1140   }
   1141 }
   1142 
   1143 void RenderWidgetHostImpl::GetWebScreenInfo(blink::WebScreenInfo* result) {
   1144   TRACE_EVENT0("renderer_host", "RenderWidgetHostImpl::GetWebScreenInfo");
   1145   if (view_)
   1146     view_->GetScreenInfo(result);
   1147   else
   1148     RenderWidgetHostViewBase::GetDefaultScreenInfo(result);
   1149   screen_info_out_of_date_ = false;
   1150 }
   1151 
   1152 const NativeWebKeyboardEvent*
   1153     RenderWidgetHostImpl::GetLastKeyboardEvent() const {
   1154   return input_router_->GetLastKeyboardEvent();
   1155 }
   1156 
   1157 void RenderWidgetHostImpl::NotifyScreenInfoChanged() {
   1158   // The resize message (which may not happen immediately) will carry with it
   1159   // the screen info as well as the new size (if the screen has changed scale
   1160   // factor).
   1161   InvalidateScreenInfo();
   1162   WasResized();
   1163 }
   1164 
   1165 void RenderWidgetHostImpl::InvalidateScreenInfo() {
   1166   screen_info_out_of_date_ = true;
   1167   screen_info_.reset();
   1168 }
   1169 
   1170 void RenderWidgetHostImpl::OnSelectionChanged(const base::string16& text,
   1171                                               size_t offset,
   1172                                               const gfx::Range& range) {
   1173   if (view_)
   1174     view_->SelectionChanged(text, offset, range);
   1175 }
   1176 
   1177 void RenderWidgetHostImpl::OnSelectionBoundsChanged(
   1178     const ViewHostMsg_SelectionBounds_Params& params) {
   1179   if (view_) {
   1180     view_->SelectionBoundsChanged(params);
   1181   }
   1182 }
   1183 
   1184 void RenderWidgetHostImpl::UpdateVSyncParameters(base::TimeTicks timebase,
   1185                                                  base::TimeDelta interval) {
   1186   Send(new ViewMsg_UpdateVSyncParameters(GetRoutingID(), timebase, interval));
   1187 }
   1188 
   1189 void RenderWidgetHostImpl::RendererExited(base::TerminationStatus status,
   1190                                           int exit_code) {
   1191   // Clearing this flag causes us to re-create the renderer when recovering
   1192   // from a crashed renderer.
   1193   renderer_initialized_ = false;
   1194 
   1195   waiting_for_screen_rects_ack_ = false;
   1196 
   1197   // Must reset these to ensure that keyboard events work with a new renderer.
   1198   suppress_next_char_events_ = false;
   1199 
   1200   // Reset some fields in preparation for recovering from a crash.
   1201   ResetSizeAndRepaintPendingFlags();
   1202   current_size_.SetSize(0, 0);
   1203   // After the renderer crashes, the view is destroyed and so the
   1204   // RenderWidgetHost cannot track its visibility anymore. We assume such
   1205   // RenderWidgetHost to be visible for the sake of internal accounting - be
   1206   // careful about changing this - see http://crbug.com/401859.
   1207   //
   1208   // We need to at least make sure that the RenderProcessHost is notified about
   1209   // the |is_hidden_| change, so that the renderer will have correct visibility
   1210   // set when respawned.
   1211   if (is_hidden_) {
   1212     process_->WidgetRestored();
   1213     is_hidden_ = false;
   1214   }
   1215 
   1216   // Reset this to ensure the hung renderer mechanism is working properly.
   1217   in_flight_event_count_ = 0;
   1218 
   1219   if (view_) {
   1220     GpuSurfaceTracker::Get()->SetSurfaceHandle(surface_id_,
   1221                                                gfx::GLSurfaceHandle());
   1222     view_->RenderProcessGone(status, exit_code);
   1223     view_ = NULL;  // The View should be deleted by RenderProcessGone.
   1224   }
   1225 
   1226   // Reconstruct the input router to ensure that it has fresh state for a new
   1227   // renderer. Otherwise it may be stuck waiting for the old renderer to ack an
   1228   // event. (In particular, the above call to view_->RenderProcessGone will
   1229   // destroy the aura window, which may dispatch a synthetic mouse move.)
   1230   input_router_.reset(new InputRouterImpl(
   1231       process_, this, this, routing_id_, GetInputRouterConfigForPlatform()));
   1232 
   1233   synthetic_gesture_controller_.reset();
   1234 }
   1235 
   1236 void RenderWidgetHostImpl::UpdateTextDirection(WebTextDirection direction) {
   1237   text_direction_updated_ = true;
   1238   text_direction_ = direction;
   1239 }
   1240 
   1241 void RenderWidgetHostImpl::CancelUpdateTextDirection() {
   1242   if (text_direction_updated_)
   1243     text_direction_canceled_ = true;
   1244 }
   1245 
   1246 void RenderWidgetHostImpl::NotifyTextDirection() {
   1247   if (text_direction_updated_) {
   1248     if (!text_direction_canceled_)
   1249       Send(new ViewMsg_SetTextDirection(GetRoutingID(), text_direction_));
   1250     text_direction_updated_ = false;
   1251     text_direction_canceled_ = false;
   1252   }
   1253 }
   1254 
   1255 void RenderWidgetHostImpl::SetInputMethodActive(bool activate) {
   1256   input_method_active_ = activate;
   1257   Send(new ViewMsg_SetInputMethodActive(GetRoutingID(), activate));
   1258 }
   1259 
   1260 void RenderWidgetHostImpl::CandidateWindowShown() {
   1261   Send(new ViewMsg_CandidateWindowShown(GetRoutingID()));
   1262 }
   1263 
   1264 void RenderWidgetHostImpl::CandidateWindowUpdated() {
   1265   Send(new ViewMsg_CandidateWindowUpdated(GetRoutingID()));
   1266 }
   1267 
   1268 void RenderWidgetHostImpl::CandidateWindowHidden() {
   1269   Send(new ViewMsg_CandidateWindowHidden(GetRoutingID()));
   1270 }
   1271 
   1272 void RenderWidgetHostImpl::ImeSetComposition(
   1273     const base::string16& text,
   1274     const std::vector<blink::WebCompositionUnderline>& underlines,
   1275     int selection_start,
   1276     int selection_end) {
   1277   Send(new ViewMsg_ImeSetComposition(
   1278             GetRoutingID(), text, underlines, selection_start, selection_end));
   1279 }
   1280 
   1281 void RenderWidgetHostImpl::ImeConfirmComposition(
   1282     const base::string16& text,
   1283     const gfx::Range& replacement_range,
   1284     bool keep_selection) {
   1285   Send(new ViewMsg_ImeConfirmComposition(
   1286         GetRoutingID(), text, replacement_range, keep_selection));
   1287 }
   1288 
   1289 void RenderWidgetHostImpl::ImeCancelComposition() {
   1290   Send(new ViewMsg_ImeSetComposition(GetRoutingID(), base::string16(),
   1291             std::vector<blink::WebCompositionUnderline>(), 0, 0));
   1292 }
   1293 
   1294 gfx::Rect RenderWidgetHostImpl::GetRootWindowResizerRect() const {
   1295   return gfx::Rect();
   1296 }
   1297 
   1298 void RenderWidgetHostImpl::RequestToLockMouse(bool user_gesture,
   1299                                               bool last_unlocked_by_target) {
   1300   // Directly reject to lock the mouse. Subclass can override this method to
   1301   // decide whether to allow mouse lock or not.
   1302   GotResponseToLockMouseRequest(false);
   1303 }
   1304 
   1305 void RenderWidgetHostImpl::RejectMouseLockOrUnlockIfNecessary() {
   1306   DCHECK(!pending_mouse_lock_request_ || !IsMouseLocked());
   1307   if (pending_mouse_lock_request_) {
   1308     pending_mouse_lock_request_ = false;
   1309     Send(new ViewMsg_LockMouse_ACK(routing_id_, false));
   1310   } else if (IsMouseLocked()) {
   1311     view_->UnlockMouse();
   1312   }
   1313 }
   1314 
   1315 bool RenderWidgetHostImpl::IsMouseLocked() const {
   1316   return view_ ? view_->IsMouseLocked() : false;
   1317 }
   1318 
   1319 bool RenderWidgetHostImpl::IsFullscreen() const {
   1320   return false;
   1321 }
   1322 
   1323 void RenderWidgetHostImpl::SetShouldAutoResize(bool enable) {
   1324   should_auto_resize_ = enable;
   1325 }
   1326 
   1327 void RenderWidgetHostImpl::Destroy() {
   1328   NotificationService::current()->Notify(
   1329       NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED,
   1330       Source<RenderWidgetHost>(this),
   1331       NotificationService::NoDetails());
   1332 
   1333   // Tell the view to die.
   1334   // Note that in the process of the view shutting down, it can call a ton
   1335   // of other messages on us.  So if you do any other deinitialization here,
   1336   // do it after this call to view_->Destroy().
   1337   if (view_)
   1338     view_->Destroy();
   1339 
   1340   delete this;
   1341 }
   1342 
   1343 void RenderWidgetHostImpl::RendererIsUnresponsive() {
   1344   NotificationService::current()->Notify(
   1345       NOTIFICATION_RENDER_WIDGET_HOST_HANG,
   1346       Source<RenderWidgetHost>(this),
   1347       NotificationService::NoDetails());
   1348   is_unresponsive_ = true;
   1349   NotifyRendererUnresponsive();
   1350 }
   1351 
   1352 void RenderWidgetHostImpl::RendererIsResponsive() {
   1353   if (is_unresponsive_) {
   1354     is_unresponsive_ = false;
   1355     NotifyRendererResponsive();
   1356   }
   1357 }
   1358 
   1359 void RenderWidgetHostImpl::OnRenderViewReady() {
   1360   SendScreenRects();
   1361   WasResized();
   1362 }
   1363 
   1364 void RenderWidgetHostImpl::OnRenderProcessGone(int status, int exit_code) {
   1365   // TODO(evanm): This synchronously ends up calling "delete this".
   1366   // Is that really what we want in response to this message?  I'm matching
   1367   // previous behavior of the code here.
   1368   Destroy();
   1369 }
   1370 
   1371 void RenderWidgetHostImpl::OnClose() {
   1372   Shutdown();
   1373 }
   1374 
   1375 void RenderWidgetHostImpl::OnSetTooltipText(
   1376     const base::string16& tooltip_text,
   1377     WebTextDirection text_direction_hint) {
   1378   // First, add directionality marks around tooltip text if necessary.
   1379   // A naive solution would be to simply always wrap the text. However, on
   1380   // windows, Unicode directional embedding characters can't be displayed on
   1381   // systems that lack RTL fonts and are instead displayed as empty squares.
   1382   //
   1383   // To get around this we only wrap the string when we deem it necessary i.e.
   1384   // when the locale direction is different than the tooltip direction hint.
   1385   //
   1386   // Currently, we use element's directionality as the tooltip direction hint.
   1387   // An alternate solution would be to set the overall directionality based on
   1388   // trying to detect the directionality from the tooltip text rather than the
   1389   // element direction.  One could argue that would be a preferable solution
   1390   // but we use the current approach to match Fx & IE's behavior.
   1391   base::string16 wrapped_tooltip_text = tooltip_text;
   1392   if (!tooltip_text.empty()) {
   1393     if (text_direction_hint == blink::WebTextDirectionLeftToRight) {
   1394       // Force the tooltip to have LTR directionality.
   1395       wrapped_tooltip_text =
   1396           base::i18n::GetDisplayStringInLTRDirectionality(wrapped_tooltip_text);
   1397     } else if (text_direction_hint == blink::WebTextDirectionRightToLeft &&
   1398                !base::i18n::IsRTL()) {
   1399       // Force the tooltip to have RTL directionality.
   1400       base::i18n::WrapStringWithRTLFormatting(&wrapped_tooltip_text);
   1401     }
   1402   }
   1403   if (GetView())
   1404     view_->SetTooltipText(wrapped_tooltip_text);
   1405 }
   1406 
   1407 void RenderWidgetHostImpl::OnUpdateScreenRectsAck() {
   1408   waiting_for_screen_rects_ack_ = false;
   1409   if (!view_)
   1410     return;
   1411 
   1412   if (view_->GetViewBounds() == last_view_screen_rect_ &&
   1413       view_->GetBoundsInRootWindow() == last_window_screen_rect_) {
   1414     return;
   1415   }
   1416 
   1417   SendScreenRects();
   1418 }
   1419 
   1420 void RenderWidgetHostImpl::OnRequestMove(const gfx::Rect& pos) {
   1421   if (view_) {
   1422     view_->SetBounds(pos);
   1423     Send(new ViewMsg_Move_ACK(routing_id_));
   1424   }
   1425 }
   1426 
   1427 #if defined(OS_MACOSX)
   1428 void RenderWidgetHostImpl::OnCompositorSurfaceBuffersSwapped(
   1429       const ViewHostMsg_CompositorSurfaceBuffersSwapped_Params& params) {
   1430   // This trace event is used in
   1431   // chrome/browser/extensions/api/cast_streaming/performance_test.cc
   1432   TRACE_EVENT0("renderer_host",
   1433                "RenderWidgetHostImpl::OnCompositorSurfaceBuffersSwapped");
   1434   // This trace event is used in
   1435   // chrome/browser/extensions/api/cast_streaming/performance_test.cc
   1436   UNSHIPPED_TRACE_EVENT0("test_fps",
   1437                          TRACE_DISABLED_BY_DEFAULT("OnSwapCompositorFrame"));
   1438   if (!ui::LatencyInfo::Verify(params.latency_info,
   1439                                "ViewHostMsg_CompositorSurfaceBuffersSwapped"))
   1440     return;
   1441   if (!view_) {
   1442     AcceleratedSurfaceMsg_BufferPresented_Params ack_params;
   1443     ack_params.sync_point = 0;
   1444     RenderWidgetHostImpl::AcknowledgeBufferPresent(params.route_id,
   1445                                                    params.gpu_process_host_id,
   1446                                                    ack_params);
   1447     return;
   1448   }
   1449   GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params gpu_params;
   1450   gpu_params.surface_id = params.surface_id;
   1451   gpu_params.surface_handle = params.surface_handle;
   1452   gpu_params.route_id = params.route_id;
   1453   gpu_params.size = params.size;
   1454   gpu_params.scale_factor = params.scale_factor;
   1455   gpu_params.latency_info = params.latency_info;
   1456   for (size_t i = 0; i < gpu_params.latency_info.size(); i++)
   1457     AddLatencyInfoComponentIds(&gpu_params.latency_info[i]);
   1458   view_->AcceleratedSurfaceBuffersSwapped(gpu_params,
   1459                                           params.gpu_process_host_id);
   1460   view_->DidReceiveRendererFrame();
   1461 }
   1462 #endif  // OS_MACOSX
   1463 
   1464 bool RenderWidgetHostImpl::OnSwapCompositorFrame(
   1465     const IPC::Message& message) {
   1466   // This trace event is used in
   1467   // chrome/browser/extensions/api/cast_streaming/performance_test.cc
   1468   UNSHIPPED_TRACE_EVENT0("test_fps",
   1469                          TRACE_DISABLED_BY_DEFAULT("OnSwapCompositorFrame"));
   1470   ViewHostMsg_SwapCompositorFrame::Param param;
   1471   if (!ViewHostMsg_SwapCompositorFrame::Read(&message, &param))
   1472     return false;
   1473   scoped_ptr<cc::CompositorFrame> frame(new cc::CompositorFrame);
   1474   uint32 output_surface_id = param.a;
   1475   param.b.AssignTo(frame.get());
   1476 
   1477   for (size_t i = 0; i < frame->metadata.latency_info.size(); i++)
   1478     AddLatencyInfoComponentIds(&frame->metadata.latency_info[i]);
   1479 
   1480   input_router_->OnViewUpdated(
   1481       GetInputRouterViewFlagsFromCompositorFrameMetadata(frame->metadata));
   1482 
   1483   if (view_) {
   1484     view_->OnSwapCompositorFrame(output_surface_id, frame.Pass());
   1485     view_->DidReceiveRendererFrame();
   1486   } else {
   1487     cc::CompositorFrameAck ack;
   1488     if (frame->gl_frame_data) {
   1489       ack.gl_frame_data = frame->gl_frame_data.Pass();
   1490       ack.gl_frame_data->sync_point = 0;
   1491     } else if (frame->delegated_frame_data) {
   1492       cc::TransferableResource::ReturnResources(
   1493           frame->delegated_frame_data->resource_list,
   1494           &ack.resources);
   1495     } else if (frame->software_frame_data) {
   1496       ack.last_software_frame_id = frame->software_frame_data->id;
   1497     }
   1498     SendSwapCompositorFrameAck(routing_id_, output_surface_id,
   1499                                process_->GetID(), ack);
   1500   }
   1501   return true;
   1502 }
   1503 
   1504 void RenderWidgetHostImpl::OnFlingingStopped() {
   1505   if (view_)
   1506     view_->DidStopFlinging();
   1507 }
   1508 
   1509 void RenderWidgetHostImpl::OnUpdateRect(
   1510     const ViewHostMsg_UpdateRect_Params& params) {
   1511   TRACE_EVENT0("renderer_host", "RenderWidgetHostImpl::OnUpdateRect");
   1512   TimeTicks paint_start = TimeTicks::Now();
   1513 
   1514   // Update our knowledge of the RenderWidget's size.
   1515   current_size_ = params.view_size;
   1516   // Update our knowledge of the RenderWidget's scroll offset.
   1517   last_scroll_offset_ = params.scroll_offset;
   1518 
   1519   bool is_resize_ack =
   1520       ViewHostMsg_UpdateRect_Flags::is_resize_ack(params.flags);
   1521 
   1522   // resize_ack_pending_ needs to be cleared before we call DidPaintRect, since
   1523   // that will end up reaching GetBackingStore.
   1524   if (is_resize_ack) {
   1525     DCHECK(!g_check_for_pending_resize_ack || resize_ack_pending_);
   1526     resize_ack_pending_ = false;
   1527   }
   1528 
   1529   bool is_repaint_ack =
   1530       ViewHostMsg_UpdateRect_Flags::is_repaint_ack(params.flags);
   1531   if (is_repaint_ack) {
   1532     DCHECK(repaint_ack_pending_);
   1533     TRACE_EVENT_ASYNC_END0(
   1534         "renderer_host", "RenderWidgetHostImpl::repaint_ack_pending_", this);
   1535     repaint_ack_pending_ = false;
   1536     TimeDelta delta = TimeTicks::Now() - repaint_start_time_;
   1537     UMA_HISTOGRAM_TIMES("MPArch.RWH_RepaintDelta", delta);
   1538   }
   1539 
   1540   DCHECK(!params.view_size.IsEmpty());
   1541 
   1542   DidUpdateBackingStore(params, paint_start);
   1543 
   1544   if (should_auto_resize_) {
   1545     bool post_callback = new_auto_size_.IsEmpty();
   1546     new_auto_size_ = params.view_size;
   1547     if (post_callback) {
   1548       base::MessageLoop::current()->PostTask(
   1549           FROM_HERE,
   1550           base::Bind(&RenderWidgetHostImpl::DelayedAutoResized,
   1551                      weak_factory_.GetWeakPtr()));
   1552     }
   1553   }
   1554 
   1555   // Log the time delta for processing a paint message. On platforms that don't
   1556   // support asynchronous painting, this is equivalent to
   1557   // MPArch.RWH_TotalPaintTime.
   1558   TimeDelta delta = TimeTicks::Now() - paint_start;
   1559   UMA_HISTOGRAM_TIMES("MPArch.RWH_OnMsgUpdateRect", delta);
   1560 }
   1561 
   1562 void RenderWidgetHostImpl::DidUpdateBackingStore(
   1563     const ViewHostMsg_UpdateRect_Params& params,
   1564     const TimeTicks& paint_start) {
   1565   TRACE_EVENT0("renderer_host", "RenderWidgetHostImpl::DidUpdateBackingStore");
   1566   TimeTicks update_start = TimeTicks::Now();
   1567 
   1568   // Move the plugins if the view hasn't already been destroyed.  Plugin moves
   1569   // will not be re-issued, so must move them now, regardless of whether we
   1570   // paint or not.  MovePluginWindows attempts to move the plugin windows and
   1571   // in the process could dispatch other window messages which could cause the
   1572   // view to be destroyed.
   1573   if (view_)
   1574     view_->MovePluginWindows(params.plugin_window_moves);
   1575 
   1576   NotificationService::current()->Notify(
   1577       NOTIFICATION_RENDER_WIDGET_HOST_DID_UPDATE_BACKING_STORE,
   1578       Source<RenderWidgetHost>(this),
   1579       NotificationService::NoDetails());
   1580 
   1581   // We don't need to update the view if the view is hidden. We must do this
   1582   // early return after the ACK is sent, however, or the renderer will not send
   1583   // us more data.
   1584   if (is_hidden_)
   1585     return;
   1586 
   1587   // If we got a resize ack, then perhaps we have another resize to send?
   1588   bool is_resize_ack =
   1589       ViewHostMsg_UpdateRect_Flags::is_resize_ack(params.flags);
   1590   if (is_resize_ack)
   1591     WasResized();
   1592 
   1593   // Log the time delta for processing a paint message.
   1594   TimeTicks now = TimeTicks::Now();
   1595   TimeDelta delta = now - update_start;
   1596   UMA_HISTOGRAM_TIMES("MPArch.RWH_DidUpdateBackingStore", delta);
   1597 }
   1598 
   1599 void RenderWidgetHostImpl::OnQueueSyntheticGesture(
   1600     const SyntheticGesturePacket& gesture_packet) {
   1601   // Only allow untrustworthy gestures if explicitly enabled.
   1602   if (!CommandLine::ForCurrentProcess()->HasSwitch(
   1603           cc::switches::kEnableGpuBenchmarking)) {
   1604     RecordAction(base::UserMetricsAction("BadMessageTerminate_RWH7"));
   1605     GetProcess()->ReceivedBadMessage();
   1606     return;
   1607   }
   1608 
   1609   QueueSyntheticGesture(
   1610         SyntheticGesture::Create(*gesture_packet.gesture_params()),
   1611         base::Bind(&RenderWidgetHostImpl::OnSyntheticGestureCompleted,
   1612                    weak_factory_.GetWeakPtr()));
   1613 }
   1614 
   1615 void RenderWidgetHostImpl::OnFocus() {
   1616   // Only RenderViewHost can deal with that message.
   1617   RecordAction(base::UserMetricsAction("BadMessageTerminate_RWH4"));
   1618   GetProcess()->ReceivedBadMessage();
   1619 }
   1620 
   1621 void RenderWidgetHostImpl::OnBlur() {
   1622   // Only RenderViewHost can deal with that message.
   1623   RecordAction(base::UserMetricsAction("BadMessageTerminate_RWH5"));
   1624   GetProcess()->ReceivedBadMessage();
   1625 }
   1626 
   1627 void RenderWidgetHostImpl::OnSetCursor(const WebCursor& cursor) {
   1628   SetCursor(cursor);
   1629 }
   1630 
   1631 void RenderWidgetHostImpl::OnSetTouchEventEmulationEnabled(
   1632     bool enabled, bool allow_pinch) {
   1633   if (delegate_)
   1634     delegate_->OnTouchEmulationEnabled(enabled);
   1635 
   1636   if (enabled) {
   1637     if (!touch_emulator_)
   1638       touch_emulator_.reset(new TouchEmulator(this));
   1639     touch_emulator_->Enable(allow_pinch);
   1640   } else {
   1641     if (touch_emulator_)
   1642       touch_emulator_->Disable();
   1643   }
   1644 }
   1645 
   1646 void RenderWidgetHostImpl::OnTextInputStateChanged(
   1647     const ViewHostMsg_TextInputState_Params& params) {
   1648   if (view_)
   1649     view_->TextInputStateChanged(params);
   1650 }
   1651 
   1652 #if defined(OS_MACOSX) || defined(USE_AURA)
   1653 void RenderWidgetHostImpl::OnImeCompositionRangeChanged(
   1654     const gfx::Range& range,
   1655     const std::vector<gfx::Rect>& character_bounds) {
   1656   if (view_)
   1657     view_->ImeCompositionRangeChanged(range, character_bounds);
   1658 }
   1659 #endif
   1660 
   1661 void RenderWidgetHostImpl::OnImeCancelComposition() {
   1662   if (view_)
   1663     view_->ImeCancelComposition();
   1664 }
   1665 
   1666 void RenderWidgetHostImpl::OnLockMouse(bool user_gesture,
   1667                                        bool last_unlocked_by_target,
   1668                                        bool privileged) {
   1669 
   1670   if (pending_mouse_lock_request_) {
   1671     Send(new ViewMsg_LockMouse_ACK(routing_id_, false));
   1672     return;
   1673   } else if (IsMouseLocked()) {
   1674     Send(new ViewMsg_LockMouse_ACK(routing_id_, true));
   1675     return;
   1676   }
   1677 
   1678   pending_mouse_lock_request_ = true;
   1679   if (privileged && allow_privileged_mouse_lock_) {
   1680     // Directly approve to lock the mouse.
   1681     GotResponseToLockMouseRequest(true);
   1682   } else {
   1683     RequestToLockMouse(user_gesture, last_unlocked_by_target);
   1684   }
   1685 }
   1686 
   1687 void RenderWidgetHostImpl::OnUnlockMouse() {
   1688   RejectMouseLockOrUnlockIfNecessary();
   1689 }
   1690 
   1691 void RenderWidgetHostImpl::OnShowDisambiguationPopup(
   1692     const gfx::Rect& rect,
   1693     const gfx::Size& size,
   1694     const cc::SharedBitmapId& id) {
   1695   DCHECK(!rect.IsEmpty());
   1696   DCHECK(!size.IsEmpty());
   1697 
   1698   scoped_ptr<cc::SharedBitmap> bitmap =
   1699       HostSharedBitmapManager::current()->GetSharedBitmapFromId(size, id);
   1700   if (!bitmap) {
   1701     RecordAction(base::UserMetricsAction("BadMessageTerminate_RWH6"));
   1702     GetProcess()->ReceivedBadMessage();
   1703     return;
   1704   }
   1705 
   1706   DCHECK(bitmap->pixels());
   1707 
   1708   SkBitmap zoomed_bitmap;
   1709   zoomed_bitmap.setConfig(SkBitmap::kARGB_8888_Config,
   1710       size.width(), size.height());
   1711   zoomed_bitmap.setPixels(bitmap->pixels());
   1712 
   1713 #if defined(OS_ANDROID)
   1714   if (view_)
   1715     view_->ShowDisambiguationPopup(rect, zoomed_bitmap);
   1716 #else
   1717   NOTIMPLEMENTED();
   1718 #endif
   1719 
   1720   zoomed_bitmap.setPixels(0);
   1721   Send(new ViewMsg_ReleaseDisambiguationPopupBitmap(GetRoutingID(), id));
   1722 }
   1723 
   1724 #if defined(OS_WIN)
   1725 void RenderWidgetHostImpl::OnWindowlessPluginDummyWindowCreated(
   1726     gfx::NativeViewId dummy_activation_window) {
   1727   HWND hwnd = reinterpret_cast<HWND>(dummy_activation_window);
   1728 
   1729   // This may happen as a result of a race condition when the plugin is going
   1730   // away.
   1731   wchar_t window_title[MAX_PATH + 1] = {0};
   1732   if (!IsWindow(hwnd) ||
   1733       !GetWindowText(hwnd, window_title, arraysize(window_title)) ||
   1734       lstrcmpiW(window_title, kDummyActivationWindowName) != 0) {
   1735     return;
   1736   }
   1737 
   1738 #if defined(USE_AURA)
   1739   SetParent(hwnd,
   1740             reinterpret_cast<HWND>(view_->GetParentForWindowlessPlugin()));
   1741 #else
   1742   SetParent(hwnd, reinterpret_cast<HWND>(GetNativeViewId()));
   1743 #endif
   1744   dummy_windows_for_activation_.push_back(hwnd);
   1745 }
   1746 
   1747 void RenderWidgetHostImpl::OnWindowlessPluginDummyWindowDestroyed(
   1748     gfx::NativeViewId dummy_activation_window) {
   1749   HWND hwnd = reinterpret_cast<HWND>(dummy_activation_window);
   1750   std::list<HWND>::iterator i = dummy_windows_for_activation_.begin();
   1751   for (; i != dummy_windows_for_activation_.end(); ++i) {
   1752     if ((*i) == hwnd) {
   1753       dummy_windows_for_activation_.erase(i);
   1754       return;
   1755     }
   1756   }
   1757   NOTREACHED() << "Unknown dummy window";
   1758 }
   1759 #endif
   1760 
   1761 void RenderWidgetHostImpl::SetIgnoreInputEvents(bool ignore_input_events) {
   1762   ignore_input_events_ = ignore_input_events;
   1763 }
   1764 
   1765 bool RenderWidgetHostImpl::KeyPressListenersHandleEvent(
   1766     const NativeWebKeyboardEvent& event) {
   1767   if (event.skip_in_browser || event.type != WebKeyboardEvent::RawKeyDown)
   1768     return false;
   1769 
   1770   for (size_t i = 0; i < key_press_event_callbacks_.size(); i++) {
   1771     size_t original_size = key_press_event_callbacks_.size();
   1772     if (key_press_event_callbacks_[i].Run(event))
   1773       return true;
   1774 
   1775     // Check whether the callback that just ran removed itself, in which case
   1776     // the iterator needs to be decremented to properly account for the removal.
   1777     size_t current_size = key_press_event_callbacks_.size();
   1778     if (current_size != original_size) {
   1779       DCHECK_EQ(original_size - 1, current_size);
   1780       --i;
   1781     }
   1782   }
   1783 
   1784   return false;
   1785 }
   1786 
   1787 InputEventAckState RenderWidgetHostImpl::FilterInputEvent(
   1788     const blink::WebInputEvent& event, const ui::LatencyInfo& latency_info) {
   1789   // Don't ignore touch cancel events, since they may be sent while input
   1790   // events are being ignored in order to keep the renderer from getting
   1791   // confused about how many touches are active.
   1792   if (IgnoreInputEvents() && event.type != WebInputEvent::TouchCancel)
   1793     return INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS;
   1794 
   1795   if (!process_->HasConnection())
   1796     return INPUT_EVENT_ACK_STATE_UNKNOWN;
   1797 
   1798   if (event.type == WebInputEvent::MouseDown)
   1799     OnUserGesture();
   1800 
   1801   return view_ ? view_->FilterInputEvent(event)
   1802                : INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
   1803 }
   1804 
   1805 void RenderWidgetHostImpl::IncrementInFlightEventCount() {
   1806   StartHangMonitorTimeout(
   1807       TimeDelta::FromMilliseconds(hung_renderer_delay_ms_));
   1808   increment_in_flight_event_count();
   1809 }
   1810 
   1811 void RenderWidgetHostImpl::DecrementInFlightEventCount() {
   1812   DCHECK_GE(in_flight_event_count_, 0);
   1813   // Cancel pending hung renderer checks since the renderer is responsive.
   1814   if (decrement_in_flight_event_count() <= 0)
   1815     StopHangMonitorTimeout();
   1816 }
   1817 
   1818 void RenderWidgetHostImpl::OnHasTouchEventHandlers(bool has_handlers) {
   1819   has_touch_handler_ = has_handlers;
   1820 }
   1821 
   1822 void RenderWidgetHostImpl::DidFlush() {
   1823   if (synthetic_gesture_controller_)
   1824     synthetic_gesture_controller_->OnDidFlushInput();
   1825   if (view_)
   1826     view_->OnDidFlushInput();
   1827 }
   1828 
   1829 void RenderWidgetHostImpl::DidOverscroll(const DidOverscrollParams& params) {
   1830   if (view_)
   1831     view_->DidOverscroll(params);
   1832 }
   1833 
   1834 void RenderWidgetHostImpl::OnKeyboardEventAck(
   1835       const NativeWebKeyboardEvent& event,
   1836       InputEventAckState ack_result) {
   1837 #if defined(OS_MACOSX)
   1838   if (!is_hidden() && view_ && view_->PostProcessEventForPluginIme(event))
   1839     return;
   1840 #endif
   1841 
   1842   // We only send unprocessed key event upwards if we are not hidden,
   1843   // because the user has moved away from us and no longer expect any effect
   1844   // of this key event.
   1845   const bool processed = (INPUT_EVENT_ACK_STATE_CONSUMED == ack_result);
   1846   if (delegate_ && !processed && !is_hidden() && !event.skip_in_browser) {
   1847     delegate_->HandleKeyboardEvent(event);
   1848 
   1849     // WARNING: This RenderWidgetHostImpl can be deallocated at this point
   1850     // (i.e.  in the case of Ctrl+W, where the call to
   1851     // HandleKeyboardEvent destroys this RenderWidgetHostImpl).
   1852   }
   1853 }
   1854 
   1855 void RenderWidgetHostImpl::OnWheelEventAck(
   1856     const MouseWheelEventWithLatencyInfo& wheel_event,
   1857     InputEventAckState ack_result) {
   1858   if (!wheel_event.latency.FindLatency(
   1859           ui::INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_COMPONENT, 0, NULL)) {
   1860     // MouseWheelEvent latency ends when it is acked but does not cause any
   1861     // rendering scheduled.
   1862     ui::LatencyInfo latency = wheel_event.latency;
   1863     latency.AddLatencyNumber(
   1864         ui::INPUT_EVENT_LATENCY_TERMINATED_MOUSE_COMPONENT, 0, 0);
   1865   }
   1866 
   1867   if (!is_hidden() && view_) {
   1868     if (ack_result != INPUT_EVENT_ACK_STATE_CONSUMED &&
   1869         delegate_->HandleWheelEvent(wheel_event.event)) {
   1870       ack_result = INPUT_EVENT_ACK_STATE_CONSUMED;
   1871     }
   1872     view_->WheelEventAck(wheel_event.event, ack_result);
   1873   }
   1874 }
   1875 
   1876 void RenderWidgetHostImpl::OnGestureEventAck(
   1877     const GestureEventWithLatencyInfo& event,
   1878     InputEventAckState ack_result) {
   1879   if (!event.latency.FindLatency(
   1880           ui::INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_COMPONENT, 0, NULL)) {
   1881     // GestureEvent latency ends when it is acked but does not cause any
   1882     // rendering scheduled.
   1883     ui::LatencyInfo latency = event.latency;
   1884     latency.AddLatencyNumber(
   1885         ui::INPUT_EVENT_LATENCY_TERMINATED_GESTURE_COMPONENT, 0 ,0);
   1886   }
   1887 
   1888   if (ack_result != INPUT_EVENT_ACK_STATE_CONSUMED) {
   1889     if (delegate_->HandleGestureEvent(event.event))
   1890       ack_result = INPUT_EVENT_ACK_STATE_CONSUMED;
   1891   }
   1892 
   1893   if (view_)
   1894     view_->GestureEventAck(event.event, ack_result);
   1895 }
   1896 
   1897 void RenderWidgetHostImpl::OnTouchEventAck(
   1898     const TouchEventWithLatencyInfo& event,
   1899     InputEventAckState ack_result) {
   1900   TouchEventWithLatencyInfo touch_event = event;
   1901   touch_event.latency.AddLatencyNumber(
   1902       ui::INPUT_EVENT_LATENCY_ACKED_TOUCH_COMPONENT, 0, 0);
   1903   // TouchEvent latency ends at ack if it didn't cause any rendering.
   1904   if (!touch_event.latency.FindLatency(
   1905           ui::INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_COMPONENT, 0, NULL)) {
   1906     touch_event.latency.AddLatencyNumber(
   1907         ui::INPUT_EVENT_LATENCY_TERMINATED_TOUCH_COMPONENT, 0, 0);
   1908   }
   1909   ComputeTouchLatency(touch_event.latency);
   1910 
   1911   if (touch_emulator_ && touch_emulator_->HandleTouchEventAck(ack_result))
   1912     return;
   1913 
   1914   if (view_)
   1915     view_->ProcessAckedTouchEvent(touch_event, ack_result);
   1916 }
   1917 
   1918 void RenderWidgetHostImpl::OnUnexpectedEventAck(UnexpectedEventAckType type) {
   1919   if (type == BAD_ACK_MESSAGE) {
   1920     RecordAction(base::UserMetricsAction("BadMessageTerminate_RWH2"));
   1921     process_->ReceivedBadMessage();
   1922   } else if (type == UNEXPECTED_EVENT_TYPE) {
   1923     suppress_next_char_events_ = false;
   1924   }
   1925 }
   1926 
   1927 void RenderWidgetHostImpl::OnSyntheticGestureCompleted(
   1928     SyntheticGesture::Result result) {
   1929   Send(new InputMsg_SyntheticGestureCompleted(GetRoutingID()));
   1930 }
   1931 
   1932 const gfx::Vector2d& RenderWidgetHostImpl::GetLastScrollOffset() const {
   1933   return last_scroll_offset_;
   1934 }
   1935 
   1936 bool RenderWidgetHostImpl::IgnoreInputEvents() const {
   1937   return ignore_input_events_ || process_->IgnoreInputEvents();
   1938 }
   1939 
   1940 bool RenderWidgetHostImpl::ShouldForwardTouchEvent() const {
   1941   return input_router_->ShouldForwardTouchEvent();
   1942 }
   1943 
   1944 void RenderWidgetHostImpl::StartUserGesture() {
   1945   OnUserGesture();
   1946 }
   1947 
   1948 void RenderWidgetHostImpl::Stop() {
   1949   Send(new ViewMsg_Stop(GetRoutingID()));
   1950 }
   1951 
   1952 void RenderWidgetHostImpl::SetBackgroundOpaque(bool opaque) {
   1953   Send(new ViewMsg_SetBackgroundOpaque(GetRoutingID(), opaque));
   1954 }
   1955 
   1956 void RenderWidgetHostImpl::SetEditCommandsForNextKeyEvent(
   1957     const std::vector<EditCommand>& commands) {
   1958   Send(new InputMsg_SetEditCommandsForNextKeyEvent(GetRoutingID(), commands));
   1959 }
   1960 
   1961 void RenderWidgetHostImpl::AddAccessibilityMode(AccessibilityMode mode) {
   1962   SetAccessibilityMode(
   1963       content::AddAccessibilityModeTo(accessibility_mode_, mode));
   1964 }
   1965 
   1966 void RenderWidgetHostImpl::RemoveAccessibilityMode(AccessibilityMode mode) {
   1967   SetAccessibilityMode(
   1968       content::RemoveAccessibilityModeFrom(accessibility_mode_, mode));
   1969 }
   1970 
   1971 void RenderWidgetHostImpl::ResetAccessibilityMode() {
   1972   SetAccessibilityMode(
   1973       BrowserAccessibilityStateImpl::GetInstance()->accessibility_mode());
   1974 }
   1975 
   1976 void RenderWidgetHostImpl::SetAccessibilityMode(AccessibilityMode mode) {
   1977   accessibility_mode_ = mode;
   1978   Send(new ViewMsg_SetAccessibilityMode(GetRoutingID(), mode));
   1979 }
   1980 
   1981 void RenderWidgetHostImpl::AccessibilitySetFocus(int object_id) {
   1982   Send(new AccessibilityMsg_SetFocus(GetRoutingID(), object_id));
   1983   view_->OnAccessibilitySetFocus(object_id);
   1984 }
   1985 
   1986 void RenderWidgetHostImpl::AccessibilityDoDefaultAction(int object_id) {
   1987   Send(new AccessibilityMsg_DoDefaultAction(GetRoutingID(), object_id));
   1988 }
   1989 
   1990 void RenderWidgetHostImpl::AccessibilityShowMenu(int object_id) {
   1991   view_->AccessibilityShowMenu(object_id);
   1992 }
   1993 
   1994 void RenderWidgetHostImpl::AccessibilityScrollToMakeVisible(
   1995     int acc_obj_id, gfx::Rect subfocus) {
   1996   Send(new AccessibilityMsg_ScrollToMakeVisible(
   1997       GetRoutingID(), acc_obj_id, subfocus));
   1998 }
   1999 
   2000 void RenderWidgetHostImpl::AccessibilityScrollToPoint(
   2001     int acc_obj_id, gfx::Point point) {
   2002   Send(new AccessibilityMsg_ScrollToPoint(
   2003       GetRoutingID(), acc_obj_id, point));
   2004 }
   2005 
   2006 void RenderWidgetHostImpl::AccessibilitySetTextSelection(
   2007     int object_id, int start_offset, int end_offset) {
   2008   Send(new AccessibilityMsg_SetTextSelection(
   2009       GetRoutingID(), object_id, start_offset, end_offset));
   2010 }
   2011 
   2012 bool RenderWidgetHostImpl::AccessibilityViewHasFocus() const {
   2013   return view_->HasFocus();
   2014 }
   2015 
   2016 gfx::Rect RenderWidgetHostImpl::AccessibilityGetViewBounds() const {
   2017   return view_->GetViewBounds();
   2018 }
   2019 
   2020 gfx::Point RenderWidgetHostImpl::AccessibilityOriginInScreen(
   2021     const gfx::Rect& bounds) const {
   2022   return view_->AccessibilityOriginInScreen(bounds);
   2023 }
   2024 
   2025 void RenderWidgetHostImpl::AccessibilityHitTest(const gfx::Point& point) {
   2026   Send(new AccessibilityMsg_HitTest(GetRoutingID(), point));
   2027 }
   2028 
   2029 void RenderWidgetHostImpl::AccessibilityFatalError() {
   2030   Send(new AccessibilityMsg_FatalError(GetRoutingID()));
   2031   view_->SetBrowserAccessibilityManager(NULL);
   2032 }
   2033 
   2034 #if defined(OS_WIN)
   2035 void RenderWidgetHostImpl::SetParentNativeViewAccessible(
   2036     gfx::NativeViewAccessible accessible_parent) {
   2037   if (view_)
   2038     view_->SetParentNativeViewAccessible(accessible_parent);
   2039 }
   2040 
   2041 gfx::NativeViewAccessible
   2042 RenderWidgetHostImpl::GetParentNativeViewAccessible() const {
   2043   return delegate_->GetParentNativeViewAccessible();
   2044 }
   2045 #endif
   2046 
   2047 void RenderWidgetHostImpl::ExecuteEditCommand(const std::string& command,
   2048                                               const std::string& value) {
   2049   Send(new InputMsg_ExecuteEditCommand(GetRoutingID(), command, value));
   2050 }
   2051 
   2052 void RenderWidgetHostImpl::ScrollFocusedEditableNodeIntoRect(
   2053     const gfx::Rect& rect) {
   2054   Send(new InputMsg_ScrollFocusedEditableNodeIntoRect(GetRoutingID(), rect));
   2055 }
   2056 
   2057 void RenderWidgetHostImpl::MoveCaret(const gfx::Point& point) {
   2058   Send(new InputMsg_MoveCaret(GetRoutingID(), point));
   2059 }
   2060 
   2061 bool RenderWidgetHostImpl::GotResponseToLockMouseRequest(bool allowed) {
   2062   if (!allowed) {
   2063     RejectMouseLockOrUnlockIfNecessary();
   2064     return false;
   2065   } else {
   2066     if (!pending_mouse_lock_request_) {
   2067       // This is possible, e.g., the plugin sends us an unlock request before
   2068       // the user allows to lock to mouse.
   2069       return false;
   2070     }
   2071 
   2072     pending_mouse_lock_request_ = false;
   2073     if (!view_ || !view_->HasFocus()|| !view_->LockMouse()) {
   2074       Send(new ViewMsg_LockMouse_ACK(routing_id_, false));
   2075       return false;
   2076     } else {
   2077       Send(new ViewMsg_LockMouse_ACK(routing_id_, true));
   2078       return true;
   2079     }
   2080   }
   2081 }
   2082 
   2083 // static
   2084 void RenderWidgetHostImpl::AcknowledgeBufferPresent(
   2085     int32 route_id, int gpu_host_id,
   2086     const AcceleratedSurfaceMsg_BufferPresented_Params& params) {
   2087   GpuProcessHostUIShim* ui_shim = GpuProcessHostUIShim::FromID(gpu_host_id);
   2088   if (ui_shim) {
   2089     ui_shim->Send(new AcceleratedSurfaceMsg_BufferPresented(route_id,
   2090                                                             params));
   2091   }
   2092 }
   2093 
   2094 // static
   2095 void RenderWidgetHostImpl::SendSwapCompositorFrameAck(
   2096     int32 route_id,
   2097     uint32 output_surface_id,
   2098     int renderer_host_id,
   2099     const cc::CompositorFrameAck& ack) {
   2100   RenderProcessHost* host = RenderProcessHost::FromID(renderer_host_id);
   2101   if (!host)
   2102     return;
   2103   host->Send(new ViewMsg_SwapCompositorFrameAck(
   2104       route_id, output_surface_id, ack));
   2105 }
   2106 
   2107 // static
   2108 void RenderWidgetHostImpl::SendReclaimCompositorResources(
   2109     int32 route_id,
   2110     uint32 output_surface_id,
   2111     int renderer_host_id,
   2112     const cc::CompositorFrameAck& ack) {
   2113   RenderProcessHost* host = RenderProcessHost::FromID(renderer_host_id);
   2114   if (!host)
   2115     return;
   2116   host->Send(
   2117       new ViewMsg_ReclaimCompositorResources(route_id, output_surface_id, ack));
   2118 }
   2119 
   2120 void RenderWidgetHostImpl::DelayedAutoResized() {
   2121   gfx::Size new_size = new_auto_size_;
   2122   // Clear the new_auto_size_ since the empty value is used as a flag to
   2123   // indicate that no callback is in progress (i.e. without this line
   2124   // DelayedAutoResized will not get called again).
   2125   new_auto_size_.SetSize(0, 0);
   2126   if (!should_auto_resize_)
   2127     return;
   2128 
   2129   OnRenderAutoResized(new_size);
   2130 }
   2131 
   2132 void RenderWidgetHostImpl::DetachDelegate() {
   2133   delegate_ = NULL;
   2134 }
   2135 
   2136 void RenderWidgetHostImpl::ComputeTouchLatency(
   2137     const ui::LatencyInfo& latency_info) {
   2138   ui::LatencyInfo::LatencyComponent ui_component;
   2139   ui::LatencyInfo::LatencyComponent rwh_component;
   2140   ui::LatencyInfo::LatencyComponent acked_component;
   2141 
   2142   if (!latency_info.FindLatency(ui::INPUT_EVENT_LATENCY_UI_COMPONENT,
   2143                                 0,
   2144                                 &ui_component) ||
   2145       !latency_info.FindLatency(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
   2146                                 GetLatencyComponentId(),
   2147                                 &rwh_component))
   2148     return;
   2149 
   2150   DCHECK(ui_component.event_count == 1);
   2151   DCHECK(rwh_component.event_count == 1);
   2152 
   2153   base::TimeDelta ui_delta =
   2154       rwh_component.event_time - ui_component.event_time;
   2155   UMA_HISTOGRAM_CUSTOM_COUNTS(
   2156       "Event.Latency.Browser.TouchUI",
   2157       ui_delta.InMicroseconds(),
   2158       1,
   2159       20000,
   2160       100);
   2161 
   2162   if (latency_info.FindLatency(ui::INPUT_EVENT_LATENCY_ACKED_TOUCH_COMPONENT,
   2163                                0,
   2164                                &acked_component)) {
   2165     DCHECK(acked_component.event_count == 1);
   2166     base::TimeDelta acked_delta =
   2167         acked_component.event_time - rwh_component.event_time;
   2168     UMA_HISTOGRAM_CUSTOM_COUNTS(
   2169         "Event.Latency.Browser.TouchAcked",
   2170         acked_delta.InMicroseconds(),
   2171         1,
   2172         1000000,
   2173         100);
   2174   }
   2175 }
   2176 
   2177 void RenderWidgetHostImpl::FrameSwapped(const ui::LatencyInfo& latency_info) {
   2178   ui::LatencyInfo::LatencyComponent window_snapshot_component;
   2179   if (latency_info.FindLatency(ui::WINDOW_SNAPSHOT_FRAME_NUMBER_COMPONENT,
   2180                                GetLatencyComponentId(),
   2181                                &window_snapshot_component)) {
   2182     int sequence_number = static_cast<int>(
   2183         window_snapshot_component.sequence_number);
   2184 #if defined(OS_MACOSX)
   2185     // On Mac, when using CoreAnmation, there is a delay between when content
   2186     // is drawn to the screen, and when the snapshot will actually pick up
   2187     // that content. Insert a manual delay of 1/6th of a second (to simulate
   2188     // 10 frames at 60 fps) before actually taking the snapshot.
   2189     base::MessageLoop::current()->PostDelayedTask(
   2190         FROM_HERE,
   2191         base::Bind(&RenderWidgetHostImpl::WindowSnapshotReachedScreen,
   2192                    weak_factory_.GetWeakPtr(),
   2193                    sequence_number),
   2194         base::TimeDelta::FromSecondsD(1. / 6));
   2195 #else
   2196     WindowSnapshotReachedScreen(sequence_number);
   2197 #endif
   2198   }
   2199 
   2200   ui::LatencyInfo::LatencyComponent rwh_component;
   2201   ui::LatencyInfo::LatencyComponent swap_component;
   2202   if (!latency_info.FindLatency(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
   2203                                 GetLatencyComponentId(),
   2204                                 &rwh_component) ||
   2205       !latency_info.FindLatency(
   2206           ui::INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT,
   2207           0, &swap_component)) {
   2208     return;
   2209   }
   2210 
   2211   ui::LatencyInfo::LatencyComponent original_component;
   2212   if (latency_info.FindLatency(
   2213           ui::INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT,
   2214           GetLatencyComponentId(),
   2215           &original_component)) {
   2216     // This UMA metric tracks the time from when the original touch event is
   2217     // created (averaged if there are multiple) to when the scroll gesture
   2218     // results in final frame swap.
   2219     base::TimeDelta delta =
   2220         swap_component.event_time - original_component.event_time;
   2221     for (size_t i = 0; i < original_component.event_count; i++) {
   2222       UMA_HISTOGRAM_CUSTOM_COUNTS(
   2223           "Event.Latency.TouchToScrollUpdateSwap",
   2224           delta.InMicroseconds(),
   2225           1,
   2226           1000000,
   2227           100);
   2228     }
   2229   }
   2230 }
   2231 
   2232 void RenderWidgetHostImpl::DidReceiveRendererFrame() {
   2233   view_->DidReceiveRendererFrame();
   2234 }
   2235 
   2236 void RenderWidgetHostImpl::WindowSnapshotAsyncCallback(
   2237     int routing_id,
   2238     int snapshot_id,
   2239     gfx::Size snapshot_size,
   2240     scoped_refptr<base::RefCountedBytes> png_data) {
   2241   if (!png_data) {
   2242     std::vector<unsigned char> png_vector;
   2243     Send(new ViewMsg_WindowSnapshotCompleted(
   2244         routing_id, snapshot_id, gfx::Size(), png_vector));
   2245     return;
   2246   }
   2247 
   2248   Send(new ViewMsg_WindowSnapshotCompleted(
   2249       routing_id, snapshot_id, snapshot_size, png_data->data()));
   2250 }
   2251 
   2252 void RenderWidgetHostImpl::WindowSnapshotReachedScreen(int snapshot_id) {
   2253   DCHECK(base::MessageLoopForUI::IsCurrent());
   2254 
   2255   std::vector<unsigned char> png;
   2256 
   2257   // This feature is behind the kEnableGpuBenchmarking command line switch
   2258   // because it poses security concerns and should only be used for testing.
   2259   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
   2260   if (!command_line.HasSwitch(cc::switches::kEnableGpuBenchmarking)) {
   2261     Send(new ViewMsg_WindowSnapshotCompleted(
   2262         GetRoutingID(), snapshot_id, gfx::Size(), png));
   2263     return;
   2264   }
   2265 
   2266   gfx::Rect view_bounds = GetView()->GetViewBounds();
   2267   gfx::Rect snapshot_bounds(view_bounds.size());
   2268   gfx::Size snapshot_size = snapshot_bounds.size();
   2269 
   2270   if (ui::GrabViewSnapshot(
   2271           GetView()->GetNativeView(), &png, snapshot_bounds)) {
   2272     Send(new ViewMsg_WindowSnapshotCompleted(
   2273         GetRoutingID(), snapshot_id, snapshot_size, png));
   2274     return;
   2275   }
   2276 
   2277   ui::GrabViewSnapshotAsync(
   2278       GetView()->GetNativeView(),
   2279       snapshot_bounds,
   2280       base::ThreadTaskRunnerHandle::Get(),
   2281       base::Bind(&RenderWidgetHostImpl::WindowSnapshotAsyncCallback,
   2282                  weak_factory_.GetWeakPtr(),
   2283                  GetRoutingID(),
   2284                  snapshot_id,
   2285                  snapshot_size));
   2286 }
   2287 
   2288 // static
   2289 void RenderWidgetHostImpl::CompositorFrameDrawn(
   2290     const std::vector<ui::LatencyInfo>& latency_info) {
   2291   for (size_t i = 0; i < latency_info.size(); i++) {
   2292     std::set<RenderWidgetHostImpl*> rwhi_set;
   2293     for (ui::LatencyInfo::LatencyMap::const_iterator b =
   2294              latency_info[i].latency_components.begin();
   2295          b != latency_info[i].latency_components.end();
   2296          ++b) {
   2297       if (b->first.first == ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT ||
   2298           b->first.first == ui::WINDOW_SNAPSHOT_FRAME_NUMBER_COMPONENT) {
   2299         // Matches with GetLatencyComponentId
   2300         int routing_id = b->first.second & 0xffffffff;
   2301         int process_id = (b->first.second >> 32) & 0xffffffff;
   2302         RenderWidgetHost* rwh =
   2303             RenderWidgetHost::FromID(process_id, routing_id);
   2304         if (!rwh) {
   2305           continue;
   2306         }
   2307         RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(rwh);
   2308         if (rwhi_set.insert(rwhi).second)
   2309           rwhi->FrameSwapped(latency_info[i]);
   2310       }
   2311     }
   2312   }
   2313 }
   2314 
   2315 void RenderWidgetHostImpl::AddLatencyInfoComponentIds(
   2316     ui::LatencyInfo* latency_info) {
   2317   ui::LatencyInfo::LatencyMap new_components;
   2318   ui::LatencyInfo::LatencyMap::iterator lc =
   2319       latency_info->latency_components.begin();
   2320   while (lc != latency_info->latency_components.end()) {
   2321     ui::LatencyComponentType component_type = lc->first.first;
   2322     if (component_type == ui::WINDOW_SNAPSHOT_FRAME_NUMBER_COMPONENT) {
   2323       // Generate a new component entry with the correct component ID
   2324       ui::LatencyInfo::LatencyMap::key_type key =
   2325           std::make_pair(component_type, GetLatencyComponentId());
   2326       new_components[key] = lc->second;
   2327 
   2328       // Remove the old entry
   2329       latency_info->latency_components.erase(lc++);
   2330     } else {
   2331       ++lc;
   2332     }
   2333   }
   2334 
   2335   // Add newly generated components into the latency info
   2336   for (lc = new_components.begin(); lc != new_components.end(); ++lc) {
   2337     latency_info->latency_components[lc->first] = lc->second;
   2338   }
   2339 }
   2340 
   2341 SkBitmap::Config RenderWidgetHostImpl::PreferredReadbackFormat() {
   2342   if (view_)
   2343     return view_->PreferredReadbackFormat();
   2344   return SkBitmap::kARGB_8888_Config;
   2345 }
   2346 
   2347 }  // namespace content
   2348