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