IndexedDBFactory now ForceCloses databases.
[chromium-blink-merge.git] / content / browser / renderer_host / render_widget_host_view_android.cc
blob64edead900919062273824bdf24593f586479459
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.
5 #include "content/browser/renderer_host/render_widget_host_view_android.h"
7 #include <android/bitmap.h>
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"
61 namespace content {
63 namespace {
65 const int kUndefinedOutputSurfaceId = -1;
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();
81 RenderWidgetHostImpl::SendSwapCompositorFrameAck(
82 route_id, output_surface_id, renderer_host_id, ack);
85 // Sends an acknowledgement to the renderer of a processed IME event.
86 void SendImeEventAck(RenderWidgetHostImpl* host) {
87 host->Send(new ViewMsg_ImeEventAck(host->GetRoutingID()));
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);
101 bool UsingDelegatedRenderer() {
102 bool using_delegated_renderer = false;
104 using_delegated_renderer |= CommandLine::ForCurrentProcess()->HasSwitch(
105 switches::kEnableDelegatedRenderer);
107 using_delegated_renderer &= !CommandLine::ForCurrentProcess()->HasSwitch(
108 switches::kDisableDelegatedRenderer);
110 return using_delegated_renderer;
113 } // anonymous namespace
115 RenderWidgetHostViewAndroid::RenderWidgetHostViewAndroid(
116 RenderWidgetHostImpl* widget_host,
117 ContentViewCoreImpl* content_view_core)
118 : host_(widget_host),
119 needs_begin_frame_(false),
120 are_layers_attached_(!widget_host->is_hidden()),
121 content_view_core_(NULL),
122 ime_adapter_android_(this),
123 cached_background_color_(SK_ColorWHITE),
124 texture_id_in_layer_(0),
125 last_output_surface_id_(kUndefinedOutputSurfaceId),
126 weak_ptr_factory_(this),
127 overscroll_effect_enabled_(
128 !CommandLine::ForCurrentProcess()->
129 HasSwitch(switches::kDisableOverscrollEdgeEffect)),
130 overscroll_effect_(OverscrollGlow::Create(overscroll_effect_enabled_)),
131 flush_input_requested_(false),
132 accelerated_surface_route_id_(0),
133 using_synchronous_compositor_(SynchronousCompositorImpl::FromID(
134 widget_host->GetProcess()->GetID(),
135 widget_host->GetRoutingID()) != NULL),
136 frame_evictor_(new DelegatedFrameEvictor(this)) {
137 if (!UsingDelegatedRenderer()) {
138 texture_layer_ = cc::TextureLayer::Create(NULL);
139 layer_ = texture_layer_;
142 host_->SetView(this);
143 SetContentViewCore(content_view_core);
144 ImageTransportFactoryAndroid::AddObserver(this);
147 RenderWidgetHostViewAndroid::~RenderWidgetHostViewAndroid() {
148 ImageTransportFactoryAndroid::RemoveObserver(this);
149 SetContentViewCore(NULL);
150 DCHECK(ack_callbacks_.empty());
151 if (texture_id_in_layer_) {
152 ImageTransportFactoryAndroid::GetInstance()->DeleteTexture(
153 texture_id_in_layer_);
156 if (texture_layer_.get())
157 texture_layer_->ClearClient();
159 if (resource_collection_.get())
160 resource_collection_->SetClient(NULL);
164 bool RenderWidgetHostViewAndroid::OnMessageReceived(
165 const IPC::Message& message) {
166 bool handled = true;
167 IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewAndroid, message)
168 IPC_MESSAGE_HANDLER(ViewHostMsg_StartContentIntent, OnStartContentIntent)
169 IPC_MESSAGE_HANDLER(ViewHostMsg_DidChangeBodyBackgroundColor,
170 OnDidChangeBodyBackgroundColor)
171 IPC_MESSAGE_HANDLER(ViewHostMsg_SetNeedsBeginFrame,
172 OnSetNeedsBeginFrame)
173 IPC_MESSAGE_HANDLER(ViewHostMsg_TextInputStateChanged,
174 OnTextInputStateChanged)
175 IPC_MESSAGE_HANDLER(ViewHostMsg_SmartClipDataExtracted,
176 OnSmartClipDataExtracted)
177 IPC_MESSAGE_UNHANDLED(handled = false)
178 IPC_END_MESSAGE_MAP()
179 return handled;
182 void RenderWidgetHostViewAndroid::InitAsChild(gfx::NativeView parent_view) {
183 NOTIMPLEMENTED();
186 void RenderWidgetHostViewAndroid::InitAsPopup(
187 RenderWidgetHostView* parent_host_view, const gfx::Rect& pos) {
188 NOTIMPLEMENTED();
191 void RenderWidgetHostViewAndroid::InitAsFullscreen(
192 RenderWidgetHostView* reference_host_view) {
193 NOTIMPLEMENTED();
196 RenderWidgetHost*
197 RenderWidgetHostViewAndroid::GetRenderWidgetHost() const {
198 return host_;
201 void RenderWidgetHostViewAndroid::WasShown() {
202 if (!host_ || !host_->is_hidden())
203 return;
205 host_->WasShown();
207 if (content_view_core_ && !using_synchronous_compositor_)
208 content_view_core_->GetWindowAndroid()->AddObserver(this);
211 void RenderWidgetHostViewAndroid::WasHidden() {
212 RunAckCallbacks();
214 if (!host_ || host_->is_hidden())
215 return;
217 // Inform the renderer that we are being hidden so it can reduce its resource
218 // utilization.
219 host_->WasHidden();
221 if (content_view_core_ && !using_synchronous_compositor_)
222 content_view_core_->GetWindowAndroid()->RemoveObserver(this);
225 void RenderWidgetHostViewAndroid::WasResized() {
226 host_->WasResized();
229 void RenderWidgetHostViewAndroid::SetSize(const gfx::Size& size) {
230 // Ignore the given size as only the Java code has the power to
231 // resize the view on Android.
232 default_size_ = size;
233 WasResized();
236 void RenderWidgetHostViewAndroid::SetBounds(const gfx::Rect& rect) {
237 SetSize(rect.size());
240 blink::WebGLId RenderWidgetHostViewAndroid::GetScaledContentTexture(
241 float scale,
242 gfx::Size* out_size) {
243 gfx::Size size(gfx::ToCeiledSize(
244 gfx::ScaleSize(texture_size_in_layer_, scale)));
246 if (!CompositorImpl::IsInitialized() ||
247 texture_id_in_layer_ == 0 ||
248 texture_size_in_layer_.IsEmpty() ||
249 size.IsEmpty()) {
250 if (out_size)
251 out_size->SetSize(0, 0);
253 return 0;
256 if (out_size)
257 *out_size = size;
259 GLHelper* helper = ImageTransportFactoryAndroid::GetInstance()->GetGLHelper();
260 return helper->CopyAndScaleTexture(texture_id_in_layer_,
261 texture_size_in_layer_,
262 size,
263 true,
264 GLHelper::SCALER_QUALITY_FAST);
267 bool RenderWidgetHostViewAndroid::PopulateBitmapWithContents(jobject jbitmap) {
268 if (!CompositorImpl::IsInitialized() ||
269 texture_id_in_layer_ == 0 ||
270 texture_size_in_layer_.IsEmpty())
271 return false;
273 gfx::JavaBitmap bitmap(jbitmap);
275 // TODO(dtrainor): Eventually add support for multiple formats here.
276 DCHECK(bitmap.format() == ANDROID_BITMAP_FORMAT_RGBA_8888);
278 GLHelper* helper = ImageTransportFactoryAndroid::GetInstance()->GetGLHelper();
280 blink::WebGLId texture = helper->CopyAndScaleTexture(
281 texture_id_in_layer_,
282 texture_size_in_layer_,
283 bitmap.size(),
284 true,
285 GLHelper::SCALER_QUALITY_FAST);
286 if (texture == 0)
287 return false;
289 helper->ReadbackTextureSync(texture,
290 gfx::Rect(bitmap.size()),
291 static_cast<unsigned char*> (bitmap.pixels()));
293 blink::WebGraphicsContext3D* context =
294 ImageTransportFactoryAndroid::GetInstance()->GetContext3D();
295 context->deleteTexture(texture);
297 return true;
300 bool RenderWidgetHostViewAndroid::HasValidFrame() const {
301 if (!content_view_core_)
302 return false;
303 if (texture_size_in_layer_.IsEmpty())
304 return false;
306 if (UsingDelegatedRenderer()) {
307 if (!delegated_renderer_layer_.get())
308 return false;
309 } else {
310 if (texture_id_in_layer_ == 0)
311 return false;
314 return true;
317 gfx::NativeView RenderWidgetHostViewAndroid::GetNativeView() const {
318 return content_view_core_->GetViewAndroid();
321 gfx::NativeViewId RenderWidgetHostViewAndroid::GetNativeViewId() const {
322 return reinterpret_cast<gfx::NativeViewId>(
323 const_cast<RenderWidgetHostViewAndroid*>(this));
326 gfx::NativeViewAccessible
327 RenderWidgetHostViewAndroid::GetNativeViewAccessible() {
328 NOTIMPLEMENTED();
329 return NULL;
332 void RenderWidgetHostViewAndroid::MovePluginWindows(
333 const gfx::Vector2d& scroll_offset,
334 const std::vector<WebPluginGeometry>& moves) {
335 // We don't have plugin windows on Android. Do nothing. Note: this is called
336 // from RenderWidgetHost::OnUpdateRect which is itself invoked while
337 // processing the corresponding message from Renderer.
340 void RenderWidgetHostViewAndroid::Focus() {
341 host_->Focus();
342 host_->SetInputMethodActive(true);
343 ResetClipping();
344 if (overscroll_effect_enabled_)
345 overscroll_effect_->Enable();
348 void RenderWidgetHostViewAndroid::Blur() {
349 host_->ExecuteEditCommand("Unselect", "");
350 host_->SetInputMethodActive(false);
351 host_->Blur();
352 overscroll_effect_->Disable();
355 bool RenderWidgetHostViewAndroid::HasFocus() const {
356 if (!content_view_core_)
357 return false; // ContentViewCore not created yet.
359 return content_view_core_->HasFocus();
362 bool RenderWidgetHostViewAndroid::IsSurfaceAvailableForCopy() const {
363 return HasValidFrame();
366 void RenderWidgetHostViewAndroid::Show() {
367 if (are_layers_attached_)
368 return;
370 are_layers_attached_ = true;
371 AttachLayers();
373 frame_evictor_->SetVisible(true);
374 WasShown();
377 void RenderWidgetHostViewAndroid::Hide() {
378 if (!are_layers_attached_)
379 return;
381 are_layers_attached_ = false;
382 RemoveLayers();
384 frame_evictor_->SetVisible(false);
385 WasHidden();
388 bool RenderWidgetHostViewAndroid::IsShowing() {
389 // ContentViewCoreImpl represents the native side of the Java
390 // ContentViewCore. It being NULL means that it is not attached
391 // to the View system yet, so we treat this RWHVA as hidden.
392 return are_layers_attached_ && content_view_core_;
395 void RenderWidgetHostViewAndroid::LockResources() {
396 DCHECK(HasValidFrame());
397 DCHECK(host_);
398 DCHECK(!host_->is_hidden());
399 frame_evictor_->LockFrame();
402 void RenderWidgetHostViewAndroid::UnlockResources() {
403 DCHECK(HasValidFrame());
404 frame_evictor_->UnlockFrame();
407 gfx::Rect RenderWidgetHostViewAndroid::GetViewBounds() const {
408 if (!content_view_core_)
409 return gfx::Rect(default_size_);
411 gfx::Size size = content_view_core_->GetViewportSizeDip();
412 gfx::Size offset = content_view_core_->GetViewportSizeOffsetDip();
413 size.Enlarge(-offset.width(), -offset.height());
415 return gfx::Rect(size);
418 gfx::Size RenderWidgetHostViewAndroid::GetPhysicalBackingSize() const {
419 if (!content_view_core_)
420 return gfx::Size();
422 return content_view_core_->GetPhysicalBackingSize();
425 float RenderWidgetHostViewAndroid::GetOverdrawBottomHeight() const {
426 if (!content_view_core_)
427 return 0.f;
429 return content_view_core_->GetOverdrawBottomHeightDip();
432 void RenderWidgetHostViewAndroid::UpdateCursor(const WebCursor& cursor) {
433 // There are no cursors on Android.
436 void RenderWidgetHostViewAndroid::SetIsLoading(bool is_loading) {
437 // Do nothing. The UI notification is handled through ContentViewClient which
438 // is TabContentsDelegate.
441 void RenderWidgetHostViewAndroid::TextInputTypeChanged(
442 ui::TextInputType type,
443 ui::TextInputMode input_mode,
444 bool can_compose_inline) {
445 // Unused on Android, which uses OnTextInputChanged instead.
448 int RenderWidgetHostViewAndroid::GetNativeImeAdapter() {
449 return reinterpret_cast<int>(&ime_adapter_android_);
452 void RenderWidgetHostViewAndroid::OnTextInputStateChanged(
453 const ViewHostMsg_TextInputState_Params& params) {
454 // If an acknowledgement is required for this event, regardless of how we exit
455 // from this method, we must acknowledge that we processed the input state
456 // change.
457 base::ScopedClosureRunner ack_caller;
458 if (params.require_ack)
459 ack_caller.Reset(base::Bind(&SendImeEventAck, host_));
461 if (!IsShowing())
462 return;
464 content_view_core_->UpdateImeAdapter(
465 GetNativeImeAdapter(),
466 static_cast<int>(params.type),
467 params.value, params.selection_start, params.selection_end,
468 params.composition_start, params.composition_end,
469 params.show_ime_if_needed, params.require_ack);
472 void RenderWidgetHostViewAndroid::OnDidChangeBodyBackgroundColor(
473 SkColor color) {
474 if (cached_background_color_ == color)
475 return;
477 cached_background_color_ = color;
478 if (content_view_core_)
479 content_view_core_->OnBackgroundColorChanged(color);
482 void RenderWidgetHostViewAndroid::SendBeginFrame(
483 const cc::BeginFrameArgs& args) {
484 TRACE_EVENT0("cc", "RenderWidgetHostViewAndroid::SendBeginFrame");
485 if (!host_)
486 return;
488 if (flush_input_requested_) {
489 flush_input_requested_ = false;
490 host_->FlushInput();
491 content_view_core_->RemoveBeginFrameSubscriber();
494 host_->Send(new ViewMsg_BeginFrame(host_->GetRoutingID(), args));
497 void RenderWidgetHostViewAndroid::OnSetNeedsBeginFrame(
498 bool enabled) {
499 TRACE_EVENT1("cc", "RenderWidgetHostViewAndroid::OnSetNeedsBeginFrame",
500 "enabled", enabled);
501 // ContentViewCoreImpl handles multiple subscribers to the BeginFrame, so
502 // we have to make sure calls to ContentViewCoreImpl's
503 // {Add,Remove}BeginFrameSubscriber are balanced, even if
504 // RenderWidgetHostViewAndroid's may not be.
505 if (content_view_core_ && needs_begin_frame_ != enabled) {
506 if (enabled)
507 content_view_core_->AddBeginFrameSubscriber();
508 else
509 content_view_core_->RemoveBeginFrameSubscriber();
510 needs_begin_frame_ = enabled;
514 void RenderWidgetHostViewAndroid::OnStartContentIntent(
515 const GURL& content_url) {
516 if (content_view_core_)
517 content_view_core_->StartContentIntent(content_url);
520 void RenderWidgetHostViewAndroid::OnSmartClipDataExtracted(
521 const base::string16& result) {
522 // Custom serialization over IPC isn't allowed normally for security reasons.
523 // Since this feature is only used in (single-process) WebView, there are no
524 // security issues. Enforce that it's only called in single process mode.
525 CHECK(RenderProcessHost::run_renderer_in_process());
526 if (content_view_core_)
527 content_view_core_->OnSmartClipDataExtracted(result);
530 void RenderWidgetHostViewAndroid::ImeCancelComposition() {
531 ime_adapter_android_.CancelComposition();
534 void RenderWidgetHostViewAndroid::DidUpdateBackingStore(
535 const gfx::Rect& scroll_rect,
536 const gfx::Vector2d& scroll_delta,
537 const std::vector<gfx::Rect>& copy_rects,
538 const std::vector<ui::LatencyInfo>& latency_info) {
539 NOTIMPLEMENTED();
542 void RenderWidgetHostViewAndroid::RenderProcessGone(
543 base::TerminationStatus status, int error_code) {
544 Destroy();
547 void RenderWidgetHostViewAndroid::Destroy() {
548 RemoveLayers();
549 SetContentViewCore(NULL);
551 // The RenderWidgetHost's destruction led here, so don't call it.
552 host_ = NULL;
554 delete this;
557 void RenderWidgetHostViewAndroid::SetTooltipText(
558 const base::string16& tooltip_text) {
559 // Tooltips don't makes sense on Android.
562 void RenderWidgetHostViewAndroid::SelectionChanged(const base::string16& text,
563 size_t offset,
564 const gfx::Range& range) {
565 RenderWidgetHostViewBase::SelectionChanged(text, offset, range);
567 if (text.empty() || range.is_empty() || !content_view_core_)
568 return;
569 size_t pos = range.GetMin() - offset;
570 size_t n = range.length();
572 DCHECK(pos + n <= text.length()) << "The text can not fully cover range.";
573 if (pos >= text.length()) {
574 NOTREACHED() << "The text can not cover range.";
575 return;
578 std::string utf8_selection = base::UTF16ToUTF8(text.substr(pos, n));
580 content_view_core_->OnSelectionChanged(utf8_selection);
583 void RenderWidgetHostViewAndroid::SelectionBoundsChanged(
584 const ViewHostMsg_SelectionBounds_Params& params) {
585 if (content_view_core_) {
586 content_view_core_->OnSelectionBoundsChanged(params);
590 void RenderWidgetHostViewAndroid::ScrollOffsetChanged() {
593 BackingStore* RenderWidgetHostViewAndroid::AllocBackingStore(
594 const gfx::Size& size) {
595 NOTIMPLEMENTED();
596 return NULL;
599 void RenderWidgetHostViewAndroid::SetBackground(const SkBitmap& background) {
600 RenderWidgetHostViewBase::SetBackground(background);
601 host_->Send(new ViewMsg_SetBackground(host_->GetRoutingID(), background));
604 void RenderWidgetHostViewAndroid::CopyFromCompositingSurface(
605 const gfx::Rect& src_subrect,
606 const gfx::Size& dst_size,
607 const base::Callback<void(bool, const SkBitmap&)>& callback) {
608 if (!using_synchronous_compositor_ && !IsSurfaceAvailableForCopy()) {
609 callback.Run(false, SkBitmap());
610 return;
613 const gfx::Display& display =
614 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
615 float device_scale_factor = display.device_scale_factor();
617 DCHECK_EQ(device_scale_factor,
618 ui::GetImageScale(GetScaleFactorForView(this)));
620 const gfx::Size& dst_size_in_pixel = ConvertViewSizeToPixel(this, dst_size);
621 gfx::Rect src_subrect_in_pixel =
622 ConvertRectToPixel(device_scale_factor, src_subrect);
624 if (using_synchronous_compositor_) {
625 SynchronousCopyContents(src_subrect_in_pixel, dst_size_in_pixel, callback);
626 return;
629 scoped_ptr<cc::CopyOutputRequest> request;
630 if (src_subrect_in_pixel.size() == dst_size_in_pixel) {
631 request = cc::CopyOutputRequest::CreateBitmapRequest(base::Bind(
632 &RenderWidgetHostViewAndroid::PrepareBitmapCopyOutputResult,
633 dst_size_in_pixel,
634 callback));
635 } else {
636 request = cc::CopyOutputRequest::CreateRequest(base::Bind(
637 &RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResult,
638 dst_size_in_pixel,
639 callback));
641 request->set_area(src_subrect_in_pixel);
642 layer_->RequestCopyOfOutput(request.Pass());
645 void RenderWidgetHostViewAndroid::CopyFromCompositingSurfaceToVideoFrame(
646 const gfx::Rect& src_subrect,
647 const scoped_refptr<media::VideoFrame>& target,
648 const base::Callback<void(bool)>& callback) {
649 NOTIMPLEMENTED();
650 callback.Run(false);
653 bool RenderWidgetHostViewAndroid::CanCopyToVideoFrame() const {
654 return false;
657 void RenderWidgetHostViewAndroid::ShowDisambiguationPopup(
658 const gfx::Rect& target_rect, const SkBitmap& zoomed_bitmap) {
659 if (!content_view_core_)
660 return;
662 content_view_core_->ShowDisambiguationPopup(target_rect, zoomed_bitmap);
665 scoped_ptr<SyntheticGestureTarget>
666 RenderWidgetHostViewAndroid::CreateSyntheticGestureTarget() {
667 return scoped_ptr<SyntheticGestureTarget>(new SyntheticGestureTargetAndroid(
668 host_, content_view_core_->CreateTouchEventSynthesizer()));
671 void RenderWidgetHostViewAndroid::OnAcceleratedCompositingStateChange() {
674 void RenderWidgetHostViewAndroid::SendDelegatedFrameAck(
675 uint32 output_surface_id) {
676 cc::CompositorFrameAck ack;
677 if (resource_collection_.get())
678 resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources);
679 RenderWidgetHostImpl::SendSwapCompositorFrameAck(host_->GetRoutingID(),
680 output_surface_id,
681 host_->GetProcess()->GetID(),
682 ack);
685 void RenderWidgetHostViewAndroid::UnusedResourcesAreAvailable() {
686 // TODO(danakj): If no ack is pending, collect and send resources now.
689 void RenderWidgetHostViewAndroid::DestroyDelegatedContent() {
690 if (are_layers_attached_)
691 RemoveLayers();
692 frame_provider_ = NULL;
693 delegated_renderer_layer_ = NULL;
694 layer_ = NULL;
697 void RenderWidgetHostViewAndroid::SwapDelegatedFrame(
698 uint32 output_surface_id,
699 scoped_ptr<cc::DelegatedFrameData> frame_data) {
700 bool has_content = !texture_size_in_layer_.IsEmpty();
702 if (output_surface_id != last_output_surface_id_) {
703 // TODO(danakj): Lose all resources and send them back here, such as:
704 // resource_collection_->LoseAllResources();
705 // SendReturnedDelegatedResources(last_output_surface_id_);
707 // Drop the cc::DelegatedFrameResourceCollection so that we will not return
708 // any resources from the old output surface with the new output surface id.
709 if (resource_collection_.get()) {
710 resource_collection_->SetClient(NULL);
711 resource_collection_ = NULL;
713 DestroyDelegatedContent();
715 last_output_surface_id_ = output_surface_id;
718 if (!has_content) {
719 DestroyDelegatedContent();
720 } else {
721 if (!resource_collection_.get()) {
722 resource_collection_ = new cc::DelegatedFrameResourceCollection;
723 resource_collection_->SetClient(this);
725 if (!frame_provider_ ||
726 texture_size_in_layer_ != frame_provider_->frame_size()) {
727 if (are_layers_attached_)
728 RemoveLayers();
729 frame_provider_ = new cc::DelegatedFrameProvider(
730 resource_collection_.get(), frame_data.Pass());
731 delegated_renderer_layer_ =
732 cc::DelegatedRendererLayer::Create(frame_provider_);
733 layer_ = delegated_renderer_layer_;
734 if (are_layers_attached_)
735 AttachLayers();
736 } else {
737 frame_provider_->SetFrameData(frame_data.Pass());
741 if (delegated_renderer_layer_.get()) {
742 delegated_renderer_layer_->SetDisplaySize(texture_size_in_layer_);
743 delegated_renderer_layer_->SetIsDrawable(true);
744 delegated_renderer_layer_->SetContentsOpaque(true);
745 delegated_renderer_layer_->SetBounds(content_size_in_layer_);
746 delegated_renderer_layer_->SetNeedsDisplay();
749 base::Closure ack_callback =
750 base::Bind(&RenderWidgetHostViewAndroid::SendDelegatedFrameAck,
751 weak_ptr_factory_.GetWeakPtr(),
752 output_surface_id);
754 if (host_->is_hidden())
755 ack_callback.Run();
756 else
757 ack_callbacks_.push(ack_callback);
760 void RenderWidgetHostViewAndroid::ComputeContentsSize(
761 const cc::CompositorFrameMetadata& frame_metadata) {
762 // Calculate the content size. This should be 0 if the texture_size is 0.
763 gfx::Vector2dF offset;
764 if (texture_size_in_layer_.GetArea() > 0)
765 offset = frame_metadata.location_bar_content_translation;
766 offset.set_y(offset.y() + frame_metadata.overdraw_bottom_height);
767 offset.Scale(frame_metadata.device_scale_factor);
768 content_size_in_layer_ =
769 gfx::Size(texture_size_in_layer_.width() - offset.x(),
770 texture_size_in_layer_.height() - offset.y());
771 // Content size changes should be reflected in associated animation effects.
772 UpdateAnimationSize(frame_metadata);
775 void RenderWidgetHostViewAndroid::OnSwapCompositorFrame(
776 uint32 output_surface_id,
777 scoped_ptr<cc::CompositorFrame> frame) {
778 // Always let ContentViewCore know about the new frame first, so it can decide
779 // to schedule a Draw immediately when it sees the texture layer invalidation.
780 UpdateContentViewCoreFrameMetadata(frame->metadata);
782 if (frame->delegated_frame_data) {
783 DCHECK(UsingDelegatedRenderer());
785 DCHECK(frame->delegated_frame_data);
786 DCHECK(!frame->delegated_frame_data->render_pass_list.empty());
788 cc::RenderPass* root_pass =
789 frame->delegated_frame_data->render_pass_list.back();
790 texture_size_in_layer_ = root_pass->output_rect.size();
791 ComputeContentsSize(frame->metadata);
793 SwapDelegatedFrame(output_surface_id, frame->delegated_frame_data.Pass());
794 return;
797 DCHECK(!UsingDelegatedRenderer());
799 if (!frame->gl_frame_data || frame->gl_frame_data->mailbox.IsZero())
800 return;
802 if (output_surface_id != last_output_surface_id_) {
803 current_mailbox_ = gpu::Mailbox();
804 last_output_surface_id_ = kUndefinedOutputSurfaceId;
807 base::Closure callback = base::Bind(&InsertSyncPointAndAckForCompositor,
808 host_->GetProcess()->GetID(),
809 output_surface_id,
810 host_->GetRoutingID(),
811 current_mailbox_,
812 texture_size_in_layer_);
813 ImageTransportFactoryAndroid::GetInstance()->WaitSyncPoint(
814 frame->gl_frame_data->sync_point);
816 texture_size_in_layer_ = frame->gl_frame_data->size;
817 ComputeContentsSize(frame->metadata);
819 if (layer_->layer_tree_host()) {
820 for (size_t i = 0; i < frame->metadata.latency_info.size(); i++) {
821 scoped_ptr<cc::SwapPromise> swap_promise(
822 new cc::LatencyInfoSwapPromise(frame->metadata.latency_info[i]));
823 layer_->layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
827 BuffersSwapped(frame->gl_frame_data->mailbox, output_surface_id, callback);
828 frame_evictor_->SwappedFrame(!host_->is_hidden());
831 void RenderWidgetHostViewAndroid::SynchronousFrameMetadata(
832 const cc::CompositorFrameMetadata& frame_metadata) {
833 // This is a subset of OnSwapCompositorFrame() used in the synchronous
834 // compositor flow.
835 UpdateContentViewCoreFrameMetadata(frame_metadata);
836 ComputeContentsSize(frame_metadata);
838 // DevTools ScreenCast support for Android WebView.
839 if (DevToolsAgentHost::HasFor(RenderViewHost::From(GetRenderWidgetHost()))) {
840 scoped_refptr<DevToolsAgentHost> dtah =
841 DevToolsAgentHost::GetOrCreateFor(
842 RenderViewHost::From(GetRenderWidgetHost()));
843 // Unblock the compositor.
844 BrowserThread::PostTask(
845 BrowserThread::UI, FROM_HERE,
846 base::Bind(&RenderViewDevToolsAgentHost::SynchronousSwapCompositorFrame,
847 static_cast<RenderViewDevToolsAgentHost*>(dtah.get()),
848 frame_metadata));
852 void RenderWidgetHostViewAndroid::SetOverlayVideoMode(bool enabled) {
853 layer_->SetContentsOpaque(!enabled);
856 void RenderWidgetHostViewAndroid::SynchronousCopyContents(
857 const gfx::Rect& src_subrect_in_pixel,
858 const gfx::Size& dst_size_in_pixel,
859 const base::Callback<void(bool, const SkBitmap&)>& callback) {
860 SynchronousCompositor* compositor =
861 SynchronousCompositorImpl::FromID(host_->GetProcess()->GetID(),
862 host_->GetRoutingID());
863 if (!compositor) {
864 callback.Run(false, SkBitmap());
865 return;
868 SkBitmap bitmap;
869 bitmap.setConfig(SkBitmap::kARGB_8888_Config,
870 dst_size_in_pixel.width(),
871 dst_size_in_pixel.height());
872 bitmap.allocPixels();
873 SkCanvas canvas(bitmap);
874 canvas.scale(
875 (float)dst_size_in_pixel.width() / (float)src_subrect_in_pixel.width(),
876 (float)dst_size_in_pixel.height() / (float)src_subrect_in_pixel.height());
877 compositor->DemandDrawSw(&canvas);
878 callback.Run(true, bitmap);
881 void RenderWidgetHostViewAndroid::UpdateContentViewCoreFrameMetadata(
882 const cc::CompositorFrameMetadata& frame_metadata) {
883 if (content_view_core_) {
884 // All offsets and sizes are in CSS pixels.
885 content_view_core_->UpdateFrameInfo(
886 frame_metadata.root_scroll_offset,
887 frame_metadata.page_scale_factor,
888 gfx::Vector2dF(frame_metadata.min_page_scale_factor,
889 frame_metadata.max_page_scale_factor),
890 frame_metadata.root_layer_size,
891 frame_metadata.viewport_size,
892 frame_metadata.location_bar_offset,
893 frame_metadata.location_bar_content_translation,
894 frame_metadata.overdraw_bottom_height);
898 void RenderWidgetHostViewAndroid::AcceleratedSurfaceInitialized(int host_id,
899 int route_id) {
900 accelerated_surface_route_id_ = route_id;
903 void RenderWidgetHostViewAndroid::AcceleratedSurfaceBuffersSwapped(
904 const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params,
905 int gpu_host_id) {
906 NOTREACHED() << "Need --composite-to-mailbox or --enable-delegated-renderer";
909 void RenderWidgetHostViewAndroid::BuffersSwapped(
910 const gpu::Mailbox& mailbox,
911 uint32_t output_surface_id,
912 const base::Closure& ack_callback) {
913 ImageTransportFactoryAndroid* factory =
914 ImageTransportFactoryAndroid::GetInstance();
916 if (!texture_id_in_layer_) {
917 texture_id_in_layer_ = factory->CreateTexture();
918 texture_layer_->SetTextureId(texture_id_in_layer_);
919 texture_layer_->SetIsDrawable(true);
920 texture_layer_->SetContentsOpaque(true);
923 ImageTransportFactoryAndroid::GetInstance()->AcquireTexture(
924 texture_id_in_layer_, mailbox.name);
926 ResetClipping();
928 current_mailbox_ = mailbox;
929 last_output_surface_id_ = output_surface_id;
931 if (host_->is_hidden())
932 ack_callback.Run();
933 else
934 ack_callbacks_.push(ack_callback);
937 void RenderWidgetHostViewAndroid::AttachLayers() {
938 if (!content_view_core_)
939 return;
940 if (!layer_.get())
941 return;
943 content_view_core_->AttachLayer(layer_);
944 if (overscroll_effect_enabled_)
945 overscroll_effect_->Enable();
948 void RenderWidgetHostViewAndroid::RemoveLayers() {
949 if (!content_view_core_)
950 return;
951 if (!layer_.get())
952 return;
954 content_view_core_->RemoveLayer(layer_);
955 overscroll_effect_->Disable();
958 bool RenderWidgetHostViewAndroid::Animate(base::TimeTicks frame_time) {
959 return overscroll_effect_->Animate(frame_time);
962 void RenderWidgetHostViewAndroid::UpdateAnimationSize(
963 const cc::CompositorFrameMetadata& frame_metadata) {
964 // Disable edge effects for axes on which scrolling is impossible.
965 gfx::SizeF ceiled_viewport_size =
966 gfx::ToCeiledSize(frame_metadata.viewport_size);
967 overscroll_effect_->set_horizontal_overscroll_enabled(
968 ceiled_viewport_size.width() < frame_metadata.root_layer_size.width());
969 overscroll_effect_->set_vertical_overscroll_enabled(
970 ceiled_viewport_size.height() < frame_metadata.root_layer_size.height());
971 overscroll_effect_->set_size(content_size_in_layer_);
974 void RenderWidgetHostViewAndroid::AcceleratedSurfacePostSubBuffer(
975 const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params,
976 int gpu_host_id) {
977 NOTREACHED();
980 void RenderWidgetHostViewAndroid::AcceleratedSurfaceSuspend() {
981 NOTREACHED();
984 void RenderWidgetHostViewAndroid::AcceleratedSurfaceRelease() {
985 NOTREACHED();
988 void RenderWidgetHostViewAndroid::EvictDelegatedFrame() {
989 if (texture_id_in_layer_) {
990 texture_layer_->SetTextureId(0);
991 texture_layer_->SetIsDrawable(false);
992 ImageTransportFactoryAndroid::GetInstance()->DeleteTexture(
993 texture_id_in_layer_);
994 texture_id_in_layer_ = 0;
995 current_mailbox_ = gpu::Mailbox();
996 last_output_surface_id_ = kUndefinedOutputSurfaceId;
998 if (delegated_renderer_layer_.get())
999 DestroyDelegatedContent();
1000 frame_evictor_->DiscardedFrame();
1003 bool RenderWidgetHostViewAndroid::HasAcceleratedSurface(
1004 const gfx::Size& desired_size) {
1005 NOTREACHED();
1006 return false;
1009 void RenderWidgetHostViewAndroid::GetScreenInfo(blink::WebScreenInfo* result) {
1010 // ScreenInfo isn't tied to the widget on Android. Always return the default.
1011 RenderWidgetHostViewBase::GetDefaultScreenInfo(result);
1014 // TODO(jrg): Find out the implications and answer correctly here,
1015 // as we are returning the WebView and not root window bounds.
1016 gfx::Rect RenderWidgetHostViewAndroid::GetBoundsInRootWindow() {
1017 return GetViewBounds();
1020 gfx::GLSurfaceHandle RenderWidgetHostViewAndroid::GetCompositingSurface() {
1021 gfx::GLSurfaceHandle handle =
1022 gfx::GLSurfaceHandle(gfx::kNullPluginWindow, gfx::NATIVE_TRANSPORT);
1023 if (CompositorImpl::IsInitialized()) {
1024 handle.parent_client_id =
1025 ImageTransportFactoryAndroid::GetInstance()->GetChannelID();
1027 return handle;
1030 void RenderWidgetHostViewAndroid::ProcessAckedTouchEvent(
1031 const TouchEventWithLatencyInfo& touch, InputEventAckState ack_result) {
1032 if (content_view_core_)
1033 content_view_core_->ConfirmTouchEvent(ack_result);
1036 void RenderWidgetHostViewAndroid::SetHasHorizontalScrollbar(
1037 bool has_horizontal_scrollbar) {
1038 // intentionally empty, like RenderWidgetHostViewViews
1041 void RenderWidgetHostViewAndroid::SetScrollOffsetPinning(
1042 bool is_pinned_to_left, bool is_pinned_to_right) {
1043 // intentionally empty, like RenderWidgetHostViewViews
1046 void RenderWidgetHostViewAndroid::UnhandledWheelEvent(
1047 const blink::WebMouseWheelEvent& event) {
1048 // intentionally empty, like RenderWidgetHostViewViews
1051 void RenderWidgetHostViewAndroid::GestureEventAck(
1052 int gesture_event_type,
1053 InputEventAckState ack_result) {
1054 if (gesture_event_type == blink::WebInputEvent::GestureScrollUpdate &&
1055 ack_result == INPUT_EVENT_ACK_STATE_CONSUMED) {
1056 content_view_core_->OnScrollUpdateGestureConsumed();
1058 if (gesture_event_type == blink::WebInputEvent::GestureFlingStart &&
1059 ack_result == INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS) {
1060 content_view_core_->UnhandledFlingStartEvent();
1064 InputEventAckState RenderWidgetHostViewAndroid::FilterInputEvent(
1065 const blink::WebInputEvent& input_event) {
1066 if (!host_)
1067 return INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
1069 if (input_event.type == blink::WebInputEvent::GestureTapDown ||
1070 input_event.type == blink::WebInputEvent::TouchStart) {
1071 GpuDataManagerImpl* gpu_data = GpuDataManagerImpl::GetInstance();
1072 GpuProcessHostUIShim* shim = GpuProcessHostUIShim::GetOneInstance();
1073 if (shim && gpu_data && accelerated_surface_route_id_ &&
1074 gpu_data->IsDriverBugWorkaroundActive(gpu::WAKE_UP_GPU_BEFORE_DRAWING))
1075 shim->Send(
1076 new AcceleratedSurfaceMsg_WakeUpGpu(accelerated_surface_route_id_));
1079 SynchronousCompositorImpl* compositor =
1080 SynchronousCompositorImpl::FromID(host_->GetProcess()->GetID(),
1081 host_->GetRoutingID());
1082 if (compositor)
1083 return compositor->HandleInputEvent(input_event);
1084 return INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
1087 void RenderWidgetHostViewAndroid::OnSetNeedsFlushInput() {
1088 if (flush_input_requested_ || !content_view_core_)
1089 return;
1090 flush_input_requested_ = true;
1091 content_view_core_->AddBeginFrameSubscriber();
1094 void RenderWidgetHostViewAndroid::CreateBrowserAccessibilityManagerIfNeeded() {
1095 if (!host_ || host_->accessibility_mode() != AccessibilityModeComplete)
1096 return;
1098 if (!GetBrowserAccessibilityManager()) {
1099 base::android::ScopedJavaLocalRef<jobject> obj;
1100 if (content_view_core_)
1101 obj = content_view_core_->GetJavaObject();
1102 SetBrowserAccessibilityManager(
1103 new BrowserAccessibilityManagerAndroid(
1104 obj, BrowserAccessibilityManagerAndroid::GetEmptyDocument(), this));
1108 void RenderWidgetHostViewAndroid::SetAccessibilityFocus(int acc_obj_id) {
1109 if (!host_)
1110 return;
1112 host_->AccessibilitySetFocus(acc_obj_id);
1115 void RenderWidgetHostViewAndroid::AccessibilityDoDefaultAction(int acc_obj_id) {
1116 if (!host_)
1117 return;
1119 host_->AccessibilityDoDefaultAction(acc_obj_id);
1122 void RenderWidgetHostViewAndroid::AccessibilityScrollToMakeVisible(
1123 int acc_obj_id, gfx::Rect subfocus) {
1124 if (!host_)
1125 return;
1127 host_->AccessibilityScrollToMakeVisible(acc_obj_id, subfocus);
1130 void RenderWidgetHostViewAndroid::AccessibilityScrollToPoint(
1131 int acc_obj_id, gfx::Point point) {
1132 if (!host_)
1133 return;
1135 host_->AccessibilityScrollToPoint(acc_obj_id, point);
1138 void RenderWidgetHostViewAndroid::AccessibilitySetTextSelection(
1139 int acc_obj_id, int start_offset, int end_offset) {
1140 if (!host_)
1141 return;
1143 host_->AccessibilitySetTextSelection(
1144 acc_obj_id, start_offset, end_offset);
1147 gfx::Point RenderWidgetHostViewAndroid::GetLastTouchEventLocation() const {
1148 NOTIMPLEMENTED();
1149 // Only used on Win8
1150 return gfx::Point();
1153 void RenderWidgetHostViewAndroid::FatalAccessibilityTreeError() {
1154 if (!host_)
1155 return;
1157 host_->FatalAccessibilityTreeError();
1158 SetBrowserAccessibilityManager(NULL);
1161 bool RenderWidgetHostViewAndroid::LockMouse() {
1162 NOTIMPLEMENTED();
1163 return false;
1166 void RenderWidgetHostViewAndroid::UnlockMouse() {
1167 NOTIMPLEMENTED();
1170 // Methods called from the host to the render
1172 void RenderWidgetHostViewAndroid::SendKeyEvent(
1173 const NativeWebKeyboardEvent& event) {
1174 if (host_)
1175 host_->ForwardKeyboardEvent(event);
1178 void RenderWidgetHostViewAndroid::SendTouchEvent(
1179 const blink::WebTouchEvent& event) {
1180 if (host_)
1181 host_->ForwardTouchEventWithLatencyInfo(event, ui::LatencyInfo());
1185 void RenderWidgetHostViewAndroid::SendMouseEvent(
1186 const blink::WebMouseEvent& event) {
1187 if (host_)
1188 host_->ForwardMouseEvent(event);
1191 void RenderWidgetHostViewAndroid::SendMouseWheelEvent(
1192 const blink::WebMouseWheelEvent& event) {
1193 if (host_)
1194 host_->ForwardWheelEvent(event);
1197 void RenderWidgetHostViewAndroid::SendGestureEvent(
1198 const blink::WebGestureEvent& event) {
1199 // Sending a gesture that may trigger overscroll should resume the effect.
1200 if (overscroll_effect_enabled_)
1201 overscroll_effect_->Enable();
1203 if (host_)
1204 host_->ForwardGestureEvent(event);
1207 void RenderWidgetHostViewAndroid::SelectRange(const gfx::Point& start,
1208 const gfx::Point& end) {
1209 if (host_)
1210 host_->SelectRange(start, end);
1213 void RenderWidgetHostViewAndroid::MoveCaret(const gfx::Point& point) {
1214 if (host_)
1215 host_->MoveCaret(point);
1218 void RenderWidgetHostViewAndroid::RequestContentClipping(
1219 const gfx::Rect& clipping,
1220 const gfx::Size& content_size) {
1221 // A focused view provides its own clipping.
1222 if (HasFocus())
1223 return;
1225 ClipContents(clipping, content_size);
1228 void RenderWidgetHostViewAndroid::ResetClipping() {
1229 ClipContents(gfx::Rect(gfx::Point(), content_size_in_layer_),
1230 content_size_in_layer_);
1233 void RenderWidgetHostViewAndroid::ClipContents(const gfx::Rect& clipping,
1234 const gfx::Size& content_size) {
1235 if (!texture_id_in_layer_ || content_size_in_layer_.IsEmpty())
1236 return;
1238 gfx::Size clipped_content(content_size_in_layer_);
1239 clipped_content.SetToMin(clipping.size());
1240 texture_layer_->SetBounds(clipped_content);
1241 texture_layer_->SetNeedsDisplay();
1243 if (texture_size_in_layer_.IsEmpty()) {
1244 texture_layer_->SetUV(gfx::PointF(), gfx::PointF());
1245 return;
1248 gfx::PointF offset(
1249 clipping.x() + content_size_in_layer_.width() - content_size.width(),
1250 clipping.y() + content_size_in_layer_.height() - content_size.height());
1251 offset.SetToMax(gfx::PointF());
1253 gfx::Vector2dF uv_scale(1.f / texture_size_in_layer_.width(),
1254 1.f / texture_size_in_layer_.height());
1255 texture_layer_->SetUV(
1256 gfx::PointF(offset.x() * uv_scale.x(),
1257 offset.y() * uv_scale.y()),
1258 gfx::PointF((offset.x() + clipped_content.width()) * uv_scale.x(),
1259 (offset.y() + clipped_content.height()) * uv_scale.y()));
1262 SkColor RenderWidgetHostViewAndroid::GetCachedBackgroundColor() const {
1263 return cached_background_color_;
1266 void RenderWidgetHostViewAndroid::OnOverscrolled(
1267 gfx::Vector2dF accumulated_overscroll,
1268 gfx::Vector2dF current_fling_velocity) {
1269 if (!content_view_core_ || !are_layers_attached_)
1270 return;
1272 if (overscroll_effect_->OnOverscrolled(content_view_core_->GetLayer(),
1273 base::TimeTicks::Now(),
1274 accumulated_overscroll,
1275 current_fling_velocity)) {
1276 content_view_core_->SetNeedsAnimate();
1280 void RenderWidgetHostViewAndroid::SetContentViewCore(
1281 ContentViewCoreImpl* content_view_core) {
1282 RunAckCallbacks();
1284 if (are_layers_attached_)
1285 RemoveLayers();
1287 if (content_view_core_ && !using_synchronous_compositor_)
1288 content_view_core_->GetWindowAndroid()->RemoveObserver(this);
1290 content_view_core_ = content_view_core;
1292 if (GetBrowserAccessibilityManager()) {
1293 base::android::ScopedJavaLocalRef<jobject> obj;
1294 if (content_view_core_)
1295 obj = content_view_core_->GetJavaObject();
1296 GetBrowserAccessibilityManager()->ToBrowserAccessibilityManagerAndroid()->
1297 SetContentViewCore(obj);
1300 if (are_layers_attached_) {
1301 AttachLayers();
1302 if (content_view_core_ && !using_synchronous_compositor_)
1303 content_view_core_->GetWindowAndroid()->AddObserver(this);
1307 void RenderWidgetHostViewAndroid::RunAckCallbacks() {
1308 while (!ack_callbacks_.empty()) {
1309 ack_callbacks_.front().Run();
1310 ack_callbacks_.pop();
1314 void RenderWidgetHostViewAndroid::HasTouchEventHandlers(
1315 bool need_touch_events) {
1316 if (content_view_core_)
1317 content_view_core_->HasTouchEventHandlers(need_touch_events);
1320 void RenderWidgetHostViewAndroid::OnCompositingDidCommit() {
1321 RunAckCallbacks();
1324 void RenderWidgetHostViewAndroid::OnDetachCompositor() {
1325 DCHECK(content_view_core_);
1326 DCHECK(!using_synchronous_compositor_);
1327 RunAckCallbacks();
1330 void RenderWidgetHostViewAndroid::OnLostResources() {
1331 if (texture_layer_.get())
1332 texture_layer_->SetIsDrawable(false);
1333 if (delegated_renderer_layer_.get())
1334 DestroyDelegatedContent();
1335 texture_id_in_layer_ = 0;
1336 RunAckCallbacks();
1339 // static
1340 void RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResult(
1341 const gfx::Size& dst_size_in_pixel,
1342 const base::Callback<void(bool, const SkBitmap&)>& callback,
1343 scoped_ptr<cc::CopyOutputResult> result) {
1344 DCHECK(result->HasTexture());
1345 base::ScopedClosureRunner scoped_callback_runner(
1346 base::Bind(callback, false, SkBitmap()));
1348 if (!result->HasTexture() || result->IsEmpty() || result->size().IsEmpty())
1349 return;
1351 scoped_ptr<SkBitmap> bitmap(new SkBitmap);
1352 bitmap->setConfig(SkBitmap::kARGB_8888_Config,
1353 dst_size_in_pixel.width(), dst_size_in_pixel.height(),
1354 0, kOpaque_SkAlphaType);
1355 if (!bitmap->allocPixels())
1356 return;
1358 ImageTransportFactoryAndroid* factory =
1359 ImageTransportFactoryAndroid::GetInstance();
1360 GLHelper* gl_helper = factory->GetGLHelper();
1361 if (!gl_helper)
1362 return;
1364 scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock(
1365 new SkAutoLockPixels(*bitmap));
1366 uint8* pixels = static_cast<uint8*>(bitmap->getPixels());
1368 cc::TextureMailbox texture_mailbox;
1369 scoped_ptr<cc::SingleReleaseCallback> release_callback;
1370 result->TakeTexture(&texture_mailbox, &release_callback);
1371 DCHECK(texture_mailbox.IsTexture());
1372 if (!texture_mailbox.IsTexture())
1373 return;
1375 ignore_result(scoped_callback_runner.Release());
1377 gl_helper->CropScaleReadbackAndCleanMailbox(
1378 texture_mailbox.name(),
1379 texture_mailbox.sync_point(),
1380 result->size(),
1381 gfx::Rect(result->size()),
1382 dst_size_in_pixel,
1383 pixels,
1384 base::Bind(&CopyFromCompositingSurfaceFinished,
1385 callback,
1386 base::Passed(&release_callback),
1387 base::Passed(&bitmap),
1388 base::Passed(&bitmap_pixels_lock)));
1391 // static
1392 void RenderWidgetHostViewAndroid::PrepareBitmapCopyOutputResult(
1393 const gfx::Size& dst_size_in_pixel,
1394 const base::Callback<void(bool, const SkBitmap&)>& callback,
1395 scoped_ptr<cc::CopyOutputResult> result) {
1396 DCHECK(result->HasBitmap());
1397 base::ScopedClosureRunner scoped_callback_runner(
1398 base::Bind(callback, false, SkBitmap()));
1400 if (!result->HasBitmap() || result->IsEmpty() || result->size().IsEmpty())
1401 return;
1403 scoped_ptr<SkBitmap> source = result->TakeBitmap();
1404 DCHECK(source);
1405 if (!source)
1406 return;
1408 DCHECK_EQ(source->width(), dst_size_in_pixel.width());
1409 DCHECK_EQ(source->height(), dst_size_in_pixel.height());
1411 ignore_result(scoped_callback_runner.Release());
1412 callback.Run(true, *source);
1415 // static
1416 void RenderWidgetHostViewPort::GetDefaultScreenInfo(
1417 blink::WebScreenInfo* results) {
1418 const gfx::Display& display =
1419 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
1420 results->rect = display.bounds();
1421 // TODO(husky): Remove any system controls from availableRect.
1422 results->availableRect = display.work_area();
1423 results->deviceScaleFactor = display.device_scale_factor();
1424 gfx::DeviceDisplayInfo info;
1425 results->depth = info.GetBitsPerPixel();
1426 results->depthPerComponent = info.GetBitsPerComponent();
1427 results->isMonochrome = (results->depthPerComponent == 0);
1430 ////////////////////////////////////////////////////////////////////////////////
1431 // RenderWidgetHostView, public:
1433 // static
1434 RenderWidgetHostView*
1435 RenderWidgetHostView::CreateViewForWidget(RenderWidgetHost* widget) {
1436 RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(widget);
1437 return new RenderWidgetHostViewAndroid(rwhi, NULL);
1440 } // namespace content