OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "extensions/browser/extension_icon_image.h" | 5 #include "extensions/browser/extension_icon_image.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/json/json_file_value_serializer.h" | 9 #include "base/json/json_file_value_serializer.h" |
10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
11 #include "base/path_service.h" | 11 #include "base/path_service.h" |
12 #include "content/public/browser/notification_service.h" | 12 #include "content/public/browser/notification_service.h" |
13 #include "content/public/test/test_browser_context.h" | 13 #include "content/public/test/test_browser_context.h" |
14 #include "content/public/test/test_browser_thread.h" | 14 #include "content/public/test/test_browser_thread.h" |
15 #include "extensions/browser/extensions_test.h" | 15 #include "extensions/browser/extensions_test.h" |
16 #include "extensions/browser/image_loader.h" | 16 #include "extensions/browser/image_loader.h" |
| 17 #include "extensions/browser/test_image_loader.h" |
17 #include "extensions/common/extension.h" | 18 #include "extensions/common/extension.h" |
18 #include "extensions/common/extension_paths.h" | 19 #include "extensions/common/extension_paths.h" |
19 #include "extensions/common/manifest.h" | 20 #include "extensions/common/manifest.h" |
20 #include "extensions/common/manifest_handlers/icons_handler.h" | 21 #include "extensions/common/manifest_handlers/icons_handler.h" |
21 #include "skia/ext/image_operations.h" | 22 #include "skia/ext/image_operations.h" |
22 #include "testing/gtest/include/gtest/gtest.h" | 23 #include "testing/gtest/include/gtest/gtest.h" |
23 #include "ui/base/resource/resource_bundle.h" | 24 #include "ui/base/resource/resource_bundle.h" |
24 #include "ui/gfx/image/image_skia_source.h" | 25 #include "ui/gfx/image/image_skia_source.h" |
25 #include "ui/gfx/skia_util.h" | 26 #include "ui/gfx/skia_util.h" |
26 | 27 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
58 ~MockImageSkiaSource() override {} | 59 ~MockImageSkiaSource() override {} |
59 | 60 |
60 gfx::ImageSkiaRep GetImageForScale(float scale) override { | 61 gfx::ImageSkiaRep GetImageForScale(float scale) override { |
61 return image_.GetRepresentation(scale); | 62 return image_.GetRepresentation(scale); |
62 } | 63 } |
63 | 64 |
64 private: | 65 private: |
65 gfx::ImageSkia image_; | 66 gfx::ImageSkia image_; |
66 }; | 67 }; |
67 | 68 |
68 // Helper class for synchronously loading extension image resource. | |
69 class TestImageLoader { | |
70 public: | |
71 explicit TestImageLoader(const Extension* extension) | |
72 : extension_(extension), | |
73 waiting_(false), | |
74 image_loaded_(false) { | |
75 } | |
76 virtual ~TestImageLoader() {} | |
77 | |
78 void OnImageLoaded(const gfx::Image& image) { | |
79 image_ = image; | |
80 image_loaded_ = true; | |
81 if (waiting_) | |
82 base::MessageLoop::current()->Quit(); | |
83 } | |
84 | |
85 SkBitmap LoadBitmap(const std::string& path, | |
86 int size) { | |
87 image_loaded_ = false; | |
88 | |
89 image_loader_.LoadImageAsync( | |
90 extension_, extension_->GetResource(path), gfx::Size(size, size), | |
91 base::Bind(&TestImageLoader::OnImageLoaded, | |
92 base::Unretained(this))); | |
93 | |
94 // If |image_| still hasn't been loaded (i.e. it is being loaded | |
95 // asynchronously), wait for it. | |
96 if (!image_loaded_) { | |
97 waiting_ = true; | |
98 base::MessageLoop::current()->Run(); | |
99 waiting_ = false; | |
100 } | |
101 | |
102 EXPECT_TRUE(image_loaded_); | |
103 | |
104 return image_.IsEmpty() ? SkBitmap() : *image_.ToSkBitmap(); | |
105 } | |
106 | |
107 private: | |
108 const Extension* extension_; | |
109 bool waiting_; | |
110 bool image_loaded_; | |
111 gfx::Image image_; | |
112 ImageLoader image_loader_; | |
113 | |
114 DISALLOW_COPY_AND_ASSIGN(TestImageLoader); | |
115 }; | |
116 | |
117 class ExtensionIconImageTest : public ExtensionsTest, | 69 class ExtensionIconImageTest : public ExtensionsTest, |
118 public IconImage::Observer { | 70 public IconImage::Observer { |
119 public: | 71 public: |
120 ExtensionIconImageTest() | 72 ExtensionIconImageTest() |
121 : image_loaded_count_(0), | 73 : image_loaded_count_(0), |
122 quit_in_image_loaded_(false), | 74 quit_in_image_loaded_(false), |
123 ui_thread_(BrowserThread::UI, &ui_loop_), | 75 ui_thread_(BrowserThread::UI, &ui_loop_), |
124 file_thread_(BrowserThread::FILE), | 76 file_thread_(BrowserThread::FILE), |
125 io_thread_(BrowserThread::IO), | 77 io_thread_(BrowserThread::IO), |
126 notification_service_(content::NotificationService::Create()) {} | 78 notification_service_(content::NotificationService::Create()) {} |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 void OnExtensionIconImageChanged(IconImage* image) override { | 129 void OnExtensionIconImageChanged(IconImage* image) override { |
178 image_loaded_count_++; | 130 image_loaded_count_++; |
179 if (quit_in_image_loaded_) | 131 if (quit_in_image_loaded_) |
180 base::MessageLoop::current()->Quit(); | 132 base::MessageLoop::current()->Quit(); |
181 } | 133 } |
182 | 134 |
183 gfx::ImageSkia GetDefaultIcon() { | 135 gfx::ImageSkia GetDefaultIcon() { |
184 return gfx::ImageSkia(gfx::ImageSkiaRep(gfx::Size(16, 16), 1.0f)); | 136 return gfx::ImageSkia(gfx::ImageSkiaRep(gfx::Size(16, 16), 1.0f)); |
185 } | 137 } |
186 | 138 |
187 // Loads an image to be used in test from the extension. | |
188 // The image will be loaded from the relative path |path|. | |
189 SkBitmap GetTestBitmap(const Extension* extension, | |
190 const std::string& path, | |
191 int size) { | |
192 TestImageLoader image_loader(extension); | |
193 return image_loader.LoadBitmap(path, size); | |
194 } | |
195 | |
196 private: | 139 private: |
197 int image_loaded_count_; | 140 int image_loaded_count_; |
198 bool quit_in_image_loaded_; | 141 bool quit_in_image_loaded_; |
199 base::MessageLoop ui_loop_; | 142 base::MessageLoop ui_loop_; |
200 content::TestBrowserThread ui_thread_; | 143 content::TestBrowserThread ui_thread_; |
201 content::TestBrowserThread file_thread_; | 144 content::TestBrowserThread file_thread_; |
202 content::TestBrowserThread io_thread_; | 145 content::TestBrowserThread io_thread_; |
203 scoped_ptr<content::NotificationService> notification_service_; | 146 scoped_ptr<content::NotificationService> notification_service_; |
204 | 147 |
205 DISALLOW_COPY_AND_ASSIGN(ExtensionIconImageTest); | 148 DISALLOW_COPY_AND_ASSIGN(ExtensionIconImageTest); |
206 }; | 149 }; |
207 | 150 |
208 } // namespace | 151 } // namespace |
209 | 152 |
210 TEST_F(ExtensionIconImageTest, Basic) { | 153 TEST_F(ExtensionIconImageTest, Basic) { |
211 std::vector<ui::ScaleFactor> supported_factors; | 154 std::vector<ui::ScaleFactor> supported_factors; |
212 supported_factors.push_back(ui::SCALE_FACTOR_100P); | 155 supported_factors.push_back(ui::SCALE_FACTOR_100P); |
213 supported_factors.push_back(ui::SCALE_FACTOR_200P); | 156 supported_factors.push_back(ui::SCALE_FACTOR_200P); |
214 ui::test::ScopedSetSupportedScaleFactors scoped_supported(supported_factors); | 157 ui::test::ScopedSetSupportedScaleFactors scoped_supported(supported_factors); |
215 scoped_refptr<Extension> extension(CreateExtension( | 158 scoped_refptr<Extension> extension(CreateExtension( |
216 "extension_icon_image", Manifest::INVALID_LOCATION)); | 159 "extension_icon_image", Manifest::INVALID_LOCATION)); |
217 ASSERT_TRUE(extension.get() != NULL); | 160 ASSERT_TRUE(extension.get() != NULL); |
218 | 161 |
219 gfx::ImageSkia default_icon = GetDefaultIcon(); | 162 gfx::ImageSkia default_icon = GetDefaultIcon(); |
220 | 163 |
221 // Load images we expect to find as representations in icon_image, so we | 164 // Load images we expect to find as representations in icon_image, so we |
222 // can later use them to validate icon_image. | 165 // can later use them to validate icon_image. |
223 SkBitmap bitmap_16 = GetTestBitmap(extension.get(), "16.png", 16); | 166 SkBitmap bitmap_16 = |
| 167 TestImageLoader::LoadAndGetExtensionBitmap(extension.get(), "16.png", 16); |
224 ASSERT_FALSE(bitmap_16.empty()); | 168 ASSERT_FALSE(bitmap_16.empty()); |
225 | 169 |
226 // There is no image of size 32 defined in the extension manifest, so we | 170 // There is no image of size 32 defined in the extension manifest, so we |
227 // should expect manifest image of size 48 resized to size 32. | 171 // should expect manifest image of size 48 resized to size 32. |
228 SkBitmap bitmap_48_resized_to_32 = | 172 SkBitmap bitmap_48_resized_to_32 = |
229 GetTestBitmap(extension.get(), "48.png", 32); | 173 TestImageLoader::LoadAndGetExtensionBitmap(extension.get(), "48.png", 32); |
230 ASSERT_FALSE(bitmap_48_resized_to_32.empty()); | 174 ASSERT_FALSE(bitmap_48_resized_to_32.empty()); |
231 | 175 |
232 IconImage image(browser_context(), | 176 IconImage image(browser_context(), |
233 extension.get(), | 177 extension.get(), |
234 IconsInfo::GetIcons(extension.get()), | 178 IconsInfo::GetIcons(extension.get()), |
235 16, | 179 16, |
236 default_icon, | 180 default_icon, |
237 this); | 181 this); |
238 | 182 |
239 // No representations in |image_| yet. | 183 // No representations in |image_| yet. |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
286 supported_factors.push_back(ui::SCALE_FACTOR_200P); | 230 supported_factors.push_back(ui::SCALE_FACTOR_200P); |
287 ui::test::ScopedSetSupportedScaleFactors scoped_supported(supported_factors); | 231 ui::test::ScopedSetSupportedScaleFactors scoped_supported(supported_factors); |
288 scoped_refptr<Extension> extension(CreateExtension( | 232 scoped_refptr<Extension> extension(CreateExtension( |
289 "extension_icon_image", Manifest::INVALID_LOCATION)); | 233 "extension_icon_image", Manifest::INVALID_LOCATION)); |
290 ASSERT_TRUE(extension.get() != NULL); | 234 ASSERT_TRUE(extension.get() != NULL); |
291 | 235 |
292 gfx::ImageSkia default_icon = GetDefaultIcon(); | 236 gfx::ImageSkia default_icon = GetDefaultIcon(); |
293 | 237 |
294 // Load images we expect to find as representations in icon_image, so we | 238 // Load images we expect to find as representations in icon_image, so we |
295 // can later use them to validate icon_image. | 239 // can later use them to validate icon_image. |
296 SkBitmap bitmap_48 = GetTestBitmap(extension.get(), "48.png", 48); | 240 SkBitmap bitmap_48 = |
| 241 TestImageLoader::LoadAndGetExtensionBitmap(extension.get(), "48.png", 48); |
297 ASSERT_FALSE(bitmap_48.empty()); | 242 ASSERT_FALSE(bitmap_48.empty()); |
298 | 243 |
299 IconImage image(browser_context(), | 244 IconImage image(browser_context(), |
300 extension.get(), | 245 extension.get(), |
301 IconsInfo::GetIcons(extension.get()), | 246 IconsInfo::GetIcons(extension.get()), |
302 32, | 247 32, |
303 default_icon, | 248 default_icon, |
304 this); | 249 this); |
305 | 250 |
306 gfx::ImageSkiaRep representation = image.image_skia().GetRepresentation(2.0f); | 251 gfx::ImageSkiaRep representation = image.image_skia().GetRepresentation(2.0f); |
(...skipping 16 matching lines...) Expand all Loading... |
323 // one. The bigger resource should be loaded. | 268 // one. The bigger resource should be loaded. |
324 TEST_F(ExtensionIconImageTest, FallbackToBigger) { | 269 TEST_F(ExtensionIconImageTest, FallbackToBigger) { |
325 scoped_refptr<Extension> extension(CreateExtension( | 270 scoped_refptr<Extension> extension(CreateExtension( |
326 "extension_icon_image", Manifest::INVALID_LOCATION)); | 271 "extension_icon_image", Manifest::INVALID_LOCATION)); |
327 ASSERT_TRUE(extension.get() != NULL); | 272 ASSERT_TRUE(extension.get() != NULL); |
328 | 273 |
329 gfx::ImageSkia default_icon = GetDefaultIcon(); | 274 gfx::ImageSkia default_icon = GetDefaultIcon(); |
330 | 275 |
331 // Load images we expect to find as representations in icon_image, so we | 276 // Load images we expect to find as representations in icon_image, so we |
332 // can later use them to validate icon_image. | 277 // can later use them to validate icon_image. |
333 SkBitmap bitmap_24 = GetTestBitmap(extension.get(), "24.png", 24); | 278 SkBitmap bitmap_24 = |
| 279 TestImageLoader::LoadAndGetExtensionBitmap(extension.get(), "24.png", 24); |
334 ASSERT_FALSE(bitmap_24.empty()); | 280 ASSERT_FALSE(bitmap_24.empty()); |
335 | 281 |
336 IconImage image(browser_context(), | 282 IconImage image(browser_context(), |
337 extension.get(), | 283 extension.get(), |
338 IconsInfo::GetIcons(extension.get()), | 284 IconsInfo::GetIcons(extension.get()), |
339 17, | 285 17, |
340 default_icon, | 286 default_icon, |
341 this); | 287 this); |
342 | 288 |
343 gfx::ImageSkiaRep representation = image.image_skia().GetRepresentation(1.0f); | 289 gfx::ImageSkiaRep representation = image.image_skia().GetRepresentation(1.0f); |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
515 // representations should be returned. | 461 // representations should be returned. |
516 TEST_F(ExtensionIconImageTest, IconImageDestruction) { | 462 TEST_F(ExtensionIconImageTest, IconImageDestruction) { |
517 scoped_refptr<Extension> extension(CreateExtension( | 463 scoped_refptr<Extension> extension(CreateExtension( |
518 "extension_icon_image", Manifest::INVALID_LOCATION)); | 464 "extension_icon_image", Manifest::INVALID_LOCATION)); |
519 ASSERT_TRUE(extension.get() != NULL); | 465 ASSERT_TRUE(extension.get() != NULL); |
520 | 466 |
521 gfx::ImageSkia default_icon = GetDefaultIcon(); | 467 gfx::ImageSkia default_icon = GetDefaultIcon(); |
522 | 468 |
523 // Load images we expect to find as representations in icon_image, so we | 469 // Load images we expect to find as representations in icon_image, so we |
524 // can later use them to validate icon_image. | 470 // can later use them to validate icon_image. |
525 SkBitmap bitmap_16 = GetTestBitmap(extension.get(), "16.png", 16); | 471 SkBitmap bitmap_16 = |
| 472 TestImageLoader::LoadAndGetExtensionBitmap(extension.get(), "16.png", 16); |
526 ASSERT_FALSE(bitmap_16.empty()); | 473 ASSERT_FALSE(bitmap_16.empty()); |
527 | 474 |
528 scoped_ptr<IconImage> image( | 475 scoped_ptr<IconImage> image( |
529 new IconImage(browser_context(), | 476 new IconImage(browser_context(), |
530 extension.get(), | 477 extension.get(), |
531 IconsInfo::GetIcons(extension.get()), | 478 IconsInfo::GetIcons(extension.get()), |
532 16, | 479 16, |
533 default_icon, | 480 default_icon, |
534 this)); | 481 this)); |
535 | 482 |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
597 // because image storage is shared, so when we created one from the first | 544 // because image storage is shared, so when we created one from the first |
598 // image, all other images should also have that representation... | 545 // image, all other images should also have that representation... |
599 gfx::Image image2 = icon_image->image(); | 546 gfx::Image image2 = icon_image->image(); |
600 EXPECT_EQ(image_as_png.get(), image2.As1xPNGBytes().get()); | 547 EXPECT_EQ(image_as_png.get(), image2.As1xPNGBytes().get()); |
601 | 548 |
602 // ...even images that were copied before the representation was constructed. | 549 // ...even images that were copied before the representation was constructed. |
603 EXPECT_EQ(image_as_png.get(), prior_image.As1xPNGBytes().get()); | 550 EXPECT_EQ(image_as_png.get(), prior_image.As1xPNGBytes().get()); |
604 } | 551 } |
605 | 552 |
606 } // namespace extensions | 553 } // namespace extensions |
OLD | NEW |