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/bind.h"
     10 #include "base/bind_helpers.h"
     11 #include "base/command_line.h"
     12 #include "base/logging.h"
     13 #include "base/message_loop/message_loop.h"
     14 #include "base/strings/utf_string_conversions.h"
     15 #include "base/threading/worker_pool.h"
     16 #include "cc/layers/delegated_renderer_layer.h"
     17 #include "cc/layers/layer.h"
     18 #include "cc/layers/texture_layer.h"
     19 #include "cc/output/compositor_frame.h"
     20 #include "cc/output/compositor_frame_ack.h"
     21 #include "cc/output/copy_output_request.h"
     22 #include "cc/output/copy_output_result.h"
     23 #include "cc/trees/layer_tree_host.h"
     24 #include "content/browser/accessibility/browser_accessibility_manager_android.h"
     25 #include "content/browser/android/content_view_core_impl.h"
     26 #include "content/browser/android/in_process/synchronous_compositor_impl.h"
     27 #include "content/browser/android/overscroll_glow.h"
     28 #include "content/browser/gpu/gpu_surface_tracker.h"
     29 #include "content/browser/renderer_host/compositor_impl_android.h"
     30 #include "content/browser/renderer_host/dip_util.h"
     31 #include "content/browser/renderer_host/image_transport_factory_android.h"
     32 #include "content/browser/renderer_host/render_widget_host_impl.h"
     33 #include "content/browser/renderer_host/surface_texture_transport_client_android.h"
     34 #include "content/browser/renderer_host/touch_smooth_scroll_gesture_android.h"
     35 #include "content/common/gpu/client/gl_helper.h"
     36 #include "content/common/gpu/gpu_messages.h"
     37 #include "content/common/input_messages.h"
     38 #include "content/common/view_messages.h"
     39 #include "content/public/common/content_switches.h"
     40 #include "skia/ext/image_operations.h"
     41 #include "third_party/khronos/GLES2/gl2.h"
     42 #include "third_party/khronos/GLES2/gl2ext.h"
     43 #include "ui/gfx/android/device_display_info.h"
     44 #include "ui/gfx/android/java_bitmap.h"
     45 #include "ui/gfx/display.h"
     46 #include "ui/gfx/screen.h"
     47 #include "ui/gfx/size_conversions.h"
     48 
     49 namespace content {
     50 
     51 namespace {
     52 
     53 const int kUndefinedOutputSurfaceId = -1;
     54 
     55 void InsertSyncPointAndAckForGpu(
     56     int gpu_host_id, int route_id, const std::string& return_mailbox) {
     57   uint32 sync_point =
     58       ImageTransportFactoryAndroid::GetInstance()->InsertSyncPoint();
     59   AcceleratedSurfaceMsg_BufferPresented_Params ack_params;
     60   ack_params.mailbox_name = return_mailbox;
     61   ack_params.sync_point = sync_point;
     62   RenderWidgetHostImpl::AcknowledgeBufferPresent(
     63       route_id, gpu_host_id, ack_params);
     64 }
     65 
     66 void InsertSyncPointAndAckForCompositor(
     67     int renderer_host_id,
     68     uint32 output_surface_id,
     69     int route_id,
     70     const gpu::Mailbox& return_mailbox,
     71     const gfx::Size return_size) {
     72   cc::CompositorFrameAck ack;
     73   ack.gl_frame_data.reset(new cc::GLFrameData());
     74   if (!return_mailbox.IsZero()) {
     75     ack.gl_frame_data->mailbox = return_mailbox;
     76     ack.gl_frame_data->size = return_size;
     77     ack.gl_frame_data->sync_point =
     78         ImageTransportFactoryAndroid::GetInstance()->InsertSyncPoint();
     79   }
     80   RenderWidgetHostImpl::SendSwapCompositorFrameAck(
     81       route_id, output_surface_id, renderer_host_id, ack);
     82 }
     83 
     84 // Sends an acknowledgement to the renderer of a processed IME event.
     85 void SendImeEventAck(RenderWidgetHostImpl* host) {
     86   host->Send(new ViewMsg_ImeEventAck(host->GetRoutingID()));
     87 }
     88 
     89 void CopyFromCompositingSurfaceFinished(
     90     const base::Callback<void(bool, const SkBitmap&)>& callback,
     91     const cc::TextureMailbox::ReleaseCallback& release_callback,
     92     scoped_ptr<SkBitmap> bitmap,
     93     scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock,
     94     bool result) {
     95   bitmap_pixels_lock.reset();
     96   release_callback.Run(0, false);
     97   callback.Run(result, *bitmap);
     98 }
     99 
    100 }  // anonymous namespace
    101 
    102 RenderWidgetHostViewAndroid::RenderWidgetHostViewAndroid(
    103     RenderWidgetHostImpl* widget_host,
    104     ContentViewCoreImpl* content_view_core)
    105     : host_(widget_host),
    106       needs_begin_frame_(false),
    107       are_layers_attached_(true),
    108       content_view_core_(NULL),
    109       ime_adapter_android_(this),
    110       cached_background_color_(SK_ColorWHITE),
    111       texture_id_in_layer_(0),
    112       current_mailbox_output_surface_id_(kUndefinedOutputSurfaceId),
    113       weak_ptr_factory_(this),
    114       overscroll_effect_enabled_(true) {
    115   if (CompositorImpl::UsesDirectGL()) {
    116     surface_texture_transport_.reset(new SurfaceTextureTransportClient());
    117     layer_ = surface_texture_transport_->Initialize();
    118     layer_->SetIsDrawable(true);
    119   } else {
    120     if (CommandLine::ForCurrentProcess()->HasSwitch(
    121             switches::kEnableDelegatedRenderer)) {
    122       delegated_renderer_layer_ = cc::DelegatedRendererLayer::Create(this);
    123       layer_ = delegated_renderer_layer_;
    124     } else {
    125       texture_layer_ = cc::TextureLayer::Create(this);
    126       layer_ = texture_layer_;
    127     }
    128   }
    129 
    130   layer_->SetContentsOpaque(true);
    131 
    132   overscroll_effect_enabled_ = !CommandLine::ForCurrentProcess()->
    133       HasSwitch(switches::kDisableOverscrollEdgeEffect);
    134   // Don't block the main thread with effect resource loading.
    135   // Actual effect creation is deferred until an overscroll event is received.
    136   if (overscroll_effect_enabled_) {
    137     base::WorkerPool::PostTask(FROM_HERE,
    138                                base::Bind(&OverscrollGlow::EnsureResources),
    139                                true);
    140   }
    141 
    142   host_->SetView(this);
    143   SetContentViewCore(content_view_core);
    144   ImageTransportFactoryAndroid::AddObserver(this);
    145 }
    146 
    147 RenderWidgetHostViewAndroid::~RenderWidgetHostViewAndroid() {
    148   ImageTransportFactoryAndroid::RemoveObserver(this);
    149   SetContentViewCore(NULL);
    150   DCHECK(ack_callbacks_.empty());
    151   if (texture_id_in_layer_) {
    152     ImageTransportFactoryAndroid::GetInstance()->DeleteTexture(
    153         texture_id_in_layer_);
    154   }
    155 
    156   if (texture_layer_.get())
    157     texture_layer_->ClearClient();
    158 }
    159 
    160 
    161 bool RenderWidgetHostViewAndroid::OnMessageReceived(
    162     const IPC::Message& message) {
    163   bool handled = true;
    164   IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewAndroid, message)
    165     IPC_MESSAGE_HANDLER(ViewHostMsg_ImeBatchStateChanged_ACK,
    166                         OnProcessImeBatchStateAck)
    167     IPC_MESSAGE_HANDLER(ViewHostMsg_StartContentIntent, OnStartContentIntent)
    168     IPC_MESSAGE_HANDLER(ViewHostMsg_DidChangeBodyBackgroundColor,
    169                         OnDidChangeBodyBackgroundColor)
    170     IPC_MESSAGE_HANDLER(ViewHostMsg_SetNeedsBeginFrame,
    171                         OnSetNeedsBeginFrame)
    172     IPC_MESSAGE_HANDLER(ViewHostMsg_TextInputStateChanged,
    173                         OnTextInputStateChanged)
    174     IPC_MESSAGE_UNHANDLED(handled = false)
    175   IPC_END_MESSAGE_MAP()
    176   return handled;
    177 }
    178 
    179 void RenderWidgetHostViewAndroid::InitAsChild(gfx::NativeView parent_view) {
    180   NOTIMPLEMENTED();
    181 }
    182 
    183 void RenderWidgetHostViewAndroid::InitAsPopup(
    184     RenderWidgetHostView* parent_host_view, const gfx::Rect& pos) {
    185   NOTIMPLEMENTED();
    186 }
    187 
    188 void RenderWidgetHostViewAndroid::InitAsFullscreen(
    189     RenderWidgetHostView* reference_host_view) {
    190   NOTIMPLEMENTED();
    191 }
    192 
    193 RenderWidgetHost*
    194 RenderWidgetHostViewAndroid::GetRenderWidgetHost() const {
    195   return host_;
    196 }
    197 
    198 void RenderWidgetHostViewAndroid::WasShown() {
    199   if (!host_->is_hidden())
    200     return;
    201 
    202   host_->WasShown();
    203 }
    204 
    205 void RenderWidgetHostViewAndroid::WasHidden() {
    206   RunAckCallbacks();
    207 
    208   if (host_->is_hidden())
    209     return;
    210 
    211   // Inform the renderer that we are being hidden so it can reduce its resource
    212   // utilization.
    213   host_->WasHidden();
    214 }
    215 
    216 void RenderWidgetHostViewAndroid::WasResized() {
    217   if (surface_texture_transport_.get() && content_view_core_)
    218     surface_texture_transport_->SetSize(
    219         content_view_core_->GetPhysicalBackingSize());
    220 
    221   host_->WasResized();
    222 }
    223 
    224 void RenderWidgetHostViewAndroid::SetSize(const gfx::Size& size) {
    225   // Ignore the given size as only the Java code has the power to
    226   // resize the view on Android.
    227   WasResized();
    228 }
    229 
    230 void RenderWidgetHostViewAndroid::SetBounds(const gfx::Rect& rect) {
    231   SetSize(rect.size());
    232 }
    233 
    234 WebKit::WebGLId RenderWidgetHostViewAndroid::GetScaledContentTexture(
    235     float scale,
    236     gfx::Size* out_size) {
    237   gfx::Size size(gfx::ToCeiledSize(
    238       gfx::ScaleSize(texture_size_in_layer_, scale)));
    239 
    240   if (!CompositorImpl::IsInitialized() ||
    241       texture_id_in_layer_ == 0 ||
    242       texture_size_in_layer_.IsEmpty() ||
    243       size.IsEmpty()) {
    244     if (out_size)
    245         out_size->SetSize(0, 0);
    246 
    247     return 0;
    248   }
    249 
    250   if (out_size)
    251     *out_size = size;
    252 
    253   GLHelper* helper = ImageTransportFactoryAndroid::GetInstance()->GetGLHelper();
    254   return helper->CopyAndScaleTexture(texture_id_in_layer_,
    255                                      texture_size_in_layer_,
    256                                      size,
    257                                      true,
    258                                      GLHelper::SCALER_QUALITY_FAST);
    259 }
    260 
    261 bool RenderWidgetHostViewAndroid::PopulateBitmapWithContents(jobject jbitmap) {
    262   if (!CompositorImpl::IsInitialized() ||
    263       texture_id_in_layer_ == 0 ||
    264       texture_size_in_layer_.IsEmpty())
    265     return false;
    266 
    267   gfx::JavaBitmap bitmap(jbitmap);
    268 
    269   // TODO(dtrainor): Eventually add support for multiple formats here.
    270   DCHECK(bitmap.format() == ANDROID_BITMAP_FORMAT_RGBA_8888);
    271 
    272   GLHelper* helper = ImageTransportFactoryAndroid::GetInstance()->GetGLHelper();
    273 
    274   WebKit::WebGLId texture = helper->CopyAndScaleTexture(
    275       texture_id_in_layer_,
    276       texture_size_in_layer_,
    277       bitmap.size(),
    278       true,
    279       GLHelper::SCALER_QUALITY_FAST);
    280   if (texture == 0)
    281     return false;
    282 
    283   helper->ReadbackTextureSync(texture,
    284                               gfx::Rect(bitmap.size()),
    285                               static_cast<unsigned char*> (bitmap.pixels()));
    286 
    287   WebKit::WebGraphicsContext3D* context =
    288       ImageTransportFactoryAndroid::GetInstance()->GetContext3D();
    289   context->deleteTexture(texture);
    290 
    291   return true;
    292 }
    293 
    294 bool RenderWidgetHostViewAndroid::HasValidFrame() const {
    295   return texture_id_in_layer_ != 0 &&
    296       content_view_core_ &&
    297       !texture_size_in_layer_.IsEmpty();
    298 }
    299 
    300 gfx::NativeView RenderWidgetHostViewAndroid::GetNativeView() const {
    301   return content_view_core_->GetViewAndroid();
    302 }
    303 
    304 gfx::NativeViewId RenderWidgetHostViewAndroid::GetNativeViewId() const {
    305   return reinterpret_cast<gfx::NativeViewId>(
    306       const_cast<RenderWidgetHostViewAndroid*>(this));
    307 }
    308 
    309 gfx::NativeViewAccessible
    310 RenderWidgetHostViewAndroid::GetNativeViewAccessible() {
    311   NOTIMPLEMENTED();
    312   return NULL;
    313 }
    314 
    315 void RenderWidgetHostViewAndroid::MovePluginWindows(
    316     const gfx::Vector2d& scroll_offset,
    317     const std::vector<WebPluginGeometry>& moves) {
    318   // We don't have plugin windows on Android. Do nothing. Note: this is called
    319   // from RenderWidgetHost::OnUpdateRect which is itself invoked while
    320   // processing the corresponding message from Renderer.
    321 }
    322 
    323 void RenderWidgetHostViewAndroid::Focus() {
    324   host_->Focus();
    325   host_->SetInputMethodActive(true);
    326   ResetClipping();
    327   if (overscroll_effect_)
    328     overscroll_effect_->SetEnabled(true);
    329 }
    330 
    331 void RenderWidgetHostViewAndroid::Blur() {
    332   host_->ExecuteEditCommand("Unselect", "");
    333   host_->SetInputMethodActive(false);
    334   host_->Blur();
    335   if (overscroll_effect_)
    336     overscroll_effect_->SetEnabled(false);
    337 }
    338 
    339 bool RenderWidgetHostViewAndroid::HasFocus() const {
    340   if (!content_view_core_)
    341     return false;  // ContentViewCore not created yet.
    342 
    343   return content_view_core_->HasFocus();
    344 }
    345 
    346 bool RenderWidgetHostViewAndroid::IsSurfaceAvailableForCopy() const {
    347   return HasValidFrame();
    348 }
    349 
    350 void RenderWidgetHostViewAndroid::Show() {
    351   if (are_layers_attached_)
    352     return;
    353 
    354   are_layers_attached_ = true;
    355   AttachLayers();
    356 }
    357 
    358 void RenderWidgetHostViewAndroid::Hide() {
    359   if (!are_layers_attached_)
    360     return;
    361 
    362   are_layers_attached_ = false;
    363   RemoveLayers();
    364 }
    365 
    366 bool RenderWidgetHostViewAndroid::IsShowing() {
    367   // ContentViewCoreImpl represents the native side of the Java
    368   // ContentViewCore.  It being NULL means that it is not attached
    369   // to the View system yet, so we treat this RWHVA as hidden.
    370   return are_layers_attached_ && content_view_core_;
    371 }
    372 
    373 gfx::Rect RenderWidgetHostViewAndroid::GetViewBounds() const {
    374   if (!content_view_core_)
    375     return gfx::Rect();
    376 
    377   gfx::Size size = content_view_core_->GetViewportSizeDip();
    378   gfx::Size offset = content_view_core_->GetViewportSizeOffsetDip();
    379   size.Enlarge(-offset.width(), -offset.height());
    380 
    381   return gfx::Rect(size);
    382 }
    383 
    384 gfx::Size RenderWidgetHostViewAndroid::GetPhysicalBackingSize() const {
    385   if (!content_view_core_)
    386     return gfx::Size();
    387 
    388   return content_view_core_->GetPhysicalBackingSize();
    389 }
    390 
    391 float RenderWidgetHostViewAndroid::GetOverdrawBottomHeight() const {
    392   if (!content_view_core_)
    393     return 0.f;
    394 
    395   return content_view_core_->GetOverdrawBottomHeightDip();
    396 }
    397 
    398 void RenderWidgetHostViewAndroid::UpdateCursor(const WebCursor& cursor) {
    399   // There are no cursors on Android.
    400 }
    401 
    402 void RenderWidgetHostViewAndroid::SetIsLoading(bool is_loading) {
    403   // Do nothing. The UI notification is handled through ContentViewClient which
    404   // is TabContentsDelegate.
    405 }
    406 
    407 void RenderWidgetHostViewAndroid::TextInputTypeChanged(
    408     ui::TextInputType type,
    409     bool can_compose_inline,
    410     ui::TextInputMode input_mode) {
    411   // Unused on Android, which uses OnTextInputChanged instead.
    412 }
    413 
    414 int RenderWidgetHostViewAndroid::GetNativeImeAdapter() {
    415   return reinterpret_cast<int>(&ime_adapter_android_);
    416 }
    417 
    418 void RenderWidgetHostViewAndroid::OnTextInputStateChanged(
    419     const ViewHostMsg_TextInputState_Params& params) {
    420   // If an acknowledgement is required for this event, regardless of how we exit
    421   // from this method, we must acknowledge that we processed the input state
    422   // change.
    423   base::ScopedClosureRunner ack_caller(base::Bind(&SendImeEventAck, host_));
    424   if (!params.require_ack)
    425     ack_caller.Release();
    426 
    427   if (!IsShowing())
    428     return;
    429 
    430   content_view_core_->UpdateImeAdapter(
    431       GetNativeImeAdapter(),
    432       static_cast<int>(params.type),
    433       params.value, params.selection_start, params.selection_end,
    434       params.composition_start, params.composition_end,
    435       params.show_ime_if_needed);
    436 }
    437 
    438 void RenderWidgetHostViewAndroid::OnProcessImeBatchStateAck(bool is_begin) {
    439   if (content_view_core_)
    440     content_view_core_->ProcessImeBatchStateAck(is_begin);
    441 }
    442 
    443 void RenderWidgetHostViewAndroid::OnDidChangeBodyBackgroundColor(
    444     SkColor color) {
    445   if (cached_background_color_ == color)
    446     return;
    447 
    448   cached_background_color_ = color;
    449   if (content_view_core_)
    450     content_view_core_->OnBackgroundColorChanged(color);
    451 }
    452 
    453 void RenderWidgetHostViewAndroid::SendBeginFrame(
    454     const cc::BeginFrameArgs& args) {
    455   TRACE_EVENT0("cc", "RenderWidgetHostViewAndroid::SendBeginFrame");
    456   if (host_)
    457     host_->Send(new ViewMsg_BeginFrame(host_->GetRoutingID(), args));
    458 }
    459 
    460 void RenderWidgetHostViewAndroid::OnSetNeedsBeginFrame(
    461     bool enabled) {
    462   TRACE_EVENT1("cc", "RenderWidgetHostViewAndroid::OnSetNeedsBeginFrame",
    463                "enabled", enabled);
    464   // ContentViewCoreImpl handles multiple subscribers to the BeginFrame, so
    465   // we have to make sure calls to ContentViewCoreImpl's SetNeedsBeginFrame
    466   // are balanced, even if RenderWidgetHostViewAndroid's may not be.
    467   if (content_view_core_ && needs_begin_frame_ != enabled) {
    468     content_view_core_->SetNeedsBeginFrame(enabled);
    469     needs_begin_frame_ = enabled;
    470   }
    471 }
    472 
    473 void RenderWidgetHostViewAndroid::OnStartContentIntent(
    474     const GURL& content_url) {
    475   if (content_view_core_)
    476     content_view_core_->StartContentIntent(content_url);
    477 }
    478 
    479 void RenderWidgetHostViewAndroid::ImeCancelComposition() {
    480   ime_adapter_android_.CancelComposition();
    481 }
    482 
    483 void RenderWidgetHostViewAndroid::DidUpdateBackingStore(
    484     const gfx::Rect& scroll_rect,
    485     const gfx::Vector2d& scroll_delta,
    486     const std::vector<gfx::Rect>& copy_rects,
    487     const ui::LatencyInfo& latency_info) {
    488   NOTIMPLEMENTED();
    489 }
    490 
    491 void RenderWidgetHostViewAndroid::RenderProcessGone(
    492     base::TerminationStatus status, int error_code) {
    493   Destroy();
    494 }
    495 
    496 void RenderWidgetHostViewAndroid::Destroy() {
    497   RemoveLayers();
    498   content_view_core_ = NULL;
    499 
    500   // The RenderWidgetHost's destruction led here, so don't call it.
    501   host_ = NULL;
    502 
    503   delete this;
    504 }
    505 
    506 void RenderWidgetHostViewAndroid::SetTooltipText(
    507     const string16& tooltip_text) {
    508   // Tooltips don't makes sense on Android.
    509 }
    510 
    511 void RenderWidgetHostViewAndroid::SelectionChanged(const string16& text,
    512                                                    size_t offset,
    513                                                    const ui::Range& range) {
    514   RenderWidgetHostViewBase::SelectionChanged(text, offset, range);
    515 
    516   if (text.empty() || range.is_empty() || !content_view_core_)
    517     return;
    518   size_t pos = range.GetMin() - offset;
    519   size_t n = range.length();
    520 
    521   DCHECK(pos + n <= text.length()) << "The text can not fully cover range.";
    522   if (pos >= text.length()) {
    523     NOTREACHED() << "The text can not cover range.";
    524     return;
    525   }
    526 
    527   std::string utf8_selection = UTF16ToUTF8(text.substr(pos, n));
    528 
    529   content_view_core_->OnSelectionChanged(utf8_selection);
    530 }
    531 
    532 void RenderWidgetHostViewAndroid::SelectionBoundsChanged(
    533     const ViewHostMsg_SelectionBounds_Params& params) {
    534   if (content_view_core_) {
    535     content_view_core_->OnSelectionBoundsChanged(params);
    536   }
    537 }
    538 
    539 void RenderWidgetHostViewAndroid::ScrollOffsetChanged() {
    540 }
    541 
    542 BackingStore* RenderWidgetHostViewAndroid::AllocBackingStore(
    543     const gfx::Size& size) {
    544   NOTIMPLEMENTED();
    545   return NULL;
    546 }
    547 
    548 void RenderWidgetHostViewAndroid::SetBackground(const SkBitmap& background) {
    549   RenderWidgetHostViewBase::SetBackground(background);
    550   host_->Send(new ViewMsg_SetBackground(host_->GetRoutingID(), background));
    551 }
    552 
    553 void RenderWidgetHostViewAndroid::CopyFromCompositingSurface(
    554     const gfx::Rect& src_subrect,
    555     const gfx::Size& dst_size,
    556     const base::Callback<void(bool, const SkBitmap&)>& callback) {
    557   if (!IsSurfaceAvailableForCopy()) {
    558     callback.Run(false, SkBitmap());
    559     return;
    560   }
    561 
    562   const gfx::Display& display =
    563       gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
    564   float device_scale_factor = display.device_scale_factor();
    565 
    566   DCHECK_EQ(device_scale_factor,
    567             ui::GetScaleFactorScale(GetScaleFactorForView(this)));
    568 
    569   const gfx::Size& dst_size_in_pixel = ConvertViewSizeToPixel(this, dst_size);
    570   gfx::Rect src_subrect_in_pixel =
    571       ConvertRectToPixel(device_scale_factor, src_subrect);
    572 
    573   scoped_ptr<cc::CopyOutputRequest> request;
    574   if (src_subrect_in_pixel.size() == dst_size_in_pixel) {
    575       request = cc::CopyOutputRequest::CreateBitmapRequest(base::Bind(
    576           &RenderWidgetHostViewAndroid::PrepareBitmapCopyOutputResult,
    577           dst_size_in_pixel,
    578           callback));
    579   } else {
    580       request = cc::CopyOutputRequest::CreateRequest(base::Bind(
    581           &RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResult,
    582           dst_size_in_pixel,
    583           callback));
    584   }
    585   request->set_area(src_subrect_in_pixel);
    586   layer_->RequestCopyOfOutput(request.Pass());
    587 }
    588 
    589 void RenderWidgetHostViewAndroid::CopyFromCompositingSurfaceToVideoFrame(
    590       const gfx::Rect& src_subrect,
    591       const scoped_refptr<media::VideoFrame>& target,
    592       const base::Callback<void(bool)>& callback) {
    593   NOTIMPLEMENTED();
    594   callback.Run(false);
    595 }
    596 
    597 bool RenderWidgetHostViewAndroid::CanCopyToVideoFrame() const {
    598   return false;
    599 }
    600 
    601 void RenderWidgetHostViewAndroid::ShowDisambiguationPopup(
    602     const gfx::Rect& target_rect, const SkBitmap& zoomed_bitmap) {
    603   if (!content_view_core_)
    604     return;
    605 
    606   content_view_core_->ShowDisambiguationPopup(target_rect, zoomed_bitmap);
    607 }
    608 
    609 SmoothScrollGesture* RenderWidgetHostViewAndroid::CreateSmoothScrollGesture(
    610     bool scroll_down, int pixels_to_scroll, int mouse_event_x,
    611     int mouse_event_y) {
    612   return new TouchSmoothScrollGestureAndroid(
    613       pixels_to_scroll,
    614       GetRenderWidgetHost(),
    615       content_view_core_->CreateSmoothScroller(
    616           scroll_down, mouse_event_x, mouse_event_y));
    617 }
    618 
    619 void RenderWidgetHostViewAndroid::OnAcceleratedCompositingStateChange() {
    620 }
    621 
    622 void RenderWidgetHostViewAndroid::SendDelegatedFrameAck(
    623     uint32 output_surface_id) {
    624   cc::CompositorFrameAck ack;
    625   delegated_renderer_layer_->TakeUnusedResourcesForChildCompositor(
    626       &ack.resources);
    627   RenderWidgetHostImpl::SendSwapCompositorFrameAck(
    628       host_->GetRoutingID(), output_surface_id,
    629       host_->GetProcess()->GetID(), ack);
    630 }
    631 
    632 void RenderWidgetHostViewAndroid::SwapDelegatedFrame(
    633     uint32 output_surface_id,
    634     scoped_ptr<cc::DelegatedFrameData> frame_data) {
    635   bool has_frame = frame_data.get() && !frame_data->render_pass_list.empty();
    636 
    637   if (has_frame) {
    638     delegated_renderer_layer_->SetFrameData(frame_data.Pass());
    639     delegated_renderer_layer_->SetDisplaySize(texture_size_in_layer_);
    640     layer_->SetIsDrawable(true);
    641   }
    642   layer_->SetBounds(content_size_in_layer_);
    643   layer_->SetNeedsDisplay();
    644 
    645   base::Closure ack_callback =
    646       base::Bind(&RenderWidgetHostViewAndroid::SendDelegatedFrameAck,
    647                  weak_ptr_factory_.GetWeakPtr(),
    648                  output_surface_id);
    649 
    650   if (host_->is_hidden())
    651     ack_callback.Run();
    652   else
    653     ack_callbacks_.push(ack_callback);
    654 }
    655 
    656 void RenderWidgetHostViewAndroid::ComputeContentsSize(
    657     const cc::CompositorFrameMetadata& frame_metadata) {
    658   // Calculate the content size.  This should be 0 if the texture_size is 0.
    659   gfx::Vector2dF offset;
    660   if (texture_size_in_layer_.GetArea() > 0)
    661     offset = frame_metadata.location_bar_content_translation;
    662   offset.set_y(offset.y() + frame_metadata.overdraw_bottom_height);
    663   offset.Scale(frame_metadata.device_scale_factor);
    664   content_size_in_layer_ =
    665       gfx::Size(texture_size_in_layer_.width() - offset.x(),
    666                 texture_size_in_layer_.height() - offset.y());
    667   // Content size changes should be reflected in associated animation effects.
    668   UpdateAnimationSize(frame_metadata);
    669 }
    670 
    671 void RenderWidgetHostViewAndroid::OnSwapCompositorFrame(
    672     uint32 output_surface_id,
    673     scoped_ptr<cc::CompositorFrame> frame) {
    674   // Always let ContentViewCore know about the new frame first, so it can decide
    675   // to schedule a Draw immediately when it sees the texture layer invalidation.
    676   UpdateContentViewCoreFrameMetadata(frame->metadata);
    677 
    678   if (frame->delegated_frame_data) {
    679     if (!frame->delegated_frame_data->render_pass_list.empty()) {
    680       texture_size_in_layer_ = frame->delegated_frame_data->render_pass_list
    681           .back()->output_rect.size();
    682     }
    683     ComputeContentsSize(frame->metadata);
    684 
    685     SwapDelegatedFrame(output_surface_id, frame->delegated_frame_data.Pass());
    686     return;
    687   }
    688 
    689   if (!frame->gl_frame_data || frame->gl_frame_data->mailbox.IsZero())
    690     return;
    691 
    692   if (output_surface_id != current_mailbox_output_surface_id_) {
    693     current_mailbox_ = gpu::Mailbox();
    694     current_mailbox_output_surface_id_ = kUndefinedOutputSurfaceId;
    695   }
    696 
    697   base::Closure callback = base::Bind(&InsertSyncPointAndAckForCompositor,
    698                                       host_->GetProcess()->GetID(),
    699                                       output_surface_id,
    700                                       host_->GetRoutingID(),
    701                                       current_mailbox_,
    702                                       texture_size_in_layer_);
    703   ImageTransportFactoryAndroid::GetInstance()->WaitSyncPoint(
    704       frame->gl_frame_data->sync_point);
    705 
    706   texture_size_in_layer_ = frame->gl_frame_data->size;
    707   ComputeContentsSize(frame->metadata);
    708 
    709   if (layer_->layer_tree_host())
    710     layer_->layer_tree_host()->SetLatencyInfo(frame->metadata.latency_info);
    711 
    712   BuffersSwapped(frame->gl_frame_data->mailbox, output_surface_id, callback);
    713 }
    714 
    715 void RenderWidgetHostViewAndroid::SynchronousFrameMetadata(
    716     const cc::CompositorFrameMetadata& frame_metadata) {
    717   // This is a subset of OnSwapCompositorFrame() used in the synchronous
    718   // compositor flow.
    719   UpdateContentViewCoreFrameMetadata(frame_metadata);
    720   ComputeContentsSize(frame_metadata);
    721 }
    722 
    723 void RenderWidgetHostViewAndroid::UpdateContentViewCoreFrameMetadata(
    724     const cc::CompositorFrameMetadata& frame_metadata) {
    725   if (content_view_core_) {
    726     // All offsets and sizes are in CSS pixels.
    727     content_view_core_->UpdateFrameInfo(
    728         frame_metadata.root_scroll_offset,
    729         frame_metadata.page_scale_factor,
    730         gfx::Vector2dF(frame_metadata.min_page_scale_factor,
    731                        frame_metadata.max_page_scale_factor),
    732         frame_metadata.root_layer_size,
    733         frame_metadata.viewport_size,
    734         frame_metadata.location_bar_offset,
    735         frame_metadata.location_bar_content_translation,
    736         frame_metadata.overdraw_bottom_height);
    737   }
    738 }
    739 
    740 void RenderWidgetHostViewAndroid::AcceleratedSurfaceBuffersSwapped(
    741     const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params,
    742     int gpu_host_id) {
    743   NOTREACHED() << "Deprecated. Use --composite-to-mailbox.";
    744 
    745   if (params.mailbox_name.empty())
    746     return;
    747 
    748   std::string return_mailbox;
    749   if (!current_mailbox_.IsZero()) {
    750     return_mailbox.assign(
    751         reinterpret_cast<const char*>(current_mailbox_.name),
    752         sizeof(current_mailbox_.name));
    753   }
    754 
    755   base::Closure callback = base::Bind(&InsertSyncPointAndAckForGpu,
    756                                       gpu_host_id, params.route_id,
    757                                       return_mailbox);
    758 
    759   gpu::Mailbox mailbox;
    760   std::copy(params.mailbox_name.data(),
    761             params.mailbox_name.data() + params.mailbox_name.length(),
    762             reinterpret_cast<char*>(mailbox.name));
    763 
    764   texture_size_in_layer_ = params.size;
    765   content_size_in_layer_ = params.size;
    766 
    767   BuffersSwapped(mailbox, kUndefinedOutputSurfaceId, callback);
    768 }
    769 
    770 void RenderWidgetHostViewAndroid::BuffersSwapped(
    771     const gpu::Mailbox& mailbox,
    772     uint32_t output_surface_id,
    773     const base::Closure& ack_callback) {
    774   ImageTransportFactoryAndroid* factory =
    775       ImageTransportFactoryAndroid::GetInstance();
    776 
    777   // TODO(sievers): When running the impl thread in the browser we
    778   // need to delay the ACK until after commit and use more than a single
    779   // texture.
    780   DCHECK(!CompositorImpl::IsThreadingEnabled());
    781 
    782   if (!texture_id_in_layer_) {
    783     texture_id_in_layer_ = factory->CreateTexture();
    784     texture_layer_->SetIsDrawable(true);
    785   }
    786 
    787   ImageTransportFactoryAndroid::GetInstance()->AcquireTexture(
    788       texture_id_in_layer_, mailbox.name);
    789 
    790   ResetClipping();
    791 
    792   current_mailbox_ = mailbox;
    793   current_mailbox_output_surface_id_ = output_surface_id;
    794 
    795   if (host_->is_hidden())
    796     ack_callback.Run();
    797   else
    798     ack_callbacks_.push(ack_callback);
    799 }
    800 
    801 void RenderWidgetHostViewAndroid::AttachLayers() {
    802   if (!content_view_core_)
    803     return;
    804 
    805   content_view_core_->AttachLayer(layer_);
    806 
    807   if (overscroll_effect_)
    808     content_view_core_->AttachLayer(overscroll_effect_->root_layer());
    809 }
    810 
    811 void RenderWidgetHostViewAndroid::RemoveLayers() {
    812   if (!content_view_core_)
    813     return;
    814 
    815   if (overscroll_effect_)
    816     content_view_core_->RemoveLayer(overscroll_effect_->root_layer());
    817 
    818   content_view_core_->RemoveLayer(layer_);
    819 }
    820 
    821 bool RenderWidgetHostViewAndroid::Animate(base::TimeTicks frame_time) {
    822   if (!overscroll_effect_)
    823     return false;
    824   return overscroll_effect_->Animate(frame_time);
    825 }
    826 
    827 void RenderWidgetHostViewAndroid::CreateOverscrollEffectIfNecessary() {
    828   if (!overscroll_effect_enabled_ || overscroll_effect_)
    829     return;
    830 
    831   overscroll_effect_ = OverscrollGlow::Create(true);
    832 
    833   // Prevent future creation attempts on failure.
    834   if (!overscroll_effect_)
    835     overscroll_effect_enabled_ = false;
    836 
    837   if (overscroll_effect_ && content_view_core_ && are_layers_attached_)
    838     content_view_core_->AttachLayer(overscroll_effect_->root_layer());
    839 }
    840 
    841 void RenderWidgetHostViewAndroid::UpdateAnimationSize(
    842     const cc::CompositorFrameMetadata& frame_metadata) {
    843   if (!overscroll_effect_)
    844     return;
    845   // Disable edge effects for axes on which scrolling is impossible.
    846   gfx::SizeF ceiled_viewport_size =
    847       gfx::ToCeiledSize(frame_metadata.viewport_size);
    848   overscroll_effect_->set_horizontal_overscroll_enabled(
    849       ceiled_viewport_size.width() < frame_metadata.root_layer_size.width());
    850   overscroll_effect_->set_vertical_overscroll_enabled(
    851       ceiled_viewport_size.height() < frame_metadata.root_layer_size.height());
    852   overscroll_effect_->set_size(content_size_in_layer_);
    853 }
    854 
    855 void RenderWidgetHostViewAndroid::ScheduleAnimationIfNecessary() {
    856   if (!content_view_core_)
    857     return;
    858   if (overscroll_effect_ && overscroll_effect_->NeedsAnimate())
    859     content_view_core_->SetNeedsAnimate();
    860 }
    861 
    862 void RenderWidgetHostViewAndroid::AcceleratedSurfacePostSubBuffer(
    863     const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params,
    864     int gpu_host_id) {
    865   NOTREACHED();
    866 }
    867 
    868 void RenderWidgetHostViewAndroid::AcceleratedSurfaceSuspend() {
    869   NOTREACHED();
    870 }
    871 
    872 void RenderWidgetHostViewAndroid::AcceleratedSurfaceRelease() {
    873   // This tells us we should free the frontbuffer.
    874   if (texture_id_in_layer_) {
    875     texture_layer_->SetTextureId(0);
    876     texture_layer_->SetIsDrawable(false);
    877     ImageTransportFactoryAndroid::GetInstance()->DeleteTexture(
    878         texture_id_in_layer_);
    879     texture_id_in_layer_ = 0;
    880     current_mailbox_ = gpu::Mailbox();
    881     current_mailbox_output_surface_id_ = kUndefinedOutputSurfaceId;
    882   }
    883 }
    884 
    885 bool RenderWidgetHostViewAndroid::HasAcceleratedSurface(
    886     const gfx::Size& desired_size) {
    887   NOTREACHED();
    888   return false;
    889 }
    890 
    891 void RenderWidgetHostViewAndroid::GetScreenInfo(WebKit::WebScreenInfo* result) {
    892   // ScreenInfo isn't tied to the widget on Android. Always return the default.
    893   RenderWidgetHostViewBase::GetDefaultScreenInfo(result);
    894 }
    895 
    896 // TODO(jrg): Find out the implications and answer correctly here,
    897 // as we are returning the WebView and not root window bounds.
    898 gfx::Rect RenderWidgetHostViewAndroid::GetBoundsInRootWindow() {
    899   return GetViewBounds();
    900 }
    901 
    902 gfx::GLSurfaceHandle RenderWidgetHostViewAndroid::GetCompositingSurface() {
    903   if (surface_texture_transport_) {
    904     return surface_texture_transport_->GetCompositingSurface(
    905         host_->surface_id());
    906   } else {
    907     return gfx::GLSurfaceHandle(gfx::kNullPluginWindow, gfx::TEXTURE_TRANSPORT);
    908   }
    909 }
    910 
    911 void RenderWidgetHostViewAndroid::ProcessAckedTouchEvent(
    912     const TouchEventWithLatencyInfo& touch, InputEventAckState ack_result) {
    913   if (content_view_core_)
    914     content_view_core_->ConfirmTouchEvent(ack_result);
    915 }
    916 
    917 void RenderWidgetHostViewAndroid::SetHasHorizontalScrollbar(
    918     bool has_horizontal_scrollbar) {
    919   // intentionally empty, like RenderWidgetHostViewViews
    920 }
    921 
    922 void RenderWidgetHostViewAndroid::SetScrollOffsetPinning(
    923     bool is_pinned_to_left, bool is_pinned_to_right) {
    924   // intentionally empty, like RenderWidgetHostViewViews
    925 }
    926 
    927 void RenderWidgetHostViewAndroid::UnhandledWheelEvent(
    928     const WebKit::WebMouseWheelEvent& event) {
    929   // intentionally empty, like RenderWidgetHostViewViews
    930 }
    931 
    932 void RenderWidgetHostViewAndroid::GestureEventAck(
    933     int gesture_event_type,
    934     InputEventAckState ack_result) {
    935   if (gesture_event_type == WebKit::WebInputEvent::GestureScrollUpdate &&
    936       ack_result == INPUT_EVENT_ACK_STATE_CONSUMED) {
    937     content_view_core_->OnScrollUpdateGestureConsumed();
    938   }
    939   if (gesture_event_type == WebKit::WebInputEvent::GestureFlingStart &&
    940       ack_result == INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS) {
    941     content_view_core_->UnhandledFlingStartEvent();
    942   }
    943 }
    944 
    945 InputEventAckState RenderWidgetHostViewAndroid::FilterInputEvent(
    946     const WebKit::WebInputEvent& input_event) {
    947   if (host_) {
    948     SynchronousCompositorImpl* compositor =
    949         SynchronousCompositorImpl::FromID(host_->GetProcess()->GetID(),
    950                                           host_->GetRoutingID());
    951     if (compositor)
    952       return compositor->HandleInputEvent(input_event);
    953   }
    954   return INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
    955 }
    956 
    957 void RenderWidgetHostViewAndroid::OnAccessibilityNotifications(
    958     const std::vector<AccessibilityHostMsg_NotificationParams>& params) {
    959   if (!host_ ||
    960       host_->accessibility_mode() != AccessibilityModeComplete ||
    961       !content_view_core_) {
    962     return;
    963   }
    964 
    965   if (!GetBrowserAccessibilityManager()) {
    966     SetBrowserAccessibilityManager(
    967         new BrowserAccessibilityManagerAndroid(
    968             content_view_core_->GetJavaObject(),
    969             BrowserAccessibilityManagerAndroid::GetEmptyDocument(),
    970             this));
    971   }
    972   GetBrowserAccessibilityManager()->OnAccessibilityNotifications(params);
    973 }
    974 
    975 void RenderWidgetHostViewAndroid::SetAccessibilityFocus(int acc_obj_id) {
    976   if (!host_)
    977     return;
    978 
    979   host_->AccessibilitySetFocus(acc_obj_id);
    980 }
    981 
    982 void RenderWidgetHostViewAndroid::AccessibilityDoDefaultAction(int acc_obj_id) {
    983   if (!host_)
    984     return;
    985 
    986   host_->AccessibilityDoDefaultAction(acc_obj_id);
    987 }
    988 
    989 void RenderWidgetHostViewAndroid::AccessibilityScrollToMakeVisible(
    990     int acc_obj_id, gfx::Rect subfocus) {
    991   if (!host_)
    992     return;
    993 
    994   host_->AccessibilityScrollToMakeVisible(acc_obj_id, subfocus);
    995 }
    996 
    997 void RenderWidgetHostViewAndroid::AccessibilityScrollToPoint(
    998     int acc_obj_id, gfx::Point point) {
    999   if (!host_)
   1000     return;
   1001 
   1002   host_->AccessibilityScrollToPoint(acc_obj_id, point);
   1003 }
   1004 
   1005 void RenderWidgetHostViewAndroid::AccessibilitySetTextSelection(
   1006     int acc_obj_id, int start_offset, int end_offset) {
   1007   if (!host_)
   1008     return;
   1009 
   1010   host_->AccessibilitySetTextSelection(
   1011       acc_obj_id, start_offset, end_offset);
   1012 }
   1013 
   1014 gfx::Point RenderWidgetHostViewAndroid::GetLastTouchEventLocation() const {
   1015   NOTIMPLEMENTED();
   1016   // Only used on Win8
   1017   return gfx::Point();
   1018 }
   1019 
   1020 void RenderWidgetHostViewAndroid::FatalAccessibilityTreeError() {
   1021   if (!host_)
   1022     return;
   1023 
   1024   host_->FatalAccessibilityTreeError();
   1025   SetBrowserAccessibilityManager(NULL);
   1026 }
   1027 
   1028 bool RenderWidgetHostViewAndroid::LockMouse() {
   1029   NOTIMPLEMENTED();
   1030   return false;
   1031 }
   1032 
   1033 void RenderWidgetHostViewAndroid::UnlockMouse() {
   1034   NOTIMPLEMENTED();
   1035 }
   1036 
   1037 // Methods called from the host to the render
   1038 
   1039 void RenderWidgetHostViewAndroid::SendKeyEvent(
   1040     const NativeWebKeyboardEvent& event) {
   1041   if (host_)
   1042     host_->ForwardKeyboardEvent(event);
   1043 }
   1044 
   1045 void RenderWidgetHostViewAndroid::SendTouchEvent(
   1046     const WebKit::WebTouchEvent& event) {
   1047   if (host_)
   1048     host_->ForwardTouchEventWithLatencyInfo(event, ui::LatencyInfo());
   1049 }
   1050 
   1051 
   1052 void RenderWidgetHostViewAndroid::SendMouseEvent(
   1053     const WebKit::WebMouseEvent& event) {
   1054   if (host_)
   1055     host_->ForwardMouseEvent(event);
   1056 }
   1057 
   1058 void RenderWidgetHostViewAndroid::SendMouseWheelEvent(
   1059     const WebKit::WebMouseWheelEvent& event) {
   1060   if (host_)
   1061     host_->ForwardWheelEvent(event);
   1062 }
   1063 
   1064 void RenderWidgetHostViewAndroid::SendGestureEvent(
   1065     const WebKit::WebGestureEvent& event) {
   1066   // Sending a gesture that may trigger overscroll should resume the effect.
   1067   if (overscroll_effect_) {
   1068     overscroll_effect_->SetEnabled(true);
   1069     if (event.type == WebKit::WebInputEvent::GestureScrollEnd)
   1070       overscroll_effect_->Release(base::TimeTicks::Now());
   1071   }
   1072 
   1073   if (host_)
   1074     host_->ForwardGestureEvent(event);
   1075 }
   1076 
   1077 void RenderWidgetHostViewAndroid::SelectRange(const gfx::Point& start,
   1078                                               const gfx::Point& end) {
   1079   if (host_)
   1080     host_->SelectRange(start, end);
   1081 }
   1082 
   1083 void RenderWidgetHostViewAndroid::MoveCaret(const gfx::Point& point) {
   1084   if (host_)
   1085     host_->MoveCaret(point);
   1086 }
   1087 
   1088 void RenderWidgetHostViewAndroid::RequestContentClipping(
   1089     const gfx::Rect& clipping,
   1090     const gfx::Size& content_size) {
   1091   // A focused view provides its own clipping.
   1092   if (HasFocus())
   1093     return;
   1094 
   1095   ClipContents(clipping, content_size);
   1096 }
   1097 
   1098 void RenderWidgetHostViewAndroid::ResetClipping() {
   1099   ClipContents(gfx::Rect(gfx::Point(), content_size_in_layer_),
   1100                content_size_in_layer_);
   1101 }
   1102 
   1103 void RenderWidgetHostViewAndroid::ClipContents(const gfx::Rect& clipping,
   1104                                                const gfx::Size& content_size) {
   1105   if (!texture_id_in_layer_ || content_size_in_layer_.IsEmpty())
   1106     return;
   1107 
   1108   gfx::Size clipped_content(content_size_in_layer_);
   1109   clipped_content.SetToMin(clipping.size());
   1110   texture_layer_->SetBounds(clipped_content);
   1111   texture_layer_->SetNeedsDisplay();
   1112 
   1113   if (texture_size_in_layer_.IsEmpty()) {
   1114     texture_layer_->SetUV(gfx::PointF(), gfx::PointF());
   1115     return;
   1116   }
   1117 
   1118   gfx::PointF offset(
   1119       clipping.x() + content_size_in_layer_.width() - content_size.width(),
   1120       clipping.y() + content_size_in_layer_.height() - content_size.height());
   1121   offset.SetToMax(gfx::PointF());
   1122 
   1123   gfx::Vector2dF uv_scale(1.f / texture_size_in_layer_.width(),
   1124                           1.f / texture_size_in_layer_.height());
   1125   texture_layer_->SetUV(
   1126       gfx::PointF(offset.x() * uv_scale.x(),
   1127                   offset.y() * uv_scale.y()),
   1128       gfx::PointF((offset.x() + clipped_content.width()) * uv_scale.x(),
   1129                   (offset.y() + clipped_content.height()) * uv_scale.y()));
   1130 }
   1131 
   1132 SkColor RenderWidgetHostViewAndroid::GetCachedBackgroundColor() const {
   1133   return cached_background_color_;
   1134 }
   1135 
   1136 void RenderWidgetHostViewAndroid::OnOverscrolled(
   1137     gfx::Vector2dF accumulated_overscroll,
   1138     gfx::Vector2dF current_fling_velocity) {
   1139   CreateOverscrollEffectIfNecessary();
   1140   if (!overscroll_effect_)
   1141     return;
   1142 
   1143   overscroll_effect_->OnOverscrolled(base::TimeTicks::Now(),
   1144                                      accumulated_overscroll,
   1145                                      current_fling_velocity);
   1146   ScheduleAnimationIfNecessary();
   1147 }
   1148 
   1149 void RenderWidgetHostViewAndroid::SetContentViewCore(
   1150     ContentViewCoreImpl* content_view_core) {
   1151   RunAckCallbacks();
   1152 
   1153   if (are_layers_attached_)
   1154     RemoveLayers();
   1155 
   1156   content_view_core_ = content_view_core;
   1157 
   1158   if (are_layers_attached_)
   1159     AttachLayers();
   1160 }
   1161 
   1162 void RenderWidgetHostViewAndroid::RunAckCallbacks() {
   1163   while (!ack_callbacks_.empty()) {
   1164     ack_callbacks_.front().Run();
   1165     ack_callbacks_.pop();
   1166   }
   1167 }
   1168 
   1169 void RenderWidgetHostViewAndroid::HasTouchEventHandlers(
   1170     bool need_touch_events) {
   1171   if (content_view_core_)
   1172     content_view_core_->HasTouchEventHandlers(need_touch_events);
   1173 }
   1174 
   1175 unsigned RenderWidgetHostViewAndroid::PrepareTexture() {
   1176   RunAckCallbacks();
   1177   return texture_id_in_layer_;
   1178 }
   1179 
   1180 void RenderWidgetHostViewAndroid::DidCommitFrameData() {
   1181   RunAckCallbacks();
   1182 }
   1183 
   1184 WebKit::WebGraphicsContext3D* RenderWidgetHostViewAndroid::Context3d() {
   1185   return ImageTransportFactoryAndroid::GetInstance()->GetContext3D();
   1186 }
   1187 
   1188 bool RenderWidgetHostViewAndroid::PrepareTextureMailbox(
   1189     cc::TextureMailbox* mailbox,
   1190     bool use_shared_memory) {
   1191   return false;
   1192 }
   1193 
   1194 void RenderWidgetHostViewAndroid::OnLostResources() {
   1195   if (texture_layer_)
   1196     texture_layer_->SetIsDrawable(false);
   1197   texture_id_in_layer_ = 0;
   1198   RunAckCallbacks();
   1199 }
   1200 
   1201 // static
   1202 void RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResult(
   1203     const gfx::Size& dst_size_in_pixel,
   1204     const base::Callback<void(bool, const SkBitmap&)>& callback,
   1205     scoped_ptr<cc::CopyOutputResult> result) {
   1206   DCHECK(result->HasTexture());
   1207   base::ScopedClosureRunner scoped_callback_runner(
   1208       base::Bind(callback, false, SkBitmap()));
   1209 
   1210   if (!result->HasTexture() || result->IsEmpty() || result->size().IsEmpty())
   1211     return;
   1212 
   1213   scoped_ptr<SkBitmap> bitmap(new SkBitmap);
   1214   bitmap->setConfig(SkBitmap::kARGB_8888_Config,
   1215                     dst_size_in_pixel.width(), dst_size_in_pixel.height());
   1216   if (!bitmap->allocPixels())
   1217     return;
   1218   bitmap->setIsOpaque(true);
   1219 
   1220   ImageTransportFactoryAndroid* factory =
   1221       ImageTransportFactoryAndroid::GetInstance();
   1222   GLHelper* gl_helper = factory->GetGLHelper();
   1223   if (!gl_helper)
   1224     return;
   1225 
   1226   scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock(
   1227       new SkAutoLockPixels(*bitmap));
   1228   uint8* pixels = static_cast<uint8*>(bitmap->getPixels());
   1229 
   1230   scoped_ptr<cc::TextureMailbox> texture_mailbox = result->TakeTexture();
   1231   DCHECK(texture_mailbox->IsTexture());
   1232   if (!texture_mailbox->IsTexture())
   1233     return;
   1234 
   1235   scoped_callback_runner.Release();
   1236 
   1237   gl_helper->CropScaleReadbackAndCleanMailbox(
   1238       texture_mailbox->name(),
   1239       texture_mailbox->sync_point(),
   1240       result->size(),
   1241       gfx::Rect(result->size()),
   1242       dst_size_in_pixel,
   1243       pixels,
   1244       base::Bind(&CopyFromCompositingSurfaceFinished,
   1245                  callback,
   1246                  texture_mailbox->callback(),
   1247                  base::Passed(&bitmap),
   1248                  base::Passed(&bitmap_pixels_lock)));
   1249 }
   1250 
   1251 // static
   1252 void RenderWidgetHostViewAndroid::PrepareBitmapCopyOutputResult(
   1253     const gfx::Size& dst_size_in_pixel,
   1254     const base::Callback<void(bool, const SkBitmap&)>& callback,
   1255     scoped_ptr<cc::CopyOutputResult> result) {
   1256   DCHECK(result->HasBitmap());
   1257   base::ScopedClosureRunner scoped_callback_runner(
   1258       base::Bind(callback, false, SkBitmap()));
   1259 
   1260   if (!result->HasBitmap() || result->IsEmpty() || result->size().IsEmpty())
   1261     return;
   1262 
   1263   scoped_ptr<SkBitmap> source = result->TakeBitmap();
   1264   DCHECK(source);
   1265   if (!source)
   1266     return;
   1267 
   1268   DCHECK_EQ(source->width(), dst_size_in_pixel.width());
   1269   DCHECK_EQ(source->height(), dst_size_in_pixel.height());
   1270 
   1271   scoped_callback_runner.Release();
   1272   callback.Run(true, *source);
   1273 }
   1274 
   1275 // static
   1276 void RenderWidgetHostViewPort::GetDefaultScreenInfo(
   1277     WebKit::WebScreenInfo* results) {
   1278   const gfx::Display& display =
   1279       gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
   1280   results->rect = display.bounds();
   1281   // TODO(husky): Remove any system controls from availableRect.
   1282   results->availableRect = display.work_area();
   1283   results->deviceScaleFactor = display.device_scale_factor();
   1284   gfx::DeviceDisplayInfo info;
   1285   results->depth = info.GetBitsPerPixel();
   1286   results->depthPerComponent = info.GetBitsPerComponent();
   1287   results->isMonochrome = (results->depthPerComponent == 0);
   1288 }
   1289 
   1290 ////////////////////////////////////////////////////////////////////////////////
   1291 // RenderWidgetHostView, public:
   1292 
   1293 // static
   1294 RenderWidgetHostView*
   1295 RenderWidgetHostView::CreateViewForWidget(RenderWidgetHost* widget) {
   1296   RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(widget);
   1297   return new RenderWidgetHostViewAndroid(rwhi, NULL);
   1298 }
   1299 
   1300 } // namespace content
   1301