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