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 "ui/gfx/android/java_bitmap.h"
20 #include "ui/gfx/screen.h"
25 SkBitmap CreateOverscrollGlowLBitmap(const gfx::Size& screen_size) {
26 const float kSin = 0.5f; // sin(PI / 6)
27 const float kCos = 0.866f; // cos(PI / 6);
30 paint.setAntiAlias(true);
32 paint.setStyle(SkPaint::kFill_Style);
34 const float arc_width =
35 std::min(screen_size.width(), screen_size.height()) * 0.5f / kSin;
36 const float y = kCos * arc_width;
37 const float height = arc_width - y;
38 gfx::Size bounds(arc_width, height);
39 SkRect arc_rect = SkRect::MakeXYWH(
40 -arc_width / 2.f, -arc_width - y, arc_width * 2.f, arc_width * 2.f);
42 glow_bitmap.allocPixels(SkImageInfo::MakeA8(bounds.width(), bounds.height()));
43 glow_bitmap.eraseColor(SK_ColorTRANSPARENT);
45 SkCanvas canvas(glow_bitmap);
46 canvas.clipRect(SkRect::MakeXYWH(0, 0, bounds.width(), bounds.height()));
47 canvas.drawArc(arc_rect, 45, 90, true, paint);
51 void LoadBitmap(ui::SystemUIResourceManager::ResourceType type,
52 SkBitmap* bitmap_holder,
53 const gfx::Size& screen_size) {
55 "browser", "SystemUIResourceManagerImpl::LoadBitmap", "type", type);
58 case ui::SystemUIResourceManager::OVERSCROLL_EDGE:
59 bitmap = gfx::CreateSkBitmapFromAndroidResource(
60 "android:drawable/overscroll_edge", gfx::Size(128, 12));
62 case ui::SystemUIResourceManager::OVERSCROLL_GLOW:
63 bitmap = gfx::CreateSkBitmapFromAndroidResource(
64 "android:drawable/overscroll_glow", gfx::Size(128, 64));
66 case ui::SystemUIResourceManager::OVERSCROLL_GLOW_L:
67 bitmap = CreateOverscrollGlowLBitmap(screen_size);
70 bitmap.setImmutable();
71 *bitmap_holder = bitmap;
76 class SystemUIResourceManagerImpl::Entry
77 : public content::UIResourceClientAndroid {
79 explicit Entry(UIResourceProvider* provider) : id_(0), provider_(provider) {
85 provider_->DeleteUIResource(id_);
89 void SetBitmap(const SkBitmap& bitmap) {
90 DCHECK(!bitmap.empty());
91 DCHECK(bitmap_.empty());
96 cc::UIResourceId GetUIResourceId() {
100 id_ = provider_->CreateUIResource(this);
104 // content::UIResourceClient implementation.
105 virtual cc::UIResourceBitmap GetBitmap(cc::UIResourceId uid,
106 bool resource_lost) override {
107 DCHECK(!bitmap_.empty());
108 return cc::UIResourceBitmap(bitmap_);
111 // content::UIResourceClientAndroid implementation.
112 virtual void UIResourceIsInvalid() override { id_ = 0; }
114 const SkBitmap& bitmap() const { return bitmap_; }
118 cc::UIResourceId id_;
119 UIResourceProvider* provider_;
121 DISALLOW_COPY_AND_ASSIGN(Entry);
124 SystemUIResourceManagerImpl::SystemUIResourceManagerImpl(
125 UIResourceProvider* ui_resource_provider)
126 : ui_resource_provider_(ui_resource_provider), weak_factory_(this) {
129 SystemUIResourceManagerImpl::~SystemUIResourceManagerImpl() {
132 void SystemUIResourceManagerImpl::PreloadResource(ResourceType type) {
136 cc::UIResourceId SystemUIResourceManagerImpl::GetUIResourceId(
138 return GetEntry(type)->GetUIResourceId();
141 SystemUIResourceManagerImpl::Entry* SystemUIResourceManagerImpl::GetEntry(
143 DCHECK_GE(type, RESOURCE_TYPE_FIRST);
144 DCHECK_LE(type, RESOURCE_TYPE_LAST);
145 if (!resource_map_[type]) {
146 resource_map_[type].reset(new Entry(ui_resource_provider_));
147 // Lazily build the resource.
150 return resource_map_[type].get();
153 void SystemUIResourceManagerImpl::BuildResource(ResourceType type) {
154 DCHECK(GetEntry(type)->bitmap().empty());
156 // Instead of blocking the main thread, we post a task to load the bitmap.
157 SkBitmap* bitmap = new SkBitmap();
158 gfx::Size screen_size =
159 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().GetSizeInPixel();
160 base::Closure load_bitmap =
161 base::Bind(&LoadBitmap, type, bitmap, screen_size);
162 base::Closure finished_load =
163 base::Bind(&SystemUIResourceManagerImpl::OnFinishedLoadBitmap,
164 weak_factory_.GetWeakPtr(),
166 base::Owned(bitmap));
167 base::WorkerPool::PostTaskAndReply(
168 FROM_HERE, load_bitmap, finished_load, true);
171 void SystemUIResourceManagerImpl::OnFinishedLoadBitmap(
173 SkBitmap* bitmap_holder) {
174 DCHECK(bitmap_holder);
175 GetEntry(type)->SetBitmap(*bitmap_holder);
178 } // namespace content