Chromium Code Reviews| 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 "build/build_config.h" | 5 #include "build/build_config.h" |
| 6 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h" | 6 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h" |
| 7 #include "chrome/browser/extensions/browser_action_test_util.h" | 7 #include "chrome/browser/extensions/browser_action_test_util.h" |
| 8 #include "chrome/browser/extensions/extension_action.h" | 8 #include "chrome/browser/extensions/extension_action.h" |
| 9 #include "chrome/browser/extensions/extension_action_icon_factory.h" | 9 #include "chrome/browser/extensions/extension_action_icon_factory.h" |
| 10 #include "chrome/browser/extensions/extension_action_manager.h" | 10 #include "chrome/browser/extensions/extension_action_manager.h" |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 26 #include "extensions/browser/extension_system.h" | 26 #include "extensions/browser/extension_system.h" |
| 27 #include "extensions/browser/notification_types.h" | 27 #include "extensions/browser/notification_types.h" |
| 28 #include "extensions/browser/process_manager.h" | 28 #include "extensions/browser/process_manager.h" |
| 29 #include "extensions/browser/test_extension_registry_observer.h" | 29 #include "extensions/browser/test_extension_registry_observer.h" |
| 30 #include "extensions/common/feature_switch.h" | 30 #include "extensions/common/feature_switch.h" |
| 31 #include "extensions/test/result_catcher.h" | 31 #include "extensions/test/result_catcher.h" |
| 32 #include "grit/theme_resources.h" | 32 #include "grit/theme_resources.h" |
| 33 #include "ui/base/resource/resource_bundle.h" | 33 #include "ui/base/resource/resource_bundle.h" |
| 34 #include "ui/gfx/geometry/rect.h" | 34 #include "ui/gfx/geometry/rect.h" |
| 35 #include "ui/gfx/geometry/size.h" | 35 #include "ui/gfx/geometry/size.h" |
| 36 #include "ui/gfx/image/canvas_image_source.h" | |
| 36 #include "ui/gfx/image/image_skia.h" | 37 #include "ui/gfx/image/image_skia.h" |
| 37 #include "ui/gfx/image/image_skia_operations.h" | 38 #include "ui/gfx/image/image_skia_operations.h" |
| 38 #include "ui/gfx/skia_util.h" | 39 #include "ui/gfx/skia_util.h" |
| 39 | 40 |
| 40 using content::WebContents; | 41 using content::WebContents; |
| 41 | 42 |
| 42 namespace extensions { | 43 namespace extensions { |
| 43 namespace { | 44 namespace { |
| 44 | 45 |
| 46 // An ImageSkia source that will do nothing (i.e., have a blank skia). We need | |
| 47 // this because we need a blank skia at a certain size, and that can't be done | |
| 48 // by an empty skia. | |
|
Avi (use Gerrit)
2015/07/02 00:33:23
"have a blank skia"? "empty skia"?
s/skia/canvas/
Devlin
2015/07/06 19:16:07
For "blank", yeah, blank canvas is better. For "e
Avi (use Gerrit)
2015/07/06 19:33:30
What is a "skia"? That's my question. ImageSkia is
Devlin
2015/07/06 19:35:52
That's fair. s/skia/ImageSkia.
| |
| 49 class BlankImageSource : public gfx::CanvasImageSource { | |
| 50 public: | |
| 51 explicit BlankImageSource(const gfx::Size& size) | |
| 52 : gfx::CanvasImageSource(size, false) {} | |
| 53 ~BlankImageSource() override {} | |
| 54 | |
| 55 void Draw(gfx::Canvas* canvas) override {} | |
| 56 | |
| 57 private: | |
| 58 DISALLOW_COPY_AND_ASSIGN(BlankImageSource); | |
| 59 }; | |
| 60 | |
| 45 const char kEmptyImageDataError[] = | 61 const char kEmptyImageDataError[] = |
| 46 "The imageData property must contain an ImageData object or dictionary " | 62 "The imageData property must contain an ImageData object or dictionary " |
| 47 "of ImageData objects."; | 63 "of ImageData objects."; |
| 48 const char kEmptyPathError[] = "The path property must not be empty."; | 64 const char kEmptyPathError[] = "The path property must not be empty."; |
| 49 | 65 |
| 50 // Views implementation of browser action button will return icon whose | 66 // Views platforms have the icon superimposed over a button's background. |
| 51 // background will be set. | 67 // Macs don't, but still need a 29x29-sized image (and the easiest way to do |
| 52 gfx::ImageSkia AddBackgroundForViews(const gfx::ImageSkia& icon) { | 68 // that is to superimpose the icon over a blank background). |
| 69 gfx::ImageSkia AddBackground(const gfx::ImageSkia& icon) { | |
| 53 #if !defined(OS_MACOSX) | 70 #if !defined(OS_MACOSX) |
| 54 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 71 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
| 55 gfx::ImageSkia bg = *rb.GetImageSkiaNamed(IDR_BROWSER_ACTION); | 72 gfx::ImageSkia bg = *rb.GetImageSkiaNamed(IDR_BROWSER_ACTION); |
| 73 #else | |
| 74 gfx::Size size(29, 29); // Size of browser actions buttons. | |
|
Finnur
2015/07/06 10:27:09
nit: const-ify.
Devlin
2015/07/06 19:16:07
Done.
| |
| 75 gfx::ImageSkia bg(new BlankImageSource(size), size); | |
| 76 #endif | |
| 56 return gfx::ImageSkiaOperations::CreateSuperimposedImage(bg, icon); | 77 return gfx::ImageSkiaOperations::CreateSuperimposedImage(bg, icon); |
| 57 #else | |
| 58 return icon; | |
| 59 #endif | |
| 60 } | 78 } |
| 61 | 79 |
| 62 bool ImagesAreEqualAtScale(const gfx::ImageSkia& i1, | 80 bool ImagesAreEqualAtScale(const gfx::ImageSkia& i1, |
| 63 const gfx::ImageSkia& i2, | 81 const gfx::ImageSkia& i2, |
| 64 float scale) { | 82 float scale) { |
| 65 SkBitmap bitmap1 = i1.GetRepresentation(scale).sk_bitmap(); | 83 SkBitmap bitmap1 = i1.GetRepresentation(scale).sk_bitmap(); |
| 66 SkBitmap bitmap2 = i2.GetRepresentation(scale).sk_bitmap(); | 84 SkBitmap bitmap2 = i2.GetRepresentation(scale).sk_bitmap(); |
| 67 return gfx::BitmapsAreEqual(bitmap1, bitmap2); | 85 return gfx::BitmapsAreEqual(bitmap1, bitmap2); |
| 68 } | 86 } |
| 69 | 87 |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 175 | 193 |
| 176 action_icon = icon_factory.GetIcon(0); | 194 action_icon = icon_factory.GetIcon(0); |
| 177 | 195 |
| 178 action_icon_current_id = action_icon.ToSkBitmap()->getGenerationID(); | 196 action_icon_current_id = action_icon.ToSkBitmap()->getGenerationID(); |
| 179 EXPECT_GT(action_icon_current_id, action_icon_last_id); | 197 EXPECT_GT(action_icon_current_id, action_icon_last_id); |
| 180 action_icon_last_id = action_icon_current_id; | 198 action_icon_last_id = action_icon_current_id; |
| 181 | 199 |
| 182 EXPECT_FALSE(action_icon.ToImageSkia()->HasRepresentation(2.0f)); | 200 EXPECT_FALSE(action_icon.ToImageSkia()->HasRepresentation(2.0f)); |
| 183 | 201 |
| 184 EXPECT_TRUE( | 202 EXPECT_TRUE( |
| 185 ImagesAreEqualAtScale(AddBackgroundForViews(*action_icon.ToImageSkia()), | 203 ImagesAreEqualAtScale(AddBackground(*action_icon.ToImageSkia()), |
| 186 *GetBrowserActionsBar()->GetIcon(0).ToImageSkia(), | 204 *GetBrowserActionsBar()->GetIcon(0).ToImageSkia(), |
| 187 1.0f)); | 205 1.0f)); |
| 188 | 206 |
| 189 // Tell the extension to update the icon using path. | 207 // Tell the extension to update the icon using path. |
| 190 GetBrowserActionsBar()->Press(0); | 208 GetBrowserActionsBar()->Press(0); |
| 191 ASSERT_TRUE(catcher.GetNextResult()); | 209 ASSERT_TRUE(catcher.GetNextResult()); |
| 192 | 210 |
| 193 action_icon = icon_factory.GetIcon(0); | 211 action_icon = icon_factory.GetIcon(0); |
| 194 | 212 |
| 195 action_icon_current_id = action_icon.ToSkBitmap()->getGenerationID(); | 213 action_icon_current_id = action_icon.ToSkBitmap()->getGenerationID(); |
| 196 EXPECT_GT(action_icon_current_id, action_icon_last_id); | 214 EXPECT_GT(action_icon_current_id, action_icon_last_id); |
| 197 action_icon_last_id = action_icon_current_id; | 215 action_icon_last_id = action_icon_current_id; |
| 198 | 216 |
| 199 EXPECT_FALSE( | 217 EXPECT_FALSE( |
| 200 action_icon.ToImageSkia()->HasRepresentation(2.0f)); | 218 action_icon.ToImageSkia()->HasRepresentation(2.0f)); |
| 201 | 219 |
| 202 EXPECT_TRUE( | 220 EXPECT_TRUE( |
| 203 ImagesAreEqualAtScale(AddBackgroundForViews(*action_icon.ToImageSkia()), | 221 ImagesAreEqualAtScale(AddBackground(*action_icon.ToImageSkia()), |
| 204 *GetBrowserActionsBar()->GetIcon(0).ToImageSkia(), | 222 *GetBrowserActionsBar()->GetIcon(0).ToImageSkia(), |
| 205 1.0f)); | 223 1.0f)); |
| 206 | 224 |
| 207 // Tell the extension to update the icon using dictionary of ImageData | 225 // Tell the extension to update the icon using dictionary of ImageData |
| 208 // objects. | 226 // objects. |
| 209 GetBrowserActionsBar()->Press(0); | 227 GetBrowserActionsBar()->Press(0); |
| 210 ASSERT_TRUE(catcher.GetNextResult()); | 228 ASSERT_TRUE(catcher.GetNextResult()); |
| 211 | 229 |
| 212 action_icon = icon_factory.GetIcon(0); | 230 action_icon = icon_factory.GetIcon(0); |
| 213 | 231 |
| 214 action_icon_current_id = action_icon.ToSkBitmap()->getGenerationID(); | 232 action_icon_current_id = action_icon.ToSkBitmap()->getGenerationID(); |
| 215 EXPECT_GT(action_icon_current_id, action_icon_last_id); | 233 EXPECT_GT(action_icon_current_id, action_icon_last_id); |
| 216 action_icon_last_id = action_icon_current_id; | 234 action_icon_last_id = action_icon_current_id; |
| 217 | 235 |
| 218 EXPECT_TRUE(action_icon.ToImageSkia()->HasRepresentation(2.0f)); | 236 EXPECT_TRUE(action_icon.ToImageSkia()->HasRepresentation(2.0f)); |
| 219 | 237 |
| 220 EXPECT_TRUE( | 238 EXPECT_TRUE( |
| 221 ImagesAreEqualAtScale(AddBackgroundForViews(*action_icon.ToImageSkia()), | 239 ImagesAreEqualAtScale(AddBackground(*action_icon.ToImageSkia()), |
| 222 *GetBrowserActionsBar()->GetIcon(0).ToImageSkia(), | 240 *GetBrowserActionsBar()->GetIcon(0).ToImageSkia(), |
| 223 1.0f)); | 241 1.0f)); |
| 224 | 242 |
| 225 // Tell the extension to update the icon using dictionary of paths. | 243 // Tell the extension to update the icon using dictionary of paths. |
| 226 GetBrowserActionsBar()->Press(0); | 244 GetBrowserActionsBar()->Press(0); |
| 227 ASSERT_TRUE(catcher.GetNextResult()); | 245 ASSERT_TRUE(catcher.GetNextResult()); |
| 228 | 246 |
| 229 action_icon = icon_factory.GetIcon(0); | 247 action_icon = icon_factory.GetIcon(0); |
| 230 | 248 |
| 231 action_icon_current_id = action_icon.ToSkBitmap()->getGenerationID(); | 249 action_icon_current_id = action_icon.ToSkBitmap()->getGenerationID(); |
| 232 EXPECT_GT(action_icon_current_id, action_icon_last_id); | 250 EXPECT_GT(action_icon_current_id, action_icon_last_id); |
| 233 action_icon_last_id = action_icon_current_id; | 251 action_icon_last_id = action_icon_current_id; |
| 234 | 252 |
| 235 EXPECT_TRUE(action_icon.ToImageSkia()->HasRepresentation(2.0f)); | 253 EXPECT_TRUE(action_icon.ToImageSkia()->HasRepresentation(2.0f)); |
| 236 | 254 |
| 237 EXPECT_TRUE( | 255 EXPECT_TRUE( |
| 238 ImagesAreEqualAtScale(AddBackgroundForViews(*action_icon.ToImageSkia()), | 256 ImagesAreEqualAtScale(AddBackground(*action_icon.ToImageSkia()), |
| 239 *GetBrowserActionsBar()->GetIcon(0).ToImageSkia(), | 257 *GetBrowserActionsBar()->GetIcon(0).ToImageSkia(), |
| 240 1.0f)); | 258 1.0f)); |
| 241 | 259 |
| 242 // Tell the extension to update the icon using dictionary of ImageData | 260 // Tell the extension to update the icon using dictionary of ImageData |
| 243 // objects, but setting only size 19. | 261 // objects, but setting only size 19. |
| 244 GetBrowserActionsBar()->Press(0); | 262 GetBrowserActionsBar()->Press(0); |
| 245 ASSERT_TRUE(catcher.GetNextResult()); | 263 ASSERT_TRUE(catcher.GetNextResult()); |
| 246 | 264 |
| 247 action_icon = icon_factory.GetIcon(0); | 265 action_icon = icon_factory.GetIcon(0); |
| 248 | 266 |
| 249 action_icon_current_id = action_icon.ToSkBitmap()->getGenerationID(); | 267 action_icon_current_id = action_icon.ToSkBitmap()->getGenerationID(); |
| 250 EXPECT_GT(action_icon_current_id, action_icon_last_id); | 268 EXPECT_GT(action_icon_current_id, action_icon_last_id); |
| 251 action_icon_last_id = action_icon_current_id; | 269 action_icon_last_id = action_icon_current_id; |
| 252 | 270 |
| 253 EXPECT_FALSE(action_icon.ToImageSkia()->HasRepresentation(2.0f)); | 271 EXPECT_FALSE(action_icon.ToImageSkia()->HasRepresentation(2.0f)); |
| 254 | 272 |
| 255 EXPECT_TRUE( | 273 EXPECT_TRUE( |
| 256 ImagesAreEqualAtScale(AddBackgroundForViews(*action_icon.ToImageSkia()), | 274 ImagesAreEqualAtScale(AddBackground(*action_icon.ToImageSkia()), |
| 257 *GetBrowserActionsBar()->GetIcon(0).ToImageSkia(), | 275 *GetBrowserActionsBar()->GetIcon(0).ToImageSkia(), |
| 258 1.0f)); | 276 1.0f)); |
| 259 | 277 |
| 260 // Tell the extension to update the icon using dictionary of paths, but | 278 // Tell the extension to update the icon using dictionary of paths, but |
| 261 // setting only size 19. | 279 // setting only size 19. |
| 262 GetBrowserActionsBar()->Press(0); | 280 GetBrowserActionsBar()->Press(0); |
| 263 ASSERT_TRUE(catcher.GetNextResult()); | 281 ASSERT_TRUE(catcher.GetNextResult()); |
| 264 | 282 |
| 265 action_icon = icon_factory.GetIcon(0); | 283 action_icon = icon_factory.GetIcon(0); |
| 266 | 284 |
| 267 action_icon_current_id = action_icon.ToSkBitmap()->getGenerationID(); | 285 action_icon_current_id = action_icon.ToSkBitmap()->getGenerationID(); |
| 268 EXPECT_GT(action_icon_current_id, action_icon_last_id); | 286 EXPECT_GT(action_icon_current_id, action_icon_last_id); |
| 269 action_icon_last_id = action_icon_current_id; | 287 action_icon_last_id = action_icon_current_id; |
| 270 | 288 |
| 271 EXPECT_FALSE(action_icon.ToImageSkia()->HasRepresentation(2.0f)); | 289 EXPECT_FALSE(action_icon.ToImageSkia()->HasRepresentation(2.0f)); |
| 272 | 290 |
| 273 EXPECT_TRUE( | 291 EXPECT_TRUE( |
| 274 ImagesAreEqualAtScale(AddBackgroundForViews(*action_icon.ToImageSkia()), | 292 ImagesAreEqualAtScale(AddBackground(*action_icon.ToImageSkia()), |
| 275 *GetBrowserActionsBar()->GetIcon(0).ToImageSkia(), | 293 *GetBrowserActionsBar()->GetIcon(0).ToImageSkia(), |
| 276 1.0f)); | 294 1.0f)); |
| 277 | 295 |
| 278 // Tell the extension to update the icon using dictionary of ImageData | 296 // Tell the extension to update the icon using dictionary of ImageData |
| 279 // objects, but setting only size 38. | 297 // objects, but setting only size 38. |
| 280 GetBrowserActionsBar()->Press(0); | 298 GetBrowserActionsBar()->Press(0); |
| 281 ASSERT_TRUE(catcher.GetNextResult()); | 299 ASSERT_TRUE(catcher.GetNextResult()); |
| 282 | 300 |
| 283 action_icon = icon_factory.GetIcon(0); | 301 action_icon = icon_factory.GetIcon(0); |
| 284 | 302 |
| 285 const gfx::ImageSkia* action_icon_skia = action_icon.ToImageSkia(); | 303 const gfx::ImageSkia* action_icon_skia = action_icon.ToImageSkia(); |
| 286 | 304 |
| 287 EXPECT_FALSE(action_icon_skia->HasRepresentation(1.0f)); | 305 EXPECT_FALSE(action_icon_skia->HasRepresentation(1.0f)); |
| 288 EXPECT_TRUE(action_icon_skia->HasRepresentation(2.0f)); | 306 EXPECT_TRUE(action_icon_skia->HasRepresentation(2.0f)); |
| 289 | 307 |
| 290 action_icon_current_id = action_icon.ToSkBitmap()->getGenerationID(); | 308 action_icon_current_id = action_icon.ToSkBitmap()->getGenerationID(); |
| 291 EXPECT_GT(action_icon_current_id, action_icon_last_id); | 309 EXPECT_GT(action_icon_current_id, action_icon_last_id); |
| 292 action_icon_last_id = action_icon_current_id; | 310 action_icon_last_id = action_icon_current_id; |
| 293 | 311 |
| 294 EXPECT_TRUE(gfx::BitmapsAreEqual( | 312 EXPECT_TRUE(gfx::BitmapsAreEqual( |
| 295 *action_icon.ToSkBitmap(), | 313 *action_icon.ToSkBitmap(), |
| 296 action_icon_skia->GetRepresentation(2.0f).sk_bitmap())); | 314 action_icon_skia->GetRepresentation(2.0f).sk_bitmap())); |
| 297 | 315 |
| 298 EXPECT_TRUE( | 316 EXPECT_TRUE( |
| 299 ImagesAreEqualAtScale(AddBackgroundForViews(*action_icon_skia), | 317 ImagesAreEqualAtScale(AddBackground(*action_icon_skia), |
| 300 *GetBrowserActionsBar()->GetIcon(0).ToImageSkia(), | 318 *GetBrowserActionsBar()->GetIcon(0).ToImageSkia(), |
| 301 2.0f)); | 319 2.0f)); |
| 302 | 320 |
| 303 // Try setting icon with empty dictionary of ImageData objects. | 321 // Try setting icon with empty dictionary of ImageData objects. |
| 304 GetBrowserActionsBar()->Press(0); | 322 GetBrowserActionsBar()->Press(0); |
| 305 ASSERT_FALSE(catcher.GetNextResult()); | 323 ASSERT_FALSE(catcher.GetNextResult()); |
| 306 EXPECT_EQ(kEmptyImageDataError, catcher.message()); | 324 EXPECT_EQ(kEmptyImageDataError, catcher.message()); |
| 307 | 325 |
| 308 // Try setting icon with empty dictionary of path objects. | 326 // Try setting icon with empty dictionary of path objects. |
| 309 GetBrowserActionsBar()->Press(0); | 327 GetBrowserActionsBar()->Press(0); |
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 654 const std::string script = | 672 const std::string script = |
| 655 "window.domAutomationController.send(document.body.style." | 673 "window.domAutomationController.send(document.body.style." |
| 656 "backgroundColor);"; | 674 "backgroundColor);"; |
| 657 std::string result; | 675 std::string result; |
| 658 EXPECT_TRUE(content::ExecuteScriptAndExtractString(tab, script, &result)); | 676 EXPECT_TRUE(content::ExecuteScriptAndExtractString(tab, script, &result)); |
| 659 EXPECT_EQ(result, "red"); | 677 EXPECT_EQ(result, "red"); |
| 660 } | 678 } |
| 661 | 679 |
| 662 } // namespace | 680 } // namespace |
| 663 } // namespace extensions | 681 } // namespace extensions |
| OLD | NEW |