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