16e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 26e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 36e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// found in the LICENSE file. 46e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 56e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "content/browser/android/system_ui_resource_manager_impl.h" 66e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 76e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/bind.h" 86e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/bind_helpers.h" 903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/debug/trace_event.h" 106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/location.h" 116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/observer_list.h" 126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/threading/worker_pool.h" 136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "cc/resources/ui_resource_bitmap.h" 146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "content/public/browser/android/ui_resource_client_android.h" 156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "content/public/browser/android/ui_resource_provider.h" 166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "third_party/skia/include/core/SkBitmap.h" 1703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "third_party/skia/include/core/SkCanvas.h" 1803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "third_party/skia/include/core/SkPaint.h" 1903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "third_party/skia/include/effects/SkPorterDuff.h" 206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "ui/gfx/android/java_bitmap.h" 2103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "ui/gfx/screen.h" 226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)namespace content { 2403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)namespace { 2503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 2603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)SkBitmap CreateOverscrollGlowLBitmap(const gfx::Size& screen_size) { 2703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const float kSin = 0.5f; // sin(PI / 6) 2803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const float kCos = 0.866f; // cos(PI / 6); 2903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 3003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) SkPaint paint; 3103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) paint.setAntiAlias(true); 321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci paint.setAlpha(0xBB); 3303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) paint.setStyle(SkPaint::kFill_Style); 3403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 3503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const float arc_width = 3603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) std::min(screen_size.width(), screen_size.height()) * 0.5f / kSin; 3703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const float y = kCos * arc_width; 3803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const float height = arc_width - y; 3903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) gfx::Size bounds(arc_width, height); 4003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) SkRect arc_rect = SkRect::MakeXYWH( 4103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) -arc_width / 2.f, -arc_width - y, arc_width * 2.f, arc_width * 2.f); 4203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) SkBitmap glow_bitmap; 431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci glow_bitmap.allocPixels(SkImageInfo::MakeA8(bounds.width(), bounds.height())); 441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci glow_bitmap.eraseColor(SK_ColorTRANSPARENT); 4503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 4603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) SkCanvas canvas(glow_bitmap); 4703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) canvas.clipRect(SkRect::MakeXYWH(0, 0, bounds.width(), bounds.height())); 4803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) canvas.drawArc(arc_rect, 45, 90, true, paint); 4903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return glow_bitmap; 5003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 5103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 5203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void LoadBitmap(ui::SystemUIResourceManager::ResourceType type, 5303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) SkBitmap* bitmap_holder, 5403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const gfx::Size& screen_size) { 5503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) TRACE_EVENT1( 5603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) "browser", "SystemUIResourceManagerImpl::LoadBitmap", "type", type); 5703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) SkBitmap bitmap; 5803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) switch (type) { 5903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) case ui::SystemUIResourceManager::OVERSCROLL_EDGE: 6003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) bitmap = gfx::CreateSkBitmapFromAndroidResource( 6103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) "android:drawable/overscroll_edge", gfx::Size(128, 12)); 6203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) break; 6303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) case ui::SystemUIResourceManager::OVERSCROLL_GLOW: 6403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) bitmap = gfx::CreateSkBitmapFromAndroidResource( 6503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) "android:drawable/overscroll_glow", gfx::Size(128, 64)); 6603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) break; 6703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) case ui::SystemUIResourceManager::OVERSCROLL_GLOW_L: 6803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) bitmap = CreateOverscrollGlowLBitmap(screen_size); 6903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) break; 7003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 7103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) bitmap.setImmutable(); 7203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) *bitmap_holder = bitmap; 7303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 7403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 7503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} // namespace 766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)class SystemUIResourceManagerImpl::Entry 786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) : public content::UIResourceClientAndroid { 796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) public: 806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) explicit Entry(UIResourceProvider* provider) : id_(0), provider_(provider) { 816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DCHECK(provider); 826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) virtual ~Entry() { 856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (id_) 866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) provider_->DeleteUIResource(id_); 876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) id_ = 0; 886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) void SetBitmap(const SkBitmap& bitmap) { 9103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DCHECK(!bitmap.empty()); 926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DCHECK(bitmap_.empty()); 936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DCHECK(!id_); 946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) bitmap_ = bitmap; 956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) cc::UIResourceId GetUIResourceId() { 986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (bitmap_.empty()) 996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return 0; 1006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (!id_) 1016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) id_ = provider_->CreateUIResource(this); 1026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return id_; 1036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 1046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // content::UIResourceClient implementation. 1066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) virtual cc::UIResourceBitmap GetBitmap(cc::UIResourceId uid, 1076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) bool resource_lost) OVERRIDE { 1086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DCHECK(!bitmap_.empty()); 1096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return cc::UIResourceBitmap(bitmap_); 1106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 1116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // content::UIResourceClientAndroid implementation. 1136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) virtual void UIResourceIsInvalid() OVERRIDE { id_ = 0; } 1146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const SkBitmap& bitmap() const { return bitmap_; } 1166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) private: 1186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) SkBitmap bitmap_; 1196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) cc::UIResourceId id_; 1206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) UIResourceProvider* provider_; 1216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(Entry); 1236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}; 1246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)SystemUIResourceManagerImpl::SystemUIResourceManagerImpl( 1266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) UIResourceProvider* ui_resource_provider) 1276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) : ui_resource_provider_(ui_resource_provider), weak_factory_(this) { 1286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 1296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)SystemUIResourceManagerImpl::~SystemUIResourceManagerImpl() { 1316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 1326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void SystemUIResourceManagerImpl::PreloadResource(ResourceType type) { 1346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) GetEntry(type); 1356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 1366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)cc::UIResourceId SystemUIResourceManagerImpl::GetUIResourceId( 1386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ResourceType type) { 1396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return GetEntry(type)->GetUIResourceId(); 1406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 1416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)SystemUIResourceManagerImpl::Entry* SystemUIResourceManagerImpl::GetEntry( 1436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ResourceType type) { 1446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DCHECK_GE(type, RESOURCE_TYPE_FIRST); 1456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DCHECK_LE(type, RESOURCE_TYPE_LAST); 1466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (!resource_map_[type]) { 1476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) resource_map_[type].reset(new Entry(ui_resource_provider_)); 1486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Lazily build the resource. 1496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) BuildResource(type); 1506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 1516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return resource_map_[type].get(); 1526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 1536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void SystemUIResourceManagerImpl::BuildResource(ResourceType type) { 1556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DCHECK(GetEntry(type)->bitmap().empty()); 1566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Instead of blocking the main thread, we post a task to load the bitmap. 1586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) SkBitmap* bitmap = new SkBitmap(); 15903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) gfx::Size screen_size = 16003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().GetSizeInPixel(); 1616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::Closure load_bitmap = 16203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) base::Bind(&LoadBitmap, type, bitmap, screen_size); 1636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::Closure finished_load = 1646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::Bind(&SystemUIResourceManagerImpl::OnFinishedLoadBitmap, 1656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) weak_factory_.GetWeakPtr(), 1666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) type, 1676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::Owned(bitmap)); 1686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::WorkerPool::PostTaskAndReply( 1696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) FROM_HERE, load_bitmap, finished_load, true); 1706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 1716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void SystemUIResourceManagerImpl::OnFinishedLoadBitmap( 1736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ResourceType type, 1746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) SkBitmap* bitmap_holder) { 1756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DCHECK(bitmap_holder); 1766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) GetEntry(type)->SetBitmap(*bitmap_holder); 1776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 1786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} // namespace content 180