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