Supervised user whitelists: Cleanup
[chromium-blink-merge.git] / content / browser / renderer_host / render_widget_host_view_android.cc
blob3cf0e80fb7e2aed31f64fff4acad2fc7ebbe4209
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 scoped_ptr<ui::TouchSelectionController> CreateSelectionController(
265 ui::TouchSelectionControllerClient* client,
266 ContentViewCore* content_view_core) {
267 DCHECK(client);
268 DCHECK(content_view_core);
269 int tap_timeout_ms = gfx::ViewConfiguration::GetTapTimeoutInMs();
270 int touch_slop_pixels = gfx::ViewConfiguration::GetTouchSlopInPixels();
271 bool show_on_tap_for_empty_editable = false;
272 return make_scoped_ptr(new ui::TouchSelectionController(
273 client,
274 base::TimeDelta::FromMilliseconds(tap_timeout_ms),
275 touch_slop_pixels / content_view_core->GetDpiScale(),
276 show_on_tap_for_empty_editable));
279 scoped_ptr<OverscrollControllerAndroid> CreateOverscrollController(
280 ContentViewCoreImpl* content_view_core) {
281 return make_scoped_ptr(new OverscrollControllerAndroid(content_view_core));
284 ui::GestureProvider::Config CreateGestureProviderConfig() {
285 ui::GestureProvider::Config config = ui::GetGestureProviderConfig(
286 ui::GestureProviderConfigType::CURRENT_PLATFORM);
287 config.disable_click_delay =
288 base::CommandLine::ForCurrentProcess()->HasSwitch(
289 switches::kDisableClickDelay);
290 return config;
293 ui::SelectionBound::Type ConvertSelectionBoundType(
294 cc::SelectionBoundType type) {
295 switch (type) {
296 case cc::SELECTION_BOUND_LEFT:
297 return ui::SelectionBound::LEFT;
298 case cc::SELECTION_BOUND_RIGHT:
299 return ui::SelectionBound::RIGHT;
300 case cc::SELECTION_BOUND_CENTER:
301 return ui::SelectionBound::CENTER;
302 case cc::SELECTION_BOUND_EMPTY:
303 return ui::SelectionBound::EMPTY;
305 NOTREACHED() << "Unknown selection bound type";
306 return ui::SelectionBound::EMPTY;
309 ui::SelectionBound ConvertSelectionBound(
310 const cc::ViewportSelectionBound& bound) {
311 ui::SelectionBound ui_bound;
312 ui_bound.set_type(ConvertSelectionBoundType(bound.type));
313 ui_bound.set_visible(bound.visible);
314 if (ui_bound.type() != ui::SelectionBound::EMPTY)
315 ui_bound.SetEdge(bound.edge_top, bound.edge_bottom);
316 return ui_bound;
319 gfx::RectF GetSelectionRect(const ui::TouchSelectionController& controller) {
320 gfx::RectF rect = controller.GetRectBetweenBounds();
321 if (rect.IsEmpty())
322 return rect;
324 rect.Union(controller.GetStartHandleRect());
325 rect.Union(controller.GetEndHandleRect());
326 return rect;
329 } // anonymous namespace
331 ReadbackRequest::ReadbackRequest(float scale,
332 SkColorType color_type,
333 gfx::Rect src_subrect,
334 ReadbackRequestCallback& result_callback)
335 : scale_(scale),
336 color_type_(color_type),
337 src_subrect_(src_subrect),
338 result_callback_(result_callback) {
341 ReadbackRequest::ReadbackRequest() {
344 ReadbackRequest::~ReadbackRequest() {
347 RenderWidgetHostViewAndroid::LastFrameInfo::LastFrameInfo(
348 uint32 output_id,
349 scoped_ptr<cc::CompositorFrame> output_frame)
350 : output_surface_id(output_id), frame(output_frame.Pass()) {}
352 RenderWidgetHostViewAndroid::LastFrameInfo::~LastFrameInfo() {}
354 void RenderWidgetHostViewAndroid::OnContextLost() {
355 scoped_ptr<RenderWidgetHostIterator> widgets(
356 RenderWidgetHostImpl::GetAllRenderWidgetHosts());
357 while (RenderWidgetHost* widget = widgets->GetNextHost()) {
358 if (widget->GetView()) {
359 static_cast<RenderWidgetHostViewAndroid*>(widget->GetView())
360 ->OnLostResources();
365 RenderWidgetHostViewAndroid::RenderWidgetHostViewAndroid(
366 RenderWidgetHostImpl* widget_host,
367 ContentViewCoreImpl* content_view_core)
368 : host_(widget_host),
369 outstanding_vsync_requests_(0),
370 is_showing_(!widget_host->is_hidden()),
371 content_view_core_(NULL),
372 ime_adapter_android_(this),
373 cached_background_color_(SK_ColorWHITE),
374 last_output_surface_id_(kUndefinedOutputSurfaceId),
375 gesture_provider_(CreateGestureProviderConfig(), this),
376 stylus_text_selector_(this),
377 accelerated_surface_route_id_(0),
378 using_browser_compositor_(CompositorImpl::IsInitialized()),
379 frame_evictor_(new DelegatedFrameEvictor(this)),
380 locks_on_frame_count_(0),
381 observing_root_window_(false),
382 weak_ptr_factory_(this) {
383 host_->SetView(this);
384 SetContentViewCore(content_view_core);
387 RenderWidgetHostViewAndroid::~RenderWidgetHostViewAndroid() {
388 SetContentViewCore(NULL);
389 DCHECK(ack_callbacks_.empty());
390 DCHECK(readbacks_waiting_for_frame_.empty());
391 if (resource_collection_.get())
392 resource_collection_->SetClient(NULL);
393 DCHECK(!surface_factory_);
394 DCHECK(surface_id_.is_null());
398 bool RenderWidgetHostViewAndroid::OnMessageReceived(
399 const IPC::Message& message) {
400 bool handled = true;
401 IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewAndroid, message)
402 IPC_MESSAGE_HANDLER(ViewHostMsg_StartContentIntent, OnStartContentIntent)
403 IPC_MESSAGE_HANDLER(ViewHostMsg_DidChangeBodyBackgroundColor,
404 OnDidChangeBodyBackgroundColor)
405 IPC_MESSAGE_HANDLER(ViewHostMsg_SetNeedsBeginFrames,
406 OnSetNeedsBeginFrames)
407 IPC_MESSAGE_HANDLER(ViewHostMsg_TextInputStateChanged,
408 OnTextInputStateChanged)
409 IPC_MESSAGE_HANDLER(ViewHostMsg_SmartClipDataExtracted,
410 OnSmartClipDataExtracted)
411 IPC_MESSAGE_HANDLER(ViewHostMsg_ShowUnhandledTapUIIfNeeded,
412 OnShowUnhandledTapUIIfNeeded)
413 IPC_MESSAGE_UNHANDLED(handled = false)
414 IPC_END_MESSAGE_MAP()
415 return handled;
418 void RenderWidgetHostViewAndroid::InitAsChild(gfx::NativeView parent_view) {
419 NOTIMPLEMENTED();
422 void RenderWidgetHostViewAndroid::InitAsPopup(
423 RenderWidgetHostView* parent_host_view, const gfx::Rect& pos) {
424 NOTIMPLEMENTED();
427 void RenderWidgetHostViewAndroid::InitAsFullscreen(
428 RenderWidgetHostView* reference_host_view) {
429 NOTIMPLEMENTED();
432 RenderWidgetHost*
433 RenderWidgetHostViewAndroid::GetRenderWidgetHost() const {
434 return host_;
437 void RenderWidgetHostViewAndroid::WasResized() {
438 host_->WasResized();
441 void RenderWidgetHostViewAndroid::SetSize(const gfx::Size& size) {
442 // Ignore the given size as only the Java code has the power to
443 // resize the view on Android.
444 default_size_ = size;
447 void RenderWidgetHostViewAndroid::SetBounds(const gfx::Rect& rect) {
448 SetSize(rect.size());
451 void RenderWidgetHostViewAndroid::AbortPendingReadbackRequests() {
452 while (!readbacks_waiting_for_frame_.empty()) {
453 ReadbackRequest& readback_request = readbacks_waiting_for_frame_.front();
454 readback_request.GetResultCallback().Run(SkBitmap(), READBACK_FAILED);
455 readbacks_waiting_for_frame_.pop();
459 void RenderWidgetHostViewAndroid::GetScaledContentBitmap(
460 float scale,
461 SkColorType color_type,
462 gfx::Rect src_subrect,
463 ReadbackRequestCallback& result_callback) {
464 if (!host_ || host_->is_hidden()) {
465 result_callback.Run(SkBitmap(), READBACK_NOT_SUPPORTED);
466 return;
468 if (!IsSurfaceAvailableForCopy()) {
469 // The view is visible, probably the frame has not yet arrived.
470 // Just add the ReadbackRequest to queue and wait for frame arrival
471 // to get this request processed.
472 readbacks_waiting_for_frame_.push(
473 ReadbackRequest(scale, color_type, src_subrect, result_callback));
474 return;
477 gfx::Size bounds = layer_->bounds();
478 if (src_subrect.IsEmpty())
479 src_subrect = gfx::Rect(bounds);
480 DCHECK_LE(src_subrect.width() + src_subrect.x(), bounds.width());
481 DCHECK_LE(src_subrect.height() + src_subrect.y(), bounds.height());
482 const gfx::Display& display =
483 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
484 float device_scale_factor = display.device_scale_factor();
485 DCHECK_GT(device_scale_factor, 0);
486 gfx::Size dst_size(
487 gfx::ToCeiledSize(gfx::ScaleSize(bounds, scale / device_scale_factor)));
488 CopyFromCompositingSurface(
489 src_subrect, dst_size, result_callback, color_type);
492 scoped_refptr<cc::Layer> RenderWidgetHostViewAndroid::CreateDelegatedLayer()
493 const {
494 scoped_refptr<cc::Layer> delegated_layer;
495 if (!surface_id_.is_null()) {
496 cc::SurfaceManager* manager = CompositorImpl::GetSurfaceManager();
497 DCHECK(manager);
498 // manager must outlive compositors using it.
499 scoped_refptr<cc::SurfaceLayer> surface_layer = cc::SurfaceLayer::Create(
500 base::Bind(&SatisfyCallback, base::Unretained(manager)),
501 base::Bind(&RequireCallback, base::Unretained(manager)));
502 surface_layer->SetSurfaceId(surface_id_, 1.f, texture_size_in_layer_);
503 delegated_layer = surface_layer;
504 } else {
505 DCHECK(frame_provider_.get());
506 delegated_layer = cc::DelegatedRendererLayer::Create(frame_provider_);
508 delegated_layer->SetBounds(content_size_in_layer_);
509 delegated_layer->SetIsDrawable(true);
510 delegated_layer->SetContentsOpaque(true);
512 return delegated_layer;
515 bool RenderWidgetHostViewAndroid::HasValidFrame() const {
516 if (!content_view_core_)
517 return false;
518 if (!layer_.get())
519 return false;
521 if (texture_size_in_layer_.IsEmpty())
522 return false;
523 // This tell us whether a valid frame has arrived or not.
524 if (!frame_evictor_->HasFrame())
525 return false;
527 return true;
530 gfx::Vector2dF RenderWidgetHostViewAndroid::GetLastScrollOffset() const {
531 return last_scroll_offset_;
534 gfx::NativeView RenderWidgetHostViewAndroid::GetNativeView() const {
535 return content_view_core_->GetViewAndroid();
538 gfx::NativeViewId RenderWidgetHostViewAndroid::GetNativeViewId() const {
539 return reinterpret_cast<gfx::NativeViewId>(
540 const_cast<RenderWidgetHostViewAndroid*>(this));
543 gfx::NativeViewAccessible
544 RenderWidgetHostViewAndroid::GetNativeViewAccessible() {
545 NOTIMPLEMENTED();
546 return NULL;
549 void RenderWidgetHostViewAndroid::MovePluginWindows(
550 const std::vector<WebPluginGeometry>& moves) {
551 // We don't have plugin windows on Android. Do nothing. Note: this is called
552 // from RenderWidgetHost::OnUpdateRect which is itself invoked while
553 // processing the corresponding message from Renderer.
556 void RenderWidgetHostViewAndroid::Focus() {
557 host_->Focus();
558 host_->SetInputMethodActive(true);
559 if (overscroll_controller_)
560 overscroll_controller_->Enable();
563 void RenderWidgetHostViewAndroid::Blur() {
564 host_->SetInputMethodActive(false);
565 host_->Blur();
566 if (overscroll_controller_)
567 overscroll_controller_->Disable();
570 bool RenderWidgetHostViewAndroid::HasFocus() const {
571 if (!content_view_core_)
572 return false; // ContentViewCore not created yet.
574 return content_view_core_->HasFocus();
577 bool RenderWidgetHostViewAndroid::IsSurfaceAvailableForCopy() const {
578 return HasValidFrame();
581 void RenderWidgetHostViewAndroid::Show() {
582 if (is_showing_)
583 return;
585 is_showing_ = true;
586 ShowInternal();
589 void RenderWidgetHostViewAndroid::Hide() {
590 if (!is_showing_)
591 return;
593 is_showing_ = false;
595 bool hide_frontbuffer = true;
596 bool stop_observing_root_window = true;
597 HideInternal(hide_frontbuffer, stop_observing_root_window);
600 bool RenderWidgetHostViewAndroid::IsShowing() {
601 // ContentViewCoreImpl represents the native side of the Java
602 // ContentViewCore. It being NULL means that it is not attached
603 // to the View system yet, so we treat this RWHVA as hidden.
604 return is_showing_ && content_view_core_;
607 void RenderWidgetHostViewAndroid::LockCompositingSurface() {
608 DCHECK(HasValidFrame());
609 DCHECK(host_);
610 DCHECK(frame_evictor_->HasFrame());
611 frame_evictor_->LockFrame();
612 locks_on_frame_count_++;
615 void RenderWidgetHostViewAndroid::UnlockCompositingSurface() {
616 if (!frame_evictor_->HasFrame() || locks_on_frame_count_ == 0)
617 return;
619 DCHECK(HasValidFrame());
620 frame_evictor_->UnlockFrame();
621 locks_on_frame_count_--;
623 if (locks_on_frame_count_ == 0) {
624 if (last_frame_info_) {
625 InternalSwapCompositorFrame(last_frame_info_->output_surface_id,
626 last_frame_info_->frame.Pass());
627 last_frame_info_.reset();
630 if (!is_showing_ && layer_.get())
631 layer_->SetHideLayerAndSubtree(true);
635 void RenderWidgetHostViewAndroid::SetTextSurroundingSelectionCallback(
636 const TextSurroundingSelectionCallback& callback) {
637 // Only one outstanding request is allowed at any given time.
638 DCHECK(!callback.is_null());
639 text_surrounding_selection_callback_ = callback;
642 void RenderWidgetHostViewAndroid::OnTextSurroundingSelectionResponse(
643 const base::string16& content,
644 size_t start_offset,
645 size_t end_offset) {
646 if (text_surrounding_selection_callback_.is_null())
647 return;
648 text_surrounding_selection_callback_.Run(content, start_offset, end_offset);
649 text_surrounding_selection_callback_.Reset();
652 void RenderWidgetHostViewAndroid::OnShowUnhandledTapUIIfNeeded(int x_dip,
653 int y_dip) {
654 if (!content_view_core_)
655 return;
656 // Validate the coordinates are within the viewport.
657 gfx::Size viewport_size = content_view_core_->GetViewportSizeDip();
658 if (x_dip < 0 || x_dip > viewport_size.width() ||
659 y_dip < 0 || y_dip > viewport_size.height())
660 return;
661 content_view_core_->OnShowUnhandledTapUIIfNeeded(x_dip, y_dip);
664 void RenderWidgetHostViewAndroid::ReleaseLocksOnSurface() {
665 if (!frame_evictor_->HasFrame()) {
666 DCHECK_EQ(locks_on_frame_count_, 0u);
667 return;
669 while (locks_on_frame_count_ > 0) {
670 UnlockCompositingSurface();
672 RunAckCallbacks(cc::SurfaceDrawStatus::DRAW_SKIPPED);
675 gfx::Rect RenderWidgetHostViewAndroid::GetViewBounds() const {
676 if (!content_view_core_)
677 return gfx::Rect(default_size_);
679 return gfx::Rect(content_view_core_->GetViewSize());
682 gfx::Size RenderWidgetHostViewAndroid::GetPhysicalBackingSize() const {
683 if (!content_view_core_)
684 return gfx::Size();
686 return content_view_core_->GetPhysicalBackingSize();
689 bool RenderWidgetHostViewAndroid::DoTopControlsShrinkBlinkSize() const {
690 if (!content_view_core_)
691 return false;
693 // Whether or not Blink's viewport size should be shrunk by the height of the
694 // URL-bar.
695 return content_view_core_->DoTopControlsShrinkBlinkSize();
698 float RenderWidgetHostViewAndroid::GetTopControlsHeight() const {
699 if (!content_view_core_)
700 return 0.f;
702 // The height of the top controls.
703 return content_view_core_->GetTopControlsHeightDip();
706 void RenderWidgetHostViewAndroid::UpdateCursor(const WebCursor& cursor) {
707 // There are no cursors on Android.
710 void RenderWidgetHostViewAndroid::SetIsLoading(bool is_loading) {
711 // Do nothing. The UI notification is handled through ContentViewClient which
712 // is TabContentsDelegate.
715 void RenderWidgetHostViewAndroid::TextInputTypeChanged(
716 ui::TextInputType type,
717 ui::TextInputMode input_mode,
718 bool can_compose_inline,
719 int flags) {
720 // Unused on Android, which uses OnTextInputChanged instead.
723 long RenderWidgetHostViewAndroid::GetNativeImeAdapter() {
724 return reinterpret_cast<intptr_t>(&ime_adapter_android_);
727 void RenderWidgetHostViewAndroid::OnTextInputStateChanged(
728 const ViewHostMsg_TextInputState_Params& params) {
729 // If the change is not originated from IME (e.g. Javascript, autofill),
730 // send back the renderer an acknowledgement, regardless of how we exit from
731 // this method.
732 base::ScopedClosureRunner ack_caller;
733 if (params.is_non_ime_change)
734 ack_caller.Reset(base::Bind(&SendImeEventAck, host_));
736 if (!IsShowing())
737 return;
739 content_view_core_->UpdateImeAdapter(
740 GetNativeImeAdapter(),
741 static_cast<int>(params.type), params.flags,
742 params.value, params.selection_start, params.selection_end,
743 params.composition_start, params.composition_end,
744 params.show_ime_if_needed, params.is_non_ime_change);
747 void RenderWidgetHostViewAndroid::OnDidChangeBodyBackgroundColor(
748 SkColor color) {
749 if (cached_background_color_ == color)
750 return;
752 cached_background_color_ = color;
753 if (content_view_core_)
754 content_view_core_->OnBackgroundColorChanged(color);
757 void RenderWidgetHostViewAndroid::OnSetNeedsBeginFrames(bool enabled) {
758 TRACE_EVENT1("cc", "RenderWidgetHostViewAndroid::OnSetNeedsBeginFrames",
759 "enabled", enabled);
760 if (enabled)
761 RequestVSyncUpdate(PERSISTENT_BEGIN_FRAME);
762 else
763 outstanding_vsync_requests_ &= ~PERSISTENT_BEGIN_FRAME;
766 void RenderWidgetHostViewAndroid::OnStartContentIntent(
767 const GURL& content_url) {
768 if (content_view_core_)
769 content_view_core_->StartContentIntent(content_url);
772 void RenderWidgetHostViewAndroid::OnSmartClipDataExtracted(
773 const base::string16& text,
774 const base::string16& html,
775 const gfx::Rect rect) {
776 if (content_view_core_)
777 content_view_core_->OnSmartClipDataExtracted(text, html, rect);
780 bool RenderWidgetHostViewAndroid::OnTouchEvent(
781 const ui::MotionEvent& event) {
782 if (!host_)
783 return false;
785 if (selection_controller_ &&
786 selection_controller_->WillHandleTouchEvent(event))
787 return true;
789 if (stylus_text_selector_.OnTouchEvent(event))
790 return true;
792 ui::FilteredGestureProvider::TouchHandlingResult result =
793 gesture_provider_.OnTouchEvent(event);
794 if (!result.succeeded)
795 return false;
797 blink::WebTouchEvent web_event =
798 ui::CreateWebTouchEventFromMotionEvent(event, result.did_generate_scroll);
799 host_->ForwardTouchEventWithLatencyInfo(web_event, ui::LatencyInfo());
801 // Send a proactive BeginFrame on the next vsync to reduce latency.
802 // This is good enough as long as the first touch event has Begin semantics
803 // and the actual scroll happens on the next vsync.
804 if (observing_root_window_)
805 RequestVSyncUpdate(BEGIN_FRAME);
807 return true;
810 bool RenderWidgetHostViewAndroid::OnTouchHandleEvent(
811 const ui::MotionEvent& event) {
812 return selection_controller_ &&
813 selection_controller_->WillHandleTouchEvent(event);
816 void RenderWidgetHostViewAndroid::ResetGestureDetection() {
817 const ui::MotionEvent* current_down_event =
818 gesture_provider_.GetCurrentDownEvent();
819 if (current_down_event) {
820 scoped_ptr<ui::MotionEvent> cancel_event = current_down_event->Cancel();
821 OnTouchEvent(*cancel_event);
824 // A hard reset ensures prevention of any timer-based events.
825 gesture_provider_.ResetDetection();
828 void RenderWidgetHostViewAndroid::OnDidNavigateMainFrameToNewPage() {
829 ResetGestureDetection();
832 void RenderWidgetHostViewAndroid::SetDoubleTapSupportEnabled(bool enabled) {
833 gesture_provider_.SetDoubleTapSupportForPlatformEnabled(enabled);
836 void RenderWidgetHostViewAndroid::SetMultiTouchZoomSupportEnabled(
837 bool enabled) {
838 gesture_provider_.SetMultiTouchZoomSupportEnabled(enabled);
841 void RenderWidgetHostViewAndroid::ImeCancelComposition() {
842 ime_adapter_android_.CancelComposition();
845 void RenderWidgetHostViewAndroid::ImeCompositionRangeChanged(
846 const gfx::Range& range,
847 const std::vector<gfx::Rect>& character_bounds) {
848 // TODO(yukawa): Implement this.
851 void RenderWidgetHostViewAndroid::FocusedNodeChanged(bool is_editable_node) {
852 ime_adapter_android_.FocusedNodeChanged(is_editable_node);
855 void RenderWidgetHostViewAndroid::RenderProcessGone(
856 base::TerminationStatus status, int error_code) {
857 Destroy();
860 void RenderWidgetHostViewAndroid::Destroy() {
861 RemoveLayers();
862 SetContentViewCore(NULL);
864 if (!surface_id_.is_null()) {
865 DCHECK(surface_factory_.get());
866 surface_factory_->Destroy(surface_id_);
867 surface_id_ = cc::SurfaceId();
869 surface_factory_.reset();
871 // The RenderWidgetHost's destruction led here, so don't call it.
872 host_ = NULL;
874 delete this;
877 void RenderWidgetHostViewAndroid::SetTooltipText(
878 const base::string16& tooltip_text) {
879 // Tooltips don't makes sense on Android.
882 void RenderWidgetHostViewAndroid::SelectionChanged(const base::string16& text,
883 size_t offset,
884 const gfx::Range& range) {
885 RenderWidgetHostViewBase::SelectionChanged(text, offset, range);
887 if (!content_view_core_)
888 return;
889 if (range.is_empty()) {
890 content_view_core_->OnSelectionChanged("");
891 return;
894 DCHECK(!text.empty());
895 size_t pos = range.GetMin() - offset;
896 size_t n = range.length();
898 DCHECK(pos + n <= text.length()) << "The text can not fully cover range.";
899 if (pos >= text.length()) {
900 NOTREACHED() << "The text can not cover range.";
901 return;
904 std::string utf8_selection = base::UTF16ToUTF8(text.substr(pos, n));
906 content_view_core_->OnSelectionChanged(utf8_selection);
909 void RenderWidgetHostViewAndroid::SelectionBoundsChanged(
910 const ViewHostMsg_SelectionBounds_Params& params) {
911 NOTREACHED() << "Selection bounds should be routed through the compositor.";
914 void RenderWidgetHostViewAndroid::SetBackgroundColor(SkColor color) {
915 RenderWidgetHostViewBase::SetBackgroundColor(color);
916 host_->SetBackgroundOpaque(GetBackgroundOpaque());
917 OnDidChangeBodyBackgroundColor(color);
920 void RenderWidgetHostViewAndroid::CopyFromCompositingSurface(
921 const gfx::Rect& src_subrect,
922 const gfx::Size& dst_size,
923 ReadbackRequestCallback& callback,
924 const SkColorType color_type) {
925 TRACE_EVENT0("cc", "RenderWidgetHostViewAndroid::CopyFromCompositingSurface");
926 if (!host_ || host_->is_hidden()) {
927 callback.Run(SkBitmap(), READBACK_SURFACE_UNAVAILABLE);
928 return;
930 base::TimeTicks start_time = base::TimeTicks::Now();
931 if (using_browser_compositor_ && !IsSurfaceAvailableForCopy()) {
932 callback.Run(SkBitmap(), READBACK_NOT_SUPPORTED);
933 return;
935 const gfx::Display& display =
936 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
937 float device_scale_factor = display.device_scale_factor();
938 gfx::Size dst_size_in_pixel =
939 gfx::ConvertRectToPixel(device_scale_factor, gfx::Rect(dst_size)).size();
940 gfx::Rect src_subrect_in_pixel =
941 gfx::ConvertRectToPixel(device_scale_factor, src_subrect);
943 if (!using_browser_compositor_) {
944 SynchronousCopyContents(src_subrect_in_pixel, dst_size_in_pixel, callback,
945 color_type);
946 UMA_HISTOGRAM_TIMES("Compositing.CopyFromSurfaceTimeSynchronous",
947 base::TimeTicks::Now() - start_time);
948 return;
951 scoped_ptr<cc::CopyOutputRequest> request;
952 scoped_refptr<cc::Layer> readback_layer;
953 DCHECK(content_view_core_);
954 DCHECK(content_view_core_->GetWindowAndroid());
955 ui::WindowAndroidCompositor* compositor =
956 content_view_core_->GetWindowAndroid()->GetCompositor();
957 DCHECK(compositor);
958 DCHECK(frame_provider_.get() || !surface_id_.is_null());
959 scoped_refptr<cc::Layer> layer = CreateDelegatedLayer();
960 DCHECK(layer);
961 layer->SetHideLayerAndSubtree(true);
962 compositor->AttachLayerForReadback(layer);
964 readback_layer = layer;
965 request = cc::CopyOutputRequest::CreateRequest(
966 base::Bind(&RenderWidgetHostViewAndroid::
967 PrepareTextureCopyOutputResultForDelegatedReadback,
968 dst_size_in_pixel,
969 color_type,
970 start_time,
971 readback_layer,
972 callback));
973 if (!src_subrect_in_pixel.IsEmpty())
974 request->set_area(src_subrect_in_pixel);
975 readback_layer->RequestCopyOfOutput(request.Pass());
978 void RenderWidgetHostViewAndroid::CopyFromCompositingSurfaceToVideoFrame(
979 const gfx::Rect& src_subrect,
980 const scoped_refptr<media::VideoFrame>& target,
981 const base::Callback<void(bool)>& callback) {
982 NOTIMPLEMENTED();
983 callback.Run(false);
986 bool RenderWidgetHostViewAndroid::CanCopyToVideoFrame() const {
987 return false;
990 void RenderWidgetHostViewAndroid::ShowDisambiguationPopup(
991 const gfx::Rect& rect_pixels, const SkBitmap& zoomed_bitmap) {
992 if (!content_view_core_)
993 return;
995 content_view_core_->ShowDisambiguationPopup(rect_pixels, zoomed_bitmap);
998 scoped_ptr<SyntheticGestureTarget>
999 RenderWidgetHostViewAndroid::CreateSyntheticGestureTarget() {
1000 return scoped_ptr<SyntheticGestureTarget>(new SyntheticGestureTargetAndroid(
1001 host_, content_view_core_->CreateTouchEventSynthesizer()));
1004 void RenderWidgetHostViewAndroid::SendDelegatedFrameAck(
1005 uint32 output_surface_id) {
1006 DCHECK(host_);
1007 cc::CompositorFrameAck ack;
1008 if (!surface_returned_resources_.empty())
1009 ack.resources.swap(surface_returned_resources_);
1010 if (resource_collection_.get())
1011 resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources);
1012 host_->Send(new ViewMsg_SwapCompositorFrameAck(host_->GetRoutingID(),
1013 output_surface_id, ack));
1016 void RenderWidgetHostViewAndroid::SendReturnedDelegatedResources(
1017 uint32 output_surface_id) {
1018 DCHECK(host_);
1019 cc::CompositorFrameAck ack;
1020 if (!surface_returned_resources_.empty()) {
1021 ack.resources.swap(surface_returned_resources_);
1022 } else {
1023 DCHECK(resource_collection_.get());
1024 resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources);
1027 host_->Send(new ViewMsg_ReclaimCompositorResources(host_->GetRoutingID(),
1028 output_surface_id, ack));
1031 void RenderWidgetHostViewAndroid::UnusedResourcesAreAvailable() {
1032 DCHECK(surface_id_.is_null());
1033 if (ack_callbacks_.size())
1034 return;
1035 SendReturnedDelegatedResources(last_output_surface_id_);
1038 void RenderWidgetHostViewAndroid::ReturnResources(
1039 const cc::ReturnedResourceArray& resources) {
1040 if (resources.empty())
1041 return;
1042 std::copy(resources.begin(), resources.end(),
1043 std::back_inserter(surface_returned_resources_));
1044 if (!ack_callbacks_.size())
1045 SendReturnedDelegatedResources(last_output_surface_id_);
1048 void RenderWidgetHostViewAndroid::DestroyDelegatedContent() {
1049 RemoveLayers();
1050 frame_provider_ = NULL;
1051 if (!surface_id_.is_null()) {
1052 DCHECK(surface_factory_.get());
1053 surface_factory_->Destroy(surface_id_);
1054 surface_id_ = cc::SurfaceId();
1056 layer_ = NULL;
1057 // This gets called when ever any eviction, loosing resources, swapping
1058 // problems are encountered and so we abort any pending readbacks here.
1059 AbortPendingReadbackRequests();
1062 void RenderWidgetHostViewAndroid::CheckOutputSurfaceChanged(
1063 uint32 output_surface_id) {
1064 if (output_surface_id == last_output_surface_id_)
1065 return;
1066 // Drop the cc::DelegatedFrameResourceCollection so that we will not return
1067 // any resources from the old output surface with the new output surface id.
1068 if (resource_collection_.get()) {
1069 resource_collection_->SetClient(NULL);
1070 if (resource_collection_->LoseAllResources())
1071 SendReturnedDelegatedResources(last_output_surface_id_);
1072 resource_collection_ = NULL;
1074 DestroyDelegatedContent();
1075 surface_factory_.reset();
1076 if (!surface_returned_resources_.empty())
1077 SendReturnedDelegatedResources(last_output_surface_id_);
1079 last_output_surface_id_ = output_surface_id;
1082 void RenderWidgetHostViewAndroid::SubmitFrame(
1083 scoped_ptr<cc::DelegatedFrameData> frame_data) {
1084 cc::SurfaceManager* manager = CompositorImpl::GetSurfaceManager();
1085 if (manager) {
1086 if (!surface_factory_) {
1087 id_allocator_ = CompositorImpl::CreateSurfaceIdAllocator();
1088 surface_factory_ = make_scoped_ptr(new cc::SurfaceFactory(manager, this));
1090 if (surface_id_.is_null() ||
1091 texture_size_in_layer_ != current_surface_size_) {
1092 RemoveLayers();
1093 if (!surface_id_.is_null())
1094 surface_factory_->Destroy(surface_id_);
1095 surface_id_ = id_allocator_->GenerateId();
1096 surface_factory_->Create(surface_id_);
1097 layer_ = CreateDelegatedLayer();
1099 DCHECK(layer_);
1101 current_surface_size_ = texture_size_in_layer_;
1102 AttachLayers();
1104 scoped_ptr<cc::CompositorFrame> compositor_frame =
1105 make_scoped_ptr(new cc::CompositorFrame());
1106 compositor_frame->delegated_frame_data = frame_data.Pass();
1108 cc::SurfaceFactory::DrawCallback ack_callback =
1109 base::Bind(&RenderWidgetHostViewAndroid::RunAckCallbacks,
1110 weak_ptr_factory_.GetWeakPtr());
1111 surface_factory_->SubmitFrame(surface_id_, compositor_frame.Pass(),
1112 ack_callback);
1113 } else {
1114 if (!resource_collection_.get()) {
1115 resource_collection_ = new cc::DelegatedFrameResourceCollection;
1116 resource_collection_->SetClient(this);
1118 if (!frame_provider_.get() ||
1119 texture_size_in_layer_ != frame_provider_->frame_size()) {
1120 RemoveLayers();
1121 frame_provider_ = new cc::DelegatedFrameProvider(
1122 resource_collection_.get(), frame_data.Pass());
1123 layer_ = cc::DelegatedRendererLayer::Create(frame_provider_);
1124 AttachLayers();
1125 } else {
1126 frame_provider_->SetFrameData(frame_data.Pass());
1131 void RenderWidgetHostViewAndroid::SwapDelegatedFrame(
1132 uint32 output_surface_id,
1133 scoped_ptr<cc::DelegatedFrameData> frame_data) {
1134 CheckOutputSurfaceChanged(output_surface_id);
1135 bool has_content = !texture_size_in_layer_.IsEmpty();
1137 // DelegatedRendererLayerImpl applies the inverse device_scale_factor of the
1138 // renderer frame, assuming that the browser compositor will scale
1139 // it back up to device scale. But on Android we put our browser layers in
1140 // physical pixels and set our browser CC device_scale_factor to 1, so this
1141 // suppresses the transform. This line may need to be removed when fixing
1142 // http://crbug.com/384134 or http://crbug.com/310763
1143 frame_data->device_scale_factor = 1.0f;
1145 if (!has_content) {
1146 DestroyDelegatedContent();
1147 } else {
1148 SubmitFrame(frame_data.Pass());
1151 if (layer_.get()) {
1152 layer_->SetIsDrawable(true);
1153 layer_->SetContentsOpaque(true);
1154 layer_->SetBounds(content_size_in_layer_);
1157 base::Closure ack_callback =
1158 base::Bind(&RenderWidgetHostViewAndroid::SendDelegatedFrameAck,
1159 weak_ptr_factory_.GetWeakPtr(),
1160 output_surface_id);
1162 ack_callbacks_.push(ack_callback);
1163 if (host_->is_hidden())
1164 RunAckCallbacks(cc::SurfaceDrawStatus::DRAW_SKIPPED);
1167 void RenderWidgetHostViewAndroid::ComputeContentsSize(
1168 const cc::CompositorFrameMetadata& frame_metadata) {
1169 // Calculate the content size. This should be 0 if the texture_size is 0.
1170 gfx::Vector2dF offset;
1171 if (texture_size_in_layer_.IsEmpty())
1172 content_size_in_layer_ = gfx::Size();
1173 content_size_in_layer_ = gfx::ToCeiledSize(gfx::ScaleSize(
1174 frame_metadata.scrollable_viewport_size,
1175 frame_metadata.device_scale_factor * frame_metadata.page_scale_factor));
1179 void RenderWidgetHostViewAndroid::InternalSwapCompositorFrame(
1180 uint32 output_surface_id,
1181 scoped_ptr<cc::CompositorFrame> frame) {
1182 last_scroll_offset_ = frame->metadata.root_scroll_offset;
1183 if (!frame->delegated_frame_data) {
1184 LOG(ERROR) << "Non-delegated renderer path no longer supported";
1185 return;
1188 if (locks_on_frame_count_ > 0) {
1189 DCHECK(HasValidFrame());
1190 RetainFrame(output_surface_id, frame.Pass());
1191 return;
1194 if (layer_.get() && layer_->layer_tree_host()) {
1195 for (size_t i = 0; i < frame->metadata.latency_info.size(); i++) {
1196 scoped_ptr<cc::SwapPromise> swap_promise(
1197 new cc::LatencyInfoSwapPromise(frame->metadata.latency_info[i]));
1198 layer_->layer_tree_host()->QueueSwapPromise(swap_promise.Pass());
1202 DCHECK(!frame->delegated_frame_data->render_pass_list.empty());
1204 cc::RenderPass* root_pass =
1205 frame->delegated_frame_data->render_pass_list.back();
1206 texture_size_in_layer_ = root_pass->output_rect.size();
1207 ComputeContentsSize(frame->metadata);
1209 SwapDelegatedFrame(output_surface_id, frame->delegated_frame_data.Pass());
1210 frame_evictor_->SwappedFrame(!host_->is_hidden());
1212 // As the metadata update may trigger view invalidation, always call it after
1213 // any potential compositor scheduling.
1214 OnFrameMetadataUpdated(frame->metadata);
1215 // Check if we have any pending readbacks, see if we have a frame available
1216 // and process them here.
1217 if (!readbacks_waiting_for_frame_.empty()) {
1218 while (!readbacks_waiting_for_frame_.empty()) {
1219 ReadbackRequest& readback_request = readbacks_waiting_for_frame_.front();
1220 GetScaledContentBitmap(readback_request.GetScale(),
1221 readback_request.GetColorFormat(),
1222 readback_request.GetCaptureRect(),
1223 readback_request.GetResultCallback());
1224 readbacks_waiting_for_frame_.pop();
1229 void RenderWidgetHostViewAndroid::OnSwapCompositorFrame(
1230 uint32 output_surface_id,
1231 scoped_ptr<cc::CompositorFrame> frame) {
1232 InternalSwapCompositorFrame(output_surface_id, frame.Pass());
1235 void RenderWidgetHostViewAndroid::RetainFrame(
1236 uint32 output_surface_id,
1237 scoped_ptr<cc::CompositorFrame> frame) {
1238 DCHECK(locks_on_frame_count_);
1240 // Store the incoming frame so that it can be swapped when all the locks have
1241 // been released. If there is already a stored frame, then replace and skip
1242 // the previous one but make sure we still eventually send the ACK. Holding
1243 // the ACK also blocks the renderer when its max_frames_pending is reached.
1244 if (last_frame_info_) {
1245 base::Closure ack_callback =
1246 base::Bind(&RenderWidgetHostViewAndroid::SendDelegatedFrameAck,
1247 weak_ptr_factory_.GetWeakPtr(),
1248 last_frame_info_->output_surface_id);
1250 ack_callbacks_.push(ack_callback);
1253 last_frame_info_.reset(new LastFrameInfo(output_surface_id, frame.Pass()));
1256 void RenderWidgetHostViewAndroid::SynchronousFrameMetadata(
1257 const cc::CompositorFrameMetadata& frame_metadata) {
1258 if (!content_view_core_)
1259 return;
1261 // This is a subset of OnSwapCompositorFrame() used in the synchronous
1262 // compositor flow.
1263 OnFrameMetadataUpdated(frame_metadata);
1264 ComputeContentsSize(frame_metadata);
1266 // DevTools ScreenCast support for Android WebView.
1267 WebContents* web_contents = content_view_core_->GetWebContents();
1268 if (DevToolsAgentHost::HasFor(web_contents)) {
1269 scoped_refptr<DevToolsAgentHost> dtah =
1270 DevToolsAgentHost::GetOrCreateFor(web_contents);
1271 // Unblock the compositor.
1272 BrowserThread::PostTask(
1273 BrowserThread::UI, FROM_HERE,
1274 base::Bind(
1275 &RenderFrameDevToolsAgentHost::SynchronousSwapCompositorFrame,
1276 static_cast<RenderFrameDevToolsAgentHost*>(dtah.get()),
1277 frame_metadata));
1281 void RenderWidgetHostViewAndroid::SetOverlayVideoMode(bool enabled) {
1282 if (layer_.get())
1283 layer_->SetContentsOpaque(!enabled);
1286 bool RenderWidgetHostViewAndroid::SupportsAnimation() const {
1287 // The synchronous (WebView) compositor does not have a proper browser
1288 // compositor with which to drive animations.
1289 return using_browser_compositor_;
1292 void RenderWidgetHostViewAndroid::SetNeedsAnimate() {
1293 DCHECK(content_view_core_);
1294 DCHECK(using_browser_compositor_);
1295 content_view_core_->GetWindowAndroid()->SetNeedsAnimate();
1298 void RenderWidgetHostViewAndroid::MoveCaret(const gfx::PointF& position) {
1299 MoveCaret(gfx::Point(position.x(), position.y()));
1302 void RenderWidgetHostViewAndroid::MoveRangeSelectionExtent(
1303 const gfx::PointF& extent) {
1304 DCHECK(content_view_core_);
1305 content_view_core_->MoveRangeSelectionExtent(extent);
1308 void RenderWidgetHostViewAndroid::SelectBetweenCoordinates(
1309 const gfx::PointF& base,
1310 const gfx::PointF& extent) {
1311 DCHECK(content_view_core_);
1312 content_view_core_->SelectBetweenCoordinates(base, extent);
1315 void RenderWidgetHostViewAndroid::OnSelectionEvent(
1316 ui::SelectionEventType event) {
1317 DCHECK(content_view_core_);
1318 DCHECK(selection_controller_);
1319 // Showing the selection action bar can alter the current View coordinates in
1320 // such a way that the current MotionEvent stream is suddenly shifted in
1321 // space. Avoid the associated scroll jump by pre-emptively cancelling gesture
1322 // detection; scrolling after the selection is activated is unnecessary.
1323 if (event == ui::SelectionEventType::SELECTION_SHOWN)
1324 ResetGestureDetection();
1325 content_view_core_->OnSelectionEvent(
1326 event, selection_controller_->GetStartPosition(),
1327 GetSelectionRect(*selection_controller_));
1330 scoped_ptr<ui::TouchHandleDrawable>
1331 RenderWidgetHostViewAndroid::CreateDrawable() {
1332 DCHECK(content_view_core_);
1333 if (!using_browser_compositor_)
1334 return content_view_core_->CreatePopupTouchHandleDrawable();
1336 return scoped_ptr<ui::TouchHandleDrawable>(new CompositedTouchHandleDrawable(
1337 content_view_core_->GetLayer().get(),
1338 content_view_core_->GetDpiScale(),
1339 // Use the activity context (instead of the application context) to ensure
1340 // proper handle theming.
1341 content_view_core_->GetContext().obj()));
1344 void RenderWidgetHostViewAndroid::SynchronousCopyContents(
1345 const gfx::Rect& src_subrect_in_pixel,
1346 const gfx::Size& dst_size_in_pixel,
1347 ReadbackRequestCallback& callback,
1348 const SkColorType color_type) {
1349 gfx::Size input_size_in_pixel;
1350 if (src_subrect_in_pixel.IsEmpty())
1351 input_size_in_pixel = content_size_in_layer_;
1352 else
1353 input_size_in_pixel = src_subrect_in_pixel.size();
1355 gfx::Size output_size_in_pixel;
1356 if (dst_size_in_pixel.IsEmpty())
1357 output_size_in_pixel = input_size_in_pixel;
1358 else
1359 output_size_in_pixel = dst_size_in_pixel;
1360 int output_width = output_size_in_pixel.width();
1361 int output_height = output_size_in_pixel.height();
1363 SynchronousCompositor* compositor =
1364 SynchronousCompositorImpl::FromID(host_->GetProcess()->GetID(),
1365 host_->GetRoutingID());
1366 if (!compositor) {
1367 callback.Run(SkBitmap(), READBACK_FAILED);
1368 return;
1371 SkBitmap bitmap;
1372 bitmap.allocPixels(SkImageInfo::Make(output_width,
1373 output_height,
1374 color_type,
1375 kPremul_SkAlphaType));
1376 SkCanvas canvas(bitmap);
1377 canvas.scale(
1378 (float)output_width / (float)input_size_in_pixel.width(),
1379 (float)output_height / (float)input_size_in_pixel.height());
1380 compositor->DemandDrawSw(&canvas);
1381 callback.Run(bitmap, READBACK_SUCCESS);
1384 void RenderWidgetHostViewAndroid::OnFrameMetadataUpdated(
1385 const cc::CompositorFrameMetadata& frame_metadata) {
1386 bool is_mobile_optimized = IsMobileOptimizedFrame(frame_metadata);
1387 gesture_provider_.SetDoubleTapSupportForPageEnabled(!is_mobile_optimized);
1389 if (!content_view_core_)
1390 return;
1392 if (overscroll_controller_)
1393 overscroll_controller_->OnFrameMetadataUpdated(frame_metadata);
1395 if (selection_controller_) {
1396 selection_controller_->OnSelectionEditable(
1397 frame_metadata.selection.is_editable);
1398 selection_controller_->OnSelectionEmpty(
1399 frame_metadata.selection.is_empty_text_form_control);
1400 selection_controller_->OnSelectionBoundsChanged(
1401 ConvertSelectionBound(frame_metadata.selection.start),
1402 ConvertSelectionBound(frame_metadata.selection.end));
1405 // All offsets and sizes are in CSS pixels.
1406 content_view_core_->UpdateFrameInfo(
1407 frame_metadata.root_scroll_offset,
1408 frame_metadata.page_scale_factor,
1409 gfx::Vector2dF(frame_metadata.min_page_scale_factor,
1410 frame_metadata.max_page_scale_factor),
1411 frame_metadata.root_layer_size,
1412 frame_metadata.scrollable_viewport_size,
1413 frame_metadata.location_bar_offset,
1414 frame_metadata.location_bar_content_translation,
1415 is_mobile_optimized);
1416 #if defined(VIDEO_HOLE)
1417 if (host_ && host_->IsRenderView()) {
1418 RenderViewHostImpl* rvhi = static_cast<RenderViewHostImpl*>(
1419 RenderViewHost::From(host_));
1420 WebContentsImpl* web_contents_impl =
1421 static_cast<WebContentsImpl*>(WebContents::FromRenderViewHost(rvhi));
1422 if (web_contents_impl)
1423 web_contents_impl->media_web_contents_observer()->OnFrameInfoUpdated();
1425 #endif // defined(VIDEO_HOLE)
1428 void RenderWidgetHostViewAndroid::AcceleratedSurfaceInitialized(int route_id) {
1429 // TODO: remove need for the surface id here
1430 accelerated_surface_route_id_ = route_id;
1433 void RenderWidgetHostViewAndroid::ShowInternal() {
1434 DCHECK(is_showing_);
1435 if (!host_ || !host_->is_hidden())
1436 return;
1438 if (layer_.get())
1439 layer_->SetHideLayerAndSubtree(false);
1441 frame_evictor_->SetVisible(true);
1443 if (overscroll_controller_)
1444 overscroll_controller_->Enable();
1446 host_->WasShown(ui::LatencyInfo());
1448 if (content_view_core_) {
1449 StartObservingRootWindow();
1450 RequestVSyncUpdate(BEGIN_FRAME);
1454 void RenderWidgetHostViewAndroid::HideInternal(
1455 bool hide_frontbuffer,
1456 bool stop_observing_root_window) {
1457 if (hide_frontbuffer) {
1458 if (layer_.get() && locks_on_frame_count_ == 0)
1459 layer_->SetHideLayerAndSubtree(true);
1461 frame_evictor_->SetVisible(false);
1464 if (stop_observing_root_window)
1465 StopObservingRootWindow();
1467 if (!host_ || host_->is_hidden())
1468 return;
1470 if (overscroll_controller_)
1471 overscroll_controller_->Disable();
1473 // We don't know if we will ever get a frame if we are hiding the renderer, so
1474 // we need to cancel all requests
1475 AbortPendingReadbackRequests();
1477 RunAckCallbacks(cc::SurfaceDrawStatus::DRAW_SKIPPED);
1479 // Inform the renderer that we are being hidden so it can reduce its resource
1480 // utilization.
1481 host_->WasHidden();
1484 void RenderWidgetHostViewAndroid::AttachLayers() {
1485 if (!content_view_core_)
1486 return;
1487 if (!layer_.get())
1488 return;
1490 content_view_core_->AttachLayer(layer_);
1491 if (overscroll_controller_)
1492 overscroll_controller_->Enable();
1493 layer_->SetHideLayerAndSubtree(!is_showing_);
1496 void RenderWidgetHostViewAndroid::RemoveLayers() {
1497 if (!content_view_core_)
1498 return;
1500 if (!layer_.get())
1501 return;
1503 content_view_core_->RemoveLayer(layer_);
1504 if (overscroll_controller_)
1505 overscroll_controller_->Disable();
1508 void RenderWidgetHostViewAndroid::RequestVSyncUpdate(uint32 requests) {
1509 bool should_request_vsync = !outstanding_vsync_requests_ && requests;
1510 outstanding_vsync_requests_ |= requests;
1512 // If the host has been hidden, defer vsync requests until it is shown
1513 // again via |Show()|.
1514 if (!host_ || host_->is_hidden())
1515 return;
1517 // Note that if we're not currently observing the root window, outstanding
1518 // vsync requests will be pushed if/when we resume observing in
1519 // |StartObservingRootWindow()|.
1520 if (observing_root_window_ && should_request_vsync)
1521 content_view_core_->GetWindowAndroid()->RequestVSyncUpdate();
1524 void RenderWidgetHostViewAndroid::StartObservingRootWindow() {
1525 DCHECK(content_view_core_);
1526 DCHECK(is_showing_);
1527 if (observing_root_window_)
1528 return;
1530 observing_root_window_ = true;
1531 content_view_core_->GetWindowAndroid()->AddObserver(this);
1533 // Clear existing vsync requests to allow a request to the new window.
1534 uint32 outstanding_vsync_requests = outstanding_vsync_requests_;
1535 outstanding_vsync_requests_ = 0;
1536 RequestVSyncUpdate(outstanding_vsync_requests);
1539 void RenderWidgetHostViewAndroid::StopObservingRootWindow() {
1540 if (!content_view_core_) {
1541 DCHECK(!observing_root_window_);
1542 return;
1545 if (!observing_root_window_)
1546 return;
1548 observing_root_window_ = false;
1549 content_view_core_->GetWindowAndroid()->RemoveObserver(this);
1552 void RenderWidgetHostViewAndroid::SendBeginFrame(base::TimeTicks frame_time,
1553 base::TimeDelta vsync_period) {
1554 TRACE_EVENT1("cc", "RenderWidgetHostViewAndroid::SendBeginFrame",
1555 "frame_time_us", frame_time.ToInternalValue());
1557 if (using_browser_compositor_) {
1558 base::TimeTicks display_time = frame_time + vsync_period;
1560 base::TimeTicks deadline =
1561 display_time - host_->GetEstimatedBrowserCompositeTime();
1563 host_->Send(new ViewMsg_BeginFrame(
1564 host_->GetRoutingID(),
1565 cc::BeginFrameArgs::Create(BEGINFRAME_FROM_HERE, frame_time, deadline,
1566 vsync_period, cc::BeginFrameArgs::NORMAL)));
1567 } else {
1568 SynchronousCompositorImpl* compositor = SynchronousCompositorImpl::FromID(
1569 host_->GetProcess()->GetID(), host_->GetRoutingID());
1570 if (compositor) {
1571 // The synchronous compositor synchronously does it's work in this call.
1572 // It does not use a deadline.
1573 compositor->BeginFrame(cc::BeginFrameArgs::Create(
1574 BEGINFRAME_FROM_HERE, frame_time, base::TimeTicks(), vsync_period,
1575 cc::BeginFrameArgs::NORMAL));
1580 bool RenderWidgetHostViewAndroid::Animate(base::TimeTicks frame_time) {
1581 bool needs_animate = false;
1582 if (overscroll_controller_) {
1583 needs_animate |= overscroll_controller_->Animate(
1584 frame_time, content_view_core_->GetLayer().get());
1586 if (selection_controller_)
1587 needs_animate |= selection_controller_->Animate(frame_time);
1588 return needs_animate;
1591 void RenderWidgetHostViewAndroid::EvictDelegatedFrame() {
1592 if (layer_.get())
1593 DestroyDelegatedContent();
1594 frame_evictor_->DiscardedFrame();
1595 // We are evicting the delegated frame,
1596 // so there should be no pending readback requests
1597 DCHECK(readbacks_waiting_for_frame_.empty());
1600 bool RenderWidgetHostViewAndroid::HasAcceleratedSurface(
1601 const gfx::Size& desired_size) {
1602 NOTREACHED();
1603 return false;
1606 void RenderWidgetHostViewAndroid::GetScreenInfo(blink::WebScreenInfo* result) {
1607 // ScreenInfo isn't tied to the widget on Android. Always return the default.
1608 RenderWidgetHostViewBase::GetDefaultScreenInfo(result);
1611 // TODO(jrg): Find out the implications and answer correctly here,
1612 // as we are returning the WebView and not root window bounds.
1613 gfx::Rect RenderWidgetHostViewAndroid::GetBoundsInRootWindow() {
1614 return GetViewBounds();
1617 gfx::GLSurfaceHandle RenderWidgetHostViewAndroid::GetCompositingSurface() {
1618 gfx::GLSurfaceHandle handle =
1619 gfx::GLSurfaceHandle(gfx::kNullPluginWindow, gfx::NULL_TRANSPORT);
1620 if (using_browser_compositor_) {
1621 handle.parent_client_id =
1622 BrowserGpuChannelHostFactory::instance()->GetGpuChannelId();
1624 return handle;
1627 void RenderWidgetHostViewAndroid::ProcessAckedTouchEvent(
1628 const TouchEventWithLatencyInfo& touch, InputEventAckState ack_result) {
1629 const bool event_consumed = ack_result == INPUT_EVENT_ACK_STATE_CONSUMED;
1630 gesture_provider_.OnAsyncTouchEventAck(event_consumed);
1633 void RenderWidgetHostViewAndroid::GestureEventAck(
1634 const blink::WebGestureEvent& event,
1635 InputEventAckState ack_result) {
1636 if (overscroll_controller_)
1637 overscroll_controller_->OnGestureEventAck(event, ack_result);
1639 if (content_view_core_)
1640 content_view_core_->OnGestureEventAck(event, ack_result);
1643 InputEventAckState RenderWidgetHostViewAndroid::FilterInputEvent(
1644 const blink::WebInputEvent& input_event) {
1645 if (selection_controller_) {
1646 switch (input_event.type) {
1647 case blink::WebInputEvent::GestureLongPress:
1648 selection_controller_->OnLongPressEvent();
1649 break;
1650 case blink::WebInputEvent::GestureTap:
1651 selection_controller_->OnTapEvent();
1652 break;
1653 default:
1654 break;
1658 if (overscroll_controller_ &&
1659 blink::WebInputEvent::isGestureEventType(input_event.type) &&
1660 overscroll_controller_->WillHandleGestureEvent(
1661 static_cast<const blink::WebGestureEvent&>(input_event))) {
1662 return INPUT_EVENT_ACK_STATE_CONSUMED;
1665 if (content_view_core_) {
1666 InputEventAckState ack_result =
1667 content_view_core_->FilterInputEvent(input_event);
1668 if (ack_result != INPUT_EVENT_ACK_STATE_NOT_CONSUMED)
1669 return ack_result;
1672 if (!host_)
1673 return INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
1675 if (input_event.type == blink::WebInputEvent::GestureTapDown ||
1676 input_event.type == blink::WebInputEvent::TouchStart) {
1677 GpuDataManagerImpl* gpu_data = GpuDataManagerImpl::GetInstance();
1678 GpuProcessHostUIShim* shim = GpuProcessHostUIShim::GetOneInstance();
1679 if (shim && gpu_data && accelerated_surface_route_id_ &&
1680 gpu_data->IsDriverBugWorkaroundActive(gpu::WAKE_UP_GPU_BEFORE_DRAWING))
1681 shim->Send(
1682 new AcceleratedSurfaceMsg_WakeUpGpu(accelerated_surface_route_id_));
1685 SynchronousCompositorImpl* compositor =
1686 SynchronousCompositorImpl::FromID(host_->GetProcess()->GetID(),
1687 host_->GetRoutingID());
1688 if (compositor)
1689 return compositor->HandleInputEvent(input_event);
1690 return INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
1693 void RenderWidgetHostViewAndroid::OnSetNeedsFlushInput() {
1694 TRACE_EVENT0("input", "RenderWidgetHostViewAndroid::OnSetNeedsFlushInput");
1695 RequestVSyncUpdate(FLUSH_INPUT);
1698 BrowserAccessibilityManager*
1699 RenderWidgetHostViewAndroid::CreateBrowserAccessibilityManager(
1700 BrowserAccessibilityDelegate* delegate) {
1701 // TODO(dmazzoni): Currently there can only be one
1702 // BrowserAccessibilityManager per ContentViewCore, so return NULL
1703 // if there's already a BrowserAccessibilityManager for the main
1704 // frame. Eventually, in order to support cross-process iframes on
1705 // Android we'll need to add support for a
1706 // BrowserAccessibilityManager for a child frame.
1707 // http://crbug.com/423846
1708 if (!host_ || host_->GetRootBrowserAccessibilityManager())
1709 return NULL;
1711 base::android::ScopedJavaLocalRef<jobject> obj;
1712 if (content_view_core_)
1713 obj = content_view_core_->GetJavaObject();
1714 return new BrowserAccessibilityManagerAndroid(
1715 obj,
1716 BrowserAccessibilityManagerAndroid::GetEmptyDocument(),
1717 delegate);
1720 bool RenderWidgetHostViewAndroid::LockMouse() {
1721 NOTIMPLEMENTED();
1722 return false;
1725 void RenderWidgetHostViewAndroid::UnlockMouse() {
1726 NOTIMPLEMENTED();
1729 // Methods called from the host to the render
1731 void RenderWidgetHostViewAndroid::SendKeyEvent(
1732 const NativeWebKeyboardEvent& event) {
1733 if (host_)
1734 host_->ForwardKeyboardEvent(event);
1737 void RenderWidgetHostViewAndroid::SendMouseEvent(
1738 const blink::WebMouseEvent& event) {
1739 if (host_)
1740 host_->ForwardMouseEvent(event);
1743 void RenderWidgetHostViewAndroid::SendMouseWheelEvent(
1744 const blink::WebMouseWheelEvent& event) {
1745 if (host_)
1746 host_->ForwardWheelEvent(event);
1749 void RenderWidgetHostViewAndroid::SendGestureEvent(
1750 const blink::WebGestureEvent& event) {
1751 // Sending a gesture that may trigger overscroll should resume the effect.
1752 if (overscroll_controller_)
1753 overscroll_controller_->Enable();
1755 if (host_)
1756 host_->ForwardGestureEventWithLatencyInfo(event, ui::LatencyInfo());
1759 void RenderWidgetHostViewAndroid::MoveCaret(const gfx::Point& point) {
1760 if (host_)
1761 host_->MoveCaret(point);
1764 void RenderWidgetHostViewAndroid::DismissTextHandles() {
1765 if (selection_controller_)
1766 selection_controller_->HideAndDisallowShowingAutomatically();
1769 void RenderWidgetHostViewAndroid::SetTextHandlesTemporarilyHidden(bool hidden) {
1770 if (selection_controller_)
1771 selection_controller_->SetTemporarilyHidden(hidden);
1774 void RenderWidgetHostViewAndroid::OnShowingPastePopup(
1775 const gfx::PointF& point) {
1776 if (!selection_controller_)
1777 return;
1779 // As the paste popup may be triggered *before* the bounds and editability
1780 // of the region have been updated, explicitly set the properties now.
1781 // TODO(jdduke): Remove this workaround when auxiliary paste popup
1782 // notifications are no longer required, crbug.com/398170.
1783 ui::SelectionBound insertion_bound;
1784 insertion_bound.set_type(ui::SelectionBound::CENTER);
1785 insertion_bound.set_visible(true);
1786 insertion_bound.SetEdge(point, point);
1787 selection_controller_->HideAndDisallowShowingAutomatically();
1788 selection_controller_->OnSelectionEditable(true);
1789 selection_controller_->OnSelectionEmpty(true);
1790 selection_controller_->OnSelectionBoundsChanged(insertion_bound,
1791 insertion_bound);
1792 selection_controller_->AllowShowingFromCurrentSelection();
1795 SkColor RenderWidgetHostViewAndroid::GetCachedBackgroundColor() const {
1796 return cached_background_color_;
1799 void RenderWidgetHostViewAndroid::DidOverscroll(
1800 const DidOverscrollParams& params) {
1801 if (!content_view_core_ || !layer_.get() || !is_showing_)
1802 return;
1804 if (overscroll_controller_)
1805 overscroll_controller_->OnOverscrolled(params);
1808 void RenderWidgetHostViewAndroid::DidStopFlinging() {
1809 if (content_view_core_)
1810 content_view_core_->DidStopFlinging();
1813 void RenderWidgetHostViewAndroid::SetContentViewCore(
1814 ContentViewCoreImpl* content_view_core) {
1815 RemoveLayers();
1816 StopObservingRootWindow();
1818 bool resize = false;
1819 if (content_view_core != content_view_core_) {
1820 overscroll_controller_.reset();
1821 selection_controller_.reset();
1822 ReleaseLocksOnSurface();
1823 resize = true;
1826 content_view_core_ = content_view_core;
1828 BrowserAccessibilityManager* manager = NULL;
1829 if (host_)
1830 manager = host_->GetRootBrowserAccessibilityManager();
1831 if (manager) {
1832 base::android::ScopedJavaLocalRef<jobject> obj;
1833 if (content_view_core_)
1834 obj = content_view_core_->GetJavaObject();
1835 manager->ToBrowserAccessibilityManagerAndroid()->SetContentViewCore(obj);
1838 AttachLayers();
1840 if (!content_view_core_)
1841 return;
1843 if (is_showing_)
1844 StartObservingRootWindow();
1846 if (resize)
1847 WasResized();
1849 if (!selection_controller_)
1850 selection_controller_ = CreateSelectionController(this, content_view_core_);
1852 if (!overscroll_controller_ &&
1853 content_view_core_->GetWindowAndroid()->GetCompositor()) {
1854 overscroll_controller_ = CreateOverscrollController(content_view_core_);
1858 void RenderWidgetHostViewAndroid::RunAckCallbacks(
1859 cc::SurfaceDrawStatus status) {
1860 while (!ack_callbacks_.empty()) {
1861 ack_callbacks_.front().Run();
1862 ack_callbacks_.pop();
1866 void RenderWidgetHostViewAndroid::OnGestureEvent(
1867 const ui::GestureEventData& gesture) {
1868 blink::WebGestureEvent web_gesture =
1869 ui::CreateWebGestureEventFromGestureEventData(gesture);
1870 // TODO(jdduke): Remove this workaround after Android fixes UiAutomator to
1871 // stop providing shift meta values to synthetic MotionEvents. This prevents
1872 // unintended shift+click interpretation of all accessibility clicks.
1873 // See crbug.com/443247.
1874 if (web_gesture.type == blink::WebInputEvent::GestureTap &&
1875 web_gesture.modifiers == blink::WebInputEvent::ShiftKey) {
1876 web_gesture.modifiers = 0;
1878 SendGestureEvent(web_gesture);
1881 void RenderWidgetHostViewAndroid::OnCompositingDidCommit() {
1882 RunAckCallbacks(cc::SurfaceDrawStatus::DRAWN);
1885 void RenderWidgetHostViewAndroid::OnRootWindowVisibilityChanged(bool visible) {
1886 DCHECK(is_showing_);
1887 if (visible) {
1888 ShowInternal();
1889 } else {
1890 bool hide_frontbuffer = true;
1891 bool stop_observing_root_window = false;
1892 HideInternal(hide_frontbuffer, stop_observing_root_window);
1896 void RenderWidgetHostViewAndroid::OnAttachCompositor() {
1897 DCHECK(content_view_core_);
1898 if (!overscroll_controller_)
1899 overscroll_controller_ = CreateOverscrollController(content_view_core_);
1902 void RenderWidgetHostViewAndroid::OnDetachCompositor() {
1903 DCHECK(content_view_core_);
1904 DCHECK(using_browser_compositor_);
1905 RunAckCallbacks(cc::SurfaceDrawStatus::DRAW_SKIPPED);
1906 overscroll_controller_.reset();
1909 void RenderWidgetHostViewAndroid::OnVSync(base::TimeTicks frame_time,
1910 base::TimeDelta vsync_period) {
1911 TRACE_EVENT0("cc,benchmark", "RenderWidgetHostViewAndroid::OnVSync");
1912 if (!host_ || host_->is_hidden())
1913 return;
1915 if (outstanding_vsync_requests_ & FLUSH_INPUT) {
1916 outstanding_vsync_requests_ &= ~FLUSH_INPUT;
1917 host_->FlushInput();
1920 if (outstanding_vsync_requests_ & BEGIN_FRAME ||
1921 outstanding_vsync_requests_ & PERSISTENT_BEGIN_FRAME) {
1922 outstanding_vsync_requests_ &= ~BEGIN_FRAME;
1923 SendBeginFrame(frame_time, vsync_period);
1926 // This allows for SendBeginFrame and FlushInput to modify
1927 // outstanding_vsync_requests.
1928 uint32 outstanding_vsync_requests = outstanding_vsync_requests_;
1929 outstanding_vsync_requests_ = 0;
1930 RequestVSyncUpdate(outstanding_vsync_requests);
1933 void RenderWidgetHostViewAndroid::OnAnimate(base::TimeTicks begin_frame_time) {
1934 if (Animate(begin_frame_time))
1935 SetNeedsAnimate();
1938 void RenderWidgetHostViewAndroid::OnActivityPaused() {
1939 TRACE_EVENT0("browser", "RenderWidgetHostViewAndroid::OnActivityPaused");
1940 DCHECK(is_showing_);
1941 bool hide_frontbuffer = false;
1942 bool stop_observing_root_window = false;
1943 HideInternal(hide_frontbuffer, stop_observing_root_window);
1946 void RenderWidgetHostViewAndroid::OnActivityResumed() {
1947 TRACE_EVENT0("browser", "RenderWidgetHostViewAndroid::OnActivityResumed");
1948 DCHECK(is_showing_);
1949 ShowInternal();
1952 void RenderWidgetHostViewAndroid::OnLostResources() {
1953 ReleaseLocksOnSurface();
1954 if (layer_.get())
1955 DestroyDelegatedContent();
1956 DCHECK(ack_callbacks_.empty());
1957 // We should not loose a frame if we have readback requests pending.
1958 DCHECK(readbacks_waiting_for_frame_.empty());
1961 // static
1962 void
1963 RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResultForDelegatedReadback(
1964 const gfx::Size& dst_size_in_pixel,
1965 const SkColorType color_type,
1966 const base::TimeTicks& start_time,
1967 scoped_refptr<cc::Layer> readback_layer,
1968 ReadbackRequestCallback& callback,
1969 scoped_ptr<cc::CopyOutputResult> result) {
1970 readback_layer->RemoveFromParent();
1971 PrepareTextureCopyOutputResult(
1972 dst_size_in_pixel, color_type, start_time, callback, result.Pass());
1975 // static
1976 void RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResult(
1977 const gfx::Size& dst_size_in_pixel,
1978 const SkColorType color_type,
1979 const base::TimeTicks& start_time,
1980 ReadbackRequestCallback& callback,
1981 scoped_ptr<cc::CopyOutputResult> result) {
1982 base::ScopedClosureRunner scoped_callback_runner(
1983 base::Bind(callback, SkBitmap(), READBACK_FAILED));
1984 TRACE_EVENT0("cc",
1985 "RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResult");
1987 if (!result->HasTexture() || result->IsEmpty() || result->size().IsEmpty())
1988 return;
1990 gfx::Size output_size_in_pixel;
1991 if (dst_size_in_pixel.IsEmpty())
1992 output_size_in_pixel = result->size();
1993 else
1994 output_size_in_pixel = dst_size_in_pixel;
1996 scoped_ptr<SkBitmap> bitmap(new SkBitmap);
1997 if (!bitmap->tryAllocPixels(SkImageInfo::Make(output_size_in_pixel.width(),
1998 output_size_in_pixel.height(),
1999 color_type,
2000 kOpaque_SkAlphaType))) {
2001 return;
2004 GLHelper* gl_helper = GetPostReadbackGLHelper();
2005 if (!gl_helper || !gl_helper->IsReadbackConfigSupported(color_type))
2006 return;
2008 scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock(
2009 new SkAutoLockPixels(*bitmap));
2010 uint8* pixels = static_cast<uint8*>(bitmap->getPixels());
2012 cc::TextureMailbox texture_mailbox;
2013 scoped_ptr<cc::SingleReleaseCallback> release_callback;
2014 result->TakeTexture(&texture_mailbox, &release_callback);
2015 DCHECK(texture_mailbox.IsTexture());
2016 if (!texture_mailbox.IsTexture())
2017 return;
2019 ignore_result(scoped_callback_runner.Release());
2021 gl_helper->CropScaleReadbackAndCleanMailbox(
2022 texture_mailbox.mailbox(),
2023 texture_mailbox.sync_point(),
2024 result->size(),
2025 gfx::Rect(result->size()),
2026 output_size_in_pixel,
2027 pixels,
2028 color_type,
2029 base::Bind(&CopyFromCompositingSurfaceFinished,
2030 callback,
2031 base::Passed(&release_callback),
2032 base::Passed(&bitmap),
2033 start_time,
2034 base::Passed(&bitmap_pixels_lock)),
2035 GLHelper::SCALER_QUALITY_GOOD);
2038 SkColorType RenderWidgetHostViewAndroid::PreferredReadbackFormat() {
2039 // Define the criteria here. If say the 16 texture readback is
2040 // supported we should go with that (this degrades quality)
2041 // or stick back to the default format.
2042 if (base::SysInfo::IsLowEndDevice()) {
2043 // TODO(sievers): Cannot use GLHelper here. Instead remove this API
2044 // and have CopyFromCompositingSurface() fall back to RGB8 if 565 was
2045 // requested but is not supported.
2046 GLHelper* gl_helper = GetPostReadbackGLHelper();
2047 if (gl_helper && gl_helper->IsReadbackConfigSupported(kRGB_565_SkColorType))
2048 return kRGB_565_SkColorType;
2050 return kN32_SkColorType;
2053 void RenderWidgetHostViewAndroid::OnStylusSelectBegin(float x0,
2054 float y0,
2055 float x1,
2056 float y1) {
2057 SelectBetweenCoordinates(gfx::PointF(x0, y0), gfx::PointF(x1, y1));
2060 void RenderWidgetHostViewAndroid::OnStylusSelectUpdate(float x, float y) {
2061 MoveRangeSelectionExtent(gfx::PointF(x, y));
2064 void RenderWidgetHostViewAndroid::OnStylusSelectEnd() {
2065 if (selection_controller_)
2066 selection_controller_->AllowShowingFromCurrentSelection();
2069 void RenderWidgetHostViewAndroid::OnStylusSelectTap(base::TimeTicks time,
2070 float x,
2071 float y) {
2072 // Treat the stylus tap as a long press, activating either a word selection or
2073 // context menu depending on the targetted content.
2074 blink::WebGestureEvent long_press = WebGestureEventBuilder::Build(
2075 blink::WebInputEvent::GestureLongPress,
2076 (time - base::TimeTicks()).InSecondsF(), x, y);
2077 SendGestureEvent(long_press);
2080 // static
2081 void RenderWidgetHostViewBase::GetDefaultScreenInfo(
2082 blink::WebScreenInfo* results) {
2083 const gfx::Display& display =
2084 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
2085 results->rect = display.bounds();
2086 // TODO(husky): Remove any system controls from availableRect.
2087 results->availableRect = display.work_area();
2088 results->deviceScaleFactor = display.device_scale_factor();
2089 results->orientationAngle = display.RotationAsDegree();
2090 results->orientationType =
2091 RenderWidgetHostViewBase::GetOrientationTypeForMobile(display);
2092 gfx::DeviceDisplayInfo info;
2093 results->depth = info.GetBitsPerPixel();
2094 results->depthPerComponent = info.GetBitsPerComponent();
2095 results->isMonochrome = (results->depthPerComponent == 0);
2098 } // namespace content