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_android.h"
      6 
      7 #include <android/bitmap.h>
      8 
      9 #include "base/android/sys_utils.h"
     10 #include "base/basictypes.h"
     11 #include "base/bind.h"
     12 #include "base/callback_helpers.h"
     13 #include "base/command_line.h"
     14 #include "base/logging.h"
     15 #include "base/message_loop/message_loop.h"
     16 #include "base/metrics/histogram.h"
     17 #include "base/strings/utf_string_conversions.h"
     18 #include "base/threading/worker_pool.h"
     19 #include "cc/base/latency_info_swap_promise.h"
     20 #include "cc/layers/delegated_frame_provider.h"
     21 #include "cc/layers/delegated_renderer_layer.h"
     22 #include "cc/layers/layer.h"
     23 #include "cc/output/compositor_frame.h"
     24 #include "cc/output/compositor_frame_ack.h"
     25 #include "cc/output/copy_output_request.h"
     26 #include "cc/output/copy_output_result.h"
     27 #include "cc/resources/single_release_callback.h"
     28 #include "cc/trees/layer_tree_host.h"
     29 #include "content/browser/accessibility/browser_accessibility_manager_android.h"
     30 #include "content/browser/android/content_view_core_impl.h"
     31 #include "content/browser/android/in_process/synchronous_compositor_impl.h"
     32 #include "content/browser/android/overscroll_glow.h"
     33 #include "content/browser/devtools/render_view_devtools_agent_host.h"
     34 #include "content/browser/gpu/compositor_util.h"
     35 #include "content/browser/gpu/gpu_data_manager_impl.h"
     36 #include "content/browser/gpu/gpu_process_host_ui_shim.h"
     37 #include "content/browser/gpu/gpu_surface_tracker.h"
     38 #include "content/browser/media/media_web_contents_observer.h"
     39 #include "content/browser/renderer_host/compositor_impl_android.h"
     40 #include "content/browser/renderer_host/dip_util.h"
     41 #include "content/browser/renderer_host/image_transport_factory_android.h"
     42 #include "content/browser/renderer_host/input/synthetic_gesture_target_android.h"
     43 #include "content/browser/renderer_host/input/web_input_event_builders_android.h"
     44 #include "content/browser/renderer_host/input/web_input_event_util.h"
     45 #include "content/browser/renderer_host/render_process_host_impl.h"
     46 #include "content/browser/renderer_host/render_view_host_impl.h"
     47 #include "content/browser/renderer_host/render_widget_host_impl.h"
     48 #include "content/common/gpu/client/gl_helper.h"
     49 #include "content/common/gpu/gpu_messages.h"
     50 #include "content/common/input/did_overscroll_params.h"
     51 #include "content/common/input_messages.h"
     52 #include "content/common/view_messages.h"
     53 #include "content/public/browser/browser_thread.h"
     54 #include "content/public/browser/devtools_agent_host.h"
     55 #include "content/public/browser/render_view_host.h"
     56 #include "content/public/common/content_switches.h"
     57 #include "gpu/command_buffer/client/gles2_interface.h"
     58 #include "gpu/config/gpu_driver_bug_workaround_type.h"
     59 #include "skia/ext/image_operations.h"
     60 #include "third_party/khronos/GLES2/gl2.h"
     61 #include "third_party/khronos/GLES2/gl2ext.h"
     62 #include "third_party/skia/include/core/SkCanvas.h"
     63 #include "ui/base/android/window_android.h"
     64 #include "ui/base/android/window_android_compositor.h"
     65 #include "ui/events/gesture_detection/gesture_config_helper.h"
     66 #include "ui/events/gesture_detection/motion_event.h"
     67 #include "ui/gfx/android/device_display_info.h"
     68 #include "ui/gfx/android/java_bitmap.h"
     69 #include "ui/gfx/display.h"
     70 #include "ui/gfx/screen.h"
     71 #include "ui/gfx/size_conversions.h"
     72 
     73 namespace content {
     74 
     75 namespace {
     76 
     77 const int kUndefinedOutputSurfaceId = -1;
     78 
     79 // Used to accomodate finite precision when comparing scaled viewport and
     80 // content widths. While this value may seem large, width=device-width on an N7
     81 // V1 saw errors of ~0.065 between computed window and content widths.
     82 const float kMobileViewportWidthEpsilon = 0.15f;
     83 
     84 static const char kAsyncReadBackString[] = "Compositing.CopyFromSurfaceTime";
     85 
     86 // Sends an acknowledgement to the renderer of a processed IME event.
     87 void SendImeEventAck(RenderWidgetHostImpl* host) {
     88   host->Send(new ViewMsg_ImeEventAck(host->GetRoutingID()));
     89 }
     90 
     91 void CopyFromCompositingSurfaceFinished(
     92     const base::Callback<void(bool, const SkBitmap&)>& callback,
     93     scoped_ptr<cc::SingleReleaseCallback> release_callback,
     94     scoped_ptr<SkBitmap> bitmap,
     95     const base::TimeTicks& start_time,
     96     scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock,
     97     bool result) {
     98   bitmap_pixels_lock.reset();
     99   release_callback->Run(0, false);
    100   UMA_HISTOGRAM_TIMES(kAsyncReadBackString,
    101                       base::TimeTicks::Now() - start_time);
    102   callback.Run(result, *bitmap);
    103 }
    104 
    105 ui::LatencyInfo CreateLatencyInfo(const blink::WebInputEvent& event) {
    106   ui::LatencyInfo latency_info;
    107   // The latency number should only be added if the timestamp is valid.
    108   if (event.timeStampSeconds) {
    109     const int64 time_micros = static_cast<int64>(
    110         event.timeStampSeconds * base::Time::kMicrosecondsPerSecond);
    111     latency_info.AddLatencyNumberWithTimestamp(
    112         ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT,
    113         0,
    114         0,
    115         base::TimeTicks() + base::TimeDelta::FromMicroseconds(time_micros),
    116         1);
    117   }
    118   return latency_info;
    119 }
    120 
    121 OverscrollGlow::DisplayParameters CreateOverscrollDisplayParameters(
    122     const cc::CompositorFrameMetadata& frame_metadata) {
    123   const float scale_factor =
    124       frame_metadata.page_scale_factor * frame_metadata.device_scale_factor;
    125 
    126   // Compute the size and offsets for each edge, where each effect is sized to
    127   // the viewport and offset by the distance of each viewport edge to the
    128   // respective content edge.
    129   OverscrollGlow::DisplayParameters params;
    130   params.size = gfx::ScaleSize(frame_metadata.viewport_size, scale_factor);
    131   params.edge_offsets[EdgeEffect::EDGE_TOP] =
    132       -frame_metadata.root_scroll_offset.y() * scale_factor;
    133   params.edge_offsets[EdgeEffect::EDGE_LEFT] =
    134       -frame_metadata.root_scroll_offset.x() * scale_factor;
    135   params.edge_offsets[EdgeEffect::EDGE_BOTTOM] =
    136       (frame_metadata.root_layer_size.height() -
    137        frame_metadata.root_scroll_offset.y() -
    138        frame_metadata.viewport_size.height()) * scale_factor;
    139   params.edge_offsets[EdgeEffect::EDGE_RIGHT] =
    140       (frame_metadata.root_layer_size.width() -
    141        frame_metadata.root_scroll_offset.x() -
    142        frame_metadata.viewport_size.width()) * scale_factor;
    143   params.device_scale_factor = frame_metadata.device_scale_factor;
    144 
    145   return params;
    146 }
    147 
    148 ui::GestureProvider::Config CreateGestureProviderConfig() {
    149   ui::GestureProvider::Config config = ui::DefaultGestureProviderConfig();
    150   config.disable_click_delay =
    151       CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableClickDelay);
    152   return config;
    153 }
    154 
    155 bool HasFixedPageScale(const cc::CompositorFrameMetadata& frame_metadata) {
    156   return frame_metadata.min_page_scale_factor ==
    157          frame_metadata.max_page_scale_factor;
    158 }
    159 
    160 bool HasMobileViewport(const cc::CompositorFrameMetadata& frame_metadata) {
    161   float window_width_dip =
    162       frame_metadata.page_scale_factor * frame_metadata.viewport_size.width();
    163   float content_width_css = frame_metadata.root_layer_size.width();
    164   return content_width_css <= window_width_dip + kMobileViewportWidthEpsilon;
    165 }
    166 
    167 }  // anonymous namespace
    168 
    169 RenderWidgetHostViewAndroid::LastFrameInfo::LastFrameInfo(
    170     uint32 output_id,
    171     scoped_ptr<cc::CompositorFrame> output_frame)
    172     : output_surface_id(output_id), frame(output_frame.Pass()) {}
    173 
    174 RenderWidgetHostViewAndroid::LastFrameInfo::~LastFrameInfo() {}
    175 
    176 RenderWidgetHostViewAndroid::RenderWidgetHostViewAndroid(
    177     RenderWidgetHostImpl* widget_host,
    178     ContentViewCoreImpl* content_view_core)
    179     : host_(widget_host),
    180       needs_begin_frame_(false),
    181       is_showing_(!widget_host->is_hidden()),
    182       content_view_core_(NULL),
    183       ime_adapter_android_(this),
    184       cached_background_color_(SK_ColorWHITE),
    185       last_output_surface_id_(kUndefinedOutputSurfaceId),
    186       weak_ptr_factory_(this),
    187       overscroll_effect_enabled_(!CommandLine::ForCurrentProcess()->HasSwitch(
    188           switches::kDisableOverscrollEdgeEffect)),
    189       overscroll_effect_(OverscrollGlow::Create(overscroll_effect_enabled_)),
    190       gesture_provider_(CreateGestureProviderConfig(), this),
    191       gesture_text_selector_(this),
    192       flush_input_requested_(false),
    193       accelerated_surface_route_id_(0),
    194       using_synchronous_compositor_(SynchronousCompositorImpl::FromID(
    195                                         widget_host->GetProcess()->GetID(),
    196                                         widget_host->GetRoutingID()) != NULL),
    197       frame_evictor_(new DelegatedFrameEvictor(this)),
    198       locks_on_frame_count_(0),
    199       observing_root_window_(false) {
    200   host_->SetView(this);
    201   SetContentViewCore(content_view_core);
    202   ImageTransportFactoryAndroid::AddObserver(this);
    203 }
    204 
    205 RenderWidgetHostViewAndroid::~RenderWidgetHostViewAndroid() {
    206   ImageTransportFactoryAndroid::RemoveObserver(this);
    207   SetContentViewCore(NULL);
    208   DCHECK(ack_callbacks_.empty());
    209   if (resource_collection_.get())
    210     resource_collection_->SetClient(NULL);
    211 }
    212 
    213 
    214 bool RenderWidgetHostViewAndroid::OnMessageReceived(
    215     const IPC::Message& message) {
    216   bool handled = true;
    217   IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewAndroid, message)
    218     IPC_MESSAGE_HANDLER(ViewHostMsg_StartContentIntent, OnStartContentIntent)
    219     IPC_MESSAGE_HANDLER(ViewHostMsg_DidChangeBodyBackgroundColor,
    220                         OnDidChangeBodyBackgroundColor)
    221     IPC_MESSAGE_HANDLER(ViewHostMsg_SetNeedsBeginFrame,
    222                         OnSetNeedsBeginFrame)
    223     IPC_MESSAGE_HANDLER(ViewHostMsg_SmartClipDataExtracted,
    224                         OnSmartClipDataExtracted)
    225     IPC_MESSAGE_UNHANDLED(handled = false)
    226   IPC_END_MESSAGE_MAP()
    227   return handled;
    228 }
    229 
    230 void RenderWidgetHostViewAndroid::InitAsChild(gfx::NativeView parent_view) {
    231   NOTIMPLEMENTED();
    232 }
    233 
    234 void RenderWidgetHostViewAndroid::InitAsPopup(
    235     RenderWidgetHostView* parent_host_view, const gfx::Rect& pos) {
    236   NOTIMPLEMENTED();
    237 }
    238 
    239 void RenderWidgetHostViewAndroid::InitAsFullscreen(
    240     RenderWidgetHostView* reference_host_view) {
    241   NOTIMPLEMENTED();
    242 }
    243 
    244 RenderWidgetHost*
    245 RenderWidgetHostViewAndroid::GetRenderWidgetHost() const {
    246   return host_;
    247 }
    248 
    249 void RenderWidgetHostViewAndroid::WasShown() {
    250   if (!host_ || !host_->is_hidden())
    251     return;
    252 
    253   host_->WasShown();
    254 
    255   if (content_view_core_ && !using_synchronous_compositor_) {
    256     content_view_core_->GetWindowAndroid()->AddObserver(this);
    257     content_view_core_->GetWindowAndroid()->RequestVSyncUpdate();
    258     observing_root_window_ = true;
    259   }
    260 }
    261 
    262 void RenderWidgetHostViewAndroid::WasHidden() {
    263   RunAckCallbacks();
    264 
    265   if (!host_ || host_->is_hidden())
    266     return;
    267 
    268   // Inform the renderer that we are being hidden so it can reduce its resource
    269   // utilization.
    270   host_->WasHidden();
    271 
    272   if (content_view_core_ && !using_synchronous_compositor_) {
    273     content_view_core_->GetWindowAndroid()->RemoveObserver(this);
    274     observing_root_window_ = false;
    275   }
    276 }
    277 
    278 void RenderWidgetHostViewAndroid::WasResized() {
    279   host_->WasResized();
    280 }
    281 
    282 void RenderWidgetHostViewAndroid::SetSize(const gfx::Size& size) {
    283   // Ignore the given size as only the Java code has the power to
    284   // resize the view on Android.
    285   default_size_ = size;
    286 }
    287 
    288 void RenderWidgetHostViewAndroid::SetBounds(const gfx::Rect& rect) {
    289   SetSize(rect.size());
    290 }
    291 
    292 void RenderWidgetHostViewAndroid::GetScaledContentBitmap(
    293     float scale,
    294     SkBitmap::Config bitmap_config,
    295     gfx::Rect src_subrect,
    296     const base::Callback<void(bool, const SkBitmap&)>& result_callback) {
    297   if (!IsSurfaceAvailableForCopy()) {
    298     result_callback.Run(false, SkBitmap());
    299     return;
    300   }
    301 
    302   gfx::Size bounds = layer_->bounds();
    303   if (src_subrect.IsEmpty())
    304     src_subrect = gfx::Rect(bounds);
    305   DCHECK_LE(src_subrect.width() + src_subrect.x(), bounds.width());
    306   DCHECK_LE(src_subrect.height() + src_subrect.y(), bounds.height());
    307   const gfx::Display& display =
    308       gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
    309   float device_scale_factor = display.device_scale_factor();
    310   DCHECK_GT(device_scale_factor, 0);
    311   gfx::Size dst_size(
    312       gfx::ToCeiledSize(gfx::ScaleSize(bounds, scale / device_scale_factor)));
    313   CopyFromCompositingSurface(
    314       src_subrect, dst_size, result_callback, bitmap_config);
    315 }
    316 
    317 bool RenderWidgetHostViewAndroid::HasValidFrame() const {
    318   if (!content_view_core_)
    319     return false;
    320   if (!layer_)
    321     return false;
    322 
    323   if (texture_size_in_layer_.IsEmpty())
    324     return false;
    325 
    326   if (!frame_evictor_->HasFrame())
    327     return false;
    328 
    329   return true;
    330 }
    331 
    332 gfx::NativeView RenderWidgetHostViewAndroid::GetNativeView() const {
    333   return content_view_core_->GetViewAndroid();
    334 }
    335 
    336 gfx::NativeViewId RenderWidgetHostViewAndroid::GetNativeViewId() const {
    337   return reinterpret_cast<gfx::NativeViewId>(
    338       const_cast<RenderWidgetHostViewAndroid*>(this));
    339 }
    340 
    341 gfx::NativeViewAccessible
    342 RenderWidgetHostViewAndroid::GetNativeViewAccessible() {
    343   NOTIMPLEMENTED();
    344   return NULL;
    345 }
    346 
    347 void RenderWidgetHostViewAndroid::MovePluginWindows(
    348     const std::vector<WebPluginGeometry>& moves) {
    349   // We don't have plugin windows on Android. Do nothing. Note: this is called
    350   // from RenderWidgetHost::OnUpdateRect which is itself invoked while
    351   // processing the corresponding message from Renderer.
    352 }
    353 
    354 void RenderWidgetHostViewAndroid::Focus() {
    355   host_->Focus();
    356   host_->SetInputMethodActive(true);
    357   if (overscroll_effect_enabled_)
    358     overscroll_effect_->Enable();
    359 }
    360 
    361 void RenderWidgetHostViewAndroid::Blur() {
    362   host_->ExecuteEditCommand("Unselect", "");
    363   host_->SetInputMethodActive(false);
    364   host_->Blur();
    365   overscroll_effect_->Disable();
    366 }
    367 
    368 bool RenderWidgetHostViewAndroid::HasFocus() const {
    369   if (!content_view_core_)
    370     return false;  // ContentViewCore not created yet.
    371 
    372   return content_view_core_->HasFocus();
    373 }
    374 
    375 bool RenderWidgetHostViewAndroid::IsSurfaceAvailableForCopy() const {
    376   return HasValidFrame();
    377 }
    378 
    379 void RenderWidgetHostViewAndroid::Show() {
    380   if (is_showing_)
    381     return;
    382 
    383   is_showing_ = true;
    384   if (layer_)
    385     layer_->SetHideLayerAndSubtree(false);
    386 
    387   frame_evictor_->SetVisible(true);
    388   WasShown();
    389 }
    390 
    391 void RenderWidgetHostViewAndroid::Hide() {
    392   if (!is_showing_)
    393     return;
    394 
    395   is_showing_ = false;
    396   if (layer_ && locks_on_frame_count_ == 0)
    397     layer_->SetHideLayerAndSubtree(true);
    398 
    399   frame_evictor_->SetVisible(false);
    400   WasHidden();
    401 }
    402 
    403 bool RenderWidgetHostViewAndroid::IsShowing() {
    404   // ContentViewCoreImpl represents the native side of the Java
    405   // ContentViewCore.  It being NULL means that it is not attached
    406   // to the View system yet, so we treat this RWHVA as hidden.
    407   return is_showing_ && content_view_core_;
    408 }
    409 
    410 void RenderWidgetHostViewAndroid::LockCompositingSurface() {
    411   DCHECK(HasValidFrame());
    412   DCHECK(host_);
    413   DCHECK(frame_evictor_->HasFrame());
    414   frame_evictor_->LockFrame();
    415   locks_on_frame_count_++;
    416 }
    417 
    418 void RenderWidgetHostViewAndroid::UnlockCompositingSurface() {
    419   if (!frame_evictor_->HasFrame() || locks_on_frame_count_ == 0)
    420     return;
    421 
    422   DCHECK(HasValidFrame());
    423   frame_evictor_->UnlockFrame();
    424   locks_on_frame_count_--;
    425 
    426   if (locks_on_frame_count_ == 0) {
    427     if (last_frame_info_) {
    428       InternalSwapCompositorFrame(last_frame_info_->output_surface_id,
    429                                   last_frame_info_->frame.Pass());
    430       last_frame_info_.reset();
    431     }
    432 
    433     if (!is_showing_ && layer_)
    434       layer_->SetHideLayerAndSubtree(true);
    435   }
    436 }
    437 
    438 void RenderWidgetHostViewAndroid::SetTextSurroundingSelectionCallback(
    439     const TextSurroundingSelectionCallback& callback) {
    440   // Only one outstanding request is allowed at any given time.
    441   DCHECK(!callback.is_null());
    442   text_surrounding_selection_callback_ = callback;
    443 }
    444 
    445 void RenderWidgetHostViewAndroid::OnTextSurroundingSelectionResponse(
    446     const base::string16& content,
    447     size_t start_offset,
    448     size_t end_offset) {
    449   if (text_surrounding_selection_callback_.is_null())
    450     return;
    451   text_surrounding_selection_callback_.Run(content, start_offset, end_offset);
    452   text_surrounding_selection_callback_.Reset();
    453 }
    454 
    455 void RenderWidgetHostViewAndroid::ReleaseLocksOnSurface() {
    456   if (!frame_evictor_->HasFrame()) {
    457     DCHECK_EQ(locks_on_frame_count_, 0u);
    458     return;
    459   }
    460   while (locks_on_frame_count_ > 0) {
    461     UnlockCompositingSurface();
    462   }
    463   RunAckCallbacks();
    464 }
    465 
    466 gfx::Rect RenderWidgetHostViewAndroid::GetViewBounds() const {
    467   if (!content_view_core_)
    468     return gfx::Rect(default_size_);
    469 
    470   return gfx::Rect(content_view_core_->GetViewSize());
    471 }
    472 
    473 gfx::Size RenderWidgetHostViewAndroid::GetPhysicalBackingSize() const {
    474   if (!content_view_core_)
    475     return gfx::Size();
    476 
    477   return content_view_core_->GetPhysicalBackingSize();
    478 }
    479 
    480 float RenderWidgetHostViewAndroid::GetOverdrawBottomHeight() const {
    481   if (!content_view_core_)
    482     return 0.f;
    483 
    484   return content_view_core_->GetOverdrawBottomHeightDip();
    485 }
    486 
    487 void RenderWidgetHostViewAndroid::UpdateCursor(const WebCursor& cursor) {
    488   // There are no cursors on Android.
    489 }
    490 
    491 void RenderWidgetHostViewAndroid::SetIsLoading(bool is_loading) {
    492   // Do nothing. The UI notification is handled through ContentViewClient which
    493   // is TabContentsDelegate.
    494 }
    495 
    496 long RenderWidgetHostViewAndroid::GetNativeImeAdapter() {
    497   return reinterpret_cast<intptr_t>(&ime_adapter_android_);
    498 }
    499 
    500 void RenderWidgetHostViewAndroid::TextInputStateChanged(
    501     const ViewHostMsg_TextInputState_Params& params) {
    502   // If the change is not originated from IME (e.g. Javascript, autofill),
    503   // send back the renderer an acknowledgement, regardless of how we exit from
    504   // this method.
    505   base::ScopedClosureRunner ack_caller;
    506   if (params.is_non_ime_change)
    507     ack_caller.Reset(base::Bind(&SendImeEventAck, host_));
    508 
    509   if (!IsShowing())
    510     return;
    511 
    512   content_view_core_->UpdateImeAdapter(
    513       GetNativeImeAdapter(),
    514       static_cast<int>(params.type),
    515       params.value, params.selection_start, params.selection_end,
    516       params.composition_start, params.composition_end,
    517       params.show_ime_if_needed, params.is_non_ime_change);
    518 }
    519 
    520 void RenderWidgetHostViewAndroid::OnDidChangeBodyBackgroundColor(
    521     SkColor color) {
    522   if (cached_background_color_ == color)
    523     return;
    524 
    525   cached_background_color_ = color;
    526   if (content_view_core_)
    527     content_view_core_->OnBackgroundColorChanged(color);
    528 }
    529 
    530 void RenderWidgetHostViewAndroid::OnSetNeedsBeginFrame(bool enabled) {
    531   if (enabled == needs_begin_frame_)
    532     return;
    533 
    534   TRACE_EVENT1("cc", "RenderWidgetHostViewAndroid::OnSetNeedsBeginFrame",
    535                "enabled", enabled);
    536   if (content_view_core_ && enabled)
    537     content_view_core_->GetWindowAndroid()->RequestVSyncUpdate();
    538 
    539   needs_begin_frame_ = enabled;
    540 }
    541 
    542 void RenderWidgetHostViewAndroid::OnStartContentIntent(
    543     const GURL& content_url) {
    544   if (content_view_core_)
    545     content_view_core_->StartContentIntent(content_url);
    546 }
    547 
    548 void RenderWidgetHostViewAndroid::OnSmartClipDataExtracted(
    549     const base::string16& text,
    550     const base::string16& html,
    551     const gfx::Rect rect) {
    552   if (content_view_core_)
    553     content_view_core_->OnSmartClipDataExtracted(text, html, rect);
    554 }
    555 
    556 bool RenderWidgetHostViewAndroid::OnTouchEvent(
    557     const ui::MotionEvent& event) {
    558   if (!host_)
    559     return false;
    560 
    561   if (!gesture_provider_.OnTouchEvent(event))
    562     return false;
    563 
    564   if (gesture_text_selector_.OnTouchEvent(event)) {
    565     gesture_provider_.OnTouchEventAck(false);
    566     return true;
    567   }
    568 
    569   // Short-circuit touch forwarding if no touch handlers exist.
    570   if (!host_->ShouldForwardTouchEvent()) {
    571     const bool event_consumed = false;
    572     gesture_provider_.OnTouchEventAck(event_consumed);
    573     return true;
    574   }
    575 
    576   SendTouchEvent(CreateWebTouchEventFromMotionEvent(event));
    577   return true;
    578 }
    579 
    580 void RenderWidgetHostViewAndroid::ResetGestureDetection() {
    581   const ui::MotionEvent* current_down_event =
    582       gesture_provider_.GetCurrentDownEvent();
    583   if (!current_down_event)
    584     return;
    585 
    586   scoped_ptr<ui::MotionEvent> cancel_event = current_down_event->Cancel();
    587   DCHECK(cancel_event);
    588   OnTouchEvent(*cancel_event);
    589 }
    590 
    591 void RenderWidgetHostViewAndroid::SetDoubleTapSupportEnabled(bool enabled) {
    592   gesture_provider_.SetDoubleTapSupportForPlatformEnabled(enabled);
    593 }
    594 
    595 void RenderWidgetHostViewAndroid::SetMultiTouchZoomSupportEnabled(
    596     bool enabled) {
    597   gesture_provider_.SetMultiTouchZoomSupportEnabled(enabled);
    598 }
    599 
    600 void RenderWidgetHostViewAndroid::ImeCancelComposition() {
    601   ime_adapter_android_.CancelComposition();
    602 }
    603 
    604 void RenderWidgetHostViewAndroid::FocusedNodeChanged(bool is_editable_node) {
    605   ime_adapter_android_.FocusedNodeChanged(is_editable_node);
    606 }
    607 
    608 void RenderWidgetHostViewAndroid::RenderProcessGone(
    609     base::TerminationStatus status, int error_code) {
    610   Destroy();
    611 }
    612 
    613 void RenderWidgetHostViewAndroid::Destroy() {
    614   RemoveLayers();
    615   SetContentViewCore(NULL);
    616 
    617   // The RenderWidgetHost's destruction led here, so don't call it.
    618   host_ = NULL;
    619 
    620   delete this;
    621 }
    622 
    623 void RenderWidgetHostViewAndroid::SetTooltipText(
    624     const base::string16& tooltip_text) {
    625   // Tooltips don't makes sense on Android.
    626 }
    627 
    628 void RenderWidgetHostViewAndroid::SelectionChanged(const base::string16& text,
    629                                                    size_t offset,
    630                                                    const gfx::Range& range) {
    631   RenderWidgetHostViewBase::SelectionChanged(text, offset, range);
    632 
    633   if (text.empty() || range.is_empty() || !content_view_core_)
    634     return;
    635   size_t pos = range.GetMin() - offset;
    636   size_t n = range.length();
    637 
    638   DCHECK(pos + n <= text.length()) << "The text can not fully cover range.";
    639   if (pos >= text.length()) {
    640     NOTREACHED() << "The text can not cover range.";
    641     return;
    642   }
    643 
    644   std::string utf8_selection = base::UTF16ToUTF8(text.substr(pos, n));
    645 
    646   content_view_core_->OnSelectionChanged(utf8_selection);
    647 }
    648 
    649 void RenderWidgetHostViewAndroid::SelectionBoundsChanged(
    650     const ViewHostMsg_SelectionBounds_Params& params) {
    651   if (content_view_core_) {
    652     content_view_core_->OnSelectionBoundsChanged(params);
    653   }
    654 }
    655 
    656 void RenderWidgetHostViewAndroid::ScrollOffsetChanged() {
    657 }
    658 
    659 void RenderWidgetHostViewAndroid::SetBackgroundOpaque(bool opaque) {
    660   RenderWidgetHostViewBase::SetBackgroundOpaque(opaque);
    661   host_->SetBackgroundOpaque(opaque);
    662 }
    663 
    664 void RenderWidgetHostViewAndroid::CopyFromCompositingSurface(
    665     const gfx::Rect& src_subrect,
    666     const gfx::Size& dst_size,
    667     const base::Callback<void(bool, const SkBitmap&)>& callback,
    668     const SkBitmap::Config bitmap_config) {
    669   if (!IsReadbackConfigSupported(bitmap_config)) {
    670     callback.Run(false, SkBitmap());
    671     return;
    672   }
    673   base::TimeTicks start_time = base::TimeTicks::Now();
    674   if (!using_synchronous_compositor_ && !IsSurfaceAvailableForCopy()) {
    675     callback.Run(false, SkBitmap());
    676     return;
    677   }
    678   const gfx::Display& display =
    679       gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
    680   float device_scale_factor = display.device_scale_factor();
    681   gfx::Size dst_size_in_pixel =
    682       ConvertRectToPixel(device_scale_factor, gfx::Rect(dst_size)).size();
    683   gfx::Rect src_subrect_in_pixel =
    684       ConvertRectToPixel(device_scale_factor, src_subrect);
    685 
    686   if (using_synchronous_compositor_) {
    687     SynchronousCopyContents(src_subrect_in_pixel, dst_size_in_pixel, callback,
    688                             bitmap_config);
    689     UMA_HISTOGRAM_TIMES("Compositing.CopyFromSurfaceTimeSynchronous",
    690                         base::TimeTicks::Now() - start_time);
    691     return;
    692   }
    693 
    694   scoped_ptr<cc::CopyOutputRequest> request;
    695   scoped_refptr<cc::Layer> readback_layer;
    696   DCHECK(content_view_core_);
    697   DCHECK(content_view_core_->GetWindowAndroid());
    698   ui::WindowAndroidCompositor* compositor =
    699       content_view_core_->GetWindowAndroid()->GetCompositor();
    700   DCHECK(compositor);
    701   DCHECK(frame_provider_);
    702   scoped_refptr<cc::DelegatedRendererLayer> delegated_layer =
    703       cc::DelegatedRendererLayer::Create(frame_provider_);
    704   delegated_layer->SetBounds(content_size_in_layer_);
    705   delegated_layer->SetHideLayerAndSubtree(true);
    706   delegated_layer->SetIsDrawable(true);
    707   delegated_layer->SetContentsOpaque(true);
    708   compositor->AttachLayerForReadback(delegated_layer);
    709 
    710   readback_layer = delegated_layer;
    711   request = cc::CopyOutputRequest::CreateRequest(
    712       base::Bind(&RenderWidgetHostViewAndroid::
    713                      PrepareTextureCopyOutputResultForDelegatedReadback,
    714                  dst_size_in_pixel,
    715                  bitmap_config,
    716                  start_time,
    717                  readback_layer,
    718                  callback));
    719   request->set_area(src_subrect_in_pixel);
    720   readback_layer->RequestCopyOfOutput(request.Pass());
    721 }
    722 
    723 void RenderWidgetHostViewAndroid::CopyFromCompositingSurfaceToVideoFrame(
    724       const gfx::Rect& src_subrect,
    725       const scoped_refptr<media::VideoFrame>& target,
    726       const base::Callback<void(bool)>& callback) {
    727   NOTIMPLEMENTED();
    728   callback.Run(false);
    729 }
    730 
    731 bool RenderWidgetHostViewAndroid::CanCopyToVideoFrame() const {
    732   return false;
    733 }
    734 
    735 void RenderWidgetHostViewAndroid::ShowDisambiguationPopup(
    736     const gfx::Rect& target_rect, const SkBitmap& zoomed_bitmap) {
    737   if (!content_view_core_)
    738     return;
    739 
    740   content_view_core_->ShowDisambiguationPopup(target_rect, zoomed_bitmap);
    741 }
    742 
    743 scoped_ptr<SyntheticGestureTarget>
    744 RenderWidgetHostViewAndroid::CreateSyntheticGestureTarget() {
    745   return scoped_ptr<SyntheticGestureTarget>(new SyntheticGestureTargetAndroid(
    746       host_, content_view_core_->CreateTouchEventSynthesizer()));
    747 }
    748 
    749 void RenderWidgetHostViewAndroid::SendDelegatedFrameAck(
    750     uint32 output_surface_id) {
    751   DCHECK(host_);
    752   cc::CompositorFrameAck ack;
    753   if (resource_collection_.get())
    754     resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources);
    755   RenderWidgetHostImpl::SendSwapCompositorFrameAck(host_->GetRoutingID(),
    756                                                    output_surface_id,
    757                                                    host_->GetProcess()->GetID(),
    758                                                    ack);
    759 }
    760 
    761 void RenderWidgetHostViewAndroid::SendReturnedDelegatedResources(
    762     uint32 output_surface_id) {
    763   DCHECK(resource_collection_);
    764 
    765   cc::CompositorFrameAck ack;
    766   resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources);
    767   DCHECK(!ack.resources.empty());
    768 
    769   RenderWidgetHostImpl::SendReclaimCompositorResources(
    770       host_->GetRoutingID(),
    771       output_surface_id,
    772       host_->GetProcess()->GetID(),
    773       ack);
    774 }
    775 
    776 void RenderWidgetHostViewAndroid::UnusedResourcesAreAvailable() {
    777   if (ack_callbacks_.size())
    778     return;
    779   SendReturnedDelegatedResources(last_output_surface_id_);
    780 }
    781 
    782 void RenderWidgetHostViewAndroid::DestroyDelegatedContent() {
    783   RemoveLayers();
    784   frame_provider_ = NULL;
    785   layer_ = NULL;
    786 }
    787 
    788 void RenderWidgetHostViewAndroid::SwapDelegatedFrame(
    789     uint32 output_surface_id,
    790     scoped_ptr<cc::DelegatedFrameData> frame_data) {
    791   bool has_content = !texture_size_in_layer_.IsEmpty();
    792 
    793   if (output_surface_id != last_output_surface_id_) {
    794     // Drop the cc::DelegatedFrameResourceCollection so that we will not return
    795     // any resources from the old output surface with the new output surface id.
    796     if (resource_collection_.get()) {
    797       resource_collection_->SetClient(NULL);
    798       if (resource_collection_->LoseAllResources())
    799         SendReturnedDelegatedResources(last_output_surface_id_);
    800       resource_collection_ = NULL;
    801     }
    802     DestroyDelegatedContent();
    803 
    804     last_output_surface_id_ = output_surface_id;
    805   }
    806 
    807   // DelegatedRendererLayerImpl applies the inverse device_scale_factor of the
    808   // renderer frame, assuming that the browser compositor will scale
    809   // it back up to device scale.  But on Android we put our browser layers in
    810   // physical pixels and set our browser CC device_scale_factor to 1, so this
    811   // suppresses the transform.  This line may need to be removed when fixing
    812   // http://crbug.com/384134 or http://crbug.com/310763
    813   frame_data->device_scale_factor = 1.0f;
    814 
    815   if (!has_content) {
    816     DestroyDelegatedContent();
    817   } else {
    818     if (!resource_collection_.get()) {
    819       resource_collection_ = new cc::DelegatedFrameResourceCollection;
    820       resource_collection_->SetClient(this);
    821     }
    822     if (!frame_provider_ ||
    823         texture_size_in_layer_ != frame_provider_->frame_size()) {
    824       RemoveLayers();
    825       frame_provider_ = new cc::DelegatedFrameProvider(
    826           resource_collection_.get(), frame_data.Pass());
    827       layer_ = cc::DelegatedRendererLayer::Create(frame_provider_);
    828       AttachLayers();
    829     } else {
    830       frame_provider_->SetFrameData(frame_data.Pass());
    831     }
    832   }
    833 
    834   if (layer_.get()) {
    835     layer_->SetIsDrawable(true);
    836     layer_->SetContentsOpaque(true);
    837     layer_->SetBounds(content_size_in_layer_);
    838     layer_->SetNeedsDisplay();
    839   }
    840 
    841   base::Closure ack_callback =
    842       base::Bind(&RenderWidgetHostViewAndroid::SendDelegatedFrameAck,
    843                  weak_ptr_factory_.GetWeakPtr(),
    844                  output_surface_id);
    845 
    846   ack_callbacks_.push(ack_callback);
    847   if (host_->is_hidden())
    848     RunAckCallbacks();
    849 }
    850 
    851 void RenderWidgetHostViewAndroid::ComputeContentsSize(
    852     const cc::CompositorFrameMetadata& frame_metadata) {
    853   // Calculate the content size.  This should be 0 if the texture_size is 0.
    854   gfx::Vector2dF offset;
    855   if (texture_size_in_layer_.GetArea() > 0)
    856     offset = frame_metadata.location_bar_content_translation;
    857   offset.set_y(offset.y() + frame_metadata.overdraw_bottom_height);
    858   offset.Scale(frame_metadata.device_scale_factor);
    859   content_size_in_layer_ =
    860       gfx::Size(texture_size_in_layer_.width() - offset.x(),
    861                 texture_size_in_layer_.height() - offset.y());
    862 
    863   overscroll_effect_->UpdateDisplayParameters(
    864       CreateOverscrollDisplayParameters(frame_metadata));
    865 }
    866 
    867 void RenderWidgetHostViewAndroid::InternalSwapCompositorFrame(
    868     uint32 output_surface_id,
    869     scoped_ptr<cc::CompositorFrame> frame) {
    870   if (!frame->delegated_frame_data) {
    871     LOG(ERROR) << "Non-delegated renderer path no longer supported";
    872     return;
    873   }
    874 
    875   if (locks_on_frame_count_ > 0) {
    876     DCHECK(HasValidFrame());
    877     RetainFrame(output_surface_id, frame.Pass());
    878     return;
    879   }
    880 
    881   if (layer_ && layer_->layer_tree_host()) {
    882     for (size_t i = 0; i < frame->metadata.latency_info.size(); i++) {
    883       scoped_ptr<cc::SwapPromise> swap_promise(
    884           new cc::LatencyInfoSwapPromise(frame->metadata.latency_info[i]));
    885       layer_->layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
    886     }
    887   }
    888 
    889   DCHECK(!frame->delegated_frame_data->render_pass_list.empty());
    890 
    891   cc::RenderPass* root_pass =
    892       frame->delegated_frame_data->render_pass_list.back();
    893   texture_size_in_layer_ = root_pass->output_rect.size();
    894   ComputeContentsSize(frame->metadata);
    895 
    896   SwapDelegatedFrame(output_surface_id, frame->delegated_frame_data.Pass());
    897   frame_evictor_->SwappedFrame(!host_->is_hidden());
    898 
    899   OnFrameMetadataUpdated(frame->metadata);
    900 }
    901 
    902 void RenderWidgetHostViewAndroid::OnSwapCompositorFrame(
    903     uint32 output_surface_id,
    904     scoped_ptr<cc::CompositorFrame> frame) {
    905   InternalSwapCompositorFrame(output_surface_id, frame.Pass());
    906 }
    907 
    908 void RenderWidgetHostViewAndroid::RetainFrame(
    909     uint32 output_surface_id,
    910     scoped_ptr<cc::CompositorFrame> frame) {
    911   DCHECK(locks_on_frame_count_);
    912 
    913   // Store the incoming frame so that it can be swapped when all the locks have
    914   // been released. If there is already a stored frame, then replace and skip
    915   // the previous one but make sure we still eventually send the ACK. Holding
    916   // the ACK also blocks the renderer when its max_frames_pending is reached.
    917   if (last_frame_info_) {
    918     base::Closure ack_callback =
    919         base::Bind(&RenderWidgetHostViewAndroid::SendDelegatedFrameAck,
    920                    weak_ptr_factory_.GetWeakPtr(),
    921                    last_frame_info_->output_surface_id);
    922 
    923     ack_callbacks_.push(ack_callback);
    924   }
    925 
    926   last_frame_info_.reset(new LastFrameInfo(output_surface_id, frame.Pass()));
    927 }
    928 
    929 void RenderWidgetHostViewAndroid::SynchronousFrameMetadata(
    930     const cc::CompositorFrameMetadata& frame_metadata) {
    931   // This is a subset of OnSwapCompositorFrame() used in the synchronous
    932   // compositor flow.
    933   OnFrameMetadataUpdated(frame_metadata);
    934   ComputeContentsSize(frame_metadata);
    935 
    936   // DevTools ScreenCast support for Android WebView.
    937   if (DevToolsAgentHost::HasFor(RenderViewHost::From(GetRenderWidgetHost()))) {
    938     scoped_refptr<DevToolsAgentHost> dtah =
    939         DevToolsAgentHost::GetOrCreateFor(
    940             RenderViewHost::From(GetRenderWidgetHost()));
    941     // Unblock the compositor.
    942     BrowserThread::PostTask(
    943         BrowserThread::UI, FROM_HERE,
    944         base::Bind(&RenderViewDevToolsAgentHost::SynchronousSwapCompositorFrame,
    945                    static_cast<RenderViewDevToolsAgentHost*>(dtah.get()),
    946                    frame_metadata));
    947   }
    948 }
    949 
    950 void RenderWidgetHostViewAndroid::SetOverlayVideoMode(bool enabled) {
    951   if (layer_)
    952     layer_->SetContentsOpaque(!enabled);
    953 }
    954 
    955 void RenderWidgetHostViewAndroid::SynchronousCopyContents(
    956     const gfx::Rect& src_subrect_in_pixel,
    957     const gfx::Size& dst_size_in_pixel,
    958     const base::Callback<void(bool, const SkBitmap&)>& callback,
    959     const SkBitmap::Config config) {
    960   SynchronousCompositor* compositor =
    961       SynchronousCompositorImpl::FromID(host_->GetProcess()->GetID(),
    962                                         host_->GetRoutingID());
    963   if (!compositor) {
    964     callback.Run(false, SkBitmap());
    965     return;
    966   }
    967 
    968   SkBitmap bitmap;
    969   bitmap.setConfig(config,
    970                    dst_size_in_pixel.width(),
    971                    dst_size_in_pixel.height());
    972   bitmap.allocPixels();
    973   SkCanvas canvas(bitmap);
    974   canvas.scale(
    975       (float)dst_size_in_pixel.width() / (float)src_subrect_in_pixel.width(),
    976       (float)dst_size_in_pixel.height() / (float)src_subrect_in_pixel.height());
    977   compositor->DemandDrawSw(&canvas);
    978   callback.Run(true, bitmap);
    979 }
    980 
    981 void RenderWidgetHostViewAndroid::OnFrameMetadataUpdated(
    982     const cc::CompositorFrameMetadata& frame_metadata) {
    983 
    984   // Disable double tap zoom for pages that have a width=device-width or
    985   // narrower viewport (indicating that this is a mobile-optimized or responsive
    986   // web design, so text will be legible without zooming). Also disable
    987   // double tap and pinch for pages that prevent zooming in or out.
    988   bool has_mobile_viewport = HasMobileViewport(frame_metadata);
    989   bool has_fixed_page_scale = HasFixedPageScale(frame_metadata);
    990   gesture_provider_.SetDoubleTapSupportForPageEnabled(
    991       !has_fixed_page_scale && !has_mobile_viewport);
    992 
    993   if (!content_view_core_)
    994     return;
    995   // All offsets and sizes are in CSS pixels.
    996   content_view_core_->UpdateFrameInfo(
    997       frame_metadata.root_scroll_offset,
    998       frame_metadata.page_scale_factor,
    999       gfx::Vector2dF(frame_metadata.min_page_scale_factor,
   1000                      frame_metadata.max_page_scale_factor),
   1001       frame_metadata.root_layer_size,
   1002       frame_metadata.viewport_size,
   1003       frame_metadata.location_bar_offset,
   1004       frame_metadata.location_bar_content_translation,
   1005       frame_metadata.overdraw_bottom_height);
   1006 #if defined(VIDEO_HOLE)
   1007   if (host_ && host_->IsRenderView()) {
   1008     RenderViewHostImpl* rvhi = static_cast<RenderViewHostImpl*>(
   1009         RenderViewHost::From(host_));
   1010     rvhi->media_web_contents_observer()->OnFrameInfoUpdated();
   1011   }
   1012 #endif  // defined(VIDEO_HOLE)
   1013 }
   1014 
   1015 void RenderWidgetHostViewAndroid::AcceleratedSurfaceInitialized(int host_id,
   1016                                                                 int route_id) {
   1017   accelerated_surface_route_id_ = route_id;
   1018 }
   1019 
   1020 void RenderWidgetHostViewAndroid::AcceleratedSurfaceBuffersSwapped(
   1021     const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params,
   1022     int gpu_host_id) {
   1023   NOTREACHED() << "Need --composite-to-mailbox or --enable-delegated-renderer";
   1024 }
   1025 
   1026 void RenderWidgetHostViewAndroid::AttachLayers() {
   1027   if (!content_view_core_)
   1028     return;
   1029   if (!layer_.get())
   1030     return;
   1031 
   1032   content_view_core_->AttachLayer(layer_);
   1033   if (overscroll_effect_enabled_)
   1034     overscroll_effect_->Enable();
   1035   layer_->SetHideLayerAndSubtree(!is_showing_);
   1036 }
   1037 
   1038 void RenderWidgetHostViewAndroid::RemoveLayers() {
   1039   if (!content_view_core_)
   1040     return;
   1041   if (!layer_.get())
   1042     return;
   1043 
   1044   content_view_core_->RemoveLayer(layer_);
   1045   overscroll_effect_->Disable();
   1046 }
   1047 
   1048 void RenderWidgetHostViewAndroid::SetNeedsAnimate() {
   1049   content_view_core_->GetWindowAndroid()->SetNeedsAnimate();
   1050 }
   1051 
   1052 bool RenderWidgetHostViewAndroid::Animate(base::TimeTicks frame_time) {
   1053   return overscroll_effect_->Animate(frame_time);
   1054 }
   1055 
   1056 void RenderWidgetHostViewAndroid::AcceleratedSurfacePostSubBuffer(
   1057     const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params,
   1058     int gpu_host_id) {
   1059   NOTREACHED();
   1060 }
   1061 
   1062 void RenderWidgetHostViewAndroid::AcceleratedSurfaceSuspend() {
   1063   NOTREACHED();
   1064 }
   1065 
   1066 void RenderWidgetHostViewAndroid::AcceleratedSurfaceRelease() {
   1067   NOTREACHED();
   1068 }
   1069 
   1070 void RenderWidgetHostViewAndroid::EvictDelegatedFrame() {
   1071   if (layer_.get())
   1072     DestroyDelegatedContent();
   1073   frame_evictor_->DiscardedFrame();
   1074 }
   1075 
   1076 bool RenderWidgetHostViewAndroid::HasAcceleratedSurface(
   1077     const gfx::Size& desired_size) {
   1078   NOTREACHED();
   1079   return false;
   1080 }
   1081 
   1082 void RenderWidgetHostViewAndroid::GetScreenInfo(blink::WebScreenInfo* result) {
   1083   // ScreenInfo isn't tied to the widget on Android. Always return the default.
   1084   RenderWidgetHostViewBase::GetDefaultScreenInfo(result);
   1085 }
   1086 
   1087 // TODO(jrg): Find out the implications and answer correctly here,
   1088 // as we are returning the WebView and not root window bounds.
   1089 gfx::Rect RenderWidgetHostViewAndroid::GetBoundsInRootWindow() {
   1090   return GetViewBounds();
   1091 }
   1092 
   1093 gfx::GLSurfaceHandle RenderWidgetHostViewAndroid::GetCompositingSurface() {
   1094   gfx::GLSurfaceHandle handle =
   1095       gfx::GLSurfaceHandle(gfx::kNullPluginWindow, gfx::NATIVE_TRANSPORT);
   1096   if (CompositorImpl::IsInitialized()) {
   1097     handle.parent_client_id =
   1098         ImageTransportFactoryAndroid::GetInstance()->GetChannelID();
   1099   }
   1100   return handle;
   1101 }
   1102 
   1103 void RenderWidgetHostViewAndroid::ProcessAckedTouchEvent(
   1104     const TouchEventWithLatencyInfo& touch, InputEventAckState ack_result) {
   1105   const bool event_consumed = ack_result == INPUT_EVENT_ACK_STATE_CONSUMED;
   1106   gesture_provider_.OnTouchEventAck(event_consumed);
   1107 }
   1108 
   1109 void RenderWidgetHostViewAndroid::GestureEventAck(
   1110     const blink::WebGestureEvent& event,
   1111     InputEventAckState ack_result) {
   1112   if (content_view_core_)
   1113     content_view_core_->OnGestureEventAck(event, ack_result);
   1114 }
   1115 
   1116 InputEventAckState RenderWidgetHostViewAndroid::FilterInputEvent(
   1117     const blink::WebInputEvent& input_event) {
   1118   if (content_view_core_ &&
   1119       content_view_core_->FilterInputEvent(input_event))
   1120     return INPUT_EVENT_ACK_STATE_CONSUMED;
   1121 
   1122   if (!host_)
   1123     return INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
   1124 
   1125   if (input_event.type == blink::WebInputEvent::GestureTapDown ||
   1126       input_event.type == blink::WebInputEvent::TouchStart) {
   1127     GpuDataManagerImpl* gpu_data = GpuDataManagerImpl::GetInstance();
   1128     GpuProcessHostUIShim* shim = GpuProcessHostUIShim::GetOneInstance();
   1129     if (shim && gpu_data && accelerated_surface_route_id_ &&
   1130         gpu_data->IsDriverBugWorkaroundActive(gpu::WAKE_UP_GPU_BEFORE_DRAWING))
   1131       shim->Send(
   1132           new AcceleratedSurfaceMsg_WakeUpGpu(accelerated_surface_route_id_));
   1133   }
   1134 
   1135   SynchronousCompositorImpl* compositor =
   1136       SynchronousCompositorImpl::FromID(host_->GetProcess()->GetID(),
   1137                                           host_->GetRoutingID());
   1138   if (compositor)
   1139     return compositor->HandleInputEvent(input_event);
   1140   return INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
   1141 }
   1142 
   1143 void RenderWidgetHostViewAndroid::OnSetNeedsFlushInput() {
   1144   if (flush_input_requested_ || !content_view_core_)
   1145     return;
   1146   TRACE_EVENT0("input", "RenderWidgetHostViewAndroid::OnSetNeedsFlushInput");
   1147   flush_input_requested_ = true;
   1148   content_view_core_->GetWindowAndroid()->RequestVSyncUpdate();
   1149 }
   1150 
   1151 void RenderWidgetHostViewAndroid::CreateBrowserAccessibilityManagerIfNeeded() {
   1152   if (!host_ || host_->accessibility_mode() != AccessibilityModeComplete)
   1153     return;
   1154 
   1155   if (!GetBrowserAccessibilityManager()) {
   1156     base::android::ScopedJavaLocalRef<jobject> obj;
   1157     if (content_view_core_)
   1158       obj = content_view_core_->GetJavaObject();
   1159     SetBrowserAccessibilityManager(
   1160         new BrowserAccessibilityManagerAndroid(
   1161             obj,
   1162             BrowserAccessibilityManagerAndroid::GetEmptyDocument(),
   1163             host_));
   1164   }
   1165 }
   1166 
   1167 bool RenderWidgetHostViewAndroid::LockMouse() {
   1168   NOTIMPLEMENTED();
   1169   return false;
   1170 }
   1171 
   1172 void RenderWidgetHostViewAndroid::UnlockMouse() {
   1173   NOTIMPLEMENTED();
   1174 }
   1175 
   1176 // Methods called from the host to the render
   1177 
   1178 void RenderWidgetHostViewAndroid::SendKeyEvent(
   1179     const NativeWebKeyboardEvent& event) {
   1180   if (host_)
   1181     host_->ForwardKeyboardEvent(event);
   1182 }
   1183 
   1184 void RenderWidgetHostViewAndroid::SendTouchEvent(
   1185     const blink::WebTouchEvent& event) {
   1186   if (host_)
   1187     host_->ForwardTouchEventWithLatencyInfo(event, CreateLatencyInfo(event));
   1188 
   1189   // Send a proactive BeginFrame on the next vsync to reduce latency.
   1190   // This is good enough as long as the first touch event has Begin semantics
   1191   // and the actual scroll happens on the next vsync.
   1192   // TODO: Is this actually still needed?
   1193   if (content_view_core_ && observing_root_window_) {
   1194     content_view_core_->GetWindowAndroid()->RequestVSyncUpdate();
   1195   }
   1196 }
   1197 
   1198 void RenderWidgetHostViewAndroid::SendMouseEvent(
   1199     const blink::WebMouseEvent& event) {
   1200   if (host_)
   1201     host_->ForwardMouseEvent(event);
   1202 }
   1203 
   1204 void RenderWidgetHostViewAndroid::SendMouseWheelEvent(
   1205     const blink::WebMouseWheelEvent& event) {
   1206   if (host_)
   1207     host_->ForwardWheelEvent(event);
   1208 }
   1209 
   1210 void RenderWidgetHostViewAndroid::SendGestureEvent(
   1211     const blink::WebGestureEvent& event) {
   1212   // Sending a gesture that may trigger overscroll should resume the effect.
   1213   if (overscroll_effect_enabled_)
   1214    overscroll_effect_->Enable();
   1215 
   1216   if (host_)
   1217     host_->ForwardGestureEventWithLatencyInfo(event, CreateLatencyInfo(event));
   1218 }
   1219 
   1220 void RenderWidgetHostViewAndroid::MoveCaret(const gfx::Point& point) {
   1221   if (host_)
   1222     host_->MoveCaret(point);
   1223 }
   1224 
   1225 SkColor RenderWidgetHostViewAndroid::GetCachedBackgroundColor() const {
   1226   return cached_background_color_;
   1227 }
   1228 
   1229 void RenderWidgetHostViewAndroid::DidOverscroll(
   1230     const DidOverscrollParams& params) {
   1231   if (!content_view_core_ || !layer_ || !is_showing_)
   1232     return;
   1233 
   1234   const float device_scale_factor = content_view_core_->GetDpiScale();
   1235   if (overscroll_effect_->OnOverscrolled(
   1236           content_view_core_->GetLayer(),
   1237           base::TimeTicks::Now(),
   1238           gfx::ScaleVector2d(params.accumulated_overscroll,
   1239                              device_scale_factor),
   1240           gfx::ScaleVector2d(params.latest_overscroll_delta,
   1241                              device_scale_factor),
   1242           gfx::ScaleVector2d(params.current_fling_velocity,
   1243                              device_scale_factor))) {
   1244     SetNeedsAnimate();
   1245   }
   1246 }
   1247 
   1248 void RenderWidgetHostViewAndroid::DidStopFlinging() {
   1249   if (content_view_core_)
   1250     content_view_core_->DidStopFlinging();
   1251 }
   1252 
   1253 void RenderWidgetHostViewAndroid::SetContentViewCore(
   1254     ContentViewCoreImpl* content_view_core) {
   1255   RemoveLayers();
   1256   if (observing_root_window_ && content_view_core_) {
   1257     content_view_core_->GetWindowAndroid()->RemoveObserver(this);
   1258     observing_root_window_ = false;
   1259   }
   1260 
   1261   bool resize = false;
   1262   if (content_view_core != content_view_core_) {
   1263     ReleaseLocksOnSurface();
   1264     resize = true;
   1265   }
   1266 
   1267   content_view_core_ = content_view_core;
   1268 
   1269   if (GetBrowserAccessibilityManager()) {
   1270     base::android::ScopedJavaLocalRef<jobject> obj;
   1271     if (content_view_core_)
   1272       obj = content_view_core_->GetJavaObject();
   1273     GetBrowserAccessibilityManager()->ToBrowserAccessibilityManagerAndroid()->
   1274         SetContentViewCore(obj);
   1275   }
   1276 
   1277   AttachLayers();
   1278   if (content_view_core_ && !using_synchronous_compositor_) {
   1279     content_view_core_->GetWindowAndroid()->AddObserver(this);
   1280     observing_root_window_ = true;
   1281     if (needs_begin_frame_)
   1282       content_view_core_->GetWindowAndroid()->RequestVSyncUpdate();
   1283   }
   1284 
   1285   if (resize && content_view_core_)
   1286     WasResized();
   1287 }
   1288 
   1289 void RenderWidgetHostViewAndroid::RunAckCallbacks() {
   1290   while (!ack_callbacks_.empty()) {
   1291     ack_callbacks_.front().Run();
   1292     ack_callbacks_.pop();
   1293   }
   1294 }
   1295 
   1296 void RenderWidgetHostViewAndroid::OnGestureEvent(
   1297     const ui::GestureEventData& gesture) {
   1298   if (gesture_text_selector_.OnGestureEvent(gesture))
   1299     return;
   1300 
   1301   SendGestureEvent(CreateWebGestureEventFromGestureEventData(gesture));
   1302 }
   1303 
   1304 void RenderWidgetHostViewAndroid::OnCompositingDidCommit() {
   1305   RunAckCallbacks();
   1306 }
   1307 
   1308 void RenderWidgetHostViewAndroid::OnDetachCompositor() {
   1309   DCHECK(content_view_core_);
   1310   DCHECK(!using_synchronous_compositor_);
   1311   RunAckCallbacks();
   1312 }
   1313 
   1314 void RenderWidgetHostViewAndroid::OnVSync(base::TimeTicks frame_time,
   1315                                           base::TimeDelta vsync_period) {
   1316   TRACE_EVENT0("cc", "RenderWidgetHostViewAndroid::OnVSync");
   1317   if (!host_)
   1318     return;
   1319 
   1320   if (flush_input_requested_) {
   1321     flush_input_requested_ = false;
   1322     host_->FlushInput();
   1323   }
   1324 
   1325   TRACE_EVENT0("cc", "RenderWidgetHostViewAndroid::SendBeginFrame");
   1326   base::TimeTicks display_time = frame_time + vsync_period;
   1327 
   1328   // TODO(brianderson): Use adaptive draw-time estimation.
   1329   base::TimeDelta estimated_browser_composite_time =
   1330       base::TimeDelta::FromMicroseconds(
   1331           (1.0f * base::Time::kMicrosecondsPerSecond) / (3.0f * 60));
   1332 
   1333   base::TimeTicks deadline = display_time - estimated_browser_composite_time;
   1334 
   1335   host_->Send(new ViewMsg_BeginFrame(
   1336       host_->GetRoutingID(),
   1337       cc::BeginFrameArgs::Create(frame_time, deadline, vsync_period)));
   1338 
   1339   if (needs_begin_frame_)
   1340     content_view_core_->GetWindowAndroid()->RequestVSyncUpdate();
   1341 }
   1342 
   1343 void RenderWidgetHostViewAndroid::OnAnimate(base::TimeTicks begin_frame_time) {
   1344   if (Animate(begin_frame_time))
   1345     SetNeedsAnimate();
   1346 }
   1347 
   1348 void RenderWidgetHostViewAndroid::OnLostResources() {
   1349   ReleaseLocksOnSurface();
   1350   if (layer_.get())
   1351     DestroyDelegatedContent();
   1352   DCHECK(ack_callbacks_.empty());
   1353 }
   1354 
   1355 // static
   1356 void
   1357 RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResultForDelegatedReadback(
   1358     const gfx::Size& dst_size_in_pixel,
   1359     const SkBitmap::Config config,
   1360     const base::TimeTicks& start_time,
   1361     scoped_refptr<cc::Layer> readback_layer,
   1362     const base::Callback<void(bool, const SkBitmap&)>& callback,
   1363     scoped_ptr<cc::CopyOutputResult> result) {
   1364   readback_layer->RemoveFromParent();
   1365   PrepareTextureCopyOutputResult(
   1366       dst_size_in_pixel, config, start_time, callback, result.Pass());
   1367 }
   1368 
   1369 // static
   1370 void RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResult(
   1371     const gfx::Size& dst_size_in_pixel,
   1372     const SkBitmap::Config bitmap_config,
   1373     const base::TimeTicks& start_time,
   1374     const base::Callback<void(bool, const SkBitmap&)>& callback,
   1375     scoped_ptr<cc::CopyOutputResult> result) {
   1376   base::ScopedClosureRunner scoped_callback_runner(
   1377       base::Bind(callback, false, SkBitmap()));
   1378 
   1379   if (!result->HasTexture() || result->IsEmpty() || result->size().IsEmpty())
   1380     return;
   1381 
   1382   scoped_ptr<SkBitmap> bitmap(new SkBitmap);
   1383   bitmap->setConfig(bitmap_config,
   1384                     dst_size_in_pixel.width(),
   1385                     dst_size_in_pixel.height(),
   1386                     0, kOpaque_SkAlphaType);
   1387   if (!bitmap->allocPixels())
   1388     return;
   1389 
   1390   ImageTransportFactoryAndroid* factory =
   1391       ImageTransportFactoryAndroid::GetInstance();
   1392   GLHelper* gl_helper = factory->GetGLHelper();
   1393 
   1394   if (!gl_helper)
   1395     return;
   1396 
   1397   scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock(
   1398       new SkAutoLockPixels(*bitmap));
   1399   uint8* pixels = static_cast<uint8*>(bitmap->getPixels());
   1400 
   1401   cc::TextureMailbox texture_mailbox;
   1402   scoped_ptr<cc::SingleReleaseCallback> release_callback;
   1403   result->TakeTexture(&texture_mailbox, &release_callback);
   1404   DCHECK(texture_mailbox.IsTexture());
   1405   if (!texture_mailbox.IsTexture())
   1406     return;
   1407 
   1408   ignore_result(scoped_callback_runner.Release());
   1409 
   1410   gl_helper->CropScaleReadbackAndCleanMailbox(
   1411       texture_mailbox.mailbox(),
   1412       texture_mailbox.sync_point(),
   1413       result->size(),
   1414       gfx::Rect(result->size()),
   1415       dst_size_in_pixel,
   1416       pixels,
   1417       bitmap_config,
   1418       base::Bind(&CopyFromCompositingSurfaceFinished,
   1419                  callback,
   1420                  base::Passed(&release_callback),
   1421                  base::Passed(&bitmap),
   1422                  start_time,
   1423                  base::Passed(&bitmap_pixels_lock)),
   1424       GLHelper::SCALER_QUALITY_GOOD);
   1425 }
   1426 
   1427 bool RenderWidgetHostViewAndroid::IsReadbackConfigSupported(
   1428     SkBitmap::Config bitmap_config) {
   1429   ImageTransportFactoryAndroid* factory =
   1430       ImageTransportFactoryAndroid::GetInstance();
   1431   GLHelper* gl_helper = factory->GetGLHelper();
   1432   if (!gl_helper)
   1433     return false;
   1434   return gl_helper->IsReadbackConfigSupported(bitmap_config);
   1435 }
   1436 
   1437 SkBitmap::Config RenderWidgetHostViewAndroid::PreferredReadbackFormat() {
   1438   // Define the criteria here. If say the 16 texture readback is
   1439   // supported we should go with that (this degrades quality)
   1440   // or stick back to the default format.
   1441   if (base::android::SysUtils::IsLowEndDevice()) {
   1442     if (IsReadbackConfigSupported(SkBitmap::kRGB_565_Config))
   1443       return SkBitmap::kRGB_565_Config;
   1444   }
   1445   return SkBitmap::kARGB_8888_Config;
   1446 }
   1447 
   1448 void RenderWidgetHostViewAndroid::ShowSelectionHandlesAutomatically() {
   1449   if (content_view_core_)
   1450     content_view_core_->ShowSelectionHandlesAutomatically();
   1451 }
   1452 
   1453 void RenderWidgetHostViewAndroid::SelectRange(
   1454     float x1, float y1, float x2, float y2) {
   1455   if (content_view_core_)
   1456     static_cast<WebContentsImpl*>(content_view_core_->GetWebContents())->
   1457         SelectRange(gfx::Point(x1, y1), gfx::Point(x2, y2));
   1458 }
   1459 
   1460 void RenderWidgetHostViewAndroid::Unselect() {
   1461   if (content_view_core_)
   1462     content_view_core_->GetWebContents()->Unselect();
   1463 }
   1464 
   1465 void RenderWidgetHostViewAndroid::LongPress(
   1466     base::TimeTicks time, float x, float y) {
   1467   blink::WebGestureEvent long_press = WebGestureEventBuilder::Build(
   1468       blink::WebInputEvent::GestureLongPress,
   1469       (time - base::TimeTicks()).InSecondsF(), x, y);
   1470   SendGestureEvent(long_press);
   1471 }
   1472 
   1473 // static
   1474 void RenderWidgetHostViewBase::GetDefaultScreenInfo(
   1475     blink::WebScreenInfo* results) {
   1476   const gfx::Display& display =
   1477       gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
   1478   results->rect = display.bounds();
   1479   // TODO(husky): Remove any system controls from availableRect.
   1480   results->availableRect = display.work_area();
   1481   results->deviceScaleFactor = display.device_scale_factor();
   1482   results->orientationAngle = display.RotationAsDegree();
   1483   gfx::DeviceDisplayInfo info;
   1484   results->depth = info.GetBitsPerPixel();
   1485   results->depthPerComponent = info.GetBitsPerComponent();
   1486   results->isMonochrome = (results->depthPerComponent == 0);
   1487 }
   1488 
   1489 } // namespace content
   1490