OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "content/browser/android/system_ui_resource_manager_impl.h" | |
6 | |
7 #include "base/bind.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 "jni/UIResources_jni.h" | |
17 #include "skia/ext/image_operations.h" | |
18 #include "third_party/skia/include/core/SkBitmap.h" | |
19 #include "third_party/skia/include/core/SkCanvas.h" | |
20 #include "third_party/skia/include/core/SkPaint.h" | |
21 #include "ui/gfx/android/java_bitmap.h" | |
22 #include "ui/gfx/screen.h" | |
23 | |
24 namespace content { | |
25 namespace { | |
26 | |
27 SkBitmap CreateOverscrollGlowLBitmap(const gfx::Size& screen_size) { | |
28 const float kSin = 0.5f; // sin(PI / 6) | |
29 const float kCos = 0.866f; // cos(PI / 6); | |
30 | |
31 SkPaint paint; | |
32 paint.setAntiAlias(true); | |
33 paint.setAlpha(0xBB); | |
34 paint.setStyle(SkPaint::kFill_Style); | |
35 | |
36 const float arc_width = | |
37 std::min(screen_size.width(), screen_size.height()) * 0.5f / kSin; | |
38 const float y = kCos * arc_width; | |
39 const float height = arc_width - y; | |
40 gfx::Size bounds(arc_width, height); | |
41 SkRect arc_rect = SkRect::MakeXYWH( | |
42 -arc_width / 2.f, -arc_width - y, arc_width * 2.f, arc_width * 2.f); | |
43 SkBitmap glow_bitmap; | |
44 glow_bitmap.allocPixels(SkImageInfo::MakeA8(bounds.width(), bounds.height())); | |
45 glow_bitmap.eraseColor(SK_ColorTRANSPARENT); | |
46 | |
47 SkCanvas canvas(glow_bitmap); | |
48 canvas.clipRect(SkRect::MakeXYWH(0, 0, bounds.width(), bounds.height())); | |
49 canvas.drawArc(arc_rect, 45, 90, true, paint); | |
50 return glow_bitmap; | |
51 } | |
52 | |
53 SkBitmap LoadJavaBitmap(ui::SystemUIResourceType type, const gfx::Size& size) { | |
54 ScopedJavaLocalRef<jobject> jobj = | |
55 Java_UIResources_getBitmap(base::android::AttachCurrentThread(), | |
56 base::android::GetApplicationContext(), type, | |
57 size.width(), size.height()); | |
58 if (jobj.is_null()) | |
59 return SkBitmap(); | |
60 | |
61 SkBitmap bitmap = CreateSkBitmapFromJavaBitmap(gfx::JavaBitmap(jobj.obj())); | |
62 if (bitmap.isNull()) | |
63 return bitmap; | |
64 | |
65 if (size.IsEmpty()) | |
66 return bitmap; | |
67 | |
68 return skia::ImageOperations::Resize( | |
69 bitmap, skia::ImageOperations::RESIZE_BOX, size.width(), size.height()); | |
70 } | |
71 | |
72 void LoadBitmap(ui::SystemUIResourceType type, | |
73 SkBitmap* bitmap_holder, | |
74 const gfx::Size& screen_size) { | |
75 TRACE_EVENT1( | |
76 "browser", "SystemUIResourceManagerImpl::LoadBitmap", "type", type); | |
77 SkBitmap bitmap; | |
78 switch (type) { | |
79 case ui::OVERSCROLL_EDGE: | |
80 bitmap = LoadJavaBitmap(type, gfx::Size(128, 12)); | |
81 break; | |
82 case ui::OVERSCROLL_GLOW: | |
83 bitmap = LoadJavaBitmap(type, gfx::Size(128, 64)); | |
84 break; | |
85 case ui::OVERSCROLL_GLOW_L: | |
86 bitmap = CreateOverscrollGlowLBitmap(screen_size); | |
87 break; | |
88 case ui::OVERSCROLL_REFRESH_IDLE: | |
89 case ui::OVERSCROLL_REFRESH_ACTIVE: | |
90 bitmap = LoadJavaBitmap(type, gfx::Size()); | |
91 break; | |
92 } | |
93 bitmap.setImmutable(); | |
94 *bitmap_holder = bitmap; | |
95 } | |
96 | |
97 } // namespace | |
98 | |
99 class SystemUIResourceManagerImpl::Entry | |
100 : public content::UIResourceClientAndroid { | |
101 public: | |
102 explicit Entry(UIResourceProvider* provider) : id_(0), provider_(provider) { | |
103 DCHECK(provider); | |
104 } | |
105 | |
106 ~Entry() override { | |
107 if (id_) | |
108 provider_->DeleteUIResource(id_); | |
109 id_ = 0; | |
110 } | |
111 | |
112 void SetBitmap(const SkBitmap& bitmap) { | |
113 DCHECK(!bitmap.empty()); | |
114 DCHECK(bitmap_.empty()); | |
115 DCHECK(!id_); | |
116 bitmap_ = bitmap; | |
117 } | |
118 | |
119 cc::UIResourceId GetUIResourceId() { | |
120 if (bitmap_.empty()) | |
121 return 0; | |
122 if (!id_) | |
123 id_ = provider_->CreateUIResource(this); | |
124 return id_; | |
125 } | |
126 | |
127 // content::UIResourceClient implementation. | |
128 cc::UIResourceBitmap GetBitmap(cc::UIResourceId uid, | |
129 bool resource_lost) override { | |
130 DCHECK(!bitmap_.empty()); | |
131 return cc::UIResourceBitmap(bitmap_); | |
132 } | |
133 | |
134 // content::UIResourceClientAndroid implementation. | |
135 void UIResourceIsInvalid() override { id_ = 0; } | |
136 | |
137 const SkBitmap& bitmap() const { return bitmap_; } | |
138 | |
139 private: | |
140 SkBitmap bitmap_; | |
141 cc::UIResourceId id_; | |
142 UIResourceProvider* provider_; | |
143 | |
144 DISALLOW_COPY_AND_ASSIGN(Entry); | |
145 }; | |
146 | |
147 SystemUIResourceManagerImpl::SystemUIResourceManagerImpl( | |
148 UIResourceProvider* ui_resource_provider) | |
149 : ui_resource_provider_(ui_resource_provider), weak_factory_(this) { | |
150 } | |
151 | |
152 SystemUIResourceManagerImpl::~SystemUIResourceManagerImpl() { | |
153 } | |
154 | |
155 void SystemUIResourceManagerImpl::PreloadResource( | |
156 ui::SystemUIResourceType type) { | |
157 GetEntry(type); | |
158 } | |
159 | |
160 cc::UIResourceId SystemUIResourceManagerImpl::GetUIResourceId( | |
161 ui::SystemUIResourceType type) { | |
162 return GetEntry(type)->GetUIResourceId(); | |
163 } | |
164 | |
165 SystemUIResourceManagerImpl::Entry* SystemUIResourceManagerImpl::GetEntry( | |
166 ui::SystemUIResourceType type) { | |
167 DCHECK_GE(type, ui::SYSTEM_UI_RESOURCE_TYPE_FIRST); | |
168 DCHECK_LE(type, ui::SYSTEM_UI_RESOURCE_TYPE_LAST); | |
169 if (!resource_map_[type]) { | |
170 resource_map_[type].reset(new Entry(ui_resource_provider_)); | |
171 // Lazily build the resource. | |
172 BuildResource(type); | |
173 } | |
174 return resource_map_[type].get(); | |
175 } | |
176 | |
177 void SystemUIResourceManagerImpl::BuildResource(ui::SystemUIResourceType type) { | |
178 DCHECK(GetEntry(type)->bitmap().empty()); | |
179 | |
180 // Instead of blocking the main thread, we post a task to load the bitmap. | |
181 SkBitmap* bitmap = new SkBitmap(); | |
182 gfx::Size screen_size = | |
183 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().GetSizeInPixel(); | |
184 base::Closure load_bitmap = | |
185 base::Bind(&LoadBitmap, type, bitmap, screen_size); | |
186 base::Closure finished_load = | |
187 base::Bind(&SystemUIResourceManagerImpl::OnFinishedLoadBitmap, | |
188 weak_factory_.GetWeakPtr(), | |
189 type, | |
190 base::Owned(bitmap)); | |
191 base::WorkerPool::PostTaskAndReply( | |
192 FROM_HERE, load_bitmap, finished_load, true); | |
193 } | |
194 | |
195 void SystemUIResourceManagerImpl::OnFinishedLoadBitmap( | |
196 ui::SystemUIResourceType type, | |
197 SkBitmap* bitmap_holder) { | |
198 DCHECK(bitmap_holder); | |
199 GetEntry(type)->SetBitmap(*bitmap_holder); | |
200 } | |
201 | |
202 // static | |
203 bool SystemUIResourceManagerImpl::RegisterUIResources(JNIEnv* env) { | |
204 return RegisterNativesImpl(env); | |
205 } | |
206 | |
207 } // namespace content | |
OLD | NEW |