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

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

Powered by Google App Engine
This is Rietveld 408576698