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. 4 5 #include "content/browser/renderer_host/render_widget_host_view_android.h" 6 7 #include <android/bitmap.h> 8 9 #include "base/basictypes.h" 10 #include "base/bind.h" 11 #include "base/callback_helpers.h" 12 #include "base/command_line.h" 13 #include "base/logging.h" 14 #include "base/message_loop/message_loop.h" 15 #include "base/strings/utf_string_conversions.h" 16 #include "base/threading/worker_pool.h" 17 #include "cc/base/latency_info_swap_promise.h" 18 #include "cc/layers/delegated_frame_provider.h" 19 #include "cc/layers/delegated_renderer_layer.h" 20 #include "cc/layers/layer.h" 21 #include "cc/layers/texture_layer.h" 22 #include "cc/output/compositor_frame.h" 23 #include "cc/output/compositor_frame_ack.h" 24 #include "cc/output/copy_output_request.h" 25 #include "cc/output/copy_output_result.h" 26 #include "cc/resources/single_release_callback.h" 27 #include "cc/trees/layer_tree_host.h" 28 #include "content/browser/accessibility/browser_accessibility_manager_android.h" 29 #include "content/browser/android/content_view_core_impl.h" 30 #include "content/browser/android/in_process/synchronous_compositor_impl.h" 31 #include "content/browser/android/overscroll_glow.h" 32 #include "content/browser/devtools/render_view_devtools_agent_host.h" 33 #include "content/browser/gpu/gpu_data_manager_impl.h" 34 #include "content/browser/gpu/gpu_process_host_ui_shim.h" 35 #include "content/browser/gpu/gpu_surface_tracker.h" 36 #include "content/browser/renderer_host/compositor_impl_android.h" 37 #include "content/browser/renderer_host/dip_util.h" 38 #include "content/browser/renderer_host/image_transport_factory_android.h" 39 #include "content/browser/renderer_host/input/synthetic_gesture_target_android.h" 40 #include "content/browser/renderer_host/render_process_host_impl.h" 41 #include "content/browser/renderer_host/render_widget_host_impl.h" 42 #include "content/common/gpu/client/gl_helper.h" 43 #include "content/common/gpu/gpu_messages.h" 44 #include "content/common/input_messages.h" 45 #include "content/common/view_messages.h" 46 #include "content/public/browser/devtools_agent_host.h" 47 #include "content/public/browser/render_view_host.h" 48 #include "content/public/common/content_switches.h" 49 #include "gpu/config/gpu_driver_bug_workaround_type.h" 50 #include "skia/ext/image_operations.h" 51 #include "third_party/khronos/GLES2/gl2.h" 52 #include "third_party/khronos/GLES2/gl2ext.h" 53 #include "third_party/skia/include/core/SkCanvas.h" 54 #include "ui/base/android/window_android.h" 55 #include "ui/gfx/android/device_display_info.h" 56 #include "ui/gfx/android/java_bitmap.h" 57 #include "ui/gfx/display.h" 58 #include "ui/gfx/screen.h" 59 #include "ui/gfx/size_conversions.h" 60 61 namespace content { 62 63 namespace { 64 65 const int kUndefinedOutputSurfaceId = -1; 66 67 void InsertSyncPointAndAckForCompositor( 68 int renderer_host_id, 69 uint32 output_surface_id, 70 int route_id, 71 const gpu::Mailbox& return_mailbox, 72 const gfx::Size return_size) { 73 cc::CompositorFrameAck ack; 74 ack.gl_frame_data.reset(new cc::GLFrameData()); 75 if (!return_mailbox.IsZero()) { 76 ack.gl_frame_data->mailbox = return_mailbox; 77 ack.gl_frame_data->size = return_size; 78 ack.gl_frame_data->sync_point = 79 ImageTransportFactoryAndroid::GetInstance()->InsertSyncPoint(); 80 } 81 RenderWidgetHostImpl::SendSwapCompositorFrameAck( 82 route_id, output_surface_id, renderer_host_id, ack); 83 } 84 85 // Sends an acknowledgement to the renderer of a processed IME event. 86 void SendImeEventAck(RenderWidgetHostImpl* host) { 87 host->Send(new ViewMsg_ImeEventAck(host->GetRoutingID())); 88 } 89 90 void CopyFromCompositingSurfaceFinished( 91 const base::Callback<void(bool, const SkBitmap&)>& callback, 92 scoped_ptr<cc::SingleReleaseCallback> release_callback, 93 scoped_ptr<SkBitmap> bitmap, 94 scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock, 95 bool result) { 96 bitmap_pixels_lock.reset(); 97 release_callback->Run(0, false); 98 callback.Run(result, *bitmap); 99 } 100 101 bool UsingDelegatedRenderer() { 102 return CommandLine::ForCurrentProcess()->HasSwitch( 103 switches::kEnableDelegatedRenderer); 104 } 105 106 } // anonymous namespace 107 108 RenderWidgetHostViewAndroid::RenderWidgetHostViewAndroid( 109 RenderWidgetHostImpl* widget_host, 110 ContentViewCoreImpl* content_view_core) 111 : host_(widget_host), 112 needs_begin_frame_(false), 113 are_layers_attached_(true), 114 content_view_core_(NULL), 115 ime_adapter_android_(this), 116 cached_background_color_(SK_ColorWHITE), 117 texture_id_in_layer_(0), 118 last_output_surface_id_(kUndefinedOutputSurfaceId), 119 weak_ptr_factory_(this), 120 overscroll_effect_enabled_( 121 !CommandLine::ForCurrentProcess()-> 122 HasSwitch(switches::kDisableOverscrollEdgeEffect)), 123 overscroll_effect_(OverscrollGlow::Create(overscroll_effect_enabled_)), 124 flush_input_requested_(false), 125 accelerated_surface_route_id_(0), 126 using_synchronous_compositor_(SynchronousCompositorImpl::FromID( 127 widget_host->GetProcess()->GetID(), 128 widget_host->GetRoutingID()) != NULL) { 129 if (!UsingDelegatedRenderer()) { 130 texture_layer_ = cc::TextureLayer::Create(NULL); 131 layer_ = texture_layer_; 132 } 133 134 host_->SetView(this); 135 SetContentViewCore(content_view_core); 136 ImageTransportFactoryAndroid::AddObserver(this); 137 } 138 139 RenderWidgetHostViewAndroid::~RenderWidgetHostViewAndroid() { 140 ImageTransportFactoryAndroid::RemoveObserver(this); 141 SetContentViewCore(NULL); 142 DCHECK(ack_callbacks_.empty()); 143 if (texture_id_in_layer_) { 144 ImageTransportFactoryAndroid::GetInstance()->DeleteTexture( 145 texture_id_in_layer_); 146 } 147 148 if (texture_layer_.get()) 149 texture_layer_->ClearClient(); 150 151 if (resource_collection_.get()) 152 resource_collection_->SetClient(NULL); 153 } 154 155 156 bool RenderWidgetHostViewAndroid::OnMessageReceived( 157 const IPC::Message& message) { 158 bool handled = true; 159 IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewAndroid, message) 160 IPC_MESSAGE_HANDLER(ViewHostMsg_StartContentIntent, OnStartContentIntent) 161 IPC_MESSAGE_HANDLER(ViewHostMsg_DidChangeBodyBackgroundColor, 162 OnDidChangeBodyBackgroundColor) 163 IPC_MESSAGE_HANDLER(ViewHostMsg_SetNeedsBeginFrame, 164 OnSetNeedsBeginFrame) 165 IPC_MESSAGE_HANDLER(ViewHostMsg_TextInputStateChanged, 166 OnTextInputStateChanged) 167 IPC_MESSAGE_HANDLER(ViewHostMsg_SmartClipDataExtracted, 168 OnSmartClipDataExtracted) 169 IPC_MESSAGE_UNHANDLED(handled = false) 170 IPC_END_MESSAGE_MAP() 171 return handled; 172 } 173 174 void RenderWidgetHostViewAndroid::InitAsChild(gfx::NativeView parent_view) { 175 NOTIMPLEMENTED(); 176 } 177 178 void RenderWidgetHostViewAndroid::InitAsPopup( 179 RenderWidgetHostView* parent_host_view, const gfx::Rect& pos) { 180 NOTIMPLEMENTED(); 181 } 182 183 void RenderWidgetHostViewAndroid::InitAsFullscreen( 184 RenderWidgetHostView* reference_host_view) { 185 NOTIMPLEMENTED(); 186 } 187 188 RenderWidgetHost* 189 RenderWidgetHostViewAndroid::GetRenderWidgetHost() const { 190 return host_; 191 } 192 193 void RenderWidgetHostViewAndroid::WasShown() { 194 if (!host_ || !host_->is_hidden()) 195 return; 196 197 host_->WasShown(); 198 199 if (content_view_core_ && !using_synchronous_compositor_) 200 content_view_core_->GetWindowAndroid()->AddObserver(this); 201 } 202 203 void RenderWidgetHostViewAndroid::WasHidden() { 204 RunAckCallbacks(); 205 206 if (!host_ || host_->is_hidden()) 207 return; 208 209 // Inform the renderer that we are being hidden so it can reduce its resource 210 // utilization. 211 host_->WasHidden(); 212 213 if (content_view_core_ && !using_synchronous_compositor_) 214 content_view_core_->GetWindowAndroid()->RemoveObserver(this); 215 } 216 217 void RenderWidgetHostViewAndroid::WasResized() { 218 host_->WasResized(); 219 } 220 221 void RenderWidgetHostViewAndroid::SetSize(const gfx::Size& size) { 222 // Ignore the given size as only the Java code has the power to 223 // resize the view on Android. 224 default_size_ = size; 225 WasResized(); 226 } 227 228 void RenderWidgetHostViewAndroid::SetBounds(const gfx::Rect& rect) { 229 SetSize(rect.size()); 230 } 231 232 blink::WebGLId RenderWidgetHostViewAndroid::GetScaledContentTexture( 233 float scale, 234 gfx::Size* out_size) { 235 gfx::Size size(gfx::ToCeiledSize( 236 gfx::ScaleSize(texture_size_in_layer_, scale))); 237 238 if (!CompositorImpl::IsInitialized() || 239 texture_id_in_layer_ == 0 || 240 texture_size_in_layer_.IsEmpty() || 241 size.IsEmpty()) { 242 if (out_size) 243 out_size->SetSize(0, 0); 244 245 return 0; 246 } 247 248 if (out_size) 249 *out_size = size; 250 251 GLHelper* helper = ImageTransportFactoryAndroid::GetInstance()->GetGLHelper(); 252 return helper->CopyAndScaleTexture(texture_id_in_layer_, 253 texture_size_in_layer_, 254 size, 255 true, 256 GLHelper::SCALER_QUALITY_FAST); 257 } 258 259 bool RenderWidgetHostViewAndroid::PopulateBitmapWithContents(jobject jbitmap) { 260 if (!CompositorImpl::IsInitialized() || 261 texture_id_in_layer_ == 0 || 262 texture_size_in_layer_.IsEmpty()) 263 return false; 264 265 gfx::JavaBitmap bitmap(jbitmap); 266 267 // TODO(dtrainor): Eventually add support for multiple formats here. 268 DCHECK(bitmap.format() == ANDROID_BITMAP_FORMAT_RGBA_8888); 269 270 GLHelper* helper = ImageTransportFactoryAndroid::GetInstance()->GetGLHelper(); 271 272 blink::WebGLId texture = helper->CopyAndScaleTexture( 273 texture_id_in_layer_, 274 texture_size_in_layer_, 275 bitmap.size(), 276 true, 277 GLHelper::SCALER_QUALITY_FAST); 278 if (texture == 0) 279 return false; 280 281 helper->ReadbackTextureSync(texture, 282 gfx::Rect(bitmap.size()), 283 static_cast<unsigned char*> (bitmap.pixels())); 284 285 blink::WebGraphicsContext3D* context = 286 ImageTransportFactoryAndroid::GetInstance()->GetContext3D(); 287 context->deleteTexture(texture); 288 289 return true; 290 } 291 292 bool RenderWidgetHostViewAndroid::HasValidFrame() const { 293 if (!content_view_core_) 294 return false; 295 if (texture_size_in_layer_.IsEmpty()) 296 return false; 297 298 if (UsingDelegatedRenderer()) { 299 if (!delegated_renderer_layer_.get()) 300 return false; 301 } else { 302 if (texture_id_in_layer_ == 0) 303 return false; 304 } 305 306 return true; 307 } 308 309 gfx::NativeView RenderWidgetHostViewAndroid::GetNativeView() const { 310 return content_view_core_->GetViewAndroid(); 311 } 312 313 gfx::NativeViewId RenderWidgetHostViewAndroid::GetNativeViewId() const { 314 return reinterpret_cast<gfx::NativeViewId>( 315 const_cast<RenderWidgetHostViewAndroid*>(this)); 316 } 317 318 gfx::NativeViewAccessible 319 RenderWidgetHostViewAndroid::GetNativeViewAccessible() { 320 NOTIMPLEMENTED(); 321 return NULL; 322 } 323 324 void RenderWidgetHostViewAndroid::MovePluginWindows( 325 const gfx::Vector2d& scroll_offset, 326 const std::vector<WebPluginGeometry>& moves) { 327 // We don't have plugin windows on Android. Do nothing. Note: this is called 328 // from RenderWidgetHost::OnUpdateRect which is itself invoked while 329 // processing the corresponding message from Renderer. 330 } 331 332 void RenderWidgetHostViewAndroid::Focus() { 333 host_->Focus(); 334 host_->SetInputMethodActive(true); 335 ResetClipping(); 336 if (overscroll_effect_enabled_) 337 overscroll_effect_->Enable(); 338 } 339 340 void RenderWidgetHostViewAndroid::Blur() { 341 host_->ExecuteEditCommand("Unselect", ""); 342 host_->SetInputMethodActive(false); 343 host_->Blur(); 344 overscroll_effect_->Disable(); 345 } 346 347 bool RenderWidgetHostViewAndroid::HasFocus() const { 348 if (!content_view_core_) 349 return false; // ContentViewCore not created yet. 350 351 return content_view_core_->HasFocus(); 352 } 353 354 bool RenderWidgetHostViewAndroid::IsSurfaceAvailableForCopy() const { 355 return HasValidFrame(); 356 } 357 358 void RenderWidgetHostViewAndroid::Show() { 359 if (are_layers_attached_) 360 return; 361 362 are_layers_attached_ = true; 363 AttachLayers(); 364 365 WasShown(); 366 } 367 368 void RenderWidgetHostViewAndroid::Hide() { 369 if (!are_layers_attached_) 370 return; 371 372 are_layers_attached_ = false; 373 RemoveLayers(); 374 375 WasHidden(); 376 } 377 378 bool RenderWidgetHostViewAndroid::IsShowing() { 379 // ContentViewCoreImpl represents the native side of the Java 380 // ContentViewCore. It being NULL means that it is not attached 381 // to the View system yet, so we treat this RWHVA as hidden. 382 return are_layers_attached_ && content_view_core_; 383 } 384 385 gfx::Rect RenderWidgetHostViewAndroid::GetViewBounds() const { 386 if (!content_view_core_) 387 return gfx::Rect(default_size_); 388 389 gfx::Size size = content_view_core_->GetViewportSizeDip(); 390 gfx::Size offset = content_view_core_->GetViewportSizeOffsetDip(); 391 size.Enlarge(-offset.width(), -offset.height()); 392 393 return gfx::Rect(size); 394 } 395 396 gfx::Size RenderWidgetHostViewAndroid::GetPhysicalBackingSize() const { 397 if (!content_view_core_) 398 return gfx::Size(); 399 400 return content_view_core_->GetPhysicalBackingSize(); 401 } 402 403 float RenderWidgetHostViewAndroid::GetOverdrawBottomHeight() const { 404 if (!content_view_core_) 405 return 0.f; 406 407 return content_view_core_->GetOverdrawBottomHeightDip(); 408 } 409 410 void RenderWidgetHostViewAndroid::UpdateCursor(const WebCursor& cursor) { 411 // There are no cursors on Android. 412 } 413 414 void RenderWidgetHostViewAndroid::SetIsLoading(bool is_loading) { 415 // Do nothing. The UI notification is handled through ContentViewClient which 416 // is TabContentsDelegate. 417 } 418 419 void RenderWidgetHostViewAndroid::TextInputTypeChanged( 420 ui::TextInputType type, 421 ui::TextInputMode input_mode, 422 bool can_compose_inline) { 423 // Unused on Android, which uses OnTextInputChanged instead. 424 } 425 426 int RenderWidgetHostViewAndroid::GetNativeImeAdapter() { 427 return reinterpret_cast<int>(&ime_adapter_android_); 428 } 429 430 void RenderWidgetHostViewAndroid::OnTextInputStateChanged( 431 const ViewHostMsg_TextInputState_Params& params) { 432 // If an acknowledgement is required for this event, regardless of how we exit 433 // from this method, we must acknowledge that we processed the input state 434 // change. 435 base::ScopedClosureRunner ack_caller; 436 if (params.require_ack) 437 ack_caller.Reset(base::Bind(&SendImeEventAck, host_)); 438 439 if (!IsShowing()) 440 return; 441 442 content_view_core_->UpdateImeAdapter( 443 GetNativeImeAdapter(), 444 static_cast<int>(params.type), 445 params.value, params.selection_start, params.selection_end, 446 params.composition_start, params.composition_end, 447 params.show_ime_if_needed, params.require_ack); 448 } 449 450 void RenderWidgetHostViewAndroid::OnDidChangeBodyBackgroundColor( 451 SkColor color) { 452 if (cached_background_color_ == color) 453 return; 454 455 cached_background_color_ = color; 456 if (content_view_core_) 457 content_view_core_->OnBackgroundColorChanged(color); 458 } 459 460 void RenderWidgetHostViewAndroid::SendBeginFrame( 461 const cc::BeginFrameArgs& args) { 462 TRACE_EVENT0("cc", "RenderWidgetHostViewAndroid::SendBeginFrame"); 463 if (!host_) 464 return; 465 466 if (flush_input_requested_) { 467 flush_input_requested_ = false; 468 host_->FlushInput(); 469 content_view_core_->RemoveBeginFrameSubscriber(); 470 } 471 472 host_->Send(new ViewMsg_BeginFrame(host_->GetRoutingID(), args)); 473 } 474 475 void RenderWidgetHostViewAndroid::OnSetNeedsBeginFrame( 476 bool enabled) { 477 TRACE_EVENT1("cc", "RenderWidgetHostViewAndroid::OnSetNeedsBeginFrame", 478 "enabled", enabled); 479 // ContentViewCoreImpl handles multiple subscribers to the BeginFrame, so 480 // we have to make sure calls to ContentViewCoreImpl's 481 // {Add,Remove}BeginFrameSubscriber are balanced, even if 482 // RenderWidgetHostViewAndroid's may not be. 483 if (content_view_core_ && needs_begin_frame_ != enabled) { 484 if (enabled) 485 content_view_core_->AddBeginFrameSubscriber(); 486 else 487 content_view_core_->RemoveBeginFrameSubscriber(); 488 needs_begin_frame_ = enabled; 489 } 490 } 491 492 void RenderWidgetHostViewAndroid::OnStartContentIntent( 493 const GURL& content_url) { 494 if (content_view_core_) 495 content_view_core_->StartContentIntent(content_url); 496 } 497 498 void RenderWidgetHostViewAndroid::OnSmartClipDataExtracted( 499 const string16& result) { 500 // Custom serialization over IPC isn't allowed normally for security reasons. 501 // Since this feature is only used in (single-process) WebView, there are no 502 // security issues. Enforce that it's only called in single process mode. 503 CHECK(RenderProcessHost::run_renderer_in_process()); 504 if (content_view_core_) 505 content_view_core_->OnSmartClipDataExtracted(result); 506 } 507 508 void RenderWidgetHostViewAndroid::ImeCancelComposition() { 509 ime_adapter_android_.CancelComposition(); 510 } 511 512 void RenderWidgetHostViewAndroid::DidUpdateBackingStore( 513 const gfx::Rect& scroll_rect, 514 const gfx::Vector2d& scroll_delta, 515 const std::vector<gfx::Rect>& copy_rects, 516 const ui::LatencyInfo& latency_info) { 517 NOTIMPLEMENTED(); 518 } 519 520 void RenderWidgetHostViewAndroid::RenderProcessGone( 521 base::TerminationStatus status, int error_code) { 522 Destroy(); 523 } 524 525 void RenderWidgetHostViewAndroid::Destroy() { 526 RemoveLayers(); 527 SetContentViewCore(NULL); 528 529 // The RenderWidgetHost's destruction led here, so don't call it. 530 host_ = NULL; 531 532 delete this; 533 } 534 535 void RenderWidgetHostViewAndroid::SetTooltipText( 536 const base::string16& tooltip_text) { 537 // Tooltips don't makes sense on Android. 538 } 539 540 void RenderWidgetHostViewAndroid::SelectionChanged(const base::string16& text, 541 size_t offset, 542 const gfx::Range& range) { 543 RenderWidgetHostViewBase::SelectionChanged(text, offset, range); 544 545 if (text.empty() || range.is_empty() || !content_view_core_) 546 return; 547 size_t pos = range.GetMin() - offset; 548 size_t n = range.length(); 549 550 DCHECK(pos + n <= text.length()) << "The text can not fully cover range."; 551 if (pos >= text.length()) { 552 NOTREACHED() << "The text can not cover range."; 553 return; 554 } 555 556 std::string utf8_selection = UTF16ToUTF8(text.substr(pos, n)); 557 558 content_view_core_->OnSelectionChanged(utf8_selection); 559 } 560 561 void RenderWidgetHostViewAndroid::SelectionBoundsChanged( 562 const ViewHostMsg_SelectionBounds_Params& params) { 563 if (content_view_core_) { 564 content_view_core_->OnSelectionBoundsChanged(params); 565 } 566 } 567 568 void RenderWidgetHostViewAndroid::ScrollOffsetChanged() { 569 } 570 571 BackingStore* RenderWidgetHostViewAndroid::AllocBackingStore( 572 const gfx::Size& size) { 573 NOTIMPLEMENTED(); 574 return NULL; 575 } 576 577 void RenderWidgetHostViewAndroid::SetBackground(const SkBitmap& background) { 578 RenderWidgetHostViewBase::SetBackground(background); 579 host_->Send(new ViewMsg_SetBackground(host_->GetRoutingID(), background)); 580 } 581 582 void RenderWidgetHostViewAndroid::CopyFromCompositingSurface( 583 const gfx::Rect& src_subrect, 584 const gfx::Size& dst_size, 585 const base::Callback<void(bool, const SkBitmap&)>& callback) { 586 if (!using_synchronous_compositor_ && !IsSurfaceAvailableForCopy()) { 587 callback.Run(false, SkBitmap()); 588 return; 589 } 590 591 const gfx::Display& display = 592 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay(); 593 float device_scale_factor = display.device_scale_factor(); 594 595 DCHECK_EQ(device_scale_factor, 596 ui::GetImageScale(GetScaleFactorForView(this))); 597 598 const gfx::Size& dst_size_in_pixel = ConvertViewSizeToPixel(this, dst_size); 599 gfx::Rect src_subrect_in_pixel = 600 ConvertRectToPixel(device_scale_factor, src_subrect); 601 602 if (using_synchronous_compositor_) { 603 SynchronousCopyContents(src_subrect_in_pixel, dst_size_in_pixel, callback); 604 return; 605 } 606 607 scoped_ptr<cc::CopyOutputRequest> request; 608 if (src_subrect_in_pixel.size() == dst_size_in_pixel) { 609 request = cc::CopyOutputRequest::CreateBitmapRequest(base::Bind( 610 &RenderWidgetHostViewAndroid::PrepareBitmapCopyOutputResult, 611 dst_size_in_pixel, 612 callback)); 613 } else { 614 request = cc::CopyOutputRequest::CreateRequest(base::Bind( 615 &RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResult, 616 dst_size_in_pixel, 617 callback)); 618 } 619 request->set_area(src_subrect_in_pixel); 620 layer_->RequestCopyOfOutput(request.Pass()); 621 } 622 623 void RenderWidgetHostViewAndroid::CopyFromCompositingSurfaceToVideoFrame( 624 const gfx::Rect& src_subrect, 625 const scoped_refptr<media::VideoFrame>& target, 626 const base::Callback<void(bool)>& callback) { 627 NOTIMPLEMENTED(); 628 callback.Run(false); 629 } 630 631 bool RenderWidgetHostViewAndroid::CanCopyToVideoFrame() const { 632 return false; 633 } 634 635 void RenderWidgetHostViewAndroid::ShowDisambiguationPopup( 636 const gfx::Rect& target_rect, const SkBitmap& zoomed_bitmap) { 637 if (!content_view_core_) 638 return; 639 640 content_view_core_->ShowDisambiguationPopup(target_rect, zoomed_bitmap); 641 } 642 643 scoped_ptr<SyntheticGestureTarget> 644 RenderWidgetHostViewAndroid::CreateSyntheticGestureTarget() { 645 return scoped_ptr<SyntheticGestureTarget>(new SyntheticGestureTargetAndroid( 646 host_, content_view_core_->CreateTouchEventSynthesizer())); 647 } 648 649 void RenderWidgetHostViewAndroid::OnAcceleratedCompositingStateChange() { 650 } 651 652 void RenderWidgetHostViewAndroid::SendDelegatedFrameAck( 653 uint32 output_surface_id) { 654 cc::CompositorFrameAck ack; 655 if (resource_collection_.get()) 656 resource_collection_->TakeUnusedResourcesForChildCompositor(&ack.resources); 657 RenderWidgetHostImpl::SendSwapCompositorFrameAck(host_->GetRoutingID(), 658 output_surface_id, 659 host_->GetProcess()->GetID(), 660 ack); 661 } 662 663 void RenderWidgetHostViewAndroid::UnusedResourcesAreAvailable() { 664 // TODO(danakj): If no ack is pending, collect and send resources now. 665 } 666 667 void RenderWidgetHostViewAndroid::DestroyDelegatedContent() { 668 if (are_layers_attached_) 669 RemoveLayers(); 670 frame_provider_ = NULL; 671 delegated_renderer_layer_ = NULL; 672 layer_ = NULL; 673 } 674 675 void RenderWidgetHostViewAndroid::SwapDelegatedFrame( 676 uint32 output_surface_id, 677 scoped_ptr<cc::DelegatedFrameData> frame_data) { 678 bool has_content = !texture_size_in_layer_.IsEmpty(); 679 680 if (output_surface_id != last_output_surface_id_) { 681 // TODO(danakj): Lose all resources and send them back here, such as: 682 // resource_collection_->LoseAllResources(); 683 // SendReturnedDelegatedResources(last_output_surface_id_); 684 685 // Drop the cc::DelegatedFrameResourceCollection so that we will not return 686 // any resources from the old output surface with the new output surface id. 687 if (resource_collection_.get()) { 688 resource_collection_->SetClient(NULL); 689 resource_collection_ = NULL; 690 } 691 DestroyDelegatedContent(); 692 693 last_output_surface_id_ = output_surface_id; 694 } 695 696 if (!has_content) { 697 DestroyDelegatedContent(); 698 } else { 699 if (!resource_collection_.get()) { 700 resource_collection_ = new cc::DelegatedFrameResourceCollection; 701 resource_collection_->SetClient(this); 702 } 703 if (!frame_provider_ || 704 texture_size_in_layer_ != frame_provider_->frame_size()) { 705 if (are_layers_attached_) 706 RemoveLayers(); 707 frame_provider_ = new cc::DelegatedFrameProvider( 708 resource_collection_.get(), frame_data.Pass()); 709 delegated_renderer_layer_ = 710 cc::DelegatedRendererLayer::Create(frame_provider_); 711 layer_ = delegated_renderer_layer_; 712 if (are_layers_attached_) 713 AttachLayers(); 714 } else { 715 frame_provider_->SetFrameData(frame_data.Pass()); 716 } 717 } 718 719 if (delegated_renderer_layer_.get()) { 720 delegated_renderer_layer_->SetDisplaySize(texture_size_in_layer_); 721 delegated_renderer_layer_->SetIsDrawable(true); 722 delegated_renderer_layer_->SetContentsOpaque(true); 723 delegated_renderer_layer_->SetBounds(content_size_in_layer_); 724 delegated_renderer_layer_->SetNeedsDisplay(); 725 } 726 727 base::Closure ack_callback = 728 base::Bind(&RenderWidgetHostViewAndroid::SendDelegatedFrameAck, 729 weak_ptr_factory_.GetWeakPtr(), 730 output_surface_id); 731 732 if (host_->is_hidden()) 733 ack_callback.Run(); 734 else 735 ack_callbacks_.push(ack_callback); 736 } 737 738 void RenderWidgetHostViewAndroid::ComputeContentsSize( 739 const cc::CompositorFrameMetadata& frame_metadata) { 740 // Calculate the content size. This should be 0 if the texture_size is 0. 741 gfx::Vector2dF offset; 742 if (texture_size_in_layer_.GetArea() > 0) 743 offset = frame_metadata.location_bar_content_translation; 744 offset.set_y(offset.y() + frame_metadata.overdraw_bottom_height); 745 offset.Scale(frame_metadata.device_scale_factor); 746 content_size_in_layer_ = 747 gfx::Size(texture_size_in_layer_.width() - offset.x(), 748 texture_size_in_layer_.height() - offset.y()); 749 // Content size changes should be reflected in associated animation effects. 750 UpdateAnimationSize(frame_metadata); 751 } 752 753 void RenderWidgetHostViewAndroid::OnSwapCompositorFrame( 754 uint32 output_surface_id, 755 scoped_ptr<cc::CompositorFrame> frame) { 756 // Always let ContentViewCore know about the new frame first, so it can decide 757 // to schedule a Draw immediately when it sees the texture layer invalidation. 758 UpdateContentViewCoreFrameMetadata(frame->metadata); 759 760 if (frame->delegated_frame_data) { 761 DCHECK(UsingDelegatedRenderer()); 762 763 DCHECK(frame->delegated_frame_data); 764 DCHECK(!frame->delegated_frame_data->render_pass_list.empty()); 765 766 cc::RenderPass* root_pass = 767 frame->delegated_frame_data->render_pass_list.back(); 768 texture_size_in_layer_ = root_pass->output_rect.size(); 769 ComputeContentsSize(frame->metadata); 770 771 SwapDelegatedFrame(output_surface_id, frame->delegated_frame_data.Pass()); 772 return; 773 } 774 775 DCHECK(!UsingDelegatedRenderer()); 776 777 if (!frame->gl_frame_data || frame->gl_frame_data->mailbox.IsZero()) 778 return; 779 780 if (output_surface_id != last_output_surface_id_) { 781 current_mailbox_ = gpu::Mailbox(); 782 last_output_surface_id_ = kUndefinedOutputSurfaceId; 783 } 784 785 base::Closure callback = base::Bind(&InsertSyncPointAndAckForCompositor, 786 host_->GetProcess()->GetID(), 787 output_surface_id, 788 host_->GetRoutingID(), 789 current_mailbox_, 790 texture_size_in_layer_); 791 ImageTransportFactoryAndroid::GetInstance()->WaitSyncPoint( 792 frame->gl_frame_data->sync_point); 793 794 texture_size_in_layer_ = frame->gl_frame_data->size; 795 ComputeContentsSize(frame->metadata); 796 797 if (layer_->layer_tree_host()) { 798 scoped_ptr<cc::SwapPromise> swap_promise( 799 new cc::LatencyInfoSwapPromise(frame->metadata.latency_info)); 800 layer_->layer_tree_host()->QueueSwapPromise(swap_promise.Pass()); 801 } 802 803 BuffersSwapped(frame->gl_frame_data->mailbox, output_surface_id, callback); 804 } 805 806 void RenderWidgetHostViewAndroid::SynchronousFrameMetadata( 807 const cc::CompositorFrameMetadata& frame_metadata) { 808 // This is a subset of OnSwapCompositorFrame() used in the synchronous 809 // compositor flow. 810 UpdateContentViewCoreFrameMetadata(frame_metadata); 811 ComputeContentsSize(frame_metadata); 812 813 // DevTools ScreenCast support for Android WebView. 814 if (DevToolsAgentHost::HasFor(RenderViewHost::From(GetRenderWidgetHost()))) { 815 scoped_refptr<DevToolsAgentHost> dtah = 816 DevToolsAgentHost::GetOrCreateFor( 817 RenderViewHost::From(GetRenderWidgetHost())); 818 // Unblock the compositor. 819 BrowserThread::PostTask( 820 BrowserThread::UI, FROM_HERE, 821 base::Bind(&RenderViewDevToolsAgentHost::SynchronousSwapCompositorFrame, 822 static_cast<RenderViewDevToolsAgentHost*>(dtah.get()), 823 frame_metadata)); 824 } 825 } 826 827 void RenderWidgetHostViewAndroid::SynchronousCopyContents( 828 const gfx::Rect& src_subrect_in_pixel, 829 const gfx::Size& dst_size_in_pixel, 830 const base::Callback<void(bool, const SkBitmap&)>& callback) { 831 SynchronousCompositor* compositor = 832 SynchronousCompositorImpl::FromID(host_->GetProcess()->GetID(), 833 host_->GetRoutingID()); 834 if (!compositor) { 835 callback.Run(false, SkBitmap()); 836 return; 837 } 838 839 SkBitmap bitmap; 840 bitmap.setConfig(SkBitmap::kARGB_8888_Config, 841 dst_size_in_pixel.width(), 842 dst_size_in_pixel.height()); 843 bitmap.allocPixels(); 844 SkCanvas canvas(bitmap); 845 canvas.scale( 846 (float)dst_size_in_pixel.width() / (float)src_subrect_in_pixel.width(), 847 (float)dst_size_in_pixel.height() / (float)src_subrect_in_pixel.height()); 848 compositor->DemandDrawSw(&canvas); 849 callback.Run(true, bitmap); 850 } 851 852 void RenderWidgetHostViewAndroid::UpdateContentViewCoreFrameMetadata( 853 const cc::CompositorFrameMetadata& frame_metadata) { 854 if (content_view_core_) { 855 // All offsets and sizes are in CSS pixels. 856 content_view_core_->UpdateFrameInfo( 857 frame_metadata.root_scroll_offset, 858 frame_metadata.page_scale_factor, 859 gfx::Vector2dF(frame_metadata.min_page_scale_factor, 860 frame_metadata.max_page_scale_factor), 861 frame_metadata.root_layer_size, 862 frame_metadata.viewport_size, 863 frame_metadata.location_bar_offset, 864 frame_metadata.location_bar_content_translation, 865 frame_metadata.overdraw_bottom_height); 866 } 867 } 868 869 void RenderWidgetHostViewAndroid::AcceleratedSurfaceInitialized(int host_id, 870 int route_id) { 871 accelerated_surface_route_id_ = route_id; 872 } 873 874 void RenderWidgetHostViewAndroid::AcceleratedSurfaceBuffersSwapped( 875 const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params, 876 int gpu_host_id) { 877 NOTREACHED() << "Need --composite-to-mailbox or --enable-delegated-renderer"; 878 } 879 880 void RenderWidgetHostViewAndroid::BuffersSwapped( 881 const gpu::Mailbox& mailbox, 882 uint32_t output_surface_id, 883 const base::Closure& ack_callback) { 884 ImageTransportFactoryAndroid* factory = 885 ImageTransportFactoryAndroid::GetInstance(); 886 887 if (!texture_id_in_layer_) { 888 texture_id_in_layer_ = factory->CreateTexture(); 889 texture_layer_->SetTextureId(texture_id_in_layer_); 890 texture_layer_->SetIsDrawable(true); 891 texture_layer_->SetContentsOpaque(true); 892 } 893 894 ImageTransportFactoryAndroid::GetInstance()->AcquireTexture( 895 texture_id_in_layer_, mailbox.name); 896 897 ResetClipping(); 898 899 current_mailbox_ = mailbox; 900 last_output_surface_id_ = output_surface_id; 901 902 if (host_->is_hidden()) 903 ack_callback.Run(); 904 else 905 ack_callbacks_.push(ack_callback); 906 } 907 908 void RenderWidgetHostViewAndroid::AttachLayers() { 909 if (!content_view_core_) 910 return; 911 if (!layer_.get()) 912 return; 913 914 content_view_core_->AttachLayer(layer_); 915 if (overscroll_effect_enabled_) 916 overscroll_effect_->Enable(); 917 } 918 919 void RenderWidgetHostViewAndroid::RemoveLayers() { 920 if (!content_view_core_) 921 return; 922 if (!layer_.get()) 923 return; 924 925 content_view_core_->RemoveLayer(layer_); 926 overscroll_effect_->Disable(); 927 } 928 929 bool RenderWidgetHostViewAndroid::Animate(base::TimeTicks frame_time) { 930 return overscroll_effect_->Animate(frame_time); 931 } 932 933 void RenderWidgetHostViewAndroid::UpdateAnimationSize( 934 const cc::CompositorFrameMetadata& frame_metadata) { 935 // Disable edge effects for axes on which scrolling is impossible. 936 gfx::SizeF ceiled_viewport_size = 937 gfx::ToCeiledSize(frame_metadata.viewport_size); 938 overscroll_effect_->set_horizontal_overscroll_enabled( 939 ceiled_viewport_size.width() < frame_metadata.root_layer_size.width()); 940 overscroll_effect_->set_vertical_overscroll_enabled( 941 ceiled_viewport_size.height() < frame_metadata.root_layer_size.height()); 942 overscroll_effect_->set_size(content_size_in_layer_); 943 } 944 945 void RenderWidgetHostViewAndroid::AcceleratedSurfacePostSubBuffer( 946 const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params, 947 int gpu_host_id) { 948 NOTREACHED(); 949 } 950 951 void RenderWidgetHostViewAndroid::AcceleratedSurfaceSuspend() { 952 NOTREACHED(); 953 } 954 955 void RenderWidgetHostViewAndroid::AcceleratedSurfaceRelease() { 956 // This tells us we should free the frontbuffer. 957 if (texture_id_in_layer_) { 958 texture_layer_->SetTextureId(0); 959 texture_layer_->SetIsDrawable(false); 960 ImageTransportFactoryAndroid::GetInstance()->DeleteTexture( 961 texture_id_in_layer_); 962 texture_id_in_layer_ = 0; 963 current_mailbox_ = gpu::Mailbox(); 964 last_output_surface_id_ = kUndefinedOutputSurfaceId; 965 } 966 if (delegated_renderer_layer_.get()) 967 DestroyDelegatedContent(); 968 } 969 970 bool RenderWidgetHostViewAndroid::HasAcceleratedSurface( 971 const gfx::Size& desired_size) { 972 NOTREACHED(); 973 return false; 974 } 975 976 void RenderWidgetHostViewAndroid::GetScreenInfo(blink::WebScreenInfo* result) { 977 // ScreenInfo isn't tied to the widget on Android. Always return the default. 978 RenderWidgetHostViewBase::GetDefaultScreenInfo(result); 979 } 980 981 // TODO(jrg): Find out the implications and answer correctly here, 982 // as we are returning the WebView and not root window bounds. 983 gfx::Rect RenderWidgetHostViewAndroid::GetBoundsInRootWindow() { 984 return GetViewBounds(); 985 } 986 987 gfx::GLSurfaceHandle RenderWidgetHostViewAndroid::GetCompositingSurface() { 988 gfx::GLSurfaceHandle handle = 989 gfx::GLSurfaceHandle(gfx::kNullPluginWindow, gfx::NATIVE_TRANSPORT); 990 if (CompositorImpl::IsInitialized()) { 991 handle.parent_client_id = 992 ImageTransportFactoryAndroid::GetInstance()->GetChannelID(); 993 } 994 return handle; 995 } 996 997 void RenderWidgetHostViewAndroid::ProcessAckedTouchEvent( 998 const TouchEventWithLatencyInfo& touch, InputEventAckState ack_result) { 999 if (content_view_core_) 1000 content_view_core_->ConfirmTouchEvent(ack_result); 1001 } 1002 1003 void RenderWidgetHostViewAndroid::SetHasHorizontalScrollbar( 1004 bool has_horizontal_scrollbar) { 1005 // intentionally empty, like RenderWidgetHostViewViews 1006 } 1007 1008 void RenderWidgetHostViewAndroid::SetScrollOffsetPinning( 1009 bool is_pinned_to_left, bool is_pinned_to_right) { 1010 // intentionally empty, like RenderWidgetHostViewViews 1011 } 1012 1013 void RenderWidgetHostViewAndroid::UnhandledWheelEvent( 1014 const blink::WebMouseWheelEvent& event) { 1015 // intentionally empty, like RenderWidgetHostViewViews 1016 } 1017 1018 void RenderWidgetHostViewAndroid::GestureEventAck( 1019 int gesture_event_type, 1020 InputEventAckState ack_result) { 1021 if (gesture_event_type == blink::WebInputEvent::GestureScrollUpdate && 1022 ack_result == INPUT_EVENT_ACK_STATE_CONSUMED) { 1023 content_view_core_->OnScrollUpdateGestureConsumed(); 1024 } 1025 if (gesture_event_type == blink::WebInputEvent::GestureFlingStart && 1026 ack_result == INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS) { 1027 content_view_core_->UnhandledFlingStartEvent(); 1028 } 1029 } 1030 1031 InputEventAckState RenderWidgetHostViewAndroid::FilterInputEvent( 1032 const blink::WebInputEvent& input_event) { 1033 if (!host_) 1034 return INPUT_EVENT_ACK_STATE_NOT_CONSUMED; 1035 1036 if (input_event.type == blink::WebInputEvent::GestureTapDown || 1037 input_event.type == blink::WebInputEvent::TouchStart) { 1038 GpuDataManagerImpl* gpu_data = GpuDataManagerImpl::GetInstance(); 1039 GpuProcessHostUIShim* shim = GpuProcessHostUIShim::GetOneInstance(); 1040 if (shim && gpu_data && accelerated_surface_route_id_ && 1041 gpu_data->IsDriverBugWorkaroundActive(gpu::WAKE_UP_GPU_BEFORE_DRAWING)) 1042 shim->Send( 1043 new AcceleratedSurfaceMsg_WakeUpGpu(accelerated_surface_route_id_)); 1044 } 1045 1046 SynchronousCompositorImpl* compositor = 1047 SynchronousCompositorImpl::FromID(host_->GetProcess()->GetID(), 1048 host_->GetRoutingID()); 1049 if (compositor) 1050 return compositor->HandleInputEvent(input_event); 1051 return INPUT_EVENT_ACK_STATE_NOT_CONSUMED; 1052 } 1053 1054 void RenderWidgetHostViewAndroid::OnSetNeedsFlushInput() { 1055 if (flush_input_requested_ || !content_view_core_) 1056 return; 1057 flush_input_requested_ = true; 1058 content_view_core_->AddBeginFrameSubscriber(); 1059 } 1060 1061 void RenderWidgetHostViewAndroid::OnAccessibilityEvents( 1062 const std::vector<AccessibilityHostMsg_EventParams>& params) { 1063 if (!host_ || host_->accessibility_mode() != AccessibilityModeComplete) 1064 return; 1065 1066 if (!GetBrowserAccessibilityManager()) { 1067 base::android::ScopedJavaLocalRef<jobject> obj; 1068 if (content_view_core_) 1069 obj = content_view_core_->GetJavaObject(); 1070 SetBrowserAccessibilityManager( 1071 new BrowserAccessibilityManagerAndroid( 1072 obj, BrowserAccessibilityManagerAndroid::GetEmptyDocument(), this)); 1073 } 1074 GetBrowserAccessibilityManager()->OnAccessibilityEvents(params); 1075 } 1076 1077 void RenderWidgetHostViewAndroid::SetAccessibilityFocus(int acc_obj_id) { 1078 if (!host_) 1079 return; 1080 1081 host_->AccessibilitySetFocus(acc_obj_id); 1082 } 1083 1084 void RenderWidgetHostViewAndroid::AccessibilityDoDefaultAction(int acc_obj_id) { 1085 if (!host_) 1086 return; 1087 1088 host_->AccessibilityDoDefaultAction(acc_obj_id); 1089 } 1090 1091 void RenderWidgetHostViewAndroid::AccessibilityScrollToMakeVisible( 1092 int acc_obj_id, gfx::Rect subfocus) { 1093 if (!host_) 1094 return; 1095 1096 host_->AccessibilityScrollToMakeVisible(acc_obj_id, subfocus); 1097 } 1098 1099 void RenderWidgetHostViewAndroid::AccessibilityScrollToPoint( 1100 int acc_obj_id, gfx::Point point) { 1101 if (!host_) 1102 return; 1103 1104 host_->AccessibilityScrollToPoint(acc_obj_id, point); 1105 } 1106 1107 void RenderWidgetHostViewAndroid::AccessibilitySetTextSelection( 1108 int acc_obj_id, int start_offset, int end_offset) { 1109 if (!host_) 1110 return; 1111 1112 host_->AccessibilitySetTextSelection( 1113 acc_obj_id, start_offset, end_offset); 1114 } 1115 1116 gfx::Point RenderWidgetHostViewAndroid::GetLastTouchEventLocation() const { 1117 NOTIMPLEMENTED(); 1118 // Only used on Win8 1119 return gfx::Point(); 1120 } 1121 1122 void RenderWidgetHostViewAndroid::FatalAccessibilityTreeError() { 1123 if (!host_) 1124 return; 1125 1126 host_->FatalAccessibilityTreeError(); 1127 SetBrowserAccessibilityManager(NULL); 1128 } 1129 1130 bool RenderWidgetHostViewAndroid::LockMouse() { 1131 NOTIMPLEMENTED(); 1132 return false; 1133 } 1134 1135 void RenderWidgetHostViewAndroid::UnlockMouse() { 1136 NOTIMPLEMENTED(); 1137 } 1138 1139 // Methods called from the host to the render 1140 1141 void RenderWidgetHostViewAndroid::SendKeyEvent( 1142 const NativeWebKeyboardEvent& event) { 1143 if (host_) 1144 host_->ForwardKeyboardEvent(event); 1145 } 1146 1147 void RenderWidgetHostViewAndroid::SendTouchEvent( 1148 const blink::WebTouchEvent& event) { 1149 if (host_) 1150 host_->ForwardTouchEventWithLatencyInfo(event, ui::LatencyInfo()); 1151 } 1152 1153 1154 void RenderWidgetHostViewAndroid::SendMouseEvent( 1155 const blink::WebMouseEvent& event) { 1156 if (host_) 1157 host_->ForwardMouseEvent(event); 1158 } 1159 1160 void RenderWidgetHostViewAndroid::SendMouseWheelEvent( 1161 const blink::WebMouseWheelEvent& event) { 1162 if (host_) 1163 host_->ForwardWheelEvent(event); 1164 } 1165 1166 void RenderWidgetHostViewAndroid::SendGestureEvent( 1167 const blink::WebGestureEvent& event) { 1168 // Sending a gesture that may trigger overscroll should resume the effect. 1169 if (overscroll_effect_enabled_) 1170 overscroll_effect_->Enable(); 1171 1172 if (host_) 1173 host_->ForwardGestureEvent(event); 1174 } 1175 1176 void RenderWidgetHostViewAndroid::SelectRange(const gfx::Point& start, 1177 const gfx::Point& end) { 1178 if (host_) 1179 host_->SelectRange(start, end); 1180 } 1181 1182 void RenderWidgetHostViewAndroid::MoveCaret(const gfx::Point& point) { 1183 if (host_) 1184 host_->MoveCaret(point); 1185 } 1186 1187 void RenderWidgetHostViewAndroid::RequestContentClipping( 1188 const gfx::Rect& clipping, 1189 const gfx::Size& content_size) { 1190 // A focused view provides its own clipping. 1191 if (HasFocus()) 1192 return; 1193 1194 ClipContents(clipping, content_size); 1195 } 1196 1197 void RenderWidgetHostViewAndroid::ResetClipping() { 1198 ClipContents(gfx::Rect(gfx::Point(), content_size_in_layer_), 1199 content_size_in_layer_); 1200 } 1201 1202 void RenderWidgetHostViewAndroid::ClipContents(const gfx::Rect& clipping, 1203 const gfx::Size& content_size) { 1204 if (!texture_id_in_layer_ || content_size_in_layer_.IsEmpty()) 1205 return; 1206 1207 gfx::Size clipped_content(content_size_in_layer_); 1208 clipped_content.SetToMin(clipping.size()); 1209 texture_layer_->SetBounds(clipped_content); 1210 texture_layer_->SetNeedsDisplay(); 1211 1212 if (texture_size_in_layer_.IsEmpty()) { 1213 texture_layer_->SetUV(gfx::PointF(), gfx::PointF()); 1214 return; 1215 } 1216 1217 gfx::PointF offset( 1218 clipping.x() + content_size_in_layer_.width() - content_size.width(), 1219 clipping.y() + content_size_in_layer_.height() - content_size.height()); 1220 offset.SetToMax(gfx::PointF()); 1221 1222 gfx::Vector2dF uv_scale(1.f / texture_size_in_layer_.width(), 1223 1.f / texture_size_in_layer_.height()); 1224 texture_layer_->SetUV( 1225 gfx::PointF(offset.x() * uv_scale.x(), 1226 offset.y() * uv_scale.y()), 1227 gfx::PointF((offset.x() + clipped_content.width()) * uv_scale.x(), 1228 (offset.y() + clipped_content.height()) * uv_scale.y())); 1229 } 1230 1231 SkColor RenderWidgetHostViewAndroid::GetCachedBackgroundColor() const { 1232 return cached_background_color_; 1233 } 1234 1235 void RenderWidgetHostViewAndroid::OnOverscrolled( 1236 gfx::Vector2dF accumulated_overscroll, 1237 gfx::Vector2dF current_fling_velocity) { 1238 if (!content_view_core_ || !are_layers_attached_) 1239 return; 1240 1241 if (overscroll_effect_->OnOverscrolled(content_view_core_->GetLayer(), 1242 base::TimeTicks::Now(), 1243 accumulated_overscroll, 1244 current_fling_velocity)) { 1245 content_view_core_->SetNeedsAnimate(); 1246 } 1247 } 1248 1249 void RenderWidgetHostViewAndroid::SetContentViewCore( 1250 ContentViewCoreImpl* content_view_core) { 1251 RunAckCallbacks(); 1252 1253 if (are_layers_attached_) 1254 RemoveLayers(); 1255 1256 if (content_view_core_ && !using_synchronous_compositor_) 1257 content_view_core_->GetWindowAndroid()->RemoveObserver(this); 1258 1259 content_view_core_ = content_view_core; 1260 1261 if (GetBrowserAccessibilityManager()) { 1262 base::android::ScopedJavaLocalRef<jobject> obj; 1263 if (content_view_core_) 1264 obj = content_view_core_->GetJavaObject(); 1265 GetBrowserAccessibilityManager()->ToBrowserAccessibilityManagerAndroid()-> 1266 SetContentViewCore(obj); 1267 } 1268 1269 if (are_layers_attached_) { 1270 AttachLayers(); 1271 if (content_view_core_ && !using_synchronous_compositor_) 1272 content_view_core_->GetWindowAndroid()->AddObserver(this); 1273 } 1274 1275 // Ensure ContentsViewCore is aware of the current touch handling state, eg. 1276 // in case we've already been running JS for the page as part of preload. 1277 if (content_view_core_ && host_) 1278 content_view_core_->HasTouchEventHandlers(host_->has_touch_handler()); 1279 } 1280 1281 void RenderWidgetHostViewAndroid::RunAckCallbacks() { 1282 while (!ack_callbacks_.empty()) { 1283 ack_callbacks_.front().Run(); 1284 ack_callbacks_.pop(); 1285 } 1286 } 1287 1288 void RenderWidgetHostViewAndroid::HasTouchEventHandlers( 1289 bool need_touch_events) { 1290 if (content_view_core_) 1291 content_view_core_->HasTouchEventHandlers(need_touch_events); 1292 } 1293 1294 void RenderWidgetHostViewAndroid::OnCompositingDidCommit() { 1295 RunAckCallbacks(); 1296 } 1297 1298 void RenderWidgetHostViewAndroid::OnDetachCompositor() { 1299 DCHECK(content_view_core_); 1300 DCHECK(!using_synchronous_compositor_); 1301 RunAckCallbacks(); 1302 } 1303 1304 void RenderWidgetHostViewAndroid::OnLostResources() { 1305 if (texture_layer_.get()) 1306 texture_layer_->SetIsDrawable(false); 1307 if (delegated_renderer_layer_.get()) 1308 DestroyDelegatedContent(); 1309 texture_id_in_layer_ = 0; 1310 RunAckCallbacks(); 1311 } 1312 1313 // static 1314 void RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResult( 1315 const gfx::Size& dst_size_in_pixel, 1316 const base::Callback<void(bool, const SkBitmap&)>& callback, 1317 scoped_ptr<cc::CopyOutputResult> result) { 1318 DCHECK(result->HasTexture()); 1319 base::ScopedClosureRunner scoped_callback_runner( 1320 base::Bind(callback, false, SkBitmap())); 1321 1322 if (!result->HasTexture() || result->IsEmpty() || result->size().IsEmpty()) 1323 return; 1324 1325 scoped_ptr<SkBitmap> bitmap(new SkBitmap); 1326 bitmap->setConfig(SkBitmap::kARGB_8888_Config, 1327 dst_size_in_pixel.width(), dst_size_in_pixel.height(), 1328 0, kOpaque_SkAlphaType); 1329 if (!bitmap->allocPixels()) 1330 return; 1331 1332 ImageTransportFactoryAndroid* factory = 1333 ImageTransportFactoryAndroid::GetInstance(); 1334 GLHelper* gl_helper = factory->GetGLHelper(); 1335 if (!gl_helper) 1336 return; 1337 1338 scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock( 1339 new SkAutoLockPixels(*bitmap)); 1340 uint8* pixels = static_cast<uint8*>(bitmap->getPixels()); 1341 1342 cc::TextureMailbox texture_mailbox; 1343 scoped_ptr<cc::SingleReleaseCallback> release_callback; 1344 result->TakeTexture(&texture_mailbox, &release_callback); 1345 DCHECK(texture_mailbox.IsTexture()); 1346 if (!texture_mailbox.IsTexture()) 1347 return; 1348 1349 ignore_result(scoped_callback_runner.Release()); 1350 1351 gl_helper->CropScaleReadbackAndCleanMailbox( 1352 texture_mailbox.name(), 1353 texture_mailbox.sync_point(), 1354 result->size(), 1355 gfx::Rect(result->size()), 1356 dst_size_in_pixel, 1357 pixels, 1358 base::Bind(&CopyFromCompositingSurfaceFinished, 1359 callback, 1360 base::Passed(&release_callback), 1361 base::Passed(&bitmap), 1362 base::Passed(&bitmap_pixels_lock))); 1363 } 1364 1365 // static 1366 void RenderWidgetHostViewAndroid::PrepareBitmapCopyOutputResult( 1367 const gfx::Size& dst_size_in_pixel, 1368 const base::Callback<void(bool, const SkBitmap&)>& callback, 1369 scoped_ptr<cc::CopyOutputResult> result) { 1370 DCHECK(result->HasBitmap()); 1371 base::ScopedClosureRunner scoped_callback_runner( 1372 base::Bind(callback, false, SkBitmap())); 1373 1374 if (!result->HasBitmap() || result->IsEmpty() || result->size().IsEmpty()) 1375 return; 1376 1377 scoped_ptr<SkBitmap> source = result->TakeBitmap(); 1378 DCHECK(source); 1379 if (!source) 1380 return; 1381 1382 DCHECK_EQ(source->width(), dst_size_in_pixel.width()); 1383 DCHECK_EQ(source->height(), dst_size_in_pixel.height()); 1384 1385 ignore_result(scoped_callback_runner.Release()); 1386 callback.Run(true, *source); 1387 } 1388 1389 // static 1390 void RenderWidgetHostViewPort::GetDefaultScreenInfo( 1391 blink::WebScreenInfo* results) { 1392 const gfx::Display& display = 1393 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay(); 1394 results->rect = display.bounds(); 1395 // TODO(husky): Remove any system controls from availableRect. 1396 results->availableRect = display.work_area(); 1397 results->deviceScaleFactor = display.device_scale_factor(); 1398 gfx::DeviceDisplayInfo info; 1399 results->depth = info.GetBitsPerPixel(); 1400 results->depthPerComponent = info.GetBitsPerComponent(); 1401 results->isMonochrome = (results->depthPerComponent == 0); 1402 } 1403 1404 //////////////////////////////////////////////////////////////////////////////// 1405 // RenderWidgetHostView, public: 1406 1407 // static 1408 RenderWidgetHostView* 1409 RenderWidgetHostView::CreateViewForWidget(RenderWidgetHost* widget) { 1410 RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(widget); 1411 return new RenderWidgetHostViewAndroid(rwhi, NULL); 1412 } 1413 1414 } // namespace content 1415