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