Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(213)

Side by Side Diff: chrome/browser/extensions/api/extension_action/browser_action_apitest.cc

Issue 1580983002: Fix the dynamic browser action setIcon path to work with any size icon. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 <stdint.h> 5 #include <stdint.h>
6 6
7 #include "base/macros.h" 7 #include "base/macros.h"
8 #include "build/build_config.h" 8 #include "build/build_config.h"
9 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h" 9 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h"
10 #include "chrome/browser/extensions/browser_action_test_util.h" 10 #include "chrome/browser/extensions/browser_action_test_util.h"
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 61
62 private: 62 private:
63 DISALLOW_COPY_AND_ASSIGN(BlankImageSource); 63 DISALLOW_COPY_AND_ASSIGN(BlankImageSource);
64 }; 64 };
65 65
66 const char kEmptyImageDataError[] = 66 const char kEmptyImageDataError[] =
67 "The imageData property must contain an ImageData object or dictionary " 67 "The imageData property must contain an ImageData object or dictionary "
68 "of ImageData objects."; 68 "of ImageData objects.";
69 const char kEmptyPathError[] = "The path property must not be empty."; 69 const char kEmptyPathError[] = "The path property must not be empty.";
70 70
71 // Views platforms have the icon superimposed over a button's background.
72 // Macs don't, but still need a 29x29-sized image (and the easiest way to do
73 // that is to superimpose the icon over a blank background).
74 gfx::ImageSkia AddBackground(const gfx::ImageSkia& icon) {
75 #if !defined(OS_MACOSX)
76 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
77 gfx::ImageSkia bg = *rb.GetImageSkiaNamed(IDR_BROWSER_ACTION);
78 #else
79 const gfx::Size size(29, 29); // Size of browser actions buttons.
80 gfx::ImageSkia bg(new BlankImageSource(size), size);
81 #endif
82 return gfx::ImageSkiaOperations::CreateSuperimposedImage(bg, icon);
83 }
84
85 bool ImagesAreEqualAtScale(const gfx::ImageSkia& i1,
86 const gfx::ImageSkia& i2,
87 float scale) {
88 SkBitmap bitmap1 = i1.GetRepresentation(scale).sk_bitmap();
89 SkBitmap bitmap2 = i2.GetRepresentation(scale).sk_bitmap();
90 return gfx::BitmapsAreEqual(bitmap1, bitmap2);
91 }
92
93 class BrowserActionApiTest : public ExtensionApiTest { 71 class BrowserActionApiTest : public ExtensionApiTest {
94 public: 72 public:
95 BrowserActionApiTest() {} 73 BrowserActionApiTest() {}
96 ~BrowserActionApiTest() override {} 74 ~BrowserActionApiTest() override {}
97 75
98 protected: 76 protected:
99 BrowserActionTestUtil* GetBrowserActionsBar() { 77 BrowserActionTestUtil* GetBrowserActionsBar() {
100 if (!browser_action_test_util_) 78 if (!browser_action_test_util_)
101 browser_action_test_util_.reset(new BrowserActionTestUtil(browser())); 79 browser_action_test_util_.reset(new BrowserActionTestUtil(browser()));
102 return browser_action_test_util_.get(); 80 return browser_action_test_util_.get();
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
181 ASSERT_EQ(1, GetBrowserActionsBar()->NumberOfBrowserActions()); 159 ASSERT_EQ(1, GetBrowserActionsBar()->NumberOfBrowserActions());
182 EXPECT_TRUE(GetBrowserActionsBar()->HasIcon(0)); 160 EXPECT_TRUE(GetBrowserActionsBar()->HasIcon(0));
183 161
184 gfx::Image action_icon = icon_factory.GetIcon(0); 162 gfx::Image action_icon = icon_factory.GetIcon(0);
185 uint32_t action_icon_last_id = action_icon.ToSkBitmap()->getGenerationID(); 163 uint32_t action_icon_last_id = action_icon.ToSkBitmap()->getGenerationID();
186 164
187 // Let's check that |GetIcon| doesn't always return bitmap with new id. 165 // Let's check that |GetIcon| doesn't always return bitmap with new id.
188 ASSERT_EQ(action_icon_last_id, 166 ASSERT_EQ(action_icon_last_id,
189 icon_factory.GetIcon(0).ToSkBitmap()->getGenerationID()); 167 icon_factory.GetIcon(0).ToSkBitmap()->getGenerationID());
190 168
191 uint32_t action_icon_current_id = 0; 169 gfx::ImageSkia last_bar_icon =
170 GetBrowserActionsBar()->GetIcon(0).AsImageSkia();
171 EXPECT_TRUE(last_bar_icon.BackedBySameObjectAs(
172 GetBrowserActionsBar()->GetIcon(0).AsImageSkia()));
192 173
193 ResultCatcher catcher; 174 // The reason we don't test more standard scales (like 1x, 2x, etc.) is that
175 // these may be generated from the provided scales.
176 float kSmallIconScale = 21.f / ExtensionAction::ActionIconSize();
177 float kLargeIconScale = 42.f / ExtensionAction::ActionIconSize();
178 ASSERT_FALSE(ui::IsSupportedScale(kSmallIconScale));
179 ASSERT_FALSE(ui::IsSupportedScale(kLargeIconScale));
194 180
195 // Tell the extension to update the icon using ImageData object. 181 // Tell the extension to update the icon using ImageData object.
182 ResultCatcher catcher;
196 GetBrowserActionsBar()->Press(0); 183 GetBrowserActionsBar()->Press(0);
197 ASSERT_TRUE(catcher.GetNextResult()); 184 ASSERT_TRUE(catcher.GetNextResult());
198 185
199 action_icon = icon_factory.GetIcon(0); 186 action_icon = icon_factory.GetIcon(0);
187 EXPECT_FALSE(last_bar_icon.BackedBySameObjectAs(
188 GetBrowserActionsBar()->GetIcon(0).AsImageSkia()));
189 last_bar_icon = GetBrowserActionsBar()->GetIcon(0).AsImageSkia();
200 190
201 action_icon_current_id = action_icon.ToSkBitmap()->getGenerationID(); 191 uint32_t action_icon_current_id = action_icon.ToSkBitmap()->getGenerationID();
202 EXPECT_GT(action_icon_current_id, action_icon_last_id); 192 EXPECT_GT(action_icon_current_id, action_icon_last_id);
203 action_icon_last_id = action_icon_current_id; 193 action_icon_last_id = action_icon_current_id;
204 194
205 EXPECT_FALSE(action_icon.ToImageSkia()->HasRepresentation(2.0f)); 195 EXPECT_TRUE(action_icon.ToImageSkia()->HasRepresentation(kSmallIconScale));
206 196 EXPECT_FALSE(action_icon.ToImageSkia()->HasRepresentation(kLargeIconScale));
207 EXPECT_TRUE(
208 ImagesAreEqualAtScale(AddBackground(*action_icon.ToImageSkia()),
209 *GetBrowserActionsBar()->GetIcon(0).ToImageSkia(),
210 1.0f));
211 197
212 // Tell the extension to update the icon using path. 198 // Tell the extension to update the icon using path.
213 GetBrowserActionsBar()->Press(0); 199 GetBrowserActionsBar()->Press(0);
214 ASSERT_TRUE(catcher.GetNextResult()); 200 ASSERT_TRUE(catcher.GetNextResult());
215 201
202 // Make sure the browser action bar updated.
Evan Stade 2016/01/13 18:35:41 I couldn't come up with a good way to keep compari
Devlin 2016/01/13 19:58:12 What's stopping us from comparing pixels/bitmaps/e
Evan Stade 2016/01/14 01:59:19 We have to reconstruct the scaling that I recently
Devlin 2016/01/19 22:44:40 It seems that what we should be checking is that t
Evan Stade 2016/01/20 23:04:36 I think I found a way to salvage image comparisons
203 EXPECT_FALSE(last_bar_icon.BackedBySameObjectAs(
204 GetBrowserActionsBar()->GetIcon(0).AsImageSkia()));
205 last_bar_icon = GetBrowserActionsBar()->GetIcon(0).AsImageSkia();
206
216 action_icon = icon_factory.GetIcon(0); 207 action_icon = icon_factory.GetIcon(0);
217
218 action_icon_current_id = action_icon.ToSkBitmap()->getGenerationID(); 208 action_icon_current_id = action_icon.ToSkBitmap()->getGenerationID();
219 EXPECT_GT(action_icon_current_id, action_icon_last_id); 209 EXPECT_GT(action_icon_current_id, action_icon_last_id);
220 action_icon_last_id = action_icon_current_id; 210 action_icon_last_id = action_icon_current_id;
221 211
222 EXPECT_FALSE( 212 EXPECT_TRUE(action_icon.ToImageSkia()->HasRepresentation(kSmallIconScale));
223 action_icon.ToImageSkia()->HasRepresentation(2.0f)); 213 EXPECT_FALSE(action_icon.ToImageSkia()->HasRepresentation(kLargeIconScale));
224
225 EXPECT_TRUE(
226 ImagesAreEqualAtScale(AddBackground(*action_icon.ToImageSkia()),
227 *GetBrowserActionsBar()->GetIcon(0).ToImageSkia(),
228 1.0f));
229 214
230 // Tell the extension to update the icon using dictionary of ImageData 215 // Tell the extension to update the icon using dictionary of ImageData
231 // objects. 216 // objects.
232 GetBrowserActionsBar()->Press(0); 217 GetBrowserActionsBar()->Press(0);
233 ASSERT_TRUE(catcher.GetNextResult()); 218 ASSERT_TRUE(catcher.GetNextResult());
234 219
220 EXPECT_FALSE(last_bar_icon.BackedBySameObjectAs(
221 GetBrowserActionsBar()->GetIcon(0).AsImageSkia()));
222 last_bar_icon = GetBrowserActionsBar()->GetIcon(0).AsImageSkia();
223
235 action_icon = icon_factory.GetIcon(0); 224 action_icon = icon_factory.GetIcon(0);
236
237 action_icon_current_id = action_icon.ToSkBitmap()->getGenerationID(); 225 action_icon_current_id = action_icon.ToSkBitmap()->getGenerationID();
238 EXPECT_GT(action_icon_current_id, action_icon_last_id); 226 EXPECT_GT(action_icon_current_id, action_icon_last_id);
239 action_icon_last_id = action_icon_current_id; 227 action_icon_last_id = action_icon_current_id;
240 228
241 EXPECT_TRUE(action_icon.ToImageSkia()->HasRepresentation(2.0f)); 229 EXPECT_TRUE(action_icon.ToImageSkia()->HasRepresentation(kSmallIconScale));
242 230 EXPECT_TRUE(action_icon.ToImageSkia()->HasRepresentation(kLargeIconScale));
243 EXPECT_TRUE(
244 ImagesAreEqualAtScale(AddBackground(*action_icon.ToImageSkia()),
245 *GetBrowserActionsBar()->GetIcon(0).ToImageSkia(),
246 1.0f));
247 231
248 // Tell the extension to update the icon using dictionary of paths. 232 // Tell the extension to update the icon using dictionary of paths.
249 GetBrowserActionsBar()->Press(0); 233 GetBrowserActionsBar()->Press(0);
250 ASSERT_TRUE(catcher.GetNextResult()); 234 ASSERT_TRUE(catcher.GetNextResult());
251 235
236 EXPECT_FALSE(last_bar_icon.BackedBySameObjectAs(
237 GetBrowserActionsBar()->GetIcon(0).AsImageSkia()));
238 last_bar_icon = GetBrowserActionsBar()->GetIcon(0).AsImageSkia();
239
252 action_icon = icon_factory.GetIcon(0); 240 action_icon = icon_factory.GetIcon(0);
253
254 action_icon_current_id = action_icon.ToSkBitmap()->getGenerationID(); 241 action_icon_current_id = action_icon.ToSkBitmap()->getGenerationID();
255 EXPECT_GT(action_icon_current_id, action_icon_last_id); 242 EXPECT_GT(action_icon_current_id, action_icon_last_id);
256 action_icon_last_id = action_icon_current_id; 243 action_icon_last_id = action_icon_current_id;
257 244
258 EXPECT_TRUE(action_icon.ToImageSkia()->HasRepresentation(2.0f)); 245 EXPECT_TRUE(action_icon.ToImageSkia()->HasRepresentation(kSmallIconScale));
259 246 EXPECT_TRUE(action_icon.ToImageSkia()->HasRepresentation(kLargeIconScale));
260 EXPECT_TRUE(
261 ImagesAreEqualAtScale(AddBackground(*action_icon.ToImageSkia()),
262 *GetBrowserActionsBar()->GetIcon(0).ToImageSkia(),
263 1.0f));
264 247
265 // Tell the extension to update the icon using dictionary of ImageData 248 // Tell the extension to update the icon using dictionary of ImageData
266 // objects, but setting only size 19. 249 // objects, but setting only size 19.
267 GetBrowserActionsBar()->Press(0); 250 GetBrowserActionsBar()->Press(0);
268 ASSERT_TRUE(catcher.GetNextResult()); 251 ASSERT_TRUE(catcher.GetNextResult());
269 252
253 EXPECT_FALSE(last_bar_icon.BackedBySameObjectAs(
254 GetBrowserActionsBar()->GetIcon(0).AsImageSkia()));
255 last_bar_icon = GetBrowserActionsBar()->GetIcon(0).AsImageSkia();
256
270 action_icon = icon_factory.GetIcon(0); 257 action_icon = icon_factory.GetIcon(0);
271
272 action_icon_current_id = action_icon.ToSkBitmap()->getGenerationID(); 258 action_icon_current_id = action_icon.ToSkBitmap()->getGenerationID();
273 EXPECT_GT(action_icon_current_id, action_icon_last_id); 259 EXPECT_GT(action_icon_current_id, action_icon_last_id);
274 action_icon_last_id = action_icon_current_id; 260 action_icon_last_id = action_icon_current_id;
275 261
276 EXPECT_FALSE(action_icon.ToImageSkia()->HasRepresentation(2.0f)); 262 EXPECT_TRUE(action_icon.ToImageSkia()->HasRepresentation(kSmallIconScale));
277 263 EXPECT_FALSE(action_icon.ToImageSkia()->HasRepresentation(kLargeIconScale));
278 EXPECT_TRUE(
279 ImagesAreEqualAtScale(AddBackground(*action_icon.ToImageSkia()),
280 *GetBrowserActionsBar()->GetIcon(0).ToImageSkia(),
281 1.0f));
282 264
283 // Tell the extension to update the icon using dictionary of paths, but 265 // Tell the extension to update the icon using dictionary of paths, but
284 // setting only size 19. 266 // setting only size 19.
285 GetBrowserActionsBar()->Press(0); 267 GetBrowserActionsBar()->Press(0);
286 ASSERT_TRUE(catcher.GetNextResult()); 268 ASSERT_TRUE(catcher.GetNextResult());
287 269
270 EXPECT_FALSE(last_bar_icon.BackedBySameObjectAs(
271 GetBrowserActionsBar()->GetIcon(0).AsImageSkia()));
272 last_bar_icon = GetBrowserActionsBar()->GetIcon(0).AsImageSkia();
273
288 action_icon = icon_factory.GetIcon(0); 274 action_icon = icon_factory.GetIcon(0);
289
290 action_icon_current_id = action_icon.ToSkBitmap()->getGenerationID(); 275 action_icon_current_id = action_icon.ToSkBitmap()->getGenerationID();
291 EXPECT_GT(action_icon_current_id, action_icon_last_id); 276 EXPECT_GT(action_icon_current_id, action_icon_last_id);
292 action_icon_last_id = action_icon_current_id; 277 action_icon_last_id = action_icon_current_id;
293 278
294 EXPECT_FALSE(action_icon.ToImageSkia()->HasRepresentation(2.0f)); 279 EXPECT_TRUE(action_icon.ToImageSkia()->HasRepresentation(kSmallIconScale));
295 280 EXPECT_FALSE(action_icon.ToImageSkia()->HasRepresentation(kLargeIconScale));
296 EXPECT_TRUE(
297 ImagesAreEqualAtScale(AddBackground(*action_icon.ToImageSkia()),
298 *GetBrowserActionsBar()->GetIcon(0).ToImageSkia(),
299 1.0f));
300 281
301 // Tell the extension to update the icon using dictionary of ImageData 282 // Tell the extension to update the icon using dictionary of ImageData
302 // objects, but setting only size 38. 283 // objects, but setting only size 42.
303 GetBrowserActionsBar()->Press(0); 284 GetBrowserActionsBar()->Press(0);
304 ASSERT_TRUE(catcher.GetNextResult()); 285 ASSERT_TRUE(catcher.GetNextResult());
305 286
287 EXPECT_FALSE(last_bar_icon.BackedBySameObjectAs(
288 GetBrowserActionsBar()->GetIcon(0).AsImageSkia()));
289 last_bar_icon = GetBrowserActionsBar()->GetIcon(0).AsImageSkia();
290
306 action_icon = icon_factory.GetIcon(0); 291 action_icon = icon_factory.GetIcon(0);
307
308 const gfx::ImageSkia* action_icon_skia = action_icon.ToImageSkia();
309
310 EXPECT_FALSE(action_icon_skia->HasRepresentation(1.0f));
311 EXPECT_TRUE(action_icon_skia->HasRepresentation(2.0f));
312
313 action_icon_current_id = action_icon.ToSkBitmap()->getGenerationID(); 292 action_icon_current_id = action_icon.ToSkBitmap()->getGenerationID();
314 EXPECT_GT(action_icon_current_id, action_icon_last_id); 293 EXPECT_GT(action_icon_current_id, action_icon_last_id);
315 action_icon_last_id = action_icon_current_id; 294 action_icon_last_id = action_icon_current_id;
316 295
317 EXPECT_TRUE(gfx::BitmapsAreEqual( 296 EXPECT_FALSE(action_icon.ToImageSkia()->HasRepresentation(kSmallIconScale));
318 *action_icon.ToSkBitmap(), 297 EXPECT_TRUE(action_icon.ToImageSkia()->HasRepresentation(kLargeIconScale));
319 action_icon_skia->GetRepresentation(2.0f).sk_bitmap()));
320 298
321 EXPECT_TRUE( 299 EXPECT_TRUE(gfx::BitmapsAreEqual(*action_icon.ToSkBitmap(),
322 ImagesAreEqualAtScale(AddBackground(*action_icon_skia), 300 action_icon.ToImageSkia()
323 *GetBrowserActionsBar()->GetIcon(0).ToImageSkia(), 301 ->GetRepresentation(kLargeIconScale)
324 2.0f)); 302 .sk_bitmap()));
325 303
326 // Try setting icon with empty dictionary of ImageData objects. 304 // Try setting icon with empty dictionary of ImageData objects.
327 GetBrowserActionsBar()->Press(0); 305 GetBrowserActionsBar()->Press(0);
328 ASSERT_FALSE(catcher.GetNextResult()); 306 ASSERT_FALSE(catcher.GetNextResult());
329 EXPECT_EQ(kEmptyImageDataError, catcher.message()); 307 EXPECT_EQ(kEmptyImageDataError, catcher.message());
330 308
331 // Try setting icon with empty dictionary of path objects. 309 // Try setting icon with empty dictionary of path objects.
332 GetBrowserActionsBar()->Press(0); 310 GetBrowserActionsBar()->Press(0);
333 ASSERT_FALSE(catcher.GetNextResult()); 311 ASSERT_FALSE(catcher.GetNextResult());
334 EXPECT_EQ(kEmptyPathError, catcher.message()); 312 EXPECT_EQ(kEmptyPathError, catcher.message());
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after
730 std::string result; 708 std::string result;
731 EXPECT_TRUE( 709 EXPECT_TRUE(
732 content::ExecuteScriptAndExtractString(frame_host, script, &result)); 710 content::ExecuteScriptAndExtractString(frame_host, script, &result));
733 EXPECT_EQ("DONE", result); 711 EXPECT_EQ("DONE", result);
734 712
735 EXPECT_TRUE(actions_bar->HidePopup()); 713 EXPECT_TRUE(actions_bar->HidePopup());
736 } 714 }
737 715
738 } // namespace 716 } // namespace
739 } // namespace extensions 717 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698