| 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/extension_icon_image.h" | 5 #include "chrome/browser/extensions/extension_icon_image.h" |
| 6 | 6 |
| 7 #include "base/json/json_file_value_serializer.h" | 7 #include "base/json/json_file_value_serializer.h" |
| 8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
| 9 #include "base/path_service.h" | 9 #include "base/path_service.h" |
| 10 #include "chrome/browser/extensions/image_loading_tracker.h" | 10 #include "chrome/browser/extensions/image_loader.h" |
| 11 #include "chrome/common/chrome_paths.h" | 11 #include "chrome/common/chrome_paths.h" |
| 12 #include "chrome/common/extensions/extension.h" | 12 #include "chrome/common/extensions/extension.h" |
| 13 #include "chrome/common/extensions/extension_constants.h" | 13 #include "chrome/common/extensions/extension_constants.h" |
| 14 #include "content/public/test/test_browser_thread.h" | 14 #include "content/public/test/test_browser_thread.h" |
| 15 #include "grit/theme_resources.h" | 15 #include "grit/theme_resources.h" |
| 16 #include "skia/ext/image_operations.h" | 16 #include "skia/ext/image_operations.h" |
| 17 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
| 18 #include "ui/base/resource/resource_bundle.h" | 18 #include "ui/base/resource/resource_bundle.h" |
| 19 #include "ui/gfx/image/image_skia_source.h" | 19 #include "ui/gfx/image/image_skia_source.h" |
| 20 #include "ui/gfx/skia_util.h" | 20 #include "ui/gfx/skia_util.h" |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 58 virtual gfx::ImageSkiaRep GetImageForScale( | 58 virtual gfx::ImageSkiaRep GetImageForScale( |
| 59 ui::ScaleFactor scale_factor) OVERRIDE { | 59 ui::ScaleFactor scale_factor) OVERRIDE { |
| 60 return image_.GetRepresentation(scale_factor); | 60 return image_.GetRepresentation(scale_factor); |
| 61 } | 61 } |
| 62 | 62 |
| 63 private: | 63 private: |
| 64 gfx::ImageSkia image_; | 64 gfx::ImageSkia image_; |
| 65 }; | 65 }; |
| 66 | 66 |
| 67 // Helper class for synchronously loading extension image resource. | 67 // Helper class for synchronously loading extension image resource. |
| 68 class TestImageLoader : public ImageLoadingTracker::Observer { | 68 class TestImageLoader { |
| 69 public: | 69 public: |
| 70 explicit TestImageLoader(const Extension* extension) | 70 explicit TestImageLoader(const Extension* extension) |
| 71 : extension_(extension), | 71 : extension_(extension), |
| 72 waiting_(false), | 72 waiting_(false), |
| 73 image_loaded_(false), | 73 image_loaded_(false) { |
| 74 ALLOW_THIS_IN_INITIALIZER_LIST(tracker_(this)) { | |
| 75 } | 74 } |
| 76 virtual ~TestImageLoader() {} | 75 virtual ~TestImageLoader() {} |
| 77 | 76 |
| 78 // ImageLoadingTracker::Observer override. | 77 void OnImageLoaded(const gfx::Image& image) { |
| 79 virtual void OnImageLoaded(const gfx::Image& image, | |
| 80 const std::string& extension_id, | |
| 81 int index) OVERRIDE { | |
| 82 image_ = image; | 78 image_ = image; |
| 83 image_loaded_ = true; | 79 image_loaded_ = true; |
| 84 if (waiting_) | 80 if (waiting_) |
| 85 MessageLoop::current()->Quit(); | 81 MessageLoop::current()->Quit(); |
| 86 } | 82 } |
| 87 | 83 |
| 88 SkBitmap LoadBitmap(const std::string& path, | 84 SkBitmap LoadBitmap(const std::string& path, |
| 89 int size, | 85 int size) { |
| 90 ImageLoadingTracker::CacheParam cache_param) { | |
| 91 image_loaded_ = false; | 86 image_loaded_ = false; |
| 92 | 87 |
| 93 tracker_.LoadImage(extension_, | 88 image_loader_.LoadImageAsync( |
| 94 extension_->GetResource(path), | 89 extension_, extension_->GetResource(path), gfx::Size(size, size), |
| 95 gfx::Size(size, size), | 90 base::Bind(&TestImageLoader::OnImageLoaded, |
| 96 cache_param); | 91 base::Unretained(this))); |
| 97 | 92 |
| 98 // If |image_| still hasn't been loaded (i.e. it is being loaded | 93 // If |image_| still hasn't been loaded (i.e. it is being loaded |
| 99 // asynchronously), wait for it. | 94 // asynchronously), wait for it. |
| 100 if (!image_loaded_) { | 95 if (!image_loaded_) { |
| 101 waiting_ = true; | 96 waiting_ = true; |
| 102 MessageLoop::current()->Run(); | 97 MessageLoop::current()->Run(); |
| 103 waiting_ = false; | 98 waiting_ = false; |
| 104 } | 99 } |
| 105 | 100 |
| 106 EXPECT_TRUE(image_loaded_); | 101 EXPECT_TRUE(image_loaded_); |
| 107 | 102 |
| 108 return image_.IsEmpty() ? SkBitmap() : *image_.ToSkBitmap(); | 103 return image_.IsEmpty() ? SkBitmap() : *image_.ToSkBitmap(); |
| 109 } | 104 } |
| 110 | 105 |
| 111 private: | 106 private: |
| 112 const Extension* extension_; | 107 const Extension* extension_; |
| 113 bool waiting_; | 108 bool waiting_; |
| 114 bool image_loaded_; | 109 bool image_loaded_; |
| 115 gfx::Image image_; | 110 gfx::Image image_; |
| 116 ImageLoadingTracker tracker_; | 111 extensions::ImageLoader image_loader_; |
| 117 | 112 |
| 118 DISALLOW_COPY_AND_ASSIGN(TestImageLoader); | 113 DISALLOW_COPY_AND_ASSIGN(TestImageLoader); |
| 119 }; | 114 }; |
| 120 | 115 |
| 121 class ExtensionIconImageTest : public testing::Test, | 116 class ExtensionIconImageTest : public testing::Test, |
| 122 public IconImage::Observer { | 117 public IconImage::Observer { |
| 123 public: | 118 public: |
| 124 ExtensionIconImageTest() | 119 ExtensionIconImageTest() |
| 125 : image_loaded_count_(0), | 120 : image_loaded_count_(0), |
| 126 quit_in_image_loaded_(false), | 121 quit_in_image_loaded_(false), |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 185 | 180 |
| 186 gfx::ImageSkia GetDefaultIcon() { | 181 gfx::ImageSkia GetDefaultIcon() { |
| 187 return *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( | 182 return *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( |
| 188 IDR_EXTENSIONS_FAVICON); | 183 IDR_EXTENSIONS_FAVICON); |
| 189 } | 184 } |
| 190 | 185 |
| 191 // Loads an image to be used in test from the extension. | 186 // Loads an image to be used in test from the extension. |
| 192 // The image will be loaded from the relative path |path|. | 187 // The image will be loaded from the relative path |path|. |
| 193 SkBitmap GetTestBitmap(const Extension* extension, | 188 SkBitmap GetTestBitmap(const Extension* extension, |
| 194 const std::string& path, | 189 const std::string& path, |
| 195 int size, | 190 int size) { |
| 196 ImageLoadingTracker::CacheParam cache_param) { | |
| 197 TestImageLoader image_loader(extension); | 191 TestImageLoader image_loader(extension); |
| 198 return image_loader.LoadBitmap(path, size, cache_param); | 192 return image_loader.LoadBitmap(path, size); |
| 199 } | 193 } |
| 200 | 194 |
| 201 private: | 195 private: |
| 202 int image_loaded_count_; | 196 int image_loaded_count_; |
| 203 bool quit_in_image_loaded_; | 197 bool quit_in_image_loaded_; |
| 204 MessageLoop ui_loop_; | 198 MessageLoop ui_loop_; |
| 205 content::TestBrowserThread ui_thread_; | 199 content::TestBrowserThread ui_thread_; |
| 206 content::TestBrowserThread file_thread_; | 200 content::TestBrowserThread file_thread_; |
| 207 content::TestBrowserThread io_thread_; | 201 content::TestBrowserThread io_thread_; |
| 208 | 202 |
| 209 DISALLOW_COPY_AND_ASSIGN(ExtensionIconImageTest); | 203 DISALLOW_COPY_AND_ASSIGN(ExtensionIconImageTest); |
| 210 }; | 204 }; |
| 211 | 205 |
| 212 } // namespace | 206 } // namespace |
| 213 | 207 |
| 214 TEST_F(ExtensionIconImageTest, Basic) { | 208 TEST_F(ExtensionIconImageTest, Basic) { |
| 215 scoped_refptr<Extension> extension(CreateExtension( | 209 scoped_refptr<Extension> extension(CreateExtension( |
| 216 "extension_icon_image", Extension::INVALID)); | 210 "extension_icon_image", Extension::INVALID)); |
| 217 ASSERT_TRUE(extension.get() != NULL); | 211 ASSERT_TRUE(extension.get() != NULL); |
| 218 | 212 |
| 219 gfx::ImageSkia default_icon = GetDefaultIcon(); | 213 gfx::ImageSkia default_icon = GetDefaultIcon(); |
| 220 | 214 |
| 221 // Load images we expect to find as representations in icon_image, so we | 215 // Load images we expect to find as representations in icon_image, so we |
| 222 // can later use them to validate icon_image. | 216 // can later use them to validate icon_image. |
| 223 SkBitmap bitmap_16 = | 217 SkBitmap bitmap_16 = |
| 224 GetTestBitmap(extension, "16.png", 16, ImageLoadingTracker::DONT_CACHE); | 218 GetTestBitmap(extension, "16.png", 16); |
| 225 ASSERT_FALSE(bitmap_16.empty()); | 219 ASSERT_FALSE(bitmap_16.empty()); |
| 226 | 220 |
| 227 // There is no image of size 32 defined in the extension manifest, so we | 221 // There is no image of size 32 defined in the extension manifest, so we |
| 228 // should expect manifest image of size 48 resized to size 32. | 222 // should expect manifest image of size 48 resized to size 32. |
| 229 SkBitmap bitmap_48_resized_to_32 = | 223 SkBitmap bitmap_48_resized_to_32 = |
| 230 GetTestBitmap(extension, "48.png", 32, ImageLoadingTracker::DONT_CACHE); | 224 GetTestBitmap(extension, "48.png", 32); |
| 231 ASSERT_FALSE(bitmap_48_resized_to_32.empty()); | 225 ASSERT_FALSE(bitmap_48_resized_to_32.empty()); |
| 232 | 226 |
| 233 IconImage image(extension, extension->icons(), 16, default_icon, this); | 227 IconImage image(extension, extension->icons(), 16, default_icon, this); |
| 234 | 228 |
| 235 // No representations in |image_| yet. | 229 // No representations in |image_| yet. |
| 236 gfx::ImageSkia::ImageSkiaReps image_reps = image.image_skia().image_reps(); | 230 gfx::ImageSkia::ImageSkiaReps image_reps = image.image_skia().image_reps(); |
| 237 ASSERT_EQ(0u, image_reps.size()); | 231 ASSERT_EQ(0u, image_reps.size()); |
| 238 | 232 |
| 239 // Gets representation for a scale factor. | 233 // Gets representation for a scale factor. |
| 240 gfx::ImageSkiaRep representation = | 234 gfx::ImageSkiaRep representation = |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 280 TEST_F(ExtensionIconImageTest, FallbackToSmallerWhenNoBigger) { | 274 TEST_F(ExtensionIconImageTest, FallbackToSmallerWhenNoBigger) { |
| 281 scoped_refptr<Extension> extension(CreateExtension( | 275 scoped_refptr<Extension> extension(CreateExtension( |
| 282 "extension_icon_image", Extension::INVALID)); | 276 "extension_icon_image", Extension::INVALID)); |
| 283 ASSERT_TRUE(extension.get() != NULL); | 277 ASSERT_TRUE(extension.get() != NULL); |
| 284 | 278 |
| 285 gfx::ImageSkia default_icon = GetDefaultIcon(); | 279 gfx::ImageSkia default_icon = GetDefaultIcon(); |
| 286 | 280 |
| 287 // Load images we expect to find as representations in icon_image, so we | 281 // Load images we expect to find as representations in icon_image, so we |
| 288 // can later use them to validate icon_image. | 282 // can later use them to validate icon_image. |
| 289 SkBitmap bitmap_48 = | 283 SkBitmap bitmap_48 = |
| 290 GetTestBitmap(extension, "48.png", 48, ImageLoadingTracker::DONT_CACHE); | 284 GetTestBitmap(extension, "48.png", 48); |
| 291 ASSERT_FALSE(bitmap_48.empty()); | 285 ASSERT_FALSE(bitmap_48.empty()); |
| 292 | 286 |
| 293 IconImage image(extension, extension->icons(), 32, default_icon, this); | 287 IconImage image(extension, extension->icons(), 32, default_icon, this); |
| 294 | 288 |
| 295 gfx::ImageSkiaRep representation = | 289 gfx::ImageSkiaRep representation = |
| 296 image.image_skia().GetRepresentation(ui::SCALE_FACTOR_200P); | 290 image.image_skia().GetRepresentation(ui::SCALE_FACTOR_200P); |
| 297 | 291 |
| 298 WaitForImageLoad(); | 292 WaitForImageLoad(); |
| 299 EXPECT_EQ(1, ImageLoadedCount()); | 293 EXPECT_EQ(1, ImageLoadedCount()); |
| 300 ASSERT_EQ(1u, image.image_skia().image_reps().size()); | 294 ASSERT_EQ(1u, image.image_skia().image_reps().size()); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 315 TEST_F(ExtensionIconImageTest, FallbackToSmaller) { | 309 TEST_F(ExtensionIconImageTest, FallbackToSmaller) { |
| 316 scoped_refptr<Extension> extension(CreateExtension( | 310 scoped_refptr<Extension> extension(CreateExtension( |
| 317 "extension_icon_image", Extension::INVALID)); | 311 "extension_icon_image", Extension::INVALID)); |
| 318 ASSERT_TRUE(extension.get() != NULL); | 312 ASSERT_TRUE(extension.get() != NULL); |
| 319 | 313 |
| 320 gfx::ImageSkia default_icon = GetDefaultIcon(); | 314 gfx::ImageSkia default_icon = GetDefaultIcon(); |
| 321 | 315 |
| 322 // Load images we expect to find as representations in icon_image, so we | 316 // Load images we expect to find as representations in icon_image, so we |
| 323 // can later use them to validate icon_image. | 317 // can later use them to validate icon_image. |
| 324 SkBitmap bitmap_16 = | 318 SkBitmap bitmap_16 = |
| 325 GetTestBitmap(extension, "16.png", 16, ImageLoadingTracker::DONT_CACHE); | 319 GetTestBitmap(extension, "16.png", 16); |
| 326 ASSERT_FALSE(bitmap_16.empty()); | 320 ASSERT_FALSE(bitmap_16.empty()); |
| 327 | 321 |
| 328 IconImage image(extension, extension->icons(), 17, default_icon, this); | 322 IconImage image(extension, extension->icons(), 17, default_icon, this); |
| 329 | 323 |
| 330 gfx::ImageSkiaRep representation = | 324 gfx::ImageSkiaRep representation = |
| 331 image.image_skia().GetRepresentation(ui::SCALE_FACTOR_100P); | 325 image.image_skia().GetRepresentation(ui::SCALE_FACTOR_100P); |
| 332 | 326 |
| 333 WaitForImageLoad(); | 327 WaitForImageLoad(); |
| 334 EXPECT_EQ(1, ImageLoadedCount()); | 328 EXPECT_EQ(1, ImageLoadedCount()); |
| 335 ASSERT_EQ(1u, image.image_skia().image_reps().size()); | 329 ASSERT_EQ(1u, image.image_skia().image_reps().size()); |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 467 default_icon.GetRepresentation(ui::SCALE_FACTOR_100P).sk_bitmap())); | 461 default_icon.GetRepresentation(ui::SCALE_FACTOR_100P).sk_bitmap())); |
| 468 } | 462 } |
| 469 | 463 |
| 470 TEST_F(ExtensionIconImageTest, LoadPrecachedImage) { | 464 TEST_F(ExtensionIconImageTest, LoadPrecachedImage) { |
| 471 scoped_refptr<Extension> extension(CreateExtension( | 465 scoped_refptr<Extension> extension(CreateExtension( |
| 472 "extension_icon_image", Extension::INVALID)); | 466 "extension_icon_image", Extension::INVALID)); |
| 473 ASSERT_TRUE(extension.get() != NULL); | 467 ASSERT_TRUE(extension.get() != NULL); |
| 474 | 468 |
| 475 gfx::ImageSkia default_icon = GetDefaultIcon(); | 469 gfx::ImageSkia default_icon = GetDefaultIcon(); |
| 476 | 470 |
| 477 // Note the cache parameter. | 471 // Store the image in the cache. |
| 478 SkBitmap bitmap_16 = | 472 SkBitmap bitmap_16 = |
| 479 GetTestBitmap(extension, "16.png", 16, ImageLoadingTracker::CACHE); | 473 GetTestBitmap(extension, "16.png", 16); |
| 480 ASSERT_FALSE(bitmap_16.empty()); | 474 ASSERT_FALSE(bitmap_16.empty()); |
| 475 extension->SetCachedImage(extension->GetResource("16.png"), bitmap_16, |
| 476 gfx::Size(16, 16)); |
| 481 | 477 |
| 482 IconImage image(extension, extension->icons(), 16, default_icon, this); | 478 IconImage image(extension, extension->icons(), 16, default_icon, this); |
| 483 | 479 |
| 484 // No representations in |image_| yet. | 480 // No representations in |image_| yet. |
| 485 gfx::ImageSkia::ImageSkiaReps image_reps = image.image_skia().image_reps(); | 481 gfx::ImageSkia::ImageSkiaReps image_reps = image.image_skia().image_reps(); |
| 486 ASSERT_EQ(0u, image_reps.size()); | 482 ASSERT_EQ(0u, image_reps.size()); |
| 487 | 483 |
| 488 // Gets representation for a scale factor. | 484 // Gets representation for a scale factor. |
| 489 // Since the icon representation is precached, it should be returned right | 485 // Since the icon representation is precached, it should be returned right |
| 490 // away. Also, we should not receive any notifications. | 486 // away. Also, we should not receive any notifications. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 503 TEST_F(ExtensionIconImageTest, IconImageDestruction) { | 499 TEST_F(ExtensionIconImageTest, IconImageDestruction) { |
| 504 scoped_refptr<Extension> extension(CreateExtension( | 500 scoped_refptr<Extension> extension(CreateExtension( |
| 505 "extension_icon_image", Extension::INVALID)); | 501 "extension_icon_image", Extension::INVALID)); |
| 506 ASSERT_TRUE(extension.get() != NULL); | 502 ASSERT_TRUE(extension.get() != NULL); |
| 507 | 503 |
| 508 gfx::ImageSkia default_icon = GetDefaultIcon(); | 504 gfx::ImageSkia default_icon = GetDefaultIcon(); |
| 509 | 505 |
| 510 // Load images we expect to find as representations in icon_image, so we | 506 // Load images we expect to find as representations in icon_image, so we |
| 511 // can later use them to validate icon_image. | 507 // can later use them to validate icon_image. |
| 512 SkBitmap bitmap_16 = | 508 SkBitmap bitmap_16 = |
| 513 GetTestBitmap(extension, "16.png", 16, ImageLoadingTracker::DONT_CACHE); | 509 GetTestBitmap(extension, "16.png", 16); |
| 514 ASSERT_FALSE(bitmap_16.empty()); | 510 ASSERT_FALSE(bitmap_16.empty()); |
| 515 | 511 |
| 516 scoped_ptr<IconImage> image( | 512 scoped_ptr<IconImage> image( |
| 517 new IconImage(extension, extension->icons(), 16, default_icon, this)); | 513 new IconImage(extension, extension->icons(), 16, default_icon, this)); |
| 518 | 514 |
| 519 // Load an image representation. | 515 // Load an image representation. |
| 520 gfx::ImageSkiaRep representation = | 516 gfx::ImageSkiaRep representation = |
| 521 image->image_skia().GetRepresentation(ui::SCALE_FACTOR_100P); | 517 image->image_skia().GetRepresentation(ui::SCALE_FACTOR_100P); |
| 522 | 518 |
| 523 WaitForImageLoad(); | 519 WaitForImageLoad(); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 536 EXPECT_EQ(16, representation.pixel_width()); | 532 EXPECT_EQ(16, representation.pixel_width()); |
| 537 EXPECT_TRUE(gfx::BitmapsAreEqual(representation.sk_bitmap(), bitmap_16)); | 533 EXPECT_TRUE(gfx::BitmapsAreEqual(representation.sk_bitmap(), bitmap_16)); |
| 538 | 534 |
| 539 // When requesting another representation, we should get blank image. | 535 // When requesting another representation, we should get blank image. |
| 540 representation = image_skia.GetRepresentation(ui::SCALE_FACTOR_200P); | 536 representation = image_skia.GetRepresentation(ui::SCALE_FACTOR_200P); |
| 541 | 537 |
| 542 EXPECT_TRUE(gfx::BitmapsAreEqual( | 538 EXPECT_TRUE(gfx::BitmapsAreEqual( |
| 543 representation.sk_bitmap(), | 539 representation.sk_bitmap(), |
| 544 CreateBlankBitmapForScale(16, ui::SCALE_FACTOR_200P))); | 540 CreateBlankBitmapForScale(16, ui::SCALE_FACTOR_200P))); |
| 545 } | 541 } |
| OLD | NEW |