OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/extensions/image_loader.h" | 5 #include "chrome/browser/extensions/image_loader.h" |
6 | 6 |
7 #include <map> | 7 #include <map> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/callback.h" | 10 #include "base/callback.h" |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 const gfx::Size& original_size, | 155 const gfx::Size& original_size, |
156 const ImageLoader::ImageRepresentation& image_representation) | 156 const ImageLoader::ImageRepresentation& image_representation) |
157 : bitmap(bitmap), | 157 : bitmap(bitmap), |
158 original_size(original_size), | 158 original_size(original_size), |
159 image_representation(image_representation) { | 159 image_representation(image_representation) { |
160 } | 160 } |
161 | 161 |
162 ImageLoader::LoadResult::~LoadResult() { | 162 ImageLoader::LoadResult::~LoadResult() { |
163 } | 163 } |
164 | 164 |
| 165 namespace { |
| 166 |
| 167 // Need to be after ImageRepresentation and LoadResult are defined. |
| 168 std::vector<ImageLoader::LoadResult> LoadImagesOnBlockingPool( |
| 169 const std::vector<ImageLoader::ImageRepresentation>& info_list, |
| 170 const std::vector<SkBitmap>& bitmaps) { |
| 171 DCHECK(BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread()); |
| 172 std::vector<ImageLoader::LoadResult> load_result; |
| 173 |
| 174 for (size_t i = 0; i < info_list.size(); ++i) { |
| 175 const ImageLoader::ImageRepresentation& image = info_list[i]; |
| 176 |
| 177 // If we don't have a path there isn't anything we can do, just skip it. |
| 178 if (image.resource.relative_path().empty()) |
| 179 continue; |
| 180 |
| 181 SkBitmap bitmap; |
| 182 if (bitmaps[i].isNull()) |
| 183 LoadImageOnBlockingPool(image, &bitmap); |
| 184 else |
| 185 bitmap = bitmaps[i]; |
| 186 |
| 187 // If the image failed to load, skip it. |
| 188 if (bitmap.isNull() || bitmap.empty()) |
| 189 continue; |
| 190 |
| 191 gfx::Size original_size(bitmap.width(), bitmap.height()); |
| 192 bitmap = ResizeIfNeeded(bitmap, image); |
| 193 |
| 194 load_result.push_back( |
| 195 ImageLoader::LoadResult(bitmap, original_size, image)); |
| 196 } |
| 197 |
| 198 return load_result; |
| 199 } |
| 200 |
| 201 } // namespace |
| 202 |
165 //////////////////////////////////////////////////////////////////////////////// | 203 //////////////////////////////////////////////////////////////////////////////// |
166 // ImageLoader | 204 // ImageLoader |
167 | 205 |
168 ImageLoader::ImageLoader() | 206 ImageLoader::ImageLoader() |
169 : weak_ptr_factory_(this) { | 207 : weak_ptr_factory_(this) { |
170 } | 208 } |
171 | 209 |
172 ImageLoader::~ImageLoader() { | 210 ImageLoader::~ImageLoader() { |
173 } | 211 } |
174 | 212 |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
231 relative_path = relative_path.NormalizePathSeparators(); | 269 relative_path = relative_path.NormalizePathSeparators(); |
232 | 270 |
233 std::map<base::FilePath, int>::const_iterator entry = | 271 std::map<base::FilePath, int>::const_iterator entry = |
234 path_to_resource_id.Get().find(relative_path); | 272 path_to_resource_id.Get().find(relative_path); |
235 if (entry != path_to_resource_id.Get().end()) | 273 if (entry != path_to_resource_id.Get().end()) |
236 *resource_id = entry->second; | 274 *resource_id = entry->second; |
237 | 275 |
238 return entry != path_to_resource_id.Get().end(); | 276 return entry != path_to_resource_id.Get().end(); |
239 } | 277 } |
240 | 278 |
241 void ImageLoader::LoadImageAsync( | 279 void ImageLoader::LoadImageAsync(const Extension* extension, |
242 const Extension* extension, | 280 const ExtensionResource& resource, |
243 const ExtensionResource& resource, | 281 const gfx::Size& max_size, |
244 const gfx::Size& max_size, | 282 const ImageLoaderCallback& callback) { |
245 const base::Callback<void(const gfx::Image&)>& callback) { | |
246 std::vector<ImageRepresentation> info_list; | 283 std::vector<ImageRepresentation> info_list; |
247 info_list.push_back(ImageRepresentation( | 284 info_list.push_back(ImageRepresentation( |
248 resource, | 285 resource, |
249 ImageRepresentation::RESIZE_WHEN_LARGER, | 286 ImageRepresentation::RESIZE_WHEN_LARGER, |
250 max_size, | 287 max_size, |
251 ui::SCALE_FACTOR_100P)); | 288 ui::SCALE_FACTOR_100P)); |
252 LoadImagesAsync(extension, info_list, callback); | 289 LoadImagesAsync(extension, info_list, callback); |
253 } | 290 } |
254 | 291 |
255 void ImageLoader::LoadImagesAsync( | 292 void ImageLoader::LoadImagesAsync( |
256 const Extension* extension, | 293 const Extension* extension, |
257 const std::vector<ImageRepresentation>& info_list, | 294 const std::vector<ImageRepresentation>& info_list, |
258 const base::Callback<void(const gfx::Image&)>& callback) { | 295 const ImageLoaderCallback& callback) { |
259 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 296 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
260 | 297 |
261 // Loading an image from the cache and loading resources have to happen | 298 // Loading an image from the cache and loading resources have to happen |
262 // on the UI thread. So do those two things first, and pass the rest of the | 299 // on the UI thread. So do those two things first, and pass the rest of the |
263 // work of as a blocking pool task. | 300 // work of as a blocking pool task. |
264 | 301 |
265 std::vector<SkBitmap> bitmaps; | 302 std::vector<SkBitmap> bitmaps; |
266 bitmaps.resize(info_list.size()); | 303 bitmaps.resize(info_list.size()); |
267 | 304 |
268 int i = 0; | 305 int i = 0; |
269 for (std::vector<ImageRepresentation>::const_iterator it = info_list.begin(); | 306 for (std::vector<ImageRepresentation>::const_iterator it = info_list.begin(); |
270 it != info_list.end(); ++it, ++i) { | 307 it != info_list.end(); ++it, ++i) { |
271 DCHECK(it->resource.relative_path().empty() || | 308 DCHECK(it->resource.relative_path().empty() || |
272 extension->path() == it->resource.extension_root()); | 309 extension->path() == it->resource.extension_root()); |
273 | 310 |
274 int resource_id; | 311 int resource_id; |
275 if (extension->location() == Manifest::COMPONENT && | 312 if (extension->location() == Manifest::COMPONENT && |
276 IsComponentExtensionResource(extension->path(), | 313 IsComponentExtensionResource(extension->path(), |
277 it->resource.relative_path(), | 314 it->resource.relative_path(), |
278 &resource_id)) { | 315 &resource_id)) { |
279 LoadResourceOnUIThread(resource_id, &bitmaps[i]); | 316 LoadResourceOnUIThread(resource_id, &bitmaps[i]); |
280 } | 317 } |
281 } | 318 } |
282 | 319 |
283 DCHECK(!BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread()); | 320 DCHECK(!BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread()); |
284 std::vector<LoadResult>* load_result = new std::vector<LoadResult>; | 321 base::PostTaskAndReplyWithResult( |
285 BrowserThread::PostBlockingPoolTaskAndReply( | 322 BrowserThread::GetBlockingPool(), |
286 FROM_HERE, | 323 FROM_HERE, |
287 base::Bind(LoadImagesOnBlockingPool, info_list, bitmaps, load_result), | 324 base::Bind(LoadImagesOnBlockingPool, info_list, bitmaps), |
288 base::Bind(&ImageLoader::ReplyBack, weak_ptr_factory_.GetWeakPtr(), | 325 base::Bind(&ImageLoader::ReplyBack, weak_ptr_factory_.GetWeakPtr(), |
289 base::Owned(load_result), callback)); | 326 callback)); |
290 } | 327 } |
291 | 328 |
292 // static | 329 void ImageLoader::ReplyBack(const ImageLoaderCallback& callback, |
293 void ImageLoader::LoadImagesOnBlockingPool( | 330 const std::vector<LoadResult>& load_result) { |
294 const std::vector<ImageRepresentation>& info_list, | |
295 const std::vector<SkBitmap>& bitmaps, | |
296 std::vector<LoadResult>* load_result) { | |
297 DCHECK(BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread()); | |
298 | |
299 int i = 0; | |
300 for (std::vector<ImageRepresentation>::const_iterator it = info_list.begin(); | |
301 it != info_list.end(); ++it, ++i) { | |
302 // If we don't have a path there isn't anything we can do, just skip it. | |
303 if (it->resource.relative_path().empty()) | |
304 continue; | |
305 | |
306 SkBitmap bitmap; | |
307 if (!bitmaps[i].isNull()) { | |
308 bitmap = bitmaps[i]; | |
309 } else { | |
310 LoadImageOnBlockingPool(*it, &bitmap); | |
311 } | |
312 | |
313 // If the image failed to load, skip it. | |
314 if (bitmap.isNull() || bitmap.empty()) | |
315 continue; | |
316 | |
317 gfx::Size original_size(bitmap.width(), bitmap.height()); | |
318 bitmap = ResizeIfNeeded(bitmap, *it); | |
319 | |
320 load_result->push_back(LoadResult(bitmap, original_size, *it)); | |
321 } | |
322 } | |
323 | |
324 void ImageLoader::ReplyBack( | |
325 const std::vector<LoadResult>* load_result, | |
326 const base::Callback<void(const gfx::Image&)>& callback) { | |
327 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 331 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
328 | 332 |
329 gfx::ImageSkia image_skia; | 333 gfx::ImageSkia image_skia; |
330 | 334 |
331 for (std::vector<LoadResult>::const_iterator it = load_result->begin(); | 335 for (std::vector<LoadResult>::const_iterator it = load_result.begin(); |
332 it != load_result->end(); ++it) { | 336 it != load_result.end(); ++it) { |
333 const SkBitmap& bitmap = it->bitmap; | 337 const SkBitmap& bitmap = it->bitmap; |
334 const ImageRepresentation& image_rep = it->image_representation; | 338 const ImageRepresentation& image_rep = it->image_representation; |
335 | 339 |
336 image_skia.AddRepresentation(gfx::ImageSkiaRep( | 340 image_skia.AddRepresentation(gfx::ImageSkiaRep( |
337 bitmap, | 341 bitmap, |
338 ui::GetImageScale(image_rep.scale_factor))); | 342 ui::GetImageScale(image_rep.scale_factor))); |
339 } | 343 } |
340 | 344 |
341 gfx::Image image; | 345 gfx::Image image; |
342 if (!image_skia.isNull()) { | 346 if (!image_skia.isNull()) { |
343 image_skia.MakeThreadSafe(); | 347 image_skia.MakeThreadSafe(); |
344 image = gfx::Image(image_skia); | 348 image = gfx::Image(image_skia); |
345 } | 349 } |
346 | 350 |
347 callback.Run(image); | 351 callback.Run(image); |
348 } | 352 } |
349 | 353 |
350 } // namespace extensions | 354 } // namespace extensions |
OLD | NEW |