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