Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(306)

Side by Side Diff: chrome/browser/ui/app_list/arc/arc_app_icon.cc

Issue 1413153007: arc-app-launcher: Minimal support for ARC app launcher. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added missing links to BUILD.gn Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 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 "chrome/browser/ui/app_list/arc/arc_app_icon.h"
6
7 #include <algorithm>
8
9 #include "base/bind.h"
10 #include "base/files/file_path.h"
11 #include "base/files/file_util.h"
12 #include "base/task_runner_util.h"
13 #include "chrome/browser/image_decoder.h"
14 #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h"
15 #include "content/public/browser/browser_thread.h"
16 #include "extensions/grit/extensions_browser_resources.h"
17 #include "ui/base/resource/resource_bundle.h"
18 #include "ui/gfx/geometry/size.h"
19 #include "ui/gfx/image/image_skia_source.h"
20
21 namespace {
22
23 bool g_disable_decoding = false;
24
25 } // namespace
26
27 ////////////////////////////////////////////////////////////////////////////////
28 // ArcAppIcon::ReadResult
29
30 struct ArcAppIcon::ReadResult {
31 enum class Status {
32 OK,
33 FAIL,
34 REQUEST_TO_INSTALL,
35 };
36
37 // Used for fail results or for the requests to install an icon.
38 ReadResult(Status status, ui::ScaleFactor scale_factor)
39 : status(status), scale_factor(scale_factor) {
40 DCHECK(status == Status::FAIL || status == Status::REQUEST_TO_INSTALL);
41 }
42
43 // Used for successful results.
44 ReadResult(ui::ScaleFactor scale_factor,
45 const std::string& unsafe_icon_data)
46 : status(Status::OK),
47 scale_factor(scale_factor),
48 unsafe_icon_data(unsafe_icon_data) {
49 }
50
51 Status status;
52 ui::ScaleFactor scale_factor;
53 std::string unsafe_icon_data;
54 };
55
56 ////////////////////////////////////////////////////////////////////////////////
57 // ArcAppIcon::Source
58
59 class ArcAppIcon::Source : public gfx::ImageSkiaSource {
60 public:
61 explicit Source(const base::WeakPtr<ArcAppIcon>& host);
62 ~Source() override;
63
64 private:
65 // gfx::ImageSkiaSource overrides:
66 gfx::ImageSkiaRep GetImageForScale(float scale) override;
67
68 // Used to load images asynchronously. NULLed out when the ArcAppIcon is
69 // destroyed.
70 base::WeakPtr<ArcAppIcon> host_;
71
72 DISALLOW_COPY_AND_ASSIGN(Source);
73 };
74
75 ArcAppIcon::Source::Source(const base::WeakPtr<ArcAppIcon>& host)
76 : host_(host) {
77 }
78
79 ArcAppIcon::Source::~Source() {
80 }
81
82 gfx::ImageSkiaRep ArcAppIcon::Source::GetImageForScale(float scale) {
83 if (host_)
84 host_->LoadForScaleFactor(ui::GetSupportedScaleFactor(scale));
85
86 // Host loads icon asynchronously, so use default icon so far.
87 const gfx::ImageSkia* default_image = ResourceBundle::GetSharedInstance().
88 GetImageSkiaNamed(IDR_APP_DEFAULT_ICON);
89 CHECK(default_image);
90
91 return default_image->GetRepresentation(scale);
92 }
93
94 class ArcAppIcon::DecodeRequest : public ImageDecoder::ImageRequest {
95 public:
96 DecodeRequest(const base::WeakPtr<ArcAppIcon>& host,
97 int dimension,
98 ui::ScaleFactor scale_factor);
99 ~DecodeRequest() override;
100
101 // ImageDecoder::ImageRequest
102 void OnImageDecoded(const SkBitmap& bitmap) override;
103 void OnDecodeImageFailed() override;
104 private:
105 base::WeakPtr<ArcAppIcon> host_;
106 int dimension_;
107 ui::ScaleFactor scale_factor_;
108
109 DISALLOW_COPY_AND_ASSIGN(DecodeRequest);
110 };
111
112 ////////////////////////////////////////////////////////////////////////////////
113 // ArcAppIcon::DecodeRequest
114
115 ArcAppIcon::DecodeRequest::DecodeRequest(const base::WeakPtr<ArcAppIcon>& host,
116 int dimension,
117 ui::ScaleFactor scale_factor)
118 : host_(host),
119 dimension_(dimension),
120 scale_factor_(scale_factor) {
121 }
122
123 ArcAppIcon::DecodeRequest::~DecodeRequest() {
124 }
125
126 void ArcAppIcon::DecodeRequest::OnImageDecoded(const SkBitmap& bitmap) {
127 DCHECK(!bitmap.isNull() && !bitmap.empty());
128
129 if (!host_)
130 return;
131
132 int expected_dim = static_cast<int>(
133 ui::GetScaleForScaleFactor(scale_factor_) * dimension_ + 0.5f);
134 if (bitmap.width() != expected_dim || bitmap.height() != expected_dim) {
135 VLOG(2) << "Decoded ARC icon has unexpected dimension "
136 << bitmap.width() << "x" << bitmap.height() << ". Expected "
137 << expected_dim << "x" << ".";
138 host_->DiscardDecodeRequest(this);
139 return;
140 }
141
142 gfx::ImageSkia image_skia;
143 image_skia.AddRepresentation(gfx::ImageSkiaRep(
144 bitmap,
145 ui::GetScaleForScaleFactor(scale_factor_)));
146
147 host_->Update(&image_skia);
148 host_->DiscardDecodeRequest(this);
149 }
150
151 void ArcAppIcon::DecodeRequest::OnDecodeImageFailed() {
152 VLOG(2) << "Failed to decode ARC icon.";
153
154 if (!host_)
155 return;
156
157 host_->DiscardDecodeRequest(this);
158 }
159
160 ////////////////////////////////////////////////////////////////////////////////
161 // ArcAppIcon
162
163 // static
164 void ArcAppIcon::DisableDecodingForTesting() {
165 g_disable_decoding = true;
166 }
167
168 ArcAppIcon::ArcAppIcon(content::BrowserContext* context,
169 const std::string& app_id,
170 int resource_size_in_dip,
171 Observer* observer)
172 : context_(context),
173 app_id_(app_id),
174 resource_size_in_dip_(resource_size_in_dip),
175 observer_(observer),
176 weak_ptr_factory_(this) {
177 CHECK(observer_ != nullptr);
178 source_ = new Source(weak_ptr_factory_.GetWeakPtr());
179 gfx::Size resource_size(resource_size_in_dip, resource_size_in_dip);
180 image_skia_ = gfx::ImageSkia(source_, resource_size);
181 }
182
183 ArcAppIcon::~ArcAppIcon() {
184 }
185
186 void ArcAppIcon::LoadForScaleFactor(ui::ScaleFactor scale_factor) {
187 ArcAppListPrefs* prefs = ArcAppListPrefs::Get(context_);
188
189 base::FilePath path = prefs->GetIconPath(app_id_, scale_factor);
190 if (path.empty())
191 return;
192
193 base::PostTaskAndReplyWithResult(content::BrowserThread::GetBlockingPool(),
194 FROM_HERE,
195 base::Bind(&ArcAppIcon::ReadOnFileThread,
196 scale_factor,
197 path),
198 base::Bind(&ArcAppIcon::OnIconRead,
199 weak_ptr_factory_.GetWeakPtr()));
200 }
201
202 void ArcAppIcon::RequestIcon(ui::ScaleFactor scale_factor) {
203 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
204 ArcAppListPrefs* prefs = ArcAppListPrefs::Get(context_);
205
206 // ArcAppListPrefs notifies ArcAppModelBuilder via Observer when icon is ready
207 // and ArcAppModelBuilder refreshes the icon of the corresponding item by
208 // calling LoadScaleFactor.
209 prefs->RequestIcon(app_id_, scale_factor);
210 }
211
212 // static
213 scoped_ptr<ArcAppIcon::ReadResult> ArcAppIcon::ReadOnFileThread(
214 ui::ScaleFactor scale_factor,
215 const base::FilePath& path) {
216 DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
217 DCHECK(!path.empty());
218
219 if (!base::PathExists(path))
220 return make_scoped_ptr(new ArcAppIcon::ReadResult(
221 ArcAppIcon::ReadResult::Status::REQUEST_TO_INSTALL, scale_factor));
222
223 // Read the file from disk.
224 std::string unsafe_icon_data;
225 if (!base::ReadFileToString(path, &unsafe_icon_data)) {
226 VLOG(2) << "Failed to read an ARC icon from file " << path.MaybeAsASCII();
227 return make_scoped_ptr(new ArcAppIcon::ReadResult(
228 ArcAppIcon::ReadResult::Status::FAIL, scale_factor));
229 }
230
231 return make_scoped_ptr(new ArcAppIcon::ReadResult(scale_factor,
232 unsafe_icon_data));
233 }
234
235 void ArcAppIcon::OnIconRead(scoped_ptr<ArcAppIcon::ReadResult> read_result) {
236 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
237
238 switch (read_result->status) {
239 case ReadResult::Status::OK:
240 if (!g_disable_decoding) {
241 decode_requests_.push_back(
242 new DecodeRequest(weak_ptr_factory_.GetWeakPtr(),
243 resource_size_in_dip_,
244 read_result->scale_factor));
245 ImageDecoder::Start(decode_requests_.back(),
246 read_result->unsafe_icon_data);
247 }
248 break;
249 case ReadResult::Status::FAIL:
250 break;
251 case ReadResult::Status::REQUEST_TO_INSTALL:
252 RequestIcon(read_result->scale_factor);
253 break;
254 default:
255 NOTREACHED();
256 }
257 }
258
259 void ArcAppIcon::Update(const gfx::ImageSkia* image) {
260 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
261 CHECK(image && !image->isNull());
262
263 std::vector<gfx::ImageSkiaRep> reps = image->image_reps();
264 for (const auto& image_rep : reps) {
265 if (ui::IsSupportedScale(image_rep.scale())) {
266 image_skia_.RemoveRepresentation(image_rep.scale());
267 image_skia_.AddRepresentation(image_rep);
268 }
269 }
270
271 image_ = gfx::Image(image_skia_);
272
273 observer_->OnIconUpdated();
274 }
275
276 void ArcAppIcon::DiscardDecodeRequest(DecodeRequest* request) {
277 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
278
279 ScopedVector<DecodeRequest>::iterator it = std::find(decode_requests_.begin(),
280 decode_requests_.end(),
281 request);
282 CHECK(it != decode_requests_.end());
283 decode_requests_.erase(it);
284 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/app_list/arc/arc_app_icon.h ('k') | chrome/browser/ui/app_list/arc/arc_app_item.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698