Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / content / browser / android / system_ui_resource_manager_impl.cc
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 "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"
21
22 namespace content {
23 namespace {
24
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);
28
29   SkPaint paint;
30   paint.setAntiAlias(true);
31   paint.setAlpha(0xBB);
32   paint.setStyle(SkPaint::kFill_Style);
33
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);
41   SkBitmap glow_bitmap;
42   glow_bitmap.allocPixels(SkImageInfo::MakeA8(bounds.width(), bounds.height()));
43   glow_bitmap.eraseColor(SK_ColorTRANSPARENT);
44
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);
48   return glow_bitmap;
49 }
50
51 void LoadBitmap(ui::SystemUIResourceManager::ResourceType type,
52                 SkBitmap* bitmap_holder,
53                 const gfx::Size& screen_size) {
54   TRACE_EVENT1(
55       "browser", "SystemUIResourceManagerImpl::LoadBitmap", "type", type);
56   SkBitmap bitmap;
57   switch (type) {
58     case ui::SystemUIResourceManager::OVERSCROLL_EDGE:
59       bitmap = gfx::CreateSkBitmapFromAndroidResource(
60           "android:drawable/overscroll_edge", gfx::Size(128, 12));
61       break;
62     case ui::SystemUIResourceManager::OVERSCROLL_GLOW:
63       bitmap = gfx::CreateSkBitmapFromAndroidResource(
64           "android:drawable/overscroll_glow", gfx::Size(128, 64));
65       break;
66     case ui::SystemUIResourceManager::OVERSCROLL_GLOW_L:
67       bitmap = CreateOverscrollGlowLBitmap(screen_size);
68       break;
69   }
70   bitmap.setImmutable();
71   *bitmap_holder = bitmap;
72 }
73
74 }  // namespace
75
76 class SystemUIResourceManagerImpl::Entry
77     : public content::UIResourceClientAndroid {
78  public:
79   explicit Entry(UIResourceProvider* provider) : id_(0), provider_(provider) {
80     DCHECK(provider);
81   }
82
83   virtual ~Entry() {
84     if (id_)
85       provider_->DeleteUIResource(id_);
86     id_ = 0;
87   }
88
89   void SetBitmap(const SkBitmap& bitmap) {
90     DCHECK(!bitmap.empty());
91     DCHECK(bitmap_.empty());
92     DCHECK(!id_);
93     bitmap_ = bitmap;
94   }
95
96   cc::UIResourceId GetUIResourceId() {
97     if (bitmap_.empty())
98       return 0;
99     if (!id_)
100       id_ = provider_->CreateUIResource(this);
101     return id_;
102   }
103
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_);
109   }
110
111   // content::UIResourceClientAndroid implementation.
112   virtual void UIResourceIsInvalid() override { id_ = 0; }
113
114   const SkBitmap& bitmap() const { return bitmap_; }
115
116  private:
117   SkBitmap bitmap_;
118   cc::UIResourceId id_;
119   UIResourceProvider* provider_;
120
121   DISALLOW_COPY_AND_ASSIGN(Entry);
122 };
123
124 SystemUIResourceManagerImpl::SystemUIResourceManagerImpl(
125     UIResourceProvider* ui_resource_provider)
126     : ui_resource_provider_(ui_resource_provider), weak_factory_(this) {
127 }
128
129 SystemUIResourceManagerImpl::~SystemUIResourceManagerImpl() {
130 }
131
132 void SystemUIResourceManagerImpl::PreloadResource(ResourceType type) {
133   GetEntry(type);
134 }
135
136 cc::UIResourceId SystemUIResourceManagerImpl::GetUIResourceId(
137     ResourceType type) {
138   return GetEntry(type)->GetUIResourceId();
139 }
140
141 SystemUIResourceManagerImpl::Entry* SystemUIResourceManagerImpl::GetEntry(
142     ResourceType type) {
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.
148     BuildResource(type);
149   }
150   return resource_map_[type].get();
151 }
152
153 void SystemUIResourceManagerImpl::BuildResource(ResourceType type) {
154   DCHECK(GetEntry(type)->bitmap().empty());
155
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(),
165                  type,
166                  base::Owned(bitmap));
167   base::WorkerPool::PostTaskAndReply(
168       FROM_HERE, load_bitmap, finished_load, true);
169 }
170
171 void SystemUIResourceManagerImpl::OnFinishedLoadBitmap(
172     ResourceType type,
173     SkBitmap* bitmap_holder) {
174   DCHECK(bitmap_holder);
175   GetEntry(type)->SetBitmap(*bitmap_holder);
176 }
177
178 }  // namespace content