| 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_action_icon_factory.h" | 5 #include "chrome/browser/extensions/extension_action_icon_factory.h" |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/file_util.h" | 8 #include "base/file_util.h" |
| 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" |
| (...skipping 20 matching lines...) Expand all Loading... |
| 31 #include "chrome/browser/chromeos/settings/device_settings_service.h" | 31 #include "chrome/browser/chromeos/settings/device_settings_service.h" |
| 32 #endif | 32 #endif |
| 33 | 33 |
| 34 using content::BrowserThread; | 34 using content::BrowserThread; |
| 35 | 35 |
| 36 namespace extensions { | 36 namespace extensions { |
| 37 namespace { | 37 namespace { |
| 38 | 38 |
| 39 bool ImageRepsAreEqual(const gfx::ImageSkiaRep& image_rep1, | 39 bool ImageRepsAreEqual(const gfx::ImageSkiaRep& image_rep1, |
| 40 const gfx::ImageSkiaRep& image_rep2) { | 40 const gfx::ImageSkiaRep& image_rep2) { |
| 41 return image_rep1.scale() == image_rep2.scale() && | 41 return image_rep1.scale_factor() == image_rep2.scale_factor() && |
| 42 gfx::BitmapsAreEqual(image_rep1.sk_bitmap(), image_rep2.sk_bitmap()); | 42 gfx::BitmapsAreEqual(image_rep1.sk_bitmap(), image_rep2.sk_bitmap()); |
| 43 } | 43 } |
| 44 | 44 |
| 45 gfx::Image EnsureImageSize(const gfx::Image& original, int size) { | 45 gfx::Image EnsureImageSize(const gfx::Image& original, int size) { |
| 46 const SkBitmap* original_bitmap = original.ToSkBitmap(); | 46 const SkBitmap* original_bitmap = original.ToSkBitmap(); |
| 47 if (original_bitmap->width() == size && original_bitmap->height() == size) | 47 if (original_bitmap->width() == size && original_bitmap->height() == size) |
| 48 return original; | 48 return original; |
| 49 | 49 |
| 50 SkBitmap resized = skia::ImageOperations::Resize( | 50 SkBitmap resized = skia::ImageOperations::Resize( |
| 51 *original.ToSkBitmap(), skia::ImageOperations::RESIZE_LANCZOS3, | 51 *original.ToSkBitmap(), skia::ImageOperations::RESIZE_LANCZOS3, |
| 52 size, size); | 52 size, size); |
| 53 return gfx::Image::CreateFrom1xBitmap(resized); | 53 return gfx::Image::CreateFrom1xBitmap(resized); |
| 54 } | 54 } |
| 55 | 55 |
| 56 gfx::ImageSkiaRep CreateBlankRep(int size_dip, float scale) { | 56 gfx::ImageSkiaRep CreateBlankRep(int size_dip, ui::ScaleFactor scale_factor) { |
| 57 SkBitmap bitmap; | 57 SkBitmap bitmap; |
| 58 bitmap.setConfig(SkBitmap::kARGB_8888_Config, | 58 const float scale = ui::GetScaleFactorScale(scale_factor); |
| 59 static_cast<int>(size_dip * scale), | 59 bitmap.setConfig(SkBitmap::kARGB_8888_Config, |
| 60 static_cast<int>(size_dip * scale)); | 60 static_cast<int>(size_dip * scale), |
| 61 bitmap.allocPixels(); | 61 static_cast<int>(size_dip * scale)); |
| 62 bitmap.eraseColor(SkColorSetARGB(0, 0, 0, 0)); | 62 bitmap.allocPixels(); |
| 63 return gfx::ImageSkiaRep(bitmap, scale); | 63 bitmap.eraseColor(SkColorSetARGB(0, 0, 0, 0)); |
| 64 return gfx::ImageSkiaRep(bitmap, scale_factor); |
| 64 } | 65 } |
| 65 | 66 |
| 66 gfx::Image LoadIcon(const std::string& filename) { | 67 gfx::Image LoadIcon(const std::string& filename) { |
| 67 base::FilePath path; | 68 base::FilePath path; |
| 68 PathService::Get(chrome::DIR_TEST_DATA, &path); | 69 PathService::Get(chrome::DIR_TEST_DATA, &path); |
| 69 path = path.AppendASCII("extensions/api_test").AppendASCII(filename); | 70 path = path.AppendASCII("extensions/api_test").AppendASCII(filename); |
| 70 | 71 |
| 71 std::string file_contents; | 72 std::string file_contents; |
| 72 base::ReadFileToString(path, &file_contents); | 73 base::ReadFileToString(path, &file_contents); |
| 73 const unsigned char* data = | 74 const unsigned char* data = |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 195 ASSERT_TRUE(browser_action->GetExplicitlySetIcon(0 /*tab id*/).isNull()); | 196 ASSERT_TRUE(browser_action->GetExplicitlySetIcon(0 /*tab id*/).isNull()); |
| 196 | 197 |
| 197 gfx::ImageSkia favicon = GetFavicon(); | 198 gfx::ImageSkia favicon = GetFavicon(); |
| 198 | 199 |
| 199 ExtensionActionIconFactory icon_factory( | 200 ExtensionActionIconFactory icon_factory( |
| 200 profile(), extension.get(), browser_action, this); | 201 profile(), extension.get(), browser_action, this); |
| 201 | 202 |
| 202 gfx::Image icon = icon_factory.GetIcon(0); | 203 gfx::Image icon = icon_factory.GetIcon(0); |
| 203 | 204 |
| 204 EXPECT_TRUE(ImageRepsAreEqual( | 205 EXPECT_TRUE(ImageRepsAreEqual( |
| 205 favicon.GetRepresentation(1.0f), | 206 favicon.GetRepresentation(ui::SCALE_FACTOR_100P), |
| 206 icon.ToImageSkia()->GetRepresentation(1.0f))); | 207 icon.ToImageSkia()->GetRepresentation(ui::SCALE_FACTOR_100P))); |
| 207 } | 208 } |
| 208 | 209 |
| 209 // If the icon has been set using |SetIcon|, the factory should return that | 210 // If the icon has been set using |SetIcon|, the factory should return that |
| 210 // icon. | 211 // icon. |
| 211 TEST_F(ExtensionActionIconFactoryTest, AfterSetIcon) { | 212 TEST_F(ExtensionActionIconFactoryTest, AfterSetIcon) { |
| 212 // Load an extension that has browser action without default icon set in the | 213 // Load an extension that has browser action without default icon set in the |
| 213 // manifest and does not call |SetIcon| by default (but has an browser action | 214 // manifest and does not call |SetIcon| by default (but has an browser action |
| 214 // icon resource). | 215 // icon resource). |
| 215 scoped_refptr<Extension> extension(CreateExtension( | 216 scoped_refptr<Extension> extension(CreateExtension( |
| 216 "browser_action/no_icon", Manifest::INVALID_LOCATION)); | 217 "browser_action/no_icon", Manifest::INVALID_LOCATION)); |
| 217 ASSERT_TRUE(extension.get() != NULL); | 218 ASSERT_TRUE(extension.get() != NULL); |
| 218 ExtensionAction* browser_action = GetBrowserAction(*extension.get()); | 219 ExtensionAction* browser_action = GetBrowserAction(*extension.get()); |
| 219 ASSERT_TRUE(browser_action); | 220 ASSERT_TRUE(browser_action); |
| 220 ASSERT_FALSE(browser_action->default_icon()); | 221 ASSERT_FALSE(browser_action->default_icon()); |
| 221 ASSERT_TRUE(browser_action->GetExplicitlySetIcon(0 /*tab id*/).isNull()); | 222 ASSERT_TRUE(browser_action->GetExplicitlySetIcon(0 /*tab id*/).isNull()); |
| 222 | 223 |
| 223 gfx::Image set_icon = LoadIcon("browser_action/no_icon/icon.png"); | 224 gfx::Image set_icon = LoadIcon("browser_action/no_icon/icon.png"); |
| 224 ASSERT_FALSE(set_icon.IsEmpty()); | 225 ASSERT_FALSE(set_icon.IsEmpty()); |
| 225 | 226 |
| 226 browser_action->SetIcon(0, set_icon); | 227 browser_action->SetIcon(0, set_icon); |
| 227 | 228 |
| 228 ASSERT_FALSE(browser_action->GetExplicitlySetIcon(0 /*tab id*/).isNull()); | 229 ASSERT_FALSE(browser_action->GetExplicitlySetIcon(0 /*tab id*/).isNull()); |
| 229 | 230 |
| 230 ExtensionActionIconFactory icon_factory( | 231 ExtensionActionIconFactory icon_factory( |
| 231 profile(), extension.get(), browser_action, this); | 232 profile(), extension.get(), browser_action, this); |
| 232 | 233 |
| 233 gfx::Image icon = icon_factory.GetIcon(0); | 234 gfx::Image icon = icon_factory.GetIcon(0); |
| 234 | 235 |
| 235 EXPECT_TRUE(ImageRepsAreEqual( | 236 EXPECT_TRUE(ImageRepsAreEqual( |
| 236 set_icon.ToImageSkia()->GetRepresentation(1.0f), | 237 set_icon.ToImageSkia()->GetRepresentation(ui::SCALE_FACTOR_100P), |
| 237 icon.ToImageSkia()->GetRepresentation(1.0f))); | 238 icon.ToImageSkia()->GetRepresentation(ui::SCALE_FACTOR_100P))); |
| 238 | 239 |
| 239 // It should still return favicon for another tabs. | 240 // It should still return favicon for another tabs. |
| 240 icon = icon_factory.GetIcon(1); | 241 icon = icon_factory.GetIcon(1); |
| 241 | 242 |
| 242 EXPECT_TRUE(ImageRepsAreEqual( | 243 EXPECT_TRUE(ImageRepsAreEqual( |
| 243 GetFavicon().GetRepresentation(1.0f), | 244 GetFavicon().GetRepresentation(ui::SCALE_FACTOR_100P), |
| 244 icon.ToImageSkia()->GetRepresentation(1.0f))); | 245 icon.ToImageSkia()->GetRepresentation(ui::SCALE_FACTOR_100P))); |
| 245 } | 246 } |
| 246 | 247 |
| 247 // If there is a default icon, and the icon has not been set using |SetIcon|, | 248 // If there is a default icon, and the icon has not been set using |SetIcon|, |
| 248 // the factory should return the default icon. | 249 // the factory should return the default icon. |
| 249 TEST_F(ExtensionActionIconFactoryTest, DefaultIcon) { | 250 TEST_F(ExtensionActionIconFactoryTest, DefaultIcon) { |
| 250 // Load an extension that has browser action without default icon set in the | 251 // Load an extension that has browser action without default icon set in the |
| 251 // manifest and does not call |SetIcon| by default (but has an browser action | 252 // manifest and does not call |SetIcon| by default (but has an browser action |
| 252 // icon resource). | 253 // icon resource). |
| 253 scoped_refptr<Extension> extension(CreateExtension( | 254 scoped_refptr<Extension> extension(CreateExtension( |
| 254 "browser_action/no_icon", Manifest::INVALID_LOCATION)); | 255 "browser_action/no_icon", Manifest::INVALID_LOCATION)); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 269 ASSERT_TRUE(browser_action->default_icon()); | 270 ASSERT_TRUE(browser_action->default_icon()); |
| 270 | 271 |
| 271 ExtensionActionIconFactory icon_factory( | 272 ExtensionActionIconFactory icon_factory( |
| 272 profile(), extension.get(), browser_action, this); | 273 profile(), extension.get(), browser_action, this); |
| 273 | 274 |
| 274 gfx::Image icon = icon_factory.GetIcon(0); | 275 gfx::Image icon = icon_factory.GetIcon(0); |
| 275 | 276 |
| 276 // The icon should be loaded asynchronously. Initially a transparent icon | 277 // The icon should be loaded asynchronously. Initially a transparent icon |
| 277 // should be returned. | 278 // should be returned. |
| 278 EXPECT_TRUE(ImageRepsAreEqual( | 279 EXPECT_TRUE(ImageRepsAreEqual( |
| 279 CreateBlankRep(19, 1.0f), | 280 CreateBlankRep(19, ui::SCALE_FACTOR_100P), |
| 280 icon.ToImageSkia()->GetRepresentation(1.0f))); | 281 icon.ToImageSkia()->GetRepresentation(ui::SCALE_FACTOR_100P))); |
| 281 | 282 |
| 282 WaitForIconUpdate(); | 283 WaitForIconUpdate(); |
| 283 | 284 |
| 284 icon = icon_factory.GetIcon(0); | 285 icon = icon_factory.GetIcon(0); |
| 285 | 286 |
| 286 // The default icon representation should be loaded at this point. | 287 // The default icon representation should be loaded at this point. |
| 287 EXPECT_TRUE(ImageRepsAreEqual( | 288 EXPECT_TRUE(ImageRepsAreEqual( |
| 288 default_icon.ToImageSkia()->GetRepresentation(1.0f), | 289 default_icon.ToImageSkia()->GetRepresentation(ui::SCALE_FACTOR_100P), |
| 289 icon.ToImageSkia()->GetRepresentation(1.0f))); | 290 icon.ToImageSkia()->GetRepresentation(ui::SCALE_FACTOR_100P))); |
| 290 | 291 |
| 291 // The same icon should be returned for the other tabs. | 292 // The same icon should be returned for the other tabs. |
| 292 icon = icon_factory.GetIcon(1); | 293 icon = icon_factory.GetIcon(1); |
| 293 | 294 |
| 294 EXPECT_TRUE(ImageRepsAreEqual( | 295 EXPECT_TRUE(ImageRepsAreEqual( |
| 295 default_icon.ToImageSkia()->GetRepresentation(1.0f), | 296 default_icon.ToImageSkia()->GetRepresentation(ui::SCALE_FACTOR_100P), |
| 296 icon.ToImageSkia()->GetRepresentation(1.0f))); | 297 icon.ToImageSkia()->GetRepresentation(ui::SCALE_FACTOR_100P))); |
| 297 | 298 |
| 298 } | 299 } |
| 299 | 300 |
| 300 } // namespace | 301 } // namespace |
| 301 } // namespace extensions | 302 } // namespace extensions |
| OLD | NEW |