cc: Make scheduling be driven by vsync for android webview.
[chromium-blink-merge.git] / content / browser / renderer_host / render_widget_host_view_android.cc
blob318584e90469b20fb2afdfe7d6e68fbc543036fd
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"
92 namespace content {
94 namespace {
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,
104 cc::SurfaceId id,
105 cc::SurfaceSequence sequence) {
106 cc::Surface* surface = manager->GetSurfaceForId(id);
107 if (!surface) {
108 LOG(ERROR) << "Attempting to require callback on nonexistent surface";
109 return;
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()));
123 class GLHelperHolder
124 : public blink::WebGraphicsContext3D::WebGraphicsContextLostCallback {
125 public:
126 static GLHelperHolder* Create();
127 ~GLHelperHolder() override;
129 void Initialize();
131 // WebGraphicsContextLostCallback implementation.
132 virtual void onContextLost() override;
134 GLHelper* GetGLHelper() { return gl_helper_.get(); }
135 bool IsLost() { return !context_.get() || context_->isContextLost(); }
137 private:
138 GLHelperHolder();
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();
151 return holder;
154 GLHelperHolder::GLHelperHolder() {
157 GLHelperHolder::~GLHelperHolder() {
160 void GLHelperHolder::Initialize() {
161 context_ = CreateContext3D();
162 if (context_) {
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(
174 FROM_HERE,
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() *
197 kBytesPerPixel;
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(
209 0, // offscreen
210 url, gpu_channel_host.get(), attrs, lose_context_when_out_of_memory,
211 limits, nullptr));
212 if (context->InitializeOnCurrentThread()) {
213 context->traceBeginCHROMIUM(
214 "gpu_toplevel",
215 base::StringPrintf("CmdBufferImageTransportFactory-%p",
216 context.get()).c_str());
217 } else {
218 context.reset();
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,
246 bool result) {
247 TRACE_EVENT0(
248 "cc", "RenderWidgetHostViewAndroid::CopyFromCompositingSurfaceFinished");
249 bitmap_pixels_lock.reset();
250 uint32 sync_point = 0;
251 if (result) {
252 GLHelper* gl_helper = GetPostReadbackGLHelper();
253 if (gl_helper)
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),
277 return latency_info;
280 scoped_ptr<ui::TouchSelectionController> CreateSelectionController(
281 ui::TouchSelectionControllerClient* client,
282 ContentViewCore* content_view_core) {
283 DCHECK(client);
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(
289 client,
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();
299 DCHECK(window);
300 ui::WindowAndroidCompositor* compositor = window->GetCompositor();
301 DCHECK(compositor);
302 return make_scoped_ptr(new OverscrollControllerAndroid(
303 content_view_core->GetWebContents(),
304 compositor,
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);
314 return config;
317 ui::SelectionBound::Type ConvertSelectionBoundType(
318 cc::SelectionBoundType type) {
319 switch (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);
340 return ui_bound;
343 } // anonymous namespace
345 ReadbackRequest::ReadbackRequest(float scale,
346 SkColorType color_type,
347 gfx::Rect src_subrect,
348 ReadbackRequestCallback& result_callback)
349 : scale_(scale),
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(
362 uint32 output_id,
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())
374 ->OnLostResources();
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) {
414 bool handled = true;
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()
429 return handled;
432 void RenderWidgetHostViewAndroid::InitAsChild(gfx::NativeView parent_view) {
433 NOTIMPLEMENTED();
436 void RenderWidgetHostViewAndroid::InitAsPopup(
437 RenderWidgetHostView* parent_host_view, const gfx::Rect& pos) {
438 NOTIMPLEMENTED();
441 void RenderWidgetHostViewAndroid::InitAsFullscreen(
442 RenderWidgetHostView* reference_host_view) {
443 NOTIMPLEMENTED();
446 RenderWidgetHost*
447 RenderWidgetHostViewAndroid::GetRenderWidgetHost() const {
448 return host_;
451 void RenderWidgetHostViewAndroid::WasResized() {
452 host_->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(
474 float scale,
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);
480 return;
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));
488 return;
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);
500 gfx::Size dst_size(
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()
507 const {
508 scoped_refptr<cc::Layer> delegated_layer;
509 if (!surface_id_.is_null()) {
510 cc::SurfaceManager* manager = CompositorImpl::GetSurfaceManager();
511 DCHECK(manager);
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;
518 } else {
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_)
531 return false;
532 if (!layer_.get())
533 return false;
535 if (texture_size_in_layer_.IsEmpty())
536 return false;
537 // This tell us whether a valid frame has arrived or not.
538 if (!frame_evictor_->HasFrame())
539 return false;
541 return true;
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() {
559 NOTIMPLEMENTED();
560 return NULL;
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() {
571 host_->Focus();
572 host_->SetInputMethodActive(true);
573 if (overscroll_controller_)
574 overscroll_controller_->Enable();
577 void RenderWidgetHostViewAndroid::Blur() {
578 host_->SetInputMethodActive(false);
579 host_->Blur();
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() {
596 if (is_showing_)
597 return;
599 is_showing_ = true;
600 ShowInternal();
603 void RenderWidgetHostViewAndroid::Hide() {
604 if (!is_showing_)
605 return;
607 is_showing_ = false;
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());
623 DCHECK(host_);
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)
631 return;
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,
658 size_t start_offset,
659 size_t end_offset) {
660 if (text_surrounding_selection_callback_.is_null())
661 return;
662 text_surrounding_selection_callback_.Run(content, start_offset, end_offset);
663 text_surrounding_selection_callback_.Reset();
666 void RenderWidgetHostViewAndroid::OnShowUnhandledTapUIIfNeeded(int x_dip,
667 int y_dip) {
668 if (!content_view_core_)
669 return;
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())
674 return;
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);
681 return;
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_)
698 return gfx::Size();
700 return content_view_core_->GetPhysicalBackingSize();
703 bool RenderWidgetHostViewAndroid::DoTopControlsShrinkBlinkSize() const {
704 if (!content_view_core_)
705 return false;
707 // Whether or not Blink's viewport size should be shrunk by the height of the
708 // URL-bar.
709 return content_view_core_->DoTopControlsShrinkBlinkSize();
712 float RenderWidgetHostViewAndroid::GetTopControlsHeight() const {
713 if (!content_view_core_)
714 return 0.f;
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,
733 int flags) {
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
754 // this method.
755 base::ScopedClosureRunner ack_caller;
756 if (params.is_non_ime_change)
757 ack_caller.Reset(base::Bind(&SendImeEventAck, host_));
759 if (!IsShowing())
760 return;
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(
771 SkColor color) {
772 if (cached_background_color_ == color)
773 return;
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",
782 "enabled", enabled);
783 if (enabled)
784 RequestVSyncUpdate(PERSISTENT_BEGIN_FRAME);
785 else
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) {
805 if (!host_)
806 return false;
808 if (selection_controller_ &&
809 selection_controller_->WillHandleTouchEvent(event))
810 return true;
812 if (stylus_text_selector_.OnTouchEvent(event))
813 return true;
815 ui::FilteredGestureProvider::TouchHandlingResult result =
816 gesture_provider_.OnTouchEvent(event);
817 if (!result.succeeded)
818 return false;
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);
831 return true;
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(
861 bool enabled) {
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) {
883 Destroy();
886 void RenderWidgetHostViewAndroid::Destroy() {
887 RemoveLayers();
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.
898 host_ = NULL;
900 delete this;
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,
909 size_t offset,
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_)
917 return;
918 if (range.is_empty()) {
919 content_view_core_->OnSelectionChanged("");
920 return;
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.";
930 return;
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);
957 return;
959 base::TimeTicks start_time = base::TimeTicks::Now();
960 if (using_browser_compositor_ && !IsSurfaceAvailableForCopy()) {
961 callback.Run(SkBitmap(), READBACK_NOT_SUPPORTED);
962 return;
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,
974 color_type);
975 UMA_HISTOGRAM_TIMES("Compositing.CopyFromSurfaceTimeSynchronous",
976 base::TimeTicks::Now() - start_time);
977 return;
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();
986 DCHECK(compositor);
987 DCHECK(frame_provider_.get() || !surface_id_.is_null());
988 scoped_refptr<cc::Layer> layer = CreateDelegatedLayer();
989 DCHECK(layer);
990 layer->SetHideLayerAndSubtree(true);
991 compositor->AttachLayerForReadback(layer);
993 readback_layer = layer;
994 request = cc::CopyOutputRequest::CreateRequest(
995 base::Bind(&RenderWidgetHostViewAndroid::
996 PrepareTextureCopyOutputResultForDelegatedReadback,
997 dst_size_in_pixel,
998 color_type,
999 start_time,
1000 readback_layer,
1001 callback));
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) {
1011 NOTIMPLEMENTED();
1012 callback.Run(false);
1015 bool RenderWidgetHostViewAndroid::CanCopyToVideoFrame() const {
1016 return false;
1019 void RenderWidgetHostViewAndroid::ShowDisambiguationPopup(
1020 const gfx::Rect& rect_pixels, const SkBitmap& zoomed_bitmap) {
1021 if (!content_view_core_)
1022 return;
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) {
1035 DCHECK(host_);
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) {
1047 DCHECK(host_);
1048 cc::CompositorFrameAck ack;
1049 if (!surface_returned_resources_.empty()) {
1050 ack.resources.swap(surface_returned_resources_);
1051 } else {
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())
1063 return;
1064 SendReturnedDelegatedResources(last_output_surface_id_);
1067 void RenderWidgetHostViewAndroid::ReturnResources(
1068 const cc::ReturnedResourceArray& resources) {
1069 if (resources.empty())
1070 return;
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() {
1078 RemoveLayers();
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();
1085 layer_ = NULL;
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_)
1094 return;
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();
1114 if (manager) {
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_) {
1121 RemoveLayers();
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();
1128 DCHECK(layer_);
1130 current_surface_size_ = texture_size_in_layer_;
1131 AttachLayers();
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(),
1141 ack_callback);
1142 } else {
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()) {
1149 RemoveLayers();
1150 frame_provider_ = new cc::DelegatedFrameProvider(
1151 resource_collection_.get(), frame_data.Pass());
1152 layer_ = cc::DelegatedRendererLayer::Create(frame_provider_);
1153 AttachLayers();
1154 } else {
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;
1174 if (!has_content) {
1175 DestroyDelegatedContent();
1176 } else {
1177 SubmitFrame(frame_data.Pass());
1180 if (layer_.get()) {
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(),
1190 output_surface_id);
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";
1215 return;
1218 if (locks_on_frame_count_ > 0) {
1219 DCHECK(HasValidFrame());
1220 RetainFrame(output_surface_id, frame.Pass());
1221 return;
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_)
1289 return;
1291 // This is a subset of OnSwapCompositorFrame() used in the synchronous
1292 // compositor flow.
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,
1304 base::Bind(
1305 &RenderFrameDevToolsAgentHost::SynchronousSwapCompositorFrame,
1306 static_cast<RenderFrameDevToolsAgentHost*>(dtah.get()),
1307 frame_metadata));
1311 void RenderWidgetHostViewAndroid::SetOverlayVideoMode(bool enabled) {
1312 if (layer_.get())
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_;
1380 else
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;
1386 else
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());
1394 if (!compositor) {
1395 callback.Run(SkBitmap(), READBACK_FAILED);
1396 return;
1399 SkBitmap bitmap;
1400 bitmap.allocPixels(SkImageInfo::Make(output_width,
1401 output_height,
1402 color_type,
1403 kPremul_SkAlphaType));
1404 SkCanvas canvas(bitmap);
1405 canvas.scale(
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_)
1418 return;
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())
1460 return;
1462 if (layer_.get())
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())
1492 return;
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
1504 // utilization.
1505 host_->WasHidden();
1508 void RenderWidgetHostViewAndroid::AttachLayers() {
1509 if (!content_view_core_)
1510 return;
1511 if (!layer_.get())
1512 return;
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_)
1522 return;
1524 if (!layer_.get())
1525 return;
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())
1539 return;
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_)
1552 return;
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_);
1566 return;
1569 if (!observing_root_window_)
1570 return;
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)));
1591 } else {
1592 SynchronousCompositorImpl* compositor = SynchronousCompositorImpl::FromID(
1593 host_->GetProcess()->GetID(), host_->GetRoutingID());
1594 if (compositor) {
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() {
1616 if (layer_.get())
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) {
1626 NOTREACHED();
1627 return false;
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();
1648 return handle;
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();
1673 break;
1674 case blink::WebInputEvent::GestureTap:
1675 selection_controller_->OnTapEvent();
1676 break;
1677 default:
1678 break;
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;
1693 if (!host_)
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))
1702 shim->Send(
1703 new AcceleratedSurfaceMsg_WakeUpGpu(accelerated_surface_route_id_));
1706 SynchronousCompositorImpl* compositor =
1707 SynchronousCompositorImpl::FromID(host_->GetProcess()->GetID(),
1708 host_->GetRoutingID());
1709 if (compositor)
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())
1730 return NULL;
1732 base::android::ScopedJavaLocalRef<jobject> obj;
1733 if (content_view_core_)
1734 obj = content_view_core_->GetJavaObject();
1735 return new BrowserAccessibilityManagerAndroid(
1736 obj,
1737 BrowserAccessibilityManagerAndroid::GetEmptyDocument(),
1738 delegate);
1741 bool RenderWidgetHostViewAndroid::LockMouse() {
1742 NOTIMPLEMENTED();
1743 return false;
1746 void RenderWidgetHostViewAndroid::UnlockMouse() {
1747 NOTIMPLEMENTED();
1750 // Methods called from the host to the render
1752 void RenderWidgetHostViewAndroid::SendKeyEvent(
1753 const NativeWebKeyboardEvent& event) {
1754 if (host_)
1755 host_->ForwardKeyboardEvent(event);
1758 void RenderWidgetHostViewAndroid::SendMouseEvent(
1759 const blink::WebMouseEvent& event) {
1760 if (host_)
1761 host_->ForwardMouseEvent(event);
1764 void RenderWidgetHostViewAndroid::SendMouseWheelEvent(
1765 const blink::WebMouseWheelEvent& event) {
1766 if (host_)
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();
1776 if (host_)
1777 host_->ForwardGestureEventWithLatencyInfo(event, CreateLatencyInfo(event));
1780 void RenderWidgetHostViewAndroid::MoveCaret(const gfx::Point& point) {
1781 if (host_)
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_)
1798 return;
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,
1812 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_)
1823 return;
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) {
1836 RemoveLayers();
1837 StopObservingRootWindow();
1839 bool resize = false;
1840 if (content_view_core != content_view_core_) {
1841 overscroll_controller_.reset();
1842 selection_controller_.reset();
1843 ReleaseLocksOnSurface();
1844 resize = true;
1847 content_view_core_ = content_view_core;
1849 BrowserAccessibilityManager* manager = NULL;
1850 if (host_)
1851 manager = host_->GetRootBrowserAccessibilityManager();
1852 if (manager) {
1853 base::android::ScopedJavaLocalRef<jobject> obj;
1854 if (content_view_core_)
1855 obj = content_view_core_->GetJavaObject();
1856 manager->ToBrowserAccessibilityManagerAndroid()->SetContentViewCore(obj);
1859 AttachLayers();
1861 if (!content_view_core_)
1862 return;
1864 if (is_showing_)
1865 StartObservingRootWindow();
1867 if (resize)
1868 WasResized();
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_);
1908 if (visible) {
1909 ShowInternal();
1910 } else {
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())
1934 return;
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))
1956 SetNeedsAnimate();
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_);
1970 ShowInternal();
1973 void RenderWidgetHostViewAndroid::OnLostResources() {
1974 ReleaseLocksOnSurface();
1975 if (layer_.get())
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());
1982 // static
1983 void
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());
1996 // static
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));
2005 TRACE_EVENT0("cc",
2006 "RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResult");
2008 if (!result->HasTexture() || result->IsEmpty() || result->size().IsEmpty())
2009 return;
2011 gfx::Size output_size_in_pixel;
2012 if (dst_size_in_pixel.IsEmpty())
2013 output_size_in_pixel = result->size();
2014 else
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(),
2020 color_type,
2021 kOpaque_SkAlphaType))) {
2022 return;
2025 GLHelper* gl_helper = GetPostReadbackGLHelper();
2026 if (!gl_helper || !gl_helper->IsReadbackConfigSupported(color_type))
2027 return;
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())
2038 return;
2040 ignore_result(scoped_callback_runner.Release());
2042 gl_helper->CropScaleReadbackAndCleanMailbox(
2043 texture_mailbox.mailbox(),
2044 texture_mailbox.sync_point(),
2045 result->size(),
2046 gfx::Rect(result->size()),
2047 output_size_in_pixel,
2048 pixels,
2049 color_type,
2050 base::Bind(&CopyFromCompositingSurfaceFinished,
2051 callback,
2052 base::Passed(&release_callback),
2053 base::Passed(&bitmap),
2054 start_time,
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,
2075 float y0,
2076 float x1,
2077 float y1) {
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,
2091 float x,
2092 float y) {
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);
2101 // static
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