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_loading_tracker.h" | 5 #include "chrome/browser/extensions/image_loader.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/common/chrome_notification_types.h" | 10 #include "chrome/common/chrome_notification_types.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 "chrome/common/extensions/extension_icon_set.h" | 14 #include "chrome/common/extensions/extension_icon_set.h" |
15 #include "chrome/common/extensions/extension_resource.h" | 15 #include "chrome/common/extensions/extension_resource.h" |
16 #include "content/public/browser/notification_service.h" | 16 #include "content/public/browser/notification_service.h" |
17 #include "content/public/test/test_browser_thread.h" | 17 #include "content/public/test/test_browser_thread.h" |
18 #include "grit/component_extension_resources.h" | 18 #include "grit/component_extension_resources.h" |
19 #include "testing/gtest/include/gtest/gtest.h" | 19 #include "testing/gtest/include/gtest/gtest.h" |
20 #include "third_party/skia/include/core/SkBitmap.h" | 20 #include "third_party/skia/include/core/SkBitmap.h" |
21 #include "ui/gfx/image/image.h" | 21 #include "ui/gfx/image/image.h" |
22 #include "ui/gfx/image/image_skia.h" | 22 #include "ui/gfx/image/image_skia.h" |
23 #include "ui/gfx/size.h" | 23 #include "ui/gfx/size.h" |
24 | 24 |
25 using content::BrowserThread; | 25 using content::BrowserThread; |
26 using extensions::Extension; | 26 using extensions::Extension; |
| 27 using extensions::ImageLoader; |
27 | 28 |
28 class ImageLoadingTrackerTest : public testing::Test, | 29 class ImageLoaderTest : public testing::Test { |
29 public ImageLoadingTracker::Observer { | |
30 public: | 30 public: |
31 ImageLoadingTrackerTest() | 31 ImageLoaderTest() |
32 : image_loaded_count_(0), | 32 : image_loaded_count_(0), |
33 quit_in_image_loaded_(false), | 33 quit_in_image_loaded_(false), |
34 ui_thread_(BrowserThread::UI, &ui_loop_), | 34 ui_thread_(BrowserThread::UI, &ui_loop_), |
35 file_thread_(BrowserThread::FILE), | 35 file_thread_(BrowserThread::FILE), |
36 io_thread_(BrowserThread::IO) { | 36 io_thread_(BrowserThread::IO) { |
37 } | 37 } |
38 | 38 |
39 virtual void OnImageLoaded(const gfx::Image& image, | 39 void OnImageLoaded(const gfx::Image& image) { |
40 const std::string& extension_id, | |
41 int index) OVERRIDE { | |
42 image_loaded_count_++; | 40 image_loaded_count_++; |
43 if (quit_in_image_loaded_) | 41 if (quit_in_image_loaded_) |
44 MessageLoop::current()->Quit(); | 42 MessageLoop::current()->Quit(); |
45 image_ = image; | 43 image_ = image; |
46 } | 44 } |
47 | 45 |
48 void WaitForImageLoad() { | 46 void WaitForImageLoad() { |
49 quit_in_image_loaded_ = true; | 47 quit_in_image_loaded_ = true; |
50 MessageLoop::current()->Run(); | 48 MessageLoop::current()->Run(); |
51 quit_in_image_loaded_ = false; | 49 quit_in_image_loaded_ = false; |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 } | 99 } |
102 | 100 |
103 int image_loaded_count_; | 101 int image_loaded_count_; |
104 bool quit_in_image_loaded_; | 102 bool quit_in_image_loaded_; |
105 MessageLoop ui_loop_; | 103 MessageLoop ui_loop_; |
106 content::TestBrowserThread ui_thread_; | 104 content::TestBrowserThread ui_thread_; |
107 content::TestBrowserThread file_thread_; | 105 content::TestBrowserThread file_thread_; |
108 content::TestBrowserThread io_thread_; | 106 content::TestBrowserThread io_thread_; |
109 }; | 107 }; |
110 | 108 |
111 // Tests asking ImageLoadingTracker to cache pushes the result to the Extension. | 109 // Tests loading an image works correctly. |
112 TEST_F(ImageLoadingTrackerTest, Cache) { | 110 TEST_F(ImageLoaderTest, LoadImage) { |
113 scoped_refptr<Extension> extension(CreateExtension( | 111 scoped_refptr<Extension> extension(CreateExtension( |
114 "image_loading_tracker", Extension::INVALID)); | 112 "image_loading_tracker", Extension::INVALID)); |
115 ASSERT_TRUE(extension.get() != NULL); | 113 ASSERT_TRUE(extension.get() != NULL); |
116 | 114 |
117 ExtensionResource image_resource = | 115 ExtensionResource image_resource = |
118 extension->GetIconResource(extension_misc::EXTENSION_ICON_SMALLISH, | 116 extension->GetIconResource(extension_misc::EXTENSION_ICON_SMALLISH, |
119 ExtensionIconSet::MATCH_EXACTLY); | 117 ExtensionIconSet::MATCH_EXACTLY); |
120 gfx::Size max_size(extension_misc::EXTENSION_ICON_SMALLISH, | 118 gfx::Size max_size(extension_misc::EXTENSION_ICON_SMALLISH, |
121 extension_misc::EXTENSION_ICON_SMALLISH); | 119 extension_misc::EXTENSION_ICON_SMALLISH); |
122 ImageLoadingTracker loader(this); | 120 ImageLoader loader; |
123 loader.LoadImage(extension.get(), | 121 loader.LoadImageAsync(extension.get(), |
124 image_resource, | 122 image_resource, |
125 max_size, | 123 max_size, |
126 ImageLoadingTracker::CACHE); | 124 base::Bind(&ImageLoaderTest::OnImageLoaded, |
| 125 base::Unretained(this))); |
127 | 126 |
128 // The image isn't cached, so we should not have received notification. | 127 // The image isn't cached, so we should not have received notification. |
129 EXPECT_EQ(0, image_loaded_count()); | 128 EXPECT_EQ(0, image_loaded_count()); |
130 | 129 |
131 WaitForImageLoad(); | 130 WaitForImageLoad(); |
132 | 131 |
133 // We should have gotten the image. | 132 // We should have gotten the image. |
134 EXPECT_EQ(1, image_loaded_count()); | 133 EXPECT_EQ(1, image_loaded_count()); |
135 | 134 |
136 // Check that the image was loaded. | 135 // Check that the image was loaded. |
137 EXPECT_EQ(extension_misc::EXTENSION_ICON_SMALLISH, | 136 EXPECT_EQ(extension_misc::EXTENSION_ICON_SMALLISH, |
138 image_.ToSkBitmap()->width()); | 137 image_.ToSkBitmap()->width()); |
139 | |
140 // The image should be cached in the Extension. | |
141 EXPECT_TRUE(extension->HasCachedImage(image_resource, max_size)); | |
142 | |
143 // Make sure the image is in the extension. | |
144 EXPECT_EQ(extension_misc::EXTENSION_ICON_SMALLISH, | |
145 extension->GetCachedImage(image_resource, max_size).width()); | |
146 | |
147 // Ask the tracker for the image again, this should call us back immediately. | |
148 loader.LoadImage(extension.get(), | |
149 image_resource, | |
150 max_size, | |
151 ImageLoadingTracker::CACHE); | |
152 // We should have gotten the image. | |
153 EXPECT_EQ(1, image_loaded_count()); | |
154 | |
155 // Check that the image was loaded. | |
156 EXPECT_EQ(extension_misc::EXTENSION_ICON_SMALLISH, | |
157 image_.ToSkBitmap()->width()); | |
158 } | 138 } |
159 | 139 |
160 // Tests deleting an extension while waiting for the image to load doesn't cause | 140 // Tests deleting an extension while waiting for the image to load doesn't cause |
161 // problems. | 141 // problems. |
162 TEST_F(ImageLoadingTrackerTest, DeleteExtensionWhileWaitingForCache) { | 142 TEST_F(ImageLoaderTest, DeleteExtensionWhileWaitingForCache) { |
163 scoped_refptr<Extension> extension(CreateExtension( | 143 scoped_refptr<Extension> extension(CreateExtension( |
164 "image_loading_tracker", Extension::INVALID)); | 144 "image_loading_tracker", Extension::INVALID)); |
165 ASSERT_TRUE(extension.get() != NULL); | 145 ASSERT_TRUE(extension.get() != NULL); |
166 | 146 |
167 ExtensionResource image_resource = | 147 ExtensionResource image_resource = |
168 extension->GetIconResource(extension_misc::EXTENSION_ICON_SMALLISH, | 148 extension->GetIconResource(extension_misc::EXTENSION_ICON_SMALLISH, |
169 ExtensionIconSet::MATCH_EXACTLY); | 149 ExtensionIconSet::MATCH_EXACTLY); |
170 ImageLoadingTracker loader(this); | 150 gfx::Size max_size(extension_misc::EXTENSION_ICON_SMALLISH, |
171 loader.LoadImage(extension.get(), | 151 extension_misc::EXTENSION_ICON_SMALLISH); |
172 image_resource, | 152 ImageLoader loader; |
173 gfx::Size(extension_misc::EXTENSION_ICON_SMALLISH, | 153 std::set<int> sizes; |
174 extension_misc::EXTENSION_ICON_SMALLISH), | 154 sizes.insert(extension_misc::EXTENSION_ICON_SMALLISH); |
175 ImageLoadingTracker::CACHE); | 155 loader.LoadImageAsync(extension.get(), |
| 156 image_resource, |
| 157 max_size, |
| 158 base::Bind(&ImageLoaderTest::OnImageLoaded, |
| 159 base::Unretained(this))); |
176 | 160 |
177 // The image isn't cached, so we should not have received notification. | 161 // The image isn't cached, so we should not have received notification. |
178 EXPECT_EQ(0, image_loaded_count()); | 162 EXPECT_EQ(0, image_loaded_count()); |
179 | 163 |
180 // Send out notification the extension was uninstalled. | 164 // Send out notification the extension was uninstalled. |
181 extensions::UnloadedExtensionInfo details(extension.get(), | 165 extensions::UnloadedExtensionInfo details(extension.get(), |
182 extension_misc::UNLOAD_REASON_UNINSTALL); | 166 extension_misc::UNLOAD_REASON_UNINSTALL); |
183 content::NotificationService::current()->Notify( | 167 content::NotificationService::current()->Notify( |
184 chrome::NOTIFICATION_EXTENSION_UNLOADED, | 168 chrome::NOTIFICATION_EXTENSION_UNLOADED, |
185 content::NotificationService::AllSources(), | 169 content::NotificationService::AllSources(), |
186 content::Details<extensions::UnloadedExtensionInfo>(&details)); | 170 content::Details<extensions::UnloadedExtensionInfo>(&details)); |
187 | 171 |
188 // Chuck the extension, that way if anyone tries to access it we should crash | 172 // Chuck the extension, that way if anyone tries to access it we should crash |
189 // or get valgrind errors. | 173 // or get valgrind errors. |
190 extension = NULL; | 174 extension = NULL; |
191 | 175 |
192 WaitForImageLoad(); | 176 WaitForImageLoad(); |
193 | 177 |
194 // Even though we deleted the extension, we should still get the image. | 178 // Even though we deleted the extension, we should still get the image. |
195 // We should still have gotten the image. | 179 // We should still have gotten the image. |
196 EXPECT_EQ(1, image_loaded_count()); | 180 EXPECT_EQ(1, image_loaded_count()); |
197 | 181 |
198 // Check that the image was loaded. | 182 // Check that the image was loaded. |
199 EXPECT_EQ(extension_misc::EXTENSION_ICON_SMALLISH, | 183 EXPECT_EQ(extension_misc::EXTENSION_ICON_SMALLISH, |
200 image_.ToSkBitmap()->width()); | 184 image_.ToSkBitmap()->width()); |
201 } | 185 } |
202 | 186 |
203 // Tests loading multiple dimensions of the same image. | 187 // Tests loading multiple dimensions of the same image. |
204 TEST_F(ImageLoadingTrackerTest, MultipleImages) { | 188 TEST_F(ImageLoaderTest, MultipleImages) { |
205 scoped_refptr<Extension> extension(CreateExtension( | 189 scoped_refptr<Extension> extension(CreateExtension( |
206 "image_loading_tracker", Extension::INVALID)); | 190 "image_loading_tracker", Extension::INVALID)); |
207 ASSERT_TRUE(extension.get() != NULL); | 191 ASSERT_TRUE(extension.get() != NULL); |
208 | 192 |
209 std::vector<ImageLoadingTracker::ImageRepresentation> info_list; | 193 std::vector<ImageLoader::ImageRepresentation> info_list; |
210 int sizes[] = {extension_misc::EXTENSION_ICON_SMALLISH, | 194 int sizes[] = {extension_misc::EXTENSION_ICON_SMALLISH, |
211 extension_misc::EXTENSION_ICON_BITTY}; | 195 extension_misc::EXTENSION_ICON_BITTY}; |
212 for (size_t i = 0; i < arraysize(sizes); ++i) { | 196 for (size_t i = 0; i < arraysize(sizes); ++i) { |
213 ExtensionResource resource = | 197 ExtensionResource resource = |
214 extension->GetIconResource(sizes[i], ExtensionIconSet::MATCH_EXACTLY); | 198 extension->GetIconResource(sizes[i], ExtensionIconSet::MATCH_EXACTLY); |
215 info_list.push_back(ImageLoadingTracker::ImageRepresentation( | 199 info_list.push_back(ImageLoader::ImageRepresentation( |
216 resource, | 200 resource, |
217 ImageLoadingTracker::ImageRepresentation::RESIZE_WHEN_LARGER, | 201 ImageLoader::ImageRepresentation::RESIZE_WHEN_LARGER, |
218 gfx::Size(sizes[i], sizes[i]), | 202 gfx::Size(sizes[i], sizes[i]), |
219 ui::SCALE_FACTOR_NONE)); | 203 ui::SCALE_FACTOR_NONE)); |
220 } | 204 } |
221 | 205 |
222 ImageLoadingTracker loader(this); | 206 ImageLoader loader; |
223 loader.LoadImages(extension.get(), info_list, ImageLoadingTracker::CACHE); | 207 loader.LoadImagesAsync(extension.get(), info_list, |
| 208 base::Bind(&ImageLoaderTest::OnImageLoaded, |
| 209 base::Unretained(this))); |
224 | 210 |
225 // The image isn't cached, so we should not have received notification. | 211 // The image isn't cached, so we should not have received notification. |
226 EXPECT_EQ(0, image_loaded_count()); | 212 EXPECT_EQ(0, image_loaded_count()); |
227 | 213 |
228 WaitForImageLoad(); | 214 WaitForImageLoad(); |
229 | 215 |
230 // We should have gotten the image. | 216 // We should have gotten the image. |
231 EXPECT_EQ(1, image_loaded_count()); | 217 EXPECT_EQ(1, image_loaded_count()); |
232 | 218 |
233 // Check that all images were loaded. | 219 // Check that all images were loaded. |
234 std::vector<gfx::ImageSkiaRep> image_reps = | 220 std::vector<gfx::ImageSkiaRep> image_reps = |
235 image_.ToImageSkia()->image_reps(); | 221 image_.ToImageSkia()->image_reps(); |
236 ASSERT_EQ(2u, image_reps.size()); | 222 ASSERT_EQ(2u, image_reps.size()); |
237 const gfx::ImageSkiaRep* img_rep1 = &image_reps[0]; | 223 const gfx::ImageSkiaRep* img_rep1 = &image_reps[0]; |
238 const gfx::ImageSkiaRep* img_rep2 = &image_reps[1]; | 224 const gfx::ImageSkiaRep* img_rep2 = &image_reps[1]; |
239 if (img_rep1->pixel_width() > img_rep2->pixel_width()) { | 225 if (img_rep1->pixel_width() > img_rep2->pixel_width()) { |
240 std::swap(img_rep1, img_rep2); | 226 std::swap(img_rep1, img_rep2); |
241 } | 227 } |
242 EXPECT_EQ(extension_misc::EXTENSION_ICON_BITTY, | 228 EXPECT_EQ(extension_misc::EXTENSION_ICON_BITTY, |
243 img_rep1->pixel_width()); | 229 img_rep1->pixel_width()); |
244 EXPECT_EQ(extension_misc::EXTENSION_ICON_SMALLISH, | 230 EXPECT_EQ(extension_misc::EXTENSION_ICON_SMALLISH, |
245 img_rep2->pixel_width()); | 231 img_rep2->pixel_width()); |
246 } | 232 } |
247 | 233 |
248 // Tests IsComponentExtensionResource function. | 234 // Tests IsComponentExtensionResource function. |
249 TEST_F(ImageLoadingTrackerTest, IsComponentExtensionResource) { | 235 TEST_F(ImageLoaderTest, IsComponentExtensionResource) { |
250 scoped_refptr<Extension> extension(CreateExtension( | 236 scoped_refptr<Extension> extension(CreateExtension( |
251 "file_manager", Extension::COMPONENT)); | 237 "file_manager", Extension::COMPONENT)); |
252 ASSERT_TRUE(extension.get() != NULL); | 238 ASSERT_TRUE(extension.get() != NULL); |
253 | 239 |
254 ExtensionResource resource = | 240 ExtensionResource resource = |
255 extension->GetIconResource(extension_misc::EXTENSION_ICON_BITTY, | 241 extension->GetIconResource(extension_misc::EXTENSION_ICON_BITTY, |
256 ExtensionIconSet::MATCH_EXACTLY); | 242 ExtensionIconSet::MATCH_EXACTLY); |
257 | 243 |
258 #if defined(FILE_MANAGER_EXTENSION) | 244 #if defined(FILE_MANAGER_EXTENSION) |
259 ImageLoadingTracker loader(this); | |
260 int resource_id; | 245 int resource_id; |
261 ASSERT_EQ(true, | 246 ASSERT_EQ(true, |
262 loader.IsComponentExtensionResource(extension.get(), | 247 ImageLoader::IsComponentExtensionResource(extension.get(), |
263 resource.relative_path(), | 248 resource.relative_path(), |
264 &resource_id)); | 249 &resource_id)); |
265 ASSERT_EQ(IDR_FILE_MANAGER_ICON_16, resource_id); | 250 ASSERT_EQ(IDR_FILE_MANAGER_ICON_16, resource_id); |
266 #endif | 251 #endif |
267 } | 252 } |
OLD | NEW |