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