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