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