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