Home | History | Annotate | Download | only in renderer_host
      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 
     90 using gfx::RectToSkIRect;
     91 using gfx::SkIRectToRect;
     92 
     93 using blink::WebScreenInfo;
     94 using blink::WebTouchEvent;
     95 
     96 namespace content {
     97 
     98 namespace {
     99 
    100 void 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.
    112 const 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.
    118 const int kResizeLockTimeoutMs = 67;
    119 
    120 #if defined(OS_WIN)
    121 // Used to associate a plugin HWND with its RenderWidgetHostViewAura instance.
    122 const wchar_t kWidgetOwnerProperty[] = L"RenderWidgetHostViewAuraOwner";
    123 
    124 BOOL 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 
    135 BOOL 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 
    143 BOOL 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 
    156 struct 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.
    166 BOOL 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.
    215 BOOL 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 
    229 void 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 
    242 bool 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.
    276 bool 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 
    287 void 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 
    299 bool 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 
    310 bool 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.
    324 void 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 
    354 void 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.
    381 class 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 
    409 void 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.
    432 class 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 
    463 RenderWidgetHostViewAura::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 
    507 void RenderWidgetHostViewAura::InitAsChild(
    508     gfx::NativeView parent_view) {
    509   window_->Init(ui::LAYER_TEXTURED);
    510   window_->SetName("RenderWidgetHostViewAura");
    511 }
    512 
    513 void 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 
    545 void 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 
    572 RenderWidgetHost* RenderWidgetHostViewAura::GetRenderWidgetHost() const {
    573   return host_;
    574 }
    575 
    576 void 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 
    612 void 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 
    634 void 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 
    641 void 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 
    659 void 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 
    680 bool 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 
    715 scoped_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 
    725 gfx::NativeView RenderWidgetHostViewAura::GetNativeView() const {
    726   return window_;
    727 }
    728 
    729 gfx::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 
    739 gfx::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 
    756 BrowserAccessibilityManager*
    757 RenderWidgetHostViewAura::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 
    787 void 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 
    797 void 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 
    851 void 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 
    860 void RenderWidgetHostViewAura::Blur() {
    861   window_->Blur();
    862 }
    863 
    864 bool RenderWidgetHostViewAura::HasFocus() const {
    865   return window_->HasFocus();
    866 }
    867 
    868 bool RenderWidgetHostViewAura::IsSurfaceAvailableForCopy() const {
    869   return CanCopyToBitmap() || !!host_->GetBackingStore(false);
    870 }
    871 
    872 void RenderWidgetHostViewAura::Show() {
    873   window_->Show();
    874   WasShown();
    875 }
    876 
    877 void RenderWidgetHostViewAura::Hide() {
    878   window_->Hide();
    879   WasHidden();
    880 }
    881 
    882 bool RenderWidgetHostViewAura::IsShowing() {
    883   return window_->IsVisible();
    884 }
    885 
    886 gfx::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 
    897 void RenderWidgetHostViewAura::SetBackground(const SkBitmap& background) {
    898   RenderWidgetHostViewBase::SetBackground(background);
    899   host_->SetBackground(background);
    900   window_->layer()->SetFillsBoundsOpaquely(background.isOpaque());
    901 }
    902 
    903 void 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 
    911 void 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 
    918 void 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 
    935 void RenderWidgetHostViewAura::ImeCancelComposition() {
    936   if (GetInputMethod())
    937     GetInputMethod()->CancelComposition(this);
    938   has_composition_text_ = false;
    939 }
    940 
    941 void RenderWidgetHostViewAura::ImeCompositionRangeChanged(
    942     const gfx::Range& range,
    943     const std::vector<gfx::Rect>& character_bounds) {
    944   composition_character_bounds_ = character_bounds;
    945 }
    946 
    947 void 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 
    999 void RenderWidgetHostViewAura::RenderProcessGone(base::TerminationStatus status,
   1000                                                  int error_code) {
   1001   UpdateCursorIfOverSelf();
   1002   Destroy();
   1003 }
   1004 
   1005 void 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 
   1013 void 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 
   1026 void 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 
   1043 void 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 
   1061 void 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 
   1071 BackingStore* RenderWidgetHostViewAura::AllocBackingStore(
   1072     const gfx::Size& size) {
   1073   return new BackingStoreAura(host_, size);
   1074 }
   1075 
   1076 void 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 
   1097 void 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 
   1136 bool RenderWidgetHostViewAura::CanCopyToBitmap() const {
   1137   return GetCompositor() && window_->layer()->has_external_content();
   1138 }
   1139 
   1140 bool RenderWidgetHostViewAura::CanCopyToVideoFrame() const {
   1141   return GetCompositor() &&
   1142          window_->layer()->has_external_content() &&
   1143          host_->is_accelerated_compositing_active();
   1144 }
   1145 
   1146 bool RenderWidgetHostViewAura::CanSubscribeFrame() const {
   1147   return true;
   1148 }
   1149 
   1150 void RenderWidgetHostViewAura::BeginFrameSubscription(
   1151     scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber) {
   1152   frame_subscriber_ = subscriber.Pass();
   1153 }
   1154 
   1155 void RenderWidgetHostViewAura::EndFrameSubscription() {
   1156   idle_frame_subscriber_textures_.clear();
   1157   frame_subscriber_.reset();
   1158 }
   1159 
   1160 void 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 
   1172 void RenderWidgetHostViewAura::AcceleratedSurfaceInitialized(int host_id,
   1173                                                              int route_id) {
   1174 }
   1175 
   1176 bool 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 
   1185 void 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 
   1224 void 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 
   1239 void 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 
   1272 bool 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 
   1311 void 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 
   1325 void 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)
   1341 void 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 
   1363 void 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 
   1379 void 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 
   1491 void 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 
   1503 void RenderWidgetHostViewAura::UnusedResourcesAreAvailable() {
   1504   if (pending_delegated_ack_count_)
   1505     return;
   1506 
   1507   SendReturnedDelegatedResources(last_output_surface_id_);
   1508 }
   1509 
   1510 void 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 
   1523 void RenderWidgetHostViewAura::EvictDelegatedFrame() {
   1524   window_->layer()->SetShowPaintedContent();
   1525   frame_provider_ = NULL;
   1526   delegated_frame_evictor_->DiscardedFrame();
   1527 }
   1528 
   1529 void 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 
   1592 void 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 
   1608 void 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 
   1621 void 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 
   1630 void 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)
   1679 void RenderWidgetHostViewAura::SetParentNativeViewAccessible(
   1680     gfx::NativeViewAccessible accessible_parent) {
   1681   if (GetBrowserAccessibilityManager()) {
   1682     GetBrowserAccessibilityManager()->ToBrowserAccessibilityManagerWin()
   1683         ->set_parent_iaccessible(accessible_parent);
   1684   }
   1685 }
   1686 
   1687 gfx::NativeViewId RenderWidgetHostViewAura::GetParentForWindowlessPlugin()
   1688     const {
   1689   return reinterpret_cast<gfx::NativeViewId>(plugin_parent_window_);
   1690 }
   1691 #endif
   1692 
   1693 void 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 
   1764 void 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 
   1784 void RenderWidgetHostViewAura::AcceleratedSurfaceSuspend() {
   1785 }
   1786 
   1787 void 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 
   1805 bool 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 
   1813 void RenderWidgetHostViewAura::SetSurfaceNotInUseByCompositor(
   1814     scoped_refptr<ui::Texture>) {
   1815 }
   1816 
   1817 // static
   1818 void 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 
   1836 static 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
   1848 void 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
   1899 void 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 
   1925 void 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
   1950 void 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 
   2074 void RenderWidgetHostViewAura::GetScreenInfo(WebScreenInfo* results) {
   2075   GetScreenInfoForWindow(results, window_->GetRootWindow() ? window_ : NULL);
   2076 }
   2077 
   2078 gfx::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 
   2107 void 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 
   2113 void 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 
   2133 scoped_ptr<SyntheticGestureTarget>
   2134 RenderWidgetHostViewAura::CreateSyntheticGestureTarget() {
   2135   return scoped_ptr<SyntheticGestureTarget>(
   2136       new SyntheticGestureTargetAura(host_));
   2137 }
   2138 
   2139 void RenderWidgetHostViewAura::SetHasHorizontalScrollbar(
   2140     bool has_horizontal_scrollbar) {
   2141   // Not needed. Mac-only.
   2142 }
   2143 
   2144 void RenderWidgetHostViewAura::SetScrollOffsetPinning(
   2145     bool is_pinned_to_left, bool is_pinned_to_right) {
   2146   // Not needed. Mac-only.
   2147 }
   2148 
   2149 void RenderWidgetHostViewAura::OnAccessibilityEvents(
   2150     const std::vector<AccessibilityHostMsg_EventParams>& params) {
   2151   BrowserAccessibilityManager* manager =
   2152       GetOrCreateBrowserAccessibilityManager();
   2153   if (manager)
   2154     manager->OnAccessibilityEvents(params);
   2155 }
   2156 
   2157 gfx::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 
   2167 bool 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 
   2197 void 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:
   2224 void 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 
   2250 void 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 
   2258 void RenderWidgetHostViewAura::ClearCompositionText() {
   2259   if (host_ && has_composition_text_)
   2260     host_->ImeCancelComposition();
   2261   has_composition_text_ = false;
   2262 }
   2263 
   2264 void 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 
   2271 void 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 
   2290 gfx::NativeWindow RenderWidgetHostViewAura::GetAttachedWindow() const {
   2291   return window_;
   2292 }
   2293 
   2294 ui::TextInputType RenderWidgetHostViewAura::GetTextInputType() const {
   2295   return text_input_type_;
   2296 }
   2297 
   2298 ui::TextInputMode RenderWidgetHostViewAura::GetTextInputMode() const {
   2299   return text_input_mode_;
   2300 }
   2301 
   2302 bool RenderWidgetHostViewAura::CanComposeInline() const {
   2303   return can_compose_inline_;
   2304 }
   2305 
   2306 gfx::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 
   2326 gfx::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 
   2346 gfx::Rect RenderWidgetHostViewAura::GetCaretBounds() const {
   2347   const gfx::Rect rect =
   2348       gfx::UnionRects(selection_anchor_rect_, selection_focus_rect_);
   2349   return ConvertRectToScreen(rect);
   2350 }
   2351 
   2352 bool 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 
   2362 bool RenderWidgetHostViewAura::HasCompositionText() const {
   2363   return has_composition_text_;
   2364 }
   2365 
   2366 bool 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 
   2372 bool 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 
   2379 bool 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 
   2385 bool 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 
   2391 bool 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 
   2397 bool 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 
   2418 void 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 
   2429 bool 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 
   2441 void RenderWidgetHostViewAura::ExtendSelectionAndDelete(
   2442     size_t before, size_t after) {
   2443   if (host_)
   2444     host_->ExtendSelectionAndDelete(before, after);
   2445 }
   2446 
   2447 void 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 
   2458 void RenderWidgetHostViewAura::OnCandidateWindowShown() {
   2459   host_->CandidateWindowShown();
   2460 }
   2461 
   2462 void RenderWidgetHostViewAura::OnCandidateWindowUpdated() {
   2463   host_->CandidateWindowUpdated();
   2464 }
   2465 
   2466 void RenderWidgetHostViewAura::OnCandidateWindowHidden() {
   2467   host_->CandidateWindowHidden();
   2468 }
   2469 
   2470 ////////////////////////////////////////////////////////////////////////////////
   2471 // RenderWidgetHostViewAura, gfx::DisplayObserver implementation:
   2472 
   2473 void 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 
   2483 void RenderWidgetHostViewAura::OnDisplayAdded(
   2484     const gfx::Display& new_display) {
   2485 }
   2486 
   2487 void RenderWidgetHostViewAura::OnDisplayRemoved(
   2488     const gfx::Display& old_display) {
   2489 }
   2490 
   2491 ////////////////////////////////////////////////////////////////////////////////
   2492 // RenderWidgetHostViewAura, aura::WindowDelegate implementation:
   2493 
   2494 gfx::Size RenderWidgetHostViewAura::GetMinimumSize() const {
   2495   return gfx::Size();
   2496 }
   2497 
   2498 gfx::Size RenderWidgetHostViewAura::GetMaximumSize() const {
   2499   return gfx::Size();
   2500 }
   2501 
   2502 void 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 
   2512 gfx::NativeCursor RenderWidgetHostViewAura::GetCursor(const gfx::Point& point) {
   2513   if (mouse_locked_)
   2514     return ui::kCursorNone;
   2515   return current_cursor_.GetNativeCursor();
   2516 }
   2517 
   2518 int RenderWidgetHostViewAura::GetNonClientComponent(
   2519     const gfx::Point& point) const {
   2520   return HTCLIENT;
   2521 }
   2522 
   2523 bool RenderWidgetHostViewAura::ShouldDescendIntoChildForEventHandling(
   2524     aura::Window* child,
   2525     const gfx::Point& location) {
   2526   return true;
   2527 }
   2528 
   2529 bool RenderWidgetHostViewAura::CanFocus() {
   2530   return popup_type_ == blink::WebPopupTypeNone;
   2531 }
   2532 
   2533 void RenderWidgetHostViewAura::OnCaptureLost() {
   2534   host_->LostCapture();
   2535   if (touch_editing_client_)
   2536     touch_editing_client_->EndTouchEditing();
   2537 }
   2538 
   2539 void 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 
   2564 void 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 
   2582 void 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 
   2604 void RenderWidgetHostViewAura::OnWindowDestroyed() {
   2605   host_->ViewDestroyed();
   2606   delete this;
   2607 }
   2608 
   2609 void RenderWidgetHostViewAura::OnWindowTargetVisibilityChanged(bool visible) {
   2610 }
   2611 
   2612 bool RenderWidgetHostViewAura::HasHitTestMask() const {
   2613   return false;
   2614 }
   2615 
   2616 void RenderWidgetHostViewAura::GetHitTestMask(gfx::Path* mask) const {
   2617 }
   2618 
   2619 void 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 
   2676 void 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 
   2736 void 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 
   2868 void 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 
   2899 void 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 
   2924 void 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 
   2981 bool 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 
   2995 void 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 
   3008 void RenderWidgetHostViewAura::OnCursorVisibilityChanged(bool is_visible) {
   3009   NotifyRendererOfCursorVisibilityState(is_visible);
   3010 }
   3011 
   3012 ////////////////////////////////////////////////////////////////////////////////
   3013 // RenderWidgetHostViewAura, aura::client::FocusChangeObserver implementation:
   3014 
   3015 void 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 
   3081 void 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 
   3093 void RenderWidgetHostViewAura::SoftwareFrameWasFreed(
   3094     uint32 output_surface_id, unsigned frame_id) {
   3095   ReleaseSoftwareFrame(output_surface_id, frame_id);
   3096 }
   3097 
   3098 void 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 
   3110 void 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 
   3128 void RenderWidgetHostViewAura::OnCompositingStarted(
   3129     ui::Compositor* compositor, base::TimeTicks start_time) {
   3130   last_draw_ended_ = start_time;
   3131 }
   3132 
   3133 void RenderWidgetHostViewAura::OnCompositingEnded(
   3134     ui::Compositor* compositor) {
   3135   if (paint_observer_)
   3136     paint_observer_->OnCompositingComplete();
   3137 }
   3138 
   3139 void RenderWidgetHostViewAura::OnCompositingAborted(
   3140     ui::Compositor* compositor) {
   3141 }
   3142 
   3143 void 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 
   3152 void 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 
   3172 void RenderWidgetHostViewAura::SetAccessibilityFocus(int acc_obj_id) {
   3173   if (!host_)
   3174     return;
   3175 
   3176   host_->AccessibilitySetFocus(acc_obj_id);
   3177 }
   3178 
   3179 void RenderWidgetHostViewAura::AccessibilityDoDefaultAction(int acc_obj_id) {
   3180   if (!host_)
   3181     return;
   3182 
   3183   host_->AccessibilityDoDefaultAction(acc_obj_id);
   3184 }
   3185 
   3186 void 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 
   3194 void 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 
   3202 void 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 
   3211 gfx::Point RenderWidgetHostViewAura::GetLastTouchEventLocation() const {
   3212   // Only needed for Win 8 non-aura.
   3213   return gfx::Point();
   3214 }
   3215 
   3216 void RenderWidgetHostViewAura::FatalAccessibilityTreeError() {
   3217   host_->FatalAccessibilityTreeError();
   3218   SetBrowserAccessibilityManager(NULL);
   3219 }
   3220 
   3221 ////////////////////////////////////////////////////////////////////////////////
   3222 // RenderWidgetHostViewAura, ImageTransportFactoryObserver implementation:
   3223 
   3224 void 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 
   3246 RenderWidgetHostViewAura::~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 
   3287 void 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 
   3322 ui::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 
   3329 bool RenderWidgetHostViewAura::NeedsInputGrab() {
   3330   return popup_type_ == blink::WebPopupTypeSelect;
   3331 }
   3332 
   3333 void 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 
   3343 void 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 
   3377 void 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 
   3388 void 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 
   3400 bool 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 
   3412 void 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 
   3421 void 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 
   3433 void 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 
   3455 void 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 
   3482 ui::Compositor* RenderWidgetHostViewAura::GetCompositor() const {
   3483   aura::WindowEventDispatcher* dispatcher = window_->GetDispatcher();
   3484   return dispatcher ? dispatcher->compositor() : NULL;
   3485 }
   3486 
   3487 void 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
   3497 RenderWidgetHostView* RenderWidgetHostView::CreateViewForWidget(
   3498     RenderWidgetHost* widget) {
   3499   return new RenderWidgetHostViewAura(widget);
   3500 }
   3501 
   3502 // static
   3503 void RenderWidgetHostViewPort::GetDefaultScreenInfo(WebScreenInfo* results) {
   3504   GetScreenInfoForWindow(results, NULL);
   3505 }
   3506 
   3507 }  // namespace content
   3508