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 |