| 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 |