Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / content / browser / renderer_host / render_widget_host_view_aura.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/browser/renderer_host/render_widget_host_view_aura.h"
6
7 #include "base/auto_reset.h"
8 #include "base/basictypes.h"
9 #include "base/bind.h"
10 #include "base/callback_helpers.h"
11 #include "base/command_line.h"
12 #include "base/debug/trace_event.h"
13 #include "base/logging.h"
14 #include "base/message_loop/message_loop.h"
15 #include "base/strings/string_number_conversions.h"
16 #include "cc/layers/delegated_frame_provider.h"
17 #include "cc/output/compositor_frame.h"
18 #include "cc/output/compositor_frame_ack.h"
19 #include "cc/output/copy_output_request.h"
20 #include "cc/output/copy_output_result.h"
21 #include "cc/resources/texture_mailbox.h"
22 #include "cc/trees/layer_tree_settings.h"
23 #include "content/browser/accessibility/browser_accessibility_manager.h"
24 #include "content/browser/accessibility/browser_accessibility_state_impl.h"
25 #include "content/browser/gpu/compositor_util.h"
26 #include "content/browser/renderer_host/backing_store_aura.h"
27 #include "content/browser/renderer_host/compositor_resize_lock_aura.h"
28 #include "content/browser/renderer_host/dip_util.h"
29 #include "content/browser/renderer_host/input/synthetic_gesture_target_aura.h"
30 #include "content/browser/renderer_host/overscroll_controller.h"
31 #include "content/browser/renderer_host/render_view_host_delegate.h"
32 #include "content/browser/renderer_host/render_widget_host_impl.h"
33 #include "content/browser/renderer_host/ui_events_helper.h"
34 #include "content/browser/renderer_host/web_input_event_aura.h"
35 #include "content/common/gpu/client/gl_helper.h"
36 #include "content/common/gpu/gpu_messages.h"
37 #include "content/common/view_messages.h"
38 #include "content/port/browser/render_widget_host_view_frame_subscriber.h"
39 #include "content/port/browser/render_widget_host_view_port.h"
40 #include "content/public/browser/content_browser_client.h"
41 #include "content/public/browser/render_process_host.h"
42 #include "content/public/browser/render_view_host.h"
43 #include "content/public/browser/user_metrics.h"
44 #include "content/public/common/content_switches.h"
45 #include "media/base/video_util.h"
46 #include "skia/ext/image_operations.h"
47 #include "third_party/WebKit/public/platform/WebScreenInfo.h"
48 #include "third_party/WebKit/public/web/WebCompositionUnderline.h"
49 #include "third_party/WebKit/public/web/WebInputEvent.h"
50 #include "ui/aura/client/activation_client.h"
51 #include "ui/aura/client/aura_constants.h"
52 #include "ui/aura/client/cursor_client.h"
53 #include "ui/aura/client/cursor_client_observer.h"
54 #include "ui/aura/client/focus_client.h"
55 #include "ui/aura/client/scoped_tooltip_disabler.h"
56 #include "ui/aura/client/screen_position_client.h"
57 #include "ui/aura/client/tooltip_client.h"
58 #include "ui/aura/client/transient_window_client.h"
59 #include "ui/aura/client/window_tree_client.h"
60 #include "ui/aura/env.h"
61 #include "ui/aura/root_window.h"
62 #include "ui/aura/window.h"
63 #include "ui/aura/window_observer.h"
64 #include "ui/aura/window_tracker.h"
65 #include "ui/base/clipboard/scoped_clipboard_writer.h"
66 #include "ui/base/hit_test.h"
67 #include "ui/base/ime/input_method.h"
68 #include "ui/base/ui_base_types.h"
69 #include "ui/compositor/compositor_vsync_manager.h"
70 #include "ui/compositor/layer.h"
71 #include "ui/events/event.h"
72 #include "ui/events/event_utils.h"
73 #include "ui/events/gestures/gesture_recognizer.h"
74 #include "ui/gfx/canvas.h"
75 #include "ui/gfx/display.h"
76 #include "ui/gfx/rect_conversions.h"
77 #include "ui/gfx/screen.h"
78 #include "ui/gfx/size_conversions.h"
79 #include "ui/gfx/skia_util.h"
80 #include "ui/wm/public/window_types.h"
81
82 #if defined(OS_WIN)
83 #include "content/browser/accessibility/browser_accessibility_manager_win.h"
84 #include "content/browser/accessibility/browser_accessibility_win.h"
85 #include "content/browser/renderer_host/legacy_render_widget_host_win.h"
86 #include "content/common/plugin_constants_win.h"
87 #include "ui/base/win/hidden_window.h"
88 #include "ui/gfx/gdi_util.h"
89 #include "ui/gfx/win/dpi.h"
90 #endif
91
92 using gfx::RectToSkIRect;
93 using gfx::SkIRectToRect;
94
95 using blink::WebScreenInfo;
96 using blink::WebTouchEvent;
97
98 namespace content {
99
100 namespace {
101
102 void MailboxReleaseCallback(scoped_ptr<base::SharedMemory> shared_memory,
103                             uint32 sync_point,
104                             bool lost_resource) {
105   // NOTE: shared_memory will get released when we go out of scope.
106 }
107
108 // In mouse lock mode, we need to prevent the (invisible) cursor from hitting
109 // the border of the view, in order to get valid movement information. However,
110 // forcing the cursor back to the center of the view after each mouse move
111 // doesn't work well. It reduces the frequency of useful mouse move messages
112 // significantly. Therefore, we move the cursor to the center of the view only
113 // if it approaches the border. |kMouseLockBorderPercentage| specifies the width
114 // of the border area, in percentage of the corresponding dimension.
115 const int kMouseLockBorderPercentage = 15;
116
117 // When accelerated compositing is enabled and a widget resize is pending,
118 // we delay further resizes of the UI. The following constant is the maximum
119 // length of time that we should delay further UI resizes while waiting for a
120 // resized frame from a renderer.
121 const int kResizeLockTimeoutMs = 67;
122
123 #if defined(OS_WIN)
124 // Used to associate a plugin HWND with its RenderWidgetHostViewAura instance.
125 const wchar_t kWidgetOwnerProperty[] = L"RenderWidgetHostViewAuraOwner";
126
127 BOOL CALLBACK WindowDestroyingCallback(HWND window, LPARAM param) {
128   RenderWidgetHostViewAura* widget =
129       reinterpret_cast<RenderWidgetHostViewAura*>(param);
130   if (GetProp(window, kWidgetOwnerProperty) == widget) {
131     // Properties set on HWNDs must be removed to avoid leaks.
132     RemoveProp(window, kWidgetOwnerProperty);
133     RenderWidgetHostViewBase::DetachPluginWindowsCallback(window);
134   }
135   return TRUE;
136 }
137
138 BOOL CALLBACK HideWindowsCallback(HWND window, LPARAM param) {
139   RenderWidgetHostViewAura* widget =
140       reinterpret_cast<RenderWidgetHostViewAura*>(param);
141   if (GetProp(window, kWidgetOwnerProperty) == widget)
142     SetParent(window, ui::GetHiddenWindow());
143   return TRUE;
144 }
145
146 BOOL CALLBACK ShowWindowsCallback(HWND window, LPARAM param) {
147   RenderWidgetHostViewAura* widget =
148       reinterpret_cast<RenderWidgetHostViewAura*>(param);
149
150   if (GetProp(window, kWidgetOwnerProperty) == widget &&
151       widget->GetNativeView()->GetDispatcher()) {
152     HWND parent = widget->GetNativeView()->GetDispatcher()->host()->
153         GetAcceleratedWidget();
154     SetParent(window, parent);
155   }
156   return TRUE;
157 }
158
159 struct CutoutRectsParams {
160   RenderWidgetHostViewAura* widget;
161   std::vector<gfx::Rect> cutout_rects;
162   std::map<HWND, WebPluginGeometry>* geometry;
163 };
164
165 // Used to update the region for the windowed plugin to draw in. We start with
166 // the clip rect from the renderer, then remove the cutout rects from the
167 // renderer, and then remove the transient windows from the root window and the
168 // constrained windows from the parent window.
169 BOOL CALLBACK SetCutoutRectsCallback(HWND window, LPARAM param) {
170   CutoutRectsParams* params = reinterpret_cast<CutoutRectsParams*>(param);
171
172   if (GetProp(window, kWidgetOwnerProperty) == params->widget) {
173     // First calculate the offset of this plugin from the root window, since
174     // the cutouts are relative to the root window.
175     HWND parent = params->widget->GetNativeView()->GetDispatcher()->
176         host()->GetAcceleratedWidget();
177     POINT offset;
178     offset.x = offset.y = 0;
179     MapWindowPoints(window, parent, &offset, 1);
180
181     // Now get the cached clip rect and cutouts for this plugin window that came
182     // from the renderer.
183     std::map<HWND, WebPluginGeometry>::iterator i = params->geometry->begin();
184     while (i != params->geometry->end() &&
185            i->second.window != window &&
186            GetParent(i->second.window) != window) {
187       ++i;
188     }
189
190     if (i == params->geometry->end()) {
191       NOTREACHED();
192       return TRUE;
193     }
194
195     HRGN hrgn = CreateRectRgn(i->second.clip_rect.x(),
196                               i->second.clip_rect.y(),
197                               i->second.clip_rect.right(),
198                               i->second.clip_rect.bottom());
199     // We start with the cutout rects that came from the renderer, then add the
200     // ones that came from transient and constrained windows.
201     std::vector<gfx::Rect> cutout_rects = i->second.cutout_rects;
202     for (size_t i = 0; i < params->cutout_rects.size(); ++i) {
203       gfx::Rect offset_cutout = params->cutout_rects[i];
204       offset_cutout.Offset(-offset.x, -offset.y);
205       cutout_rects.push_back(offset_cutout);
206     }
207     gfx::SubtractRectanglesFromRegion(hrgn, cutout_rects);
208     // If we don't have any cutout rects then no point in messing with the
209     // window region.
210     if (cutout_rects.size())
211       SetWindowRgn(window, hrgn, TRUE);
212   }
213   return TRUE;
214 }
215
216 // A callback function for EnumThreadWindows to enumerate and dismiss
217 // any owned popup windows.
218 BOOL CALLBACK DismissOwnedPopups(HWND window, LPARAM arg) {
219   const HWND toplevel_hwnd = reinterpret_cast<HWND>(arg);
220
221   if (::IsWindowVisible(window)) {
222     const HWND owner = ::GetWindow(window, GW_OWNER);
223     if (toplevel_hwnd == owner) {
224       ::PostMessage(window, WM_CANCELMODE, 0, 0);
225     }
226   }
227
228   return TRUE;
229 }
230 #endif
231
232 void UpdateWebTouchEventAfterDispatch(blink::WebTouchEvent* event,
233                                       blink::WebTouchPoint* point) {
234   if (point->state != blink::WebTouchPoint::StateReleased &&
235       point->state != blink::WebTouchPoint::StateCancelled)
236     return;
237   --event->touchesLength;
238   for (unsigned i = point - event->touches;
239        i < event->touchesLength;
240        ++i) {
241     event->touches[i] = event->touches[i + 1];
242   }
243 }
244
245 bool CanRendererHandleEvent(const ui::MouseEvent* event) {
246   if (event->type() == ui::ET_MOUSE_CAPTURE_CHANGED)
247     return false;
248
249 #if defined(OS_WIN)
250   // Renderer cannot handle WM_XBUTTON or NC events.
251   switch (event->native_event().message) {
252     case WM_XBUTTONDOWN:
253     case WM_XBUTTONUP:
254     case WM_XBUTTONDBLCLK:
255     case WM_NCMOUSELEAVE:
256     case WM_NCMOUSEMOVE:
257     case WM_NCLBUTTONDOWN:
258     case WM_NCLBUTTONUP:
259     case WM_NCLBUTTONDBLCLK:
260     case WM_NCRBUTTONDOWN:
261     case WM_NCRBUTTONUP:
262     case WM_NCRBUTTONDBLCLK:
263     case WM_NCMBUTTONDOWN:
264     case WM_NCMBUTTONUP:
265     case WM_NCMBUTTONDBLCLK:
266     case WM_NCXBUTTONDOWN:
267     case WM_NCXBUTTONUP:
268     case WM_NCXBUTTONDBLCLK:
269       return false;
270     default:
271       break;
272   }
273 #endif
274   return true;
275 }
276
277 // We don't mark these as handled so that they're sent back to the
278 // DefWindowProc so it can generate WM_APPCOMMAND as necessary.
279 bool IsXButtonUpEvent(const ui::MouseEvent* event) {
280 #if defined(OS_WIN)
281   switch (event->native_event().message) {
282     case WM_XBUTTONUP:
283     case WM_NCXBUTTONUP:
284       return true;
285   }
286 #endif
287   return false;
288 }
289
290 void GetScreenInfoForWindow(WebScreenInfo* results, aura::Window* window) {
291   const gfx::Display display = window ?
292       gfx::Screen::GetScreenFor(window)->GetDisplayNearestWindow(window) :
293       gfx::Screen::GetScreenFor(window)->GetPrimaryDisplay();
294   results->rect = display.bounds();
295   results->availableRect = display.work_area();
296   // TODO(derat|oshima): Don't hardcode this. Get this from display object.
297   results->depth = 24;
298   results->depthPerComponent = 8;
299   results->deviceScaleFactor = display.device_scale_factor();
300 }
301
302 bool PointerEventActivates(const ui::Event& event) {
303   if (event.type() == ui::ET_MOUSE_PRESSED)
304     return true;
305
306   if (event.type() == ui::ET_GESTURE_BEGIN) {
307     const ui::GestureEvent& gesture =
308         static_cast<const ui::GestureEvent&>(event);
309     return gesture.details().touch_points() == 1;
310   }
311
312   return false;
313 }
314
315 // Swap ack for the renderer when kCompositeToMailbox is enabled.
316 void SendCompositorFrameAck(
317     int32 route_id,
318     uint32 output_surface_id,
319     int renderer_host_id,
320     const gpu::Mailbox& received_mailbox,
321     const gfx::Size& received_size,
322     bool skip_frame,
323     const scoped_refptr<ui::Texture>& texture_to_produce) {
324   cc::CompositorFrameAck ack;
325   ack.gl_frame_data.reset(new cc::GLFrameData());
326   DCHECK(!texture_to_produce.get() || !skip_frame);
327   if (texture_to_produce.get()) {
328     GLHelper* gl_helper = ImageTransportFactory::GetInstance()->GetGLHelper();
329     ack.gl_frame_data->mailbox = texture_to_produce->Produce();
330     ack.gl_frame_data->size = texture_to_produce->size();
331     ack.gl_frame_data->sync_point =
332         gl_helper ? gl_helper->InsertSyncPoint() : 0;
333   } else if (skip_frame) {
334     // Skip the frame, i.e. tell the producer to reuse the same buffer that
335     // we just received.
336     ack.gl_frame_data->size = received_size;
337     ack.gl_frame_data->mailbox = received_mailbox;
338   }
339
340   RenderWidgetHostImpl::SendSwapCompositorFrameAck(
341       route_id, output_surface_id, renderer_host_id, ack);
342 }
343
344 void AcknowledgeBufferForGpu(
345     int32 route_id,
346     int gpu_host_id,
347     const gpu::Mailbox& received_mailbox,
348     bool skip_frame,
349     const scoped_refptr<ui::Texture>& texture_to_produce) {
350   AcceleratedSurfaceMsg_BufferPresented_Params ack;
351   uint32 sync_point = 0;
352   DCHECK(!texture_to_produce.get() || !skip_frame);
353   if (texture_to_produce.get()) {
354     GLHelper* gl_helper = ImageTransportFactory::GetInstance()->GetGLHelper();
355     ack.mailbox = texture_to_produce->Produce();
356     sync_point = gl_helper ? gl_helper->InsertSyncPoint() : 0;
357   } else if (skip_frame) {
358     ack.mailbox = received_mailbox;
359     ack.sync_point = 0;
360   }
361
362   ack.sync_point = sync_point;
363   RenderWidgetHostImpl::AcknowledgeBufferPresent(
364       route_id, gpu_host_id, ack);
365 }
366
367 }  // namespace
368
369 // We need to watch for mouse events outside a Web Popup or its parent
370 // and dismiss the popup for certain events.
371 class RenderWidgetHostViewAura::EventFilterForPopupExit
372     : public ui::EventHandler {
373  public:
374   explicit EventFilterForPopupExit(RenderWidgetHostViewAura* rwhva)
375       : rwhva_(rwhva) {
376     DCHECK(rwhva_);
377     aura::Env::GetInstance()->AddPreTargetHandler(this);
378   }
379
380   virtual ~EventFilterForPopupExit() {
381     aura::Env::GetInstance()->RemovePreTargetHandler(this);
382   }
383
384   // Overridden from ui::EventHandler
385   virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE {
386     rwhva_->ApplyEventFilterForPopupExit(event);
387   }
388
389   virtual void OnTouchEvent(ui::TouchEvent* event) OVERRIDE {
390     rwhva_->ApplyEventFilterForPopupExit(event);
391   }
392
393  private:
394   RenderWidgetHostViewAura* rwhva_;
395
396   DISALLOW_COPY_AND_ASSIGN(EventFilterForPopupExit);
397 };
398
399 void RenderWidgetHostViewAura::ApplyEventFilterForPopupExit(
400     ui::LocatedEvent* event) {
401   if (in_shutdown_ || is_fullscreen_ || !event->target())
402     return;
403
404   if (event->type() != ui::ET_MOUSE_PRESSED &&
405       event->type() != ui::ET_TOUCH_PRESSED) {
406     return;
407   }
408
409   aura::Window* target = static_cast<aura::Window*>(event->target());
410   if (target != window_ &&
411       (!popup_parent_host_view_ ||
412        target != popup_parent_host_view_->window_)) {
413     // Note: popup_parent_host_view_ may be NULL when there are multiple
414     // popup children per view. See: RenderWidgetHostViewAura::InitAsPopup().
415     in_shutdown_ = true;
416     host_->Shutdown();
417   }
418 }
419
420 // We have to implement the WindowObserver interface on a separate object
421 // because clang doesn't like implementing multiple interfaces that have
422 // methods with the same name. This object is owned by the
423 // RenderWidgetHostViewAura.
424 class RenderWidgetHostViewAura::WindowObserver : public aura::WindowObserver {
425  public:
426   explicit WindowObserver(RenderWidgetHostViewAura* view)
427       : view_(view) {
428     view_->window_->AddObserver(this);
429   }
430
431   virtual ~WindowObserver() {
432     view_->window_->RemoveObserver(this);
433   }
434
435   // Overridden from aura::WindowObserver:
436   virtual void OnWindowAddedToRootWindow(aura::Window* window) OVERRIDE {
437     if (window == view_->window_)
438       view_->AddedToRootWindow();
439   }
440
441   virtual void OnWindowRemovingFromRootWindow(aura::Window* window) OVERRIDE {
442     if (window == view_->window_)
443       view_->RemovingFromRootWindow();
444   }
445
446  private:
447   RenderWidgetHostViewAura* view_;
448
449   DISALLOW_COPY_AND_ASSIGN(WindowObserver);
450 };
451
452 ////////////////////////////////////////////////////////////////////////////////
453 // RenderWidgetHostViewAura, public:
454
455 RenderWidgetHostViewAura::RenderWidgetHostViewAura(RenderWidgetHost* host)
456     : host_(RenderWidgetHostImpl::From(host)),
457       window_(new aura::Window(this)),
458       in_shutdown_(false),
459       in_bounds_changed_(false),
460       is_fullscreen_(false),
461       popup_parent_host_view_(NULL),
462       popup_child_host_view_(NULL),
463       is_loading_(false),
464       text_input_type_(ui::TEXT_INPUT_TYPE_NONE),
465       text_input_mode_(ui::TEXT_INPUT_MODE_DEFAULT),
466       can_compose_inline_(true),
467       has_composition_text_(false),
468       accept_return_character_(false),
469       last_output_surface_id_(0),
470       pending_delegated_ack_count_(0),
471       skipped_frames_(false),
472       last_swapped_surface_scale_factor_(1.f),
473       paint_canvas_(NULL),
474       synthetic_move_sent_(false),
475       accelerated_compositing_state_changed_(false),
476       can_lock_compositor_(YES),
477       cursor_visibility_state_in_renderer_(UNKNOWN),
478       touch_editing_client_(NULL),
479       delegated_frame_evictor_(new DelegatedFrameEvictor(this)),
480       weak_ptr_factory_(this) {
481   host_->SetView(this);
482   window_observer_.reset(new WindowObserver(this));
483   aura::client::SetTooltipText(window_, &tooltip_);
484   aura::client::SetActivationDelegate(window_, this);
485   aura::client::SetActivationChangeObserver(window_, this);
486   aura::client::SetFocusChangeObserver(window_, this);
487   gfx::Screen::GetScreenFor(window_)->AddObserver(this);
488   software_frame_manager_.reset(new SoftwareFrameManager(
489       weak_ptr_factory_.GetWeakPtr()));
490   ImageTransportFactory::GetInstance()->AddObserver(this);
491 }
492
493 ////////////////////////////////////////////////////////////////////////////////
494 // RenderWidgetHostViewAura, RenderWidgetHostView implementation:
495
496 bool RenderWidgetHostViewAura::OnMessageReceived(
497     const IPC::Message& message) {
498   bool handled = true;
499   IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewAura, message)
500     // TODO(kevers): Move to RenderWidgetHostViewImpl and consolidate IPC
501     // messages for TextInput<State|Type>Changed. Corresponding code in
502     // RenderWidgetHostViewAndroid should also be moved at the same time.
503     IPC_MESSAGE_HANDLER(ViewHostMsg_TextInputStateChanged,
504                         OnTextInputStateChanged)
505     IPC_MESSAGE_UNHANDLED(handled = false)
506   IPC_END_MESSAGE_MAP()
507   return handled;
508 }
509
510 void RenderWidgetHostViewAura::InitAsChild(
511     gfx::NativeView parent_view) {
512   window_->SetType(ui::wm::WINDOW_TYPE_CONTROL);
513   window_->Init(aura::WINDOW_LAYER_TEXTURED);
514   window_->SetName("RenderWidgetHostViewAura");
515 }
516
517 void RenderWidgetHostViewAura::InitAsPopup(
518     RenderWidgetHostView* parent_host_view,
519     const gfx::Rect& bounds_in_screen) {
520   popup_parent_host_view_ =
521       static_cast<RenderWidgetHostViewAura*>(parent_host_view);
522
523   // TransientWindowClient may be NULL during tests.
524   aura::client::TransientWindowClient* transient_window_client =
525       aura::client::GetTransientWindowClient();
526   RenderWidgetHostViewAura* old_child =
527       popup_parent_host_view_->popup_child_host_view_;
528   if (old_child) {
529     // TODO(jhorwich): Allow multiple popup_child_host_view_ per view, or
530     // similar mechanism to ensure a second popup doesn't cause the first one
531     // to never get a chance to filter events. See crbug.com/160589.
532     DCHECK(old_child->popup_parent_host_view_ == popup_parent_host_view_);
533     if (transient_window_client) {
534       transient_window_client->RemoveTransientChild(
535         popup_parent_host_view_->window_, old_child->window_);
536     }
537     old_child->popup_parent_host_view_ = NULL;
538   }
539   popup_parent_host_view_->popup_child_host_view_ = this;
540   window_->SetType(ui::wm::WINDOW_TYPE_MENU);
541   window_->Init(aura::WINDOW_LAYER_TEXTURED);
542   window_->SetName("RenderWidgetHostViewAura");
543
544   aura::Window* root = popup_parent_host_view_->window_->GetRootWindow();
545   aura::client::ParentWindowWithContext(window_, root, bounds_in_screen);
546   // Setting the transient child allows for the popup to get mouse events when
547   // in a system modal dialog.
548   // This fixes crbug.com/328593.
549   if (transient_window_client) {
550     transient_window_client->AddTransientChild(
551         popup_parent_host_view_->window_, window_);
552   }
553
554   SetBounds(bounds_in_screen);
555   Show();
556 #if !defined(OS_WIN) && !defined(OS_CHROMEOS)
557   if (NeedsInputGrab())
558     window_->SetCapture();
559 #endif
560
561   event_filter_for_popup_exit_.reset(new EventFilterForPopupExit(this));
562 }
563
564 void RenderWidgetHostViewAura::InitAsFullscreen(
565     RenderWidgetHostView* reference_host_view) {
566   is_fullscreen_ = true;
567   window_->SetType(ui::wm::WINDOW_TYPE_NORMAL);
568   window_->Init(aura::WINDOW_LAYER_TEXTURED);
569   window_->SetName("RenderWidgetHostViewAura");
570   window_->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
571
572   aura::Window* parent = NULL;
573   gfx::Rect bounds;
574   if (reference_host_view) {
575     aura::Window* reference_window =
576         static_cast<RenderWidgetHostViewAura*>(reference_host_view)->window_;
577     if (reference_window) {
578       host_tracker_.reset(new aura::WindowTracker);
579       host_tracker_->Add(reference_window);
580     }
581     gfx::Display display = gfx::Screen::GetScreenFor(window_)->
582         GetDisplayNearestWindow(reference_window);
583     parent = reference_window->GetRootWindow();
584     bounds = display.bounds();
585   }
586   aura::client::ParentWindowWithContext(window_, parent, bounds);
587   Show();
588   Focus();
589 }
590
591 RenderWidgetHost* RenderWidgetHostViewAura::GetRenderWidgetHost() const {
592   return host_;
593 }
594
595 void RenderWidgetHostViewAura::WasShown() {
596   DCHECK(host_);
597   if (!host_->is_hidden())
598     return;
599   host_->WasShown();
600   software_frame_manager_->SetVisibility(true);
601   delegated_frame_evictor_->SetVisible(true);
602
603   aura::Window* root = window_->GetRootWindow();
604   if (root) {
605     aura::client::CursorClient* cursor_client =
606         aura::client::GetCursorClient(root);
607     if (cursor_client)
608       NotifyRendererOfCursorVisibilityState(cursor_client->IsCursorVisible());
609   }
610
611   if (!current_surface_.get() && host_->is_accelerated_compositing_active() &&
612       !released_front_lock_.get()) {
613     ui::Compositor* compositor = GetCompositor();
614     if (compositor)
615       released_front_lock_ = compositor->GetCompositorLock();
616   }
617
618 #if defined(OS_WIN)
619   if (legacy_render_widget_host_HWND_) {
620     // Reparent the legacy Chrome_RenderWidgetHostHWND window to the parent
621     // window before reparenting any plugins. This ensures that the plugin
622     // windows stay on top of the child Zorder in the parent and receive
623     // mouse events, etc.
624     legacy_render_widget_host_HWND_->UpdateParent(
625         GetNativeView()->GetDispatcher()->host()->GetAcceleratedWidget());
626     legacy_render_widget_host_HWND_->SetBounds(
627         window_->GetBoundsInRootWindow());
628   }
629   LPARAM lparam = reinterpret_cast<LPARAM>(this);
630   EnumChildWindows(ui::GetHiddenWindow(), ShowWindowsCallback, lparam);
631 #endif
632 }
633
634 void RenderWidgetHostViewAura::WasHidden() {
635   if (!host_ || host_->is_hidden())
636     return;
637   host_->WasHidden();
638   software_frame_manager_->SetVisibility(false);
639   delegated_frame_evictor_->SetVisible(false);
640   released_front_lock_ = NULL;
641
642 #if defined(OS_WIN)
643   constrained_rects_.clear();
644   aura::WindowEventDispatcher* dispatcher = window_->GetDispatcher();
645   if (dispatcher) {
646     HWND parent = dispatcher->host()->GetAcceleratedWidget();
647     LPARAM lparam = reinterpret_cast<LPARAM>(this);
648     EnumChildWindows(parent, HideWindowsCallback, lparam);
649     // We reparent the legacy Chrome_RenderWidgetHostHWND window to the global
650     // hidden window on the same lines as Windowed plugin windows.
651     if (legacy_render_widget_host_HWND_)
652       legacy_render_widget_host_HWND_->UpdateParent(ui::GetHiddenWindow());
653   }
654 #endif
655 }
656
657 void RenderWidgetHostViewAura::SetSize(const gfx::Size& size) {
658   // For a SetSize operation, we don't care what coordinate system the origin
659   // of the window is in, it's only important to make sure that the origin
660   // remains constant after the operation.
661   InternalSetBounds(gfx::Rect(window_->bounds().origin(), size));
662 }
663
664 void RenderWidgetHostViewAura::SetBounds(const gfx::Rect& rect) {
665   gfx::Point relative_origin(rect.origin());
666
667   // RenderWidgetHostViewAura::SetBounds() takes screen coordinates, but
668   // Window::SetBounds() takes parent coordinates, so do the conversion here.
669   aura::Window* root = window_->GetRootWindow();
670   if (root) {
671     aura::client::ScreenPositionClient* screen_position_client =
672         aura::client::GetScreenPositionClient(root);
673     if (screen_position_client) {
674       screen_position_client->ConvertPointFromScreen(
675           window_->parent(), &relative_origin);
676     }
677   }
678
679   InternalSetBounds(gfx::Rect(relative_origin, rect.size()));
680 }
681
682 void RenderWidgetHostViewAura::MaybeCreateResizeLock() {
683   if (!ShouldCreateResizeLock())
684     return;
685   DCHECK(window_->GetDispatcher());
686   DCHECK(window_->GetDispatcher()->host()->compositor());
687
688   // Listen to changes in the compositor lock state.
689   ui::Compositor* compositor = window_->GetDispatcher()->host()->compositor();
690   if (!compositor->HasObserver(this))
691     compositor->AddObserver(this);
692
693   bool defer_compositor_lock =
694       can_lock_compositor_ == NO_PENDING_RENDERER_FRAME ||
695       can_lock_compositor_ == NO_PENDING_COMMIT;
696
697   if (can_lock_compositor_ == YES)
698     can_lock_compositor_ = YES_DID_LOCK;
699
700   resize_lock_ = CreateResizeLock(defer_compositor_lock);
701 }
702
703 bool RenderWidgetHostViewAura::ShouldCreateResizeLock() {
704   // On Windows while resizing, the the resize locks makes us mis-paint a white
705   // vertical strip (including the non-client area) if the content composition
706   // is lagging the UI composition. So here we disable the throttling so that
707   // the UI bits can draw ahead of the content thereby reducing the amount of
708   // whiteout. Because this causes the content to be drawn at wrong sizes while
709   // resizing we compensate by blocking the UI thread in Compositor::Draw() by
710   // issuing a FinishAllRendering() if we are resizing.
711 #if defined (OS_WIN)
712   return false;
713 #endif
714
715   if (resize_lock_)
716     return false;
717
718   if (host_->should_auto_resize())
719     return false;
720   if (!host_->is_accelerated_compositing_active())
721     return false;
722
723   gfx::Size desired_size = window_->bounds().size();
724   if (desired_size == current_frame_size_)
725     return false;
726
727   aura::WindowEventDispatcher* dispatcher = window_->GetDispatcher();
728   if (!dispatcher)
729     return false;
730
731   ui::Compositor* compositor = dispatcher->host()->compositor();
732   if (!compositor)
733     return false;
734
735   return true;
736 }
737
738 scoped_ptr<ResizeLock> RenderWidgetHostViewAura::CreateResizeLock(
739     bool defer_compositor_lock) {
740   gfx::Size desired_size = window_->bounds().size();
741   return scoped_ptr<ResizeLock>(new CompositorResizeLock(
742       window_->GetDispatcher(),
743       desired_size,
744       defer_compositor_lock,
745       base::TimeDelta::FromMilliseconds(kResizeLockTimeoutMs)));
746 }
747
748 void RenderWidgetHostViewAura::RequestCopyOfOutput(
749     scoped_ptr<cc::CopyOutputRequest> request) {
750   window_->layer()->RequestCopyOfOutput(request.Pass());
751 }
752
753 gfx::NativeView RenderWidgetHostViewAura::GetNativeView() const {
754   return window_;
755 }
756
757 gfx::NativeViewId RenderWidgetHostViewAura::GetNativeViewId() const {
758 #if defined(OS_WIN)
759   aura::WindowEventDispatcher* dispatcher = window_->GetDispatcher();
760   if (dispatcher)
761     return reinterpret_cast<gfx::NativeViewId>(
762         dispatcher->host()->GetAcceleratedWidget());
763 #endif
764   return static_cast<gfx::NativeViewId>(NULL);
765 }
766
767 gfx::NativeViewAccessible RenderWidgetHostViewAura::GetNativeViewAccessible() {
768 #if defined(OS_WIN)
769   aura::WindowEventDispatcher* dispatcher = window_->GetDispatcher();
770   if (!dispatcher)
771     return static_cast<gfx::NativeViewAccessible>(NULL);
772   HWND hwnd = dispatcher->host()->GetAcceleratedWidget();
773
774   CreateBrowserAccessibilityManagerIfNeeded();
775   BrowserAccessibilityManager* manager = GetBrowserAccessibilityManager();
776   if (manager)
777     return manager->GetRoot()->ToBrowserAccessibilityWin();
778 #endif
779
780   NOTIMPLEMENTED();
781   return static_cast<gfx::NativeViewAccessible>(NULL);
782 }
783
784 void RenderWidgetHostViewAura::SetKeyboardFocus() {
785 #if defined(OS_WIN)
786   if (CanFocus()) {
787     aura::WindowEventDispatcher* dispatcher = window_->GetDispatcher();
788     if (dispatcher)
789       ::SetFocus(dispatcher->host()->GetAcceleratedWidget());
790   }
791 #endif
792 }
793
794 void RenderWidgetHostViewAura::MovePluginWindows(
795     const gfx::Vector2d& scroll_offset,
796     const std::vector<WebPluginGeometry>& plugin_window_moves) {
797 #if defined(OS_WIN)
798   // We need to clip the rectangle to the tab's viewport, otherwise we will draw
799   // over the browser UI.
800   if (!window_->GetRootWindow()) {
801     DCHECK(plugin_window_moves.empty());
802     return;
803   }
804   HWND parent = window_->GetDispatcher()->host()->GetAcceleratedWidget();
805   gfx::Rect view_bounds = window_->GetBoundsInRootWindow();
806   std::vector<WebPluginGeometry> moves = plugin_window_moves;
807
808   gfx::Rect view_port(scroll_offset.x(), scroll_offset.y(), view_bounds.width(),
809                       view_bounds.height());
810
811   for (size_t i = 0; i < moves.size(); ++i) {
812     gfx::Rect clip(moves[i].clip_rect);
813     gfx::Vector2d view_port_offset(
814         moves[i].window_rect.OffsetFromOrigin() + scroll_offset);
815     clip.Offset(view_port_offset);
816     clip.Intersect(view_port);
817     clip.Offset(-view_port_offset);
818     moves[i].clip_rect = clip;
819
820     moves[i].window_rect.Offset(view_bounds.OffsetFromOrigin());
821
822     plugin_window_moves_[moves[i].window] = moves[i];
823
824     // constrained_rects_ are relative to the root window. We want to convert
825     // them to be relative to the plugin window.
826     for (size_t j = 0; j < constrained_rects_.size(); ++j) {
827       gfx::Rect offset_cutout = constrained_rects_[j];
828       offset_cutout -= moves[i].window_rect.OffsetFromOrigin();
829       moves[i].cutout_rects.push_back(offset_cutout);
830     }
831   }
832
833   MovePluginWindowsHelper(parent, moves);
834
835   // Make sure each plugin window (or its wrapper if it exists) has a pointer to
836   // |this|.
837   for (size_t i = 0; i < moves.size(); ++i) {
838     HWND window = moves[i].window;
839     if (GetParent(window) != parent) {
840       window = GetParent(window);
841     }
842     if (!GetProp(window, kWidgetOwnerProperty))
843       SetProp(window, kWidgetOwnerProperty, this);
844   }
845 #endif  // defined(OS_WIN)
846 }
847
848 void RenderWidgetHostViewAura::Focus() {
849   // Make sure we have a FocusClient before attempting to Focus(). In some
850   // situations we may not yet be in a valid Window hierarchy (such as reloading
851   // after out of memory discarded the tab).
852   aura::client::FocusClient* client = aura::client::GetFocusClient(window_);
853   if (client)
854     window_->Focus();
855 }
856
857 void RenderWidgetHostViewAura::Blur() {
858   window_->Blur();
859 }
860
861 bool RenderWidgetHostViewAura::HasFocus() const {
862   return window_->HasFocus();
863 }
864
865 bool RenderWidgetHostViewAura::IsSurfaceAvailableForCopy() const {
866   return CanCopyToBitmap() || !!host_->GetBackingStore(false);
867 }
868
869 void RenderWidgetHostViewAura::Show() {
870   window_->Show();
871   WasShown();
872 #if defined(OS_WIN)
873   if (legacy_render_widget_host_HWND_)
874     legacy_render_widget_host_HWND_->Show();
875 #endif
876 }
877
878 void RenderWidgetHostViewAura::Hide() {
879   window_->Hide();
880   WasHidden();
881 #if defined(OS_WIN)
882   if (legacy_render_widget_host_HWND_)
883     legacy_render_widget_host_HWND_->Hide();
884 #endif
885 }
886
887 bool RenderWidgetHostViewAura::IsShowing() {
888   return window_->IsVisible();
889 }
890
891 gfx::Rect RenderWidgetHostViewAura::GetViewBounds() const {
892   // This is the size that we want the renderer to produce. While we're waiting
893   // for the correct frame (i.e. during a resize), don't change the size so that
894   // we don't pipeline more resizes than we can handle.
895   gfx::Rect bounds(window_->GetBoundsInScreen());
896   if (resize_lock_.get())
897     return gfx::Rect(bounds.origin(), resize_lock_->expected_size());
898   else
899     return bounds;
900 }
901
902 void RenderWidgetHostViewAura::SetBackground(const SkBitmap& background) {
903   RenderWidgetHostViewBase::SetBackground(background);
904   host_->SetBackground(background);
905   window_->layer()->SetFillsBoundsOpaquely(background.isOpaque());
906 }
907
908 void RenderWidgetHostViewAura::UpdateCursor(const WebCursor& cursor) {
909   current_cursor_ = cursor;
910   const gfx::Display display = gfx::Screen::GetScreenFor(window_)->
911       GetDisplayNearestWindow(window_);
912   current_cursor_.SetDisplayInfo(display);
913   UpdateCursorIfOverSelf();
914 }
915
916 void RenderWidgetHostViewAura::SetIsLoading(bool is_loading) {
917   is_loading_ = is_loading;
918   UpdateCursorIfOverSelf();
919 }
920
921 void RenderWidgetHostViewAura::TextInputTypeChanged(
922     ui::TextInputType type,
923     ui::TextInputMode input_mode,
924     bool can_compose_inline) {
925   if (text_input_type_ != type ||
926       text_input_mode_ != input_mode ||
927       can_compose_inline_ != can_compose_inline) {
928     text_input_type_ = type;
929     text_input_mode_ = input_mode;
930     can_compose_inline_ = can_compose_inline;
931     if (GetInputMethod())
932       GetInputMethod()->OnTextInputTypeChanged(this);
933     if (touch_editing_client_)
934       touch_editing_client_->OnTextInputTypeChanged(text_input_type_);
935   }
936 }
937
938 void RenderWidgetHostViewAura::OnTextInputStateChanged(
939     const ViewHostMsg_TextInputState_Params& params) {
940   if (params.show_ime_if_needed && params.type != ui::TEXT_INPUT_TYPE_NONE) {
941     if (GetInputMethod())
942       GetInputMethod()->ShowImeIfNeeded();
943   }
944 }
945
946 void RenderWidgetHostViewAura::ImeCancelComposition() {
947   if (GetInputMethod())
948     GetInputMethod()->CancelComposition(this);
949   has_composition_text_ = false;
950 }
951
952 void RenderWidgetHostViewAura::ImeCompositionRangeChanged(
953     const gfx::Range& range,
954     const std::vector<gfx::Rect>& character_bounds) {
955   composition_character_bounds_ = character_bounds;
956 }
957
958 void RenderWidgetHostViewAura::DidUpdateBackingStore(
959     const gfx::Rect& scroll_rect,
960     const gfx::Vector2d& scroll_delta,
961     const std::vector<gfx::Rect>& copy_rects,
962     const std::vector<ui::LatencyInfo>& latency_info) {
963   if (accelerated_compositing_state_changed_)
964     UpdateExternalTexture();
965
966   for (size_t i = 0; i < latency_info.size(); i++)
967     software_latency_info_.push_back(latency_info[i]);
968
969   // Use the state of the RenderWidgetHost and not the window as the two may
970   // differ. In particular if the window is hidden but the renderer isn't and we
971   // ignore the update and the window is made visible again the layer isn't
972   // marked as dirty and we show the wrong thing.
973   // We do this after UpdateExternalTexture() so that when we become visible
974   // we're not drawing a stale texture.
975   if (host_->is_hidden())
976     return;
977
978   gfx::Rect clip_rect;
979   if (paint_canvas_) {
980     SkRect sk_clip_rect;
981     if (paint_canvas_->sk_canvas()->getClipBounds(&sk_clip_rect))
982       clip_rect = gfx::ToEnclosingRect(gfx::SkRectToRectF(sk_clip_rect));
983   }
984
985   if (!scroll_rect.IsEmpty())
986     SchedulePaintIfNotInClip(scroll_rect, clip_rect);
987
988 #if defined(OS_WIN)
989   aura::WindowEventDispatcher* dispatcher = window_->GetDispatcher();
990 #endif
991   for (size_t i = 0; i < copy_rects.size(); ++i) {
992     gfx::Rect rect = gfx::SubtractRects(copy_rects[i], scroll_rect);
993     if (rect.IsEmpty())
994       continue;
995
996     SchedulePaintIfNotInClip(rect, clip_rect);
997
998 #if defined(OS_WIN)
999     if (dispatcher) {
1000       // Send the invalid rect in screen coordinates.
1001       gfx::Rect screen_rect = GetViewBounds();
1002       gfx::Rect invalid_screen_rect(rect);
1003       invalid_screen_rect.Offset(screen_rect.x(), screen_rect.y());
1004       HWND hwnd = dispatcher->host()->GetAcceleratedWidget();
1005       PaintPluginWindowsHelper(hwnd, invalid_screen_rect);
1006     }
1007 #endif  // defined(OS_WIN)
1008   }
1009 }
1010
1011 void RenderWidgetHostViewAura::RenderProcessGone(base::TerminationStatus status,
1012                                                  int error_code) {
1013   UpdateCursorIfOverSelf();
1014   Destroy();
1015 }
1016
1017 void RenderWidgetHostViewAura::Destroy() {
1018   // Beware, this function is not called on all destruction paths. It will
1019   // implicitly end up calling ~RenderWidgetHostViewAura though, so all
1020   // destruction/cleanup code should happen there, not here.
1021   in_shutdown_ = true;
1022   delete window_;
1023 }
1024
1025 void RenderWidgetHostViewAura::SetTooltipText(
1026     const base::string16& tooltip_text) {
1027   tooltip_ = tooltip_text;
1028   aura::Window* root_window = window_->GetRootWindow();
1029   aura::client::TooltipClient* tooltip_client =
1030       aura::client::GetTooltipClient(root_window);
1031   if (tooltip_client) {
1032     tooltip_client->UpdateTooltip(window_);
1033     // Content tooltips should be visible indefinitely.
1034     tooltip_client->SetTooltipShownTimeout(window_, 0);
1035   }
1036 }
1037
1038 void RenderWidgetHostViewAura::SelectionChanged(const base::string16& text,
1039                                                 size_t offset,
1040                                                 const gfx::Range& range) {
1041   RenderWidgetHostViewBase::SelectionChanged(text, offset, range);
1042
1043 #if defined(USE_X11) && !defined(OS_CHROMEOS)
1044   if (text.empty() || range.is_empty())
1045     return;
1046
1047   // Set the CLIPBOARD_TYPE_SELECTION to the ui::Clipboard.
1048   ui::ScopedClipboardWriter clipboard_writer(
1049       ui::Clipboard::GetForCurrentThread(),
1050       ui::CLIPBOARD_TYPE_SELECTION);
1051   clipboard_writer.WriteText(text);
1052 #endif  // defined(USE_X11) && !defined(OS_CHROMEOS)
1053 }
1054
1055 void RenderWidgetHostViewAura::SelectionBoundsChanged(
1056     const ViewHostMsg_SelectionBounds_Params& params) {
1057   if (selection_anchor_rect_ == params.anchor_rect &&
1058       selection_focus_rect_ == params.focus_rect)
1059     return;
1060
1061   selection_anchor_rect_ = params.anchor_rect;
1062   selection_focus_rect_ = params.focus_rect;
1063
1064   if (GetInputMethod())
1065     GetInputMethod()->OnCaretBoundsChanged(this);
1066
1067   if (touch_editing_client_) {
1068     touch_editing_client_->OnSelectionOrCursorChanged(selection_anchor_rect_,
1069         selection_focus_rect_);
1070   }
1071 }
1072
1073 void RenderWidgetHostViewAura::ScrollOffsetChanged() {
1074   aura::Window* root = window_->GetRootWindow();
1075   if (!root)
1076     return;
1077   aura::client::CursorClient* cursor_client =
1078       aura::client::GetCursorClient(root);
1079   if (cursor_client && !cursor_client->IsCursorVisible())
1080     cursor_client->DisableMouseEvents();
1081 }
1082
1083 BackingStore* RenderWidgetHostViewAura::AllocBackingStore(
1084     const gfx::Size& size) {
1085   return new BackingStoreAura(host_, size);
1086 }
1087
1088 void RenderWidgetHostViewAura::CopyFromCompositingSurface(
1089     const gfx::Rect& src_subrect,
1090     const gfx::Size& dst_size,
1091     const base::Callback<void(bool, const SkBitmap&)>& callback,
1092     const SkBitmap::Config config) {
1093   // Only ARGB888 and RGB565 supported as of now.
1094   bool format_support = ((config == SkBitmap::kRGB_565_Config) ||
1095                          (config == SkBitmap::kARGB_8888_Config));
1096   if (!format_support) {
1097     DCHECK(format_support);
1098     callback.Run(false, SkBitmap());
1099     return;
1100   }
1101   if (!CanCopyToBitmap()) {
1102     callback.Run(false, SkBitmap());
1103     return;
1104   }
1105
1106   const gfx::Size& dst_size_in_pixel = ConvertViewSizeToPixel(this, dst_size);
1107   scoped_ptr<cc::CopyOutputRequest> request =
1108       cc::CopyOutputRequest::CreateRequest(base::Bind(
1109           &RenderWidgetHostViewAura::CopyFromCompositingSurfaceHasResult,
1110           dst_size_in_pixel,
1111           config,
1112           callback));
1113   gfx::Rect src_subrect_in_pixel =
1114       ConvertRectToPixel(current_device_scale_factor_, src_subrect);
1115   request->set_area(src_subrect_in_pixel);
1116   RequestCopyOfOutput(request.Pass());
1117 }
1118
1119 void RenderWidgetHostViewAura::CopyFromCompositingSurfaceToVideoFrame(
1120       const gfx::Rect& src_subrect,
1121       const scoped_refptr<media::VideoFrame>& target,
1122       const base::Callback<void(bool)>& callback) {
1123   if (!CanCopyToVideoFrame()) {
1124     callback.Run(false);
1125     return;
1126   }
1127
1128   // Try get a texture to reuse.
1129   scoped_refptr<OwnedMailbox> subscriber_texture;
1130   if (frame_subscriber_) {
1131     if (!idle_frame_subscriber_textures_.empty()) {
1132       subscriber_texture = idle_frame_subscriber_textures_.back();
1133       idle_frame_subscriber_textures_.pop_back();
1134     } else if (GLHelper* helper =
1135                    ImageTransportFactory::GetInstance()->GetGLHelper()) {
1136       subscriber_texture = new OwnedMailbox(helper);
1137     }
1138     if (subscriber_texture.get())
1139       active_frame_subscriber_textures_.insert(subscriber_texture.get());
1140   }
1141
1142   scoped_ptr<cc::CopyOutputRequest> request =
1143       cc::CopyOutputRequest::CreateRequest(base::Bind(
1144           &RenderWidgetHostViewAura::
1145                CopyFromCompositingSurfaceHasResultForVideo,
1146           AsWeakPtr(),  // For caching the ReadbackYUVInterface on this class.
1147           subscriber_texture,
1148           target,
1149           callback));
1150   gfx::Rect src_subrect_in_pixel =
1151       ConvertRectToPixel(current_device_scale_factor_, src_subrect);
1152   request->set_area(src_subrect_in_pixel);
1153   if (subscriber_texture.get()) {
1154     request->SetTextureMailbox(
1155         cc::TextureMailbox(subscriber_texture->mailbox(),
1156                            subscriber_texture->target(),
1157                            subscriber_texture->sync_point()));
1158   }
1159   RequestCopyOfOutput(request.Pass());
1160 }
1161
1162 bool RenderWidgetHostViewAura::CanCopyToBitmap() const {
1163   return GetCompositor() && window_->layer()->has_external_content();
1164 }
1165
1166 bool RenderWidgetHostViewAura::CanCopyToVideoFrame() const {
1167   return GetCompositor() &&
1168          window_->layer()->has_external_content() &&
1169          host_->is_accelerated_compositing_active();
1170 }
1171
1172 bool RenderWidgetHostViewAura::CanSubscribeFrame() const {
1173   return true;
1174 }
1175
1176 void RenderWidgetHostViewAura::BeginFrameSubscription(
1177     scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber) {
1178   frame_subscriber_ = subscriber.Pass();
1179 }
1180
1181 void RenderWidgetHostViewAura::EndFrameSubscription() {
1182   idle_frame_subscriber_textures_.clear();
1183   frame_subscriber_.reset();
1184 }
1185
1186 void RenderWidgetHostViewAura::OnAcceleratedCompositingStateChange() {
1187   // Delay processing the state change until we either get a software frame if
1188   // switching to software mode or receive a buffers swapped notification
1189   // if switching to accelerated mode.
1190   // Sometimes (e.g. on a page load) the renderer will spuriously disable then
1191   // re-enable accelerated compositing, causing us to flash.
1192   // TODO(piman): factor the enable/disable accelerated compositing message into
1193   // the UpdateRect/AcceleratedSurfaceBuffersSwapped messages so that we have
1194   // fewer inconsistent temporary states.
1195   accelerated_compositing_state_changed_ = true;
1196 }
1197
1198 void RenderWidgetHostViewAura::AcceleratedSurfaceInitialized(int host_id,
1199                                                              int route_id) {
1200 }
1201
1202 bool RenderWidgetHostViewAura::ShouldSkipFrame(gfx::Size size_in_dip) const {
1203   if (can_lock_compositor_ == NO_PENDING_RENDERER_FRAME ||
1204       can_lock_compositor_ == NO_PENDING_COMMIT ||
1205       !resize_lock_.get())
1206     return false;
1207
1208   return size_in_dip != resize_lock_->expected_size();
1209 }
1210
1211 void RenderWidgetHostViewAura::InternalSetBounds(const gfx::Rect& rect) {
1212   if (HasDisplayPropertyChanged(window_))
1213     host_->InvalidateScreenInfo();
1214
1215   // Don't recursively call SetBounds if this bounds update is the result of
1216   // a Window::SetBoundsInternal call.
1217   if (!in_bounds_changed_)
1218     window_->SetBounds(rect);
1219   host_->WasResized();
1220   MaybeCreateResizeLock();
1221   if (touch_editing_client_) {
1222     touch_editing_client_->OnSelectionOrCursorChanged(selection_anchor_rect_,
1223       selection_focus_rect_);
1224   }
1225 #if defined(OS_WIN)
1226   // Create the legacy dummy window which corresponds to the bounds of the
1227   // webcontents. This will be passed as the container window for windowless
1228   // plugins.
1229   // Plugins like Flash assume the container window which is returned via the
1230   // NPNVnetscapeWindow property corresponds to the bounds of the webpage.
1231   // This is not true in Aura where we have only HWND which is the main Aura
1232   // window. If we return this window to plugins like Flash then it causes the
1233   // coordinate translations done by these plugins to break.
1234   // Additonally the legacy dummy window is needed for accessibility and for
1235   // scrolling to work in legacy drivers for trackpoints/trackpads, etc.
1236   if (GetNativeViewId()) {
1237     if (!legacy_render_widget_host_HWND_) {
1238       legacy_render_widget_host_HWND_ = LegacyRenderWidgetHostHWND::Create(
1239           reinterpret_cast<HWND>(GetNativeViewId()));
1240     }
1241     if (legacy_render_widget_host_HWND_) {
1242       legacy_render_widget_host_HWND_->SetBounds(
1243           window_->GetBoundsInRootWindow());
1244     }
1245   }
1246 #endif
1247 }
1248
1249 void RenderWidgetHostViewAura::CheckResizeLock() {
1250   if (!resize_lock_ || resize_lock_->expected_size() != current_frame_size_)
1251     return;
1252
1253   // Since we got the size we were looking for, unlock the compositor. But delay
1254   // the release of the lock until we've kicked a frame with the new texture, to
1255   // avoid resizing the UI before we have a chance to draw a "good" frame.
1256   resize_lock_->UnlockCompositor();
1257   ui::Compositor* compositor = GetCompositor();
1258   if (compositor) {
1259     if (!compositor->HasObserver(this))
1260       compositor->AddObserver(this);
1261   }
1262 }
1263
1264 void RenderWidgetHostViewAura::UpdateExternalTexture() {
1265   // Delay processing accelerated compositing state change till here where we
1266   // act upon the state change. (Clear the external texture if switching to
1267   // software mode or set the external texture if going to accelerated mode).
1268   if (accelerated_compositing_state_changed_)
1269     accelerated_compositing_state_changed_ = false;
1270
1271   bool is_compositing_active = host_->is_accelerated_compositing_active();
1272   if (is_compositing_active && current_surface_.get()) {
1273     window_->layer()->SetExternalTexture(current_surface_.get());
1274     current_frame_size_ = ConvertSizeToDIP(
1275         current_surface_->device_scale_factor(), current_surface_->size());
1276     CheckResizeLock();
1277     software_frame_manager_->DiscardCurrentFrame();
1278   } else if (is_compositing_active &&
1279              software_frame_manager_->HasCurrentFrame()) {
1280     cc::TextureMailbox mailbox;
1281     scoped_ptr<cc::SingleReleaseCallback> callback;
1282     software_frame_manager_->GetCurrentFrameMailbox(&mailbox, &callback);
1283     window_->layer()->SetTextureMailbox(mailbox,
1284                                         callback.Pass(),
1285                                         last_swapped_surface_scale_factor_);
1286     current_frame_size_ = ConvertSizeToDIP(last_swapped_surface_scale_factor_,
1287                                            mailbox.shared_memory_size());
1288     CheckResizeLock();
1289   } else {
1290     window_->layer()->SetShowPaintedContent();
1291     resize_lock_.reset();
1292     host_->WasResized();
1293     software_frame_manager_->DiscardCurrentFrame();
1294   }
1295 }
1296
1297 bool RenderWidgetHostViewAura::SwapBuffersPrepare(
1298     const gfx::Rect& surface_rect,
1299     float surface_scale_factor,
1300     const gfx::Rect& damage_rect,
1301     const gpu::Mailbox& mailbox,
1302     const BufferPresentedCallback& ack_callback) {
1303   if (last_swapped_surface_size_ != surface_rect.size()) {
1304     // The surface could have shrunk since we skipped an update, in which
1305     // case we can expect a full update.
1306     DLOG_IF(ERROR, damage_rect != surface_rect) << "Expected full damage rect";
1307     skipped_damage_.setEmpty();
1308     last_swapped_surface_size_ = surface_rect.size();
1309     last_swapped_surface_scale_factor_ = surface_scale_factor;
1310   }
1311
1312   if (ShouldSkipFrame(ConvertSizeToDIP(surface_scale_factor,
1313                                        surface_rect.size())) ||
1314       mailbox.IsZero()) {
1315     skipped_damage_.op(RectToSkIRect(damage_rect), SkRegion::kUnion_Op);
1316     ack_callback.Run(true, scoped_refptr<ui::Texture>());
1317     return false;
1318   }
1319
1320   ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
1321   current_surface_ =
1322       factory->CreateTransportClient(surface_scale_factor);
1323   if (!current_surface_.get()) {
1324     LOG(ERROR) << "Failed to create ImageTransport texture";
1325     ack_callback.Run(true, scoped_refptr<ui::Texture>());
1326     return false;
1327   }
1328
1329   current_surface_->Consume(mailbox, surface_rect.size());
1330   released_front_lock_ = NULL;
1331   UpdateExternalTexture();
1332
1333   return true;
1334 }
1335
1336 void RenderWidgetHostViewAura::SwapBuffersCompleted(
1337     const BufferPresentedCallback& ack_callback,
1338     const scoped_refptr<ui::Texture>& texture_to_return) {
1339   ui::Compositor* compositor = GetCompositor();
1340   if (!compositor) {
1341     ack_callback.Run(false, texture_to_return);
1342   } else {
1343     AddOnCommitCallbackAndDisableLocks(
1344         base::Bind(ack_callback, false, texture_to_return));
1345   }
1346
1347   DidReceiveFrameFromRenderer();
1348 }
1349
1350 void RenderWidgetHostViewAura::DidReceiveFrameFromRenderer() {
1351   if (frame_subscriber() && CanCopyToVideoFrame()) {
1352     const base::TimeTicks present_time = base::TimeTicks::Now();
1353     scoped_refptr<media::VideoFrame> frame;
1354     RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback callback;
1355     if (frame_subscriber()->ShouldCaptureFrame(present_time,
1356                                                &frame, &callback)) {
1357       CopyFromCompositingSurfaceToVideoFrame(
1358           gfx::Rect(current_frame_size_),
1359           frame,
1360           base::Bind(callback, present_time));
1361     }
1362   }
1363 }
1364
1365 #if defined(OS_WIN)
1366 void RenderWidgetHostViewAura::UpdateConstrainedWindowRects(
1367     const std::vector<gfx::Rect>& rects) {
1368   // Check this before setting constrained_rects_, so that next time they're set
1369   // and we have a root window we don't early return.
1370   if (!window_->GetDispatcher())
1371     return;
1372
1373   if (rects == constrained_rects_)
1374     return;
1375
1376   constrained_rects_ = rects;
1377
1378   HWND parent = window_->GetDispatcher()->host()->GetAcceleratedWidget();
1379   CutoutRectsParams params;
1380   params.widget = this;
1381   params.cutout_rects = constrained_rects_;
1382   params.geometry = &plugin_window_moves_;
1383   LPARAM lparam = reinterpret_cast<LPARAM>(&params);
1384   EnumChildWindows(parent, SetCutoutRectsCallback, lparam);
1385 }
1386 #endif
1387
1388 void RenderWidgetHostViewAura::AcceleratedSurfaceBuffersSwapped(
1389     const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params_in_pixel,
1390     int gpu_host_id) {
1391   BufferPresentedCallback ack_callback = base::Bind(
1392       &AcknowledgeBufferForGpu,
1393       params_in_pixel.route_id,
1394       gpu_host_id,
1395       params_in_pixel.mailbox);
1396   BuffersSwapped(params_in_pixel.size,
1397                  gfx::Rect(params_in_pixel.size),
1398                  params_in_pixel.scale_factor,
1399                  params_in_pixel.mailbox,
1400                  params_in_pixel.latency_info,
1401                  ack_callback);
1402 }
1403
1404 void RenderWidgetHostViewAura::SwapDelegatedFrame(
1405     uint32 output_surface_id,
1406     scoped_ptr<cc::DelegatedFrameData> frame_data,
1407     float frame_device_scale_factor,
1408     const std::vector<ui::LatencyInfo>& latency_info) {
1409   DCHECK_NE(0u, frame_data->render_pass_list.size());
1410
1411   cc::RenderPass* root_pass = frame_data->render_pass_list.back();
1412
1413   gfx::Size frame_size = root_pass->output_rect.size();
1414   gfx::Size frame_size_in_dip =
1415       ConvertSizeToDIP(frame_device_scale_factor, frame_size);
1416
1417   gfx::Rect damage_rect = gfx::ToEnclosingRect(root_pass->damage_rect);
1418   damage_rect.Intersect(gfx::Rect(frame_size));
1419   gfx::Rect damage_rect_in_dip =
1420       ConvertRectToDIP(frame_device_scale_factor, damage_rect);
1421
1422   software_frame_manager_->DiscardCurrentFrame();
1423
1424   if (ShouldSkipFrame(frame_size_in_dip)) {
1425     cc::CompositorFrameAck ack;
1426     cc::TransferableResource::ReturnResources(frame_data->resource_list,
1427                                               &ack.resources);
1428     RenderWidgetHostImpl::SendSwapCompositorFrameAck(
1429         host_->GetRoutingID(), output_surface_id,
1430         host_->GetProcess()->GetID(), ack);
1431     skipped_frames_ = true;
1432     return;
1433   }
1434
1435   if (skipped_frames_) {
1436     skipped_frames_ = false;
1437     damage_rect = gfx::Rect(frame_size);
1438     damage_rect_in_dip = gfx::Rect(frame_size_in_dip);
1439
1440     // Give the same damage rect to the compositor.
1441     cc::RenderPass* root_pass = frame_data->render_pass_list.back();
1442     root_pass->damage_rect = damage_rect;
1443   }
1444
1445   if (output_surface_id != last_output_surface_id_) {
1446     // Resource ids are scoped by the output surface.
1447     // If the originating output surface doesn't match the last one, it
1448     // indicates the renderer's output surface may have been recreated, in which
1449     // case we should recreate the DelegatedRendererLayer, to avoid matching
1450     // resources from the old one with resources from the new one which would
1451     // have the same id. Changing the layer to showing painted content destroys
1452     // the DelegatedRendererLayer.
1453     EvictDelegatedFrame();
1454
1455     // Drop the cc::DelegatedFrameResourceCollection so that we will not return
1456     // any resources from the old output surface with the new output surface id.
1457     if (resource_collection_.get()) {
1458       resource_collection_->SetClient(NULL);
1459
1460       if (resource_collection_->LoseAllResources())
1461         SendReturnedDelegatedResources(last_output_surface_id_);
1462
1463       resource_collection_ = NULL;
1464     }
1465     last_output_surface_id_ = output_surface_id;
1466   }
1467   if (frame_size.IsEmpty()) {
1468     DCHECK_EQ(0u, frame_data->resource_list.size());
1469     EvictDelegatedFrame();
1470   } else {
1471     if (!resource_collection_) {
1472       resource_collection_ = new cc::DelegatedFrameResourceCollection;
1473       resource_collection_->SetClient(this);
1474     }
1475     // If the physical frame size changes, we need a new |frame_provider_|. If
1476     // the physical frame size is the same, but the size in DIP changed, we
1477     // need to adjust the scale at which the frames will be drawn, and we do
1478     // this by making a new |frame_provider_| also to ensure the scale change
1479     // is presented in sync with the new frame content.
1480     if (!frame_provider_.get() || frame_size != frame_provider_->frame_size() ||
1481         frame_size_in_dip != current_frame_size_) {
1482       frame_provider_ = new cc::DelegatedFrameProvider(
1483           resource_collection_.get(), frame_data.Pass());
1484       window_->layer()->SetShowDelegatedContent(frame_provider_.get(),
1485                                                 frame_size_in_dip);
1486     } else {
1487       frame_provider_->SetFrameData(frame_data.Pass());
1488     }
1489   }
1490   released_front_lock_ = NULL;
1491   current_frame_size_ = frame_size_in_dip;
1492   CheckResizeLock();
1493
1494   window_->SchedulePaintInRect(damage_rect_in_dip);
1495
1496   pending_delegated_ack_count_++;
1497
1498   ui::Compositor* compositor = GetCompositor();
1499   if (!compositor) {
1500     SendDelegatedFrameAck(output_surface_id);
1501   } else {
1502     for (size_t i = 0; i < latency_info.size(); i++)
1503       compositor->SetLatencyInfo(latency_info[i]);
1504     AddOnCommitCallbackAndDisableLocks(
1505         base::Bind(&RenderWidgetHostViewAura::SendDelegatedFrameAck,
1506                    AsWeakPtr(),
1507                    output_surface_id));
1508   }
1509   DidReceiveFrameFromRenderer();
1510   if (frame_provider_.get())
1511     delegated_frame_evictor_->SwappedFrame(!host_->is_hidden());
1512   // Note: the frame may have been evicted immediately.
1513 }
1514
1515 void RenderWidgetHostViewAura::SendDelegatedFrameAck(uint32 output_surface_id) {
1516   cc::CompositorFrameAck ack;
1517   if (resource_collection_)
1518     resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources);
1519   RenderWidgetHostImpl::SendSwapCompositorFrameAck(host_->GetRoutingID(),
1520                                                    output_surface_id,
1521                                                    host_->GetProcess()->GetID(),
1522                                                    ack);
1523   DCHECK_GT(pending_delegated_ack_count_, 0);
1524   pending_delegated_ack_count_--;
1525 }
1526
1527 void RenderWidgetHostViewAura::UnusedResourcesAreAvailable() {
1528   if (pending_delegated_ack_count_)
1529     return;
1530
1531   SendReturnedDelegatedResources(last_output_surface_id_);
1532 }
1533
1534 void RenderWidgetHostViewAura::SendReturnedDelegatedResources(
1535     uint32 output_surface_id) {
1536   DCHECK(resource_collection_);
1537
1538   cc::CompositorFrameAck ack;
1539   resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources);
1540   DCHECK(!ack.resources.empty());
1541
1542   RenderWidgetHostImpl::SendReclaimCompositorResources(
1543       host_->GetRoutingID(),
1544       output_surface_id,
1545       host_->GetProcess()->GetID(),
1546       ack);
1547 }
1548
1549 void RenderWidgetHostViewAura::EvictDelegatedFrame() {
1550   window_->layer()->SetShowPaintedContent();
1551   frame_provider_ = NULL;
1552   delegated_frame_evictor_->DiscardedFrame();
1553 }
1554
1555 void RenderWidgetHostViewAura::SwapSoftwareFrame(
1556     uint32 output_surface_id,
1557     scoped_ptr<cc::SoftwareFrameData> frame_data,
1558     float frame_device_scale_factor,
1559     const std::vector<ui::LatencyInfo>& latency_info) {
1560   const gfx::Size& frame_size = frame_data->size;
1561   const gfx::Rect& damage_rect = frame_data->damage_rect;
1562   gfx::Size frame_size_in_dip =
1563       ConvertSizeToDIP(frame_device_scale_factor, frame_size);
1564   if (ShouldSkipFrame(frame_size_in_dip)) {
1565     ReleaseSoftwareFrame(output_surface_id, frame_data->id);
1566     SendSoftwareFrameAck(output_surface_id);
1567     return;
1568   }
1569
1570   if (!software_frame_manager_->SwapToNewFrame(
1571           output_surface_id,
1572           frame_data.get(),
1573           frame_device_scale_factor,
1574           host_->GetProcess()->GetHandle())) {
1575     ReleaseSoftwareFrame(output_surface_id, frame_data->id);
1576     SendSoftwareFrameAck(output_surface_id);
1577     return;
1578   }
1579
1580   if (last_swapped_surface_size_ != frame_size) {
1581     DLOG_IF(ERROR, damage_rect != gfx::Rect(frame_size))
1582         << "Expected full damage rect";
1583   }
1584   last_swapped_surface_size_ = frame_size;
1585   last_swapped_surface_scale_factor_ = frame_device_scale_factor;
1586
1587   cc::TextureMailbox mailbox;
1588   scoped_ptr<cc::SingleReleaseCallback> callback;
1589   software_frame_manager_->GetCurrentFrameMailbox(&mailbox, &callback);
1590   DCHECK(mailbox.IsSharedMemory());
1591   current_frame_size_ = frame_size_in_dip;
1592
1593   released_front_lock_ = NULL;
1594   CheckResizeLock();
1595   window_->layer()->SetTextureMailbox(mailbox,
1596                                       callback.Pass(),
1597                                       frame_device_scale_factor);
1598   window_->SchedulePaintInRect(
1599       ConvertRectToDIP(frame_device_scale_factor, damage_rect));
1600
1601   ui::Compositor* compositor = GetCompositor();
1602   if (compositor) {
1603     for (size_t i = 0; i < latency_info.size(); i++)
1604       compositor->SetLatencyInfo(latency_info[i]);
1605     AddOnCommitCallbackAndDisableLocks(
1606         base::Bind(&RenderWidgetHostViewAura::SendSoftwareFrameAck,
1607                    AsWeakPtr(),
1608                    output_surface_id));
1609   } else {
1610     SendSoftwareFrameAck(output_surface_id);
1611   }
1612   DidReceiveFrameFromRenderer();
1613
1614   software_frame_manager_->SwapToNewFrameComplete(!host_->is_hidden());
1615 }
1616
1617 void RenderWidgetHostViewAura::SendSoftwareFrameAck(uint32 output_surface_id) {
1618   unsigned software_frame_id = 0;
1619   if (released_software_frame_ &&
1620       released_software_frame_->output_surface_id == output_surface_id) {
1621     software_frame_id = released_software_frame_->frame_id;
1622     released_software_frame_.reset();
1623   }
1624
1625   cc::CompositorFrameAck ack;
1626   ack.last_software_frame_id = software_frame_id;
1627   RenderWidgetHostImpl::SendSwapCompositorFrameAck(
1628       host_->GetRoutingID(), output_surface_id,
1629       host_->GetProcess()->GetID(), ack);
1630   SendReclaimSoftwareFrames();
1631 }
1632
1633 void RenderWidgetHostViewAura::SendReclaimSoftwareFrames() {
1634   if (!released_software_frame_)
1635     return;
1636   cc::CompositorFrameAck ack;
1637   ack.last_software_frame_id = released_software_frame_->frame_id;
1638   RenderWidgetHostImpl::SendReclaimCompositorResources(
1639       host_->GetRoutingID(),
1640       released_software_frame_->output_surface_id,
1641       host_->GetProcess()->GetID(),
1642       ack);
1643   released_software_frame_.reset();
1644 }
1645
1646 void RenderWidgetHostViewAura::ReleaseSoftwareFrame(
1647     uint32 output_surface_id,
1648     unsigned software_frame_id) {
1649   SendReclaimSoftwareFrames();
1650   DCHECK(!released_software_frame_);
1651   released_software_frame_.reset(new ReleasedFrameInfo(
1652       output_surface_id, software_frame_id));
1653 }
1654
1655 void RenderWidgetHostViewAura::OnSwapCompositorFrame(
1656     uint32 output_surface_id,
1657     scoped_ptr<cc::CompositorFrame> frame) {
1658   TRACE_EVENT0("content", "RenderWidgetHostViewAura::OnSwapCompositorFrame");
1659   if (frame->delegated_frame_data) {
1660     SwapDelegatedFrame(output_surface_id,
1661                        frame->delegated_frame_data.Pass(),
1662                        frame->metadata.device_scale_factor,
1663                        frame->metadata.latency_info);
1664     return;
1665   }
1666
1667   if (frame->software_frame_data) {
1668     SwapSoftwareFrame(output_surface_id,
1669                       frame->software_frame_data.Pass(),
1670                       frame->metadata.device_scale_factor,
1671                       frame->metadata.latency_info);
1672     return;
1673   }
1674
1675   if (!frame->gl_frame_data || frame->gl_frame_data->mailbox.IsZero())
1676     return;
1677
1678   BufferPresentedCallback ack_callback = base::Bind(
1679       &SendCompositorFrameAck,
1680       host_->GetRoutingID(), output_surface_id, host_->GetProcess()->GetID(),
1681       frame->gl_frame_data->mailbox, frame->gl_frame_data->size);
1682
1683   if (!frame->gl_frame_data->sync_point) {
1684     LOG(ERROR) << "CompositorFrame without sync point. Skipping frame...";
1685     ack_callback.Run(true, scoped_refptr<ui::Texture>());
1686     return;
1687   }
1688
1689   GLHelper* gl_helper = ImageTransportFactory::GetInstance()->GetGLHelper();
1690   gl_helper->WaitSyncPoint(frame->gl_frame_data->sync_point);
1691
1692   BuffersSwapped(frame->gl_frame_data->size,
1693                  frame->gl_frame_data->sub_buffer_rect,
1694                  frame->metadata.device_scale_factor,
1695                  frame->gl_frame_data->mailbox,
1696                  frame->metadata.latency_info,
1697                  ack_callback);
1698 }
1699
1700 #if defined(OS_WIN)
1701 void RenderWidgetHostViewAura::SetParentNativeViewAccessible(
1702     gfx::NativeViewAccessible accessible_parent) {
1703   if (GetBrowserAccessibilityManager()) {
1704     GetBrowserAccessibilityManager()->ToBrowserAccessibilityManagerWin()
1705         ->set_parent_iaccessible(accessible_parent);
1706   }
1707 }
1708
1709 gfx::NativeViewId RenderWidgetHostViewAura::GetParentForWindowlessPlugin()
1710     const {
1711   if (legacy_render_widget_host_HWND_) {
1712     return reinterpret_cast<gfx::NativeViewId>(
1713         legacy_render_widget_host_HWND_->hwnd());
1714   }
1715   return NULL;
1716 }
1717 #endif
1718
1719 void RenderWidgetHostViewAura::BuffersSwapped(
1720     const gfx::Size& surface_size,
1721     const gfx::Rect& damage_rect,
1722     float surface_scale_factor,
1723     const gpu::Mailbox& mailbox,
1724     const std::vector<ui::LatencyInfo>& latency_info,
1725     const BufferPresentedCallback& ack_callback) {
1726   scoped_refptr<ui::Texture> previous_texture(current_surface_);
1727   const gfx::Rect surface_rect = gfx::Rect(surface_size);
1728   software_frame_manager_->DiscardCurrentFrame();
1729
1730   if (!SwapBuffersPrepare(surface_rect,
1731                           surface_scale_factor,
1732                           damage_rect,
1733                           mailbox,
1734                           ack_callback)) {
1735     return;
1736   }
1737
1738   SkRegion damage(RectToSkIRect(damage_rect));
1739   if (!skipped_damage_.isEmpty()) {
1740     damage.op(skipped_damage_, SkRegion::kUnion_Op);
1741     skipped_damage_.setEmpty();
1742   }
1743
1744   DCHECK(surface_rect.Contains(SkIRectToRect(damage.getBounds())));
1745   ui::Texture* current_texture = current_surface_.get();
1746
1747   const gfx::Size surface_size_in_pixel = surface_size;
1748   DLOG_IF(ERROR, previous_texture.get() &&
1749       previous_texture->size() != current_texture->size() &&
1750       SkIRectToRect(damage.getBounds()) != surface_rect) <<
1751       "Expected full damage rect after size change";
1752   if (previous_texture.get() && !previous_damage_.isEmpty() &&
1753       previous_texture->size() == current_texture->size()) {
1754     ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
1755     GLHelper* gl_helper = factory->GetGLHelper();
1756     gl_helper->CopySubBufferDamage(
1757         current_texture->PrepareTexture(),
1758         previous_texture->PrepareTexture(),
1759         damage,
1760         previous_damage_);
1761   }
1762   previous_damage_ = damage;
1763
1764   ui::Compositor* compositor = GetCompositor();
1765   if (compositor) {
1766     // Co-ordinates come in OpenGL co-ordinate space.
1767     // We need to convert to layer space.
1768     gfx::Rect rect_to_paint =
1769         ConvertRectToDIP(surface_scale_factor,
1770                          gfx::Rect(damage_rect.x(),
1771                                    surface_size_in_pixel.height() -
1772                                        damage_rect.y() - damage_rect.height(),
1773                                    damage_rect.width(),
1774                                    damage_rect.height()));
1775
1776     // Damage may not have been DIP aligned, so inflate damage to compensate
1777     // for any round-off error.
1778     rect_to_paint.Inset(-1, -1);
1779     rect_to_paint.Intersect(window_->bounds());
1780
1781     window_->SchedulePaintInRect(rect_to_paint);
1782     for (size_t i = 0; i < latency_info.size(); i++)
1783       compositor->SetLatencyInfo(latency_info[i]);
1784   }
1785
1786   SwapBuffersCompleted(ack_callback, previous_texture);
1787 }
1788
1789 void RenderWidgetHostViewAura::AcceleratedSurfacePostSubBuffer(
1790     const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params_in_pixel,
1791     int gpu_host_id) {
1792   gfx::Rect damage_rect(params_in_pixel.x,
1793                         params_in_pixel.y,
1794                         params_in_pixel.width,
1795                         params_in_pixel.height);
1796   BufferPresentedCallback ack_callback =
1797       base::Bind(&AcknowledgeBufferForGpu,
1798                  params_in_pixel.route_id,
1799                  gpu_host_id,
1800                  params_in_pixel.mailbox);
1801   BuffersSwapped(params_in_pixel.surface_size,
1802                  damage_rect,
1803                  params_in_pixel.surface_scale_factor,
1804                  params_in_pixel.mailbox,
1805                  params_in_pixel.latency_info,
1806                  ack_callback);
1807 }
1808
1809 void RenderWidgetHostViewAura::AcceleratedSurfaceSuspend() {
1810 }
1811
1812 void RenderWidgetHostViewAura::AcceleratedSurfaceRelease() {
1813   // This really tells us to release the frontbuffer.
1814   if (current_surface_.get()) {
1815     ui::Compositor* compositor = GetCompositor();
1816     if (compositor) {
1817       // We need to wait for a commit to clear to guarantee that all we
1818       // will not issue any more GL referencing the previous surface.
1819       AddOnCommitCallbackAndDisableLocks(
1820           base::Bind(&RenderWidgetHostViewAura::SetSurfaceNotInUseByCompositor,
1821                      AsWeakPtr(),
1822                      current_surface_));  // Hold a ref so the texture will not
1823                                           // get deleted until after commit.
1824     }
1825     current_surface_ = NULL;
1826     UpdateExternalTexture();
1827   }
1828 }
1829
1830 bool RenderWidgetHostViewAura::HasAcceleratedSurface(
1831     const gfx::Size& desired_size) {
1832   // Aura doesn't use GetBackingStore for accelerated pages, so it doesn't
1833   // matter what is returned here as GetBackingStore is the only caller of this
1834   // method. TODO(jbates) implement this if other Aura code needs it.
1835   return false;
1836 }
1837
1838 void RenderWidgetHostViewAura::SetSurfaceNotInUseByCompositor(
1839     scoped_refptr<ui::Texture>) {
1840 }
1841
1842 // static
1843 void RenderWidgetHostViewAura::CopyFromCompositingSurfaceHasResult(
1844     const gfx::Size& dst_size_in_pixel,
1845     const SkBitmap::Config config,
1846     const base::Callback<void(bool, const SkBitmap&)>& callback,
1847     scoped_ptr<cc::CopyOutputResult> result) {
1848   if (result->IsEmpty() || result->size().IsEmpty()) {
1849     callback.Run(false, SkBitmap());
1850     return;
1851   }
1852
1853   if (result->HasTexture()) {
1854     PrepareTextureCopyOutputResult(dst_size_in_pixel, config,
1855                                    callback,
1856                                    result.Pass());
1857     return;
1858   }
1859
1860   DCHECK(result->HasBitmap());
1861   PrepareBitmapCopyOutputResult(dst_size_in_pixel, config, callback,
1862                                 result.Pass());
1863 }
1864
1865 static void CopyFromCompositingSurfaceFinished(
1866     const base::Callback<void(bool, const SkBitmap&)>& callback,
1867     scoped_ptr<cc::SingleReleaseCallback> release_callback,
1868     scoped_ptr<SkBitmap> bitmap,
1869     scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock,
1870     bool result) {
1871   bitmap_pixels_lock.reset();
1872
1873   uint32 sync_point = 0;
1874   if (result) {
1875     GLHelper* gl_helper = ImageTransportFactory::GetInstance()->GetGLHelper();
1876     sync_point = gl_helper->InsertSyncPoint();
1877   }
1878   bool lost_resource = sync_point == 0;
1879   release_callback->Run(sync_point, lost_resource);
1880
1881   callback.Run(result, *bitmap);
1882 }
1883
1884 // static
1885 void RenderWidgetHostViewAura::PrepareTextureCopyOutputResult(
1886     const gfx::Size& dst_size_in_pixel,
1887     const SkBitmap::Config config,
1888     const base::Callback<void(bool, const SkBitmap&)>& callback,
1889     scoped_ptr<cc::CopyOutputResult> result) {
1890   DCHECK(result->HasTexture());
1891   base::ScopedClosureRunner scoped_callback_runner(
1892       base::Bind(callback, false, SkBitmap()));
1893
1894   scoped_ptr<SkBitmap> bitmap(new SkBitmap);
1895   bitmap->setConfig(config,
1896                     dst_size_in_pixel.width(), dst_size_in_pixel.height(),
1897                     0, kOpaque_SkAlphaType);
1898   if (!bitmap->allocPixels())
1899     return;
1900
1901   ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
1902   GLHelper* gl_helper = factory->GetGLHelper();
1903   if (!gl_helper)
1904     return;
1905
1906   scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock(
1907       new SkAutoLockPixels(*bitmap));
1908   uint8* pixels = static_cast<uint8*>(bitmap->getPixels());
1909
1910   cc::TextureMailbox texture_mailbox;
1911   scoped_ptr<cc::SingleReleaseCallback> release_callback;
1912   result->TakeTexture(&texture_mailbox, &release_callback);
1913   DCHECK(texture_mailbox.IsTexture());
1914   if (!texture_mailbox.IsTexture())
1915     return;
1916
1917   ignore_result(scoped_callback_runner.Release());
1918
1919   gl_helper->CropScaleReadbackAndCleanMailbox(
1920       texture_mailbox.mailbox(),
1921       texture_mailbox.sync_point(),
1922       result->size(),
1923       gfx::Rect(result->size()),
1924       dst_size_in_pixel,
1925       pixels,
1926       config,
1927       base::Bind(&CopyFromCompositingSurfaceFinished,
1928                  callback,
1929                  base::Passed(&release_callback),
1930                  base::Passed(&bitmap),
1931                  base::Passed(&bitmap_pixels_lock)));
1932 }
1933
1934 // static
1935 void RenderWidgetHostViewAura::PrepareBitmapCopyOutputResult(
1936     const gfx::Size& dst_size_in_pixel,
1937     const SkBitmap::Config config,
1938     const base::Callback<void(bool, const SkBitmap&)>& callback,
1939     scoped_ptr<cc::CopyOutputResult> result) {
1940   if (config != SkBitmap::kARGB_8888_Config) {
1941     NOTIMPLEMENTED();
1942     callback.Run(false, SkBitmap());
1943     return;
1944   }
1945   DCHECK(result->HasBitmap());
1946   base::ScopedClosureRunner scoped_callback_runner(
1947       base::Bind(callback, false, SkBitmap()));
1948
1949   scoped_ptr<SkBitmap> source = result->TakeBitmap();
1950   DCHECK(source);
1951   if (!source)
1952     return;
1953
1954   ignore_result(scoped_callback_runner.Release());
1955
1956   SkBitmap bitmap = skia::ImageOperations::Resize(
1957       *source,
1958       skia::ImageOperations::RESIZE_BEST,
1959       dst_size_in_pixel.width(),
1960       dst_size_in_pixel.height());
1961   callback.Run(true, bitmap);
1962 }
1963
1964 // static
1965 void RenderWidgetHostViewAura::ReturnSubscriberTexture(
1966     base::WeakPtr<RenderWidgetHostViewAura> rwhva,
1967     scoped_refptr<OwnedMailbox> subscriber_texture,
1968     uint32 sync_point) {
1969   if (!subscriber_texture.get())
1970     return;
1971   if (!rwhva)
1972     return;
1973   DCHECK_NE(
1974       rwhva->active_frame_subscriber_textures_.count(subscriber_texture.get()),
1975       0u);
1976
1977   subscriber_texture->UpdateSyncPoint(sync_point);
1978
1979   rwhva->active_frame_subscriber_textures_.erase(subscriber_texture.get());
1980   if (rwhva->frame_subscriber_ && subscriber_texture->texture_id())
1981     rwhva->idle_frame_subscriber_textures_.push_back(subscriber_texture);
1982 }
1983
1984 void RenderWidgetHostViewAura::CopyFromCompositingSurfaceFinishedForVideo(
1985     base::WeakPtr<RenderWidgetHostViewAura> rwhva,
1986     const base::Callback<void(bool)>& callback,
1987     scoped_refptr<OwnedMailbox> subscriber_texture,
1988     scoped_ptr<cc::SingleReleaseCallback> release_callback,
1989     bool result) {
1990   callback.Run(result);
1991
1992   uint32 sync_point = 0;
1993   if (result) {
1994     GLHelper* gl_helper = ImageTransportFactory::GetInstance()->GetGLHelper();
1995     sync_point = gl_helper->InsertSyncPoint();
1996   }
1997   if (release_callback) {
1998     // A release callback means the texture came from the compositor, so there
1999     // should be no |subscriber_texture|.
2000     DCHECK(!subscriber_texture);
2001     bool lost_resource = sync_point == 0;
2002     release_callback->Run(sync_point, lost_resource);
2003   }
2004   ReturnSubscriberTexture(rwhva, subscriber_texture, sync_point);
2005 }
2006
2007 // static
2008 void RenderWidgetHostViewAura::CopyFromCompositingSurfaceHasResultForVideo(
2009     base::WeakPtr<RenderWidgetHostViewAura> rwhva,
2010     scoped_refptr<OwnedMailbox> subscriber_texture,
2011     scoped_refptr<media::VideoFrame> video_frame,
2012     const base::Callback<void(bool)>& callback,
2013     scoped_ptr<cc::CopyOutputResult> result) {
2014   base::ScopedClosureRunner scoped_callback_runner(base::Bind(callback, false));
2015   base::ScopedClosureRunner scoped_return_subscriber_texture(
2016       base::Bind(&ReturnSubscriberTexture, rwhva, subscriber_texture, 0));
2017
2018   if (!rwhva)
2019     return;
2020   if (result->IsEmpty())
2021     return;
2022   if (result->size().IsEmpty())
2023     return;
2024
2025   // Compute the dest size we want after the letterboxing resize. Make the
2026   // coordinates and sizes even because we letterbox in YUV space
2027   // (see CopyRGBToVideoFrame). They need to be even for the UV samples to
2028   // line up correctly.
2029   // The video frame's coded_size() and the result's size() are both physical
2030   // pixels.
2031   gfx::Rect region_in_frame =
2032       media::ComputeLetterboxRegion(gfx::Rect(video_frame->coded_size()),
2033                                     result->size());
2034   region_in_frame = gfx::Rect(region_in_frame.x() & ~1,
2035                               region_in_frame.y() & ~1,
2036                               region_in_frame.width() & ~1,
2037                               region_in_frame.height() & ~1);
2038   if (region_in_frame.IsEmpty())
2039     return;
2040
2041   if (!result->HasTexture()) {
2042     DCHECK(result->HasBitmap());
2043     scoped_ptr<SkBitmap> bitmap = result->TakeBitmap();
2044     // Scale the bitmap to the required size, if necessary.
2045     SkBitmap scaled_bitmap;
2046     if (result->size().width() != region_in_frame.width() ||
2047         result->size().height() != region_in_frame.height()) {
2048       skia::ImageOperations::ResizeMethod method =
2049           skia::ImageOperations::RESIZE_GOOD;
2050       scaled_bitmap = skia::ImageOperations::Resize(*bitmap.get(), method,
2051                                                     region_in_frame.width(),
2052                                                     region_in_frame.height());
2053     } else {
2054       scaled_bitmap = *bitmap.get();
2055     }
2056
2057     {
2058       SkAutoLockPixels scaled_bitmap_locker(scaled_bitmap);
2059
2060       media::CopyRGBToVideoFrame(
2061           reinterpret_cast<uint8*>(scaled_bitmap.getPixels()),
2062           scaled_bitmap.rowBytes(),
2063           region_in_frame,
2064           video_frame.get());
2065     }
2066     ignore_result(scoped_callback_runner.Release());
2067     callback.Run(true);
2068     return;
2069   }
2070
2071   ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
2072   GLHelper* gl_helper = factory->GetGLHelper();
2073   if (!gl_helper)
2074     return;
2075   if (subscriber_texture.get() && !subscriber_texture->texture_id())
2076     return;
2077
2078   cc::TextureMailbox texture_mailbox;
2079   scoped_ptr<cc::SingleReleaseCallback> release_callback;
2080   result->TakeTexture(&texture_mailbox, &release_callback);
2081   DCHECK(texture_mailbox.IsTexture());
2082   if (!texture_mailbox.IsTexture())
2083     return;
2084
2085   gfx::Rect result_rect(result->size());
2086
2087   content::ReadbackYUVInterface* yuv_readback_pipeline =
2088       rwhva->yuv_readback_pipeline_.get();
2089   if (yuv_readback_pipeline == NULL ||
2090       yuv_readback_pipeline->scaler()->SrcSize() != result_rect.size() ||
2091       yuv_readback_pipeline->scaler()->SrcSubrect() != result_rect ||
2092       yuv_readback_pipeline->scaler()->DstSize() != region_in_frame.size()) {
2093     GLHelper::ScalerQuality quality = GLHelper::SCALER_QUALITY_FAST;
2094     std::string quality_switch = switches::kTabCaptureDownscaleQuality;
2095     // If we're scaling up, we can use the "best" quality.
2096     if (result_rect.size().width() < region_in_frame.size().width() &&
2097         result_rect.size().height() < region_in_frame.size().height())
2098       quality_switch = switches::kTabCaptureUpscaleQuality;
2099
2100     std::string switch_value =
2101         CommandLine::ForCurrentProcess()->GetSwitchValueASCII(quality_switch);
2102     if (switch_value == "fast")
2103       quality = GLHelper::SCALER_QUALITY_FAST;
2104     else if (switch_value == "good")
2105       quality = GLHelper::SCALER_QUALITY_GOOD;
2106     else if (switch_value == "best")
2107       quality = GLHelper::SCALER_QUALITY_BEST;
2108
2109     rwhva->yuv_readback_pipeline_.reset(
2110         gl_helper->CreateReadbackPipelineYUV(quality,
2111                                              result_rect.size(),
2112                                              result_rect,
2113                                              video_frame->coded_size(),
2114                                              region_in_frame,
2115                                              true,
2116                                              true));
2117     yuv_readback_pipeline = rwhva->yuv_readback_pipeline_.get();
2118   }
2119
2120   ignore_result(scoped_callback_runner.Release());
2121   ignore_result(scoped_return_subscriber_texture.Release());
2122   base::Callback<void(bool result)> finished_callback = base::Bind(
2123       &RenderWidgetHostViewAura::CopyFromCompositingSurfaceFinishedForVideo,
2124       rwhva->AsWeakPtr(),
2125       callback,
2126       subscriber_texture,
2127       base::Passed(&release_callback));
2128   yuv_readback_pipeline->ReadbackYUV(texture_mailbox.mailbox(),
2129                                      texture_mailbox.sync_point(),
2130                                      video_frame.get(),
2131                                      finished_callback);
2132 }
2133
2134 void RenderWidgetHostViewAura::GetScreenInfo(WebScreenInfo* results) {
2135   GetScreenInfoForWindow(results, window_->GetRootWindow() ? window_ : NULL);
2136 }
2137
2138 gfx::Rect RenderWidgetHostViewAura::GetBoundsInRootWindow() {
2139 #if defined(OS_WIN)
2140   // aura::Window::GetBoundsInScreen doesn't take non-client area into
2141   // account.
2142   RECT window_rect = {0};
2143
2144   aura::Window* top_level = window_->GetToplevelWindow();
2145   aura::WindowEventDispatcher* dispatcher = top_level->GetDispatcher();
2146   if (!dispatcher)
2147     return top_level->GetBoundsInScreen();
2148   HWND hwnd = dispatcher->host()->GetAcceleratedWidget();
2149   ::GetWindowRect(hwnd, &window_rect);
2150   gfx::Rect rect(window_rect);
2151
2152   // Maximized windows are outdented from the work area by the frame thickness
2153   // even though this "frame" is not painted.  This confuses code (and people)
2154   // that think of a maximized window as corresponding exactly to the work area.
2155   // Correct for this by subtracting the frame thickness back off.
2156   if (::IsZoomed(hwnd)) {
2157     rect.Inset(GetSystemMetrics(SM_CXSIZEFRAME),
2158                GetSystemMetrics(SM_CYSIZEFRAME));
2159   }
2160
2161   return gfx::win::ScreenToDIPRect(rect);
2162 #else
2163   return window_->GetToplevelWindow()->GetBoundsInScreen();
2164 #endif
2165 }
2166
2167 void RenderWidgetHostViewAura::GestureEventAck(
2168     const blink::WebGestureEvent& event,
2169     InputEventAckState ack_result) {
2170   if (touch_editing_client_)
2171     touch_editing_client_->GestureEventAck(event.type);
2172 }
2173
2174 void RenderWidgetHostViewAura::ProcessAckedTouchEvent(
2175     const TouchEventWithLatencyInfo& touch, InputEventAckState ack_result) {
2176   ScopedVector<ui::TouchEvent> events;
2177   if (!MakeUITouchEventsFromWebTouchEvents(touch, &events,
2178                                            SCREEN_COORDINATES))
2179     return;
2180
2181   aura::WindowEventDispatcher* dispatcher = window_->GetDispatcher();
2182   // |dispatcher| is NULL during tests.
2183   if (!dispatcher)
2184     return;
2185
2186   ui::EventResult result = (ack_result ==
2187       INPUT_EVENT_ACK_STATE_CONSUMED) ? ui::ER_HANDLED : ui::ER_UNHANDLED;
2188   for (ScopedVector<ui::TouchEvent>::iterator iter = events.begin(),
2189       end = events.end(); iter != end; ++iter) {
2190     dispatcher->ProcessedTouchEvent((*iter), window_, result);
2191   }
2192 }
2193
2194 scoped_ptr<SyntheticGestureTarget>
2195 RenderWidgetHostViewAura::CreateSyntheticGestureTarget() {
2196   return scoped_ptr<SyntheticGestureTarget>(
2197       new SyntheticGestureTargetAura(host_));
2198 }
2199
2200 void RenderWidgetHostViewAura::SetHasHorizontalScrollbar(
2201     bool has_horizontal_scrollbar) {
2202   // Not needed. Mac-only.
2203 }
2204
2205 void RenderWidgetHostViewAura::SetScrollOffsetPinning(
2206     bool is_pinned_to_left, bool is_pinned_to_right) {
2207   // Not needed. Mac-only.
2208 }
2209
2210 void RenderWidgetHostViewAura::CreateBrowserAccessibilityManagerIfNeeded() {
2211   if (GetBrowserAccessibilityManager())
2212     return;
2213
2214   BrowserAccessibilityManager* manager = NULL;
2215 #if defined(OS_WIN)
2216   aura::WindowEventDispatcher* dispatcher = window_->GetDispatcher();
2217   if (!dispatcher)
2218     return;
2219   HWND hwnd = dispatcher->host()->GetAcceleratedWidget();
2220
2221   // The accessible_parent may be NULL at this point. The WebContents will pass
2222   // it down to this instance (by way of the RenderViewHost and
2223   // RenderWidgetHost) when it is known. This instance will then set it on its
2224   // BrowserAccessibilityManager.
2225   gfx::NativeViewAccessible accessible_parent =
2226       host_->GetParentNativeViewAccessible();
2227
2228   if (legacy_render_widget_host_HWND_) {
2229     manager = new BrowserAccessibilityManagerWin(
2230         legacy_render_widget_host_HWND_.get(), accessible_parent,
2231         BrowserAccessibilityManagerWin::GetEmptyDocument(), this);
2232   }
2233 #else
2234   manager = BrowserAccessibilityManager::Create(
2235       BrowserAccessibilityManager::GetEmptyDocument(), this);
2236 #endif
2237   SetBrowserAccessibilityManager(manager);
2238 }
2239
2240 gfx::GLSurfaceHandle RenderWidgetHostViewAura::GetCompositingSurface() {
2241   return ImageTransportFactory::GetInstance()->GetSharedSurfaceHandle();
2242 }
2243
2244 bool RenderWidgetHostViewAura::LockMouse() {
2245   aura::Window* root_window = window_->GetRootWindow();
2246   if (!root_window)
2247     return false;
2248
2249   if (mouse_locked_)
2250     return true;
2251
2252   mouse_locked_ = true;
2253 #if !defined(OS_WIN)
2254   window_->SetCapture();
2255 #endif
2256   aura::client::CursorClient* cursor_client =
2257       aura::client::GetCursorClient(root_window);
2258   if (cursor_client) {
2259     cursor_client->HideCursor();
2260     cursor_client->LockCursor();
2261   }
2262
2263   if (ShouldMoveToCenter()) {
2264     synthetic_move_sent_ = true;
2265     window_->MoveCursorTo(gfx::Rect(window_->bounds().size()).CenterPoint());
2266   }
2267   tooltip_disabler_.reset(new aura::client::ScopedTooltipDisabler(root_window));
2268
2269   root_window->GetDispatcher()->host()->ConfineCursorToRootWindow();
2270   return true;
2271 }
2272
2273 void RenderWidgetHostViewAura::UnlockMouse() {
2274   tooltip_disabler_.reset();
2275
2276   aura::Window* root_window = window_->GetRootWindow();
2277   if (!mouse_locked_ || !root_window)
2278     return;
2279
2280   mouse_locked_ = false;
2281
2282 #if !defined(OS_WIN)
2283   window_->ReleaseCapture();
2284 #endif
2285   window_->MoveCursorTo(unlocked_mouse_position_);
2286   aura::client::CursorClient* cursor_client =
2287       aura::client::GetCursorClient(root_window);
2288   if (cursor_client) {
2289     cursor_client->UnlockCursor();
2290     cursor_client->ShowCursor();
2291   }
2292
2293   host_->LostMouseLock();
2294   root_window->GetDispatcher()->host()->UnConfineCursor();
2295 }
2296
2297 ////////////////////////////////////////////////////////////////////////////////
2298 // RenderWidgetHostViewAura, ui::TextInputClient implementation:
2299 void RenderWidgetHostViewAura::SetCompositionText(
2300     const ui::CompositionText& composition) {
2301   if (!host_)
2302     return;
2303
2304   // ui::CompositionUnderline should be identical to
2305   // blink::WebCompositionUnderline, so that we can do reinterpret_cast safely.
2306   COMPILE_ASSERT(sizeof(ui::CompositionUnderline) ==
2307                  sizeof(blink::WebCompositionUnderline),
2308                  ui_CompositionUnderline__WebKit_WebCompositionUnderline_diff);
2309
2310   // TODO(suzhe): convert both renderer_host and renderer to use
2311   // ui::CompositionText.
2312   const std::vector<blink::WebCompositionUnderline>& underlines =
2313       reinterpret_cast<const std::vector<blink::WebCompositionUnderline>&>(
2314           composition.underlines);
2315
2316   // TODO(suzhe): due to a bug of webkit, we can't use selection range with
2317   // composition string. See: https://bugs.webkit.org/show_bug.cgi?id=37788
2318   host_->ImeSetComposition(composition.text, underlines,
2319                            composition.selection.end(),
2320                            composition.selection.end());
2321
2322   has_composition_text_ = !composition.text.empty();
2323 }
2324
2325 void RenderWidgetHostViewAura::ConfirmCompositionText() {
2326   if (host_ && has_composition_text_) {
2327     host_->ImeConfirmComposition(base::string16(), gfx::Range::InvalidRange(),
2328                                  false);
2329   }
2330   has_composition_text_ = false;
2331 }
2332
2333 void RenderWidgetHostViewAura::ClearCompositionText() {
2334   if (host_ && has_composition_text_)
2335     host_->ImeCancelComposition();
2336   has_composition_text_ = false;
2337 }
2338
2339 void RenderWidgetHostViewAura::InsertText(const base::string16& text) {
2340   DCHECK(text_input_type_ != ui::TEXT_INPUT_TYPE_NONE);
2341   if (host_)
2342     host_->ImeConfirmComposition(text, gfx::Range::InvalidRange(), false);
2343   has_composition_text_ = false;
2344 }
2345
2346 void RenderWidgetHostViewAura::InsertChar(base::char16 ch, int flags) {
2347   if (popup_child_host_view_ && popup_child_host_view_->NeedsInputGrab()) {
2348     popup_child_host_view_->InsertChar(ch, flags);
2349     return;
2350   }
2351
2352   // Ignore character messages for VKEY_RETURN sent on CTRL+M. crbug.com/315547
2353   if (host_ && (accept_return_character_ || ch != ui::VKEY_RETURN)) {
2354     double now = ui::EventTimeForNow().InSecondsF();
2355     // Send a blink::WebInputEvent::Char event to |host_|.
2356     NativeWebKeyboardEvent webkit_event(ui::ET_KEY_PRESSED,
2357                                         true /* is_char */,
2358                                         ch,
2359                                         flags,
2360                                         now);
2361     host_->ForwardKeyboardEvent(webkit_event);
2362   }
2363 }
2364
2365 gfx::NativeWindow RenderWidgetHostViewAura::GetAttachedWindow() const {
2366   return window_;
2367 }
2368
2369 ui::TextInputType RenderWidgetHostViewAura::GetTextInputType() const {
2370   return text_input_type_;
2371 }
2372
2373 ui::TextInputMode RenderWidgetHostViewAura::GetTextInputMode() const {
2374   return text_input_mode_;
2375 }
2376
2377 bool RenderWidgetHostViewAura::CanComposeInline() const {
2378   return can_compose_inline_;
2379 }
2380
2381 gfx::Rect RenderWidgetHostViewAura::ConvertRectToScreen(
2382     const gfx::Rect& rect) const {
2383   gfx::Point origin = rect.origin();
2384   gfx::Point end = gfx::Point(rect.right(), rect.bottom());
2385
2386   aura::Window* root_window = window_->GetRootWindow();
2387   if (!root_window)
2388     return rect;
2389   aura::client::ScreenPositionClient* screen_position_client =
2390       aura::client::GetScreenPositionClient(root_window);
2391   if (!screen_position_client)
2392     return rect;
2393   screen_position_client->ConvertPointToScreen(window_, &origin);
2394   screen_position_client->ConvertPointToScreen(window_, &end);
2395   return gfx::Rect(origin.x(),
2396                    origin.y(),
2397                    end.x() - origin.x(),
2398                    end.y() - origin.y());
2399 }
2400
2401 gfx::Rect RenderWidgetHostViewAura::ConvertRectFromScreen(
2402     const gfx::Rect& rect) const {
2403   gfx::Point origin = rect.origin();
2404   gfx::Point end = gfx::Point(rect.right(), rect.bottom());
2405
2406   aura::Window* root_window = window_->GetRootWindow();
2407   if (root_window) {
2408     aura::client::ScreenPositionClient* screen_position_client =
2409         aura::client::GetScreenPositionClient(root_window);
2410     screen_position_client->ConvertPointFromScreen(window_, &origin);
2411     screen_position_client->ConvertPointFromScreen(window_, &end);
2412     return gfx::Rect(origin.x(),
2413                      origin.y(),
2414                      end.x() - origin.x(),
2415                      end.y() - origin.y());
2416   }
2417
2418   return rect;
2419 }
2420
2421 gfx::Rect RenderWidgetHostViewAura::GetCaretBounds() const {
2422   const gfx::Rect rect =
2423       gfx::UnionRects(selection_anchor_rect_, selection_focus_rect_);
2424   return ConvertRectToScreen(rect);
2425 }
2426
2427 bool RenderWidgetHostViewAura::GetCompositionCharacterBounds(
2428     uint32 index,
2429     gfx::Rect* rect) const {
2430   DCHECK(rect);
2431   if (index >= composition_character_bounds_.size())
2432     return false;
2433   *rect = ConvertRectToScreen(composition_character_bounds_[index]);
2434   return true;
2435 }
2436
2437 bool RenderWidgetHostViewAura::HasCompositionText() const {
2438   return has_composition_text_;
2439 }
2440
2441 bool RenderWidgetHostViewAura::GetTextRange(gfx::Range* range) const {
2442   range->set_start(selection_text_offset_);
2443   range->set_end(selection_text_offset_ + selection_text_.length());
2444   return true;
2445 }
2446
2447 bool RenderWidgetHostViewAura::GetCompositionTextRange(
2448     gfx::Range* range) const {
2449   // TODO(suzhe): implement this method when fixing http://crbug.com/55130.
2450   NOTIMPLEMENTED();
2451   return false;
2452 }
2453
2454 bool RenderWidgetHostViewAura::GetSelectionRange(gfx::Range* range) const {
2455   range->set_start(selection_range_.start());
2456   range->set_end(selection_range_.end());
2457   return true;
2458 }
2459
2460 bool RenderWidgetHostViewAura::SetSelectionRange(const gfx::Range& range) {
2461   // TODO(suzhe): implement this method when fixing http://crbug.com/55130.
2462   NOTIMPLEMENTED();
2463   return false;
2464 }
2465
2466 bool RenderWidgetHostViewAura::DeleteRange(const gfx::Range& range) {
2467   // TODO(suzhe): implement this method when fixing http://crbug.com/55130.
2468   NOTIMPLEMENTED();
2469   return false;
2470 }
2471
2472 bool RenderWidgetHostViewAura::GetTextFromRange(
2473     const gfx::Range& range,
2474     base::string16* text) const {
2475   gfx::Range selection_text_range(selection_text_offset_,
2476       selection_text_offset_ + selection_text_.length());
2477
2478   if (!selection_text_range.Contains(range)) {
2479     text->clear();
2480     return false;
2481   }
2482   if (selection_text_range.EqualsIgnoringDirection(range)) {
2483     // Avoid calling substr whose performance is low.
2484     *text = selection_text_;
2485   } else {
2486     *text = selection_text_.substr(
2487         range.GetMin() - selection_text_offset_,
2488         range.length());
2489   }
2490   return true;
2491 }
2492
2493 void RenderWidgetHostViewAura::OnInputMethodChanged() {
2494   if (!host_)
2495     return;
2496
2497   if (GetInputMethod())
2498     host_->SetInputMethodActive(GetInputMethod()->IsActive());
2499
2500   // TODO(suzhe): implement the newly added “locale” property of HTML DOM
2501   // TextEvent.
2502 }
2503
2504 bool RenderWidgetHostViewAura::ChangeTextDirectionAndLayoutAlignment(
2505       base::i18n::TextDirection direction) {
2506   if (!host_)
2507     return false;
2508   host_->UpdateTextDirection(
2509       direction == base::i18n::RIGHT_TO_LEFT ?
2510       blink::WebTextDirectionRightToLeft :
2511       blink::WebTextDirectionLeftToRight);
2512   host_->NotifyTextDirection();
2513   return true;
2514 }
2515
2516 void RenderWidgetHostViewAura::ExtendSelectionAndDelete(
2517     size_t before, size_t after) {
2518   if (host_)
2519     host_->ExtendSelectionAndDelete(before, after);
2520 }
2521
2522 void RenderWidgetHostViewAura::EnsureCaretInRect(const gfx::Rect& rect) {
2523   gfx::Rect intersected_rect(
2524       gfx::IntersectRects(rect, window_->GetBoundsInScreen()));
2525
2526   if (intersected_rect.IsEmpty())
2527     return;
2528
2529   host_->ScrollFocusedEditableNodeIntoRect(
2530       ConvertRectFromScreen(intersected_rect));
2531 }
2532
2533 void RenderWidgetHostViewAura::OnCandidateWindowShown() {
2534   host_->CandidateWindowShown();
2535 }
2536
2537 void RenderWidgetHostViewAura::OnCandidateWindowUpdated() {
2538   host_->CandidateWindowUpdated();
2539 }
2540
2541 void RenderWidgetHostViewAura::OnCandidateWindowHidden() {
2542   host_->CandidateWindowHidden();
2543 }
2544
2545 ////////////////////////////////////////////////////////////////////////////////
2546 // RenderWidgetHostViewAura, gfx::DisplayObserver implementation:
2547
2548 void RenderWidgetHostViewAura::OnDisplayBoundsChanged(
2549     const gfx::Display& display) {
2550   gfx::Screen* screen = gfx::Screen::GetScreenFor(window_);
2551   if (display.id() == screen->GetDisplayNearestWindow(window_).id()) {
2552     UpdateScreenInfo(window_);
2553     current_cursor_.SetDisplayInfo(display);
2554     UpdateCursorIfOverSelf();
2555   }
2556 }
2557
2558 void RenderWidgetHostViewAura::OnDisplayAdded(
2559     const gfx::Display& new_display) {
2560 }
2561
2562 void RenderWidgetHostViewAura::OnDisplayRemoved(
2563     const gfx::Display& old_display) {
2564 }
2565
2566 ////////////////////////////////////////////////////////////////////////////////
2567 // RenderWidgetHostViewAura, aura::WindowDelegate implementation:
2568
2569 gfx::Size RenderWidgetHostViewAura::GetMinimumSize() const {
2570   return gfx::Size();
2571 }
2572
2573 gfx::Size RenderWidgetHostViewAura::GetMaximumSize() const {
2574   return gfx::Size();
2575 }
2576
2577 void RenderWidgetHostViewAura::OnBoundsChanged(const gfx::Rect& old_bounds,
2578                                                const gfx::Rect& new_bounds) {
2579   base::AutoReset<bool> in_bounds_changed(&in_bounds_changed_, true);
2580   // We care about this whenever RenderWidgetHostViewAura is not owned by a
2581   // WebContentsViewAura since changes to the Window's bounds need to be
2582   // messaged to the renderer.  WebContentsViewAura invokes SetSize() or
2583   // SetBounds() itself.  No matter how we got here, any redundant calls are
2584   // harmless.
2585   SetSize(new_bounds.size());
2586 }
2587
2588 gfx::NativeCursor RenderWidgetHostViewAura::GetCursor(const gfx::Point& point) {
2589   if (mouse_locked_)
2590     return ui::kCursorNone;
2591   return current_cursor_.GetNativeCursor();
2592 }
2593
2594 int RenderWidgetHostViewAura::GetNonClientComponent(
2595     const gfx::Point& point) const {
2596   return HTCLIENT;
2597 }
2598
2599 bool RenderWidgetHostViewAura::ShouldDescendIntoChildForEventHandling(
2600     aura::Window* child,
2601     const gfx::Point& location) {
2602   return true;
2603 }
2604
2605 bool RenderWidgetHostViewAura::CanFocus() {
2606   return popup_type_ == blink::WebPopupTypeNone;
2607 }
2608
2609 void RenderWidgetHostViewAura::OnCaptureLost() {
2610   host_->LostCapture();
2611   if (touch_editing_client_)
2612     touch_editing_client_->EndTouchEditing(false);
2613 }
2614
2615 void RenderWidgetHostViewAura::OnPaint(gfx::Canvas* canvas) {
2616   bool has_backing_store = !!host_->GetBackingStore(false);
2617   if (has_backing_store) {
2618     paint_canvas_ = canvas;
2619     BackingStoreAura* backing_store = static_cast<BackingStoreAura*>(
2620         host_->GetBackingStore(true));
2621     paint_canvas_ = NULL;
2622     backing_store->SkiaShowRect(gfx::Point(), canvas);
2623
2624     ui::Compositor* compositor = GetCompositor();
2625     if (compositor) {
2626       for (size_t i = 0; i < software_latency_info_.size(); i++)
2627         compositor->SetLatencyInfo(software_latency_info_[i]);
2628     }
2629     software_latency_info_.clear();
2630   } else {
2631     // For non-opaque windows, we don't draw anything, since we depend on the
2632     // canvas coming from the compositor to already be initialized as
2633     // transparent.
2634     if (window_->layer()->fills_bounds_opaquely())
2635       canvas->DrawColor(SK_ColorWHITE);
2636   }
2637 }
2638
2639 void RenderWidgetHostViewAura::OnDeviceScaleFactorChanged(
2640     float device_scale_factor) {
2641   if (!host_)
2642     return;
2643
2644   BackingStoreAura* backing_store = static_cast<BackingStoreAura*>(
2645       host_->GetBackingStore(false));
2646   if (backing_store)  // NULL in hardware path.
2647     backing_store->ScaleFactorChanged(device_scale_factor);
2648
2649   UpdateScreenInfo(window_);
2650
2651   const gfx::Display display = gfx::Screen::GetScreenFor(window_)->
2652       GetDisplayNearestWindow(window_);
2653   DCHECK_EQ(device_scale_factor, display.device_scale_factor());
2654   current_cursor_.SetDisplayInfo(display);
2655 }
2656
2657 void RenderWidgetHostViewAura::OnWindowDestroying() {
2658 #if defined(OS_WIN)
2659   HWND parent = NULL;
2660   // If the tab was hidden and it's closed, host_->is_hidden would have been
2661   // reset to false in RenderWidgetHostImpl::RendererExited.
2662   if (!window_->GetRootWindow() || host_->is_hidden()) {
2663     parent = ui::GetHiddenWindow();
2664   } else {
2665     parent = window_->GetDispatcher()->host()->GetAcceleratedWidget();
2666   }
2667   LPARAM lparam = reinterpret_cast<LPARAM>(this);
2668   EnumChildWindows(parent, WindowDestroyingCallback, lparam);
2669 #endif
2670
2671   // Make sure that the input method no longer references to this object before
2672   // this object is removed from the root window (i.e. this object loses access
2673   // to the input method).
2674   ui::InputMethod* input_method = GetInputMethod();
2675   if (input_method)
2676     input_method->DetachTextInputClient(this);
2677 }
2678
2679 void RenderWidgetHostViewAura::OnWindowDestroyed() {
2680   host_->ViewDestroyed();
2681   delete this;
2682 }
2683
2684 void RenderWidgetHostViewAura::OnWindowTargetVisibilityChanged(bool visible) {
2685 }
2686
2687 bool RenderWidgetHostViewAura::HasHitTestMask() const {
2688   return false;
2689 }
2690
2691 void RenderWidgetHostViewAura::GetHitTestMask(gfx::Path* mask) const {
2692 }
2693
2694 void RenderWidgetHostViewAura::DidRecreateLayer(ui::Layer *old_layer,
2695                                                 ui::Layer *new_layer) {
2696   float mailbox_scale_factor;
2697   cc::TextureMailbox old_mailbox =
2698       old_layer->GetTextureMailbox(&mailbox_scale_factor);
2699   scoped_refptr<ui::Texture> old_texture = old_layer->external_texture();
2700   // The new_layer is the one that will be used by our Window, so that's the one
2701   // that should keep our texture. old_layer will be returned to the
2702   // RecreateLayer caller, and should have a copy.
2703   if (old_texture.get()) {
2704     ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
2705     GLHelper* gl_helper = factory->GetGLHelper();
2706     scoped_refptr<ui::Texture> new_texture;
2707     if (host_->is_accelerated_compositing_active() &&
2708         gl_helper && current_surface_.get()) {
2709       GLuint texture_id =
2710           gl_helper->CopyTexture(current_surface_->PrepareTexture(),
2711                                  current_surface_->size());
2712       if (texture_id) {
2713         new_texture = factory->CreateOwnedTexture(
2714           current_surface_->size(),
2715           current_surface_->device_scale_factor(), texture_id);
2716       }
2717     }
2718     if (new_texture.get())
2719       old_layer->SetExternalTexture(new_texture.get());
2720     else
2721       old_layer->SetShowPaintedContent();
2722     new_layer->SetExternalTexture(old_texture.get());
2723   } else if (old_mailbox.IsSharedMemory()) {
2724     base::SharedMemory* old_buffer = old_mailbox.shared_memory();
2725     const size_t size = old_mailbox.shared_memory_size_in_bytes();
2726
2727     scoped_ptr<base::SharedMemory> new_buffer(new base::SharedMemory);
2728     new_buffer->CreateAndMapAnonymous(size);
2729
2730     if (old_buffer->memory() && new_buffer->memory()) {
2731       memcpy(new_buffer->memory(), old_buffer->memory(), size);
2732       base::SharedMemory* new_buffer_raw_ptr = new_buffer.get();
2733       scoped_ptr<cc::SingleReleaseCallback> callback =
2734           cc::SingleReleaseCallback::Create(base::Bind(MailboxReleaseCallback,
2735                                                        Passed(&new_buffer)));
2736       cc::TextureMailbox new_mailbox(new_buffer_raw_ptr,
2737                                      old_mailbox.shared_memory_size());
2738       new_layer->SetTextureMailbox(new_mailbox,
2739                                    callback.Pass(),
2740                                    mailbox_scale_factor);
2741     }
2742   } else if (frame_provider_.get()) {
2743     new_layer->SetShowDelegatedContent(frame_provider_.get(),
2744                                        current_frame_size_);
2745   }
2746 }
2747
2748 ////////////////////////////////////////////////////////////////////////////////
2749 // RenderWidgetHostViewAura, ui::EventHandler implementation:
2750
2751 void RenderWidgetHostViewAura::OnKeyEvent(ui::KeyEvent* event) {
2752   TRACE_EVENT0("input", "RenderWidgetHostViewAura::OnKeyEvent");
2753   if (touch_editing_client_ && touch_editing_client_->HandleInputEvent(event))
2754     return;
2755
2756   if (popup_child_host_view_ && popup_child_host_view_->NeedsInputGrab()) {
2757     popup_child_host_view_->OnKeyEvent(event);
2758     if (event->handled())
2759       return;
2760   }
2761
2762   // We need to handle the Escape key for Pepper Flash.
2763   if (is_fullscreen_ && event->key_code() == ui::VKEY_ESCAPE) {
2764     // Focus the window we were created from.
2765     if (host_tracker_.get() && !host_tracker_->windows().empty()) {
2766       aura::Window* host = *(host_tracker_->windows().begin());
2767       aura::client::FocusClient* client = aura::client::GetFocusClient(host);
2768       if (client) {
2769         // Calling host->Focus() may delete |this|. We create a local observer
2770         // for that. In that case we exit without further access to any members.
2771         aura::WindowTracker tracker;
2772         aura::Window* window = window_;
2773         tracker.Add(window);
2774         host->Focus();
2775         if (!tracker.Contains(window)) {
2776           event->SetHandled();
2777           return;
2778         }
2779       }
2780     }
2781     if (!in_shutdown_) {
2782       in_shutdown_ = true;
2783       host_->Shutdown();
2784     }
2785   } else {
2786     if (event->key_code() == ui::VKEY_RETURN) {
2787       // Do not forward return key release events if no press event was handled.
2788       if (event->type() == ui::ET_KEY_RELEASED && !accept_return_character_)
2789         return;
2790       // Accept return key character events between press and release events.
2791       accept_return_character_ = event->type() == ui::ET_KEY_PRESSED;
2792     }
2793
2794     // We don't have to communicate with an input method here.
2795     if (!event->HasNativeEvent()) {
2796       NativeWebKeyboardEvent webkit_event(
2797           event->type(),
2798           event->is_char(),
2799           event->is_char() ? event->GetCharacter() : event->key_code(),
2800           event->flags(),
2801           ui::EventTimeForNow().InSecondsF());
2802       host_->ForwardKeyboardEvent(webkit_event);
2803     } else {
2804       NativeWebKeyboardEvent webkit_event(event);
2805       host_->ForwardKeyboardEvent(webkit_event);
2806     }
2807   }
2808   event->SetHandled();
2809 }
2810
2811 void RenderWidgetHostViewAura::OnMouseEvent(ui::MouseEvent* event) {
2812   TRACE_EVENT0("input", "RenderWidgetHostViewAura::OnMouseEvent");
2813
2814   if (touch_editing_client_ && touch_editing_client_->HandleInputEvent(event))
2815     return;
2816
2817   if (mouse_locked_) {
2818     aura::client::CursorClient* cursor_client =
2819         aura::client::GetCursorClient(window_->GetRootWindow());
2820     DCHECK(!cursor_client || !cursor_client->IsCursorVisible());
2821
2822     if (event->type() == ui::ET_MOUSEWHEEL) {
2823       blink::WebMouseWheelEvent mouse_wheel_event =
2824           MakeWebMouseWheelEvent(static_cast<ui::MouseWheelEvent*>(event));
2825       if (mouse_wheel_event.deltaX != 0 || mouse_wheel_event.deltaY != 0)
2826         host_->ForwardWheelEvent(mouse_wheel_event);
2827       return;
2828     }
2829
2830     gfx::Point center(gfx::Rect(window_->bounds().size()).CenterPoint());
2831
2832     // If we receive non client mouse messages while we are in the locked state
2833     // it probably means that the mouse left the borders of our window and
2834     // needs to be moved back to the center.
2835     if (event->flags() & ui::EF_IS_NON_CLIENT) {
2836       synthetic_move_sent_ = true;
2837       window_->MoveCursorTo(center);
2838       return;
2839     }
2840
2841     blink::WebMouseEvent mouse_event = MakeWebMouseEvent(event);
2842
2843     bool is_move_to_center_event = (event->type() == ui::ET_MOUSE_MOVED ||
2844         event->type() == ui::ET_MOUSE_DRAGGED) &&
2845         mouse_event.x == center.x() && mouse_event.y == center.y();
2846
2847     ModifyEventMovementAndCoords(&mouse_event);
2848
2849     bool should_not_forward = is_move_to_center_event && synthetic_move_sent_;
2850     if (should_not_forward) {
2851       synthetic_move_sent_ = false;
2852     } else {
2853       // Check if the mouse has reached the border and needs to be centered.
2854       if (ShouldMoveToCenter()) {
2855         synthetic_move_sent_ = true;
2856         window_->MoveCursorTo(center);
2857       }
2858       // Forward event to renderer.
2859       if (CanRendererHandleEvent(event) &&
2860           !(event->flags() & ui::EF_FROM_TOUCH)) {
2861         host_->ForwardMouseEvent(mouse_event);
2862         // Ensure that we get keyboard focus on mouse down as a plugin window
2863         // may have grabbed keyboard focus.
2864         if (event->type() == ui::ET_MOUSE_PRESSED)
2865           SetKeyboardFocus();
2866       }
2867     }
2868     return;
2869   }
2870
2871   // As the overscroll is handled during scroll events from the trackpad, the
2872   // RWHVA window is transformed by the overscroll controller. This transform
2873   // triggers a synthetic mouse-move event to be generated (by the aura
2874   // RootWindow). But this event interferes with the overscroll gesture. So,
2875   // ignore such synthetic mouse-move events if an overscroll gesture is in
2876   // progress.
2877   if (host_->overscroll_controller() &&
2878       host_->overscroll_controller()->overscroll_mode() != OVERSCROLL_NONE &&
2879       event->flags() & ui::EF_IS_SYNTHESIZED &&
2880       (event->type() == ui::ET_MOUSE_ENTERED ||
2881        event->type() == ui::ET_MOUSE_EXITED ||
2882        event->type() == ui::ET_MOUSE_MOVED)) {
2883     event->StopPropagation();
2884     return;
2885   }
2886
2887   if (event->type() == ui::ET_MOUSEWHEEL) {
2888 #if defined(OS_WIN)
2889     // We get mouse wheel/scroll messages even if we are not in the foreground.
2890     // So here we check if we have any owned popup windows in the foreground and
2891     // dismiss them.
2892     aura::WindowEventDispatcher* dispatcher = window_->GetDispatcher();
2893     if (dispatcher) {
2894       HWND parent = dispatcher->host()->GetAcceleratedWidget();
2895       HWND toplevel_hwnd = ::GetAncestor(parent, GA_ROOT);
2896       EnumThreadWindows(GetCurrentThreadId(),
2897                         DismissOwnedPopups,
2898                         reinterpret_cast<LPARAM>(toplevel_hwnd));
2899     }
2900 #endif
2901     blink::WebMouseWheelEvent mouse_wheel_event =
2902         MakeWebMouseWheelEvent(static_cast<ui::MouseWheelEvent*>(event));
2903     if (mouse_wheel_event.deltaX != 0 || mouse_wheel_event.deltaY != 0)
2904       host_->ForwardWheelEvent(mouse_wheel_event);
2905   } else if (CanRendererHandleEvent(event) &&
2906              !(event->flags() & ui::EF_FROM_TOUCH)) {
2907     blink::WebMouseEvent mouse_event = MakeWebMouseEvent(event);
2908     ModifyEventMovementAndCoords(&mouse_event);
2909     host_->ForwardMouseEvent(mouse_event);
2910     // Ensure that we get keyboard focus on mouse down as a plugin window may
2911     // have grabbed keyboard focus.
2912     if (event->type() == ui::ET_MOUSE_PRESSED)
2913       SetKeyboardFocus();
2914   }
2915
2916   switch (event->type()) {
2917     case ui::ET_MOUSE_PRESSED:
2918       window_->SetCapture();
2919       // Confirm existing composition text on mouse click events, to make sure
2920       // the input caret won't be moved with an ongoing composition text.
2921       FinishImeCompositionSession();
2922       break;
2923     case ui::ET_MOUSE_RELEASED:
2924       window_->ReleaseCapture();
2925       break;
2926     default:
2927       break;
2928   }
2929
2930   // Needed to propagate mouse event to |window_->parent()->delegate()|, but
2931   // note that it might be something other than a WebContentsViewAura instance.
2932   // TODO(pkotwicz): Find a better way of doing this.
2933   // In fullscreen mode which is typically used by flash, don't forward
2934   // the mouse events to the parent. The renderer and the plugin process
2935   // handle these events.
2936   if (!is_fullscreen_ && window_->parent()->delegate() &&
2937       !(event->flags() & ui::EF_FROM_TOUCH)) {
2938     event->ConvertLocationToTarget(window_, window_->parent());
2939     window_->parent()->delegate()->OnMouseEvent(event);
2940   }
2941
2942   if (!IsXButtonUpEvent(event))
2943     event->SetHandled();
2944 }
2945
2946 void RenderWidgetHostViewAura::OnScrollEvent(ui::ScrollEvent* event) {
2947   TRACE_EVENT0("input", "RenderWidgetHostViewAura::OnScrollEvent");
2948   if (touch_editing_client_ && touch_editing_client_->HandleInputEvent(event))
2949     return;
2950
2951   if (event->type() == ui::ET_SCROLL) {
2952 #if !defined(OS_WIN)
2953     // TODO(ananta)
2954     // Investigate if this is true for Windows 8 Metro ASH as well.
2955     if (event->finger_count() != 2)
2956       return;
2957 #endif
2958     blink::WebGestureEvent gesture_event =
2959         MakeWebGestureEventFlingCancel();
2960     host_->ForwardGestureEvent(gesture_event);
2961     blink::WebMouseWheelEvent mouse_wheel_event =
2962         MakeWebMouseWheelEvent(event);
2963     host_->ForwardWheelEvent(mouse_wheel_event);
2964     RecordAction(base::UserMetricsAction("TrackpadScroll"));
2965   } else if (event->type() == ui::ET_SCROLL_FLING_START ||
2966              event->type() == ui::ET_SCROLL_FLING_CANCEL) {
2967     blink::WebGestureEvent gesture_event =
2968         MakeWebGestureEvent(event);
2969     host_->ForwardGestureEvent(gesture_event);
2970     if (event->type() == ui::ET_SCROLL_FLING_START)
2971       RecordAction(base::UserMetricsAction("TrackpadScrollFling"));
2972   }
2973
2974   event->SetHandled();
2975 }
2976
2977 void RenderWidgetHostViewAura::OnTouchEvent(ui::TouchEvent* event) {
2978   TRACE_EVENT0("input", "RenderWidgetHostViewAura::OnTouchEvent");
2979   if (touch_editing_client_ && touch_editing_client_->HandleInputEvent(event))
2980     return;
2981
2982   // Update the touch event first.
2983   blink::WebTouchPoint* point = UpdateWebTouchEventFromUIEvent(*event,
2984                                                                 &touch_event_);
2985
2986   // Forward the touch event only if a touch point was updated, and there's a
2987   // touch-event handler in the page, and no other touch-event is in the queue.
2988   // It is important to always consume the event if there is a touch-event
2989   // handler in the page, or some touch-event is already in the queue, even if
2990   // no point has been updated, to make sure that this event does not get
2991   // processed by the gesture recognizer before the events in the queue.
2992   if (host_->ShouldForwardTouchEvent())
2993     event->StopPropagation();
2994
2995   if (point) {
2996     if (host_->ShouldForwardTouchEvent())
2997       host_->ForwardTouchEventWithLatencyInfo(touch_event_, *event->latency());
2998     UpdateWebTouchEventAfterDispatch(&touch_event_, point);
2999   }
3000 }
3001
3002 void RenderWidgetHostViewAura::OnGestureEvent(ui::GestureEvent* event) {
3003   TRACE_EVENT0("input", "RenderWidgetHostViewAura::OnGestureEvent");
3004   if ((event->type() == ui::ET_GESTURE_PINCH_BEGIN ||
3005       event->type() == ui::ET_GESTURE_PINCH_UPDATE ||
3006       event->type() == ui::ET_GESTURE_PINCH_END) && !pinch_zoom_enabled_) {
3007     event->SetHandled();
3008     return;
3009   }
3010
3011   if (touch_editing_client_ && touch_editing_client_->HandleInputEvent(event))
3012     return;
3013
3014   RenderViewHostDelegate* delegate = NULL;
3015   if (popup_type_ == blink::WebPopupTypeNone && !is_fullscreen_)
3016     delegate = RenderViewHost::From(host_)->GetDelegate();
3017
3018   if (delegate && event->type() == ui::ET_GESTURE_BEGIN &&
3019       event->details().touch_points() == 1) {
3020     delegate->HandleGestureBegin();
3021   }
3022
3023   blink::WebGestureEvent gesture = MakeWebGestureEvent(event);
3024   if (event->type() == ui::ET_GESTURE_TAP_DOWN) {
3025     // Webkit does not stop a fling-scroll on tap-down. So explicitly send an
3026     // event to stop any in-progress flings.
3027     blink::WebGestureEvent fling_cancel = gesture;
3028     fling_cancel.type = blink::WebInputEvent::GestureFlingCancel;
3029     fling_cancel.sourceDevice = blink::WebGestureEvent::Touchscreen;
3030     host_->ForwardGestureEvent(fling_cancel);
3031   }
3032
3033   if (gesture.type != blink::WebInputEvent::Undefined) {
3034     host_->ForwardGestureEventWithLatencyInfo(gesture, *event->latency());
3035
3036     if (event->type() == ui::ET_GESTURE_SCROLL_BEGIN ||
3037         event->type() == ui::ET_GESTURE_SCROLL_UPDATE ||
3038         event->type() == ui::ET_GESTURE_SCROLL_END) {
3039       RecordAction(base::UserMetricsAction("TouchscreenScroll"));
3040     } else if (event->type() == ui::ET_SCROLL_FLING_START) {
3041       RecordAction(base::UserMetricsAction("TouchscreenScrollFling"));
3042     }
3043   }
3044
3045   if (delegate && event->type() == ui::ET_GESTURE_END &&
3046       event->details().touch_points() == 1) {
3047     delegate->HandleGestureEnd();
3048   }
3049
3050   // If a gesture is not processed by the webpage, then WebKit processes it
3051   // (e.g. generates synthetic mouse events).
3052   event->SetHandled();
3053 }
3054
3055 ////////////////////////////////////////////////////////////////////////////////
3056 // RenderWidgetHostViewAura, aura::client::ActivationDelegate implementation:
3057
3058 bool RenderWidgetHostViewAura::ShouldActivate() const {
3059   aura::WindowEventDispatcher* dispatcher = window_->GetDispatcher();
3060   if (!dispatcher)
3061     return true;
3062   const ui::Event* event = dispatcher->current_event();
3063   if (!event)
3064     return true;
3065   return is_fullscreen_;
3066 }
3067
3068 ////////////////////////////////////////////////////////////////////////////////
3069 // RenderWidgetHostViewAura,
3070 //     aura::client::ActivationChangeObserver implementation:
3071
3072 void RenderWidgetHostViewAura::OnWindowActivated(aura::Window* gained_active,
3073                                                  aura::Window* lost_active) {
3074   DCHECK(window_ == gained_active || window_ == lost_active);
3075   if (window_ == gained_active) {
3076     const ui::Event* event = window_->GetDispatcher()->current_event();
3077     if (event && PointerEventActivates(*event))
3078       host_->OnPointerEventActivate();
3079   }
3080 }
3081
3082 ////////////////////////////////////////////////////////////////////////////////
3083 // RenderWidgetHostViewAura, aura::client::CursorClientObserver implementation:
3084
3085 void RenderWidgetHostViewAura::OnCursorVisibilityChanged(bool is_visible) {
3086   NotifyRendererOfCursorVisibilityState(is_visible);
3087 }
3088
3089 ////////////////////////////////////////////////////////////////////////////////
3090 // RenderWidgetHostViewAura, aura::client::FocusChangeObserver implementation:
3091
3092 void RenderWidgetHostViewAura::OnWindowFocused(aura::Window* gained_focus,
3093                                                aura::Window* lost_focus) {
3094   DCHECK(window_ == gained_focus || window_ == lost_focus);
3095   if (window_ == gained_focus) {
3096     // We need to honor input bypass if the associated tab is does not want
3097     // input. This gives the current focused window a chance to be the text
3098     // input client and handle events.
3099     if (host_->ignore_input_events())
3100       return;
3101
3102     host_->GotFocus();
3103     host_->SetActive(true);
3104
3105     ui::InputMethod* input_method = GetInputMethod();
3106     if (input_method) {
3107       // Ask the system-wide IME to send all TextInputClient messages to |this|
3108       // object.
3109       input_method->SetFocusedTextInputClient(this);
3110       host_->SetInputMethodActive(input_method->IsActive());
3111
3112       // Often the application can set focus to the view in response to a key
3113       // down. However the following char event shouldn't be sent to the web
3114       // page.
3115       host_->SuppressNextCharEvents();
3116     } else {
3117       host_->SetInputMethodActive(false);
3118     }
3119   } else if (window_ == lost_focus) {
3120     host_->SetActive(false);
3121     host_->Blur();
3122
3123     DetachFromInputMethod();
3124     host_->SetInputMethodActive(false);
3125
3126     if (touch_editing_client_)
3127       touch_editing_client_->EndTouchEditing(false);
3128
3129     // If we lose the focus while fullscreen, close the window; Pepper Flash
3130     // won't do it for us (unlike NPAPI Flash). However, we do not close the
3131     // window if we lose the focus to a window on another display.
3132     gfx::Screen* screen = gfx::Screen::GetScreenFor(window_);
3133     bool focusing_other_display =
3134         gained_focus && screen->GetNumDisplays() > 1 &&
3135         (screen->GetDisplayNearestWindow(window_).id() !=
3136          screen->GetDisplayNearestWindow(gained_focus).id());
3137     if (is_fullscreen_ && !in_shutdown_ && !focusing_other_display) {
3138 #if defined(OS_WIN)
3139       // On Windows, if we are switching to a non Aura Window on a different
3140       // screen we should not close the fullscreen window.
3141       if (!gained_focus) {
3142         POINT point = {0};
3143         ::GetCursorPos(&point);
3144         if (screen->GetDisplayNearestWindow(window_).id() !=
3145             screen->GetDisplayNearestPoint(gfx::Point(point)).id())
3146           return;
3147       }
3148 #endif
3149       in_shutdown_ = true;
3150       host_->Shutdown();
3151     }
3152   }
3153 }
3154
3155 ////////////////////////////////////////////////////////////////////////////////
3156 // RenderWidgetHostViewAura, aura::RootWindowObserver implementation:
3157
3158 void RenderWidgetHostViewAura::OnWindowTreeHostMoved(
3159     const aura::RootWindow* root,
3160     const gfx::Point& new_origin) {
3161   TRACE_EVENT1("ui", "RenderWidgetHostViewAura::OnWindowTreeHostMoved",
3162                "new_origin", new_origin.ToString());
3163
3164   UpdateScreenInfo(window_);
3165 }
3166
3167 ////////////////////////////////////////////////////////////////////////////////
3168 // RenderWidgetHostViewAura, SoftwareFrameManagerClient implementation:
3169
3170 void RenderWidgetHostViewAura::SoftwareFrameWasFreed(
3171     uint32 output_surface_id, unsigned frame_id) {
3172   ReleaseSoftwareFrame(output_surface_id, frame_id);
3173 }
3174
3175 void RenderWidgetHostViewAura::ReleaseReferencesToSoftwareFrame() {
3176   ui::Compositor* compositor = GetCompositor();
3177   if (compositor) {
3178     AddOnCommitCallbackAndDisableLocks(base::Bind(
3179         &RenderWidgetHostViewAura::SendReclaimSoftwareFrames, AsWeakPtr()));
3180   }
3181   UpdateExternalTexture();
3182 }
3183
3184 ////////////////////////////////////////////////////////////////////////////////
3185 // RenderWidgetHostViewAura, ui::CompositorObserver implementation:
3186
3187 void RenderWidgetHostViewAura::OnCompositingDidCommit(
3188     ui::Compositor* compositor) {
3189   if (can_lock_compositor_ == NO_PENDING_COMMIT) {
3190     can_lock_compositor_ = YES;
3191     if (resize_lock_.get() && resize_lock_->GrabDeferredLock())
3192       can_lock_compositor_ = YES_DID_LOCK;
3193   }
3194   RunOnCommitCallbacks();
3195   if (resize_lock_ && resize_lock_->expected_size() == current_frame_size_) {
3196     resize_lock_.reset();
3197     host_->WasResized();
3198     // We may have had a resize while we had the lock (e.g. if the lock expired,
3199     // or if the UI still gave us some resizes), so make sure we grab a new lock
3200     // if necessary.
3201     MaybeCreateResizeLock();
3202   }
3203 }
3204
3205 void RenderWidgetHostViewAura::OnCompositingStarted(
3206     ui::Compositor* compositor, base::TimeTicks start_time) {
3207   last_draw_ended_ = start_time;
3208 }
3209
3210 void RenderWidgetHostViewAura::OnCompositingEnded(
3211     ui::Compositor* compositor) {
3212 }
3213
3214 void RenderWidgetHostViewAura::OnCompositingAborted(
3215     ui::Compositor* compositor) {
3216 }
3217
3218 void RenderWidgetHostViewAura::OnCompositingLockStateChanged(
3219     ui::Compositor* compositor) {
3220   // A compositor lock that is part of a resize lock timed out. We
3221   // should display a renderer frame.
3222   if (!compositor->IsLocked() && can_lock_compositor_ == YES_DID_LOCK) {
3223     can_lock_compositor_ = NO_PENDING_RENDERER_FRAME;
3224   }
3225 }
3226
3227 void RenderWidgetHostViewAura::OnUpdateVSyncParameters(
3228     base::TimeTicks timebase,
3229     base::TimeDelta interval) {
3230   if (IsShowing()) {
3231     if (IsDeadlineSchedulingEnabled()) {
3232       // The deadline scheduler has logic to stagger the draws of the
3233       // Renderer and Browser built-in, so send it an accurate timebase.
3234       host_->UpdateVSyncParameters(timebase, interval);
3235     } else if (!last_draw_ended_.is_null()) {
3236       // For the non-deadline scheduler, we send the Renderer an offset
3237       // vsync timebase to avoid its draws racing the Browser's draws.
3238       host_->UpdateVSyncParameters(last_draw_ended_, interval);
3239     }
3240   }
3241 }
3242
3243 ////////////////////////////////////////////////////////////////////////////////
3244 // RenderWidgetHostViewAura, BrowserAccessibilityDelegate implementation:
3245
3246 void RenderWidgetHostViewAura::SetAccessibilityFocus(int acc_obj_id) {
3247   if (!host_)
3248     return;
3249
3250   host_->AccessibilitySetFocus(acc_obj_id);
3251 }
3252
3253 void RenderWidgetHostViewAura::AccessibilityDoDefaultAction(int acc_obj_id) {
3254   if (!host_)
3255     return;
3256
3257   host_->AccessibilityDoDefaultAction(acc_obj_id);
3258 }
3259
3260 void RenderWidgetHostViewAura::AccessibilityScrollToMakeVisible(
3261     int acc_obj_id, gfx::Rect subfocus) {
3262   if (!host_)
3263     return;
3264
3265   host_->AccessibilityScrollToMakeVisible(acc_obj_id, subfocus);
3266 }
3267
3268 void RenderWidgetHostViewAura::AccessibilityScrollToPoint(
3269     int acc_obj_id, gfx::Point point) {
3270   if (!host_)
3271     return;
3272
3273   host_->AccessibilityScrollToPoint(acc_obj_id, point);
3274 }
3275
3276 void RenderWidgetHostViewAura::AccessibilitySetTextSelection(
3277     int acc_obj_id, int start_offset, int end_offset) {
3278   if (!host_)
3279     return;
3280
3281   host_->AccessibilitySetTextSelection(
3282       acc_obj_id, start_offset, end_offset);
3283 }
3284
3285 gfx::Point RenderWidgetHostViewAura::GetLastTouchEventLocation() const {
3286   // Only needed for Win 8 non-aura.
3287   return gfx::Point();
3288 }
3289
3290 void RenderWidgetHostViewAura::FatalAccessibilityTreeError() {
3291   host_->FatalAccessibilityTreeError();
3292   SetBrowserAccessibilityManager(NULL);
3293 }
3294
3295 ////////////////////////////////////////////////////////////////////////////////
3296 // RenderWidgetHostViewAura, ImageTransportFactoryObserver implementation:
3297
3298 void RenderWidgetHostViewAura::OnLostResources() {
3299   current_surface_ = NULL;
3300   UpdateExternalTexture();
3301
3302   idle_frame_subscriber_textures_.clear();
3303   yuv_readback_pipeline_.reset();
3304
3305   // Make sure all ImageTransportClients are deleted now that the context those
3306   // are using is becoming invalid. This sends pending ACKs and needs to happen
3307   // after calling UpdateExternalTexture() which syncs with the impl thread.
3308   RunOnCommitCallbacks();
3309   host_->ScheduleComposite();
3310 }
3311
3312 ////////////////////////////////////////////////////////////////////////////////
3313 // RenderWidgetHostViewAura, private:
3314
3315 RenderWidgetHostViewAura::~RenderWidgetHostViewAura() {
3316   if (touch_editing_client_)
3317     touch_editing_client_->OnViewDestroyed();
3318
3319   ImageTransportFactory::GetInstance()->RemoveObserver(this);
3320
3321   window_observer_.reset();
3322   if (window_->GetDispatcher())
3323     window_->GetDispatcher()->RemoveRootWindowObserver(this);
3324   UnlockMouse();
3325   if (popup_parent_host_view_) {
3326     DCHECK(popup_parent_host_view_->popup_child_host_view_ == NULL ||
3327            popup_parent_host_view_->popup_child_host_view_ == this);
3328     popup_parent_host_view_->popup_child_host_view_ = NULL;
3329   }
3330   if (popup_child_host_view_) {
3331     DCHECK(popup_child_host_view_->popup_parent_host_view_ == NULL ||
3332            popup_child_host_view_->popup_parent_host_view_ == this);
3333     popup_child_host_view_->popup_parent_host_view_ = NULL;
3334   }
3335   event_filter_for_popup_exit_.reset();
3336   aura::client::SetTooltipText(window_, NULL);
3337   gfx::Screen::GetScreenFor(window_)->RemoveObserver(this);
3338
3339   // This call is usually no-op since |this| object is already removed from the
3340   // Aura root window and we don't have a way to get an input method object
3341   // associated with the window, but just in case.
3342   DetachFromInputMethod();
3343
3344   if (resource_collection_.get())
3345     resource_collection_->SetClient(NULL);
3346
3347   // An OwnedMailbox should not refer to the GLHelper anymore once the RWHVA is
3348   // destroyed, as it may then outlive the GLHelper.
3349   for (std::set<OwnedMailbox*>::iterator it =
3350            active_frame_subscriber_textures_.begin();
3351        it != active_frame_subscriber_textures_.end();
3352        ++it) {
3353     (*it)->Destroy();
3354   }
3355   active_frame_subscriber_textures_.clear();
3356
3357 #if defined(OS_WIN)
3358   legacy_render_widget_host_HWND_.reset(NULL);
3359 #endif
3360
3361   DCHECK(!vsync_manager_);
3362 }
3363
3364 void RenderWidgetHostViewAura::UpdateCursorIfOverSelf() {
3365   const gfx::Point screen_point =
3366       gfx::Screen::GetScreenFor(GetNativeView())->GetCursorScreenPoint();
3367   aura::Window* root_window = window_->GetRootWindow();
3368   if (!root_window)
3369     return;
3370
3371   gfx::Point root_window_point = screen_point;
3372   aura::client::ScreenPositionClient* screen_position_client =
3373       aura::client::GetScreenPositionClient(root_window);
3374   if (screen_position_client) {
3375     screen_position_client->ConvertPointFromScreen(
3376         root_window, &root_window_point);
3377   }
3378
3379   if (root_window->GetEventHandlerForPoint(root_window_point) != window_)
3380     return;
3381
3382   gfx::NativeCursor cursor = current_cursor_.GetNativeCursor();
3383   // Do not show loading cursor when the cursor is currently hidden.
3384   if (is_loading_ && cursor != ui::kCursorNone)
3385     cursor = ui::kCursorPointer;
3386
3387   aura::client::CursorClient* cursor_client =
3388       aura::client::GetCursorClient(root_window);
3389   if (cursor_client) {
3390     cursor_client->SetCursor(cursor);
3391   }
3392 }
3393
3394 ui::InputMethod* RenderWidgetHostViewAura::GetInputMethod() const {
3395   aura::Window* root_window = window_->GetRootWindow();
3396   if (!root_window)
3397     return NULL;
3398   return root_window->GetProperty(aura::client::kRootWindowInputMethodKey);
3399 }
3400
3401 bool RenderWidgetHostViewAura::NeedsInputGrab() {
3402   return popup_type_ == blink::WebPopupTypeSelect;
3403 }
3404
3405 void RenderWidgetHostViewAura::FinishImeCompositionSession() {
3406   if (!has_composition_text_)
3407     return;
3408   if (host_) {
3409     host_->ImeConfirmComposition(base::string16(), gfx::Range::InvalidRange(),
3410                                  false);
3411   }
3412   ImeCancelComposition();
3413 }
3414
3415 void RenderWidgetHostViewAura::ModifyEventMovementAndCoords(
3416     blink::WebMouseEvent* event) {
3417   // If the mouse has just entered, we must report zero movementX/Y. Hence we
3418   // reset any global_mouse_position set previously.
3419   if (event->type == blink::WebInputEvent::MouseEnter ||
3420       event->type == blink::WebInputEvent::MouseLeave)
3421     global_mouse_position_.SetPoint(event->globalX, event->globalY);
3422
3423   // Movement is computed by taking the difference of the new cursor position
3424   // and the previous. Under mouse lock the cursor will be warped back to the
3425   // center so that we are not limited by clipping boundaries.
3426   // We do not measure movement as the delta from cursor to center because
3427   // we may receive more mouse movement events before our warp has taken
3428   // effect.
3429   event->movementX = event->globalX - global_mouse_position_.x();
3430   event->movementY = event->globalY - global_mouse_position_.y();
3431
3432   global_mouse_position_.SetPoint(event->globalX, event->globalY);
3433
3434   // Under mouse lock, coordinates of mouse are locked to what they were when
3435   // mouse lock was entered.
3436   if (mouse_locked_) {
3437     event->x = unlocked_mouse_position_.x();
3438     event->y = unlocked_mouse_position_.y();
3439     event->windowX = unlocked_mouse_position_.x();
3440     event->windowY = unlocked_mouse_position_.y();
3441     event->globalX = unlocked_global_mouse_position_.x();
3442     event->globalY = unlocked_global_mouse_position_.y();
3443   } else {
3444     unlocked_mouse_position_.SetPoint(event->windowX, event->windowY);
3445     unlocked_global_mouse_position_.SetPoint(event->globalX, event->globalY);
3446   }
3447 }
3448
3449 void RenderWidgetHostViewAura::NotifyRendererOfCursorVisibilityState(
3450     bool is_visible) {
3451   if (host_->is_hidden() ||
3452       (cursor_visibility_state_in_renderer_ == VISIBLE && is_visible) ||
3453       (cursor_visibility_state_in_renderer_ == NOT_VISIBLE && !is_visible))
3454     return;
3455
3456   cursor_visibility_state_in_renderer_ = is_visible ? VISIBLE : NOT_VISIBLE;
3457   host_->SendCursorVisibilityState(is_visible);
3458 }
3459
3460 void RenderWidgetHostViewAura::SchedulePaintIfNotInClip(
3461     const gfx::Rect& rect,
3462     const gfx::Rect& clip) {
3463   if (!clip.IsEmpty()) {
3464     gfx::Rect to_paint = gfx::SubtractRects(rect, clip);
3465     if (!to_paint.IsEmpty())
3466       window_->SchedulePaintInRect(to_paint);
3467   } else {
3468     window_->SchedulePaintInRect(rect);
3469   }
3470 }
3471
3472 bool RenderWidgetHostViewAura::ShouldMoveToCenter() {
3473   gfx::Rect rect = window_->bounds();
3474   rect = ConvertRectToScreen(rect);
3475   int border_x = rect.width() * kMouseLockBorderPercentage / 100;
3476   int border_y = rect.height() * kMouseLockBorderPercentage / 100;
3477
3478   return global_mouse_position_.x() < rect.x() + border_x ||
3479       global_mouse_position_.x() > rect.right() - border_x ||
3480       global_mouse_position_.y() < rect.y() + border_y ||
3481       global_mouse_position_.y() > rect.bottom() - border_y;
3482 }
3483
3484 void RenderWidgetHostViewAura::RunOnCommitCallbacks() {
3485   for (std::vector<base::Closure>::const_iterator
3486       it = on_compositing_did_commit_callbacks_.begin();
3487       it != on_compositing_did_commit_callbacks_.end(); ++it) {
3488     it->Run();
3489   }
3490   on_compositing_did_commit_callbacks_.clear();
3491 }
3492
3493 void RenderWidgetHostViewAura::AddOnCommitCallbackAndDisableLocks(
3494     const base::Closure& callback) {
3495   ui::Compositor* compositor = GetCompositor();
3496   DCHECK(compositor);
3497
3498   if (!compositor->HasObserver(this))
3499     compositor->AddObserver(this);
3500
3501   can_lock_compositor_ = NO_PENDING_COMMIT;
3502   on_compositing_did_commit_callbacks_.push_back(callback);
3503 }
3504
3505 void RenderWidgetHostViewAura::AddedToRootWindow() {
3506   window_->GetDispatcher()->AddRootWindowObserver(this);
3507   UpdateScreenInfo(window_);
3508
3509   aura::client::CursorClient* cursor_client =
3510       aura::client::GetCursorClient(window_->GetRootWindow());
3511   if (cursor_client) {
3512     cursor_client->AddObserver(this);
3513     NotifyRendererOfCursorVisibilityState(cursor_client->IsCursorVisible());
3514   }
3515   if (current_surface_.get())
3516     UpdateExternalTexture();
3517   if (HasFocus()) {
3518     ui::InputMethod* input_method = GetInputMethod();
3519     if (input_method)
3520       input_method->SetFocusedTextInputClient(this);
3521   }
3522
3523 #if defined(OS_WIN)
3524   // The parent may have changed here. Ensure that the legacy window is
3525   // reparented accordingly.
3526   if (legacy_render_widget_host_HWND_)
3527     legacy_render_widget_host_HWND_->UpdateParent(
3528         reinterpret_cast<HWND>(GetNativeViewId()));
3529 #endif
3530
3531   ui::Compositor* compositor = GetCompositor();
3532   if (compositor) {
3533     DCHECK(!vsync_manager_);
3534     vsync_manager_ = compositor->vsync_manager();
3535     vsync_manager_->AddObserver(this);
3536   }
3537 }
3538
3539 void RenderWidgetHostViewAura::RemovingFromRootWindow() {
3540   aura::client::CursorClient* cursor_client =
3541       aura::client::GetCursorClient(window_->GetRootWindow());
3542   if (cursor_client)
3543     cursor_client->RemoveObserver(this);
3544
3545   DetachFromInputMethod();
3546
3547   window_->GetDispatcher()->RemoveRootWindowObserver(this);
3548   ui::Compositor* compositor = GetCompositor();
3549   if (current_surface_.get()) {
3550     // We can't get notification for commits after this point, which would
3551     // guarantee that the compositor isn't using an old texture any more, so
3552     // instead we force the layer to stop using any external resources which
3553     // synchronizes with the compositor thread, and makes it safe to run the
3554     // callback.
3555     window_->layer()->SetShowPaintedContent();
3556   }
3557   RunOnCommitCallbacks();
3558   resize_lock_.reset();
3559   host_->WasResized();
3560
3561   if (compositor && compositor->HasObserver(this))
3562     compositor->RemoveObserver(this);
3563
3564 #if defined(OS_WIN)
3565   // Update the legacy window's parent temporarily to the desktop window. It
3566   // will eventually get reparented to the right root.
3567   if (legacy_render_widget_host_HWND_)
3568     legacy_render_widget_host_HWND_->UpdateParent(::GetDesktopWindow());
3569 #endif
3570
3571   if (vsync_manager_) {
3572     vsync_manager_->RemoveObserver(this);
3573     vsync_manager_ = NULL;
3574   }
3575 }
3576
3577 ui::Compositor* RenderWidgetHostViewAura::GetCompositor() const {
3578   aura::WindowEventDispatcher* dispatcher = window_->GetDispatcher();
3579   return dispatcher ? dispatcher->host()->compositor() : NULL;
3580 }
3581
3582 void RenderWidgetHostViewAura::DetachFromInputMethod() {
3583   ui::InputMethod* input_method = GetInputMethod();
3584   if (input_method && input_method->GetTextInputClient() == this)
3585     input_method->SetFocusedTextInputClient(NULL);
3586 }
3587
3588 void RenderWidgetHostViewAura::LockResources() {
3589   DCHECK(frame_provider_);
3590   delegated_frame_evictor_->LockFrame();
3591 }
3592
3593 void RenderWidgetHostViewAura::UnlockResources() {
3594   DCHECK(frame_provider_);
3595   delegated_frame_evictor_->UnlockFrame();
3596 }
3597
3598 ////////////////////////////////////////////////////////////////////////////////
3599 // RenderWidgetHostView, public:
3600
3601 // static
3602 RenderWidgetHostView* RenderWidgetHostView::CreateViewForWidget(
3603     RenderWidgetHost* widget) {
3604   return new RenderWidgetHostViewAura(widget);
3605 }
3606
3607 // static
3608 void RenderWidgetHostViewPort::GetDefaultScreenInfo(WebScreenInfo* results) {
3609   GetScreenInfoForWindow(results, NULL);
3610 }
3611
3612 }  // namespace content