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/web_input_event_builders_android.h"
55 #include "content/browser/renderer_host/input/web_input_event_util.h"
56 #include "content/browser/renderer_host/render_process_host_impl.h"
57 #include "content/browser/renderer_host/render_view_host_impl.h"
58 #include "content/browser/renderer_host/render_widget_host_impl.h"
59 #include "content/common/gpu/client/gl_helper.h"
60 #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
61 #include "content/common/gpu/gpu_messages.h"
62 #include "content/common/gpu/gpu_process_launch_causes.h"
63 #include "content/common/input/did_overscroll_params.h"
64 #include "content/common/input_messages.h"
65 #include "content/common/view_messages.h"
66 #include "content/public/browser/browser_thread.h"
67 #include "content/public/browser/devtools_agent_host.h"
68 #include "content/public/browser/render_view_host.h"
69 #include "content/public/browser/render_widget_host_iterator.h"
70 #include "content/public/common/content_switches.h"
71 #include "gpu/command_buffer/client/gles2_implementation.h"
72 #include "gpu/command_buffer/client/gles2_interface.h"
73 #include "gpu/config/gpu_driver_bug_workaround_type.h"
74 #include "skia/ext/image_operations.h"
75 #include "third_party/khronos/GLES2/gl2.h"
76 #include "third_party/khronos/GLES2/gl2ext.h"
77 #include "third_party/skia/include/core/SkCanvas.h"
78 #include "ui/android/window_android.h"
79 #include "ui/android/window_android_compositor.h"
80 #include "ui/events/blink/blink_event_util.h"
81 #include "ui/events/gesture_detection/gesture_provider_config_helper.h"
82 #include "ui/events/gesture_detection/motion_event.h"
83 #include "ui/gfx/android/device_display_info.h"
84 #include "ui/gfx/android/java_bitmap.h"
85 #include "ui/gfx/android/view_configuration.h"
86 #include "ui/gfx/display.h"
87 #include "ui/gfx/geometry/dip_util.h"
88 #include "ui/gfx/geometry/size_conversions.h"
89 #include "ui/gfx/screen.h"
90 #include "ui/touch_selection/touch_selection_controller.h"
96 void SatisfyCallback(cc::SurfaceManager
* manager
,
97 cc::SurfaceSequence sequence
) {
98 std::vector
<uint32_t> sequences
;
99 sequences
.push_back(sequence
.sequence
);
100 manager
->DidSatisfySequences(sequence
.id_namespace
, &sequences
);
103 void RequireCallback(cc::SurfaceManager
* manager
,
105 cc::SurfaceSequence sequence
) {
106 cc::Surface
* surface
= manager
->GetSurfaceForId(id
);
108 LOG(ERROR
) << "Attempting to require callback on nonexistent surface";
111 surface
->AddDestructionDependency(sequence
);
114 const int kUndefinedOutputSurfaceId
= -1;
116 static const char kAsyncReadBackString
[] = "Compositing.CopyFromSurfaceTime";
118 // Sends an acknowledgement to the renderer of a processed IME event.
119 void SendImeEventAck(RenderWidgetHostImpl
* host
) {
120 host
->Send(new ViewMsg_ImeEventAck(host
->GetRoutingID()));
124 : public blink::WebGraphicsContext3D::WebGraphicsContextLostCallback
{
126 static GLHelperHolder
* Create();
127 ~GLHelperHolder() override
;
131 // WebGraphicsContextLostCallback implementation.
132 virtual void onContextLost() override
;
134 GLHelper
* GetGLHelper() { return gl_helper_
.get(); }
135 bool IsLost() { return !context_
.get() || context_
->isContextLost(); }
139 static scoped_ptr
<WebGraphicsContext3DCommandBufferImpl
> CreateContext3D();
141 scoped_ptr
<WebGraphicsContext3DCommandBufferImpl
> context_
;
142 scoped_ptr
<GLHelper
> gl_helper_
;
144 DISALLOW_COPY_AND_ASSIGN(GLHelperHolder
);
147 GLHelperHolder
* GLHelperHolder::Create() {
148 GLHelperHolder
* holder
= new GLHelperHolder
;
149 holder
->Initialize();
154 GLHelperHolder::GLHelperHolder() {
157 GLHelperHolder::~GLHelperHolder() {
160 void GLHelperHolder::Initialize() {
161 context_
= CreateContext3D();
163 context_
->setContextLostCallback(this);
164 gl_helper_
.reset(new GLHelper(context_
->GetImplementation(),
165 context_
->GetContextSupport()));
169 void GLHelperHolder::onContextLost() {
170 // Need to post a task because the command buffer client cannot be deleted
171 // from within this callback.
172 LOG(ERROR
) << "Context lost.";
173 base::MessageLoop::current()->PostTask(
175 base::Bind(&RenderWidgetHostViewAndroid::OnContextLost
));
178 scoped_ptr
<WebGraphicsContext3DCommandBufferImpl
>
179 GLHelperHolder::CreateContext3D() {
180 BrowserGpuChannelHostFactory
* factory
=
181 BrowserGpuChannelHostFactory::instance();
182 scoped_refptr
<GpuChannelHost
> gpu_channel_host(factory
->GetGpuChannel());
183 // GLHelper can only be used in asynchronous APIs for postprocessing after
184 // Browser Compositor operations (i.e. readback).
185 if (!gpu_channel_host
.get()) {
186 // The Browser Compositor is in charge of reestablishing the channel.
187 return scoped_ptr
<WebGraphicsContext3DCommandBufferImpl
>();
190 blink::WebGraphicsContext3D::Attributes attrs
;
191 attrs
.shareResources
= true;
192 GURL
url("chrome://gpu/RenderWidgetHostViewAndroid");
193 static const size_t kBytesPerPixel
= 4;
194 gfx::DeviceDisplayInfo display_info
;
195 size_t full_screen_texture_size_in_bytes
= display_info
.GetDisplayHeight() *
196 display_info
.GetDisplayWidth() *
198 WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits limits
;
199 limits
.command_buffer_size
= 64 * 1024;
200 limits
.start_transfer_buffer_size
= 64 * 1024;
201 limits
.min_transfer_buffer_size
= 64 * 1024;
202 limits
.max_transfer_buffer_size
= std::min(
203 3 * full_screen_texture_size_in_bytes
, kDefaultMaxTransferBufferSize
);
204 limits
.mapped_memory_reclaim_limit
=
205 WebGraphicsContext3DCommandBufferImpl::kNoLimit
;
206 bool lose_context_when_out_of_memory
= false;
207 scoped_ptr
<WebGraphicsContext3DCommandBufferImpl
> context(
208 new WebGraphicsContext3DCommandBufferImpl(
210 url
, gpu_channel_host
.get(), attrs
, lose_context_when_out_of_memory
,
212 if (context
->InitializeOnCurrentThread()) {
213 context
->traceBeginCHROMIUM(
215 base::StringPrintf("CmdBufferImageTransportFactory-%p",
216 context
.get()).c_str());
221 return context
.Pass();
224 // This can only be used for readback postprocessing. It may return null if the
225 // channel was lost and not reestablished yet.
226 GLHelper
* GetPostReadbackGLHelper() {
227 static GLHelperHolder
* g_readback_helper_holder
= nullptr;
229 if (g_readback_helper_holder
&& g_readback_helper_holder
->IsLost()) {
230 delete g_readback_helper_holder
;
231 g_readback_helper_holder
= nullptr;
234 if (!g_readback_helper_holder
)
235 g_readback_helper_holder
= GLHelperHolder::Create();
237 return g_readback_helper_holder
->GetGLHelper();
240 void CopyFromCompositingSurfaceFinished(
241 ReadbackRequestCallback
& callback
,
242 scoped_ptr
<cc::SingleReleaseCallback
> release_callback
,
243 scoped_ptr
<SkBitmap
> bitmap
,
244 const base::TimeTicks
& start_time
,
245 scoped_ptr
<SkAutoLockPixels
> bitmap_pixels_lock
,
248 "cc", "RenderWidgetHostViewAndroid::CopyFromCompositingSurfaceFinished");
249 bitmap_pixels_lock
.reset();
250 uint32 sync_point
= 0;
252 GLHelper
* gl_helper
= GetPostReadbackGLHelper();
254 sync_point
= gl_helper
->InsertSyncPoint();
256 bool lost_resource
= sync_point
== 0;
257 release_callback
->Run(sync_point
, lost_resource
);
258 UMA_HISTOGRAM_TIMES(kAsyncReadBackString
,
259 base::TimeTicks::Now() - start_time
);
260 ReadbackResponse response
= result
? READBACK_SUCCESS
: READBACK_FAILED
;
261 callback
.Run(*bitmap
, response
);
264 ui::LatencyInfo
CreateLatencyInfo(const blink::WebInputEvent
& event
) {
265 ui::LatencyInfo latency_info
;
266 // The latency number should only be added if the timestamp is valid.
267 if (event
.timeStampSeconds
) {
268 const int64 time_micros
= static_cast<int64
>(
269 event
.timeStampSeconds
* base::Time::kMicrosecondsPerSecond
);
270 latency_info
.AddLatencyNumberWithTimestamp(
271 ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT
,
274 base::TimeTicks() + base::TimeDelta::FromMicroseconds(time_micros
),
280 scoped_ptr
<ui::TouchSelectionController
> CreateSelectionController(
281 ui::TouchSelectionControllerClient
* client
,
282 ContentViewCore
* content_view_core
) {
284 DCHECK(content_view_core
);
285 int tap_timeout_ms
= gfx::ViewConfiguration::GetTapTimeoutInMs();
286 int touch_slop_pixels
= gfx::ViewConfiguration::GetTouchSlopInPixels();
287 bool show_on_tap_for_empty_editable
= false;
288 return make_scoped_ptr(new ui::TouchSelectionController(
290 base::TimeDelta::FromMilliseconds(tap_timeout_ms
),
291 touch_slop_pixels
/ content_view_core
->GetDpiScale(),
292 show_on_tap_for_empty_editable
));
295 scoped_ptr
<OverscrollControllerAndroid
> CreateOverscrollController(
296 ContentViewCore
* content_view_core
) {
297 DCHECK(content_view_core
);
298 ui::WindowAndroid
* window
= content_view_core
->GetWindowAndroid();
300 ui::WindowAndroidCompositor
* compositor
= window
->GetCompositor();
302 return make_scoped_ptr(new OverscrollControllerAndroid(
303 content_view_core
->GetWebContents(),
305 content_view_core
->GetDpiScale()));
308 ui::GestureProvider::Config
CreateGestureProviderConfig() {
309 ui::GestureProvider::Config config
= ui::GetGestureProviderConfig(
310 ui::GestureProviderConfigType::CURRENT_PLATFORM
);
311 config
.disable_click_delay
=
312 base::CommandLine::ForCurrentProcess()->HasSwitch(
313 switches::kDisableClickDelay
);
317 ui::SelectionBound::Type
ConvertSelectionBoundType(
318 cc::SelectionBoundType type
) {
320 case cc::SELECTION_BOUND_LEFT
:
321 return ui::SelectionBound::LEFT
;
322 case cc::SELECTION_BOUND_RIGHT
:
323 return ui::SelectionBound::RIGHT
;
324 case cc::SELECTION_BOUND_CENTER
:
325 return ui::SelectionBound::CENTER
;
326 case cc::SELECTION_BOUND_EMPTY
:
327 return ui::SelectionBound::EMPTY
;
329 NOTREACHED() << "Unknown selection bound type";
330 return ui::SelectionBound::EMPTY
;
333 ui::SelectionBound
ConvertSelectionBound(
334 const cc::ViewportSelectionBound
& bound
) {
335 ui::SelectionBound ui_bound
;
336 ui_bound
.set_type(ConvertSelectionBoundType(bound
.type
));
337 ui_bound
.set_visible(bound
.visible
);
338 if (ui_bound
.type() != ui::SelectionBound::EMPTY
)
339 ui_bound
.SetEdge(bound
.edge_top
, bound
.edge_bottom
);
343 } // anonymous namespace
345 ReadbackRequest::ReadbackRequest(float scale
,
346 SkColorType color_type
,
347 gfx::Rect src_subrect
,
348 ReadbackRequestCallback
& result_callback
)
350 color_type_(color_type
),
351 src_subrect_(src_subrect
),
352 result_callback_(result_callback
) {
355 ReadbackRequest::ReadbackRequest() {
358 ReadbackRequest::~ReadbackRequest() {
361 RenderWidgetHostViewAndroid::LastFrameInfo::LastFrameInfo(
363 scoped_ptr
<cc::CompositorFrame
> output_frame
)
364 : output_surface_id(output_id
), frame(output_frame
.Pass()) {}
366 RenderWidgetHostViewAndroid::LastFrameInfo::~LastFrameInfo() {}
368 void RenderWidgetHostViewAndroid::OnContextLost() {
369 scoped_ptr
<RenderWidgetHostIterator
> widgets(
370 RenderWidgetHostImpl::GetAllRenderWidgetHosts());
371 while (RenderWidgetHost
* widget
= widgets
->GetNextHost()) {
372 if (widget
->GetView()) {
373 static_cast<RenderWidgetHostViewAndroid
*>(widget
->GetView())
379 RenderWidgetHostViewAndroid::RenderWidgetHostViewAndroid(
380 RenderWidgetHostImpl
* widget_host
,
381 ContentViewCoreImpl
* content_view_core
)
382 : host_(widget_host
),
383 outstanding_vsync_requests_(0),
384 is_showing_(!widget_host
->is_hidden()),
385 content_view_core_(NULL
),
386 ime_adapter_android_(this),
387 cached_background_color_(SK_ColorWHITE
),
388 last_output_surface_id_(kUndefinedOutputSurfaceId
),
389 gesture_provider_(CreateGestureProviderConfig(), this),
390 stylus_text_selector_(this),
391 accelerated_surface_route_id_(0),
392 using_browser_compositor_(CompositorImpl::IsInitialized()),
393 frame_evictor_(new DelegatedFrameEvictor(this)),
394 locks_on_frame_count_(0),
395 observing_root_window_(false),
396 weak_ptr_factory_(this) {
397 host_
->SetView(this);
398 SetContentViewCore(content_view_core
);
401 RenderWidgetHostViewAndroid::~RenderWidgetHostViewAndroid() {
402 SetContentViewCore(NULL
);
403 DCHECK(ack_callbacks_
.empty());
404 DCHECK(readbacks_waiting_for_frame_
.empty());
405 if (resource_collection_
.get())
406 resource_collection_
->SetClient(NULL
);
407 DCHECK(!surface_factory_
);
408 DCHECK(surface_id_
.is_null());
412 bool RenderWidgetHostViewAndroid::OnMessageReceived(
413 const IPC::Message
& message
) {
415 IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewAndroid
, message
)
416 IPC_MESSAGE_HANDLER(ViewHostMsg_StartContentIntent
, OnStartContentIntent
)
417 IPC_MESSAGE_HANDLER(ViewHostMsg_DidChangeBodyBackgroundColor
,
418 OnDidChangeBodyBackgroundColor
)
419 IPC_MESSAGE_HANDLER(ViewHostMsg_SetNeedsBeginFrames
,
420 OnSetNeedsBeginFrames
)
421 IPC_MESSAGE_HANDLER(ViewHostMsg_TextInputStateChanged
,
422 OnTextInputStateChanged
)
423 IPC_MESSAGE_HANDLER(ViewHostMsg_SmartClipDataExtracted
,
424 OnSmartClipDataExtracted
)
425 IPC_MESSAGE_HANDLER(ViewHostMsg_ShowUnhandledTapUIIfNeeded
,
426 OnShowUnhandledTapUIIfNeeded
)
427 IPC_MESSAGE_UNHANDLED(handled
= false)
428 IPC_END_MESSAGE_MAP()
432 void RenderWidgetHostViewAndroid::InitAsChild(gfx::NativeView parent_view
) {
436 void RenderWidgetHostViewAndroid::InitAsPopup(
437 RenderWidgetHostView
* parent_host_view
, const gfx::Rect
& pos
) {
441 void RenderWidgetHostViewAndroid::InitAsFullscreen(
442 RenderWidgetHostView
* reference_host_view
) {
447 RenderWidgetHostViewAndroid::GetRenderWidgetHost() const {
451 void RenderWidgetHostViewAndroid::WasResized() {
455 void RenderWidgetHostViewAndroid::SetSize(const gfx::Size
& size
) {
456 // Ignore the given size as only the Java code has the power to
457 // resize the view on Android.
458 default_size_
= size
;
461 void RenderWidgetHostViewAndroid::SetBounds(const gfx::Rect
& rect
) {
462 SetSize(rect
.size());
465 void RenderWidgetHostViewAndroid::AbortPendingReadbackRequests() {
466 while (!readbacks_waiting_for_frame_
.empty()) {
467 ReadbackRequest
& readback_request
= readbacks_waiting_for_frame_
.front();
468 readback_request
.GetResultCallback().Run(SkBitmap(), READBACK_FAILED
);
469 readbacks_waiting_for_frame_
.pop();
473 void RenderWidgetHostViewAndroid::GetScaledContentBitmap(
475 SkColorType color_type
,
476 gfx::Rect src_subrect
,
477 ReadbackRequestCallback
& result_callback
) {
478 if (!host_
|| host_
->is_hidden()) {
479 result_callback
.Run(SkBitmap(), READBACK_NOT_SUPPORTED
);
482 if (!IsSurfaceAvailableForCopy()) {
483 // The view is visible, probably the frame has not yet arrived.
484 // Just add the ReadbackRequest to queue and wait for frame arrival
485 // to get this request processed.
486 readbacks_waiting_for_frame_
.push(
487 ReadbackRequest(scale
, color_type
, src_subrect
, result_callback
));
491 gfx::Size bounds
= layer_
->bounds();
492 if (src_subrect
.IsEmpty())
493 src_subrect
= gfx::Rect(bounds
);
494 DCHECK_LE(src_subrect
.width() + src_subrect
.x(), bounds
.width());
495 DCHECK_LE(src_subrect
.height() + src_subrect
.y(), bounds
.height());
496 const gfx::Display
& display
=
497 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
498 float device_scale_factor
= display
.device_scale_factor();
499 DCHECK_GT(device_scale_factor
, 0);
501 gfx::ToCeiledSize(gfx::ScaleSize(bounds
, scale
/ device_scale_factor
)));
502 CopyFromCompositingSurface(
503 src_subrect
, dst_size
, result_callback
, color_type
);
506 scoped_refptr
<cc::Layer
> RenderWidgetHostViewAndroid::CreateDelegatedLayer()
508 scoped_refptr
<cc::Layer
> delegated_layer
;
509 if (!surface_id_
.is_null()) {
510 cc::SurfaceManager
* manager
= CompositorImpl::GetSurfaceManager();
512 // manager must outlive compositors using it.
513 scoped_refptr
<cc::SurfaceLayer
> surface_layer
= cc::SurfaceLayer::Create(
514 base::Bind(&SatisfyCallback
, base::Unretained(manager
)),
515 base::Bind(&RequireCallback
, base::Unretained(manager
)));
516 surface_layer
->SetSurfaceId(surface_id_
, 1.f
, texture_size_in_layer_
);
517 delegated_layer
= surface_layer
;
519 DCHECK(frame_provider_
.get());
520 delegated_layer
= cc::DelegatedRendererLayer::Create(frame_provider_
);
522 delegated_layer
->SetBounds(content_size_in_layer_
);
523 delegated_layer
->SetIsDrawable(true);
524 delegated_layer
->SetContentsOpaque(true);
526 return delegated_layer
;
529 bool RenderWidgetHostViewAndroid::HasValidFrame() const {
530 if (!content_view_core_
)
535 if (texture_size_in_layer_
.IsEmpty())
537 // This tell us whether a valid frame has arrived or not.
538 if (!frame_evictor_
->HasFrame())
544 gfx::Vector2dF
RenderWidgetHostViewAndroid::GetLastScrollOffset() const {
545 return last_scroll_offset_
;
548 gfx::NativeView
RenderWidgetHostViewAndroid::GetNativeView() const {
549 return content_view_core_
->GetViewAndroid();
552 gfx::NativeViewId
RenderWidgetHostViewAndroid::GetNativeViewId() const {
553 return reinterpret_cast<gfx::NativeViewId
>(
554 const_cast<RenderWidgetHostViewAndroid
*>(this));
557 gfx::NativeViewAccessible
558 RenderWidgetHostViewAndroid::GetNativeViewAccessible() {
563 void RenderWidgetHostViewAndroid::MovePluginWindows(
564 const std::vector
<WebPluginGeometry
>& moves
) {
565 // We don't have plugin windows on Android. Do nothing. Note: this is called
566 // from RenderWidgetHost::OnUpdateRect which is itself invoked while
567 // processing the corresponding message from Renderer.
570 void RenderWidgetHostViewAndroid::Focus() {
572 host_
->SetInputMethodActive(true);
573 if (overscroll_controller_
)
574 overscroll_controller_
->Enable();
577 void RenderWidgetHostViewAndroid::Blur() {
578 host_
->SetInputMethodActive(false);
580 if (overscroll_controller_
)
581 overscroll_controller_
->Disable();
584 bool RenderWidgetHostViewAndroid::HasFocus() const {
585 if (!content_view_core_
)
586 return false; // ContentViewCore not created yet.
588 return content_view_core_
->HasFocus();
591 bool RenderWidgetHostViewAndroid::IsSurfaceAvailableForCopy() const {
592 return HasValidFrame();
595 void RenderWidgetHostViewAndroid::Show() {
603 void RenderWidgetHostViewAndroid::Hide() {
609 bool hide_frontbuffer
= true;
610 bool stop_observing_root_window
= true;
611 HideInternal(hide_frontbuffer
, stop_observing_root_window
);
614 bool RenderWidgetHostViewAndroid::IsShowing() {
615 // ContentViewCoreImpl represents the native side of the Java
616 // ContentViewCore. It being NULL means that it is not attached
617 // to the View system yet, so we treat this RWHVA as hidden.
618 return is_showing_
&& content_view_core_
;
621 void RenderWidgetHostViewAndroid::LockCompositingSurface() {
622 DCHECK(HasValidFrame());
624 DCHECK(frame_evictor_
->HasFrame());
625 frame_evictor_
->LockFrame();
626 locks_on_frame_count_
++;
629 void RenderWidgetHostViewAndroid::UnlockCompositingSurface() {
630 if (!frame_evictor_
->HasFrame() || locks_on_frame_count_
== 0)
633 DCHECK(HasValidFrame());
634 frame_evictor_
->UnlockFrame();
635 locks_on_frame_count_
--;
637 if (locks_on_frame_count_
== 0) {
638 if (last_frame_info_
) {
639 InternalSwapCompositorFrame(last_frame_info_
->output_surface_id
,
640 last_frame_info_
->frame
.Pass());
641 last_frame_info_
.reset();
644 if (!is_showing_
&& layer_
.get())
645 layer_
->SetHideLayerAndSubtree(true);
649 void RenderWidgetHostViewAndroid::SetTextSurroundingSelectionCallback(
650 const TextSurroundingSelectionCallback
& callback
) {
651 // Only one outstanding request is allowed at any given time.
652 DCHECK(!callback
.is_null());
653 text_surrounding_selection_callback_
= callback
;
656 void RenderWidgetHostViewAndroid::OnTextSurroundingSelectionResponse(
657 const base::string16
& content
,
660 if (text_surrounding_selection_callback_
.is_null())
662 text_surrounding_selection_callback_
.Run(content
, start_offset
, end_offset
);
663 text_surrounding_selection_callback_
.Reset();
666 void RenderWidgetHostViewAndroid::OnShowUnhandledTapUIIfNeeded(int x_dip
,
668 if (!content_view_core_
)
670 // Validate the coordinates are within the viewport.
671 gfx::Size viewport_size
= content_view_core_
->GetViewportSizeDip();
672 if (x_dip
< 0 || x_dip
> viewport_size
.width() ||
673 y_dip
< 0 || y_dip
> viewport_size
.height())
675 content_view_core_
->OnShowUnhandledTapUIIfNeeded(x_dip
, y_dip
);
678 void RenderWidgetHostViewAndroid::ReleaseLocksOnSurface() {
679 if (!frame_evictor_
->HasFrame()) {
680 DCHECK_EQ(locks_on_frame_count_
, 0u);
683 while (locks_on_frame_count_
> 0) {
684 UnlockCompositingSurface();
686 RunAckCallbacks(cc::SurfaceDrawStatus::DRAW_SKIPPED
);
689 gfx::Rect
RenderWidgetHostViewAndroid::GetViewBounds() const {
690 if (!content_view_core_
)
691 return gfx::Rect(default_size_
);
693 return gfx::Rect(content_view_core_
->GetViewSize());
696 gfx::Size
RenderWidgetHostViewAndroid::GetPhysicalBackingSize() const {
697 if (!content_view_core_
)
700 return content_view_core_
->GetPhysicalBackingSize();
703 bool RenderWidgetHostViewAndroid::DoTopControlsShrinkBlinkSize() const {
704 if (!content_view_core_
)
707 // Whether or not Blink's viewport size should be shrunk by the height of the
709 return content_view_core_
->DoTopControlsShrinkBlinkSize();
712 float RenderWidgetHostViewAndroid::GetTopControlsHeight() const {
713 if (!content_view_core_
)
716 // The height of the top controls.
717 return content_view_core_
->GetTopControlsHeightDip();
720 void RenderWidgetHostViewAndroid::UpdateCursor(const WebCursor
& cursor
) {
721 // There are no cursors on Android.
724 void RenderWidgetHostViewAndroid::SetIsLoading(bool is_loading
) {
725 // Do nothing. The UI notification is handled through ContentViewClient which
726 // is TabContentsDelegate.
729 void RenderWidgetHostViewAndroid::TextInputTypeChanged(
730 ui::TextInputType type
,
731 ui::TextInputMode input_mode
,
732 bool can_compose_inline
,
734 // Unused on Android, which uses OnTextInputChanged instead.
737 long RenderWidgetHostViewAndroid::GetNativeImeAdapter() {
738 return reinterpret_cast<intptr_t>(&ime_adapter_android_
);
741 void RenderWidgetHostViewAndroid::OnTextInputStateChanged(
742 const ViewHostMsg_TextInputState_Params
& params
) {
743 if (selection_controller_
) {
744 // This call is semi-redundant with that in |OnFocusedNodeChanged|. The
745 // latter is guaranteed to be called before |OnSelectionBoundsChanged|,
746 // while this call is present to ensure consistency with IME after
747 // navigation and tab focus changes
748 const bool is_editable_node
= params
.type
!= ui::TEXT_INPUT_TYPE_NONE
;
749 selection_controller_
->OnSelectionEditable(is_editable_node
);
752 // If the change is not originated from IME (e.g. Javascript, autofill),
753 // send back the renderer an acknowledgement, regardless of how we exit from
755 base::ScopedClosureRunner ack_caller
;
756 if (params
.is_non_ime_change
)
757 ack_caller
.Reset(base::Bind(&SendImeEventAck
, host_
));
762 content_view_core_
->UpdateImeAdapter(
763 GetNativeImeAdapter(),
764 static_cast<int>(params
.type
), params
.flags
,
765 params
.value
, params
.selection_start
, params
.selection_end
,
766 params
.composition_start
, params
.composition_end
,
767 params
.show_ime_if_needed
, params
.is_non_ime_change
);
770 void RenderWidgetHostViewAndroid::OnDidChangeBodyBackgroundColor(
772 if (cached_background_color_
== color
)
775 cached_background_color_
= color
;
776 if (content_view_core_
)
777 content_view_core_
->OnBackgroundColorChanged(color
);
780 void RenderWidgetHostViewAndroid::OnSetNeedsBeginFrames(bool enabled
) {
781 TRACE_EVENT1("cc", "RenderWidgetHostViewAndroid::OnSetNeedsBeginFrames",
784 RequestVSyncUpdate(PERSISTENT_BEGIN_FRAME
);
786 outstanding_vsync_requests_
&= ~PERSISTENT_BEGIN_FRAME
;
789 void RenderWidgetHostViewAndroid::OnStartContentIntent(
790 const GURL
& content_url
) {
791 if (content_view_core_
)
792 content_view_core_
->StartContentIntent(content_url
);
795 void RenderWidgetHostViewAndroid::OnSmartClipDataExtracted(
796 const base::string16
& text
,
797 const base::string16
& html
,
798 const gfx::Rect rect
) {
799 if (content_view_core_
)
800 content_view_core_
->OnSmartClipDataExtracted(text
, html
, rect
);
803 bool RenderWidgetHostViewAndroid::OnTouchEvent(
804 const ui::MotionEvent
& event
) {
808 if (selection_controller_
&&
809 selection_controller_
->WillHandleTouchEvent(event
))
812 if (stylus_text_selector_
.OnTouchEvent(event
))
815 ui::FilteredGestureProvider::TouchHandlingResult result
=
816 gesture_provider_
.OnTouchEvent(event
);
817 if (!result
.succeeded
)
820 blink::WebTouchEvent web_event
=
821 ui::CreateWebTouchEventFromMotionEvent(event
, result
.did_generate_scroll
);
822 host_
->ForwardTouchEventWithLatencyInfo(web_event
,
823 CreateLatencyInfo(web_event
));
825 // Send a proactive BeginFrame on the next vsync to reduce latency.
826 // This is good enough as long as the first touch event has Begin semantics
827 // and the actual scroll happens on the next vsync.
828 if (observing_root_window_
)
829 RequestVSyncUpdate(BEGIN_FRAME
);
834 bool RenderWidgetHostViewAndroid::OnTouchHandleEvent(
835 const ui::MotionEvent
& event
) {
836 return selection_controller_
&&
837 selection_controller_
->WillHandleTouchEvent(event
);
840 void RenderWidgetHostViewAndroid::ResetGestureDetection() {
841 const ui::MotionEvent
* current_down_event
=
842 gesture_provider_
.GetCurrentDownEvent();
843 if (current_down_event
) {
844 scoped_ptr
<ui::MotionEvent
> cancel_event
= current_down_event
->Cancel();
845 OnTouchEvent(*cancel_event
);
848 // A hard reset ensures prevention of any timer-based events.
849 gesture_provider_
.ResetDetection();
852 void RenderWidgetHostViewAndroid::OnDidNavigateMainFrameToNewPage() {
853 ResetGestureDetection();
856 void RenderWidgetHostViewAndroid::SetDoubleTapSupportEnabled(bool enabled
) {
857 gesture_provider_
.SetDoubleTapSupportForPlatformEnabled(enabled
);
860 void RenderWidgetHostViewAndroid::SetMultiTouchZoomSupportEnabled(
862 gesture_provider_
.SetMultiTouchZoomSupportEnabled(enabled
);
865 void RenderWidgetHostViewAndroid::ImeCancelComposition() {
866 ime_adapter_android_
.CancelComposition();
869 void RenderWidgetHostViewAndroid::ImeCompositionRangeChanged(
870 const gfx::Range
& range
,
871 const std::vector
<gfx::Rect
>& character_bounds
) {
872 // TODO(yukawa): Implement this.
875 void RenderWidgetHostViewAndroid::FocusedNodeChanged(bool is_editable_node
) {
876 ime_adapter_android_
.FocusedNodeChanged(is_editable_node
);
877 if (selection_controller_
)
878 selection_controller_
->OnSelectionEditable(is_editable_node
);
881 void RenderWidgetHostViewAndroid::RenderProcessGone(
882 base::TerminationStatus status
, int error_code
) {
886 void RenderWidgetHostViewAndroid::Destroy() {
888 SetContentViewCore(NULL
);
890 if (!surface_id_
.is_null()) {
891 DCHECK(surface_factory_
.get());
892 surface_factory_
->Destroy(surface_id_
);
893 surface_id_
= cc::SurfaceId();
895 surface_factory_
.reset();
897 // The RenderWidgetHost's destruction led here, so don't call it.
903 void RenderWidgetHostViewAndroid::SetTooltipText(
904 const base::string16
& tooltip_text
) {
905 // Tooltips don't makes sense on Android.
908 void RenderWidgetHostViewAndroid::SelectionChanged(const base::string16
& text
,
910 const gfx::Range
& range
) {
911 RenderWidgetHostViewBase::SelectionChanged(text
, offset
, range
);
913 if (selection_controller_
)
914 selection_controller_
->OnSelectionEmpty(text
.empty());
916 if (!content_view_core_
)
918 if (range
.is_empty()) {
919 content_view_core_
->OnSelectionChanged("");
923 DCHECK(!text
.empty());
924 size_t pos
= range
.GetMin() - offset
;
925 size_t n
= range
.length();
927 DCHECK(pos
+ n
<= text
.length()) << "The text can not fully cover range.";
928 if (pos
>= text
.length()) {
929 NOTREACHED() << "The text can not cover range.";
933 std::string utf8_selection
= base::UTF16ToUTF8(text
.substr(pos
, n
));
935 content_view_core_
->OnSelectionChanged(utf8_selection
);
938 void RenderWidgetHostViewAndroid::SelectionBoundsChanged(
939 const ViewHostMsg_SelectionBounds_Params
& params
) {
940 NOTREACHED() << "Selection bounds should be routed through the compositor.";
943 void RenderWidgetHostViewAndroid::SetBackgroundColor(SkColor color
) {
944 RenderWidgetHostViewBase::SetBackgroundColor(color
);
945 host_
->SetBackgroundOpaque(GetBackgroundOpaque());
946 OnDidChangeBodyBackgroundColor(color
);
949 void RenderWidgetHostViewAndroid::CopyFromCompositingSurface(
950 const gfx::Rect
& src_subrect
,
951 const gfx::Size
& dst_size
,
952 ReadbackRequestCallback
& callback
,
953 const SkColorType color_type
) {
954 TRACE_EVENT0("cc", "RenderWidgetHostViewAndroid::CopyFromCompositingSurface");
955 if (!host_
|| host_
->is_hidden()) {
956 callback
.Run(SkBitmap(), READBACK_SURFACE_UNAVAILABLE
);
959 base::TimeTicks start_time
= base::TimeTicks::Now();
960 if (using_browser_compositor_
&& !IsSurfaceAvailableForCopy()) {
961 callback
.Run(SkBitmap(), READBACK_NOT_SUPPORTED
);
964 const gfx::Display
& display
=
965 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
966 float device_scale_factor
= display
.device_scale_factor();
967 gfx::Size dst_size_in_pixel
=
968 gfx::ConvertRectToPixel(device_scale_factor
, gfx::Rect(dst_size
)).size();
969 gfx::Rect src_subrect_in_pixel
=
970 gfx::ConvertRectToPixel(device_scale_factor
, src_subrect
);
972 if (!using_browser_compositor_
) {
973 SynchronousCopyContents(src_subrect_in_pixel
, dst_size_in_pixel
, callback
,
975 UMA_HISTOGRAM_TIMES("Compositing.CopyFromSurfaceTimeSynchronous",
976 base::TimeTicks::Now() - start_time
);
980 scoped_ptr
<cc::CopyOutputRequest
> request
;
981 scoped_refptr
<cc::Layer
> readback_layer
;
982 DCHECK(content_view_core_
);
983 DCHECK(content_view_core_
->GetWindowAndroid());
984 ui::WindowAndroidCompositor
* compositor
=
985 content_view_core_
->GetWindowAndroid()->GetCompositor();
987 DCHECK(frame_provider_
.get() || !surface_id_
.is_null());
988 scoped_refptr
<cc::Layer
> layer
= CreateDelegatedLayer();
990 layer
->SetHideLayerAndSubtree(true);
991 compositor
->AttachLayerForReadback(layer
);
993 readback_layer
= layer
;
994 request
= cc::CopyOutputRequest::CreateRequest(
995 base::Bind(&RenderWidgetHostViewAndroid::
996 PrepareTextureCopyOutputResultForDelegatedReadback
,
1002 if (!src_subrect_in_pixel
.IsEmpty())
1003 request
->set_area(src_subrect_in_pixel
);
1004 readback_layer
->RequestCopyOfOutput(request
.Pass());
1007 void RenderWidgetHostViewAndroid::CopyFromCompositingSurfaceToVideoFrame(
1008 const gfx::Rect
& src_subrect
,
1009 const scoped_refptr
<media::VideoFrame
>& target
,
1010 const base::Callback
<void(bool)>& callback
) {
1012 callback
.Run(false);
1015 bool RenderWidgetHostViewAndroid::CanCopyToVideoFrame() const {
1019 void RenderWidgetHostViewAndroid::ShowDisambiguationPopup(
1020 const gfx::Rect
& rect_pixels
, const SkBitmap
& zoomed_bitmap
) {
1021 if (!content_view_core_
)
1024 content_view_core_
->ShowDisambiguationPopup(rect_pixels
, zoomed_bitmap
);
1027 scoped_ptr
<SyntheticGestureTarget
>
1028 RenderWidgetHostViewAndroid::CreateSyntheticGestureTarget() {
1029 return scoped_ptr
<SyntheticGestureTarget
>(new SyntheticGestureTargetAndroid(
1030 host_
, content_view_core_
->CreateTouchEventSynthesizer()));
1033 void RenderWidgetHostViewAndroid::SendDelegatedFrameAck(
1034 uint32 output_surface_id
) {
1036 cc::CompositorFrameAck ack
;
1037 if (!surface_returned_resources_
.empty())
1038 ack
.resources
.swap(surface_returned_resources_
);
1039 if (resource_collection_
.get())
1040 resource_collection_
->TakeUnusedResourcesForChildCompositor(&ack
.resources
);
1041 host_
->Send(new ViewMsg_SwapCompositorFrameAck(host_
->GetRoutingID(),
1042 output_surface_id
, ack
));
1045 void RenderWidgetHostViewAndroid::SendReturnedDelegatedResources(
1046 uint32 output_surface_id
) {
1048 cc::CompositorFrameAck ack
;
1049 if (!surface_returned_resources_
.empty()) {
1050 ack
.resources
.swap(surface_returned_resources_
);
1052 DCHECK(resource_collection_
.get());
1053 resource_collection_
->TakeUnusedResourcesForChildCompositor(&ack
.resources
);
1056 host_
->Send(new ViewMsg_ReclaimCompositorResources(host_
->GetRoutingID(),
1057 output_surface_id
, ack
));
1060 void RenderWidgetHostViewAndroid::UnusedResourcesAreAvailable() {
1061 DCHECK(surface_id_
.is_null());
1062 if (ack_callbacks_
.size())
1064 SendReturnedDelegatedResources(last_output_surface_id_
);
1067 void RenderWidgetHostViewAndroid::ReturnResources(
1068 const cc::ReturnedResourceArray
& resources
) {
1069 if (resources
.empty())
1071 std::copy(resources
.begin(), resources
.end(),
1072 std::back_inserter(surface_returned_resources_
));
1073 if (!ack_callbacks_
.size())
1074 SendReturnedDelegatedResources(last_output_surface_id_
);
1077 void RenderWidgetHostViewAndroid::DestroyDelegatedContent() {
1079 frame_provider_
= NULL
;
1080 if (!surface_id_
.is_null()) {
1081 DCHECK(surface_factory_
.get());
1082 surface_factory_
->Destroy(surface_id_
);
1083 surface_id_
= cc::SurfaceId();
1086 // This gets called when ever any eviction, loosing resources, swapping
1087 // problems are encountered and so we abort any pending readbacks here.
1088 AbortPendingReadbackRequests();
1091 void RenderWidgetHostViewAndroid::CheckOutputSurfaceChanged(
1092 uint32 output_surface_id
) {
1093 if (output_surface_id
== last_output_surface_id_
)
1095 // Drop the cc::DelegatedFrameResourceCollection so that we will not return
1096 // any resources from the old output surface with the new output surface id.
1097 if (resource_collection_
.get()) {
1098 resource_collection_
->SetClient(NULL
);
1099 if (resource_collection_
->LoseAllResources())
1100 SendReturnedDelegatedResources(last_output_surface_id_
);
1101 resource_collection_
= NULL
;
1103 DestroyDelegatedContent();
1104 surface_factory_
.reset();
1105 if (!surface_returned_resources_
.empty())
1106 SendReturnedDelegatedResources(last_output_surface_id_
);
1108 last_output_surface_id_
= output_surface_id
;
1111 void RenderWidgetHostViewAndroid::SubmitFrame(
1112 scoped_ptr
<cc::DelegatedFrameData
> frame_data
) {
1113 cc::SurfaceManager
* manager
= CompositorImpl::GetSurfaceManager();
1115 if (!surface_factory_
) {
1116 id_allocator_
= CompositorImpl::CreateSurfaceIdAllocator();
1117 surface_factory_
= make_scoped_ptr(new cc::SurfaceFactory(manager
, this));
1119 if (surface_id_
.is_null() ||
1120 texture_size_in_layer_
!= current_surface_size_
) {
1122 if (!surface_id_
.is_null())
1123 surface_factory_
->Destroy(surface_id_
);
1124 surface_id_
= id_allocator_
->GenerateId();
1125 surface_factory_
->Create(surface_id_
);
1126 layer_
= CreateDelegatedLayer();
1130 current_surface_size_
= texture_size_in_layer_
;
1133 scoped_ptr
<cc::CompositorFrame
> compositor_frame
=
1134 make_scoped_ptr(new cc::CompositorFrame());
1135 compositor_frame
->delegated_frame_data
= frame_data
.Pass();
1137 cc::SurfaceFactory::DrawCallback ack_callback
=
1138 base::Bind(&RenderWidgetHostViewAndroid::RunAckCallbacks
,
1139 weak_ptr_factory_
.GetWeakPtr());
1140 surface_factory_
->SubmitFrame(surface_id_
, compositor_frame
.Pass(),
1143 if (!resource_collection_
.get()) {
1144 resource_collection_
= new cc::DelegatedFrameResourceCollection
;
1145 resource_collection_
->SetClient(this);
1147 if (!frame_provider_
.get() ||
1148 texture_size_in_layer_
!= frame_provider_
->frame_size()) {
1150 frame_provider_
= new cc::DelegatedFrameProvider(
1151 resource_collection_
.get(), frame_data
.Pass());
1152 layer_
= cc::DelegatedRendererLayer::Create(frame_provider_
);
1155 frame_provider_
->SetFrameData(frame_data
.Pass());
1160 void RenderWidgetHostViewAndroid::SwapDelegatedFrame(
1161 uint32 output_surface_id
,
1162 scoped_ptr
<cc::DelegatedFrameData
> frame_data
) {
1163 CheckOutputSurfaceChanged(output_surface_id
);
1164 bool has_content
= !texture_size_in_layer_
.IsEmpty();
1166 // DelegatedRendererLayerImpl applies the inverse device_scale_factor of the
1167 // renderer frame, assuming that the browser compositor will scale
1168 // it back up to device scale. But on Android we put our browser layers in
1169 // physical pixels and set our browser CC device_scale_factor to 1, so this
1170 // suppresses the transform. This line may need to be removed when fixing
1171 // http://crbug.com/384134 or http://crbug.com/310763
1172 frame_data
->device_scale_factor
= 1.0f
;
1175 DestroyDelegatedContent();
1177 SubmitFrame(frame_data
.Pass());
1181 layer_
->SetIsDrawable(true);
1182 layer_
->SetContentsOpaque(true);
1183 layer_
->SetBounds(content_size_in_layer_
);
1184 layer_
->SetNeedsDisplay();
1187 base::Closure ack_callback
=
1188 base::Bind(&RenderWidgetHostViewAndroid::SendDelegatedFrameAck
,
1189 weak_ptr_factory_
.GetWeakPtr(),
1192 ack_callbacks_
.push(ack_callback
);
1193 if (host_
->is_hidden())
1194 RunAckCallbacks(cc::SurfaceDrawStatus::DRAW_SKIPPED
);
1197 void RenderWidgetHostViewAndroid::ComputeContentsSize(
1198 const cc::CompositorFrameMetadata
& frame_metadata
) {
1199 // Calculate the content size. This should be 0 if the texture_size is 0.
1200 gfx::Vector2dF offset
;
1201 if (texture_size_in_layer_
.IsEmpty())
1202 content_size_in_layer_
= gfx::Size();
1203 content_size_in_layer_
= gfx::ToCeiledSize(gfx::ScaleSize(
1204 frame_metadata
.scrollable_viewport_size
,
1205 frame_metadata
.device_scale_factor
* frame_metadata
.page_scale_factor
));
1209 void RenderWidgetHostViewAndroid::InternalSwapCompositorFrame(
1210 uint32 output_surface_id
,
1211 scoped_ptr
<cc::CompositorFrame
> frame
) {
1212 last_scroll_offset_
= frame
->metadata
.root_scroll_offset
;
1213 if (!frame
->delegated_frame_data
) {
1214 LOG(ERROR
) << "Non-delegated renderer path no longer supported";
1218 if (locks_on_frame_count_
> 0) {
1219 DCHECK(HasValidFrame());
1220 RetainFrame(output_surface_id
, frame
.Pass());
1224 if (layer_
.get() && layer_
->layer_tree_host()) {
1225 for (size_t i
= 0; i
< frame
->metadata
.latency_info
.size(); i
++) {
1226 scoped_ptr
<cc::SwapPromise
> swap_promise(
1227 new cc::LatencyInfoSwapPromise(frame
->metadata
.latency_info
[i
]));
1228 layer_
->layer_tree_host()->QueueSwapPromise(swap_promise
.Pass());
1232 DCHECK(!frame
->delegated_frame_data
->render_pass_list
.empty());
1234 cc::RenderPass
* root_pass
=
1235 frame
->delegated_frame_data
->render_pass_list
.back();
1236 texture_size_in_layer_
= root_pass
->output_rect
.size();
1237 ComputeContentsSize(frame
->metadata
);
1239 SwapDelegatedFrame(output_surface_id
, frame
->delegated_frame_data
.Pass());
1240 frame_evictor_
->SwappedFrame(!host_
->is_hidden());
1242 // As the metadata update may trigger view invalidation, always call it after
1243 // any potential compositor scheduling.
1244 OnFrameMetadataUpdated(frame
->metadata
);
1245 // Check if we have any pending readbacks, see if we have a frame available
1246 // and process them here.
1247 if (!readbacks_waiting_for_frame_
.empty()) {
1248 while (!readbacks_waiting_for_frame_
.empty()) {
1249 ReadbackRequest
& readback_request
= readbacks_waiting_for_frame_
.front();
1250 GetScaledContentBitmap(readback_request
.GetScale(),
1251 readback_request
.GetColorFormat(),
1252 readback_request
.GetCaptureRect(),
1253 readback_request
.GetResultCallback());
1254 readbacks_waiting_for_frame_
.pop();
1259 void RenderWidgetHostViewAndroid::OnSwapCompositorFrame(
1260 uint32 output_surface_id
,
1261 scoped_ptr
<cc::CompositorFrame
> frame
) {
1262 InternalSwapCompositorFrame(output_surface_id
, frame
.Pass());
1265 void RenderWidgetHostViewAndroid::RetainFrame(
1266 uint32 output_surface_id
,
1267 scoped_ptr
<cc::CompositorFrame
> frame
) {
1268 DCHECK(locks_on_frame_count_
);
1270 // Store the incoming frame so that it can be swapped when all the locks have
1271 // been released. If there is already a stored frame, then replace and skip
1272 // the previous one but make sure we still eventually send the ACK. Holding
1273 // the ACK also blocks the renderer when its max_frames_pending is reached.
1274 if (last_frame_info_
) {
1275 base::Closure ack_callback
=
1276 base::Bind(&RenderWidgetHostViewAndroid::SendDelegatedFrameAck
,
1277 weak_ptr_factory_
.GetWeakPtr(),
1278 last_frame_info_
->output_surface_id
);
1280 ack_callbacks_
.push(ack_callback
);
1283 last_frame_info_
.reset(new LastFrameInfo(output_surface_id
, frame
.Pass()));
1286 void RenderWidgetHostViewAndroid::SynchronousFrameMetadata(
1287 const cc::CompositorFrameMetadata
& frame_metadata
) {
1288 if (!content_view_core_
)
1291 // This is a subset of OnSwapCompositorFrame() used in the synchronous
1293 OnFrameMetadataUpdated(frame_metadata
);
1294 ComputeContentsSize(frame_metadata
);
1296 // DevTools ScreenCast support for Android WebView.
1297 WebContents
* web_contents
= content_view_core_
->GetWebContents();
1298 if (DevToolsAgentHost::HasFor(web_contents
)) {
1299 scoped_refptr
<DevToolsAgentHost
> dtah
=
1300 DevToolsAgentHost::GetOrCreateFor(web_contents
);
1301 // Unblock the compositor.
1302 BrowserThread::PostTask(
1303 BrowserThread::UI
, FROM_HERE
,
1305 &RenderFrameDevToolsAgentHost::SynchronousSwapCompositorFrame
,
1306 static_cast<RenderFrameDevToolsAgentHost
*>(dtah
.get()),
1311 void RenderWidgetHostViewAndroid::SetOverlayVideoMode(bool enabled
) {
1313 layer_
->SetContentsOpaque(!enabled
);
1316 bool RenderWidgetHostViewAndroid::SupportsAnimation() const {
1317 // The synchronous (WebView) compositor does not have a proper browser
1318 // compositor with which to drive animations.
1319 return using_browser_compositor_
;
1322 void RenderWidgetHostViewAndroid::SetNeedsAnimate() {
1323 DCHECK(content_view_core_
);
1324 DCHECK(using_browser_compositor_
);
1325 content_view_core_
->GetWindowAndroid()->SetNeedsAnimate();
1328 void RenderWidgetHostViewAndroid::MoveCaret(const gfx::PointF
& position
) {
1329 MoveCaret(gfx::Point(position
.x(), position
.y()));
1332 void RenderWidgetHostViewAndroid::MoveRangeSelectionExtent(
1333 const gfx::PointF
& extent
) {
1334 DCHECK(content_view_core_
);
1335 content_view_core_
->MoveRangeSelectionExtent(extent
);
1338 void RenderWidgetHostViewAndroid::SelectBetweenCoordinates(
1339 const gfx::PointF
& base
,
1340 const gfx::PointF
& extent
) {
1341 DCHECK(content_view_core_
);
1342 content_view_core_
->SelectBetweenCoordinates(base
, extent
);
1345 void RenderWidgetHostViewAndroid::OnSelectionEvent(
1346 ui::SelectionEventType event
,
1347 const gfx::PointF
& position
) {
1348 DCHECK(content_view_core_
);
1349 // Showing the selection action bar can alter the current View coordinates in
1350 // such a way that the current MotionEvent stream is suddenly shifted in
1351 // space. Avoid the associated scroll jump by pre-emptively cancelling gesture
1352 // detection; scrolling after the selection is activated is unnecessary.
1353 if (event
== ui::SelectionEventType::SELECTION_SHOWN
)
1354 ResetGestureDetection();
1355 content_view_core_
->OnSelectionEvent(event
, position
);
1358 scoped_ptr
<ui::TouchHandleDrawable
>
1359 RenderWidgetHostViewAndroid::CreateDrawable() {
1360 DCHECK(content_view_core_
);
1361 if (!using_browser_compositor_
)
1362 return content_view_core_
->CreatePopupTouchHandleDrawable();
1364 return scoped_ptr
<ui::TouchHandleDrawable
>(new CompositedTouchHandleDrawable(
1365 content_view_core_
->GetLayer().get(),
1366 content_view_core_
->GetDpiScale(),
1367 // Use the activity context (instead of the application context) to ensure
1368 // proper handle theming.
1369 content_view_core_
->GetContext().obj()));
1372 void RenderWidgetHostViewAndroid::SynchronousCopyContents(
1373 const gfx::Rect
& src_subrect_in_pixel
,
1374 const gfx::Size
& dst_size_in_pixel
,
1375 ReadbackRequestCallback
& callback
,
1376 const SkColorType color_type
) {
1377 gfx::Size input_size_in_pixel
;
1378 if (src_subrect_in_pixel
.IsEmpty())
1379 input_size_in_pixel
= content_size_in_layer_
;
1381 input_size_in_pixel
= src_subrect_in_pixel
.size();
1383 gfx::Size output_size_in_pixel
;
1384 if (dst_size_in_pixel
.IsEmpty())
1385 output_size_in_pixel
= input_size_in_pixel
;
1387 output_size_in_pixel
= dst_size_in_pixel
;
1388 int output_width
= output_size_in_pixel
.width();
1389 int output_height
= output_size_in_pixel
.height();
1391 SynchronousCompositor
* compositor
=
1392 SynchronousCompositorImpl::FromID(host_
->GetProcess()->GetID(),
1393 host_
->GetRoutingID());
1395 callback
.Run(SkBitmap(), READBACK_FAILED
);
1400 bitmap
.allocPixels(SkImageInfo::Make(output_width
,
1403 kPremul_SkAlphaType
));
1404 SkCanvas
canvas(bitmap
);
1406 (float)output_width
/ (float)input_size_in_pixel
.width(),
1407 (float)output_height
/ (float)input_size_in_pixel
.height());
1408 compositor
->DemandDrawSw(&canvas
);
1409 callback
.Run(bitmap
, READBACK_SUCCESS
);
1412 void RenderWidgetHostViewAndroid::OnFrameMetadataUpdated(
1413 const cc::CompositorFrameMetadata
& frame_metadata
) {
1414 bool is_mobile_optimized
= IsMobileOptimizedFrame(frame_metadata
);
1415 gesture_provider_
.SetDoubleTapSupportForPageEnabled(!is_mobile_optimized
);
1417 if (!content_view_core_
)
1420 if (overscroll_controller_
)
1421 overscroll_controller_
->OnFrameMetadataUpdated(frame_metadata
);
1423 if (selection_controller_
) {
1424 selection_controller_
->OnSelectionBoundsChanged(
1425 ConvertSelectionBound(frame_metadata
.selection_start
),
1426 ConvertSelectionBound(frame_metadata
.selection_end
));
1429 // All offsets and sizes are in CSS pixels.
1430 content_view_core_
->UpdateFrameInfo(
1431 frame_metadata
.root_scroll_offset
,
1432 frame_metadata
.page_scale_factor
,
1433 gfx::Vector2dF(frame_metadata
.min_page_scale_factor
,
1434 frame_metadata
.max_page_scale_factor
),
1435 frame_metadata
.root_layer_size
,
1436 frame_metadata
.scrollable_viewport_size
,
1437 frame_metadata
.location_bar_offset
,
1438 frame_metadata
.location_bar_content_translation
,
1439 is_mobile_optimized
);
1440 #if defined(VIDEO_HOLE)
1441 if (host_
&& host_
->IsRenderView()) {
1442 RenderViewHostImpl
* rvhi
= static_cast<RenderViewHostImpl
*>(
1443 RenderViewHost::From(host_
));
1444 WebContentsImpl
* web_contents_impl
=
1445 static_cast<WebContentsImpl
*>(WebContents::FromRenderViewHost(rvhi
));
1446 if (web_contents_impl
)
1447 web_contents_impl
->media_web_contents_observer()->OnFrameInfoUpdated();
1449 #endif // defined(VIDEO_HOLE)
1452 void RenderWidgetHostViewAndroid::AcceleratedSurfaceInitialized(int route_id
) {
1453 // TODO: remove need for the surface id here
1454 accelerated_surface_route_id_
= route_id
;
1457 void RenderWidgetHostViewAndroid::ShowInternal() {
1458 DCHECK(is_showing_
);
1459 if (!host_
|| !host_
->is_hidden())
1463 layer_
->SetHideLayerAndSubtree(false);
1465 frame_evictor_
->SetVisible(true);
1467 if (overscroll_controller_
)
1468 overscroll_controller_
->Enable();
1470 host_
->WasShown(ui::LatencyInfo());
1472 if (content_view_core_
) {
1473 StartObservingRootWindow();
1474 RequestVSyncUpdate(BEGIN_FRAME
);
1478 void RenderWidgetHostViewAndroid::HideInternal(
1479 bool hide_frontbuffer
,
1480 bool stop_observing_root_window
) {
1481 if (hide_frontbuffer
) {
1482 if (layer_
.get() && locks_on_frame_count_
== 0)
1483 layer_
->SetHideLayerAndSubtree(true);
1485 frame_evictor_
->SetVisible(false);
1488 if (stop_observing_root_window
)
1489 StopObservingRootWindow();
1491 if (!host_
|| host_
->is_hidden())
1494 if (overscroll_controller_
)
1495 overscroll_controller_
->Disable();
1497 // We don't know if we will ever get a frame if we are hiding the renderer, so
1498 // we need to cancel all requests
1499 AbortPendingReadbackRequests();
1501 RunAckCallbacks(cc::SurfaceDrawStatus::DRAW_SKIPPED
);
1503 // Inform the renderer that we are being hidden so it can reduce its resource
1508 void RenderWidgetHostViewAndroid::AttachLayers() {
1509 if (!content_view_core_
)
1514 content_view_core_
->AttachLayer(layer_
);
1515 if (overscroll_controller_
)
1516 overscroll_controller_
->Enable();
1517 layer_
->SetHideLayerAndSubtree(!is_showing_
);
1520 void RenderWidgetHostViewAndroid::RemoveLayers() {
1521 if (!content_view_core_
)
1527 content_view_core_
->RemoveLayer(layer_
);
1528 if (overscroll_controller_
)
1529 overscroll_controller_
->Disable();
1532 void RenderWidgetHostViewAndroid::RequestVSyncUpdate(uint32 requests
) {
1533 bool should_request_vsync
= !outstanding_vsync_requests_
&& requests
;
1534 outstanding_vsync_requests_
|= requests
;
1536 // If the host has been hidden, defer vsync requests until it is shown
1537 // again via |Show()|.
1538 if (!host_
|| host_
->is_hidden())
1541 // Note that if we're not currently observing the root window, outstanding
1542 // vsync requests will be pushed if/when we resume observing in
1543 // |StartObservingRootWindow()|.
1544 if (observing_root_window_
&& should_request_vsync
)
1545 content_view_core_
->GetWindowAndroid()->RequestVSyncUpdate();
1548 void RenderWidgetHostViewAndroid::StartObservingRootWindow() {
1549 DCHECK(content_view_core_
);
1550 DCHECK(is_showing_
);
1551 if (observing_root_window_
)
1554 observing_root_window_
= true;
1555 content_view_core_
->GetWindowAndroid()->AddObserver(this);
1557 // Clear existing vsync requests to allow a request to the new window.
1558 uint32 outstanding_vsync_requests
= outstanding_vsync_requests_
;
1559 outstanding_vsync_requests_
= 0;
1560 RequestVSyncUpdate(outstanding_vsync_requests
);
1563 void RenderWidgetHostViewAndroid::StopObservingRootWindow() {
1564 if (!content_view_core_
) {
1565 DCHECK(!observing_root_window_
);
1569 if (!observing_root_window_
)
1572 observing_root_window_
= false;
1573 content_view_core_
->GetWindowAndroid()->RemoveObserver(this);
1576 void RenderWidgetHostViewAndroid::SendBeginFrame(base::TimeTicks frame_time
,
1577 base::TimeDelta vsync_period
) {
1578 TRACE_EVENT1("cc", "RenderWidgetHostViewAndroid::SendBeginFrame",
1579 "frame_time_us", frame_time
.ToInternalValue());
1581 if (using_browser_compositor_
) {
1582 base::TimeTicks display_time
= frame_time
+ vsync_period
;
1584 base::TimeTicks deadline
=
1585 display_time
- host_
->GetEstimatedBrowserCompositeTime();
1587 host_
->Send(new ViewMsg_BeginFrame(
1588 host_
->GetRoutingID(),
1589 cc::BeginFrameArgs::Create(BEGINFRAME_FROM_HERE
, frame_time
, deadline
,
1590 vsync_period
, cc::BeginFrameArgs::NORMAL
)));
1592 SynchronousCompositorImpl
* compositor
= SynchronousCompositorImpl::FromID(
1593 host_
->GetProcess()->GetID(), host_
->GetRoutingID());
1595 // The synchronous compositor synchronously does it's work in this call.
1596 // It does not use a deadline.
1597 compositor
->BeginFrame(cc::BeginFrameArgs::Create(
1598 BEGINFRAME_FROM_HERE
, frame_time
, base::TimeTicks(), vsync_period
,
1599 cc::BeginFrameArgs::NORMAL
));
1604 bool RenderWidgetHostViewAndroid::Animate(base::TimeTicks frame_time
) {
1605 bool needs_animate
= false;
1606 if (overscroll_controller_
) {
1607 needs_animate
|= overscroll_controller_
->Animate(
1608 frame_time
, content_view_core_
->GetLayer().get());
1610 if (selection_controller_
)
1611 needs_animate
|= selection_controller_
->Animate(frame_time
);
1612 return needs_animate
;
1615 void RenderWidgetHostViewAndroid::EvictDelegatedFrame() {
1617 DestroyDelegatedContent();
1618 frame_evictor_
->DiscardedFrame();
1619 // We are evicting the delegated frame,
1620 // so there should be no pending readback requests
1621 DCHECK(readbacks_waiting_for_frame_
.empty());
1624 bool RenderWidgetHostViewAndroid::HasAcceleratedSurface(
1625 const gfx::Size
& desired_size
) {
1630 void RenderWidgetHostViewAndroid::GetScreenInfo(blink::WebScreenInfo
* result
) {
1631 // ScreenInfo isn't tied to the widget on Android. Always return the default.
1632 RenderWidgetHostViewBase::GetDefaultScreenInfo(result
);
1635 // TODO(jrg): Find out the implications and answer correctly here,
1636 // as we are returning the WebView and not root window bounds.
1637 gfx::Rect
RenderWidgetHostViewAndroid::GetBoundsInRootWindow() {
1638 return GetViewBounds();
1641 gfx::GLSurfaceHandle
RenderWidgetHostViewAndroid::GetCompositingSurface() {
1642 gfx::GLSurfaceHandle handle
=
1643 gfx::GLSurfaceHandle(gfx::kNullPluginWindow
, gfx::NULL_TRANSPORT
);
1644 if (using_browser_compositor_
) {
1645 handle
.parent_client_id
=
1646 BrowserGpuChannelHostFactory::instance()->GetGpuChannelId();
1651 void RenderWidgetHostViewAndroid::ProcessAckedTouchEvent(
1652 const TouchEventWithLatencyInfo
& touch
, InputEventAckState ack_result
) {
1653 const bool event_consumed
= ack_result
== INPUT_EVENT_ACK_STATE_CONSUMED
;
1654 gesture_provider_
.OnAsyncTouchEventAck(event_consumed
);
1657 void RenderWidgetHostViewAndroid::GestureEventAck(
1658 const blink::WebGestureEvent
& event
,
1659 InputEventAckState ack_result
) {
1660 if (overscroll_controller_
)
1661 overscroll_controller_
->OnGestureEventAck(event
, ack_result
);
1663 if (content_view_core_
)
1664 content_view_core_
->OnGestureEventAck(event
, ack_result
);
1667 InputEventAckState
RenderWidgetHostViewAndroid::FilterInputEvent(
1668 const blink::WebInputEvent
& input_event
) {
1669 if (selection_controller_
) {
1670 switch (input_event
.type
) {
1671 case blink::WebInputEvent::GestureLongPress
:
1672 selection_controller_
->OnLongPressEvent();
1674 case blink::WebInputEvent::GestureTap
:
1675 selection_controller_
->OnTapEvent();
1682 if (overscroll_controller_
&&
1683 blink::WebInputEvent::isGestureEventType(input_event
.type
) &&
1684 overscroll_controller_
->WillHandleGestureEvent(
1685 static_cast<const blink::WebGestureEvent
&>(input_event
))) {
1686 return INPUT_EVENT_ACK_STATE_CONSUMED
;
1689 if (content_view_core_
&&
1690 content_view_core_
->FilterInputEvent(input_event
))
1691 return INPUT_EVENT_ACK_STATE_CONSUMED
;
1694 return INPUT_EVENT_ACK_STATE_NOT_CONSUMED
;
1696 if (input_event
.type
== blink::WebInputEvent::GestureTapDown
||
1697 input_event
.type
== blink::WebInputEvent::TouchStart
) {
1698 GpuDataManagerImpl
* gpu_data
= GpuDataManagerImpl::GetInstance();
1699 GpuProcessHostUIShim
* shim
= GpuProcessHostUIShim::GetOneInstance();
1700 if (shim
&& gpu_data
&& accelerated_surface_route_id_
&&
1701 gpu_data
->IsDriverBugWorkaroundActive(gpu::WAKE_UP_GPU_BEFORE_DRAWING
))
1703 new AcceleratedSurfaceMsg_WakeUpGpu(accelerated_surface_route_id_
));
1706 SynchronousCompositorImpl
* compositor
=
1707 SynchronousCompositorImpl::FromID(host_
->GetProcess()->GetID(),
1708 host_
->GetRoutingID());
1710 return compositor
->HandleInputEvent(input_event
);
1711 return INPUT_EVENT_ACK_STATE_NOT_CONSUMED
;
1714 void RenderWidgetHostViewAndroid::OnSetNeedsFlushInput() {
1715 TRACE_EVENT0("input", "RenderWidgetHostViewAndroid::OnSetNeedsFlushInput");
1716 RequestVSyncUpdate(FLUSH_INPUT
);
1719 BrowserAccessibilityManager
*
1720 RenderWidgetHostViewAndroid::CreateBrowserAccessibilityManager(
1721 BrowserAccessibilityDelegate
* delegate
) {
1722 // TODO(dmazzoni): Currently there can only be one
1723 // BrowserAccessibilityManager per ContentViewCore, so return NULL
1724 // if there's already a BrowserAccessibilityManager for the main
1725 // frame. Eventually, in order to support cross-process iframes on
1726 // Android we'll need to add support for a
1727 // BrowserAccessibilityManager for a child frame.
1728 // http://crbug.com/423846
1729 if (!host_
|| host_
->GetRootBrowserAccessibilityManager())
1732 base::android::ScopedJavaLocalRef
<jobject
> obj
;
1733 if (content_view_core_
)
1734 obj
= content_view_core_
->GetJavaObject();
1735 return new BrowserAccessibilityManagerAndroid(
1737 BrowserAccessibilityManagerAndroid::GetEmptyDocument(),
1741 bool RenderWidgetHostViewAndroid::LockMouse() {
1746 void RenderWidgetHostViewAndroid::UnlockMouse() {
1750 // Methods called from the host to the render
1752 void RenderWidgetHostViewAndroid::SendKeyEvent(
1753 const NativeWebKeyboardEvent
& event
) {
1755 host_
->ForwardKeyboardEvent(event
);
1758 void RenderWidgetHostViewAndroid::SendMouseEvent(
1759 const blink::WebMouseEvent
& event
) {
1761 host_
->ForwardMouseEvent(event
);
1764 void RenderWidgetHostViewAndroid::SendMouseWheelEvent(
1765 const blink::WebMouseWheelEvent
& event
) {
1767 host_
->ForwardWheelEvent(event
);
1770 void RenderWidgetHostViewAndroid::SendGestureEvent(
1771 const blink::WebGestureEvent
& event
) {
1772 // Sending a gesture that may trigger overscroll should resume the effect.
1773 if (overscroll_controller_
)
1774 overscroll_controller_
->Enable();
1777 host_
->ForwardGestureEventWithLatencyInfo(event
, CreateLatencyInfo(event
));
1780 void RenderWidgetHostViewAndroid::MoveCaret(const gfx::Point
& point
) {
1782 host_
->MoveCaret(point
);
1785 void RenderWidgetHostViewAndroid::DismissTextHandles() {
1786 if (selection_controller_
)
1787 selection_controller_
->HideAndDisallowShowingAutomatically();
1790 void RenderWidgetHostViewAndroid::SetTextHandlesTemporarilyHidden(bool hidden
) {
1791 if (selection_controller_
)
1792 selection_controller_
->SetTemporarilyHidden(hidden
);
1795 void RenderWidgetHostViewAndroid::OnShowingPastePopup(
1796 const gfx::PointF
& point
) {
1797 if (!selection_controller_
)
1800 // As the paste popup may be triggered *before* the bounds and editability
1801 // of the region have been updated, explicitly set the properties now.
1802 // TODO(jdduke): Remove this workaround when auxiliary paste popup
1803 // notifications are no longer required, crbug.com/398170.
1804 ui::SelectionBound insertion_bound
;
1805 insertion_bound
.set_type(ui::SelectionBound::CENTER
);
1806 insertion_bound
.set_visible(true);
1807 insertion_bound
.SetEdge(point
, point
);
1808 selection_controller_
->HideAndDisallowShowingAutomatically();
1809 selection_controller_
->OnSelectionEditable(true);
1810 selection_controller_
->OnSelectionEmpty(true);
1811 selection_controller_
->OnSelectionBoundsChanged(insertion_bound
,
1813 selection_controller_
->AllowShowingFromCurrentSelection();
1816 SkColor
RenderWidgetHostViewAndroid::GetCachedBackgroundColor() const {
1817 return cached_background_color_
;
1820 void RenderWidgetHostViewAndroid::DidOverscroll(
1821 const DidOverscrollParams
& params
) {
1822 if (!content_view_core_
|| !layer_
.get() || !is_showing_
)
1825 if (overscroll_controller_
)
1826 overscroll_controller_
->OnOverscrolled(params
);
1829 void RenderWidgetHostViewAndroid::DidStopFlinging() {
1830 if (content_view_core_
)
1831 content_view_core_
->DidStopFlinging();
1834 void RenderWidgetHostViewAndroid::SetContentViewCore(
1835 ContentViewCoreImpl
* content_view_core
) {
1837 StopObservingRootWindow();
1839 bool resize
= false;
1840 if (content_view_core
!= content_view_core_
) {
1841 overscroll_controller_
.reset();
1842 selection_controller_
.reset();
1843 ReleaseLocksOnSurface();
1847 content_view_core_
= content_view_core
;
1849 BrowserAccessibilityManager
* manager
= NULL
;
1851 manager
= host_
->GetRootBrowserAccessibilityManager();
1853 base::android::ScopedJavaLocalRef
<jobject
> obj
;
1854 if (content_view_core_
)
1855 obj
= content_view_core_
->GetJavaObject();
1856 manager
->ToBrowserAccessibilityManagerAndroid()->SetContentViewCore(obj
);
1861 if (!content_view_core_
)
1865 StartObservingRootWindow();
1870 if (!selection_controller_
)
1871 selection_controller_
= CreateSelectionController(this, content_view_core_
);
1873 if (!overscroll_controller_
&&
1874 content_view_core_
->GetWindowAndroid()->GetCompositor()) {
1875 overscroll_controller_
= CreateOverscrollController(content_view_core_
);
1879 void RenderWidgetHostViewAndroid::RunAckCallbacks(
1880 cc::SurfaceDrawStatus status
) {
1881 while (!ack_callbacks_
.empty()) {
1882 ack_callbacks_
.front().Run();
1883 ack_callbacks_
.pop();
1887 void RenderWidgetHostViewAndroid::OnGestureEvent(
1888 const ui::GestureEventData
& gesture
) {
1889 blink::WebGestureEvent web_gesture
=
1890 ui::CreateWebGestureEventFromGestureEventData(gesture
);
1891 // TODO(jdduke): Remove this workaround after Android fixes UiAutomator to
1892 // stop providing shift meta values to synthetic MotionEvents. This prevents
1893 // unintended shift+click interpretation of all accessibility clicks.
1894 // See crbug.com/443247.
1895 if (web_gesture
.type
== blink::WebInputEvent::GestureTap
&&
1896 web_gesture
.modifiers
== blink::WebInputEvent::ShiftKey
) {
1897 web_gesture
.modifiers
= 0;
1899 SendGestureEvent(web_gesture
);
1902 void RenderWidgetHostViewAndroid::OnCompositingDidCommit() {
1903 RunAckCallbacks(cc::SurfaceDrawStatus::DRAWN
);
1906 void RenderWidgetHostViewAndroid::OnRootWindowVisibilityChanged(bool visible
) {
1907 DCHECK(is_showing_
);
1911 bool hide_frontbuffer
= true;
1912 bool stop_observing_root_window
= false;
1913 HideInternal(hide_frontbuffer
, stop_observing_root_window
);
1917 void RenderWidgetHostViewAndroid::OnAttachCompositor() {
1918 DCHECK(content_view_core_
);
1919 if (!overscroll_controller_
)
1920 overscroll_controller_
= CreateOverscrollController(content_view_core_
);
1923 void RenderWidgetHostViewAndroid::OnDetachCompositor() {
1924 DCHECK(content_view_core_
);
1925 DCHECK(using_browser_compositor_
);
1926 RunAckCallbacks(cc::SurfaceDrawStatus::DRAW_SKIPPED
);
1927 overscroll_controller_
.reset();
1930 void RenderWidgetHostViewAndroid::OnVSync(base::TimeTicks frame_time
,
1931 base::TimeDelta vsync_period
) {
1932 TRACE_EVENT0("cc,benchmark", "RenderWidgetHostViewAndroid::OnVSync");
1933 if (!host_
|| host_
->is_hidden())
1936 if (outstanding_vsync_requests_
& FLUSH_INPUT
) {
1937 outstanding_vsync_requests_
&= ~FLUSH_INPUT
;
1938 host_
->FlushInput();
1941 if (outstanding_vsync_requests_
& BEGIN_FRAME
||
1942 outstanding_vsync_requests_
& PERSISTENT_BEGIN_FRAME
) {
1943 outstanding_vsync_requests_
&= ~BEGIN_FRAME
;
1944 SendBeginFrame(frame_time
, vsync_period
);
1947 // This allows for SendBeginFrame and FlushInput to modify
1948 // outstanding_vsync_requests.
1949 uint32 outstanding_vsync_requests
= outstanding_vsync_requests_
;
1950 outstanding_vsync_requests_
= 0;
1951 RequestVSyncUpdate(outstanding_vsync_requests
);
1954 void RenderWidgetHostViewAndroid::OnAnimate(base::TimeTicks begin_frame_time
) {
1955 if (Animate(begin_frame_time
))
1959 void RenderWidgetHostViewAndroid::OnActivityPaused() {
1960 TRACE_EVENT0("browser", "RenderWidgetHostViewAndroid::OnActivityPaused");
1961 DCHECK(is_showing_
);
1962 bool hide_frontbuffer
= false;
1963 bool stop_observing_root_window
= false;
1964 HideInternal(hide_frontbuffer
, stop_observing_root_window
);
1967 void RenderWidgetHostViewAndroid::OnActivityResumed() {
1968 TRACE_EVENT0("browser", "RenderWidgetHostViewAndroid::OnActivityResumed");
1969 DCHECK(is_showing_
);
1973 void RenderWidgetHostViewAndroid::OnLostResources() {
1974 ReleaseLocksOnSurface();
1976 DestroyDelegatedContent();
1977 DCHECK(ack_callbacks_
.empty());
1978 // We should not loose a frame if we have readback requests pending.
1979 DCHECK(readbacks_waiting_for_frame_
.empty());
1984 RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResultForDelegatedReadback(
1985 const gfx::Size
& dst_size_in_pixel
,
1986 const SkColorType color_type
,
1987 const base::TimeTicks
& start_time
,
1988 scoped_refptr
<cc::Layer
> readback_layer
,
1989 ReadbackRequestCallback
& callback
,
1990 scoped_ptr
<cc::CopyOutputResult
> result
) {
1991 readback_layer
->RemoveFromParent();
1992 PrepareTextureCopyOutputResult(
1993 dst_size_in_pixel
, color_type
, start_time
, callback
, result
.Pass());
1997 void RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResult(
1998 const gfx::Size
& dst_size_in_pixel
,
1999 const SkColorType color_type
,
2000 const base::TimeTicks
& start_time
,
2001 ReadbackRequestCallback
& callback
,
2002 scoped_ptr
<cc::CopyOutputResult
> result
) {
2003 base::ScopedClosureRunner
scoped_callback_runner(
2004 base::Bind(callback
, SkBitmap(), READBACK_FAILED
));
2006 "RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResult");
2008 if (!result
->HasTexture() || result
->IsEmpty() || result
->size().IsEmpty())
2011 gfx::Size output_size_in_pixel
;
2012 if (dst_size_in_pixel
.IsEmpty())
2013 output_size_in_pixel
= result
->size();
2015 output_size_in_pixel
= dst_size_in_pixel
;
2017 scoped_ptr
<SkBitmap
> bitmap(new SkBitmap
);
2018 if (!bitmap
->tryAllocPixels(SkImageInfo::Make(output_size_in_pixel
.width(),
2019 output_size_in_pixel
.height(),
2021 kOpaque_SkAlphaType
))) {
2025 GLHelper
* gl_helper
= GetPostReadbackGLHelper();
2026 if (!gl_helper
|| !gl_helper
->IsReadbackConfigSupported(color_type
))
2029 scoped_ptr
<SkAutoLockPixels
> bitmap_pixels_lock(
2030 new SkAutoLockPixels(*bitmap
));
2031 uint8
* pixels
= static_cast<uint8
*>(bitmap
->getPixels());
2033 cc::TextureMailbox texture_mailbox
;
2034 scoped_ptr
<cc::SingleReleaseCallback
> release_callback
;
2035 result
->TakeTexture(&texture_mailbox
, &release_callback
);
2036 DCHECK(texture_mailbox
.IsTexture());
2037 if (!texture_mailbox
.IsTexture())
2040 ignore_result(scoped_callback_runner
.Release());
2042 gl_helper
->CropScaleReadbackAndCleanMailbox(
2043 texture_mailbox
.mailbox(),
2044 texture_mailbox
.sync_point(),
2046 gfx::Rect(result
->size()),
2047 output_size_in_pixel
,
2050 base::Bind(&CopyFromCompositingSurfaceFinished
,
2052 base::Passed(&release_callback
),
2053 base::Passed(&bitmap
),
2055 base::Passed(&bitmap_pixels_lock
)),
2056 GLHelper::SCALER_QUALITY_GOOD
);
2059 SkColorType
RenderWidgetHostViewAndroid::PreferredReadbackFormat() {
2060 // Define the criteria here. If say the 16 texture readback is
2061 // supported we should go with that (this degrades quality)
2062 // or stick back to the default format.
2063 if (base::SysInfo::IsLowEndDevice()) {
2064 // TODO(sievers): Cannot use GLHelper here. Instead remove this API
2065 // and have CopyFromCompositingSurface() fall back to RGB8 if 565 was
2066 // requested but is not supported.
2067 GLHelper
* gl_helper
= GetPostReadbackGLHelper();
2068 if (gl_helper
&& gl_helper
->IsReadbackConfigSupported(kRGB_565_SkColorType
))
2069 return kRGB_565_SkColorType
;
2071 return kN32_SkColorType
;
2074 void RenderWidgetHostViewAndroid::OnStylusSelectBegin(float x0
,
2078 SelectBetweenCoordinates(gfx::PointF(x0
, y0
), gfx::PointF(x1
, y1
));
2081 void RenderWidgetHostViewAndroid::OnStylusSelectUpdate(float x
, float y
) {
2082 MoveRangeSelectionExtent(gfx::PointF(x
, y
));
2085 void RenderWidgetHostViewAndroid::OnStylusSelectEnd() {
2086 if (selection_controller_
)
2087 selection_controller_
->AllowShowingFromCurrentSelection();
2090 void RenderWidgetHostViewAndroid::OnStylusSelectTap(base::TimeTicks time
,
2093 // Treat the stylus tap as a long press, activating either a word selection or
2094 // context menu depending on the targetted content.
2095 blink::WebGestureEvent long_press
= WebGestureEventBuilder::Build(
2096 blink::WebInputEvent::GestureLongPress
,
2097 (time
- base::TimeTicks()).InSecondsF(), x
, y
);
2098 SendGestureEvent(long_press
);
2102 void RenderWidgetHostViewBase::GetDefaultScreenInfo(
2103 blink::WebScreenInfo
* results
) {
2104 const gfx::Display
& display
=
2105 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
2106 results
->rect
= display
.bounds();
2107 // TODO(husky): Remove any system controls from availableRect.
2108 results
->availableRect
= display
.work_area();
2109 results
->deviceScaleFactor
= display
.device_scale_factor();
2110 results
->orientationAngle
= display
.RotationAsDegree();
2111 results
->orientationType
=
2112 RenderWidgetHostViewBase::GetOrientationTypeForMobile(display
);
2113 gfx::DeviceDisplayInfo info
;
2114 results
->depth
= info
.GetBitsPerPixel();
2115 results
->depthPerComponent
= info
.GetBitsPerComponent();
2116 results
->isMonochrome
= (results
->depthPerComponent
== 0);
2119 } // namespace content