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