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