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/android/build_info.h"
10 #include "base/basictypes.h"
11 #include "base/bind.h"
12 #include "base/callback_helpers.h"
13 #include "base/command_line.h"
14 #include "base/logging.h"
15 #include "base/message_loop/message_loop.h"
16 #include "base/metrics/histogram.h"
17 #include "base/strings/utf_string_conversions.h"
18 #include "base/sys_info.h"
19 #include "base/threading/worker_pool.h"
20 #include "cc/layers/delegated_frame_provider.h"
21 #include "cc/layers/delegated_renderer_layer.h"
22 #include "cc/layers/layer.h"
23 #include "cc/layers/surface_layer.h"
24 #include "cc/output/compositor_frame.h"
25 #include "cc/output/compositor_frame_ack.h"
26 #include "cc/output/copy_output_request.h"
27 #include "cc/output/copy_output_result.h"
28 #include "cc/output/latency_info_swap_promise.h"
29 #include "cc/output/viewport_selection_bound.h"
30 #include "cc/resources/single_release_callback.h"
31 #include "cc/surfaces/surface.h"
32 #include "cc/surfaces/surface_factory.h"
33 #include "cc/surfaces/surface_id_allocator.h"
34 #include "cc/surfaces/surface_manager.h"
35 #include "cc/trees/layer_tree_host.h"
36 #include "content/browser/accessibility/browser_accessibility_manager_android.h"
37 #include "content/browser/android/composited_touch_handle_drawable.h"
38 #include "content/browser/android/content_view_core_impl.h"
39 #include "content/browser/android/edge_effect.h"
40 #include "content/browser/android/edge_effect_l.h"
41 #include "content/browser/android/in_process/synchronous_compositor_impl.h"
42 #include "content/browser/android/overscroll_controller_android.h"
43 #include "content/browser/devtools/render_frame_devtools_agent_host.h"
44 #include "content/browser/gpu/browser_gpu_channel_host_factory.h"
45 #include "content/browser/gpu/compositor_util.h"
46 #include "content/browser/gpu/gpu_data_manager_impl.h"
47 #include "content/browser/gpu/gpu_process_host_ui_shim.h"
48 #include "content/browser/gpu/gpu_surface_tracker.h"
49 #include "content/browser/media/media_web_contents_observer.h"
50 #include "content/browser/renderer_host/compositor_impl_android.h"
51 #include "content/browser/renderer_host/dip_util.h"
52 #include "content/browser/renderer_host/frame_metadata_util.h"
53 #include "content/browser/renderer_host/input/synthetic_gesture_target_android.h"
54 #include "content/browser/renderer_host/input/ui_touch_selection_helper.h"
55 #include "content/browser/renderer_host/input/web_input_event_builders_android.h"
56 #include "content/browser/renderer_host/input/web_input_event_util.h"
57 #include "content/browser/renderer_host/render_process_host_impl.h"
58 #include "content/browser/renderer_host/render_view_host_impl.h"
59 #include "content/browser/renderer_host/render_widget_host_impl.h"
60 #include "content/common/gpu/client/gl_helper.h"
61 #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
62 #include "content/common/gpu/gpu_messages.h"
63 #include "content/common/gpu/gpu_process_launch_causes.h"
64 #include "content/common/input/did_overscroll_params.h"
65 #include "content/common/input_messages.h"
66 #include "content/common/view_messages.h"
67 #include "content/public/browser/android/compositor.h"
68 #include "content/public/browser/browser_thread.h"
69 #include "content/public/browser/devtools_agent_host.h"
70 #include "content/public/browser/render_view_host.h"
71 #include "content/public/browser/render_widget_host_iterator.h"
72 #include "content/public/common/content_switches.h"
73 #include "gpu/command_buffer/client/gles2_implementation.h"
74 #include "gpu/command_buffer/client/gles2_interface.h"
75 #include "gpu/config/gpu_driver_bug_workaround_type.h"
76 #include "skia/ext/image_operations.h"
77 #include "third_party/khronos/GLES2/gl2.h"
78 #include "third_party/khronos/GLES2/gl2ext.h"
79 #include "third_party/skia/include/core/SkCanvas.h"
80 #include "ui/android/window_android.h"
81 #include "ui/android/window_android_compositor.h"
82 #include "ui/events/blink/blink_event_util.h"
83 #include "ui/events/gesture_detection/gesture_provider_config_helper.h"
84 #include "ui/events/gesture_detection/motion_event.h"
85 #include "ui/gfx/android/device_display_info.h"
86 #include "ui/gfx/android/java_bitmap.h"
87 #include "ui/gfx/android/view_configuration.h"
88 #include "ui/gfx/display.h"
89 #include "ui/gfx/geometry/dip_util.h"
90 #include "ui/gfx/geometry/size_conversions.h"
91 #include "ui/gfx/screen.h"
92 #include "ui/touch_selection/touch_selection_controller.h"
98 void SatisfyCallback(cc::SurfaceManager
* manager
,
99 cc::SurfaceSequence sequence
) {
100 std::vector
<uint32_t> sequences
;
101 sequences
.push_back(sequence
.sequence
);
102 manager
->DidSatisfySequences(sequence
.id_namespace
, &sequences
);
105 void RequireCallback(cc::SurfaceManager
* manager
,
107 cc::SurfaceSequence sequence
) {
108 cc::Surface
* surface
= manager
->GetSurfaceForId(id
);
110 LOG(ERROR
) << "Attempting to require callback on nonexistent surface";
113 surface
->AddDestructionDependency(sequence
);
116 const int kUndefinedOutputSurfaceId
= -1;
118 static const char kAsyncReadBackString
[] = "Compositing.CopyFromSurfaceTime";
121 : public blink::WebGraphicsContext3D::WebGraphicsContextLostCallback
{
123 static GLHelperHolder
* Create();
124 ~GLHelperHolder() override
;
128 // WebGraphicsContextLostCallback implementation.
129 void onContextLost() override
;
131 GLHelper
* GetGLHelper() { return gl_helper_
.get(); }
132 bool IsLost() { return !context_
.get() || context_
->isContextLost(); }
136 static scoped_ptr
<WebGraphicsContext3DCommandBufferImpl
> CreateContext3D();
138 scoped_ptr
<WebGraphicsContext3DCommandBufferImpl
> context_
;
139 scoped_ptr
<GLHelper
> gl_helper_
;
141 DISALLOW_COPY_AND_ASSIGN(GLHelperHolder
);
144 GLHelperHolder
* GLHelperHolder::Create() {
145 GLHelperHolder
* holder
= new GLHelperHolder
;
146 holder
->Initialize();
151 GLHelperHolder::GLHelperHolder() {
154 GLHelperHolder::~GLHelperHolder() {
157 void GLHelperHolder::Initialize() {
158 context_
= CreateContext3D();
160 context_
->setContextLostCallback(this);
161 gl_helper_
.reset(new GLHelper(context_
->GetImplementation(),
162 context_
->GetContextSupport()));
166 void GLHelperHolder::onContextLost() {
167 // Need to post a task because the command buffer client cannot be deleted
168 // from within this callback.
169 LOG(ERROR
) << "Context lost.";
170 base::MessageLoop::current()->PostTask(
172 base::Bind(&RenderWidgetHostViewAndroid::OnContextLost
));
175 scoped_ptr
<WebGraphicsContext3DCommandBufferImpl
>
176 GLHelperHolder::CreateContext3D() {
177 BrowserGpuChannelHostFactory
* factory
=
178 BrowserGpuChannelHostFactory::instance();
179 scoped_refptr
<GpuChannelHost
> gpu_channel_host(factory
->GetGpuChannel());
180 // GLHelper can only be used in asynchronous APIs for postprocessing after
181 // Browser Compositor operations (i.e. readback).
182 if (!gpu_channel_host
.get()) {
183 // The Browser Compositor is in charge of reestablishing the channel.
184 return scoped_ptr
<WebGraphicsContext3DCommandBufferImpl
>();
187 blink::WebGraphicsContext3D::Attributes attrs
;
188 attrs
.shareResources
= true;
189 GURL
url("chrome://gpu/RenderWidgetHostViewAndroid");
190 static const size_t kBytesPerPixel
= 4;
191 gfx::DeviceDisplayInfo display_info
;
192 size_t full_screen_texture_size_in_bytes
= display_info
.GetDisplayHeight() *
193 display_info
.GetDisplayWidth() *
195 WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits limits
;
196 limits
.command_buffer_size
= 64 * 1024;
197 limits
.start_transfer_buffer_size
= 64 * 1024;
198 limits
.min_transfer_buffer_size
= 64 * 1024;
199 limits
.max_transfer_buffer_size
= std::min(
200 3 * full_screen_texture_size_in_bytes
, kDefaultMaxTransferBufferSize
);
201 limits
.mapped_memory_reclaim_limit
=
202 WebGraphicsContext3DCommandBufferImpl::kNoLimit
;
203 bool lose_context_when_out_of_memory
= false;
204 scoped_ptr
<WebGraphicsContext3DCommandBufferImpl
> context(
205 new WebGraphicsContext3DCommandBufferImpl(
207 url
, gpu_channel_host
.get(), attrs
, lose_context_when_out_of_memory
,
209 context
->SetContextType(BROWSER_OFFSCREEN_MAINTHREAD_CONTEXT
);
210 if (context
->InitializeOnCurrentThread()) {
211 context
->traceBeginCHROMIUM(
213 base::StringPrintf("CmdBufferImageTransportFactory-%p",
214 context
.get()).c_str());
219 return context
.Pass();
222 // This can only be used for readback postprocessing. It may return null if the
223 // channel was lost and not reestablished yet.
224 GLHelper
* GetPostReadbackGLHelper() {
225 static GLHelperHolder
* g_readback_helper_holder
= nullptr;
227 if (g_readback_helper_holder
&& g_readback_helper_holder
->IsLost()) {
228 delete g_readback_helper_holder
;
229 g_readback_helper_holder
= nullptr;
232 if (!g_readback_helper_holder
)
233 g_readback_helper_holder
= GLHelperHolder::Create();
235 return g_readback_helper_holder
->GetGLHelper();
238 void CopyFromCompositingSurfaceFinished(
239 ReadbackRequestCallback
& callback
,
240 scoped_ptr
<cc::SingleReleaseCallback
> release_callback
,
241 scoped_ptr
<SkBitmap
> bitmap
,
242 const base::TimeTicks
& start_time
,
243 scoped_ptr
<SkAutoLockPixels
> bitmap_pixels_lock
,
246 "cc", "RenderWidgetHostViewAndroid::CopyFromCompositingSurfaceFinished");
247 bitmap_pixels_lock
.reset();
248 uint32 sync_point
= 0;
250 GLHelper
* gl_helper
= GetPostReadbackGLHelper();
252 sync_point
= gl_helper
->InsertSyncPoint();
254 bool lost_resource
= sync_point
== 0;
255 release_callback
->Run(sync_point
, lost_resource
);
256 UMA_HISTOGRAM_TIMES(kAsyncReadBackString
,
257 base::TimeTicks::Now() - start_time
);
258 ReadbackResponse response
= result
? READBACK_SUCCESS
: READBACK_FAILED
;
259 callback
.Run(*bitmap
, response
);
262 scoped_ptr
<ui::TouchSelectionController
> CreateSelectionController(
263 ui::TouchSelectionControllerClient
* client
,
264 ContentViewCore
* content_view_core
) {
266 DCHECK(content_view_core
);
267 ui::TouchSelectionController::Config config
;
268 config
.max_tap_duration
= base::TimeDelta::FromMilliseconds(
269 gfx::ViewConfiguration::GetLongPressTimeoutInMs());
270 config
.tap_slop
= gfx::ViewConfiguration::GetTouchSlopInDips();
271 config
.show_on_tap_for_empty_editable
= false;
272 config
.enable_longpress_drag_selection
=
273 base::CommandLine::ForCurrentProcess()->HasSwitch(
274 switches::kEnableLongpressDragSelection
);
275 return make_scoped_ptr(new ui::TouchSelectionController(client
, config
));
278 scoped_ptr
<OverscrollControllerAndroid
> CreateOverscrollController(
279 ContentViewCoreImpl
* content_view_core
) {
280 return make_scoped_ptr(new OverscrollControllerAndroid(content_view_core
));
283 gfx::RectF
GetSelectionRect(const ui::TouchSelectionController
& controller
) {
284 gfx::RectF rect
= controller
.GetRectBetweenBounds();
288 rect
.Union(controller
.GetStartHandleRect());
289 rect
.Union(controller
.GetEndHandleRect());
293 } // anonymous namespace
295 RenderWidgetHostViewAndroid::LastFrameInfo::LastFrameInfo(
297 scoped_ptr
<cc::CompositorFrame
> output_frame
)
298 : output_surface_id(output_id
), frame(output_frame
.Pass()) {}
300 RenderWidgetHostViewAndroid::LastFrameInfo::~LastFrameInfo() {}
302 void RenderWidgetHostViewAndroid::OnContextLost() {
303 scoped_ptr
<RenderWidgetHostIterator
> widgets(
304 RenderWidgetHostImpl::GetAllRenderWidgetHosts());
305 while (RenderWidgetHost
* widget
= widgets
->GetNextHost()) {
306 if (widget
->GetView()) {
307 static_cast<RenderWidgetHostViewAndroid
*>(widget
->GetView())
313 RenderWidgetHostViewAndroid::RenderWidgetHostViewAndroid(
314 RenderWidgetHostImpl
* widget_host
,
315 ContentViewCoreImpl
* content_view_core
)
316 : host_(widget_host
),
317 outstanding_vsync_requests_(0),
318 is_showing_(!widget_host
->is_hidden()),
319 content_view_core_(nullptr),
320 content_view_core_window_android_(nullptr),
321 ime_adapter_android_(this),
322 cached_background_color_(SK_ColorWHITE
),
323 last_output_surface_id_(kUndefinedOutputSurfaceId
),
324 gesture_provider_(ui::GetGestureProviderConfig(
325 ui::GestureProviderConfigType::CURRENT_PLATFORM
),
327 stylus_text_selector_(this),
328 accelerated_surface_route_id_(0),
329 using_browser_compositor_(CompositorImpl::IsInitialized()),
330 frame_evictor_(new DelegatedFrameEvictor(this)),
331 locks_on_frame_count_(0),
332 observing_root_window_(false),
333 weak_ptr_factory_(this) {
334 if (CompositorImpl::GetSurfaceManager())
335 id_allocator_
= CompositorImpl::CreateSurfaceIdAllocator();
336 host_
->SetView(this);
337 SetContentViewCore(content_view_core
);
340 RenderWidgetHostViewAndroid::~RenderWidgetHostViewAndroid() {
341 SetContentViewCore(NULL
);
342 DCHECK(ack_callbacks_
.empty());
343 if (resource_collection_
.get())
344 resource_collection_
->SetClient(NULL
);
345 DCHECK(!surface_factory_
);
346 DCHECK(surface_id_
.is_null());
349 void RenderWidgetHostViewAndroid::Blur() {
351 if (overscroll_controller_
)
352 overscroll_controller_
->Disable();
355 bool RenderWidgetHostViewAndroid::OnMessageReceived(
356 const IPC::Message
& message
) {
358 IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewAndroid
, message
)
359 IPC_MESSAGE_HANDLER(ViewHostMsg_StartContentIntent
, OnStartContentIntent
)
360 IPC_MESSAGE_HANDLER(ViewHostMsg_DidChangeBodyBackgroundColor
,
361 OnDidChangeBodyBackgroundColor
)
362 IPC_MESSAGE_HANDLER(ViewHostMsg_SetNeedsBeginFrames
,
363 OnSetNeedsBeginFrames
)
364 IPC_MESSAGE_HANDLER(ViewHostMsg_SmartClipDataExtracted
,
365 OnSmartClipDataExtracted
)
366 IPC_MESSAGE_HANDLER(ViewHostMsg_ShowUnhandledTapUIIfNeeded
,
367 OnShowUnhandledTapUIIfNeeded
)
368 IPC_MESSAGE_UNHANDLED(handled
= false)
369 IPC_END_MESSAGE_MAP()
373 void RenderWidgetHostViewAndroid::InitAsChild(gfx::NativeView parent_view
) {
377 void RenderWidgetHostViewAndroid::InitAsPopup(
378 RenderWidgetHostView
* parent_host_view
, const gfx::Rect
& pos
) {
382 void RenderWidgetHostViewAndroid::InitAsFullscreen(
383 RenderWidgetHostView
* reference_host_view
) {
388 RenderWidgetHostViewAndroid::GetRenderWidgetHost() const {
392 void RenderWidgetHostViewAndroid::WasResized() {
396 void RenderWidgetHostViewAndroid::SetSize(const gfx::Size
& size
) {
397 // Ignore the given size as only the Java code has the power to
398 // resize the view on Android.
399 default_size_
= size
;
402 void RenderWidgetHostViewAndroid::SetBounds(const gfx::Rect
& rect
) {
403 SetSize(rect
.size());
406 void RenderWidgetHostViewAndroid::GetScaledContentBitmap(
408 SkColorType preferred_color_type
,
409 gfx::Rect src_subrect
,
410 ReadbackRequestCallback
& result_callback
) {
411 if (!host_
|| host_
->is_hidden() || !IsSurfaceAvailableForCopy()) {
412 result_callback
.Run(SkBitmap(), READBACK_SURFACE_UNAVAILABLE
);
415 gfx::Size bounds
= layer_
->bounds();
416 if (src_subrect
.IsEmpty())
417 src_subrect
= gfx::Rect(bounds
);
418 DCHECK_LE(src_subrect
.width() + src_subrect
.x(), bounds
.width());
419 DCHECK_LE(src_subrect
.height() + src_subrect
.y(), bounds
.height());
420 const gfx::Display
& display
=
421 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
422 float device_scale_factor
= display
.device_scale_factor();
423 DCHECK_GT(device_scale_factor
, 0);
424 gfx::Size
dst_size(gfx::ToCeiledSize(
425 gfx::ScaleSize(src_subrect
.size(), scale
/ device_scale_factor
)));
426 src_subrect
= gfx::ConvertRectToDIP(device_scale_factor
, src_subrect
);
428 CopyFromCompositingSurface(src_subrect
, dst_size
, result_callback
,
429 preferred_color_type
);
432 scoped_refptr
<cc::Layer
> RenderWidgetHostViewAndroid::CreateDelegatedLayer()
434 scoped_refptr
<cc::Layer
> delegated_layer
;
435 if (!surface_id_
.is_null()) {
436 cc::SurfaceManager
* manager
= CompositorImpl::GetSurfaceManager();
438 // manager must outlive compositors using it.
439 scoped_refptr
<cc::SurfaceLayer
> surface_layer
= cc::SurfaceLayer::Create(
440 Compositor::LayerSettings(),
441 base::Bind(&SatisfyCallback
, base::Unretained(manager
)),
442 base::Bind(&RequireCallback
, base::Unretained(manager
)));
443 surface_layer
->SetSurfaceId(surface_id_
, 1.f
, texture_size_in_layer_
);
444 delegated_layer
= surface_layer
;
446 DCHECK(frame_provider_
.get());
447 delegated_layer
= cc::DelegatedRendererLayer::Create(
448 Compositor::LayerSettings(), frame_provider_
);
450 delegated_layer
->SetBounds(texture_size_in_layer_
);
451 delegated_layer
->SetIsDrawable(true);
452 delegated_layer
->SetContentsOpaque(true);
454 return delegated_layer
;
457 bool RenderWidgetHostViewAndroid::HasValidFrame() const {
458 if (!content_view_core_
)
463 if (texture_size_in_layer_
.IsEmpty())
465 // This tell us whether a valid frame has arrived or not.
466 if (!frame_evictor_
->HasFrame())
472 gfx::Vector2dF
RenderWidgetHostViewAndroid::GetLastScrollOffset() const {
473 return last_scroll_offset_
;
476 gfx::NativeView
RenderWidgetHostViewAndroid::GetNativeView() const {
477 return content_view_core_
->GetViewAndroid();
480 gfx::NativeViewId
RenderWidgetHostViewAndroid::GetNativeViewId() const {
481 return reinterpret_cast<gfx::NativeViewId
>(
482 const_cast<RenderWidgetHostViewAndroid
*>(this));
485 gfx::NativeViewAccessible
486 RenderWidgetHostViewAndroid::GetNativeViewAccessible() {
491 void RenderWidgetHostViewAndroid::MovePluginWindows(
492 const std::vector
<WebPluginGeometry
>& moves
) {
493 // We don't have plugin windows on Android. Do nothing. Note: this is called
494 // from RenderWidgetHost::OnUpdateRect which is itself invoked while
495 // processing the corresponding message from Renderer.
498 void RenderWidgetHostViewAndroid::Focus() {
500 if (overscroll_controller_
)
501 overscroll_controller_
->Enable();
502 if (content_view_core_
) {
503 WebContentsImpl
* web_contents_impl
=
504 static_cast<WebContentsImpl
*>(content_view_core_
->GetWebContents());
505 if (web_contents_impl
->ShowingInterstitialPage())
506 content_view_core_
->ForceUpdateImeAdapter(GetNativeImeAdapter());
510 bool RenderWidgetHostViewAndroid::HasFocus() const {
511 if (!content_view_core_
)
512 return false; // ContentViewCore not created yet.
514 return content_view_core_
->HasFocus();
517 bool RenderWidgetHostViewAndroid::IsSurfaceAvailableForCopy() const {
518 return HasValidFrame();
521 void RenderWidgetHostViewAndroid::Show() {
529 void RenderWidgetHostViewAndroid::Hide() {
535 bool hide_frontbuffer
= true;
536 bool stop_observing_root_window
= true;
537 HideInternal(hide_frontbuffer
, stop_observing_root_window
);
540 bool RenderWidgetHostViewAndroid::IsShowing() {
541 // ContentViewCoreImpl represents the native side of the Java
542 // ContentViewCore. It being NULL means that it is not attached
543 // to the View system yet, so we treat this RWHVA as hidden.
544 return is_showing_
&& content_view_core_
;
547 void RenderWidgetHostViewAndroid::LockCompositingSurface() {
548 DCHECK(HasValidFrame());
550 DCHECK(frame_evictor_
->HasFrame());
551 frame_evictor_
->LockFrame();
552 locks_on_frame_count_
++;
555 void RenderWidgetHostViewAndroid::UnlockCompositingSurface() {
556 if (!frame_evictor_
->HasFrame() || locks_on_frame_count_
== 0)
559 DCHECK(HasValidFrame());
560 frame_evictor_
->UnlockFrame();
561 locks_on_frame_count_
--;
563 if (locks_on_frame_count_
== 0) {
564 if (last_frame_info_
) {
565 InternalSwapCompositorFrame(last_frame_info_
->output_surface_id
,
566 last_frame_info_
->frame
.Pass());
567 last_frame_info_
.reset();
570 if (!is_showing_
&& layer_
.get())
571 layer_
->SetHideLayerAndSubtree(true);
575 void RenderWidgetHostViewAndroid::SetTextSurroundingSelectionCallback(
576 const TextSurroundingSelectionCallback
& callback
) {
577 // Only one outstanding request is allowed at any given time.
578 DCHECK(!callback
.is_null());
579 text_surrounding_selection_callback_
= callback
;
582 void RenderWidgetHostViewAndroid::OnTextSurroundingSelectionResponse(
583 const base::string16
& content
,
586 if (text_surrounding_selection_callback_
.is_null())
588 text_surrounding_selection_callback_
.Run(content
, start_offset
, end_offset
);
589 text_surrounding_selection_callback_
.Reset();
592 void RenderWidgetHostViewAndroid::OnShowUnhandledTapUIIfNeeded(int x_dip
,
594 if (!content_view_core_
)
596 // Validate the coordinates are within the viewport.
597 gfx::Size viewport_size
= content_view_core_
->GetViewportSizeDip();
598 if (x_dip
< 0 || x_dip
> viewport_size
.width() ||
599 y_dip
< 0 || y_dip
> viewport_size
.height())
601 content_view_core_
->OnShowUnhandledTapUIIfNeeded(x_dip
, y_dip
);
604 void RenderWidgetHostViewAndroid::ReleaseLocksOnSurface() {
605 if (!frame_evictor_
->HasFrame()) {
606 DCHECK_EQ(locks_on_frame_count_
, 0u);
609 while (locks_on_frame_count_
> 0) {
610 UnlockCompositingSurface();
612 RunAckCallbacks(cc::SurfaceDrawStatus::DRAW_SKIPPED
);
615 gfx::Rect
RenderWidgetHostViewAndroid::GetViewBounds() const {
616 if (!content_view_core_
)
617 return gfx::Rect(default_size_
);
619 return gfx::Rect(content_view_core_
->GetViewSize());
622 gfx::Size
RenderWidgetHostViewAndroid::GetPhysicalBackingSize() const {
623 if (!content_view_core_
)
626 return content_view_core_
->GetPhysicalBackingSize();
629 bool RenderWidgetHostViewAndroid::DoTopControlsShrinkBlinkSize() const {
630 if (!content_view_core_
)
633 // Whether or not Blink's viewport size should be shrunk by the height of the
635 return content_view_core_
->DoTopControlsShrinkBlinkSize();
638 float RenderWidgetHostViewAndroid::GetTopControlsHeight() const {
639 if (!content_view_core_
)
642 // The height of the top controls.
643 return content_view_core_
->GetTopControlsHeightDip();
646 void RenderWidgetHostViewAndroid::UpdateCursor(const WebCursor
& cursor
) {
647 // There are no cursors on Android.
650 void RenderWidgetHostViewAndroid::SetIsLoading(bool is_loading
) {
651 // Do nothing. The UI notification is handled through ContentViewClient which
652 // is TabContentsDelegate.
655 long RenderWidgetHostViewAndroid::GetNativeImeAdapter() {
656 return reinterpret_cast<intptr_t>(&ime_adapter_android_
);
659 void RenderWidgetHostViewAndroid::TextInputStateChanged(
660 const ViewHostMsg_TextInputState_Params
& params
) {
661 if (params
.is_non_ime_change
) {
662 // Sends an acknowledgement to the renderer of a processed IME event.
663 host_
->Send(new InputMsg_ImeEventAck(host_
->GetRoutingID()));
669 content_view_core_
->UpdateImeAdapter(
670 GetNativeImeAdapter(),
671 static_cast<int>(params
.type
), params
.flags
,
672 params
.value
, params
.selection_start
, params
.selection_end
,
673 params
.composition_start
, params
.composition_end
,
674 params
.show_ime_if_needed
, params
.is_non_ime_change
);
677 void RenderWidgetHostViewAndroid::OnDidChangeBodyBackgroundColor(
679 if (cached_background_color_
== color
)
682 cached_background_color_
= color
;
683 if (content_view_core_
)
684 content_view_core_
->OnBackgroundColorChanged(color
);
687 void RenderWidgetHostViewAndroid::OnSetNeedsBeginFrames(bool enabled
) {
688 TRACE_EVENT1("cc", "RenderWidgetHostViewAndroid::OnSetNeedsBeginFrames",
691 RequestVSyncUpdate(PERSISTENT_BEGIN_FRAME
);
693 outstanding_vsync_requests_
&= ~PERSISTENT_BEGIN_FRAME
;
696 void RenderWidgetHostViewAndroid::OnStartContentIntent(
697 const GURL
& content_url
) {
698 if (content_view_core_
)
699 content_view_core_
->StartContentIntent(content_url
);
702 void RenderWidgetHostViewAndroid::OnSmartClipDataExtracted(
703 const base::string16
& text
,
704 const base::string16
& html
,
705 const gfx::Rect rect
) {
706 if (content_view_core_
)
707 content_view_core_
->OnSmartClipDataExtracted(text
, html
, rect
);
710 bool RenderWidgetHostViewAndroid::OnTouchEvent(
711 const ui::MotionEvent
& event
) {
715 // If a browser-based widget consumes the touch event, it's critical that
716 // touch event interception be disabled. This avoids issues with
717 // double-handling for embedder-detected gestures like side swipe.
718 if (selection_controller_
&&
719 selection_controller_
->WillHandleTouchEvent(event
)) {
720 RequestDisallowInterceptTouchEvent();
724 if (stylus_text_selector_
.OnTouchEvent(event
)) {
725 RequestDisallowInterceptTouchEvent();
729 ui::FilteredGestureProvider::TouchHandlingResult result
=
730 gesture_provider_
.OnTouchEvent(event
);
731 if (!result
.succeeded
)
734 blink::WebTouchEvent web_event
=
735 ui::CreateWebTouchEventFromMotionEvent(event
, result
.did_generate_scroll
);
736 host_
->ForwardTouchEventWithLatencyInfo(web_event
, ui::LatencyInfo());
738 // Send a proactive BeginFrame for this vsync to reduce scroll latency for
739 // scroll-inducing touch events. Note that Android's Choreographer ensures
740 // that BeginFrame requests made during ACTION_MOVE dispatch will be honored
741 // in the same vsync phase.
742 if (observing_root_window_
&& result
.did_generate_scroll
)
743 RequestVSyncUpdate(BEGIN_FRAME
);
748 bool RenderWidgetHostViewAndroid::OnTouchHandleEvent(
749 const ui::MotionEvent
& event
) {
750 return selection_controller_
&&
751 selection_controller_
->WillHandleTouchEvent(event
);
754 void RenderWidgetHostViewAndroid::ResetGestureDetection() {
755 const ui::MotionEvent
* current_down_event
=
756 gesture_provider_
.GetCurrentDownEvent();
757 if (!current_down_event
) {
758 // A hard reset ensures prevention of any timer-based events that might fire
759 // after a touch sequence has ended.
760 gesture_provider_
.ResetDetection();
764 scoped_ptr
<ui::MotionEvent
> cancel_event
= current_down_event
->Cancel();
765 if (gesture_provider_
.OnTouchEvent(*cancel_event
).succeeded
) {
766 bool causes_scrolling
= false;
767 host_
->ForwardTouchEventWithLatencyInfo(
768 ui::CreateWebTouchEventFromMotionEvent(*cancel_event
, causes_scrolling
),
773 void RenderWidgetHostViewAndroid::OnDidNavigateMainFrameToNewPage() {
774 ResetGestureDetection();
777 void RenderWidgetHostViewAndroid::SetDoubleTapSupportEnabled(bool enabled
) {
778 gesture_provider_
.SetDoubleTapSupportForPlatformEnabled(enabled
);
781 void RenderWidgetHostViewAndroid::SetMultiTouchZoomSupportEnabled(
783 gesture_provider_
.SetMultiTouchZoomSupportEnabled(enabled
);
786 void RenderWidgetHostViewAndroid::ImeCancelComposition() {
787 ime_adapter_android_
.CancelComposition();
790 void RenderWidgetHostViewAndroid::ImeCompositionRangeChanged(
791 const gfx::Range
& range
,
792 const std::vector
<gfx::Rect
>& character_bounds
) {
793 // TODO(yukawa): Implement this.
796 void RenderWidgetHostViewAndroid::FocusedNodeChanged(bool is_editable_node
) {
797 ime_adapter_android_
.FocusedNodeChanged(is_editable_node
);
800 void RenderWidgetHostViewAndroid::RenderProcessGone(
801 base::TerminationStatus status
, int error_code
) {
805 void RenderWidgetHostViewAndroid::Destroy() {
807 SetContentViewCore(NULL
);
809 if (!surface_id_
.is_null()) {
810 DCHECK(surface_factory_
.get());
811 surface_factory_
->Destroy(surface_id_
);
812 surface_id_
= cc::SurfaceId();
814 surface_factory_
.reset();
816 // The RenderWidgetHost's destruction led here, so don't call it.
822 void RenderWidgetHostViewAndroid::SetTooltipText(
823 const base::string16
& tooltip_text
) {
824 // Tooltips don't makes sense on Android.
827 void RenderWidgetHostViewAndroid::SelectionChanged(const base::string16
& text
,
829 const gfx::Range
& range
) {
830 RenderWidgetHostViewBase::SelectionChanged(text
, offset
, range
);
832 if (!content_view_core_
)
834 if (range
.is_empty()) {
835 content_view_core_
->OnSelectionChanged("");
839 DCHECK(!text
.empty());
840 size_t pos
= range
.GetMin() - offset
;
841 size_t n
= range
.length();
843 DCHECK(pos
+ n
<= text
.length()) << "The text can not fully cover range.";
844 if (pos
>= text
.length()) {
845 NOTREACHED() << "The text can not cover range.";
849 std::string utf8_selection
= base::UTF16ToUTF8(text
.substr(pos
, n
));
851 content_view_core_
->OnSelectionChanged(utf8_selection
);
854 void RenderWidgetHostViewAndroid::SelectionBoundsChanged(
855 const ViewHostMsg_SelectionBounds_Params
& params
) {
856 NOTREACHED() << "Selection bounds should be routed through the compositor.";
859 void RenderWidgetHostViewAndroid::SetBackgroundColor(SkColor color
) {
860 RenderWidgetHostViewBase::SetBackgroundColor(color
);
861 host_
->SetBackgroundOpaque(GetBackgroundOpaque());
862 OnDidChangeBodyBackgroundColor(color
);
865 void RenderWidgetHostViewAndroid::CopyFromCompositingSurface(
866 const gfx::Rect
& src_subrect
,
867 const gfx::Size
& dst_size
,
868 ReadbackRequestCallback
& callback
,
869 const SkColorType preferred_color_type
) {
870 TRACE_EVENT0("cc", "RenderWidgetHostViewAndroid::CopyFromCompositingSurface");
871 if (!host_
|| host_
->is_hidden()) {
872 callback
.Run(SkBitmap(), READBACK_SURFACE_UNAVAILABLE
);
875 base::TimeTicks start_time
= base::TimeTicks::Now();
876 if (using_browser_compositor_
&& !IsSurfaceAvailableForCopy()) {
877 callback
.Run(SkBitmap(), READBACK_SURFACE_UNAVAILABLE
);
880 const gfx::Display
& display
=
881 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
882 float device_scale_factor
= display
.device_scale_factor();
883 gfx::Size dst_size_in_pixel
=
884 gfx::ConvertRectToPixel(device_scale_factor
, gfx::Rect(dst_size
)).size();
885 gfx::Rect src_subrect_in_pixel
=
886 gfx::ConvertRectToPixel(device_scale_factor
, src_subrect
);
888 if (!using_browser_compositor_
) {
889 SynchronousCopyContents(src_subrect_in_pixel
, dst_size_in_pixel
, callback
,
890 preferred_color_type
);
891 UMA_HISTOGRAM_TIMES("Compositing.CopyFromSurfaceTimeSynchronous",
892 base::TimeTicks::Now() - start_time
);
896 scoped_ptr
<cc::CopyOutputRequest
> request
;
897 scoped_refptr
<cc::Layer
> readback_layer
;
898 DCHECK(content_view_core_window_android_
);
899 ui::WindowAndroidCompositor
* compositor
=
900 content_view_core_window_android_
->GetCompositor();
902 DCHECK(frame_provider_
.get() || !surface_id_
.is_null());
903 scoped_refptr
<cc::Layer
> layer
= CreateDelegatedLayer();
905 layer
->SetHideLayerAndSubtree(true);
906 compositor
->AttachLayerForReadback(layer
);
908 readback_layer
= layer
;
909 request
= cc::CopyOutputRequest::CreateRequest(
910 base::Bind(&RenderWidgetHostViewAndroid::
911 PrepareTextureCopyOutputResultForDelegatedReadback
,
912 dst_size_in_pixel
, preferred_color_type
, start_time
,
913 readback_layer
, callback
));
914 if (!src_subrect_in_pixel
.IsEmpty())
915 request
->set_area(src_subrect_in_pixel
);
916 readback_layer
->RequestCopyOfOutput(request
.Pass());
919 void RenderWidgetHostViewAndroid::CopyFromCompositingSurfaceToVideoFrame(
920 const gfx::Rect
& src_subrect
,
921 const scoped_refptr
<media::VideoFrame
>& target
,
922 const base::Callback
<void(bool)>& callback
) {
927 bool RenderWidgetHostViewAndroid::CanCopyToVideoFrame() const {
931 void RenderWidgetHostViewAndroid::ShowDisambiguationPopup(
932 const gfx::Rect
& rect_pixels
, const SkBitmap
& zoomed_bitmap
) {
933 if (!content_view_core_
)
936 content_view_core_
->ShowDisambiguationPopup(rect_pixels
, zoomed_bitmap
);
939 scoped_ptr
<SyntheticGestureTarget
>
940 RenderWidgetHostViewAndroid::CreateSyntheticGestureTarget() {
941 return scoped_ptr
<SyntheticGestureTarget
>(new SyntheticGestureTargetAndroid(
942 host_
, content_view_core_
->CreateMotionEventSynthesizer()));
945 void RenderWidgetHostViewAndroid::SendDelegatedFrameAck(
946 uint32 output_surface_id
) {
948 cc::CompositorFrameAck ack
;
949 if (!surface_returned_resources_
.empty())
950 ack
.resources
.swap(surface_returned_resources_
);
951 if (resource_collection_
.get())
952 resource_collection_
->TakeUnusedResourcesForChildCompositor(&ack
.resources
);
953 host_
->Send(new ViewMsg_SwapCompositorFrameAck(host_
->GetRoutingID(),
954 output_surface_id
, ack
));
957 void RenderWidgetHostViewAndroid::SendReturnedDelegatedResources(
958 uint32 output_surface_id
) {
960 cc::CompositorFrameAck ack
;
961 if (!surface_returned_resources_
.empty()) {
962 ack
.resources
.swap(surface_returned_resources_
);
964 DCHECK(resource_collection_
.get());
965 resource_collection_
->TakeUnusedResourcesForChildCompositor(&ack
.resources
);
968 host_
->Send(new ViewMsg_ReclaimCompositorResources(host_
->GetRoutingID(),
969 output_surface_id
, ack
));
972 void RenderWidgetHostViewAndroid::UnusedResourcesAreAvailable() {
973 DCHECK(surface_id_
.is_null());
974 if (ack_callbacks_
.size())
976 SendReturnedDelegatedResources(last_output_surface_id_
);
979 void RenderWidgetHostViewAndroid::ReturnResources(
980 const cc::ReturnedResourceArray
& resources
) {
981 if (resources
.empty())
983 std::copy(resources
.begin(), resources
.end(),
984 std::back_inserter(surface_returned_resources_
));
985 if (!ack_callbacks_
.size())
986 SendReturnedDelegatedResources(last_output_surface_id_
);
989 void RenderWidgetHostViewAndroid::DestroyDelegatedContent() {
991 frame_provider_
= NULL
;
992 if (!surface_id_
.is_null()) {
993 DCHECK(surface_factory_
.get());
994 surface_factory_
->Destroy(surface_id_
);
995 surface_id_
= cc::SurfaceId();
1000 void RenderWidgetHostViewAndroid::CheckOutputSurfaceChanged(
1001 uint32 output_surface_id
) {
1002 if (output_surface_id
== last_output_surface_id_
)
1004 // Drop the cc::DelegatedFrameResourceCollection so that we will not return
1005 // any resources from the old output surface with the new output surface id.
1006 if (resource_collection_
.get()) {
1007 resource_collection_
->SetClient(NULL
);
1008 if (resource_collection_
->LoseAllResources())
1009 SendReturnedDelegatedResources(last_output_surface_id_
);
1010 resource_collection_
= NULL
;
1012 DestroyDelegatedContent();
1013 surface_factory_
.reset();
1014 if (!surface_returned_resources_
.empty())
1015 SendReturnedDelegatedResources(last_output_surface_id_
);
1017 last_output_surface_id_
= output_surface_id
;
1020 void RenderWidgetHostViewAndroid::SubmitCompositorFrame(
1021 scoped_ptr
<cc::CompositorFrame
> frame
) {
1022 cc::SurfaceManager
* manager
= CompositorImpl::GetSurfaceManager();
1024 if (!surface_factory_
) {
1025 surface_factory_
= make_scoped_ptr(new cc::SurfaceFactory(manager
, this));
1027 if (surface_id_
.is_null() ||
1028 texture_size_in_layer_
!= current_surface_size_
||
1029 location_bar_content_translation_
!=
1030 frame
->metadata
.location_bar_content_translation
||
1031 current_viewport_selection_
!= frame
->metadata
.selection
) {
1033 if (!surface_id_
.is_null())
1034 surface_factory_
->Destroy(surface_id_
);
1035 surface_id_
= id_allocator_
->GenerateId();
1036 surface_factory_
->Create(surface_id_
);
1037 layer_
= CreateDelegatedLayer();
1041 current_surface_size_
= texture_size_in_layer_
;
1042 location_bar_content_translation_
=
1043 frame
->metadata
.location_bar_content_translation
;
1044 current_viewport_selection_
= frame
->metadata
.selection
;
1048 cc::SurfaceFactory::DrawCallback ack_callback
=
1049 base::Bind(&RenderWidgetHostViewAndroid::RunAckCallbacks
,
1050 weak_ptr_factory_
.GetWeakPtr());
1051 surface_factory_
->SubmitCompositorFrame(surface_id_
, frame
.Pass(),
1054 if (!resource_collection_
.get()) {
1055 resource_collection_
= new cc::DelegatedFrameResourceCollection
;
1056 resource_collection_
->SetClient(this);
1058 if (!frame_provider_
.get() ||
1059 texture_size_in_layer_
!= frame_provider_
->frame_size()) {
1061 frame_provider_
= new cc::DelegatedFrameProvider(
1062 resource_collection_
.get(), frame
->delegated_frame_data
.Pass());
1063 layer_
= cc::DelegatedRendererLayer::Create(Compositor::LayerSettings(),
1067 frame_provider_
->SetFrameData(frame
->delegated_frame_data
.Pass());
1072 void RenderWidgetHostViewAndroid::SwapDelegatedFrame(
1073 uint32 output_surface_id
,
1074 scoped_ptr
<cc::CompositorFrame
> frame
) {
1075 CheckOutputSurfaceChanged(output_surface_id
);
1076 bool has_content
= !texture_size_in_layer_
.IsEmpty();
1078 // DelegatedRendererLayerImpl applies the inverse device_scale_factor of the
1079 // renderer frame, assuming that the browser compositor will scale
1080 // it back up to device scale. But on Android we put our browser layers in
1081 // physical pixels and set our browser CC device_scale_factor to 1, so this
1082 // suppresses the transform. This line may need to be removed when fixing
1083 // http://crbug.com/384134 or http://crbug.com/310763
1084 frame
->delegated_frame_data
->device_scale_factor
= 1.0f
;
1086 base::Closure ack_callback
=
1087 base::Bind(&RenderWidgetHostViewAndroid::SendDelegatedFrameAck
,
1088 weak_ptr_factory_
.GetWeakPtr(),
1091 ack_callbacks_
.push(ack_callback
);
1094 DestroyDelegatedContent();
1096 SubmitCompositorFrame(frame
.Pass());
1100 layer_
->SetIsDrawable(true);
1101 layer_
->SetContentsOpaque(true);
1102 layer_
->SetBounds(texture_size_in_layer_
);
1105 if (host_
->is_hidden())
1106 RunAckCallbacks(cc::SurfaceDrawStatus::DRAW_SKIPPED
);
1109 void RenderWidgetHostViewAndroid::InternalSwapCompositorFrame(
1110 uint32 output_surface_id
,
1111 scoped_ptr
<cc::CompositorFrame
> frame
) {
1112 last_scroll_offset_
= frame
->metadata
.root_scroll_offset
;
1113 if (!frame
->delegated_frame_data
) {
1114 LOG(ERROR
) << "Non-delegated renderer path no longer supported";
1118 if (locks_on_frame_count_
> 0) {
1119 DCHECK(HasValidFrame());
1120 RetainFrame(output_surface_id
, frame
.Pass());
1124 if (!CompositorImpl::GetSurfaceManager() && layer_
.get() &&
1125 layer_
->layer_tree_host()) {
1126 for (size_t i
= 0; i
< frame
->metadata
.latency_info
.size(); i
++) {
1127 scoped_ptr
<cc::SwapPromise
> swap_promise(
1128 new cc::LatencyInfoSwapPromise(frame
->metadata
.latency_info
[i
]));
1129 layer_
->layer_tree_host()->QueueSwapPromise(swap_promise
.Pass());
1133 DCHECK(!frame
->delegated_frame_data
->render_pass_list
.empty());
1135 cc::RenderPass
* root_pass
=
1136 frame
->delegated_frame_data
->render_pass_list
.back();
1137 texture_size_in_layer_
= root_pass
->output_rect
.size();
1139 cc::CompositorFrameMetadata metadata
= frame
->metadata
;
1141 SwapDelegatedFrame(output_surface_id
, frame
.Pass());
1142 frame_evictor_
->SwappedFrame(!host_
->is_hidden());
1144 // As the metadata update may trigger view invalidation, always call it after
1145 // any potential compositor scheduling.
1146 OnFrameMetadataUpdated(metadata
);
1149 void RenderWidgetHostViewAndroid::OnSwapCompositorFrame(
1150 uint32 output_surface_id
,
1151 scoped_ptr
<cc::CompositorFrame
> frame
) {
1152 InternalSwapCompositorFrame(output_surface_id
, frame
.Pass());
1155 void RenderWidgetHostViewAndroid::RetainFrame(
1156 uint32 output_surface_id
,
1157 scoped_ptr
<cc::CompositorFrame
> frame
) {
1158 DCHECK(locks_on_frame_count_
);
1160 // Store the incoming frame so that it can be swapped when all the locks have
1161 // been released. If there is already a stored frame, then replace and skip
1162 // the previous one but make sure we still eventually send the ACK. Holding
1163 // the ACK also blocks the renderer when its max_frames_pending is reached.
1164 if (last_frame_info_
) {
1165 base::Closure ack_callback
=
1166 base::Bind(&RenderWidgetHostViewAndroid::SendDelegatedFrameAck
,
1167 weak_ptr_factory_
.GetWeakPtr(),
1168 last_frame_info_
->output_surface_id
);
1170 ack_callbacks_
.push(ack_callback
);
1173 last_frame_info_
.reset(new LastFrameInfo(output_surface_id
, frame
.Pass()));
1176 void RenderWidgetHostViewAndroid::SynchronousFrameMetadata(
1177 const cc::CompositorFrameMetadata
& frame_metadata
) {
1178 if (!content_view_core_
)
1181 // This is a subset of OnSwapCompositorFrame() used in the synchronous
1183 OnFrameMetadataUpdated(frame_metadata
);
1185 // DevTools ScreenCast support for Android WebView.
1186 WebContents
* web_contents
= content_view_core_
->GetWebContents();
1187 if (DevToolsAgentHost::HasFor(web_contents
)) {
1188 scoped_refptr
<DevToolsAgentHost
> dtah
=
1189 DevToolsAgentHost::GetOrCreateFor(web_contents
);
1190 // Unblock the compositor.
1191 BrowserThread::PostTask(
1192 BrowserThread::UI
, FROM_HERE
,
1194 &RenderFrameDevToolsAgentHost::SynchronousSwapCompositorFrame
,
1195 static_cast<RenderFrameDevToolsAgentHost
*>(dtah
.get()),
1200 void RenderWidgetHostViewAndroid::SetOverlayVideoMode(bool enabled
) {
1202 layer_
->SetContentsOpaque(!enabled
);
1205 bool RenderWidgetHostViewAndroid::SupportsAnimation() const {
1206 // The synchronous (WebView) compositor does not have a proper browser
1207 // compositor with which to drive animations.
1208 return using_browser_compositor_
;
1211 void RenderWidgetHostViewAndroid::SetNeedsAnimate() {
1212 DCHECK(content_view_core_window_android_
);
1213 DCHECK(using_browser_compositor_
);
1214 content_view_core_window_android_
->SetNeedsAnimate();
1217 void RenderWidgetHostViewAndroid::MoveCaret(const gfx::PointF
& position
) {
1218 MoveCaret(gfx::Point(position
.x(), position
.y()));
1221 void RenderWidgetHostViewAndroid::MoveRangeSelectionExtent(
1222 const gfx::PointF
& extent
) {
1223 DCHECK(content_view_core_
);
1224 content_view_core_
->MoveRangeSelectionExtent(extent
);
1227 void RenderWidgetHostViewAndroid::SelectBetweenCoordinates(
1228 const gfx::PointF
& base
,
1229 const gfx::PointF
& extent
) {
1230 DCHECK(content_view_core_
);
1231 content_view_core_
->SelectBetweenCoordinates(base
, extent
);
1234 void RenderWidgetHostViewAndroid::OnSelectionEvent(
1235 ui::SelectionEventType event
) {
1236 DCHECK(content_view_core_
);
1237 DCHECK(selection_controller_
);
1238 // If a selection drag has started, it has taken over the active touch
1239 // sequence. Immediately cancel gesture detection and any downstream touch
1240 // listeners (e.g., web content) to communicate this transfer.
1241 if (event
== ui::SELECTION_HANDLES_SHOWN
)
1242 ResetGestureDetection();
1243 content_view_core_
->OnSelectionEvent(
1244 event
, selection_controller_
->GetStartPosition(),
1245 GetSelectionRect(*selection_controller_
));
1248 scoped_ptr
<ui::TouchHandleDrawable
>
1249 RenderWidgetHostViewAndroid::CreateDrawable() {
1250 DCHECK(content_view_core_
);
1251 if (!using_browser_compositor_
)
1252 return content_view_core_
->CreatePopupTouchHandleDrawable();
1254 return scoped_ptr
<ui::TouchHandleDrawable
>(new CompositedTouchHandleDrawable(
1255 content_view_core_
->GetLayer().get(),
1256 content_view_core_
->GetDpiScale(),
1257 // Use the activity context (instead of the application context) to ensure
1258 // proper handle theming.
1259 content_view_core_
->GetContext().obj()));
1262 void RenderWidgetHostViewAndroid::SynchronousCopyContents(
1263 const gfx::Rect
& src_subrect_in_pixel
,
1264 const gfx::Size
& dst_size_in_pixel
,
1265 ReadbackRequestCallback
& callback
,
1266 const SkColorType color_type
) {
1267 gfx::Size input_size_in_pixel
;
1268 if (src_subrect_in_pixel
.IsEmpty())
1269 input_size_in_pixel
= texture_size_in_layer_
;
1271 input_size_in_pixel
= src_subrect_in_pixel
.size();
1273 gfx::Size output_size_in_pixel
;
1274 if (dst_size_in_pixel
.IsEmpty())
1275 output_size_in_pixel
= input_size_in_pixel
;
1277 output_size_in_pixel
= dst_size_in_pixel
;
1278 int output_width
= output_size_in_pixel
.width();
1279 int output_height
= output_size_in_pixel
.height();
1281 SynchronousCompositor
* compositor
=
1282 SynchronousCompositorImpl::FromID(host_
->GetProcess()->GetID(),
1283 host_
->GetRoutingID());
1285 callback
.Run(SkBitmap(), READBACK_FAILED
);
1290 bitmap
.allocPixels(SkImageInfo::Make(output_width
,
1293 kPremul_SkAlphaType
));
1294 SkCanvas
canvas(bitmap
);
1296 (float)output_width
/ (float)input_size_in_pixel
.width(),
1297 (float)output_height
/ (float)input_size_in_pixel
.height());
1298 compositor
->DemandDrawSw(&canvas
);
1299 callback
.Run(bitmap
, READBACK_SUCCESS
);
1302 void RenderWidgetHostViewAndroid::OnFrameMetadataUpdated(
1303 const cc::CompositorFrameMetadata
& frame_metadata
) {
1304 bool is_mobile_optimized
= IsMobileOptimizedFrame(frame_metadata
);
1305 gesture_provider_
.SetDoubleTapSupportForPageEnabled(!is_mobile_optimized
);
1307 if (!content_view_core_
)
1310 if (overscroll_controller_
)
1311 overscroll_controller_
->OnFrameMetadataUpdated(frame_metadata
);
1313 if (selection_controller_
) {
1314 selection_controller_
->OnSelectionEditable(
1315 frame_metadata
.selection
.is_editable
);
1316 selection_controller_
->OnSelectionEmpty(
1317 frame_metadata
.selection
.is_empty_text_form_control
);
1318 selection_controller_
->OnSelectionBoundsChanged(
1319 ConvertSelectionBound(frame_metadata
.selection
.start
),
1320 ConvertSelectionBound(frame_metadata
.selection
.end
));
1323 // All offsets and sizes are in CSS pixels.
1324 content_view_core_
->UpdateFrameInfo(
1325 frame_metadata
.root_scroll_offset
,
1326 frame_metadata
.page_scale_factor
,
1327 gfx::Vector2dF(frame_metadata
.min_page_scale_factor
,
1328 frame_metadata
.max_page_scale_factor
),
1329 frame_metadata
.root_layer_size
,
1330 frame_metadata
.scrollable_viewport_size
,
1331 frame_metadata
.location_bar_offset
,
1332 frame_metadata
.location_bar_content_translation
,
1333 is_mobile_optimized
);
1334 #if defined(VIDEO_HOLE)
1335 if (host_
&& host_
->IsRenderView()) {
1336 RenderViewHostImpl
* rvhi
= static_cast<RenderViewHostImpl
*>(
1337 RenderViewHost::From(host_
));
1338 WebContentsImpl
* web_contents_impl
=
1339 static_cast<WebContentsImpl
*>(WebContents::FromRenderViewHost(rvhi
));
1340 if (web_contents_impl
)
1341 web_contents_impl
->media_web_contents_observer()->OnFrameInfoUpdated();
1343 #endif // defined(VIDEO_HOLE)
1346 void RenderWidgetHostViewAndroid::AcceleratedSurfaceInitialized(int route_id
) {
1347 // TODO: remove need for the surface id here
1348 accelerated_surface_route_id_
= route_id
;
1351 void RenderWidgetHostViewAndroid::ShowInternal() {
1352 DCHECK(is_showing_
);
1353 if (!host_
|| !host_
->is_hidden())
1357 layer_
->SetHideLayerAndSubtree(false);
1359 frame_evictor_
->SetVisible(true);
1361 if (overscroll_controller_
)
1362 overscroll_controller_
->Enable();
1364 host_
->WasShown(ui::LatencyInfo());
1366 if (content_view_core_
) {
1367 StartObservingRootWindow();
1368 RequestVSyncUpdate(BEGIN_FRAME
);
1372 void RenderWidgetHostViewAndroid::HideInternal(
1373 bool hide_frontbuffer
,
1374 bool stop_observing_root_window
) {
1375 if (hide_frontbuffer
) {
1376 if (layer_
.get() && locks_on_frame_count_
== 0)
1377 layer_
->SetHideLayerAndSubtree(true);
1379 frame_evictor_
->SetVisible(false);
1382 if (stop_observing_root_window
)
1383 StopObservingRootWindow();
1385 if (!host_
|| host_
->is_hidden())
1388 if (overscroll_controller_
)
1389 overscroll_controller_
->Disable();
1391 RunAckCallbacks(cc::SurfaceDrawStatus::DRAW_SKIPPED
);
1393 // Inform the renderer that we are being hidden so it can reduce its resource
1398 void RenderWidgetHostViewAndroid::AttachLayers() {
1399 if (!content_view_core_
)
1404 content_view_core_
->AttachLayer(layer_
);
1405 layer_
->SetHideLayerAndSubtree(!is_showing_
);
1408 void RenderWidgetHostViewAndroid::RemoveLayers() {
1409 if (!content_view_core_
)
1415 content_view_core_
->RemoveLayer(layer_
);
1418 void RenderWidgetHostViewAndroid::RequestVSyncUpdate(uint32 requests
) {
1419 bool should_request_vsync
= !outstanding_vsync_requests_
&& requests
;
1420 outstanding_vsync_requests_
|= requests
;
1422 // If the host has been hidden, defer vsync requests until it is shown
1423 // again via |Show()|.
1424 if (!host_
|| host_
->is_hidden())
1427 // Note that if we're not currently observing the root window, outstanding
1428 // vsync requests will be pushed if/when we resume observing in
1429 // |StartObservingRootWindow()|.
1430 if (observing_root_window_
&& should_request_vsync
)
1431 content_view_core_window_android_
->RequestVSyncUpdate();
1434 void RenderWidgetHostViewAndroid::StartObservingRootWindow() {
1435 DCHECK(content_view_core_window_android_
);
1436 DCHECK(is_showing_
);
1437 if (observing_root_window_
)
1440 observing_root_window_
= true;
1441 content_view_core_window_android_
->AddObserver(this);
1443 // Clear existing vsync requests to allow a request to the new window.
1444 uint32 outstanding_vsync_requests
= outstanding_vsync_requests_
;
1445 outstanding_vsync_requests_
= 0;
1446 RequestVSyncUpdate(outstanding_vsync_requests
);
1449 void RenderWidgetHostViewAndroid::StopObservingRootWindow() {
1450 if (!content_view_core_window_android_
) {
1451 DCHECK(!observing_root_window_
);
1455 if (!observing_root_window_
)
1458 observing_root_window_
= false;
1459 content_view_core_window_android_
->RemoveObserver(this);
1462 void RenderWidgetHostViewAndroid::SendBeginFrame(base::TimeTicks frame_time
,
1463 base::TimeDelta vsync_period
) {
1464 TRACE_EVENT1("cc", "RenderWidgetHostViewAndroid::SendBeginFrame",
1465 "frame_time_us", frame_time
.ToInternalValue());
1467 if (using_browser_compositor_
) {
1468 // TODO(brianderson): Replace this hardcoded deadline after Android
1469 // switches to Surfaces and the Browser's commit isn't in the critcal path.
1470 base::TimeTicks deadline
= frame_time
+ (vsync_period
* 0.6);
1472 host_
->Send(new ViewMsg_BeginFrame(
1473 host_
->GetRoutingID(),
1474 cc::BeginFrameArgs::Create(BEGINFRAME_FROM_HERE
, frame_time
, deadline
,
1475 vsync_period
, cc::BeginFrameArgs::NORMAL
)));
1477 SynchronousCompositorImpl
* compositor
= SynchronousCompositorImpl::FromID(
1478 host_
->GetProcess()->GetID(), host_
->GetRoutingID());
1480 // The synchronous compositor synchronously does it's work in this call.
1481 // It does not use a deadline.
1482 compositor
->BeginFrame(cc::BeginFrameArgs::Create(
1483 BEGINFRAME_FROM_HERE
, frame_time
, base::TimeTicks(), vsync_period
,
1484 cc::BeginFrameArgs::NORMAL
));
1489 bool RenderWidgetHostViewAndroid::Animate(base::TimeTicks frame_time
) {
1490 bool needs_animate
= false;
1491 if (overscroll_controller_
) {
1492 needs_animate
|= overscroll_controller_
->Animate(
1493 frame_time
, content_view_core_
->GetLayer().get());
1495 if (selection_controller_
)
1496 needs_animate
|= selection_controller_
->Animate(frame_time
);
1497 return needs_animate
;
1500 void RenderWidgetHostViewAndroid::RequestDisallowInterceptTouchEvent() {
1501 if (content_view_core_
)
1502 content_view_core_
->RequestDisallowInterceptTouchEvent();
1505 void RenderWidgetHostViewAndroid::EvictDelegatedFrame() {
1507 DestroyDelegatedContent();
1508 frame_evictor_
->DiscardedFrame();
1511 bool RenderWidgetHostViewAndroid::HasAcceleratedSurface(
1512 const gfx::Size
& desired_size
) {
1517 void RenderWidgetHostViewAndroid::GetScreenInfo(blink::WebScreenInfo
* result
) {
1518 // ScreenInfo isn't tied to the widget on Android. Always return the default.
1519 RenderWidgetHostViewBase::GetDefaultScreenInfo(result
);
1522 bool RenderWidgetHostViewAndroid::GetScreenColorProfile(
1523 std::vector
<char>* color_profile
) {
1524 DCHECK(color_profile
->empty());
1529 // TODO(jrg): Find out the implications and answer correctly here,
1530 // as we are returning the WebView and not root window bounds.
1531 gfx::Rect
RenderWidgetHostViewAndroid::GetBoundsInRootWindow() {
1532 return GetViewBounds();
1535 gfx::GLSurfaceHandle
RenderWidgetHostViewAndroid::GetCompositingSurface() {
1536 gfx::GLSurfaceHandle handle
=
1537 gfx::GLSurfaceHandle(gfx::kNullPluginWindow
, gfx::NULL_TRANSPORT
);
1538 // Null check for when we're running inside content_unittests.
1539 if (using_browser_compositor_
&& BrowserGpuChannelHostFactory::instance()) {
1540 handle
.parent_client_id
=
1541 BrowserGpuChannelHostFactory::instance()->GetGpuChannelId();
1546 void RenderWidgetHostViewAndroid::ProcessAckedTouchEvent(
1547 const TouchEventWithLatencyInfo
& touch
, InputEventAckState ack_result
) {
1548 const bool event_consumed
= ack_result
== INPUT_EVENT_ACK_STATE_CONSUMED
;
1549 gesture_provider_
.OnTouchEventAck(touch
.event
.uniqueTouchEventId
,
1553 void RenderWidgetHostViewAndroid::GestureEventAck(
1554 const blink::WebGestureEvent
& event
,
1555 InputEventAckState ack_result
) {
1556 if (overscroll_controller_
)
1557 overscroll_controller_
->OnGestureEventAck(event
, ack_result
);
1559 if (content_view_core_
)
1560 content_view_core_
->OnGestureEventAck(event
, ack_result
);
1563 InputEventAckState
RenderWidgetHostViewAndroid::FilterInputEvent(
1564 const blink::WebInputEvent
& input_event
) {
1565 if (selection_controller_
&&
1566 blink::WebInputEvent::isGestureEventType(input_event
.type
)) {
1567 const blink::WebGestureEvent
& gesture_event
=
1568 static_cast<const blink::WebGestureEvent
&>(input_event
);
1569 switch (gesture_event
.type
) {
1570 case blink::WebInputEvent::GestureLongPress
:
1571 if (selection_controller_
->WillHandleLongPressEvent(
1573 base::TimeDelta::FromSecondsD(input_event
.timeStampSeconds
),
1574 gfx::PointF(gesture_event
.x
, gesture_event
.y
))) {
1575 return INPUT_EVENT_ACK_STATE_CONSUMED
;
1579 case blink::WebInputEvent::GestureTap
:
1580 if (selection_controller_
->WillHandleTapEvent(
1581 gfx::PointF(gesture_event
.x
, gesture_event
.y
))) {
1582 return INPUT_EVENT_ACK_STATE_CONSUMED
;
1591 if (overscroll_controller_
&&
1592 blink::WebInputEvent::isGestureEventType(input_event
.type
) &&
1593 overscroll_controller_
->WillHandleGestureEvent(
1594 static_cast<const blink::WebGestureEvent
&>(input_event
))) {
1595 return INPUT_EVENT_ACK_STATE_CONSUMED
;
1598 if (content_view_core_
&& content_view_core_
->FilterInputEvent(input_event
))
1599 return INPUT_EVENT_ACK_STATE_CONSUMED
;
1602 return INPUT_EVENT_ACK_STATE_NOT_CONSUMED
;
1604 if (input_event
.type
== blink::WebInputEvent::GestureTapDown
||
1605 input_event
.type
== blink::WebInputEvent::TouchStart
) {
1606 GpuDataManagerImpl
* gpu_data
= GpuDataManagerImpl::GetInstance();
1607 GpuProcessHostUIShim
* shim
= GpuProcessHostUIShim::GetOneInstance();
1608 if (shim
&& gpu_data
&& accelerated_surface_route_id_
&&
1609 gpu_data
->IsDriverBugWorkaroundActive(gpu::WAKE_UP_GPU_BEFORE_DRAWING
))
1611 new AcceleratedSurfaceMsg_WakeUpGpu(accelerated_surface_route_id_
));
1614 SynchronousCompositorImpl
* compositor
=
1615 SynchronousCompositorImpl::FromID(host_
->GetProcess()->GetID(),
1616 host_
->GetRoutingID());
1618 return compositor
->HandleInputEvent(input_event
);
1619 return INPUT_EVENT_ACK_STATE_NOT_CONSUMED
;
1622 void RenderWidgetHostViewAndroid::OnSetNeedsFlushInput() {
1623 TRACE_EVENT0("input", "RenderWidgetHostViewAndroid::OnSetNeedsFlushInput");
1624 RequestVSyncUpdate(FLUSH_INPUT
);
1627 BrowserAccessibilityManager
*
1628 RenderWidgetHostViewAndroid::CreateBrowserAccessibilityManager(
1629 BrowserAccessibilityDelegate
* delegate
) {
1630 // TODO(dmazzoni): Currently there can only be one
1631 // BrowserAccessibilityManager per ContentViewCore, so return NULL
1632 // if there's already a BrowserAccessibilityManager for the main
1633 // frame. Eventually, in order to support cross-process iframes on
1634 // Android we'll need to add support for a
1635 // BrowserAccessibilityManager for a child frame.
1636 // http://crbug.com/423846
1637 if (!host_
|| host_
->GetRootBrowserAccessibilityManager())
1640 base::android::ScopedJavaLocalRef
<jobject
> obj
;
1641 if (content_view_core_
)
1642 obj
= content_view_core_
->GetJavaObject();
1643 return new BrowserAccessibilityManagerAndroid(
1645 BrowserAccessibilityManagerAndroid::GetEmptyDocument(),
1649 bool RenderWidgetHostViewAndroid::LockMouse() {
1654 void RenderWidgetHostViewAndroid::UnlockMouse() {
1658 // Methods called from the host to the render
1660 void RenderWidgetHostViewAndroid::SendKeyEvent(
1661 const NativeWebKeyboardEvent
& event
) {
1663 host_
->ForwardKeyboardEvent(event
);
1666 void RenderWidgetHostViewAndroid::SendMouseEvent(
1667 const blink::WebMouseEvent
& event
) {
1669 host_
->ForwardMouseEvent(event
);
1672 void RenderWidgetHostViewAndroid::SendMouseWheelEvent(
1673 const blink::WebMouseWheelEvent
& event
) {
1675 host_
->ForwardWheelEvent(event
);
1678 void RenderWidgetHostViewAndroid::SendGestureEvent(
1679 const blink::WebGestureEvent
& event
) {
1680 // Sending a gesture that may trigger overscroll should resume the effect.
1681 if (overscroll_controller_
)
1682 overscroll_controller_
->Enable();
1685 host_
->ForwardGestureEventWithLatencyInfo(event
, ui::LatencyInfo());
1688 void RenderWidgetHostViewAndroid::MoveCaret(const gfx::Point
& point
) {
1690 host_
->MoveCaret(point
);
1693 void RenderWidgetHostViewAndroid::DismissTextHandles() {
1694 if (selection_controller_
)
1695 selection_controller_
->HideAndDisallowShowingAutomatically();
1698 void RenderWidgetHostViewAndroid::SetTextHandlesTemporarilyHidden(bool hidden
) {
1699 if (selection_controller_
)
1700 selection_controller_
->SetTemporarilyHidden(hidden
);
1703 void RenderWidgetHostViewAndroid::OnShowingPastePopup(
1704 const gfx::PointF
& point
) {
1705 if (!selection_controller_
)
1708 // As the paste popup may be triggered *before* the bounds and editability
1709 // of the region have been updated, explicitly set the properties now.
1710 // TODO(jdduke): Remove this workaround when auxiliary paste popup
1711 // notifications are no longer required, crbug.com/398170.
1712 ui::SelectionBound insertion_bound
;
1713 insertion_bound
.set_type(ui::SelectionBound::CENTER
);
1714 insertion_bound
.set_visible(true);
1715 insertion_bound
.SetEdge(point
, point
);
1716 selection_controller_
->HideAndDisallowShowingAutomatically();
1717 selection_controller_
->OnSelectionEditable(true);
1718 selection_controller_
->OnSelectionEmpty(true);
1719 selection_controller_
->OnSelectionBoundsChanged(insertion_bound
,
1721 selection_controller_
->AllowShowingFromCurrentSelection();
1724 SkColor
RenderWidgetHostViewAndroid::GetCachedBackgroundColor() const {
1725 return cached_background_color_
;
1728 void RenderWidgetHostViewAndroid::DidOverscroll(
1729 const DidOverscrollParams
& params
) {
1730 if (!content_view_core_
|| !layer_
.get() || !is_showing_
)
1733 if (overscroll_controller_
)
1734 overscroll_controller_
->OnOverscrolled(params
);
1737 void RenderWidgetHostViewAndroid::DidStopFlinging() {
1738 if (content_view_core_
)
1739 content_view_core_
->DidStopFlinging();
1742 uint32_t RenderWidgetHostViewAndroid::GetSurfaceIdNamespace() {
1744 return id_allocator_
->id_namespace();
1748 void RenderWidgetHostViewAndroid::SetContentViewCore(
1749 ContentViewCoreImpl
* content_view_core
) {
1751 StopObservingRootWindow();
1753 bool resize
= false;
1754 if (content_view_core
!= content_view_core_
) {
1755 overscroll_controller_
.reset();
1756 selection_controller_
.reset();
1757 ReleaseLocksOnSurface();
1761 content_view_core_
= content_view_core
;
1762 content_view_core_window_android_
=
1763 content_view_core_
? content_view_core_
->GetWindowAndroid() : nullptr;
1764 DCHECK_EQ(!!content_view_core_
, !!content_view_core_window_android_
);
1766 BrowserAccessibilityManager
* manager
= NULL
;
1768 manager
= host_
->GetRootBrowserAccessibilityManager();
1770 base::android::ScopedJavaLocalRef
<jobject
> obj
;
1771 if (content_view_core_
)
1772 obj
= content_view_core_
->GetJavaObject();
1773 manager
->ToBrowserAccessibilityManagerAndroid()->SetContentViewCore(obj
);
1778 if (!content_view_core_
)
1782 StartObservingRootWindow();
1787 if (!selection_controller_
)
1788 selection_controller_
= CreateSelectionController(this, content_view_core_
);
1790 if (!overscroll_controller_
&&
1791 content_view_core_window_android_
->GetCompositor()) {
1792 overscroll_controller_
= CreateOverscrollController(content_view_core_
);
1796 void RenderWidgetHostViewAndroid::RunAckCallbacks(
1797 cc::SurfaceDrawStatus status
) {
1798 while (!ack_callbacks_
.empty()) {
1799 ack_callbacks_
.front().Run();
1800 ack_callbacks_
.pop();
1804 void RenderWidgetHostViewAndroid::OnGestureEvent(
1805 const ui::GestureEventData
& gesture
) {
1806 blink::WebGestureEvent web_gesture
=
1807 ui::CreateWebGestureEventFromGestureEventData(gesture
);
1808 // TODO(jdduke): Remove this workaround after Android fixes UiAutomator to
1809 // stop providing shift meta values to synthetic MotionEvents. This prevents
1810 // unintended shift+click interpretation of all accessibility clicks.
1811 // See crbug.com/443247.
1812 if (web_gesture
.type
== blink::WebInputEvent::GestureTap
&&
1813 web_gesture
.modifiers
== blink::WebInputEvent::ShiftKey
) {
1814 web_gesture
.modifiers
= 0;
1816 SendGestureEvent(web_gesture
);
1819 void RenderWidgetHostViewAndroid::OnCompositingDidCommit() {
1820 RunAckCallbacks(cc::SurfaceDrawStatus::DRAWN
);
1823 void RenderWidgetHostViewAndroid::OnRootWindowVisibilityChanged(bool visible
) {
1824 DCHECK(is_showing_
);
1828 bool hide_frontbuffer
= true;
1829 bool stop_observing_root_window
= false;
1830 HideInternal(hide_frontbuffer
, stop_observing_root_window
);
1834 void RenderWidgetHostViewAndroid::OnAttachCompositor() {
1835 DCHECK(content_view_core_
);
1836 if (!overscroll_controller_
)
1837 overscroll_controller_
= CreateOverscrollController(content_view_core_
);
1840 void RenderWidgetHostViewAndroid::OnDetachCompositor() {
1841 DCHECK(content_view_core_
);
1842 DCHECK(using_browser_compositor_
);
1843 RunAckCallbacks(cc::SurfaceDrawStatus::DRAW_SKIPPED
);
1844 overscroll_controller_
.reset();
1847 void RenderWidgetHostViewAndroid::OnVSync(base::TimeTicks frame_time
,
1848 base::TimeDelta vsync_period
) {
1849 TRACE_EVENT0("cc,benchmark", "RenderWidgetHostViewAndroid::OnVSync");
1850 if (!host_
|| host_
->is_hidden())
1853 if (outstanding_vsync_requests_
& FLUSH_INPUT
) {
1854 outstanding_vsync_requests_
&= ~FLUSH_INPUT
;
1855 host_
->FlushInput();
1858 if (outstanding_vsync_requests_
& BEGIN_FRAME
||
1859 outstanding_vsync_requests_
& PERSISTENT_BEGIN_FRAME
) {
1860 outstanding_vsync_requests_
&= ~BEGIN_FRAME
;
1861 SendBeginFrame(frame_time
, vsync_period
);
1864 // This allows for SendBeginFrame and FlushInput to modify
1865 // outstanding_vsync_requests.
1866 uint32 outstanding_vsync_requests
= outstanding_vsync_requests_
;
1867 outstanding_vsync_requests_
= 0;
1868 RequestVSyncUpdate(outstanding_vsync_requests
);
1871 void RenderWidgetHostViewAndroid::OnAnimate(base::TimeTicks begin_frame_time
) {
1872 if (Animate(begin_frame_time
))
1876 void RenderWidgetHostViewAndroid::OnActivityStopped() {
1877 TRACE_EVENT0("browser", "RenderWidgetHostViewAndroid::OnActivityStopped");
1878 DCHECK(is_showing_
);
1879 bool hide_frontbuffer
= false;
1880 bool stop_observing_root_window
= false;
1881 HideInternal(hide_frontbuffer
, stop_observing_root_window
);
1884 void RenderWidgetHostViewAndroid::OnActivityStarted() {
1885 TRACE_EVENT0("browser", "RenderWidgetHostViewAndroid::OnActivityStarted");
1886 DCHECK(is_showing_
);
1890 void RenderWidgetHostViewAndroid::OnLostResources() {
1891 ReleaseLocksOnSurface();
1893 DestroyDelegatedContent();
1894 DCHECK(ack_callbacks_
.empty());
1898 void RenderWidgetHostViewAndroid::
1899 PrepareTextureCopyOutputResultForDelegatedReadback(
1900 const gfx::Size
& dst_size_in_pixel
,
1901 SkColorType color_type
,
1902 const base::TimeTicks
& start_time
,
1903 scoped_refptr
<cc::Layer
> readback_layer
,
1904 ReadbackRequestCallback
& callback
,
1905 scoped_ptr
<cc::CopyOutputResult
> result
) {
1906 readback_layer
->RemoveFromParent();
1907 PrepareTextureCopyOutputResult(
1908 dst_size_in_pixel
, color_type
, start_time
, callback
, result
.Pass());
1912 void RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResult(
1913 const gfx::Size
& dst_size_in_pixel
,
1914 SkColorType color_type
,
1915 const base::TimeTicks
& start_time
,
1916 ReadbackRequestCallback
& callback
,
1917 scoped_ptr
<cc::CopyOutputResult
> result
) {
1918 base::ScopedClosureRunner
scoped_callback_runner(
1919 base::Bind(callback
, SkBitmap(), READBACK_FAILED
));
1921 "RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResult");
1923 if (!result
->HasTexture() || result
->IsEmpty() || result
->size().IsEmpty())
1926 gfx::Size output_size_in_pixel
;
1927 if (dst_size_in_pixel
.IsEmpty())
1928 output_size_in_pixel
= result
->size();
1930 output_size_in_pixel
= dst_size_in_pixel
;
1932 GLHelper
* gl_helper
= GetPostReadbackGLHelper();
1935 if (!gl_helper
->IsReadbackConfigSupported(color_type
))
1936 color_type
= kRGBA_8888_SkColorType
;
1937 scoped_ptr
<SkBitmap
> bitmap(new SkBitmap
);
1938 if (!bitmap
->tryAllocPixels(SkImageInfo::Make(output_size_in_pixel
.width(),
1939 output_size_in_pixel
.height(),
1941 kOpaque_SkAlphaType
))) {
1942 scoped_callback_runner
.Reset(
1943 base::Bind(callback
, SkBitmap(), READBACK_BITMAP_ALLOCATION_FAILURE
));
1948 scoped_ptr
<SkAutoLockPixels
> bitmap_pixels_lock(
1949 new SkAutoLockPixels(*bitmap
));
1950 uint8
* pixels
= static_cast<uint8
*>(bitmap
->getPixels());
1952 cc::TextureMailbox texture_mailbox
;
1953 scoped_ptr
<cc::SingleReleaseCallback
> release_callback
;
1954 result
->TakeTexture(&texture_mailbox
, &release_callback
);
1955 DCHECK(texture_mailbox
.IsTexture());
1956 if (!texture_mailbox
.IsTexture())
1959 ignore_result(scoped_callback_runner
.Release());
1961 gl_helper
->CropScaleReadbackAndCleanMailbox(
1962 texture_mailbox
.mailbox(),
1963 texture_mailbox
.sync_point(),
1965 gfx::Rect(result
->size()),
1966 output_size_in_pixel
,
1969 base::Bind(&CopyFromCompositingSurfaceFinished
,
1971 base::Passed(&release_callback
),
1972 base::Passed(&bitmap
),
1974 base::Passed(&bitmap_pixels_lock
)),
1975 GLHelper::SCALER_QUALITY_GOOD
);
1978 void RenderWidgetHostViewAndroid::OnStylusSelectBegin(float x0
,
1982 SelectBetweenCoordinates(gfx::PointF(x0
, y0
), gfx::PointF(x1
, y1
));
1985 void RenderWidgetHostViewAndroid::OnStylusSelectUpdate(float x
, float y
) {
1986 MoveRangeSelectionExtent(gfx::PointF(x
, y
));
1989 void RenderWidgetHostViewAndroid::OnStylusSelectEnd() {
1990 if (selection_controller_
)
1991 selection_controller_
->AllowShowingFromCurrentSelection();
1994 void RenderWidgetHostViewAndroid::OnStylusSelectTap(base::TimeTicks time
,
1997 // Treat the stylus tap as a long press, activating either a word selection or
1998 // context menu depending on the targetted content.
1999 blink::WebGestureEvent long_press
= WebGestureEventBuilder::Build(
2000 blink::WebInputEvent::GestureLongPress
,
2001 (time
- base::TimeTicks()).InSecondsF(), x
, y
);
2002 SendGestureEvent(long_press
);
2006 void RenderWidgetHostViewBase::GetDefaultScreenInfo(
2007 blink::WebScreenInfo
* results
) {
2008 const gfx::Display
& display
=
2009 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
2010 results
->rect
= display
.bounds();
2011 // TODO(husky): Remove any system controls from availableRect.
2012 results
->availableRect
= display
.work_area();
2013 results
->deviceScaleFactor
= display
.device_scale_factor();
2014 results
->orientationAngle
= display
.RotationAsDegree();
2015 results
->orientationType
=
2016 RenderWidgetHostViewBase::GetOrientationTypeForMobile(display
);
2017 gfx::DeviceDisplayInfo info
;
2018 results
->depth
= info
.GetBitsPerPixel();
2019 results
->depthPerComponent
= info
.GetBitsPerComponent();
2020 results
->isMonochrome
= (results
->depthPerComponent
== 0);
2023 } // namespace content