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/build_info.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/sys_info.h"
     19 #include "base/threading/worker_pool.h"
     20 #include "cc/base/latency_info_swap_promise.h"
     21 #include "cc/layers/delegated_frame_provider.h"
     22 #include "cc/layers/delegated_renderer_layer.h"
     23 #include "cc/layers/layer.h"
     24 #include "cc/output/compositor_frame.h"
     25 #include "cc/output/compositor_frame_ack.h"
     26 #include "cc/output/copy_output_request.h"
     27 #include "cc/output/copy_output_result.h"
     28 #include "cc/output/viewport_selection_bound.h"
     29 #include "cc/resources/single_release_callback.h"
     30 #include "cc/trees/layer_tree_host.h"
     31 #include "content/browser/accessibility/browser_accessibility_manager_android.h"
     32 #include "content/browser/android/composited_touch_handle_drawable.h"
     33 #include "content/browser/android/content_view_core_impl.h"
     34 #include "content/browser/android/edge_effect.h"
     35 #include "content/browser/android/edge_effect_l.h"
     36 #include "content/browser/android/in_process/synchronous_compositor_impl.h"
     37 #include "content/browser/android/overscroll_glow.h"
     38 #include "content/browser/devtools/render_view_devtools_agent_host.h"
     39 #include "content/browser/gpu/compositor_util.h"
     40 #include "content/browser/gpu/gpu_data_manager_impl.h"
     41 #include "content/browser/gpu/gpu_process_host_ui_shim.h"
     42 #include "content/browser/gpu/gpu_surface_tracker.h"
     43 #include "content/browser/media/media_web_contents_observer.h"
     44 #include "content/browser/renderer_host/compositor_impl_android.h"
     45 #include "content/browser/renderer_host/dip_util.h"
     46 #include "content/browser/renderer_host/image_transport_factory_android.h"
     47 #include "content/browser/renderer_host/input/synthetic_gesture_target_android.h"
     48 #include "content/browser/renderer_host/input/touch_selection_controller.h"
     49 #include "content/browser/renderer_host/input/web_input_event_builders_android.h"
     50 #include "content/browser/renderer_host/input/web_input_event_util.h"
     51 #include "content/browser/renderer_host/render_process_host_impl.h"
     52 #include "content/browser/renderer_host/render_view_host_impl.h"
     53 #include "content/browser/renderer_host/render_widget_host_impl.h"
     54 #include "content/common/gpu/client/gl_helper.h"
     55 #include "content/common/gpu/gpu_messages.h"
     56 #include "content/common/input/did_overscroll_params.h"
     57 #include "content/common/input_messages.h"
     58 #include "content/common/view_messages.h"
     59 #include "content/public/browser/browser_thread.h"
     60 #include "content/public/browser/devtools_agent_host.h"
     61 #include "content/public/browser/render_view_host.h"
     62 #include "content/public/common/content_switches.h"
     63 #include "gpu/command_buffer/client/gles2_interface.h"
     64 #include "gpu/config/gpu_driver_bug_workaround_type.h"
     65 #include "skia/ext/image_operations.h"
     66 #include "third_party/khronos/GLES2/gl2.h"
     67 #include "third_party/khronos/GLES2/gl2ext.h"
     68 #include "third_party/skia/include/core/SkCanvas.h"
     69 #include "ui/base/android/window_android.h"
     70 #include "ui/base/android/window_android_compositor.h"
     71 #include "ui/events/gesture_detection/gesture_config_helper.h"
     72 #include "ui/events/gesture_detection/motion_event.h"
     73 #include "ui/gfx/android/device_display_info.h"
     74 #include "ui/gfx/android/java_bitmap.h"
     75 #include "ui/gfx/android/view_configuration.h"
     76 #include "ui/gfx/display.h"
     77 #include "ui/gfx/screen.h"
     78 #include "ui/gfx/size_conversions.h"
     79 
     80 namespace content {
     81 
     82 namespace {
     83 
     84 const int kUndefinedOutputSurfaceId = -1;
     85 
     86 // Used to accomodate finite precision when comparing scaled viewport and
     87 // content widths. While this value may seem large, width=device-width on an N7
     88 // V1 saw errors of ~0.065 between computed window and content widths.
     89 const float kMobileViewportWidthEpsilon = 0.15f;
     90 
     91 // Used for conditional creation of EdgeEffect types for overscroll.
     92 const int kKitKatMR2SDKVersion = 19;
     93 
     94 static const char kAsyncReadBackString[] = "Compositing.CopyFromSurfaceTime";
     95 
     96 // Sends an acknowledgement to the renderer of a processed IME event.
     97 void SendImeEventAck(RenderWidgetHostImpl* host) {
     98   host->Send(new ViewMsg_ImeEventAck(host->GetRoutingID()));
     99 }
    100 
    101 void CopyFromCompositingSurfaceFinished(
    102     const base::Callback<void(bool, const SkBitmap&)>& callback,
    103     scoped_ptr<cc::SingleReleaseCallback> release_callback,
    104     scoped_ptr<SkBitmap> bitmap,
    105     const base::TimeTicks& start_time,
    106     scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock,
    107     bool result) {
    108   TRACE_EVENT0(
    109       "cc", "RenderWidgetHostViewAndroid::CopyFromCompositingSurfaceFinished");
    110   bitmap_pixels_lock.reset();
    111   uint32 sync_point = 0;
    112   if (result) {
    113     GLHelper* gl_helper =
    114         ImageTransportFactoryAndroid::GetInstance()->GetGLHelper();
    115     sync_point = gl_helper->InsertSyncPoint();
    116   }
    117   bool lost_resource = sync_point == 0;
    118   release_callback->Run(sync_point, lost_resource);
    119   UMA_HISTOGRAM_TIMES(kAsyncReadBackString,
    120                       base::TimeTicks::Now() - start_time);
    121   callback.Run(result, *bitmap);
    122 }
    123 
    124 ui::LatencyInfo CreateLatencyInfo(const blink::WebInputEvent& event) {
    125   ui::LatencyInfo latency_info;
    126   // The latency number should only be added if the timestamp is valid.
    127   if (event.timeStampSeconds) {
    128     const int64 time_micros = static_cast<int64>(
    129         event.timeStampSeconds * base::Time::kMicrosecondsPerSecond);
    130     latency_info.AddLatencyNumberWithTimestamp(
    131         ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT,
    132         0,
    133         0,
    134         base::TimeTicks() + base::TimeDelta::FromMicroseconds(time_micros),
    135         1);
    136   }
    137   return latency_info;
    138 }
    139 
    140 OverscrollGlow::DisplayParameters CreateOverscrollDisplayParameters(
    141     const cc::CompositorFrameMetadata& frame_metadata) {
    142   const float scale_factor =
    143       frame_metadata.page_scale_factor * frame_metadata.device_scale_factor;
    144 
    145   // Compute the size and offsets for each edge, where each effect is sized to
    146   // the viewport and offset by the distance of each viewport edge to the
    147   // respective content edge.
    148   OverscrollGlow::DisplayParameters params;
    149   params.size = gfx::ScaleSize(
    150       frame_metadata.scrollable_viewport_size, scale_factor);
    151   params.edge_offsets[OverscrollGlow::EDGE_TOP] =
    152       -frame_metadata.root_scroll_offset.y() * scale_factor;
    153   params.edge_offsets[OverscrollGlow::EDGE_LEFT] =
    154       -frame_metadata.root_scroll_offset.x() * scale_factor;
    155   params.edge_offsets[OverscrollGlow::EDGE_BOTTOM] =
    156       (frame_metadata.root_layer_size.height() -
    157        frame_metadata.root_scroll_offset.y() -
    158        frame_metadata.scrollable_viewport_size.height()) *
    159       scale_factor;
    160   params.edge_offsets[OverscrollGlow::EDGE_RIGHT] =
    161       (frame_metadata.root_layer_size.width() -
    162        frame_metadata.root_scroll_offset.x() -
    163        frame_metadata.scrollable_viewport_size.width()) *
    164       scale_factor;
    165 
    166   return params;
    167 }
    168 
    169 bool UseEdgeEffectL() {
    170   static bool use_edge_effect_l =
    171       base::android::BuildInfo::GetInstance()->sdk_int() > kKitKatMR2SDKVersion;
    172   return use_edge_effect_l;
    173 }
    174 
    175 scoped_ptr<EdgeEffectBase> CreateEdgeEffect(
    176     ui::SystemUIResourceManager* resource_manager,
    177     float device_scale_factor) {
    178   DCHECK(resource_manager);
    179   if (UseEdgeEffectL())
    180     return scoped_ptr<EdgeEffectBase>(new EdgeEffectL(resource_manager));
    181 
    182   return scoped_ptr<EdgeEffectBase>(
    183       new EdgeEffect(resource_manager, device_scale_factor));
    184 }
    185 
    186 scoped_ptr<OverscrollGlow> CreateOverscrollEffect(
    187     ContentViewCore* content_view_core) {
    188   DCHECK(content_view_core);
    189   ui::WindowAndroidCompositor* compositor =
    190       content_view_core->GetWindowAndroid()->GetCompositor();
    191   DCHECK(compositor);
    192   ui::SystemUIResourceManager* system_resource_manager =
    193       &compositor->GetSystemUIResourceManager();
    194 
    195   if (UseEdgeEffectL())
    196     EdgeEffectL::PreloadResources(system_resource_manager);
    197   else
    198     EdgeEffect::PreloadResources(system_resource_manager);
    199 
    200   return make_scoped_ptr(
    201       new OverscrollGlow(base::Bind(&CreateEdgeEffect,
    202                                     system_resource_manager,
    203                                     content_view_core->GetDpiScale())));
    204 }
    205 
    206 scoped_ptr<TouchSelectionController> CreateSelectionController(
    207     TouchSelectionControllerClient* client,
    208     ContentViewCore* content_view_core) {
    209   DCHECK(client);
    210   DCHECK(content_view_core);
    211   int tap_timeout_ms = gfx::ViewConfiguration::GetTapTimeoutInMs();
    212   int touch_slop_pixels = gfx::ViewConfiguration::GetTouchSlopInPixels();
    213   return make_scoped_ptr(new TouchSelectionController(
    214       client,
    215       base::TimeDelta::FromMilliseconds(tap_timeout_ms),
    216       touch_slop_pixels / content_view_core->GetDpiScale()));
    217 }
    218 
    219 ui::GestureProvider::Config CreateGestureProviderConfig() {
    220   ui::GestureProvider::Config config = ui::DefaultGestureProviderConfig();
    221   config.disable_click_delay =
    222       base::CommandLine::ForCurrentProcess()->HasSwitch(
    223           switches::kDisableClickDelay);
    224   return config;
    225 }
    226 
    227 bool HasFixedPageScale(const cc::CompositorFrameMetadata& frame_metadata) {
    228   return frame_metadata.min_page_scale_factor ==
    229          frame_metadata.max_page_scale_factor;
    230 }
    231 
    232 bool HasMobileViewport(const cc::CompositorFrameMetadata& frame_metadata) {
    233   float window_width_dip =
    234       frame_metadata.page_scale_factor *
    235           frame_metadata.scrollable_viewport_size.width();
    236   float content_width_css = frame_metadata.root_layer_size.width();
    237   return content_width_css <= window_width_dip + kMobileViewportWidthEpsilon;
    238 }
    239 
    240 }  // anonymous namespace
    241 
    242 ReadbackRequest::ReadbackRequest(
    243     float scale,
    244     SkColorType color_type,
    245     gfx::Rect src_subrect,
    246     const base::Callback<void(bool, const SkBitmap&)>& result_callback)
    247     : scale_(scale),
    248       color_type_(color_type),
    249       src_subrect_(src_subrect),
    250       result_callback_(result_callback) {
    251 }
    252 
    253 ReadbackRequest::ReadbackRequest() {
    254 }
    255 
    256 ReadbackRequest::~ReadbackRequest() {
    257 }
    258 
    259 RenderWidgetHostViewAndroid::LastFrameInfo::LastFrameInfo(
    260     uint32 output_id,
    261     scoped_ptr<cc::CompositorFrame> output_frame)
    262     : output_surface_id(output_id), frame(output_frame.Pass()) {}
    263 
    264 RenderWidgetHostViewAndroid::LastFrameInfo::~LastFrameInfo() {}
    265 
    266 RenderWidgetHostViewAndroid::RenderWidgetHostViewAndroid(
    267     RenderWidgetHostImpl* widget_host,
    268     ContentViewCoreImpl* content_view_core)
    269     : host_(widget_host),
    270       outstanding_vsync_requests_(0),
    271       is_showing_(!widget_host->is_hidden()),
    272       content_view_core_(NULL),
    273       ime_adapter_android_(this),
    274       cached_background_color_(SK_ColorWHITE),
    275       last_output_surface_id_(kUndefinedOutputSurfaceId),
    276       overscroll_effect_enabled_(
    277           !base::CommandLine::ForCurrentProcess()->HasSwitch(
    278               switches::kDisableOverscrollEdgeEffect)),
    279       gesture_provider_(CreateGestureProviderConfig(), this),
    280       gesture_text_selector_(this),
    281       accelerated_surface_route_id_(0),
    282       using_browser_compositor_(CompositorImpl::IsInitialized()),
    283       frame_evictor_(new DelegatedFrameEvictor(this)),
    284       locks_on_frame_count_(0),
    285       observing_root_window_(false),
    286       weak_ptr_factory_(this) {
    287   host_->SetView(this);
    288   SetContentViewCore(content_view_core);
    289   ImageTransportFactoryAndroid::AddObserver(this);
    290 }
    291 
    292 RenderWidgetHostViewAndroid::~RenderWidgetHostViewAndroid() {
    293   ImageTransportFactoryAndroid::RemoveObserver(this);
    294   SetContentViewCore(NULL);
    295   DCHECK(ack_callbacks_.empty());
    296   DCHECK(readbacks_waiting_for_frame_.empty());
    297   if (resource_collection_.get())
    298     resource_collection_->SetClient(NULL);
    299 }
    300 
    301 
    302 bool RenderWidgetHostViewAndroid::OnMessageReceived(
    303     const IPC::Message& message) {
    304   bool handled = true;
    305   IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewAndroid, message)
    306     IPC_MESSAGE_HANDLER(ViewHostMsg_StartContentIntent, OnStartContentIntent)
    307     IPC_MESSAGE_HANDLER(ViewHostMsg_DidChangeBodyBackgroundColor,
    308                         OnDidChangeBodyBackgroundColor)
    309     IPC_MESSAGE_HANDLER(ViewHostMsg_SetNeedsBeginFrame,
    310                         OnSetNeedsBeginFrame)
    311     IPC_MESSAGE_HANDLER(ViewHostMsg_TextInputStateChanged,
    312                         OnTextInputStateChanged)
    313     IPC_MESSAGE_HANDLER(ViewHostMsg_SmartClipDataExtracted,
    314                         OnSmartClipDataExtracted)
    315     IPC_MESSAGE_UNHANDLED(handled = false)
    316   IPC_END_MESSAGE_MAP()
    317   return handled;
    318 }
    319 
    320 void RenderWidgetHostViewAndroid::InitAsChild(gfx::NativeView parent_view) {
    321   NOTIMPLEMENTED();
    322 }
    323 
    324 void RenderWidgetHostViewAndroid::InitAsPopup(
    325     RenderWidgetHostView* parent_host_view, const gfx::Rect& pos) {
    326   NOTIMPLEMENTED();
    327 }
    328 
    329 void RenderWidgetHostViewAndroid::InitAsFullscreen(
    330     RenderWidgetHostView* reference_host_view) {
    331   NOTIMPLEMENTED();
    332 }
    333 
    334 RenderWidgetHost*
    335 RenderWidgetHostViewAndroid::GetRenderWidgetHost() const {
    336   return host_;
    337 }
    338 
    339 void RenderWidgetHostViewAndroid::WasShown() {
    340   if (!host_ || !host_->is_hidden())
    341     return;
    342 
    343   host_->WasShown(ui::LatencyInfo());
    344 
    345   if (content_view_core_) {
    346     StartObservingRootWindow();
    347     RequestVSyncUpdate(BEGIN_FRAME);
    348   }
    349 }
    350 
    351 void RenderWidgetHostViewAndroid::WasHidden() {
    352   RunAckCallbacks();
    353 
    354   if (!host_ || host_->is_hidden())
    355     return;
    356 
    357   // Inform the renderer that we are being hidden so it can reduce its resource
    358   // utilization.
    359   host_->WasHidden();
    360 
    361   StopObservingRootWindow();
    362 }
    363 
    364 void RenderWidgetHostViewAndroid::WasResized() {
    365   host_->WasResized();
    366 }
    367 
    368 void RenderWidgetHostViewAndroid::SetSize(const gfx::Size& size) {
    369   // Ignore the given size as only the Java code has the power to
    370   // resize the view on Android.
    371   default_size_ = size;
    372 }
    373 
    374 void RenderWidgetHostViewAndroid::SetBounds(const gfx::Rect& rect) {
    375   SetSize(rect.size());
    376 }
    377 
    378 void RenderWidgetHostViewAndroid::AbortPendingReadbackRequests() {
    379   while (!readbacks_waiting_for_frame_.empty()) {
    380     ReadbackRequest& readback_request = readbacks_waiting_for_frame_.front();
    381     readback_request.GetResultCallback().Run(false, SkBitmap());
    382     readbacks_waiting_for_frame_.pop();
    383   }
    384 }
    385 
    386 void RenderWidgetHostViewAndroid::GetScaledContentBitmap(
    387     float scale,
    388     SkColorType color_type,
    389     gfx::Rect src_subrect,
    390     CopyFromCompositingSurfaceCallback& result_callback) {
    391   if (!host_ || host_->is_hidden()) {
    392     result_callback.Run(false, SkBitmap());
    393     return;
    394   }
    395   if (!IsSurfaceAvailableForCopy()) {
    396     // The view is visible, probably the frame has not yet arrived.
    397     // Just add the ReadbackRequest to queue and wait for frame arrival
    398     // to get this request processed.
    399     readbacks_waiting_for_frame_.push(
    400         ReadbackRequest(scale, color_type, src_subrect, result_callback));
    401     return;
    402   }
    403 
    404   gfx::Size bounds = layer_->bounds();
    405   if (src_subrect.IsEmpty())
    406     src_subrect = gfx::Rect(bounds);
    407   DCHECK_LE(src_subrect.width() + src_subrect.x(), bounds.width());
    408   DCHECK_LE(src_subrect.height() + src_subrect.y(), bounds.height());
    409   const gfx::Display& display =
    410       gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
    411   float device_scale_factor = display.device_scale_factor();
    412   DCHECK_GT(device_scale_factor, 0);
    413   gfx::Size dst_size(
    414       gfx::ToCeiledSize(gfx::ScaleSize(bounds, scale / device_scale_factor)));
    415   CopyFromCompositingSurface(
    416       src_subrect, dst_size, result_callback, color_type);
    417 }
    418 
    419 scoped_refptr<cc::DelegatedRendererLayer>
    420 RenderWidgetHostViewAndroid::CreateDelegatedLayerForFrameProvider() const {
    421   DCHECK(frame_provider_);
    422 
    423   scoped_refptr<cc::DelegatedRendererLayer> delegated_layer =
    424       cc::DelegatedRendererLayer::Create(frame_provider_);
    425   delegated_layer->SetBounds(content_size_in_layer_);
    426   delegated_layer->SetIsDrawable(true);
    427   delegated_layer->SetContentsOpaque(true);
    428 
    429   return delegated_layer;
    430 }
    431 
    432 bool RenderWidgetHostViewAndroid::HasValidFrame() const {
    433   if (!content_view_core_)
    434     return false;
    435   if (!layer_)
    436     return false;
    437 
    438   if (texture_size_in_layer_.IsEmpty())
    439     return false;
    440   // This tell us whether a valid frame has arrived or not.
    441   if (!frame_evictor_->HasFrame())
    442     return false;
    443 
    444   return true;
    445 }
    446 
    447 gfx::Vector2dF RenderWidgetHostViewAndroid::GetLastScrollOffset() const {
    448   return last_scroll_offset_;
    449 }
    450 
    451 gfx::NativeView RenderWidgetHostViewAndroid::GetNativeView() const {
    452   return content_view_core_->GetViewAndroid();
    453 }
    454 
    455 gfx::NativeViewId RenderWidgetHostViewAndroid::GetNativeViewId() const {
    456   return reinterpret_cast<gfx::NativeViewId>(
    457       const_cast<RenderWidgetHostViewAndroid*>(this));
    458 }
    459 
    460 gfx::NativeViewAccessible
    461 RenderWidgetHostViewAndroid::GetNativeViewAccessible() {
    462   NOTIMPLEMENTED();
    463   return NULL;
    464 }
    465 
    466 void RenderWidgetHostViewAndroid::MovePluginWindows(
    467     const std::vector<WebPluginGeometry>& moves) {
    468   // We don't have plugin windows on Android. Do nothing. Note: this is called
    469   // from RenderWidgetHost::OnUpdateRect which is itself invoked while
    470   // processing the corresponding message from Renderer.
    471 }
    472 
    473 void RenderWidgetHostViewAndroid::Focus() {
    474   host_->Focus();
    475   host_->SetInputMethodActive(true);
    476   if (overscroll_effect_)
    477     overscroll_effect_->Enable();
    478 }
    479 
    480 void RenderWidgetHostViewAndroid::Blur() {
    481   host_->SetInputMethodActive(false);
    482   host_->Blur();
    483   if (overscroll_effect_)
    484     overscroll_effect_->Disable();
    485 }
    486 
    487 bool RenderWidgetHostViewAndroid::HasFocus() const {
    488   if (!content_view_core_)
    489     return false;  // ContentViewCore not created yet.
    490 
    491   return content_view_core_->HasFocus();
    492 }
    493 
    494 bool RenderWidgetHostViewAndroid::IsSurfaceAvailableForCopy() const {
    495   return HasValidFrame();
    496 }
    497 
    498 void RenderWidgetHostViewAndroid::Show() {
    499   if (is_showing_)
    500     return;
    501 
    502   is_showing_ = true;
    503   if (layer_)
    504     layer_->SetHideLayerAndSubtree(false);
    505 
    506   frame_evictor_->SetVisible(true);
    507   WasShown();
    508 }
    509 
    510 void RenderWidgetHostViewAndroid::Hide() {
    511   if (!is_showing_)
    512     return;
    513 
    514   is_showing_ = false;
    515   if (layer_ && locks_on_frame_count_ == 0)
    516     layer_->SetHideLayerAndSubtree(true);
    517 
    518   frame_evictor_->SetVisible(false);
    519   // We don't know if we will ever get a frame if we are hiding the renderer, so
    520   // we need to cancel all requests
    521   AbortPendingReadbackRequests();
    522   WasHidden();
    523 }
    524 
    525 bool RenderWidgetHostViewAndroid::IsShowing() {
    526   // ContentViewCoreImpl represents the native side of the Java
    527   // ContentViewCore.  It being NULL means that it is not attached
    528   // to the View system yet, so we treat this RWHVA as hidden.
    529   return is_showing_ && content_view_core_;
    530 }
    531 
    532 void RenderWidgetHostViewAndroid::LockCompositingSurface() {
    533   DCHECK(HasValidFrame());
    534   DCHECK(host_);
    535   DCHECK(frame_evictor_->HasFrame());
    536   frame_evictor_->LockFrame();
    537   locks_on_frame_count_++;
    538 }
    539 
    540 void RenderWidgetHostViewAndroid::UnlockCompositingSurface() {
    541   if (!frame_evictor_->HasFrame() || locks_on_frame_count_ == 0)
    542     return;
    543 
    544   DCHECK(HasValidFrame());
    545   frame_evictor_->UnlockFrame();
    546   locks_on_frame_count_--;
    547 
    548   if (locks_on_frame_count_ == 0) {
    549     if (last_frame_info_) {
    550       InternalSwapCompositorFrame(last_frame_info_->output_surface_id,
    551                                   last_frame_info_->frame.Pass());
    552       last_frame_info_.reset();
    553     }
    554 
    555     if (!is_showing_ && layer_)
    556       layer_->SetHideLayerAndSubtree(true);
    557   }
    558 }
    559 
    560 void RenderWidgetHostViewAndroid::SetTextSurroundingSelectionCallback(
    561     const TextSurroundingSelectionCallback& callback) {
    562   // Only one outstanding request is allowed at any given time.
    563   DCHECK(!callback.is_null());
    564   text_surrounding_selection_callback_ = callback;
    565 }
    566 
    567 void RenderWidgetHostViewAndroid::OnTextSurroundingSelectionResponse(
    568     const base::string16& content,
    569     size_t start_offset,
    570     size_t end_offset) {
    571   if (text_surrounding_selection_callback_.is_null())
    572     return;
    573   text_surrounding_selection_callback_.Run(content, start_offset, end_offset);
    574   text_surrounding_selection_callback_.Reset();
    575 }
    576 
    577 void RenderWidgetHostViewAndroid::ReleaseLocksOnSurface() {
    578   if (!frame_evictor_->HasFrame()) {
    579     DCHECK_EQ(locks_on_frame_count_, 0u);
    580     return;
    581   }
    582   while (locks_on_frame_count_ > 0) {
    583     UnlockCompositingSurface();
    584   }
    585   RunAckCallbacks();
    586 }
    587 
    588 gfx::Rect RenderWidgetHostViewAndroid::GetViewBounds() const {
    589   if (!content_view_core_)
    590     return gfx::Rect(default_size_);
    591 
    592   return gfx::Rect(content_view_core_->GetViewSize());
    593 }
    594 
    595 gfx::Size RenderWidgetHostViewAndroid::GetPhysicalBackingSize() const {
    596   if (!content_view_core_)
    597     return gfx::Size();
    598 
    599   return content_view_core_->GetPhysicalBackingSize();
    600 }
    601 
    602 float RenderWidgetHostViewAndroid::GetTopControlsLayoutHeight() const {
    603   if (!content_view_core_)
    604     return 0.f;
    605 
    606   // The amount that the viewport size given to Blink is shrunk by the URL-bar.
    607   return content_view_core_->GetTopControlsLayoutHeightDip();
    608 }
    609 
    610 void RenderWidgetHostViewAndroid::UpdateCursor(const WebCursor& cursor) {
    611   // There are no cursors on Android.
    612 }
    613 
    614 void RenderWidgetHostViewAndroid::SetIsLoading(bool is_loading) {
    615   // Do nothing. The UI notification is handled through ContentViewClient which
    616   // is TabContentsDelegate.
    617 }
    618 
    619 void RenderWidgetHostViewAndroid::TextInputTypeChanged(
    620     ui::TextInputType type,
    621     ui::TextInputMode input_mode,
    622     bool can_compose_inline) {
    623   // Unused on Android, which uses OnTextInputChanged instead.
    624 }
    625 
    626 long RenderWidgetHostViewAndroid::GetNativeImeAdapter() {
    627   return reinterpret_cast<intptr_t>(&ime_adapter_android_);
    628 }
    629 
    630 void RenderWidgetHostViewAndroid::OnTextInputStateChanged(
    631     const ViewHostMsg_TextInputState_Params& params) {
    632   if (selection_controller_) {
    633     // This call is semi-redundant with that in |OnFocusedNodeChanged|. The
    634     // latter is guaranteed to be called before |OnSelectionBoundsChanged|,
    635     // while this call is present to ensure consistency with IME after
    636     // navigation and tab focus changes
    637     const bool is_editable_node = params.type != ui::TEXT_INPUT_TYPE_NONE;
    638     selection_controller_->OnSelectionEditable(is_editable_node);
    639   }
    640 
    641   // If the change is not originated from IME (e.g. Javascript, autofill),
    642   // send back the renderer an acknowledgement, regardless of how we exit from
    643   // this method.
    644   base::ScopedClosureRunner ack_caller;
    645   if (params.is_non_ime_change)
    646     ack_caller.Reset(base::Bind(&SendImeEventAck, host_));
    647 
    648   if (!IsShowing())
    649     return;
    650 
    651   content_view_core_->UpdateImeAdapter(
    652       GetNativeImeAdapter(),
    653       static_cast<int>(params.type), params.flags,
    654       params.value, params.selection_start, params.selection_end,
    655       params.composition_start, params.composition_end,
    656       params.show_ime_if_needed, params.is_non_ime_change);
    657 }
    658 
    659 void RenderWidgetHostViewAndroid::OnDidChangeBodyBackgroundColor(
    660     SkColor color) {
    661   if (cached_background_color_ == color)
    662     return;
    663 
    664   cached_background_color_ = color;
    665   if (content_view_core_)
    666     content_view_core_->OnBackgroundColorChanged(color);
    667 }
    668 
    669 void RenderWidgetHostViewAndroid::OnSetNeedsBeginFrame(bool enabled) {
    670   DCHECK(using_browser_compositor_);
    671   TRACE_EVENT1("cc", "RenderWidgetHostViewAndroid::OnSetNeedsBeginFrame",
    672                "enabled", enabled);
    673   if (enabled)
    674     RequestVSyncUpdate(PERSISTENT_BEGIN_FRAME);
    675   else
    676     outstanding_vsync_requests_ &= ~PERSISTENT_BEGIN_FRAME;
    677 }
    678 
    679 void RenderWidgetHostViewAndroid::OnStartContentIntent(
    680     const GURL& content_url) {
    681   if (content_view_core_)
    682     content_view_core_->StartContentIntent(content_url);
    683 }
    684 
    685 void RenderWidgetHostViewAndroid::OnSmartClipDataExtracted(
    686     const base::string16& text,
    687     const base::string16& html,
    688     const gfx::Rect rect) {
    689   if (content_view_core_)
    690     content_view_core_->OnSmartClipDataExtracted(text, html, rect);
    691 }
    692 
    693 bool RenderWidgetHostViewAndroid::OnTouchEvent(
    694     const ui::MotionEvent& event) {
    695   if (!host_)
    696     return false;
    697 
    698   if (selection_controller_ &&
    699       selection_controller_->WillHandleTouchEvent(event))
    700     return true;
    701 
    702   if (!gesture_provider_.OnTouchEvent(event))
    703     return false;
    704 
    705   if (gesture_text_selector_.OnTouchEvent(event)) {
    706     gesture_provider_.OnTouchEventAck(false);
    707     return true;
    708   }
    709 
    710   if (host_->ShouldForwardTouchEvent()) {
    711     blink::WebTouchEvent web_event = CreateWebTouchEventFromMotionEvent(event);
    712     host_->ForwardTouchEventWithLatencyInfo(web_event,
    713                                             CreateLatencyInfo(web_event));
    714   } else {
    715     const bool event_consumed = false;
    716     gesture_provider_.OnTouchEventAck(event_consumed);
    717   }
    718 
    719   // Send a proactive BeginFrame on the next vsync to reduce latency.
    720   // This is good enough as long as the first touch event has Begin semantics
    721   // and the actual scroll happens on the next vsync.
    722   if (observing_root_window_)
    723     RequestVSyncUpdate(BEGIN_FRAME);
    724 
    725   return true;
    726 }
    727 
    728 bool RenderWidgetHostViewAndroid::OnTouchHandleEvent(
    729     const ui::MotionEvent& event) {
    730   return selection_controller_ &&
    731          selection_controller_->WillHandleTouchEvent(event);
    732 }
    733 
    734 void RenderWidgetHostViewAndroid::ResetGestureDetection() {
    735   const ui::MotionEvent* current_down_event =
    736       gesture_provider_.GetCurrentDownEvent();
    737   if (!current_down_event)
    738     return;
    739 
    740   scoped_ptr<ui::MotionEvent> cancel_event = current_down_event->Cancel();
    741   DCHECK(cancel_event);
    742   OnTouchEvent(*cancel_event);
    743 }
    744 
    745 void RenderWidgetHostViewAndroid::SetDoubleTapSupportEnabled(bool enabled) {
    746   gesture_provider_.SetDoubleTapSupportForPlatformEnabled(enabled);
    747 }
    748 
    749 void RenderWidgetHostViewAndroid::SetMultiTouchZoomSupportEnabled(
    750     bool enabled) {
    751   gesture_provider_.SetMultiTouchZoomSupportEnabled(enabled);
    752 }
    753 
    754 void RenderWidgetHostViewAndroid::ImeCancelComposition() {
    755   ime_adapter_android_.CancelComposition();
    756 }
    757 
    758 void RenderWidgetHostViewAndroid::FocusedNodeChanged(bool is_editable_node) {
    759   ime_adapter_android_.FocusedNodeChanged(is_editable_node);
    760   if (selection_controller_)
    761     selection_controller_->OnSelectionEditable(is_editable_node);
    762 }
    763 
    764 void RenderWidgetHostViewAndroid::RenderProcessGone(
    765     base::TerminationStatus status, int error_code) {
    766   Destroy();
    767 }
    768 
    769 void RenderWidgetHostViewAndroid::Destroy() {
    770   RemoveLayers();
    771   SetContentViewCore(NULL);
    772 
    773   // The RenderWidgetHost's destruction led here, so don't call it.
    774   host_ = NULL;
    775 
    776   delete this;
    777 }
    778 
    779 void RenderWidgetHostViewAndroid::SetTooltipText(
    780     const base::string16& tooltip_text) {
    781   // Tooltips don't makes sense on Android.
    782 }
    783 
    784 void RenderWidgetHostViewAndroid::SelectionChanged(const base::string16& text,
    785                                                    size_t offset,
    786                                                    const gfx::Range& range) {
    787   RenderWidgetHostViewBase::SelectionChanged(text, offset, range);
    788 
    789   if (selection_controller_)
    790     selection_controller_->OnSelectionEmpty(text.empty());
    791 
    792   if (!content_view_core_)
    793     return;
    794   if (range.is_empty()) {
    795     content_view_core_->OnSelectionChanged("");
    796     return;
    797   }
    798 
    799   DCHECK(!text.empty());
    800   size_t pos = range.GetMin() - offset;
    801   size_t n = range.length();
    802 
    803   DCHECK(pos + n <= text.length()) << "The text can not fully cover range.";
    804   if (pos >= text.length()) {
    805     NOTREACHED() << "The text can not cover range.";
    806     return;
    807   }
    808 
    809   std::string utf8_selection = base::UTF16ToUTF8(text.substr(pos, n));
    810 
    811   content_view_core_->OnSelectionChanged(utf8_selection);
    812 }
    813 
    814 void RenderWidgetHostViewAndroid::SelectionBoundsChanged(
    815     const ViewHostMsg_SelectionBounds_Params& params) {
    816   NOTREACHED() << "Selection bounds should be routed through the compositor.";
    817 }
    818 
    819 void RenderWidgetHostViewAndroid::SetBackgroundOpaque(bool opaque) {
    820   RenderWidgetHostViewBase::SetBackgroundOpaque(opaque);
    821   host_->SetBackgroundOpaque(opaque);
    822 }
    823 
    824 void RenderWidgetHostViewAndroid::CopyFromCompositingSurface(
    825     const gfx::Rect& src_subrect,
    826     const gfx::Size& dst_size,
    827     CopyFromCompositingSurfaceCallback& callback,
    828     const SkColorType color_type) {
    829   TRACE_EVENT0("cc", "RenderWidgetHostViewAndroid::CopyFromCompositingSurface");
    830   if ((!host_ || host_->is_hidden()) ||
    831       !IsReadbackConfigSupported(color_type)) {
    832     callback.Run(false, SkBitmap());
    833     return;
    834   }
    835   base::TimeTicks start_time = base::TimeTicks::Now();
    836   if (using_browser_compositor_ && !IsSurfaceAvailableForCopy()) {
    837     callback.Run(false, SkBitmap());
    838     return;
    839   }
    840   const gfx::Display& display =
    841       gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
    842   float device_scale_factor = display.device_scale_factor();
    843   gfx::Size dst_size_in_pixel =
    844       ConvertRectToPixel(device_scale_factor, gfx::Rect(dst_size)).size();
    845   gfx::Rect src_subrect_in_pixel =
    846       ConvertRectToPixel(device_scale_factor, src_subrect);
    847 
    848   if (!using_browser_compositor_) {
    849     SynchronousCopyContents(src_subrect_in_pixel, dst_size_in_pixel, callback,
    850                             color_type);
    851     UMA_HISTOGRAM_TIMES("Compositing.CopyFromSurfaceTimeSynchronous",
    852                         base::TimeTicks::Now() - start_time);
    853     return;
    854   }
    855 
    856   scoped_ptr<cc::CopyOutputRequest> request;
    857   scoped_refptr<cc::Layer> readback_layer;
    858   DCHECK(content_view_core_);
    859   DCHECK(content_view_core_->GetWindowAndroid());
    860   ui::WindowAndroidCompositor* compositor =
    861       content_view_core_->GetWindowAndroid()->GetCompositor();
    862   DCHECK(compositor);
    863   DCHECK(frame_provider_);
    864   scoped_refptr<cc::DelegatedRendererLayer> delegated_layer =
    865       CreateDelegatedLayerForFrameProvider();
    866   delegated_layer->SetHideLayerAndSubtree(true);
    867   compositor->AttachLayerForReadback(delegated_layer);
    868 
    869   readback_layer = delegated_layer;
    870   request = cc::CopyOutputRequest::CreateRequest(
    871       base::Bind(&RenderWidgetHostViewAndroid::
    872                      PrepareTextureCopyOutputResultForDelegatedReadback,
    873                  dst_size_in_pixel,
    874                  color_type,
    875                  start_time,
    876                  readback_layer,
    877                  callback));
    878   request->set_area(src_subrect_in_pixel);
    879   readback_layer->RequestCopyOfOutput(request.Pass());
    880 }
    881 
    882 void RenderWidgetHostViewAndroid::CopyFromCompositingSurfaceToVideoFrame(
    883       const gfx::Rect& src_subrect,
    884       const scoped_refptr<media::VideoFrame>& target,
    885       const base::Callback<void(bool)>& callback) {
    886   NOTIMPLEMENTED();
    887   callback.Run(false);
    888 }
    889 
    890 bool RenderWidgetHostViewAndroid::CanCopyToVideoFrame() const {
    891   return false;
    892 }
    893 
    894 void RenderWidgetHostViewAndroid::ShowDisambiguationPopup(
    895     const gfx::Rect& rect_pixels, const SkBitmap& zoomed_bitmap) {
    896   if (!content_view_core_)
    897     return;
    898 
    899   content_view_core_->ShowDisambiguationPopup(rect_pixels, zoomed_bitmap);
    900 }
    901 
    902 scoped_ptr<SyntheticGestureTarget>
    903 RenderWidgetHostViewAndroid::CreateSyntheticGestureTarget() {
    904   return scoped_ptr<SyntheticGestureTarget>(new SyntheticGestureTargetAndroid(
    905       host_, content_view_core_->CreateTouchEventSynthesizer()));
    906 }
    907 
    908 void RenderWidgetHostViewAndroid::SendDelegatedFrameAck(
    909     uint32 output_surface_id) {
    910   DCHECK(host_);
    911   cc::CompositorFrameAck ack;
    912   if (resource_collection_.get())
    913     resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources);
    914   RenderWidgetHostImpl::SendSwapCompositorFrameAck(host_->GetRoutingID(),
    915                                                    output_surface_id,
    916                                                    host_->GetProcess()->GetID(),
    917                                                    ack);
    918 }
    919 
    920 void RenderWidgetHostViewAndroid::SendReturnedDelegatedResources(
    921     uint32 output_surface_id) {
    922   DCHECK(resource_collection_);
    923 
    924   cc::CompositorFrameAck ack;
    925   resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources);
    926   DCHECK(!ack.resources.empty());
    927 
    928   RenderWidgetHostImpl::SendReclaimCompositorResources(
    929       host_->GetRoutingID(),
    930       output_surface_id,
    931       host_->GetProcess()->GetID(),
    932       ack);
    933 }
    934 
    935 void RenderWidgetHostViewAndroid::UnusedResourcesAreAvailable() {
    936   if (ack_callbacks_.size())
    937     return;
    938   SendReturnedDelegatedResources(last_output_surface_id_);
    939 }
    940 
    941 void RenderWidgetHostViewAndroid::DestroyDelegatedContent() {
    942   RemoveLayers();
    943   frame_provider_ = NULL;
    944   layer_ = NULL;
    945   // This gets called when ever any eviction, loosing resources, swapping
    946   // problems are encountered and so we abort any pending readbacks here.
    947   AbortPendingReadbackRequests();
    948 }
    949 
    950 void RenderWidgetHostViewAndroid::SwapDelegatedFrame(
    951     uint32 output_surface_id,
    952     scoped_ptr<cc::DelegatedFrameData> frame_data) {
    953   bool has_content = !texture_size_in_layer_.IsEmpty();
    954 
    955   if (output_surface_id != last_output_surface_id_) {
    956     // Drop the cc::DelegatedFrameResourceCollection so that we will not return
    957     // any resources from the old output surface with the new output surface id.
    958     if (resource_collection_.get()) {
    959       resource_collection_->SetClient(NULL);
    960       if (resource_collection_->LoseAllResources())
    961         SendReturnedDelegatedResources(last_output_surface_id_);
    962       resource_collection_ = NULL;
    963     }
    964     DestroyDelegatedContent();
    965 
    966     last_output_surface_id_ = output_surface_id;
    967   }
    968 
    969   // DelegatedRendererLayerImpl applies the inverse device_scale_factor of the
    970   // renderer frame, assuming that the browser compositor will scale
    971   // it back up to device scale.  But on Android we put our browser layers in
    972   // physical pixels and set our browser CC device_scale_factor to 1, so this
    973   // suppresses the transform.  This line may need to be removed when fixing
    974   // http://crbug.com/384134 or http://crbug.com/310763
    975   frame_data->device_scale_factor = 1.0f;
    976 
    977   if (!has_content) {
    978     DestroyDelegatedContent();
    979   } else {
    980     if (!resource_collection_.get()) {
    981       resource_collection_ = new cc::DelegatedFrameResourceCollection;
    982       resource_collection_->SetClient(this);
    983     }
    984     if (!frame_provider_ ||
    985         texture_size_in_layer_ != frame_provider_->frame_size()) {
    986       RemoveLayers();
    987       frame_provider_ = new cc::DelegatedFrameProvider(
    988           resource_collection_.get(), frame_data.Pass());
    989       layer_ = cc::DelegatedRendererLayer::Create(frame_provider_);
    990       AttachLayers();
    991     } else {
    992       frame_provider_->SetFrameData(frame_data.Pass());
    993     }
    994   }
    995 
    996   if (layer_.get()) {
    997     layer_->SetIsDrawable(true);
    998     layer_->SetContentsOpaque(true);
    999     layer_->SetBounds(content_size_in_layer_);
   1000     layer_->SetNeedsDisplay();
   1001   }
   1002 
   1003   base::Closure ack_callback =
   1004       base::Bind(&RenderWidgetHostViewAndroid::SendDelegatedFrameAck,
   1005                  weak_ptr_factory_.GetWeakPtr(),
   1006                  output_surface_id);
   1007 
   1008   ack_callbacks_.push(ack_callback);
   1009   if (host_->is_hidden())
   1010     RunAckCallbacks();
   1011 }
   1012 
   1013 void RenderWidgetHostViewAndroid::ComputeContentsSize(
   1014     const cc::CompositorFrameMetadata& frame_metadata) {
   1015   // Calculate the content size.  This should be 0 if the texture_size is 0.
   1016   gfx::Vector2dF offset;
   1017   if (texture_size_in_layer_.IsEmpty())
   1018     content_size_in_layer_ = gfx::Size();
   1019   content_size_in_layer_ = gfx::ToCeiledSize(gfx::ScaleSize(
   1020       frame_metadata.scrollable_viewport_size,
   1021       frame_metadata.device_scale_factor * frame_metadata.page_scale_factor));
   1022 
   1023   if (overscroll_effect_) {
   1024     overscroll_effect_->UpdateDisplayParameters(
   1025         CreateOverscrollDisplayParameters(frame_metadata));
   1026   }
   1027 }
   1028 
   1029 void RenderWidgetHostViewAndroid::InternalSwapCompositorFrame(
   1030     uint32 output_surface_id,
   1031     scoped_ptr<cc::CompositorFrame> frame) {
   1032   last_scroll_offset_ = frame->metadata.root_scroll_offset;
   1033   if (!frame->delegated_frame_data) {
   1034     LOG(ERROR) << "Non-delegated renderer path no longer supported";
   1035     return;
   1036   }
   1037 
   1038   if (locks_on_frame_count_ > 0) {
   1039     DCHECK(HasValidFrame());
   1040     RetainFrame(output_surface_id, frame.Pass());
   1041     return;
   1042   }
   1043 
   1044   if (layer_ && layer_->layer_tree_host()) {
   1045     for (size_t i = 0; i < frame->metadata.latency_info.size(); i++) {
   1046       scoped_ptr<cc::SwapPromise> swap_promise(
   1047           new cc::LatencyInfoSwapPromise(frame->metadata.latency_info[i]));
   1048       layer_->layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
   1049     }
   1050   }
   1051 
   1052   DCHECK(!frame->delegated_frame_data->render_pass_list.empty());
   1053 
   1054   cc::RenderPass* root_pass =
   1055       frame->delegated_frame_data->render_pass_list.back();
   1056   texture_size_in_layer_ = root_pass->output_rect.size();
   1057   ComputeContentsSize(frame->metadata);
   1058 
   1059   SwapDelegatedFrame(output_surface_id, frame->delegated_frame_data.Pass());
   1060   frame_evictor_->SwappedFrame(!host_->is_hidden());
   1061 
   1062   // As the metadata update may trigger view invalidation, always call it after
   1063   // any potential compositor scheduling.
   1064   OnFrameMetadataUpdated(frame->metadata);
   1065   // Check if we have any pending readbacks, see if we have a frame available
   1066   // and process them here.
   1067   if (!readbacks_waiting_for_frame_.empty()) {
   1068     while (!readbacks_waiting_for_frame_.empty()) {
   1069       ReadbackRequest& readback_request = readbacks_waiting_for_frame_.front();
   1070       GetScaledContentBitmap(readback_request.GetScale(),
   1071                              readback_request.GetColorFormat(),
   1072                              readback_request.GetCaptureRect(),
   1073                              readback_request.GetResultCallback());
   1074       readbacks_waiting_for_frame_.pop();
   1075     }
   1076   }
   1077 }
   1078 
   1079 void RenderWidgetHostViewAndroid::OnSwapCompositorFrame(
   1080     uint32 output_surface_id,
   1081     scoped_ptr<cc::CompositorFrame> frame) {
   1082   InternalSwapCompositorFrame(output_surface_id, frame.Pass());
   1083 }
   1084 
   1085 void RenderWidgetHostViewAndroid::RetainFrame(
   1086     uint32 output_surface_id,
   1087     scoped_ptr<cc::CompositorFrame> frame) {
   1088   DCHECK(locks_on_frame_count_);
   1089 
   1090   // Store the incoming frame so that it can be swapped when all the locks have
   1091   // been released. If there is already a stored frame, then replace and skip
   1092   // the previous one but make sure we still eventually send the ACK. Holding
   1093   // the ACK also blocks the renderer when its max_frames_pending is reached.
   1094   if (last_frame_info_) {
   1095     base::Closure ack_callback =
   1096         base::Bind(&RenderWidgetHostViewAndroid::SendDelegatedFrameAck,
   1097                    weak_ptr_factory_.GetWeakPtr(),
   1098                    last_frame_info_->output_surface_id);
   1099 
   1100     ack_callbacks_.push(ack_callback);
   1101   }
   1102 
   1103   last_frame_info_.reset(new LastFrameInfo(output_surface_id, frame.Pass()));
   1104 }
   1105 
   1106 void RenderWidgetHostViewAndroid::SynchronousFrameMetadata(
   1107     const cc::CompositorFrameMetadata& frame_metadata) {
   1108   if (!content_view_core_)
   1109     return;
   1110 
   1111   // This is a subset of OnSwapCompositorFrame() used in the synchronous
   1112   // compositor flow.
   1113   OnFrameMetadataUpdated(frame_metadata);
   1114   ComputeContentsSize(frame_metadata);
   1115 
   1116   // DevTools ScreenCast support for Android WebView.
   1117   WebContents* web_contents = content_view_core_->GetWebContents();
   1118   if (DevToolsAgentHost::HasFor(web_contents)) {
   1119     scoped_refptr<DevToolsAgentHost> dtah =
   1120         DevToolsAgentHost::GetOrCreateFor(web_contents);
   1121     // Unblock the compositor.
   1122     BrowserThread::PostTask(
   1123         BrowserThread::UI, FROM_HERE,
   1124         base::Bind(&RenderViewDevToolsAgentHost::SynchronousSwapCompositorFrame,
   1125                    static_cast<RenderViewDevToolsAgentHost*>(dtah.get()),
   1126                    frame_metadata));
   1127   }
   1128 }
   1129 
   1130 void RenderWidgetHostViewAndroid::SetOverlayVideoMode(bool enabled) {
   1131   if (layer_)
   1132     layer_->SetContentsOpaque(!enabled);
   1133 }
   1134 
   1135 bool RenderWidgetHostViewAndroid::SupportsAnimation() const {
   1136   // The synchronous (WebView) compositor does not have a proper browser
   1137   // compositor with which to drive animations.
   1138   return using_browser_compositor_;
   1139 }
   1140 
   1141 void RenderWidgetHostViewAndroid::SetNeedsAnimate() {
   1142   DCHECK(content_view_core_);
   1143   DCHECK(using_browser_compositor_);
   1144   content_view_core_->GetWindowAndroid()->SetNeedsAnimate();
   1145 }
   1146 
   1147 void RenderWidgetHostViewAndroid::MoveCaret(const gfx::PointF& position) {
   1148   MoveCaret(gfx::Point(position.x(), position.y()));
   1149 }
   1150 
   1151 void RenderWidgetHostViewAndroid::SelectBetweenCoordinates(
   1152     const gfx::PointF& start,
   1153     const gfx::PointF& end) {
   1154   DCHECK(content_view_core_);
   1155   content_view_core_->SelectBetweenCoordinates(start, end);
   1156 }
   1157 
   1158 void RenderWidgetHostViewAndroid::OnSelectionEvent(
   1159     SelectionEventType event,
   1160     const gfx::PointF& position) {
   1161   DCHECK(content_view_core_);
   1162   content_view_core_->OnSelectionEvent(event, position);
   1163 }
   1164 
   1165 scoped_ptr<TouchHandleDrawable> RenderWidgetHostViewAndroid::CreateDrawable() {
   1166   DCHECK(content_view_core_);
   1167   if (!using_browser_compositor_)
   1168     return content_view_core_->CreatePopupTouchHandleDrawable();
   1169 
   1170   return scoped_ptr<TouchHandleDrawable>(new CompositedTouchHandleDrawable(
   1171       content_view_core_->GetLayer(),
   1172       content_view_core_->GetDpiScale(),
   1173       base::android::GetApplicationContext()));
   1174 }
   1175 
   1176 void RenderWidgetHostViewAndroid::SynchronousCopyContents(
   1177     const gfx::Rect& src_subrect_in_pixel,
   1178     const gfx::Size& dst_size_in_pixel,
   1179     const base::Callback<void(bool, const SkBitmap&)>& callback,
   1180     const SkColorType color_type) {
   1181   SynchronousCompositor* compositor =
   1182       SynchronousCompositorImpl::FromID(host_->GetProcess()->GetID(),
   1183                                         host_->GetRoutingID());
   1184   if (!compositor) {
   1185     callback.Run(false, SkBitmap());
   1186     return;
   1187   }
   1188 
   1189   SkBitmap bitmap;
   1190   bitmap.allocPixels(SkImageInfo::Make(dst_size_in_pixel.width(),
   1191                                        dst_size_in_pixel.height(),
   1192                                        color_type,
   1193                                        kPremul_SkAlphaType));
   1194   SkCanvas canvas(bitmap);
   1195   canvas.scale(
   1196       (float)dst_size_in_pixel.width() / (float)src_subrect_in_pixel.width(),
   1197       (float)dst_size_in_pixel.height() / (float)src_subrect_in_pixel.height());
   1198   compositor->DemandDrawSw(&canvas);
   1199   callback.Run(true, bitmap);
   1200 }
   1201 
   1202 void RenderWidgetHostViewAndroid::OnFrameMetadataUpdated(
   1203     const cc::CompositorFrameMetadata& frame_metadata) {
   1204 
   1205   // Disable double tap zoom for pages that have a width=device-width or
   1206   // narrower viewport (indicating that this is a mobile-optimized or responsive
   1207   // web design, so text will be legible without zooming). Also disable
   1208   // double tap and pinch for pages that prevent zooming in or out.
   1209   bool has_mobile_viewport = HasMobileViewport(frame_metadata);
   1210   bool has_fixed_page_scale = HasFixedPageScale(frame_metadata);
   1211   gesture_provider_.SetDoubleTapSupportForPageEnabled(
   1212       !has_fixed_page_scale && !has_mobile_viewport);
   1213 
   1214   if (!content_view_core_)
   1215     return;
   1216 
   1217   if (selection_controller_) {
   1218     selection_controller_->OnSelectionBoundsChanged(
   1219         frame_metadata.selection_start, frame_metadata.selection_end);
   1220   }
   1221 
   1222   // All offsets and sizes are in CSS pixels.
   1223   content_view_core_->UpdateFrameInfo(
   1224       frame_metadata.root_scroll_offset,
   1225       frame_metadata.page_scale_factor,
   1226       gfx::Vector2dF(frame_metadata.min_page_scale_factor,
   1227                      frame_metadata.max_page_scale_factor),
   1228       frame_metadata.root_layer_size,
   1229       frame_metadata.scrollable_viewport_size,
   1230       frame_metadata.location_bar_offset,
   1231       frame_metadata.location_bar_content_translation);
   1232 #if defined(VIDEO_HOLE)
   1233   if (host_ && host_->IsRenderView()) {
   1234     RenderViewHostImpl* rvhi = static_cast<RenderViewHostImpl*>(
   1235         RenderViewHost::From(host_));
   1236     rvhi->media_web_contents_observer()->OnFrameInfoUpdated();
   1237   }
   1238 #endif  // defined(VIDEO_HOLE)
   1239 }
   1240 
   1241 void RenderWidgetHostViewAndroid::AcceleratedSurfaceInitialized(int host_id,
   1242                                                                 int route_id) {
   1243   accelerated_surface_route_id_ = route_id;
   1244 }
   1245 
   1246 void RenderWidgetHostViewAndroid::AcceleratedSurfaceBuffersSwapped(
   1247     const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params,
   1248     int gpu_host_id) {
   1249   NOTREACHED() << "Need --composite-to-mailbox or --enable-delegated-renderer";
   1250 }
   1251 
   1252 void RenderWidgetHostViewAndroid::AttachLayers() {
   1253   if (!content_view_core_)
   1254     return;
   1255   if (!layer_.get())
   1256     return;
   1257 
   1258   content_view_core_->AttachLayer(layer_);
   1259   if (overscroll_effect_)
   1260     overscroll_effect_->Enable();
   1261   layer_->SetHideLayerAndSubtree(!is_showing_);
   1262 }
   1263 
   1264 void RenderWidgetHostViewAndroid::RemoveLayers() {
   1265   if (!content_view_core_)
   1266     return;
   1267 
   1268   if (!layer_.get())
   1269     return;
   1270 
   1271   content_view_core_->RemoveLayer(layer_);
   1272   if (overscroll_effect_)
   1273     overscroll_effect_->Disable();
   1274 }
   1275 
   1276 void RenderWidgetHostViewAndroid::RequestVSyncUpdate(uint32 requests) {
   1277   // The synchronous compositor does not requre BeginFrame messages.
   1278   if (!using_browser_compositor_)
   1279     requests &= FLUSH_INPUT;
   1280 
   1281   bool should_request_vsync = !outstanding_vsync_requests_ && requests;
   1282   outstanding_vsync_requests_ |= requests;
   1283   // Note that if we're not currently observing the root window, outstanding
   1284   // vsync requests will be pushed if/when we resume observing in
   1285   // |StartObservingRootWindow()|.
   1286   if (observing_root_window_ && should_request_vsync)
   1287     content_view_core_->GetWindowAndroid()->RequestVSyncUpdate();
   1288 }
   1289 
   1290 void RenderWidgetHostViewAndroid::StartObservingRootWindow() {
   1291   DCHECK(content_view_core_);
   1292   if (observing_root_window_)
   1293     return;
   1294 
   1295   observing_root_window_ = true;
   1296   content_view_core_->GetWindowAndroid()->AddObserver(this);
   1297 
   1298   // Clear existing vsync requests to allow a request to the new window.
   1299   uint32 outstanding_vsync_requests = outstanding_vsync_requests_;
   1300   outstanding_vsync_requests_ = 0;
   1301   RequestVSyncUpdate(outstanding_vsync_requests);
   1302 }
   1303 
   1304 void RenderWidgetHostViewAndroid::StopObservingRootWindow() {
   1305   if (!content_view_core_) {
   1306     DCHECK(!observing_root_window_);
   1307     return;
   1308   }
   1309 
   1310   if (!observing_root_window_)
   1311     return;
   1312 
   1313   observing_root_window_ = false;
   1314   content_view_core_->GetWindowAndroid()->RemoveObserver(this);
   1315 }
   1316 
   1317 void RenderWidgetHostViewAndroid::SendBeginFrame(base::TimeTicks frame_time,
   1318                                                  base::TimeDelta vsync_period) {
   1319   TRACE_EVENT1("cc", "RenderWidgetHostViewAndroid::SendBeginFrame",
   1320                "frame_time_us", frame_time.ToInternalValue());
   1321   base::TimeTicks display_time = frame_time + vsync_period;
   1322 
   1323   // TODO(brianderson): Use adaptive draw-time estimation.
   1324   base::TimeDelta estimated_browser_composite_time =
   1325       base::TimeDelta::FromMicroseconds(
   1326           (1.0f * base::Time::kMicrosecondsPerSecond) / (3.0f * 60));
   1327 
   1328   base::TimeTicks deadline = display_time - estimated_browser_composite_time;
   1329 
   1330   host_->Send(new ViewMsg_BeginFrame(
   1331       host_->GetRoutingID(),
   1332       cc::BeginFrameArgs::Create(frame_time, deadline, vsync_period)));
   1333 }
   1334 
   1335 bool RenderWidgetHostViewAndroid::Animate(base::TimeTicks frame_time) {
   1336   bool needs_animate =
   1337       overscroll_effect_ ? overscroll_effect_->Animate(frame_time) : false;
   1338   if (selection_controller_)
   1339     needs_animate |= selection_controller_->Animate(frame_time);
   1340   return needs_animate;
   1341 }
   1342 
   1343 void RenderWidgetHostViewAndroid::AcceleratedSurfacePostSubBuffer(
   1344     const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params,
   1345     int gpu_host_id) {
   1346   NOTREACHED();
   1347 }
   1348 
   1349 void RenderWidgetHostViewAndroid::AcceleratedSurfaceSuspend() {
   1350   NOTREACHED();
   1351 }
   1352 
   1353 void RenderWidgetHostViewAndroid::AcceleratedSurfaceRelease() {
   1354   NOTREACHED();
   1355 }
   1356 
   1357 void RenderWidgetHostViewAndroid::EvictDelegatedFrame() {
   1358   if (layer_.get())
   1359     DestroyDelegatedContent();
   1360   frame_evictor_->DiscardedFrame();
   1361   // We are evicting the delegated frame,
   1362   // so there should be no pending readback requests
   1363   DCHECK(readbacks_waiting_for_frame_.empty());
   1364 }
   1365 
   1366 bool RenderWidgetHostViewAndroid::HasAcceleratedSurface(
   1367     const gfx::Size& desired_size) {
   1368   NOTREACHED();
   1369   return false;
   1370 }
   1371 
   1372 void RenderWidgetHostViewAndroid::GetScreenInfo(blink::WebScreenInfo* result) {
   1373   // ScreenInfo isn't tied to the widget on Android. Always return the default.
   1374   RenderWidgetHostViewBase::GetDefaultScreenInfo(result);
   1375 }
   1376 
   1377 // TODO(jrg): Find out the implications and answer correctly here,
   1378 // as we are returning the WebView and not root window bounds.
   1379 gfx::Rect RenderWidgetHostViewAndroid::GetBoundsInRootWindow() {
   1380   return GetViewBounds();
   1381 }
   1382 
   1383 gfx::GLSurfaceHandle RenderWidgetHostViewAndroid::GetCompositingSurface() {
   1384   gfx::GLSurfaceHandle handle =
   1385       gfx::GLSurfaceHandle(gfx::kNullPluginWindow, gfx::NATIVE_TRANSPORT);
   1386   if (using_browser_compositor_) {
   1387     handle.parent_client_id =
   1388         ImageTransportFactoryAndroid::GetInstance()->GetChannelID();
   1389   }
   1390   return handle;
   1391 }
   1392 
   1393 void RenderWidgetHostViewAndroid::ProcessAckedTouchEvent(
   1394     const TouchEventWithLatencyInfo& touch, InputEventAckState ack_result) {
   1395   const bool event_consumed = ack_result == INPUT_EVENT_ACK_STATE_CONSUMED;
   1396   gesture_provider_.OnTouchEventAck(event_consumed);
   1397 }
   1398 
   1399 void RenderWidgetHostViewAndroid::GestureEventAck(
   1400     const blink::WebGestureEvent& event,
   1401     InputEventAckState ack_result) {
   1402   // The overscroll effect requires an explicit release signal that may not be
   1403   // sent from the renderer compositor.
   1404   if (event.type == blink::WebInputEvent::GestureScrollEnd ||
   1405       event.type == blink::WebInputEvent::GestureFlingStart) {
   1406     DidOverscroll(DidOverscrollParams());
   1407   }
   1408 
   1409   if (content_view_core_)
   1410     content_view_core_->OnGestureEventAck(event, ack_result);
   1411 }
   1412 
   1413 InputEventAckState RenderWidgetHostViewAndroid::FilterInputEvent(
   1414     const blink::WebInputEvent& input_event) {
   1415   if (selection_controller_) {
   1416     switch (input_event.type) {
   1417       case blink::WebInputEvent::GestureLongPress:
   1418         selection_controller_->OnLongPressEvent();
   1419         break;
   1420       case blink::WebInputEvent::GestureTap:
   1421         selection_controller_->OnTapEvent();
   1422         break;
   1423       default:
   1424         break;
   1425     }
   1426   }
   1427 
   1428   if (content_view_core_ &&
   1429       content_view_core_->FilterInputEvent(input_event))
   1430     return INPUT_EVENT_ACK_STATE_CONSUMED;
   1431 
   1432   if (!host_)
   1433     return INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
   1434 
   1435   if (input_event.type == blink::WebInputEvent::GestureTapDown ||
   1436       input_event.type == blink::WebInputEvent::TouchStart) {
   1437     GpuDataManagerImpl* gpu_data = GpuDataManagerImpl::GetInstance();
   1438     GpuProcessHostUIShim* shim = GpuProcessHostUIShim::GetOneInstance();
   1439     if (shim && gpu_data && accelerated_surface_route_id_ &&
   1440         gpu_data->IsDriverBugWorkaroundActive(gpu::WAKE_UP_GPU_BEFORE_DRAWING))
   1441       shim->Send(
   1442           new AcceleratedSurfaceMsg_WakeUpGpu(accelerated_surface_route_id_));
   1443   }
   1444 
   1445   SynchronousCompositorImpl* compositor =
   1446       SynchronousCompositorImpl::FromID(host_->GetProcess()->GetID(),
   1447                                           host_->GetRoutingID());
   1448   if (compositor)
   1449     return compositor->HandleInputEvent(input_event);
   1450   return INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
   1451 }
   1452 
   1453 void RenderWidgetHostViewAndroid::OnSetNeedsFlushInput() {
   1454   TRACE_EVENT0("input", "RenderWidgetHostViewAndroid::OnSetNeedsFlushInput");
   1455   RequestVSyncUpdate(FLUSH_INPUT);
   1456 }
   1457 
   1458 BrowserAccessibilityManager*
   1459     RenderWidgetHostViewAndroid::CreateBrowserAccessibilityManager(
   1460         BrowserAccessibilityDelegate* delegate) {
   1461   // TODO(dmazzoni): Currently there can only be one
   1462   // BrowserAccessibilityManager per ContentViewCore, so return NULL
   1463   // if there's already a BrowserAccessibilityManager for the main
   1464   // frame.  Eventually, in order to support cross-process iframes on
   1465   // Android we'll need to add support for a
   1466   // BrowserAccessibilityManager for a child frame.
   1467   // http://crbug.com/423846
   1468   if (!host_ || host_->GetRootBrowserAccessibilityManager())
   1469     return NULL;
   1470 
   1471   base::android::ScopedJavaLocalRef<jobject> obj;
   1472   if (content_view_core_)
   1473     obj = content_view_core_->GetJavaObject();
   1474   return new BrowserAccessibilityManagerAndroid(
   1475       obj,
   1476       BrowserAccessibilityManagerAndroid::GetEmptyDocument(),
   1477       delegate);
   1478 }
   1479 
   1480 bool RenderWidgetHostViewAndroid::LockMouse() {
   1481   NOTIMPLEMENTED();
   1482   return false;
   1483 }
   1484 
   1485 void RenderWidgetHostViewAndroid::UnlockMouse() {
   1486   NOTIMPLEMENTED();
   1487 }
   1488 
   1489 // Methods called from the host to the render
   1490 
   1491 void RenderWidgetHostViewAndroid::SendKeyEvent(
   1492     const NativeWebKeyboardEvent& event) {
   1493   if (host_)
   1494     host_->ForwardKeyboardEvent(event);
   1495 }
   1496 
   1497 void RenderWidgetHostViewAndroid::SendMouseEvent(
   1498     const blink::WebMouseEvent& event) {
   1499   if (host_)
   1500     host_->ForwardMouseEvent(event);
   1501 }
   1502 
   1503 void RenderWidgetHostViewAndroid::SendMouseWheelEvent(
   1504     const blink::WebMouseWheelEvent& event) {
   1505   if (host_)
   1506     host_->ForwardWheelEvent(event);
   1507 }
   1508 
   1509 void RenderWidgetHostViewAndroid::SendGestureEvent(
   1510     const blink::WebGestureEvent& event) {
   1511   // Sending a gesture that may trigger overscroll should resume the effect.
   1512   if (overscroll_effect_)
   1513     overscroll_effect_->Enable();
   1514 
   1515   if (host_)
   1516     host_->ForwardGestureEventWithLatencyInfo(event, CreateLatencyInfo(event));
   1517 }
   1518 
   1519 void RenderWidgetHostViewAndroid::MoveCaret(const gfx::Point& point) {
   1520   if (host_)
   1521     host_->MoveCaret(point);
   1522 }
   1523 
   1524 void RenderWidgetHostViewAndroid::DismissTextHandles() {
   1525   if (selection_controller_)
   1526     selection_controller_->HideAndDisallowShowingAutomatically();
   1527 }
   1528 
   1529 void RenderWidgetHostViewAndroid::SetTextHandlesTemporarilyHidden(bool hidden) {
   1530   if (selection_controller_)
   1531     selection_controller_->SetTemporarilyHidden(hidden);
   1532 }
   1533 
   1534 void RenderWidgetHostViewAndroid::OnShowingPastePopup(
   1535     const gfx::PointF& point) {
   1536   if (!selection_controller_)
   1537     return;
   1538 
   1539   // As the paste popup may be triggered *before* the bounds and editability
   1540   // of the region have been updated, explicitly set the properties now.
   1541   // TODO(jdduke): Remove this workaround when auxiliary paste popup
   1542   // notifications are no longer required, crbug.com/398170.
   1543   cc::ViewportSelectionBound insertion_bound;
   1544   insertion_bound.type = cc::SELECTION_BOUND_CENTER;
   1545   insertion_bound.visible = true;
   1546   insertion_bound.edge_top = point;
   1547   insertion_bound.edge_bottom = point;
   1548   DismissTextHandles();
   1549   ShowSelectionHandlesAutomatically();
   1550   selection_controller_->OnSelectionEditable(true);
   1551   selection_controller_->OnSelectionEmpty(true);
   1552   selection_controller_->OnSelectionBoundsChanged(insertion_bound,
   1553                                                   insertion_bound);
   1554 }
   1555 
   1556 SkColor RenderWidgetHostViewAndroid::GetCachedBackgroundColor() const {
   1557   return cached_background_color_;
   1558 }
   1559 
   1560 void RenderWidgetHostViewAndroid::DidOverscroll(
   1561     const DidOverscrollParams& params) {
   1562   if (!content_view_core_ || !layer_ || !is_showing_)
   1563     return;
   1564 
   1565   const float device_scale_factor = content_view_core_->GetDpiScale();
   1566 
   1567   if (overscroll_effect_ &&
   1568       overscroll_effect_->OnOverscrolled(
   1569           content_view_core_->GetLayer(),
   1570           base::TimeTicks::Now(),
   1571           gfx::ScaleVector2d(params.accumulated_overscroll,
   1572                              device_scale_factor),
   1573           gfx::ScaleVector2d(params.latest_overscroll_delta,
   1574                              device_scale_factor),
   1575           gfx::ScaleVector2d(params.current_fling_velocity,
   1576                              device_scale_factor),
   1577           gfx::ScaleVector2d(
   1578               params.causal_event_viewport_point.OffsetFromOrigin(),
   1579               device_scale_factor))) {
   1580     SetNeedsAnimate();
   1581   }
   1582 }
   1583 
   1584 void RenderWidgetHostViewAndroid::DidStopFlinging() {
   1585   if (content_view_core_)
   1586     content_view_core_->DidStopFlinging();
   1587 }
   1588 
   1589 void RenderWidgetHostViewAndroid::SetContentViewCore(
   1590     ContentViewCoreImpl* content_view_core) {
   1591   RemoveLayers();
   1592   StopObservingRootWindow();
   1593 
   1594   bool resize = false;
   1595   if (content_view_core != content_view_core_) {
   1596     overscroll_effect_.reset();
   1597     selection_controller_.reset();
   1598     ReleaseLocksOnSurface();
   1599     resize = true;
   1600   }
   1601 
   1602   content_view_core_ = content_view_core;
   1603 
   1604   BrowserAccessibilityManager* manager = NULL;
   1605   if (host_)
   1606     manager = host_->GetRootBrowserAccessibilityManager();
   1607   if (manager) {
   1608     base::android::ScopedJavaLocalRef<jobject> obj;
   1609     if (content_view_core_)
   1610       obj = content_view_core_->GetJavaObject();
   1611     manager->ToBrowserAccessibilityManagerAndroid()->SetContentViewCore(obj);
   1612   }
   1613 
   1614   AttachLayers();
   1615 
   1616   if (!content_view_core_)
   1617     return;
   1618 
   1619   StartObservingRootWindow();
   1620 
   1621   if (resize)
   1622     WasResized();
   1623 
   1624   if (!selection_controller_)
   1625     selection_controller_ = CreateSelectionController(this, content_view_core_);
   1626 
   1627   if (overscroll_effect_enabled_ && !overscroll_effect_ &&
   1628       content_view_core_->GetWindowAndroid()->GetCompositor())
   1629     overscroll_effect_ = CreateOverscrollEffect(content_view_core_);
   1630 }
   1631 
   1632 void RenderWidgetHostViewAndroid::RunAckCallbacks() {
   1633   while (!ack_callbacks_.empty()) {
   1634     ack_callbacks_.front().Run();
   1635     ack_callbacks_.pop();
   1636   }
   1637 }
   1638 
   1639 void RenderWidgetHostViewAndroid::OnGestureEvent(
   1640     const ui::GestureEventData& gesture) {
   1641   if (gesture_text_selector_.OnGestureEvent(gesture))
   1642     return;
   1643 
   1644   SendGestureEvent(CreateWebGestureEventFromGestureEventData(gesture));
   1645 }
   1646 
   1647 void RenderWidgetHostViewAndroid::OnCompositingDidCommit() {
   1648   RunAckCallbacks();
   1649 }
   1650 
   1651 
   1652 void RenderWidgetHostViewAndroid::OnAttachCompositor() {
   1653   DCHECK(content_view_core_);
   1654   if (overscroll_effect_enabled_ && !overscroll_effect_)
   1655     overscroll_effect_ = CreateOverscrollEffect(content_view_core_);
   1656 }
   1657 
   1658 void RenderWidgetHostViewAndroid::OnDetachCompositor() {
   1659   DCHECK(content_view_core_);
   1660   DCHECK(using_browser_compositor_);
   1661   RunAckCallbacks();
   1662   overscroll_effect_.reset();
   1663 }
   1664 
   1665 void RenderWidgetHostViewAndroid::OnVSync(base::TimeTicks frame_time,
   1666                                           base::TimeDelta vsync_period) {
   1667   TRACE_EVENT0("cc", "RenderWidgetHostViewAndroid::OnVSync");
   1668   if (!host_)
   1669     return;
   1670 
   1671   const uint32 current_vsync_requests = outstanding_vsync_requests_;
   1672   outstanding_vsync_requests_ = 0;
   1673 
   1674   if (current_vsync_requests & FLUSH_INPUT)
   1675     host_->FlushInput();
   1676 
   1677   if (current_vsync_requests & BEGIN_FRAME ||
   1678       current_vsync_requests & PERSISTENT_BEGIN_FRAME) {
   1679     SendBeginFrame(frame_time, vsync_period);
   1680   }
   1681 
   1682   if (current_vsync_requests & PERSISTENT_BEGIN_FRAME)
   1683     RequestVSyncUpdate(PERSISTENT_BEGIN_FRAME);
   1684 }
   1685 
   1686 void RenderWidgetHostViewAndroid::OnAnimate(base::TimeTicks begin_frame_time) {
   1687   if (Animate(begin_frame_time))
   1688     SetNeedsAnimate();
   1689 }
   1690 
   1691 void RenderWidgetHostViewAndroid::OnLostResources() {
   1692   ReleaseLocksOnSurface();
   1693   if (layer_.get())
   1694     DestroyDelegatedContent();
   1695   DCHECK(ack_callbacks_.empty());
   1696   // We should not loose a frame if we have readback requests pending.
   1697   DCHECK(readbacks_waiting_for_frame_.empty());
   1698 }
   1699 
   1700 // static
   1701 void
   1702 RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResultForDelegatedReadback(
   1703     const gfx::Size& dst_size_in_pixel,
   1704     const SkColorType color_type,
   1705     const base::TimeTicks& start_time,
   1706     scoped_refptr<cc::Layer> readback_layer,
   1707     const base::Callback<void(bool, const SkBitmap&)>& callback,
   1708     scoped_ptr<cc::CopyOutputResult> result) {
   1709   readback_layer->RemoveFromParent();
   1710   PrepareTextureCopyOutputResult(
   1711       dst_size_in_pixel, color_type, start_time, callback, result.Pass());
   1712 }
   1713 
   1714 // static
   1715 void RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResult(
   1716     const gfx::Size& dst_size_in_pixel,
   1717     const SkColorType color_type,
   1718     const base::TimeTicks& start_time,
   1719     const base::Callback<void(bool, const SkBitmap&)>& callback,
   1720     scoped_ptr<cc::CopyOutputResult> result) {
   1721   base::ScopedClosureRunner scoped_callback_runner(
   1722       base::Bind(callback, false, SkBitmap()));
   1723   TRACE_EVENT0("cc",
   1724                "RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResult");
   1725 
   1726   if (!result->HasTexture() || result->IsEmpty() || result->size().IsEmpty())
   1727     return;
   1728 
   1729   scoped_ptr<SkBitmap> bitmap(new SkBitmap);
   1730   if (!bitmap->tryAllocPixels(SkImageInfo::Make(dst_size_in_pixel.width(),
   1731                                                 dst_size_in_pixel.height(),
   1732                                                 color_type,
   1733                                                 kOpaque_SkAlphaType)))
   1734     return;
   1735 
   1736   ImageTransportFactoryAndroid* factory =
   1737       ImageTransportFactoryAndroid::GetInstance();
   1738   GLHelper* gl_helper = factory->GetGLHelper();
   1739 
   1740   if (!gl_helper)
   1741     return;
   1742 
   1743   scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock(
   1744       new SkAutoLockPixels(*bitmap));
   1745   uint8* pixels = static_cast<uint8*>(bitmap->getPixels());
   1746 
   1747   cc::TextureMailbox texture_mailbox;
   1748   scoped_ptr<cc::SingleReleaseCallback> release_callback;
   1749   result->TakeTexture(&texture_mailbox, &release_callback);
   1750   DCHECK(texture_mailbox.IsTexture());
   1751   if (!texture_mailbox.IsTexture())
   1752     return;
   1753 
   1754   ignore_result(scoped_callback_runner.Release());
   1755 
   1756   gl_helper->CropScaleReadbackAndCleanMailbox(
   1757       texture_mailbox.mailbox(),
   1758       texture_mailbox.sync_point(),
   1759       result->size(),
   1760       gfx::Rect(result->size()),
   1761       dst_size_in_pixel,
   1762       pixels,
   1763       color_type,
   1764       base::Bind(&CopyFromCompositingSurfaceFinished,
   1765                  callback,
   1766                  base::Passed(&release_callback),
   1767                  base::Passed(&bitmap),
   1768                  start_time,
   1769                  base::Passed(&bitmap_pixels_lock)),
   1770       GLHelper::SCALER_QUALITY_GOOD);
   1771 }
   1772 
   1773 bool RenderWidgetHostViewAndroid::IsReadbackConfigSupported(
   1774     SkColorType color_type) {
   1775   ImageTransportFactoryAndroid* factory =
   1776       ImageTransportFactoryAndroid::GetInstance();
   1777   GLHelper* gl_helper = factory->GetGLHelper();
   1778   if (!gl_helper)
   1779     return false;
   1780   return gl_helper->IsReadbackConfigSupported(color_type);
   1781 }
   1782 
   1783 SkColorType RenderWidgetHostViewAndroid::PreferredReadbackFormat() {
   1784   // Define the criteria here. If say the 16 texture readback is
   1785   // supported we should go with that (this degrades quality)
   1786   // or stick back to the default format.
   1787   if (base::SysInfo::IsLowEndDevice()) {
   1788     if (IsReadbackConfigSupported(kRGB_565_SkColorType))
   1789       return kRGB_565_SkColorType;
   1790   }
   1791   return kN32_SkColorType;
   1792 }
   1793 
   1794 void RenderWidgetHostViewAndroid::ShowSelectionHandlesAutomatically() {
   1795   // Fake a long press to allow automatic selection handle showing.
   1796   if (selection_controller_)
   1797     selection_controller_->OnLongPressEvent();
   1798 }
   1799 
   1800 void RenderWidgetHostViewAndroid::SelectRange(
   1801     float x1, float y1, float x2, float y2) {
   1802   if (content_view_core_)
   1803     static_cast<WebContentsImpl*>(content_view_core_->GetWebContents())->
   1804         SelectRange(gfx::Point(x1, y1), gfx::Point(x2, y2));
   1805 }
   1806 
   1807 void RenderWidgetHostViewAndroid::Unselect() {
   1808   if (content_view_core_)
   1809     content_view_core_->GetWebContents()->Unselect();
   1810 }
   1811 
   1812 void RenderWidgetHostViewAndroid::LongPress(
   1813     base::TimeTicks time, float x, float y) {
   1814   blink::WebGestureEvent long_press = WebGestureEventBuilder::Build(
   1815       blink::WebInputEvent::GestureLongPress,
   1816       (time - base::TimeTicks()).InSecondsF(), x, y);
   1817   SendGestureEvent(long_press);
   1818 }
   1819 
   1820 // static
   1821 void RenderWidgetHostViewBase::GetDefaultScreenInfo(
   1822     blink::WebScreenInfo* results) {
   1823   const gfx::Display& display =
   1824       gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
   1825   results->rect = display.bounds();
   1826   // TODO(husky): Remove any system controls from availableRect.
   1827   results->availableRect = display.work_area();
   1828   results->deviceScaleFactor = display.device_scale_factor();
   1829   results->orientationAngle = display.RotationAsDegree();
   1830   results->orientationType =
   1831       RenderWidgetHostViewBase::GetOrientationTypeForMobile(display);
   1832   gfx::DeviceDisplayInfo info;
   1833   results->depth = info.GetBitsPerPixel();
   1834   results->depthPerComponent = info.GetBitsPerComponent();
   1835   results->isMonochrome = (results->depthPerComponent == 0);
   1836 }
   1837 
   1838 } // namespace content
   1839