1 // Copyright 2014 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/android/system_ui_resource_manager_impl.h"
8 #include "base/bind_helpers.h"
9 #include "base/debug/trace_event.h"
10 #include "base/location.h"
11 #include "base/observer_list.h"
12 #include "base/threading/worker_pool.h"
13 #include "cc/resources/ui_resource_bitmap.h"
14 #include "content/public/browser/android/ui_resource_client_android.h"
15 #include "content/public/browser/android/ui_resource_provider.h"
16 #include "third_party/skia/include/core/SkBitmap.h"
17 #include "third_party/skia/include/core/SkCanvas.h"
18 #include "third_party/skia/include/core/SkPaint.h"
19 #include "third_party/skia/include/effects/SkPorterDuff.h"
20 #include "ui/gfx/android/java_bitmap.h"
21 #include "ui/gfx/screen.h"
26 SkBitmap
CreateOverscrollGlowLBitmap(const gfx::Size
& screen_size
) {
27 const float kSin
= 0.5f
; // sin(PI / 6)
28 const float kCos
= 0.866f
; // cos(PI / 6);
31 paint
.setAntiAlias(true);
33 paint
.setStyle(SkPaint::kFill_Style
);
35 const float arc_width
=
36 std::min(screen_size
.width(), screen_size
.height()) * 0.5f
/ kSin
;
37 const float y
= kCos
* arc_width
;
38 const float height
= arc_width
- y
;
39 gfx::Size
bounds(arc_width
, height
);
40 SkRect arc_rect
= SkRect::MakeXYWH(
41 -arc_width
/ 2.f
, -arc_width
- y
, arc_width
* 2.f
, arc_width
* 2.f
);
43 glow_bitmap
.allocPixels(SkImageInfo::MakeA8(bounds
.width(), bounds
.height()));
44 glow_bitmap
.eraseColor(SK_ColorTRANSPARENT
);
46 SkCanvas
canvas(glow_bitmap
);
47 canvas
.clipRect(SkRect::MakeXYWH(0, 0, bounds
.width(), bounds
.height()));
48 canvas
.drawArc(arc_rect
, 45, 90, true, paint
);
52 void LoadBitmap(ui::SystemUIResourceManager::ResourceType type
,
53 SkBitmap
* bitmap_holder
,
54 const gfx::Size
& screen_size
) {
56 "browser", "SystemUIResourceManagerImpl::LoadBitmap", "type", type
);
59 case ui::SystemUIResourceManager::OVERSCROLL_EDGE
:
60 bitmap
= gfx::CreateSkBitmapFromAndroidResource(
61 "android:drawable/overscroll_edge", gfx::Size(128, 12));
63 case ui::SystemUIResourceManager::OVERSCROLL_GLOW
:
64 bitmap
= gfx::CreateSkBitmapFromAndroidResource(
65 "android:drawable/overscroll_glow", gfx::Size(128, 64));
67 case ui::SystemUIResourceManager::OVERSCROLL_GLOW_L
:
68 bitmap
= CreateOverscrollGlowLBitmap(screen_size
);
71 bitmap
.setImmutable();
72 *bitmap_holder
= bitmap
;
77 class SystemUIResourceManagerImpl::Entry
78 : public content::UIResourceClientAndroid
{
80 explicit Entry(UIResourceProvider
* provider
) : id_(0), provider_(provider
) {
86 provider_
->DeleteUIResource(id_
);
90 void SetBitmap(const SkBitmap
& bitmap
) {
91 DCHECK(!bitmap
.empty());
92 DCHECK(bitmap_
.empty());
97 cc::UIResourceId
GetUIResourceId() {
101 id_
= provider_
->CreateUIResource(this);
105 // content::UIResourceClient implementation.
106 virtual cc::UIResourceBitmap
GetBitmap(cc::UIResourceId uid
,
107 bool resource_lost
) OVERRIDE
{
108 DCHECK(!bitmap_
.empty());
109 return cc::UIResourceBitmap(bitmap_
);
112 // content::UIResourceClientAndroid implementation.
113 virtual void UIResourceIsInvalid() OVERRIDE
{ id_
= 0; }
115 const SkBitmap
& bitmap() const { return bitmap_
; }
119 cc::UIResourceId id_
;
120 UIResourceProvider
* provider_
;
122 DISALLOW_COPY_AND_ASSIGN(Entry
);
125 SystemUIResourceManagerImpl::SystemUIResourceManagerImpl(
126 UIResourceProvider
* ui_resource_provider
)
127 : ui_resource_provider_(ui_resource_provider
), weak_factory_(this) {
130 SystemUIResourceManagerImpl::~SystemUIResourceManagerImpl() {
133 void SystemUIResourceManagerImpl::PreloadResource(ResourceType type
) {
137 cc::UIResourceId
SystemUIResourceManagerImpl::GetUIResourceId(
139 return GetEntry(type
)->GetUIResourceId();
142 SystemUIResourceManagerImpl::Entry
* SystemUIResourceManagerImpl::GetEntry(
144 DCHECK_GE(type
, RESOURCE_TYPE_FIRST
);
145 DCHECK_LE(type
, RESOURCE_TYPE_LAST
);
146 if (!resource_map_
[type
]) {
147 resource_map_
[type
].reset(new Entry(ui_resource_provider_
));
148 // Lazily build the resource.
151 return resource_map_
[type
].get();
154 void SystemUIResourceManagerImpl::BuildResource(ResourceType type
) {
155 DCHECK(GetEntry(type
)->bitmap().empty());
157 // Instead of blocking the main thread, we post a task to load the bitmap.
158 SkBitmap
* bitmap
= new SkBitmap();
159 gfx::Size screen_size
=
160 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().GetSizeInPixel();
161 base::Closure load_bitmap
=
162 base::Bind(&LoadBitmap
, type
, bitmap
, screen_size
);
163 base::Closure finished_load
=
164 base::Bind(&SystemUIResourceManagerImpl::OnFinishedLoadBitmap
,
165 weak_factory_
.GetWeakPtr(),
167 base::Owned(bitmap
));
168 base::WorkerPool::PostTaskAndReply(
169 FROM_HERE
, load_bitmap
, finished_load
, true);
172 void SystemUIResourceManagerImpl::OnFinishedLoadBitmap(
174 SkBitmap
* bitmap_holder
) {
175 DCHECK(bitmap_holder
);
176 GetEntry(type
)->SetBitmap(*bitmap_holder
);
179 } // namespace content