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