Battery Status API: add UMA logging for Linux.
[chromium-blink-merge.git] / content / browser / android / system_ui_resource_manager_impl.cc
blob81f12fc3a70d5d0abde50158258001d4343c7564
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"
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 "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"
23 namespace content {
24 namespace {
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);
30 SkPaint paint;
31 paint.setAntiAlias(true);
32 paint.setAlpha(0x33);
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);
42 SkBitmap glow_bitmap;
43 if (!glow_bitmap.allocPixels(
44 SkImageInfo::MakeA8(bounds.width(), bounds.height()))) {
45 LOG(FATAL) << " Failed to allocate bitmap of size " << bounds.width() << "x"
46 << bounds.height();
48 glow_bitmap.eraseColor(SK_ColorTRANSPARENT);
50 SkCanvas canvas(glow_bitmap);
51 canvas.clipRect(SkRect::MakeXYWH(0, 0, bounds.width(), bounds.height()));
52 canvas.drawArc(arc_rect, 45, 90, true, paint);
53 return glow_bitmap;
56 void LoadBitmap(ui::SystemUIResourceManager::ResourceType type,
57 SkBitmap* bitmap_holder,
58 const gfx::Size& screen_size) {
59 TRACE_EVENT1(
60 "browser", "SystemUIResourceManagerImpl::LoadBitmap", "type", type);
61 SkBitmap bitmap;
62 switch (type) {
63 case ui::SystemUIResourceManager::OVERSCROLL_EDGE:
64 bitmap = gfx::CreateSkBitmapFromAndroidResource(
65 "android:drawable/overscroll_edge", gfx::Size(128, 12));
66 break;
67 case ui::SystemUIResourceManager::OVERSCROLL_GLOW:
68 bitmap = gfx::CreateSkBitmapFromAndroidResource(
69 "android:drawable/overscroll_glow", gfx::Size(128, 64));
70 break;
71 case ui::SystemUIResourceManager::OVERSCROLL_GLOW_L:
72 bitmap = CreateOverscrollGlowLBitmap(screen_size);
73 break;
75 bitmap.setImmutable();
76 *bitmap_holder = bitmap;
79 } // namespace
81 class SystemUIResourceManagerImpl::Entry
82 : public content::UIResourceClientAndroid {
83 public:
84 explicit Entry(UIResourceProvider* provider) : id_(0), provider_(provider) {
85 DCHECK(provider);
88 virtual ~Entry() {
89 if (id_)
90 provider_->DeleteUIResource(id_);
91 id_ = 0;
94 void SetBitmap(const SkBitmap& bitmap) {
95 DCHECK(!bitmap.empty());
96 DCHECK(bitmap_.empty());
97 DCHECK(!id_);
98 bitmap_ = bitmap;
101 cc::UIResourceId GetUIResourceId() {
102 if (bitmap_.empty())
103 return 0;
104 if (!id_)
105 id_ = provider_->CreateUIResource(this);
106 return id_;
109 // content::UIResourceClient implementation.
110 virtual cc::UIResourceBitmap GetBitmap(cc::UIResourceId uid,
111 bool resource_lost) OVERRIDE {
112 DCHECK(!bitmap_.empty());
113 return cc::UIResourceBitmap(bitmap_);
116 // content::UIResourceClientAndroid implementation.
117 virtual void UIResourceIsInvalid() OVERRIDE { id_ = 0; }
119 const SkBitmap& bitmap() const { return bitmap_; }
121 private:
122 SkBitmap bitmap_;
123 cc::UIResourceId id_;
124 UIResourceProvider* provider_;
126 DISALLOW_COPY_AND_ASSIGN(Entry);
129 SystemUIResourceManagerImpl::SystemUIResourceManagerImpl(
130 UIResourceProvider* ui_resource_provider)
131 : ui_resource_provider_(ui_resource_provider), weak_factory_(this) {
134 SystemUIResourceManagerImpl::~SystemUIResourceManagerImpl() {
137 void SystemUIResourceManagerImpl::PreloadResource(ResourceType type) {
138 GetEntry(type);
141 cc::UIResourceId SystemUIResourceManagerImpl::GetUIResourceId(
142 ResourceType type) {
143 return GetEntry(type)->GetUIResourceId();
146 SystemUIResourceManagerImpl::Entry* SystemUIResourceManagerImpl::GetEntry(
147 ResourceType type) {
148 DCHECK_GE(type, RESOURCE_TYPE_FIRST);
149 DCHECK_LE(type, RESOURCE_TYPE_LAST);
150 if (!resource_map_[type]) {
151 resource_map_[type].reset(new Entry(ui_resource_provider_));
152 // Lazily build the resource.
153 BuildResource(type);
155 return resource_map_[type].get();
158 void SystemUIResourceManagerImpl::BuildResource(ResourceType type) {
159 DCHECK(GetEntry(type)->bitmap().empty());
161 // Instead of blocking the main thread, we post a task to load the bitmap.
162 SkBitmap* bitmap = new SkBitmap();
163 gfx::Size screen_size =
164 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().GetSizeInPixel();
165 base::Closure load_bitmap =
166 base::Bind(&LoadBitmap, type, bitmap, screen_size);
167 base::Closure finished_load =
168 base::Bind(&SystemUIResourceManagerImpl::OnFinishedLoadBitmap,
169 weak_factory_.GetWeakPtr(),
170 type,
171 base::Owned(bitmap));
172 base::WorkerPool::PostTaskAndReply(
173 FROM_HERE, load_bitmap, finished_load, true);
176 void SystemUIResourceManagerImpl::OnFinishedLoadBitmap(
177 ResourceType type,
178 SkBitmap* bitmap_holder) {
179 DCHECK(bitmap_holder);
180 GetEntry(type)->SetBitmap(*bitmap_holder);
183 } // namespace content