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