1 // Copyright 2014 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.
5 #include "chrome/browser/extensions/bookmark_app_helper.h"
7 #include "base/strings/utf_string_conversions.h"
8 #include "chrome/browser/extensions/extension_service.h"
9 #include "chrome/browser/extensions/extension_service_test_base.h"
10 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
11 #include "chrome/test/base/testing_profile.h"
12 #include "content/public/browser/render_process_host.h"
13 #include "content/public/browser/web_contents.h"
14 #include "content/public/test/web_contents_tester.h"
15 #include "extensions/browser/extension_registry.h"
16 #include "extensions/common/constants.h"
17 #include "extensions/common/extension_icon_set.h"
18 #include "extensions/common/manifest_handlers/icons_handler.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20 #include "third_party/skia/include/core/SkBitmap.h"
21 #include "ui/gfx/skia_util.h"
25 const char kAppUrl[] = "http://www.chromium.org";
26 const char kAppTitle[] = "Test title";
27 const char kAlternativeAppTitle[] = "Different test title";
28 const char kAppDescription[] = "Test description";
30 const int kIconSizeTiny = extension_misc::EXTENSION_ICON_BITTY;
31 const int kIconSizeSmall = extension_misc::EXTENSION_ICON_SMALL;
32 const int kIconSizeMedium = extension_misc::EXTENSION_ICON_MEDIUM;
33 const int kIconSizeLarge = extension_misc::EXTENSION_ICON_LARGE;
35 class BookmarkAppHelperTest : public testing::Test {
37 BookmarkAppHelperTest() {}
38 virtual ~BookmarkAppHelperTest() {}
41 DISALLOW_COPY_AND_ASSIGN(BookmarkAppHelperTest);
44 class BookmarkAppHelperExtensionServiceTest
45 : public extensions::ExtensionServiceTestBase {
47 BookmarkAppHelperExtensionServiceTest() {}
48 virtual ~BookmarkAppHelperExtensionServiceTest() {}
50 virtual void SetUp() OVERRIDE {
51 extensions::ExtensionServiceTestBase::SetUp();
52 InitializeEmptyExtensionService();
54 EXPECT_EQ(0u, service_->extensions()->size());
57 virtual void TearDown() OVERRIDE {
58 ExtensionServiceTestBase::TearDown();
59 for (content::RenderProcessHost::iterator i(
60 content::RenderProcessHost::AllHostsIterator());
63 content::RenderProcessHost* host = i.GetCurrentValue();
64 if (Profile::FromBrowserContext(host->GetBrowserContext()) ==
71 DISALLOW_COPY_AND_ASSIGN(BookmarkAppHelperExtensionServiceTest);
74 SkBitmap CreateSquareBitmapWithColor(int size, SkColor color) {
76 bitmap.allocN32Pixels(size, size);
77 bitmap.eraseColor(color);
81 void ValidateBitmapSizeAndColor(SkBitmap bitmap, int size, SkColor color) {
82 // Obtain pixel lock to access pixels.
83 SkAutoLockPixels lock(bitmap);
84 EXPECT_EQ(color, bitmap.getColor(0, 0));
85 EXPECT_EQ(size, bitmap.width());
86 EXPECT_EQ(size, bitmap.height());
89 WebApplicationInfo::IconInfo CreateIconInfoWithBitmap(int size, SkColor color) {
90 WebApplicationInfo::IconInfo icon_info;
91 icon_info.width = size;
92 icon_info.height = size;
93 icon_info.data = CreateSquareBitmapWithColor(size, color);
97 void ValidateWebApplicationInfo(base::Closure callback,
98 const WebApplicationInfo& expected,
99 const WebApplicationInfo& actual) {
100 EXPECT_EQ(expected.title, actual.title);
101 EXPECT_EQ(expected.description, actual.description);
102 EXPECT_EQ(expected.app_url, actual.app_url);
103 EXPECT_EQ(expected.icons.size(), actual.icons.size());
104 for (size_t i = 0; i < expected.icons.size(); ++i) {
105 EXPECT_EQ(expected.icons[i].width, actual.icons[i].width);
106 EXPECT_EQ(expected.icons[i].height, actual.icons[i].height);
107 EXPECT_EQ(expected.icons[i].url, actual.icons[i].url);
109 gfx::BitmapsAreEqual(expected.icons[i].data, actual.icons[i].data));
116 namespace extensions {
118 class TestBookmarkAppHelper : public BookmarkAppHelper {
120 TestBookmarkAppHelper(ExtensionService* service,
121 WebApplicationInfo web_app_info,
122 content::WebContents* contents)
123 : BookmarkAppHelper(service, web_app_info, contents) {}
125 virtual ~TestBookmarkAppHelper() {}
127 void CreationComplete(const extensions::Extension* extension,
128 const WebApplicationInfo& web_app_info) {
129 extension_ = extension;
132 void CompleteIconDownload(
134 const std::map<GURL, std::vector<SkBitmap> >& bitmaps) {
135 BookmarkAppHelper::OnIconsDownloaded(success, bitmaps);
138 const Extension* extension() { return extension_; }
141 const Extension* extension_;
143 DISALLOW_COPY_AND_ASSIGN(TestBookmarkAppHelper);
146 TEST_F(BookmarkAppHelperExtensionServiceTest, CreateBookmarkApp) {
147 WebApplicationInfo web_app_info;
148 web_app_info.app_url = GURL(kAppUrl);
149 web_app_info.title = base::UTF8ToUTF16(kAppTitle);
150 web_app_info.description = base::UTF8ToUTF16(kAppDescription);
152 scoped_ptr<content::WebContents> contents(
153 content::WebContentsTester::CreateTestWebContents(profile_.get(), NULL));
154 TestBookmarkAppHelper helper(service_, web_app_info, contents.get());
155 helper.Create(base::Bind(&TestBookmarkAppHelper::CreationComplete,
156 base::Unretained(&helper)));
158 std::map<GURL, std::vector<SkBitmap> > icon_map;
159 icon_map[GURL(kAppUrl)].push_back(
160 CreateSquareBitmapWithColor(kIconSizeSmall, SK_ColorRED));
161 helper.CompleteIconDownload(true, icon_map);
163 base::RunLoop().RunUntilIdle();
164 EXPECT_TRUE(helper.extension());
165 const Extension* extension =
166 service_->GetInstalledExtension(helper.extension()->id());
167 EXPECT_TRUE(extension);
168 EXPECT_EQ(1u, service_->extensions()->size());
169 EXPECT_TRUE(extension->from_bookmark());
170 EXPECT_EQ(kAppTitle, extension->name());
171 EXPECT_EQ(kAppDescription, extension->description());
172 EXPECT_EQ(GURL(kAppUrl), AppLaunchInfo::GetLaunchWebURL(extension));
174 IconsInfo::GetIconResource(
175 extension, kIconSizeSmall, ExtensionIconSet::MATCH_EXACTLY).empty());
178 TEST_F(BookmarkAppHelperExtensionServiceTest, CreateBookmarkAppNoContents) {
179 WebApplicationInfo web_app_info;
180 web_app_info.app_url = GURL(kAppUrl);
181 web_app_info.title = base::UTF8ToUTF16(kAppTitle);
182 web_app_info.description = base::UTF8ToUTF16(kAppDescription);
183 web_app_info.icons.push_back(
184 CreateIconInfoWithBitmap(kIconSizeTiny, SK_ColorRED));
186 TestBookmarkAppHelper helper(service_, web_app_info, NULL);
187 helper.Create(base::Bind(&TestBookmarkAppHelper::CreationComplete,
188 base::Unretained(&helper)));
190 base::RunLoop().RunUntilIdle();
191 EXPECT_TRUE(helper.extension());
192 const Extension* extension =
193 service_->GetInstalledExtension(helper.extension()->id());
194 EXPECT_TRUE(extension);
195 EXPECT_EQ(1u, service_->extensions()->size());
196 EXPECT_TRUE(extension->from_bookmark());
197 EXPECT_EQ(kAppTitle, extension->name());
198 EXPECT_EQ(kAppDescription, extension->description());
199 EXPECT_EQ(GURL(kAppUrl), AppLaunchInfo::GetLaunchWebURL(extension));
201 IconsInfo::GetIconResource(
202 extension, kIconSizeTiny, ExtensionIconSet::MATCH_EXACTLY).empty());
204 IconsInfo::GetIconResource(
205 extension, kIconSizeSmall, ExtensionIconSet::MATCH_EXACTLY).empty());
207 IconsInfo::GetIconResource(extension,
209 ExtensionIconSet::MATCH_EXACTLY).empty());
211 IconsInfo::GetIconResource(
212 extension, kIconSizeMedium, ExtensionIconSet::MATCH_EXACTLY).empty());
214 IconsInfo::GetIconResource(extension,
216 ExtensionIconSet::MATCH_EXACTLY).empty());
219 TEST_F(BookmarkAppHelperExtensionServiceTest, CreateAndUpdateBookmarkApp) {
220 EXPECT_EQ(0u, registry()->enabled_extensions().size());
221 WebApplicationInfo web_app_info;
222 web_app_info.app_url = GURL(kAppUrl);
223 web_app_info.title = base::UTF8ToUTF16(kAppTitle);
224 web_app_info.description = base::UTF8ToUTF16(kAppDescription);
225 web_app_info.icons.push_back(
226 CreateIconInfoWithBitmap(kIconSizeSmall, SK_ColorRED));
228 extensions::CreateOrUpdateBookmarkApp(service_, web_app_info);
229 base::RunLoop().RunUntilIdle();
232 EXPECT_EQ(1u, registry()->enabled_extensions().size());
233 const Extension* extension = service_->extensions()->begin()->get();
234 EXPECT_TRUE(extension->from_bookmark());
235 EXPECT_EQ(kAppTitle, extension->name());
236 EXPECT_EQ(kAppDescription, extension->description());
237 EXPECT_EQ(GURL(kAppUrl), AppLaunchInfo::GetLaunchWebURL(extension));
238 EXPECT_FALSE(extensions::IconsInfo::GetIconResource(
239 extension, kIconSizeSmall, ExtensionIconSet::MATCH_EXACTLY)
243 web_app_info.title = base::UTF8ToUTF16(kAlternativeAppTitle);
244 web_app_info.icons[0] = CreateIconInfoWithBitmap(kIconSizeLarge, SK_ColorRED);
246 extensions::CreateOrUpdateBookmarkApp(service_, web_app_info);
247 base::RunLoop().RunUntilIdle();
250 EXPECT_EQ(1u, registry()->enabled_extensions().size());
251 const Extension* extension = service_->extensions()->begin()->get();
252 EXPECT_TRUE(extension->from_bookmark());
253 EXPECT_EQ(kAlternativeAppTitle, extension->name());
254 EXPECT_EQ(kAppDescription, extension->description());
255 EXPECT_EQ(GURL(kAppUrl), AppLaunchInfo::GetLaunchWebURL(extension));
256 EXPECT_TRUE(extensions::IconsInfo::GetIconResource(
257 extension, kIconSizeSmall, ExtensionIconSet::MATCH_EXACTLY)
259 EXPECT_FALSE(extensions::IconsInfo::GetIconResource(
260 extension, kIconSizeLarge, ExtensionIconSet::MATCH_EXACTLY)
265 TEST_F(BookmarkAppHelperExtensionServiceTest, GetWebApplicationInfo) {
266 WebApplicationInfo web_app_info;
267 web_app_info.app_url = GURL(kAppUrl);
268 web_app_info.title = base::UTF8ToUTF16(kAppTitle);
269 web_app_info.description = base::UTF8ToUTF16(kAppDescription);
271 web_app_info.icons.push_back(
272 CreateIconInfoWithBitmap(kIconSizeSmall, SK_ColorRED));
273 web_app_info.icons.push_back(
274 CreateIconInfoWithBitmap(kIconSizeLarge, SK_ColorRED));
276 extensions::CreateOrUpdateBookmarkApp(service_, web_app_info);
277 base::RunLoop().RunUntilIdle();
279 EXPECT_EQ(1u, registry()->enabled_extensions().size());
280 base::RunLoop run_loop;
281 extensions::GetWebApplicationInfoFromApp(
283 service_->extensions()->begin()->get(),
285 &ValidateWebApplicationInfo, run_loop.QuitClosure(), web_app_info));
289 TEST_F(BookmarkAppHelperTest, ConstrainBitmapsToSizes) {
290 std::set<int> desired_sizes;
291 desired_sizes.insert(16);
292 desired_sizes.insert(32);
293 desired_sizes.insert(128);
294 desired_sizes.insert(256);
297 std::vector<SkBitmap> bitmaps;
298 bitmaps.push_back(CreateSquareBitmapWithColor(16, SK_ColorRED));
299 bitmaps.push_back(CreateSquareBitmapWithColor(32, SK_ColorGREEN));
300 bitmaps.push_back(CreateSquareBitmapWithColor(48, SK_ColorBLUE));
301 bitmaps.push_back(CreateSquareBitmapWithColor(144, SK_ColorYELLOW));
303 std::map<int, SkBitmap> results(
304 BookmarkAppHelper::ConstrainBitmapsToSizes(bitmaps, desired_sizes));
306 EXPECT_EQ(3u, results.size());
307 ValidateBitmapSizeAndColor(results[16], 16, SK_ColorRED);
308 ValidateBitmapSizeAndColor(results[32], 32, SK_ColorGREEN);
309 ValidateBitmapSizeAndColor(results[128], 128, SK_ColorYELLOW);
312 std::vector<SkBitmap> bitmaps;
313 bitmaps.push_back(CreateSquareBitmapWithColor(512, SK_ColorRED));
314 bitmaps.push_back(CreateSquareBitmapWithColor(18, SK_ColorGREEN));
315 bitmaps.push_back(CreateSquareBitmapWithColor(33, SK_ColorBLUE));
316 bitmaps.push_back(CreateSquareBitmapWithColor(17, SK_ColorYELLOW));
318 std::map<int, SkBitmap> results(
319 BookmarkAppHelper::ConstrainBitmapsToSizes(bitmaps, desired_sizes));
321 EXPECT_EQ(3u, results.size());
322 ValidateBitmapSizeAndColor(results[16], 16, SK_ColorYELLOW);
323 ValidateBitmapSizeAndColor(results[32], 32, SK_ColorBLUE);
324 ValidateBitmapSizeAndColor(results[256], 256, SK_ColorRED);
328 TEST_F(BookmarkAppHelperTest, IsValidBookmarkAppUrl) {
329 EXPECT_TRUE(IsValidBookmarkAppUrl(GURL("https://www.chromium.org")));
330 EXPECT_TRUE(IsValidBookmarkAppUrl(GURL("http://www.chromium.org/path")));
331 EXPECT_FALSE(IsValidBookmarkAppUrl(GURL("ftp://www.chromium.org")));
332 EXPECT_FALSE(IsValidBookmarkAppUrl(GURL("chrome://flags")));
335 } // namespace extensions