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

Side by Side Diff: chrome/browser/extensions/extension_action_icon_factory_unittest.cc

Issue 10905005: Change browser/page action default icon defined in manifest to support hidpi. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: disable unittest on android Created 8 years, 3 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 | Annotate | Revision Log
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "chrome/browser/extensions/extension_action_icon_factory.h"
6
7 #include "base/file_util.h"
8 #include "base/json/json_file_value_serializer.h"
9 #include "base/message_loop.h"
10 #include "base/path_service.h"
11 #include "chrome/common/chrome_paths.h"
12 #include "chrome/common/extensions/extension.h"
13 #include "chrome/common/extensions/extension_action.h"
14 #include "content/public/test/test_browser_thread.h"
15 #include "grit/theme_resources.h"
16 #include "skia/ext/image_operations.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "ui/base/resource/resource_bundle.h"
19 #include "ui/gfx/image/image_skia.h"
20 #include "ui/gfx/skia_util.h"
21 #include "webkit/glue/image_decoder.h"
22
23 using content::BrowserThread;
24 using extensions::Extension;
25
26 namespace {
27
28 bool ImageRepsAreEqual(const gfx::ImageSkiaRep& image_rep1,
29 const gfx::ImageSkiaRep& image_rep2) {
30 return image_rep1.scale_factor() == image_rep2.scale_factor() &&
31 gfx::BitmapsAreEqual(image_rep1.sk_bitmap(), image_rep2.sk_bitmap());
32 }
33
34 gfx::Image EnsureImageSize(const gfx::Image& original, int size) {
35 const SkBitmap* original_bitmap = original.ToSkBitmap();
36 if (original_bitmap->width() == size && original_bitmap->height() == size)
37 return original;
38
39 SkBitmap resized = skia::ImageOperations::Resize(
40 *original.ToSkBitmap(), skia::ImageOperations::RESIZE_LANCZOS3,
41 size, size);
42 return gfx::Image(resized);
43 }
44
45 gfx::ImageSkiaRep CreateBlankRep(int size_dip, ui::ScaleFactor scale_factor) {
46 SkBitmap bitmap;
47 const float scale = ui::GetScaleFactorScale(scale_factor);
48 bitmap.setConfig(SkBitmap::kARGB_8888_Config,
49 static_cast<int>(size_dip * scale),
50 static_cast<int>(size_dip * scale));
51 bitmap.allocPixels();
52 bitmap.eraseColor(SkColorSetARGB(0, 0, 0, 0));
53 return gfx::ImageSkiaRep(bitmap, scale_factor);
54 }
55
56 gfx::Image LoadIcon(const std::string& filename) {
57 FilePath path;
58 PathService::Get(chrome::DIR_TEST_DATA, &path);
59 path = path.AppendASCII("extensions/api_test").AppendASCII(filename);
60
61 std::string file_contents;
62 file_util::ReadFileToString(path, &file_contents);
63 const unsigned char* data =
64 reinterpret_cast<const unsigned char*>(file_contents.data());
65
66 SkBitmap bitmap;
67 webkit_glue::ImageDecoder decoder;
68 bitmap = decoder.Decode(data, file_contents.length());
69
70 return gfx::Image(bitmap);
71 }
72
73 class ExtensionActionIconFactoryTest
74 : public testing::Test,
75 public ExtensionActionIconFactory::Observer {
76 public:
77 ExtensionActionIconFactoryTest()
78 : quit_in_icon_updated_(false),
79 ui_thread_(BrowserThread::UI, &ui_loop_),
80 file_thread_(BrowserThread::FILE),
81 io_thread_(BrowserThread::IO) {
82 }
83
84 virtual ~ExtensionActionIconFactoryTest() {}
85
86 void WaitForIconUpdate() {
87 quit_in_icon_updated_ = true;
88 MessageLoop::current()->Run();
89 quit_in_icon_updated_ = false;
90 }
91
92 scoped_refptr<Extension> CreateExtension(const char* name,
93 Extension::Location location) {
94 // Create and load an extension.
95 FilePath test_file;
96 if (!PathService::Get(chrome::DIR_TEST_DATA, &test_file)) {
97 EXPECT_FALSE(true);
98 return NULL;
99 }
100 test_file = test_file.AppendASCII("extensions/api_test").AppendASCII(name);
101 int error_code = 0;
102 std::string error;
103 JSONFileValueSerializer serializer(test_file.AppendASCII("manifest.json"));
104 scoped_ptr<DictionaryValue> valid_value(
105 static_cast<DictionaryValue*>(serializer.Deserialize(&error_code,
106 &error)));
107 EXPECT_EQ(0, error_code) << error;
108 if (error_code != 0)
109 return NULL;
110
111 EXPECT_TRUE(valid_value.get());
112 if (!valid_value.get())
113 return NULL;
114
115 return Extension::Create(test_file, location, *valid_value,
116 Extension::NO_FLAGS, &error);
117 }
118
119 // testing::Test overrides:
120 virtual void SetUp() OVERRIDE {
121 file_thread_.Start();
122 io_thread_.Start();
123 }
124
125 // ExtensionActionIconFactory::Observer overrides:
126 virtual void OnIconUpdated() OVERRIDE {
127 if (quit_in_icon_updated_)
128 MessageLoop::current()->Quit();
129 }
130
131 gfx::ImageSkia GetFavicon() {
132 return *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
133 IDR_EXTENSIONS_FAVICON);
134 }
135
136 private:
137 bool quit_in_icon_updated_;
138 MessageLoop ui_loop_;
139 content::TestBrowserThread ui_thread_;
140 content::TestBrowserThread file_thread_;
141 content::TestBrowserThread io_thread_;
142
143 DISALLOW_COPY_AND_ASSIGN(ExtensionActionIconFactoryTest);
144 };
145
146 // If there is no default icon, and the icon has not been set using |SetIcon|,
147 // the factory should return favicon.
148 TEST_F(ExtensionActionIconFactoryTest, NoIcons) {
149 // Load an extension that has browser action without default icon set in the
150 // manifest and does not call |SetIcon| by default.
151 scoped_refptr<Extension> extension(CreateExtension(
152 "browser_action/no_icon", Extension::INVALID));
153 ASSERT_TRUE(extension.get() != NULL);
154 ASSERT_TRUE(extension->browser_action());
155 ASSERT_FALSE(extension->browser_action()->default_icon());
156 ASSERT_TRUE(
157 extension->browser_action()->GetExplicitlySetIcon(0 /*tab id*/).isNull());
158
159 gfx::ImageSkia favicon = GetFavicon();
160
161 ExtensionActionIconFactory icon_factory(extension,
162 extension->browser_action(),
163 this);
164
165 gfx::Image icon = icon_factory.GetIcon(0);
166
167 EXPECT_TRUE(ImageRepsAreEqual(
168 favicon.GetRepresentation(ui::SCALE_FACTOR_100P),
169 icon.ToImageSkia()->GetRepresentation(ui::SCALE_FACTOR_100P)));
170 }
171
172 // If the icon has been set using |SetIcon|, the factory should return that
173 // icon.
174 TEST_F(ExtensionActionIconFactoryTest, AfterSetIcon) {
175 // Load an extension that has browser action without default icon set in the
176 // manifest and does not call |SetIcon| by default (but has an browser action
177 // icon resource).
178 scoped_refptr<Extension> extension(CreateExtension(
179 "browser_action/no_icon", Extension::INVALID));
180 ASSERT_TRUE(extension.get() != NULL);
181 ASSERT_TRUE(extension->browser_action());
182 ASSERT_FALSE(extension->browser_action()->default_icon());
183 ASSERT_TRUE(
184 extension->browser_action()->GetExplicitlySetIcon(0 /*tab id*/).isNull());
185
186 gfx::Image set_icon = LoadIcon("browser_action/no_icon/icon.png");
187 ASSERT_FALSE(set_icon.IsEmpty());
188
189 extension->browser_action()->SetIcon(0, set_icon);
190
191 ASSERT_FALSE(
192 extension->browser_action()->GetExplicitlySetIcon(0 /*tab id*/).isNull());
193
194 ExtensionActionIconFactory icon_factory(extension,
195 extension->browser_action(),
196 this);
197
198 gfx::Image icon = icon_factory.GetIcon(0);
199
200 EXPECT_TRUE(ImageRepsAreEqual(
201 set_icon.ToImageSkia()->GetRepresentation(ui::SCALE_FACTOR_100P),
202 icon.ToImageSkia()->GetRepresentation(ui::SCALE_FACTOR_100P)));
203
204 // It should still return favicon for another tabs.
205 icon = icon_factory.GetIcon(1);
206
207 EXPECT_TRUE(ImageRepsAreEqual(
208 GetFavicon().GetRepresentation(ui::SCALE_FACTOR_100P),
209 icon.ToImageSkia()->GetRepresentation(ui::SCALE_FACTOR_100P)));
210 }
211
212 // If there is a default icon, and the icon has not been set using |SetIcon|,
213 // the factory should return the default icon.
214 TEST_F(ExtensionActionIconFactoryTest, DefaultIcon) {
215 // Load an extension that has browser action without default icon set in the
216 // manifest and does not call |SetIcon| by default (but has an browser action
217 // icon resource).
218 scoped_refptr<Extension> extension(CreateExtension(
219 "browser_action/no_icon", Extension::INVALID));
220 ASSERT_TRUE(extension.get() != NULL);
221 ASSERT_TRUE(extension->browser_action());
222 ASSERT_FALSE(extension->browser_action()->default_icon());
223 ASSERT_TRUE(
224 extension->browser_action()->GetExplicitlySetIcon(0 /*tab id*/).isNull());
225
226 gfx::Image default_icon =
227 EnsureImageSize(LoadIcon("browser_action/no_icon/icon.png"), 19);
228 ASSERT_FALSE(default_icon.IsEmpty());
229
230 scoped_ptr<ExtensionIconSet> default_icon_set(new ExtensionIconSet());
231 default_icon_set->Add(19, "icon.png");
232
233 extension->browser_action()->set_default_icon(default_icon_set.Pass());
234 ASSERT_TRUE(extension->browser_action()->default_icon());
235
236 ExtensionActionIconFactory icon_factory(extension,
237 extension->browser_action(),
238 this);
239
240 gfx::Image icon = icon_factory.GetIcon(0);
241
242 // The icon should be loaded asynchronously. Initially a transparent icon
243 // should be returned.
244 EXPECT_TRUE(ImageRepsAreEqual(
245 CreateBlankRep(19, ui::SCALE_FACTOR_100P),
246 icon.ToImageSkia()->GetRepresentation(ui::SCALE_FACTOR_100P)));
247
248 WaitForIconUpdate();
249
250 icon = icon_factory.GetIcon(0);
251
252 // The default icon representation should be loaded at this point.
253 EXPECT_TRUE(ImageRepsAreEqual(
254 default_icon.ToImageSkia()->GetRepresentation(ui::SCALE_FACTOR_100P),
255 icon.ToImageSkia()->GetRepresentation(ui::SCALE_FACTOR_100P)));
256
257 // The same icon should be returned for the other tabs.
258 icon = icon_factory.GetIcon(1);
259
260 EXPECT_TRUE(ImageRepsAreEqual(
261 default_icon.ToImageSkia()->GetRepresentation(ui::SCALE_FACTOR_100P),
262 icon.ToImageSkia()->GetRepresentation(ui::SCALE_FACTOR_100P)));
263
264 }
265
266 } // namespace
OLDNEW
« no previous file with comments | « chrome/browser/extensions/extension_action_icon_factory.cc ('k') | chrome/browser/extensions/extension_icon_image.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698