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