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