| 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 "base/json/json_file_value_serializer.h" | 5 #include "base/json/json_file_value_serializer.h" |
| 6 #include "base/message_loop.h" | 6 #include "base/message_loop.h" |
| 7 #include "base/path_service.h" | 7 #include "base/path_service.h" |
| 8 #include "chrome/browser/extensions/image_loading_tracker.h" | 8 #include "chrome/browser/extensions/image_loading_tracker.h" |
| 9 #include "chrome/common/chrome_notification_types.h" | 9 #include "chrome/common/chrome_notification_types.h" |
| 10 #include "chrome/common/chrome_paths.h" | 10 #include "chrome/common/chrome_paths.h" |
| 11 #include "chrome/common/extensions/extension.h" | 11 #include "chrome/common/extensions/extension.h" |
| 12 #include "chrome/common/extensions/extension_icon_set.h" | 12 #include "chrome/common/extensions/extension_icon_set.h" |
| 13 #include "chrome/common/extensions/extension_resource.h" | 13 #include "chrome/common/extensions/extension_resource.h" |
| 14 #include "content/public/browser/notification_service.h" | 14 #include "content/public/browser/notification_service.h" |
| 15 #include "content/test/test_browser_thread.h" | 15 #include "content/test/test_browser_thread.h" |
| 16 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
| 17 #include "third_party/skia/include/core/SkBitmap.h" | 17 #include "third_party/skia/include/core/SkBitmap.h" |
| 18 #include "ui/gfx/image/image.h" |
| 18 #include "ui/gfx/size.h" | 19 #include "ui/gfx/size.h" |
| 19 | 20 |
| 20 using content::BrowserThread; | 21 using content::BrowserThread; |
| 21 | 22 |
| 22 class ImageLoadingTrackerTest : public testing::Test, | 23 class ImageLoadingTrackerTest : public testing::Test, |
| 23 public ImageLoadingTracker::Observer { | 24 public ImageLoadingTracker::Observer { |
| 24 public: | 25 public: |
| 25 ImageLoadingTrackerTest() | 26 ImageLoadingTrackerTest() |
| 26 : image_loaded_count_(0), | 27 : image_loaded_count_(0), |
| 27 quit_in_image_loaded_(false), | 28 quit_in_image_loaded_(false), |
| 28 ui_thread_(BrowserThread::UI, &ui_loop_), | 29 ui_thread_(BrowserThread::UI, &ui_loop_), |
| 29 file_thread_(BrowserThread::FILE), | 30 file_thread_(BrowserThread::FILE), |
| 30 io_thread_(BrowserThread::IO) { | 31 io_thread_(BrowserThread::IO) { |
| 31 } | 32 } |
| 32 | 33 |
| 33 virtual void OnImageLoaded(SkBitmap* image, const ExtensionResource& resource, | 34 virtual void OnImageLoaded(const gfx::Image& image, |
| 34 int index) { | 35 const std::string& extension_id, |
| 36 int index) OVERRIDE { |
| 35 image_loaded_count_++; | 37 image_loaded_count_++; |
| 36 if (quit_in_image_loaded_) | 38 if (quit_in_image_loaded_) |
| 37 MessageLoop::current()->Quit(); | 39 MessageLoop::current()->Quit(); |
| 38 if (image) | 40 image_ = image; |
| 39 image_ = *image; | |
| 40 else | |
| 41 image_.reset(); | |
| 42 } | 41 } |
| 43 | 42 |
| 44 void WaitForImageLoad() { | 43 void WaitForImageLoad() { |
| 45 quit_in_image_loaded_ = true; | 44 quit_in_image_loaded_ = true; |
| 46 MessageLoop::current()->Run(); | 45 MessageLoop::current()->Run(); |
| 47 quit_in_image_loaded_ = false; | 46 quit_in_image_loaded_ = false; |
| 48 } | 47 } |
| 49 | 48 |
| 50 int image_loaded_count() { | 49 int image_loaded_count() { |
| 51 int result = image_loaded_count_; | 50 int result = image_loaded_count_; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 73 return NULL; | 72 return NULL; |
| 74 | 73 |
| 75 EXPECT_TRUE(valid_value.get()); | 74 EXPECT_TRUE(valid_value.get()); |
| 76 if (!valid_value.get()) | 75 if (!valid_value.get()) |
| 77 return NULL; | 76 return NULL; |
| 78 | 77 |
| 79 return Extension::Create(test_file, Extension::INVALID, *valid_value, | 78 return Extension::Create(test_file, Extension::INVALID, *valid_value, |
| 80 Extension::STRICT_ERROR_CHECKS, &error); | 79 Extension::STRICT_ERROR_CHECKS, &error); |
| 81 } | 80 } |
| 82 | 81 |
| 83 SkBitmap image_; | 82 gfx::Image image_; |
| 84 | 83 |
| 85 private: | 84 private: |
| 86 virtual void SetUp() { | 85 virtual void SetUp() { |
| 87 file_thread_.Start(); | 86 file_thread_.Start(); |
| 88 io_thread_.Start(); | 87 io_thread_.Start(); |
| 89 } | 88 } |
| 90 | 89 |
| 91 int image_loaded_count_; | 90 int image_loaded_count_; |
| 92 bool quit_in_image_loaded_; | 91 bool quit_in_image_loaded_; |
| 93 MessageLoop ui_loop_; | 92 MessageLoop ui_loop_; |
| 94 content::TestBrowserThread ui_thread_; | 93 content::TestBrowserThread ui_thread_; |
| 95 content::TestBrowserThread file_thread_; | 94 content::TestBrowserThread file_thread_; |
| 96 content::TestBrowserThread io_thread_; | 95 content::TestBrowserThread io_thread_; |
| 97 }; | 96 }; |
| 98 | 97 |
| 99 // Tests asking ImageLoadingTracker to cache pushes the result to the Extension. | 98 // Tests asking ImageLoadingTracker to cache pushes the result to the Extension. |
| 100 TEST_F(ImageLoadingTrackerTest, Cache) { | 99 TEST_F(ImageLoadingTrackerTest, Cache) { |
| 101 scoped_refptr<Extension> extension(CreateExtension()); | 100 scoped_refptr<Extension> extension(CreateExtension()); |
| 102 ASSERT_TRUE(extension.get() != NULL); | 101 ASSERT_TRUE(extension.get() != NULL); |
| 103 | 102 |
| 104 ExtensionResource image_resource = | 103 ExtensionResource image_resource = |
| 105 extension->GetIconResource(ExtensionIconSet::EXTENSION_ICON_SMALLISH, | 104 extension->GetIconResource(ExtensionIconSet::EXTENSION_ICON_SMALLISH, |
| 106 ExtensionIconSet::MATCH_EXACTLY); | 105 ExtensionIconSet::MATCH_EXACTLY); |
| 107 gfx::Size max_size(ExtensionIconSet::EXTENSION_ICON_SMALLISH, | 106 gfx::Size max_size(ExtensionIconSet::EXTENSION_ICON_SMALLISH, |
| 108 ExtensionIconSet::EXTENSION_ICON_SMALLISH); | 107 ExtensionIconSet::EXTENSION_ICON_SMALLISH); |
| 109 ImageLoadingTracker loader(static_cast<ImageLoadingTracker::Observer*>(this)); | 108 ImageLoadingTracker loader(this); |
| 110 loader.LoadImage(extension.get(), | 109 loader.LoadImage(extension.get(), |
| 111 image_resource, | 110 image_resource, |
| 112 max_size, | 111 max_size, |
| 113 ImageLoadingTracker::CACHE); | 112 ImageLoadingTracker::CACHE); |
| 114 | 113 |
| 115 // The image isn't cached, so we should not have received notification. | 114 // The image isn't cached, so we should not have received notification. |
| 116 EXPECT_EQ(0, image_loaded_count()); | 115 EXPECT_EQ(0, image_loaded_count()); |
| 117 | 116 |
| 118 WaitForImageLoad(); | 117 WaitForImageLoad(); |
| 119 | 118 |
| 120 // We should have gotten the image. | 119 // We should have gotten the image. |
| 121 EXPECT_EQ(1, image_loaded_count()); | 120 EXPECT_EQ(1, image_loaded_count()); |
| 122 | 121 |
| 123 // Check that the image was loaded. | 122 // Check that the image was loaded. |
| 124 EXPECT_EQ(ExtensionIconSet::EXTENSION_ICON_SMALLISH, image_.width()); | 123 EXPECT_EQ(ExtensionIconSet::EXTENSION_ICON_SMALLISH, |
| 124 image_.ToSkBitmap()->width()); |
| 125 | 125 |
| 126 // The image should be cached in the Extension. | 126 // The image should be cached in the Extension. |
| 127 EXPECT_TRUE(extension->HasCachedImage(image_resource, max_size)); | 127 EXPECT_TRUE(extension->HasCachedImage(image_resource, max_size)); |
| 128 | 128 |
| 129 // Make sure the image is in the extension. | 129 // Make sure the image is in the extension. |
| 130 EXPECT_EQ(ExtensionIconSet::EXTENSION_ICON_SMALLISH, | 130 EXPECT_EQ(ExtensionIconSet::EXTENSION_ICON_SMALLISH, |
| 131 extension->GetCachedImage(image_resource, max_size).width()); | 131 extension->GetCachedImage(image_resource, max_size).width()); |
| 132 | 132 |
| 133 // Ask the tracker for the image again, this should call us back immediately. | 133 // Ask the tracker for the image again, this should call us back immediately. |
| 134 loader.LoadImage(extension.get(), | 134 loader.LoadImage(extension.get(), |
| 135 image_resource, | 135 image_resource, |
| 136 max_size, | 136 max_size, |
| 137 ImageLoadingTracker::CACHE); | 137 ImageLoadingTracker::CACHE); |
| 138 // We should have gotten the image. | 138 // We should have gotten the image. |
| 139 EXPECT_EQ(1, image_loaded_count()); | 139 EXPECT_EQ(1, image_loaded_count()); |
| 140 | 140 |
| 141 // Check that the image was loaded. | 141 // Check that the image was loaded. |
| 142 EXPECT_EQ(ExtensionIconSet::EXTENSION_ICON_SMALLISH, image_.width()); | 142 EXPECT_EQ(ExtensionIconSet::EXTENSION_ICON_SMALLISH, |
| 143 image_.ToSkBitmap()->width()); |
| 143 } | 144 } |
| 144 | 145 |
| 145 // Tests deleting an extension while waiting for the image to load doesn't cause | 146 // Tests deleting an extension while waiting for the image to load doesn't cause |
| 146 // problems. | 147 // problems. |
| 147 TEST_F(ImageLoadingTrackerTest, DeleteExtensionWhileWaitingForCache) { | 148 TEST_F(ImageLoadingTrackerTest, DeleteExtensionWhileWaitingForCache) { |
| 148 scoped_refptr<Extension> extension(CreateExtension()); | 149 scoped_refptr<Extension> extension(CreateExtension()); |
| 149 ASSERT_TRUE(extension.get() != NULL); | 150 ASSERT_TRUE(extension.get() != NULL); |
| 150 | 151 |
| 151 ExtensionResource image_resource = | 152 ExtensionResource image_resource = |
| 152 extension->GetIconResource(ExtensionIconSet::EXTENSION_ICON_SMALLISH, | 153 extension->GetIconResource(ExtensionIconSet::EXTENSION_ICON_SMALLISH, |
| 153 ExtensionIconSet::MATCH_EXACTLY); | 154 ExtensionIconSet::MATCH_EXACTLY); |
| 154 ImageLoadingTracker loader(static_cast<ImageLoadingTracker::Observer*>(this)); | 155 ImageLoadingTracker loader(this); |
| 155 loader.LoadImage(extension.get(), | 156 loader.LoadImage(extension.get(), |
| 156 image_resource, | 157 image_resource, |
| 157 gfx::Size(ExtensionIconSet::EXTENSION_ICON_SMALLISH, | 158 gfx::Size(ExtensionIconSet::EXTENSION_ICON_SMALLISH, |
| 158 ExtensionIconSet::EXTENSION_ICON_SMALLISH), | 159 ExtensionIconSet::EXTENSION_ICON_SMALLISH), |
| 159 ImageLoadingTracker::CACHE); | 160 ImageLoadingTracker::CACHE); |
| 160 | 161 |
| 161 // The image isn't cached, so we should not have received notification. | 162 // The image isn't cached, so we should not have received notification. |
| 162 EXPECT_EQ(0, image_loaded_count()); | 163 EXPECT_EQ(0, image_loaded_count()); |
| 163 | 164 |
| 164 // Send out notification the extension was uninstalled. | 165 // Send out notification the extension was uninstalled. |
| 165 UnloadedExtensionInfo details(extension.get(), | 166 UnloadedExtensionInfo details(extension.get(), |
| 166 extension_misc::UNLOAD_REASON_UNINSTALL); | 167 extension_misc::UNLOAD_REASON_UNINSTALL); |
| 167 content::NotificationService::current()->Notify( | 168 content::NotificationService::current()->Notify( |
| 168 chrome::NOTIFICATION_EXTENSION_UNLOADED, | 169 chrome::NOTIFICATION_EXTENSION_UNLOADED, |
| 169 content::NotificationService::AllSources(), | 170 content::NotificationService::AllSources(), |
| 170 content::Details<UnloadedExtensionInfo>(&details)); | 171 content::Details<UnloadedExtensionInfo>(&details)); |
| 171 | 172 |
| 172 // Chuck the extension, that way if anyone tries to access it we should crash | 173 // Chuck the extension, that way if anyone tries to access it we should crash |
| 173 // or get valgrind errors. | 174 // or get valgrind errors. |
| 174 extension = NULL; | 175 extension = NULL; |
| 175 | 176 |
| 176 WaitForImageLoad(); | 177 WaitForImageLoad(); |
| 177 | 178 |
| 178 // Even though we deleted the extension, we should still get the image. | 179 // Even though we deleted the extension, we should still get the image. |
| 179 // We should still have gotten the image. | 180 // We should still have gotten the image. |
| 180 EXPECT_EQ(1, image_loaded_count()); | 181 EXPECT_EQ(1, image_loaded_count()); |
| 181 | 182 |
| 182 // Check that the image was loaded. | 183 // Check that the image was loaded. |
| 183 EXPECT_EQ(ExtensionIconSet::EXTENSION_ICON_SMALLISH, image_.width()); | 184 EXPECT_EQ(ExtensionIconSet::EXTENSION_ICON_SMALLISH, |
| 185 image_.ToSkBitmap()->width()); |
| 184 } | 186 } |
| 187 |
| 188 // Tests loading multiple dimensions of the same image. |
| 189 TEST_F(ImageLoadingTrackerTest, MultipleImages) { |
| 190 scoped_refptr<Extension> extension(CreateExtension()); |
| 191 ASSERT_TRUE(extension.get() != NULL); |
| 192 |
| 193 std::vector<ImageLoadingTracker::ImageInfo> info_list; |
| 194 int sizes[] = {ExtensionIconSet::EXTENSION_ICON_SMALLISH, |
| 195 ExtensionIconSet::EXTENSION_ICON_BITTY}; |
| 196 for (size_t i = 0; i < arraysize(sizes); ++i) { |
| 197 ExtensionResource resource = |
| 198 extension->GetIconResource(sizes[i], ExtensionIconSet::MATCH_EXACTLY); |
| 199 info_list.push_back(ImageLoadingTracker::ImageInfo( |
| 200 resource, gfx::Size(sizes[i], sizes[i]))); |
| 201 } |
| 202 |
| 203 ImageLoadingTracker loader(this); |
| 204 loader.LoadImages(extension.get(), info_list, ImageLoadingTracker::CACHE); |
| 205 |
| 206 // The image isn't cached, so we should not have received notification. |
| 207 EXPECT_EQ(0, image_loaded_count()); |
| 208 |
| 209 WaitForImageLoad(); |
| 210 |
| 211 // We should have gotten the image. |
| 212 EXPECT_EQ(1, image_loaded_count()); |
| 213 |
| 214 // Check that all images were loaded. |
| 215 ASSERT_EQ(2u, image_.GetNumberOfSkBitmaps()); |
| 216 const SkBitmap* bmp1 = image_.GetSkBitmapAtIndex(0); |
| 217 const SkBitmap* bmp2 = image_.GetSkBitmapAtIndex(1); |
| 218 if (bmp1->width() > bmp2->width()) { |
| 219 std::swap(bmp1, bmp2); |
| 220 } |
| 221 EXPECT_EQ(ExtensionIconSet::EXTENSION_ICON_BITTY, bmp1->width()); |
| 222 EXPECT_EQ(ExtensionIconSet::EXTENSION_ICON_SMALLISH, bmp2->width()); |
| 223 } |
| OLD | NEW |