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_widget_host_impl.h"
41 #include "content/common/gpu/client/gl_helper.h"
42 #include "content/common/gpu/gpu_messages.h"
43 #include "content/common/input_messages.h"
44 #include "content/common/view_messages.h"
45 #include "content/public/browser/devtools_agent_host.h"
46 #include "content/public/browser/render_view_host.h"
47 #include "content/public/common/content_switches.h"
48 #include "gpu/config/gpu_driver_bug_workaround_type.h"
49 #include "skia/ext/image_operations.h"
50 #include "third_party/khronos/GLES2/gl2.h"
51 #include "third_party/khronos/GLES2/gl2ext.h"
52 #include "third_party/skia/include/core/SkCanvas.h"
53 #include "ui/base/android/window_android.h"
54 #include "ui/gfx/android/device_display_info.h"
55 #include "ui/gfx/android/java_bitmap.h"
56 #include "ui/gfx/display.h"
57 #include "ui/gfx/screen.h"
58 #include "ui/gfx/size_conversions.h"
64 const int kUndefinedOutputSurfaceId
= -1;
66 void InsertSyncPointAndAckForCompositor(
68 uint32 output_surface_id
,
70 const gpu::Mailbox
& return_mailbox
,
71 const gfx::Size return_size
) {
72 cc::CompositorFrameAck ack
;
73 ack
.gl_frame_data
.reset(new cc::GLFrameData());
74 if (!return_mailbox
.IsZero()) {
75 ack
.gl_frame_data
->mailbox
= return_mailbox
;
76 ack
.gl_frame_data
->size
= return_size
;
77 ack
.gl_frame_data
->sync_point
=
78 ImageTransportFactoryAndroid::GetInstance()->InsertSyncPoint();
80 RenderWidgetHostImpl::SendSwapCompositorFrameAck(
81 route_id
, output_surface_id
, renderer_host_id
, ack
);
84 // Sends an acknowledgement to the renderer of a processed IME event.
85 void SendImeEventAck(RenderWidgetHostImpl
* host
) {
86 host
->Send(new ViewMsg_ImeEventAck(host
->GetRoutingID()));
89 void CopyFromCompositingSurfaceFinished(
90 const base::Callback
<void(bool, const SkBitmap
&)>& callback
,
91 scoped_ptr
<cc::SingleReleaseCallback
> release_callback
,
92 scoped_ptr
<SkBitmap
> bitmap
,
93 scoped_ptr
<SkAutoLockPixels
> bitmap_pixels_lock
,
95 bitmap_pixels_lock
.reset();
96 release_callback
->Run(0, false);
97 callback
.Run(result
, *bitmap
);
100 bool UsingDelegatedRenderer() {
101 return CommandLine::ForCurrentProcess()->HasSwitch(
102 switches::kEnableDelegatedRenderer
);
105 } // anonymous namespace
107 RenderWidgetHostViewAndroid::RenderWidgetHostViewAndroid(
108 RenderWidgetHostImpl
* widget_host
,
109 ContentViewCoreImpl
* content_view_core
)
110 : host_(widget_host
),
111 needs_begin_frame_(false),
112 are_layers_attached_(true),
113 content_view_core_(NULL
),
114 ime_adapter_android_(this),
115 cached_background_color_(SK_ColorWHITE
),
116 texture_id_in_layer_(0),
117 last_output_surface_id_(kUndefinedOutputSurfaceId
),
118 weak_ptr_factory_(this),
119 overscroll_effect_enabled_(
120 !CommandLine::ForCurrentProcess()->
121 HasSwitch(switches::kDisableOverscrollEdgeEffect
)),
122 overscroll_effect_(OverscrollGlow::Create(overscroll_effect_enabled_
)),
123 flush_input_requested_(false),
124 accelerated_surface_route_id_(0),
125 using_synchronous_compositor_(SynchronousCompositorImpl::FromID(
126 widget_host
->GetProcess()->GetID(),
127 widget_host
->GetRoutingID()) != NULL
) {
128 if (!UsingDelegatedRenderer()) {
129 texture_layer_
= cc::TextureLayer::Create(NULL
);
130 layer_
= texture_layer_
;
133 host_
->SetView(this);
134 SetContentViewCore(content_view_core
);
135 ImageTransportFactoryAndroid::AddObserver(this);
138 RenderWidgetHostViewAndroid::~RenderWidgetHostViewAndroid() {
139 ImageTransportFactoryAndroid::RemoveObserver(this);
140 SetContentViewCore(NULL
);
141 DCHECK(ack_callbacks_
.empty());
142 if (texture_id_in_layer_
) {
143 ImageTransportFactoryAndroid::GetInstance()->DeleteTexture(
144 texture_id_in_layer_
);
147 if (texture_layer_
.get())
148 texture_layer_
->ClearClient();
150 if (resource_collection_
.get())
151 resource_collection_
->SetClient(NULL
);
155 bool RenderWidgetHostViewAndroid::OnMessageReceived(
156 const IPC::Message
& message
) {
158 IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewAndroid
, message
)
159 IPC_MESSAGE_HANDLER(ViewHostMsg_StartContentIntent
, OnStartContentIntent
)
160 IPC_MESSAGE_HANDLER(ViewHostMsg_DidChangeBodyBackgroundColor
,
161 OnDidChangeBodyBackgroundColor
)
162 IPC_MESSAGE_HANDLER(ViewHostMsg_SetNeedsBeginFrame
,
163 OnSetNeedsBeginFrame
)
164 IPC_MESSAGE_HANDLER(ViewHostMsg_TextInputStateChanged
,
165 OnTextInputStateChanged
)
166 IPC_MESSAGE_UNHANDLED(handled
= false)
167 IPC_END_MESSAGE_MAP()
171 void RenderWidgetHostViewAndroid::InitAsChild(gfx::NativeView parent_view
) {
175 void RenderWidgetHostViewAndroid::InitAsPopup(
176 RenderWidgetHostView
* parent_host_view
, const gfx::Rect
& pos
) {
180 void RenderWidgetHostViewAndroid::InitAsFullscreen(
181 RenderWidgetHostView
* reference_host_view
) {
186 RenderWidgetHostViewAndroid::GetRenderWidgetHost() const {
190 void RenderWidgetHostViewAndroid::WasShown() {
191 if (!host_
|| !host_
->is_hidden())
196 if (content_view_core_
&& !using_synchronous_compositor_
)
197 content_view_core_
->GetWindowAndroid()->AddObserver(this);
200 void RenderWidgetHostViewAndroid::WasHidden() {
203 if (!host_
|| host_
->is_hidden())
206 // Inform the renderer that we are being hidden so it can reduce its resource
210 if (content_view_core_
&& !using_synchronous_compositor_
)
211 content_view_core_
->GetWindowAndroid()->RemoveObserver(this);
214 void RenderWidgetHostViewAndroid::WasResized() {
218 void RenderWidgetHostViewAndroid::SetSize(const gfx::Size
& size
) {
219 // Ignore the given size as only the Java code has the power to
220 // resize the view on Android.
221 default_size_
= size
;
225 void RenderWidgetHostViewAndroid::SetBounds(const gfx::Rect
& rect
) {
226 SetSize(rect
.size());
229 blink::WebGLId
RenderWidgetHostViewAndroid::GetScaledContentTexture(
231 gfx::Size
* out_size
) {
232 gfx::Size
size(gfx::ToCeiledSize(
233 gfx::ScaleSize(texture_size_in_layer_
, scale
)));
235 if (!CompositorImpl::IsInitialized() ||
236 texture_id_in_layer_
== 0 ||
237 texture_size_in_layer_
.IsEmpty() ||
240 out_size
->SetSize(0, 0);
248 GLHelper
* helper
= ImageTransportFactoryAndroid::GetInstance()->GetGLHelper();
249 return helper
->CopyAndScaleTexture(texture_id_in_layer_
,
250 texture_size_in_layer_
,
253 GLHelper::SCALER_QUALITY_FAST
);
256 bool RenderWidgetHostViewAndroid::PopulateBitmapWithContents(jobject jbitmap
) {
257 if (!CompositorImpl::IsInitialized() ||
258 texture_id_in_layer_
== 0 ||
259 texture_size_in_layer_
.IsEmpty())
262 gfx::JavaBitmap
bitmap(jbitmap
);
264 // TODO(dtrainor): Eventually add support for multiple formats here.
265 DCHECK(bitmap
.format() == ANDROID_BITMAP_FORMAT_RGBA_8888
);
267 GLHelper
* helper
= ImageTransportFactoryAndroid::GetInstance()->GetGLHelper();
269 blink::WebGLId texture
= helper
->CopyAndScaleTexture(
270 texture_id_in_layer_
,
271 texture_size_in_layer_
,
274 GLHelper::SCALER_QUALITY_FAST
);
278 helper
->ReadbackTextureSync(texture
,
279 gfx::Rect(bitmap
.size()),
280 static_cast<unsigned char*> (bitmap
.pixels()));
282 blink::WebGraphicsContext3D
* context
=
283 ImageTransportFactoryAndroid::GetInstance()->GetContext3D();
284 context
->deleteTexture(texture
);
289 bool RenderWidgetHostViewAndroid::HasValidFrame() const {
290 if (!content_view_core_
)
292 if (texture_size_in_layer_
.IsEmpty())
295 if (UsingDelegatedRenderer()) {
296 if (!delegated_renderer_layer_
.get())
299 if (texture_id_in_layer_
== 0)
306 gfx::NativeView
RenderWidgetHostViewAndroid::GetNativeView() const {
307 return content_view_core_
->GetViewAndroid();
310 gfx::NativeViewId
RenderWidgetHostViewAndroid::GetNativeViewId() const {
311 return reinterpret_cast<gfx::NativeViewId
>(
312 const_cast<RenderWidgetHostViewAndroid
*>(this));
315 gfx::NativeViewAccessible
316 RenderWidgetHostViewAndroid::GetNativeViewAccessible() {
321 void RenderWidgetHostViewAndroid::MovePluginWindows(
322 const gfx::Vector2d
& scroll_offset
,
323 const std::vector
<WebPluginGeometry
>& moves
) {
324 // We don't have plugin windows on Android. Do nothing. Note: this is called
325 // from RenderWidgetHost::OnUpdateRect which is itself invoked while
326 // processing the corresponding message from Renderer.
329 void RenderWidgetHostViewAndroid::Focus() {
331 host_
->SetInputMethodActive(true);
333 if (overscroll_effect_enabled_
)
334 overscroll_effect_
->Enable();
337 void RenderWidgetHostViewAndroid::Blur() {
338 host_
->ExecuteEditCommand("Unselect", "");
339 host_
->SetInputMethodActive(false);
341 overscroll_effect_
->Disable();
344 bool RenderWidgetHostViewAndroid::HasFocus() const {
345 if (!content_view_core_
)
346 return false; // ContentViewCore not created yet.
348 return content_view_core_
->HasFocus();
351 bool RenderWidgetHostViewAndroid::IsSurfaceAvailableForCopy() const {
352 return HasValidFrame();
355 void RenderWidgetHostViewAndroid::Show() {
356 if (are_layers_attached_
)
359 are_layers_attached_
= true;
365 void RenderWidgetHostViewAndroid::Hide() {
366 if (!are_layers_attached_
)
369 are_layers_attached_
= false;
375 bool RenderWidgetHostViewAndroid::IsShowing() {
376 // ContentViewCoreImpl represents the native side of the Java
377 // ContentViewCore. It being NULL means that it is not attached
378 // to the View system yet, so we treat this RWHVA as hidden.
379 return are_layers_attached_
&& content_view_core_
;
382 gfx::Rect
RenderWidgetHostViewAndroid::GetViewBounds() const {
383 if (!content_view_core_
)
384 return gfx::Rect(default_size_
);
386 gfx::Size size
= content_view_core_
->GetViewportSizeDip();
387 gfx::Size offset
= content_view_core_
->GetViewportSizeOffsetDip();
388 size
.Enlarge(-offset
.width(), -offset
.height());
390 return gfx::Rect(size
);
393 gfx::Size
RenderWidgetHostViewAndroid::GetPhysicalBackingSize() const {
394 if (!content_view_core_
)
397 return content_view_core_
->GetPhysicalBackingSize();
400 float RenderWidgetHostViewAndroid::GetOverdrawBottomHeight() const {
401 if (!content_view_core_
)
404 return content_view_core_
->GetOverdrawBottomHeightDip();
407 void RenderWidgetHostViewAndroid::UpdateCursor(const WebCursor
& cursor
) {
408 // There are no cursors on Android.
411 void RenderWidgetHostViewAndroid::SetIsLoading(bool is_loading
) {
412 // Do nothing. The UI notification is handled through ContentViewClient which
413 // is TabContentsDelegate.
416 void RenderWidgetHostViewAndroid::TextInputTypeChanged(
417 ui::TextInputType type
,
418 ui::TextInputMode input_mode
,
419 bool can_compose_inline
) {
420 // Unused on Android, which uses OnTextInputChanged instead.
423 int RenderWidgetHostViewAndroid::GetNativeImeAdapter() {
424 return reinterpret_cast<int>(&ime_adapter_android_
);
427 void RenderWidgetHostViewAndroid::OnTextInputStateChanged(
428 const ViewHostMsg_TextInputState_Params
& params
) {
429 // If an acknowledgement is required for this event, regardless of how we exit
430 // from this method, we must acknowledge that we processed the input state
432 base::ScopedClosureRunner ack_caller
;
433 if (params
.require_ack
)
434 ack_caller
.Reset(base::Bind(&SendImeEventAck
, host_
));
439 content_view_core_
->UpdateImeAdapter(
440 GetNativeImeAdapter(),
441 static_cast<int>(params
.type
),
442 params
.value
, params
.selection_start
, params
.selection_end
,
443 params
.composition_start
, params
.composition_end
,
444 params
.show_ime_if_needed
, params
.require_ack
);
447 void RenderWidgetHostViewAndroid::OnDidChangeBodyBackgroundColor(
449 if (cached_background_color_
== color
)
452 cached_background_color_
= color
;
453 if (content_view_core_
)
454 content_view_core_
->OnBackgroundColorChanged(color
);
457 void RenderWidgetHostViewAndroid::SendBeginFrame(
458 const cc::BeginFrameArgs
& args
) {
459 TRACE_EVENT0("cc", "RenderWidgetHostViewAndroid::SendBeginFrame");
463 if (flush_input_requested_
) {
464 flush_input_requested_
= false;
466 content_view_core_
->RemoveBeginFrameSubscriber();
469 host_
->Send(new ViewMsg_BeginFrame(host_
->GetRoutingID(), args
));
472 void RenderWidgetHostViewAndroid::OnSetNeedsBeginFrame(
474 TRACE_EVENT1("cc", "RenderWidgetHostViewAndroid::OnSetNeedsBeginFrame",
476 // ContentViewCoreImpl handles multiple subscribers to the BeginFrame, so
477 // we have to make sure calls to ContentViewCoreImpl's
478 // {Add,Remove}BeginFrameSubscriber are balanced, even if
479 // RenderWidgetHostViewAndroid's may not be.
480 if (content_view_core_
&& needs_begin_frame_
!= enabled
) {
482 content_view_core_
->AddBeginFrameSubscriber();
484 content_view_core_
->RemoveBeginFrameSubscriber();
485 needs_begin_frame_
= enabled
;
489 void RenderWidgetHostViewAndroid::OnStartContentIntent(
490 const GURL
& content_url
) {
491 if (content_view_core_
)
492 content_view_core_
->StartContentIntent(content_url
);
495 void RenderWidgetHostViewAndroid::ImeCancelComposition() {
496 ime_adapter_android_
.CancelComposition();
499 void RenderWidgetHostViewAndroid::DidUpdateBackingStore(
500 const gfx::Rect
& scroll_rect
,
501 const gfx::Vector2d
& scroll_delta
,
502 const std::vector
<gfx::Rect
>& copy_rects
,
503 const ui::LatencyInfo
& latency_info
) {
507 void RenderWidgetHostViewAndroid::RenderProcessGone(
508 base::TerminationStatus status
, int error_code
) {
512 void RenderWidgetHostViewAndroid::Destroy() {
514 SetContentViewCore(NULL
);
516 // The RenderWidgetHost's destruction led here, so don't call it.
522 void RenderWidgetHostViewAndroid::SetTooltipText(
523 const base::string16
& tooltip_text
) {
524 // Tooltips don't makes sense on Android.
527 void RenderWidgetHostViewAndroid::SelectionChanged(const base::string16
& text
,
529 const gfx::Range
& range
) {
530 RenderWidgetHostViewBase::SelectionChanged(text
, offset
, range
);
532 if (text
.empty() || range
.is_empty() || !content_view_core_
)
534 size_t pos
= range
.GetMin() - offset
;
535 size_t n
= range
.length();
537 DCHECK(pos
+ n
<= text
.length()) << "The text can not fully cover range.";
538 if (pos
>= text
.length()) {
539 NOTREACHED() << "The text can not cover range.";
543 std::string utf8_selection
= UTF16ToUTF8(text
.substr(pos
, n
));
545 content_view_core_
->OnSelectionChanged(utf8_selection
);
548 void RenderWidgetHostViewAndroid::SelectionBoundsChanged(
549 const ViewHostMsg_SelectionBounds_Params
& params
) {
550 if (content_view_core_
) {
551 content_view_core_
->OnSelectionBoundsChanged(params
);
555 void RenderWidgetHostViewAndroid::ScrollOffsetChanged() {
558 BackingStore
* RenderWidgetHostViewAndroid::AllocBackingStore(
559 const gfx::Size
& size
) {
564 void RenderWidgetHostViewAndroid::SetBackground(const SkBitmap
& background
) {
565 RenderWidgetHostViewBase::SetBackground(background
);
566 host_
->Send(new ViewMsg_SetBackground(host_
->GetRoutingID(), background
));
569 void RenderWidgetHostViewAndroid::CopyFromCompositingSurface(
570 const gfx::Rect
& src_subrect
,
571 const gfx::Size
& dst_size
,
572 const base::Callback
<void(bool, const SkBitmap
&)>& callback
) {
573 if (!using_synchronous_compositor_
&& !IsSurfaceAvailableForCopy()) {
574 callback
.Run(false, SkBitmap());
578 const gfx::Display
& display
=
579 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
580 float device_scale_factor
= display
.device_scale_factor();
582 DCHECK_EQ(device_scale_factor
,
583 ui::GetImageScale(GetScaleFactorForView(this)));
585 const gfx::Size
& dst_size_in_pixel
= ConvertViewSizeToPixel(this, dst_size
);
586 gfx::Rect src_subrect_in_pixel
=
587 ConvertRectToPixel(device_scale_factor
, src_subrect
);
589 if (using_synchronous_compositor_
) {
590 SynchronousCopyContents(src_subrect_in_pixel
, dst_size_in_pixel
, callback
);
594 scoped_ptr
<cc::CopyOutputRequest
> request
;
595 if (src_subrect_in_pixel
.size() == dst_size_in_pixel
) {
596 request
= cc::CopyOutputRequest::CreateBitmapRequest(base::Bind(
597 &RenderWidgetHostViewAndroid::PrepareBitmapCopyOutputResult
,
601 request
= cc::CopyOutputRequest::CreateRequest(base::Bind(
602 &RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResult
,
606 request
->set_area(src_subrect_in_pixel
);
607 layer_
->RequestCopyOfOutput(request
.Pass());
610 void RenderWidgetHostViewAndroid::CopyFromCompositingSurfaceToVideoFrame(
611 const gfx::Rect
& src_subrect
,
612 const scoped_refptr
<media::VideoFrame
>& target
,
613 const base::Callback
<void(bool)>& callback
) {
618 bool RenderWidgetHostViewAndroid::CanCopyToVideoFrame() const {
622 void RenderWidgetHostViewAndroid::ShowDisambiguationPopup(
623 const gfx::Rect
& target_rect
, const SkBitmap
& zoomed_bitmap
) {
624 if (!content_view_core_
)
627 content_view_core_
->ShowDisambiguationPopup(target_rect
, zoomed_bitmap
);
630 scoped_ptr
<SyntheticGestureTarget
>
631 RenderWidgetHostViewAndroid::CreateSyntheticGestureTarget() {
632 return scoped_ptr
<SyntheticGestureTarget
>(new SyntheticGestureTargetAndroid(
633 host_
, content_view_core_
->CreateTouchEventSynthesizer()));
636 void RenderWidgetHostViewAndroid::OnAcceleratedCompositingStateChange() {
639 void RenderWidgetHostViewAndroid::SendDelegatedFrameAck(
640 uint32 output_surface_id
) {
641 cc::CompositorFrameAck ack
;
642 if (resource_collection_
.get())
643 resource_collection_
->TakeUnusedResourcesForChildCompositor(&ack
.resources
);
644 RenderWidgetHostImpl::SendSwapCompositorFrameAck(host_
->GetRoutingID(),
646 host_
->GetProcess()->GetID(),
650 void RenderWidgetHostViewAndroid::UnusedResourcesAreAvailable() {
651 // TODO(danakj): If no ack is pending, collect and send resources now.
654 void RenderWidgetHostViewAndroid::DestroyDelegatedContent() {
655 if (are_layers_attached_
)
657 frame_provider_
= NULL
;
658 delegated_renderer_layer_
= NULL
;
662 void RenderWidgetHostViewAndroid::SwapDelegatedFrame(
663 uint32 output_surface_id
,
664 scoped_ptr
<cc::DelegatedFrameData
> frame_data
) {
665 bool has_content
= !texture_size_in_layer_
.IsEmpty();
667 if (output_surface_id
!= last_output_surface_id_
) {
668 // TODO(danakj): Lose all resources and send them back here, such as:
669 // resource_collection_->LoseAllResources();
670 // SendReturnedDelegatedResources(last_output_surface_id_);
672 // Drop the cc::DelegatedFrameResourceCollection so that we will not return
673 // any resources from the old output surface with the new output surface id.
674 if (resource_collection_
.get()) {
675 resource_collection_
->SetClient(NULL
);
676 resource_collection_
= NULL
;
678 DestroyDelegatedContent();
680 last_output_surface_id_
= output_surface_id
;
684 DestroyDelegatedContent();
686 if (!resource_collection_
.get()) {
687 resource_collection_
= new cc::DelegatedFrameResourceCollection
;
688 resource_collection_
->SetClient(this);
690 if (!frame_provider_
||
691 texture_size_in_layer_
!= frame_provider_
->frame_size()) {
692 if (are_layers_attached_
)
694 frame_provider_
= new cc::DelegatedFrameProvider(
695 resource_collection_
.get(), frame_data
.Pass());
696 delegated_renderer_layer_
=
697 cc::DelegatedRendererLayer::Create(frame_provider_
);
698 layer_
= delegated_renderer_layer_
;
699 if (are_layers_attached_
)
702 frame_provider_
->SetFrameData(frame_data
.Pass());
706 if (delegated_renderer_layer_
.get()) {
707 delegated_renderer_layer_
->SetDisplaySize(texture_size_in_layer_
);
708 delegated_renderer_layer_
->SetIsDrawable(true);
709 delegated_renderer_layer_
->SetContentsOpaque(true);
710 delegated_renderer_layer_
->SetBounds(content_size_in_layer_
);
711 delegated_renderer_layer_
->SetNeedsDisplay();
714 base::Closure ack_callback
=
715 base::Bind(&RenderWidgetHostViewAndroid::SendDelegatedFrameAck
,
716 weak_ptr_factory_
.GetWeakPtr(),
719 if (host_
->is_hidden())
722 ack_callbacks_
.push(ack_callback
);
725 void RenderWidgetHostViewAndroid::ComputeContentsSize(
726 const cc::CompositorFrameMetadata
& frame_metadata
) {
727 // Calculate the content size. This should be 0 if the texture_size is 0.
728 gfx::Vector2dF offset
;
729 if (texture_size_in_layer_
.GetArea() > 0)
730 offset
= frame_metadata
.location_bar_content_translation
;
731 offset
.set_y(offset
.y() + frame_metadata
.overdraw_bottom_height
);
732 offset
.Scale(frame_metadata
.device_scale_factor
);
733 content_size_in_layer_
=
734 gfx::Size(texture_size_in_layer_
.width() - offset
.x(),
735 texture_size_in_layer_
.height() - offset
.y());
736 // Content size changes should be reflected in associated animation effects.
737 UpdateAnimationSize(frame_metadata
);
740 void RenderWidgetHostViewAndroid::OnSwapCompositorFrame(
741 uint32 output_surface_id
,
742 scoped_ptr
<cc::CompositorFrame
> frame
) {
743 // Always let ContentViewCore know about the new frame first, so it can decide
744 // to schedule a Draw immediately when it sees the texture layer invalidation.
745 UpdateContentViewCoreFrameMetadata(frame
->metadata
);
747 if (frame
->delegated_frame_data
) {
748 DCHECK(UsingDelegatedRenderer());
750 DCHECK(frame
->delegated_frame_data
);
751 DCHECK(!frame
->delegated_frame_data
->render_pass_list
.empty());
753 cc::RenderPass
* root_pass
=
754 frame
->delegated_frame_data
->render_pass_list
.back();
755 texture_size_in_layer_
= root_pass
->output_rect
.size();
756 ComputeContentsSize(frame
->metadata
);
758 SwapDelegatedFrame(output_surface_id
, frame
->delegated_frame_data
.Pass());
762 DCHECK(!UsingDelegatedRenderer());
764 if (!frame
->gl_frame_data
|| frame
->gl_frame_data
->mailbox
.IsZero())
767 if (output_surface_id
!= last_output_surface_id_
) {
768 current_mailbox_
= gpu::Mailbox();
769 last_output_surface_id_
= kUndefinedOutputSurfaceId
;
772 base::Closure callback
= base::Bind(&InsertSyncPointAndAckForCompositor
,
773 host_
->GetProcess()->GetID(),
775 host_
->GetRoutingID(),
777 texture_size_in_layer_
);
778 ImageTransportFactoryAndroid::GetInstance()->WaitSyncPoint(
779 frame
->gl_frame_data
->sync_point
);
781 texture_size_in_layer_
= frame
->gl_frame_data
->size
;
782 ComputeContentsSize(frame
->metadata
);
784 if (layer_
->layer_tree_host()) {
785 scoped_ptr
<cc::SwapPromise
> swap_promise(
786 new cc::LatencyInfoSwapPromise(frame
->metadata
.latency_info
));
787 layer_
->layer_tree_host()->QueueSwapPromise(swap_promise
.Pass());
790 BuffersSwapped(frame
->gl_frame_data
->mailbox
, output_surface_id
, callback
);
793 void RenderWidgetHostViewAndroid::SynchronousFrameMetadata(
794 const cc::CompositorFrameMetadata
& frame_metadata
) {
795 // This is a subset of OnSwapCompositorFrame() used in the synchronous
797 UpdateContentViewCoreFrameMetadata(frame_metadata
);
798 ComputeContentsSize(frame_metadata
);
800 // DevTools ScreenCast support for Android WebView.
801 if (DevToolsAgentHost::HasFor(RenderViewHost::From(GetRenderWidgetHost()))) {
802 scoped_refptr
<DevToolsAgentHost
> dtah
=
803 DevToolsAgentHost::GetOrCreateFor(
804 RenderViewHost::From(GetRenderWidgetHost()));
805 // Unblock the compositor.
806 BrowserThread::PostTask(
807 BrowserThread::UI
, FROM_HERE
,
808 base::Bind(&RenderViewDevToolsAgentHost::SynchronousSwapCompositorFrame
,
809 static_cast<RenderViewDevToolsAgentHost
*>(dtah
.get()),
814 void RenderWidgetHostViewAndroid::SynchronousCopyContents(
815 const gfx::Rect
& src_subrect_in_pixel
,
816 const gfx::Size
& dst_size_in_pixel
,
817 const base::Callback
<void(bool, const SkBitmap
&)>& callback
) {
818 SynchronousCompositor
* compositor
=
819 SynchronousCompositorImpl::FromID(host_
->GetProcess()->GetID(),
820 host_
->GetRoutingID());
822 callback
.Run(false, SkBitmap());
827 bitmap
.setConfig(SkBitmap::kARGB_8888_Config
,
828 dst_size_in_pixel
.width(),
829 dst_size_in_pixel
.height());
830 bitmap
.allocPixels();
831 SkCanvas
canvas(bitmap
);
833 (float)dst_size_in_pixel
.width() / (float)src_subrect_in_pixel
.width(),
834 (float)dst_size_in_pixel
.height() / (float)src_subrect_in_pixel
.height());
835 compositor
->DemandDrawSw(&canvas
);
836 callback
.Run(true, bitmap
);
839 void RenderWidgetHostViewAndroid::UpdateContentViewCoreFrameMetadata(
840 const cc::CompositorFrameMetadata
& frame_metadata
) {
841 if (content_view_core_
) {
842 // All offsets and sizes are in CSS pixels.
843 content_view_core_
->UpdateFrameInfo(
844 frame_metadata
.root_scroll_offset
,
845 frame_metadata
.page_scale_factor
,
846 gfx::Vector2dF(frame_metadata
.min_page_scale_factor
,
847 frame_metadata
.max_page_scale_factor
),
848 frame_metadata
.root_layer_size
,
849 frame_metadata
.viewport_size
,
850 frame_metadata
.location_bar_offset
,
851 frame_metadata
.location_bar_content_translation
,
852 frame_metadata
.overdraw_bottom_height
);
856 void RenderWidgetHostViewAndroid::AcceleratedSurfaceInitialized(int host_id
,
858 accelerated_surface_route_id_
= route_id
;
861 void RenderWidgetHostViewAndroid::AcceleratedSurfaceBuffersSwapped(
862 const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params
& params
,
864 NOTREACHED() << "Need --composite-to-mailbox or --enable-delegated-renderer";
867 void RenderWidgetHostViewAndroid::BuffersSwapped(
868 const gpu::Mailbox
& mailbox
,
869 uint32_t output_surface_id
,
870 const base::Closure
& ack_callback
) {
871 ImageTransportFactoryAndroid
* factory
=
872 ImageTransportFactoryAndroid::GetInstance();
874 if (!texture_id_in_layer_
) {
875 texture_id_in_layer_
= factory
->CreateTexture();
876 texture_layer_
->SetTextureId(texture_id_in_layer_
);
877 texture_layer_
->SetIsDrawable(true);
878 texture_layer_
->SetContentsOpaque(true);
881 ImageTransportFactoryAndroid::GetInstance()->AcquireTexture(
882 texture_id_in_layer_
, mailbox
.name
);
886 current_mailbox_
= mailbox
;
887 last_output_surface_id_
= output_surface_id
;
889 if (host_
->is_hidden())
892 ack_callbacks_
.push(ack_callback
);
895 void RenderWidgetHostViewAndroid::AttachLayers() {
896 if (!content_view_core_
)
901 content_view_core_
->AttachLayer(layer_
);
902 if (overscroll_effect_enabled_
)
903 overscroll_effect_
->Enable();
906 void RenderWidgetHostViewAndroid::RemoveLayers() {
907 if (!content_view_core_
)
912 content_view_core_
->RemoveLayer(layer_
);
913 overscroll_effect_
->Disable();
916 bool RenderWidgetHostViewAndroid::Animate(base::TimeTicks frame_time
) {
917 return overscroll_effect_
->Animate(frame_time
);
920 void RenderWidgetHostViewAndroid::UpdateAnimationSize(
921 const cc::CompositorFrameMetadata
& frame_metadata
) {
922 // Disable edge effects for axes on which scrolling is impossible.
923 gfx::SizeF ceiled_viewport_size
=
924 gfx::ToCeiledSize(frame_metadata
.viewport_size
);
925 overscroll_effect_
->set_horizontal_overscroll_enabled(
926 ceiled_viewport_size
.width() < frame_metadata
.root_layer_size
.width());
927 overscroll_effect_
->set_vertical_overscroll_enabled(
928 ceiled_viewport_size
.height() < frame_metadata
.root_layer_size
.height());
929 overscroll_effect_
->set_size(content_size_in_layer_
);
932 void RenderWidgetHostViewAndroid::AcceleratedSurfacePostSubBuffer(
933 const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params
& params
,
938 void RenderWidgetHostViewAndroid::AcceleratedSurfaceSuspend() {
942 void RenderWidgetHostViewAndroid::AcceleratedSurfaceRelease() {
943 // This tells us we should free the frontbuffer.
944 if (texture_id_in_layer_
) {
945 texture_layer_
->SetTextureId(0);
946 texture_layer_
->SetIsDrawable(false);
947 ImageTransportFactoryAndroid::GetInstance()->DeleteTexture(
948 texture_id_in_layer_
);
949 texture_id_in_layer_
= 0;
950 current_mailbox_
= gpu::Mailbox();
951 last_output_surface_id_
= kUndefinedOutputSurfaceId
;
953 if (delegated_renderer_layer_
.get())
954 DestroyDelegatedContent();
957 bool RenderWidgetHostViewAndroid::HasAcceleratedSurface(
958 const gfx::Size
& desired_size
) {
963 void RenderWidgetHostViewAndroid::GetScreenInfo(blink::WebScreenInfo
* result
) {
964 // ScreenInfo isn't tied to the widget on Android. Always return the default.
965 RenderWidgetHostViewBase::GetDefaultScreenInfo(result
);
968 // TODO(jrg): Find out the implications and answer correctly here,
969 // as we are returning the WebView and not root window bounds.
970 gfx::Rect
RenderWidgetHostViewAndroid::GetBoundsInRootWindow() {
971 return GetViewBounds();
974 gfx::GLSurfaceHandle
RenderWidgetHostViewAndroid::GetCompositingSurface() {
975 gfx::GLSurfaceHandle handle
=
976 gfx::GLSurfaceHandle(gfx::kNullPluginWindow
, gfx::NATIVE_TRANSPORT
);
977 if (CompositorImpl::IsInitialized()) {
978 handle
.parent_client_id
=
979 ImageTransportFactoryAndroid::GetInstance()->GetChannelID();
984 void RenderWidgetHostViewAndroid::ProcessAckedTouchEvent(
985 const TouchEventWithLatencyInfo
& touch
, InputEventAckState ack_result
) {
986 if (content_view_core_
)
987 content_view_core_
->ConfirmTouchEvent(ack_result
);
990 void RenderWidgetHostViewAndroid::SetHasHorizontalScrollbar(
991 bool has_horizontal_scrollbar
) {
992 // intentionally empty, like RenderWidgetHostViewViews
995 void RenderWidgetHostViewAndroid::SetScrollOffsetPinning(
996 bool is_pinned_to_left
, bool is_pinned_to_right
) {
997 // intentionally empty, like RenderWidgetHostViewViews
1000 void RenderWidgetHostViewAndroid::UnhandledWheelEvent(
1001 const blink::WebMouseWheelEvent
& event
) {
1002 // intentionally empty, like RenderWidgetHostViewViews
1005 void RenderWidgetHostViewAndroid::GestureEventAck(
1006 int gesture_event_type
,
1007 InputEventAckState ack_result
) {
1008 if (gesture_event_type
== blink::WebInputEvent::GestureScrollUpdate
&&
1009 ack_result
== INPUT_EVENT_ACK_STATE_CONSUMED
) {
1010 content_view_core_
->OnScrollUpdateGestureConsumed();
1012 if (gesture_event_type
== blink::WebInputEvent::GestureFlingStart
&&
1013 ack_result
== INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS
) {
1014 content_view_core_
->UnhandledFlingStartEvent();
1018 InputEventAckState
RenderWidgetHostViewAndroid::FilterInputEvent(
1019 const blink::WebInputEvent
& input_event
) {
1021 return INPUT_EVENT_ACK_STATE_NOT_CONSUMED
;
1023 if (input_event
.type
== blink::WebInputEvent::GestureTapDown
||
1024 input_event
.type
== blink::WebInputEvent::TouchStart
) {
1025 GpuDataManagerImpl
* gpu_data
= GpuDataManagerImpl::GetInstance();
1026 GpuProcessHostUIShim
* shim
= GpuProcessHostUIShim::GetOneInstance();
1027 if (shim
&& gpu_data
&& accelerated_surface_route_id_
&&
1028 gpu_data
->IsDriverBugWorkaroundActive(gpu::WAKE_UP_GPU_BEFORE_DRAWING
))
1030 new AcceleratedSurfaceMsg_WakeUpGpu(accelerated_surface_route_id_
));
1033 SynchronousCompositorImpl
* compositor
=
1034 SynchronousCompositorImpl::FromID(host_
->GetProcess()->GetID(),
1035 host_
->GetRoutingID());
1037 return compositor
->HandleInputEvent(input_event
);
1038 return INPUT_EVENT_ACK_STATE_NOT_CONSUMED
;
1041 void RenderWidgetHostViewAndroid::OnSetNeedsFlushInput() {
1042 if (flush_input_requested_
|| !content_view_core_
)
1044 flush_input_requested_
= true;
1045 content_view_core_
->AddBeginFrameSubscriber();
1048 void RenderWidgetHostViewAndroid::OnAccessibilityEvents(
1049 const std::vector
<AccessibilityHostMsg_EventParams
>& params
) {
1050 if (!host_
|| host_
->accessibility_mode() != AccessibilityModeComplete
)
1053 if (!GetBrowserAccessibilityManager()) {
1054 base::android::ScopedJavaLocalRef
<jobject
> obj
;
1055 if (content_view_core_
)
1056 obj
= content_view_core_
->GetJavaObject();
1057 SetBrowserAccessibilityManager(
1058 new BrowserAccessibilityManagerAndroid(
1059 obj
, BrowserAccessibilityManagerAndroid::GetEmptyDocument(), this));
1061 GetBrowserAccessibilityManager()->OnAccessibilityEvents(params
);
1064 void RenderWidgetHostViewAndroid::SetAccessibilityFocus(int acc_obj_id
) {
1068 host_
->AccessibilitySetFocus(acc_obj_id
);
1071 void RenderWidgetHostViewAndroid::AccessibilityDoDefaultAction(int acc_obj_id
) {
1075 host_
->AccessibilityDoDefaultAction(acc_obj_id
);
1078 void RenderWidgetHostViewAndroid::AccessibilityScrollToMakeVisible(
1079 int acc_obj_id
, gfx::Rect subfocus
) {
1083 host_
->AccessibilityScrollToMakeVisible(acc_obj_id
, subfocus
);
1086 void RenderWidgetHostViewAndroid::AccessibilityScrollToPoint(
1087 int acc_obj_id
, gfx::Point point
) {
1091 host_
->AccessibilityScrollToPoint(acc_obj_id
, point
);
1094 void RenderWidgetHostViewAndroid::AccessibilitySetTextSelection(
1095 int acc_obj_id
, int start_offset
, int end_offset
) {
1099 host_
->AccessibilitySetTextSelection(
1100 acc_obj_id
, start_offset
, end_offset
);
1103 gfx::Point
RenderWidgetHostViewAndroid::GetLastTouchEventLocation() const {
1105 // Only used on Win8
1106 return gfx::Point();
1109 void RenderWidgetHostViewAndroid::FatalAccessibilityTreeError() {
1113 host_
->FatalAccessibilityTreeError();
1114 SetBrowserAccessibilityManager(NULL
);
1117 bool RenderWidgetHostViewAndroid::LockMouse() {
1122 void RenderWidgetHostViewAndroid::UnlockMouse() {
1126 // Methods called from the host to the render
1128 void RenderWidgetHostViewAndroid::SendKeyEvent(
1129 const NativeWebKeyboardEvent
& event
) {
1131 host_
->ForwardKeyboardEvent(event
);
1134 void RenderWidgetHostViewAndroid::SendTouchEvent(
1135 const blink::WebTouchEvent
& event
) {
1137 host_
->ForwardTouchEventWithLatencyInfo(event
, ui::LatencyInfo());
1141 void RenderWidgetHostViewAndroid::SendMouseEvent(
1142 const blink::WebMouseEvent
& event
) {
1144 host_
->ForwardMouseEvent(event
);
1147 void RenderWidgetHostViewAndroid::SendMouseWheelEvent(
1148 const blink::WebMouseWheelEvent
& event
) {
1150 host_
->ForwardWheelEvent(event
);
1153 void RenderWidgetHostViewAndroid::SendGestureEvent(
1154 const blink::WebGestureEvent
& event
) {
1155 // Sending a gesture that may trigger overscroll should resume the effect.
1156 if (overscroll_effect_enabled_
)
1157 overscroll_effect_
->Enable();
1160 host_
->ForwardGestureEvent(event
);
1163 void RenderWidgetHostViewAndroid::SelectRange(const gfx::Point
& start
,
1164 const gfx::Point
& end
) {
1166 host_
->SelectRange(start
, end
);
1169 void RenderWidgetHostViewAndroid::MoveCaret(const gfx::Point
& point
) {
1171 host_
->MoveCaret(point
);
1174 void RenderWidgetHostViewAndroid::RequestContentClipping(
1175 const gfx::Rect
& clipping
,
1176 const gfx::Size
& content_size
) {
1177 // A focused view provides its own clipping.
1181 ClipContents(clipping
, content_size
);
1184 void RenderWidgetHostViewAndroid::ResetClipping() {
1185 ClipContents(gfx::Rect(gfx::Point(), content_size_in_layer_
),
1186 content_size_in_layer_
);
1189 void RenderWidgetHostViewAndroid::ClipContents(const gfx::Rect
& clipping
,
1190 const gfx::Size
& content_size
) {
1191 if (!texture_id_in_layer_
|| content_size_in_layer_
.IsEmpty())
1194 gfx::Size
clipped_content(content_size_in_layer_
);
1195 clipped_content
.SetToMin(clipping
.size());
1196 texture_layer_
->SetBounds(clipped_content
);
1197 texture_layer_
->SetNeedsDisplay();
1199 if (texture_size_in_layer_
.IsEmpty()) {
1200 texture_layer_
->SetUV(gfx::PointF(), gfx::PointF());
1205 clipping
.x() + content_size_in_layer_
.width() - content_size
.width(),
1206 clipping
.y() + content_size_in_layer_
.height() - content_size
.height());
1207 offset
.SetToMax(gfx::PointF());
1209 gfx::Vector2dF
uv_scale(1.f
/ texture_size_in_layer_
.width(),
1210 1.f
/ texture_size_in_layer_
.height());
1211 texture_layer_
->SetUV(
1212 gfx::PointF(offset
.x() * uv_scale
.x(),
1213 offset
.y() * uv_scale
.y()),
1214 gfx::PointF((offset
.x() + clipped_content
.width()) * uv_scale
.x(),
1215 (offset
.y() + clipped_content
.height()) * uv_scale
.y()));
1218 SkColor
RenderWidgetHostViewAndroid::GetCachedBackgroundColor() const {
1219 return cached_background_color_
;
1222 void RenderWidgetHostViewAndroid::OnOverscrolled(
1223 gfx::Vector2dF accumulated_overscroll
,
1224 gfx::Vector2dF current_fling_velocity
) {
1225 if (!content_view_core_
|| !are_layers_attached_
)
1228 if (overscroll_effect_
->OnOverscrolled(content_view_core_
->GetLayer(),
1229 base::TimeTicks::Now(),
1230 accumulated_overscroll
,
1231 current_fling_velocity
)) {
1232 content_view_core_
->SetNeedsAnimate();
1236 void RenderWidgetHostViewAndroid::SetContentViewCore(
1237 ContentViewCoreImpl
* content_view_core
) {
1240 if (are_layers_attached_
)
1243 if (content_view_core_
&& !using_synchronous_compositor_
)
1244 content_view_core_
->GetWindowAndroid()->RemoveObserver(this);
1246 content_view_core_
= content_view_core
;
1248 if (GetBrowserAccessibilityManager()) {
1249 base::android::ScopedJavaLocalRef
<jobject
> obj
;
1250 if (content_view_core_
)
1251 obj
= content_view_core_
->GetJavaObject();
1252 GetBrowserAccessibilityManager()->ToBrowserAccessibilityManagerAndroid()->
1253 SetContentViewCore(obj
);
1256 if (are_layers_attached_
) {
1258 if (content_view_core_
&& !using_synchronous_compositor_
)
1259 content_view_core_
->GetWindowAndroid()->AddObserver(this);
1263 void RenderWidgetHostViewAndroid::RunAckCallbacks() {
1264 while (!ack_callbacks_
.empty()) {
1265 ack_callbacks_
.front().Run();
1266 ack_callbacks_
.pop();
1270 void RenderWidgetHostViewAndroid::HasTouchEventHandlers(
1271 bool need_touch_events
) {
1272 if (content_view_core_
)
1273 content_view_core_
->HasTouchEventHandlers(need_touch_events
);
1276 void RenderWidgetHostViewAndroid::OnCompositingDidCommit() {
1280 void RenderWidgetHostViewAndroid::OnDetachCompositor() {
1281 DCHECK(content_view_core_
);
1282 DCHECK(!using_synchronous_compositor_
);
1286 void RenderWidgetHostViewAndroid::OnLostResources() {
1287 if (texture_layer_
.get())
1288 texture_layer_
->SetIsDrawable(false);
1289 if (delegated_renderer_layer_
.get())
1290 DestroyDelegatedContent();
1291 texture_id_in_layer_
= 0;
1296 void RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResult(
1297 const gfx::Size
& dst_size_in_pixel
,
1298 const base::Callback
<void(bool, const SkBitmap
&)>& callback
,
1299 scoped_ptr
<cc::CopyOutputResult
> result
) {
1300 DCHECK(result
->HasTexture());
1301 base::ScopedClosureRunner
scoped_callback_runner(
1302 base::Bind(callback
, false, SkBitmap()));
1304 if (!result
->HasTexture() || result
->IsEmpty() || result
->size().IsEmpty())
1307 scoped_ptr
<SkBitmap
> bitmap(new SkBitmap
);
1308 bitmap
->setConfig(SkBitmap::kARGB_8888_Config
,
1309 dst_size_in_pixel
.width(), dst_size_in_pixel
.height(),
1310 0, kOpaque_SkAlphaType
);
1311 if (!bitmap
->allocPixels())
1314 ImageTransportFactoryAndroid
* factory
=
1315 ImageTransportFactoryAndroid::GetInstance();
1316 GLHelper
* gl_helper
= factory
->GetGLHelper();
1320 scoped_ptr
<SkAutoLockPixels
> bitmap_pixels_lock(
1321 new SkAutoLockPixels(*bitmap
));
1322 uint8
* pixels
= static_cast<uint8
*>(bitmap
->getPixels());
1324 cc::TextureMailbox texture_mailbox
;
1325 scoped_ptr
<cc::SingleReleaseCallback
> release_callback
;
1326 result
->TakeTexture(&texture_mailbox
, &release_callback
);
1327 DCHECK(texture_mailbox
.IsTexture());
1328 if (!texture_mailbox
.IsTexture())
1331 ignore_result(scoped_callback_runner
.Release());
1333 gl_helper
->CropScaleReadbackAndCleanMailbox(
1334 texture_mailbox
.name(),
1335 texture_mailbox
.sync_point(),
1337 gfx::Rect(result
->size()),
1340 base::Bind(&CopyFromCompositingSurfaceFinished
,
1342 base::Passed(&release_callback
),
1343 base::Passed(&bitmap
),
1344 base::Passed(&bitmap_pixels_lock
)));
1348 void RenderWidgetHostViewAndroid::PrepareBitmapCopyOutputResult(
1349 const gfx::Size
& dst_size_in_pixel
,
1350 const base::Callback
<void(bool, const SkBitmap
&)>& callback
,
1351 scoped_ptr
<cc::CopyOutputResult
> result
) {
1352 DCHECK(result
->HasBitmap());
1353 base::ScopedClosureRunner
scoped_callback_runner(
1354 base::Bind(callback
, false, SkBitmap()));
1356 if (!result
->HasBitmap() || result
->IsEmpty() || result
->size().IsEmpty())
1359 scoped_ptr
<SkBitmap
> source
= result
->TakeBitmap();
1364 DCHECK_EQ(source
->width(), dst_size_in_pixel
.width());
1365 DCHECK_EQ(source
->height(), dst_size_in_pixel
.height());
1367 ignore_result(scoped_callback_runner
.Release());
1368 callback
.Run(true, *source
);
1372 void RenderWidgetHostViewPort::GetDefaultScreenInfo(
1373 blink::WebScreenInfo
* results
) {
1374 const gfx::Display
& display
=
1375 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
1376 results
->rect
= display
.bounds();
1377 // TODO(husky): Remove any system controls from availableRect.
1378 results
->availableRect
= display
.work_area();
1379 results
->deviceScaleFactor
= display
.device_scale_factor();
1380 gfx::DeviceDisplayInfo info
;
1381 results
->depth
= info
.GetBitsPerPixel();
1382 results
->depthPerComponent
= info
.GetBitsPerComponent();
1383 results
->isMonochrome
= (results
->depthPerComponent
== 0);
1386 ////////////////////////////////////////////////////////////////////////////////
1387 // RenderWidgetHostView, public:
1390 RenderWidgetHostView
*
1391 RenderWidgetHostView::CreateViewForWidget(RenderWidgetHost
* widget
) {
1392 RenderWidgetHostImpl
* rwhi
= RenderWidgetHostImpl::From(widget
);
1393 return new RenderWidgetHostViewAndroid(rwhi
, NULL
);
1396 } // namespace content