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