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 kAlternativeAppUrl
[] = "http://www.notchromium.org";
27 const char kAppTitle
[] = "Test title";
28 const char kAppShortName
[] = "Test short name";
29 const char kAlternativeAppTitle
[] = "Different test title";
30 const char kAppDescription
[] = "Test description";
32 const int kIconSizeTiny
= extension_misc::EXTENSION_ICON_BITTY
;
33 const int kIconSizeSmall
= extension_misc::EXTENSION_ICON_SMALL
;
34 const int kIconSizeMedium
= extension_misc::EXTENSION_ICON_MEDIUM
;
35 const int kIconSizeLarge
= extension_misc::EXTENSION_ICON_LARGE
;
37 class BookmarkAppHelperTest
: public testing::Test
{
39 BookmarkAppHelperTest() {}
40 virtual ~BookmarkAppHelperTest() {}
43 DISALLOW_COPY_AND_ASSIGN(BookmarkAppHelperTest
);
46 class BookmarkAppHelperExtensionServiceTest
47 : public extensions::ExtensionServiceTestBase
{
49 BookmarkAppHelperExtensionServiceTest() {}
50 virtual ~BookmarkAppHelperExtensionServiceTest() {}
52 virtual void SetUp() override
{
53 extensions::ExtensionServiceTestBase::SetUp();
54 InitializeEmptyExtensionService();
56 EXPECT_EQ(0u, service_
->extensions()->size());
59 virtual void TearDown() override
{
60 ExtensionServiceTestBase::TearDown();
61 for (content::RenderProcessHost::iterator
i(
62 content::RenderProcessHost::AllHostsIterator());
65 content::RenderProcessHost
* host
= i
.GetCurrentValue();
66 if (Profile::FromBrowserContext(host
->GetBrowserContext()) ==
73 DISALLOW_COPY_AND_ASSIGN(BookmarkAppHelperExtensionServiceTest
);
76 SkBitmap
CreateSquareBitmapWithColor(int size
, SkColor color
) {
78 bitmap
.allocN32Pixels(size
, size
);
79 bitmap
.eraseColor(color
);
83 void ValidateBitmapSizeAndColor(SkBitmap bitmap
, int size
, SkColor color
) {
84 // Obtain pixel lock to access pixels.
85 SkAutoLockPixels
lock(bitmap
);
86 EXPECT_EQ(color
, bitmap
.getColor(0, 0));
87 EXPECT_EQ(size
, bitmap
.width());
88 EXPECT_EQ(size
, bitmap
.height());
91 WebApplicationInfo::IconInfo
CreateIconInfoWithBitmap(int size
, SkColor color
) {
92 WebApplicationInfo::IconInfo icon_info
;
93 icon_info
.width
= size
;
94 icon_info
.height
= size
;
95 icon_info
.data
= CreateSquareBitmapWithColor(size
, color
);
99 void ValidateWebApplicationInfo(base::Closure callback
,
100 const WebApplicationInfo
& expected
,
101 const WebApplicationInfo
& actual
) {
102 EXPECT_EQ(expected
.title
, actual
.title
);
103 EXPECT_EQ(expected
.description
, actual
.description
);
104 EXPECT_EQ(expected
.app_url
, actual
.app_url
);
105 EXPECT_EQ(expected
.icons
.size(), actual
.icons
.size());
106 for (size_t i
= 0; i
< expected
.icons
.size(); ++i
) {
107 EXPECT_EQ(expected
.icons
[i
].width
, actual
.icons
[i
].width
);
108 EXPECT_EQ(expected
.icons
[i
].height
, actual
.icons
[i
].height
);
109 EXPECT_EQ(expected
.icons
[i
].url
, actual
.icons
[i
].url
);
111 gfx::BitmapsAreEqual(expected
.icons
[i
].data
, actual
.icons
[i
].data
));
118 namespace extensions
{
120 class TestBookmarkAppHelper
: public BookmarkAppHelper
{
122 TestBookmarkAppHelper(ExtensionService
* service
,
123 WebApplicationInfo web_app_info
,
124 content::WebContents
* contents
)
125 : BookmarkAppHelper(service
, web_app_info
, contents
) {}
127 ~TestBookmarkAppHelper() override
{}
129 void CreationComplete(const extensions::Extension
* extension
,
130 const WebApplicationInfo
& web_app_info
) {
131 extension_
= extension
;
134 void CompleteGetManifest(const content::Manifest
& manifest
) {
135 BookmarkAppHelper::OnDidGetManifest(manifest
);
138 void CompleteIconDownload(
140 const std::map
<GURL
, std::vector
<SkBitmap
> >& bitmaps
) {
141 BookmarkAppHelper::OnIconsDownloaded(success
, bitmaps
);
144 const Extension
* extension() { return extension_
; }
147 const Extension
* extension_
;
149 DISALLOW_COPY_AND_ASSIGN(TestBookmarkAppHelper
);
152 TEST_F(BookmarkAppHelperExtensionServiceTest
, CreateBookmarkApp
) {
153 WebApplicationInfo web_app_info
;
154 web_app_info
.app_url
= GURL(kAppUrl
);
155 web_app_info
.title
= base::UTF8ToUTF16(kAppTitle
);
156 web_app_info
.description
= base::UTF8ToUTF16(kAppDescription
);
158 scoped_ptr
<content::WebContents
> contents(
159 content::WebContentsTester::CreateTestWebContents(profile_
.get(), NULL
));
160 TestBookmarkAppHelper
helper(service_
, web_app_info
, contents
.get());
161 helper
.Create(base::Bind(&TestBookmarkAppHelper::CreationComplete
,
162 base::Unretained(&helper
)));
164 std::map
<GURL
, std::vector
<SkBitmap
> > icon_map
;
165 icon_map
[GURL(kAppUrl
)].push_back(
166 CreateSquareBitmapWithColor(kIconSizeSmall
, SK_ColorRED
));
167 helper
.CompleteIconDownload(true, icon_map
);
169 base::RunLoop().RunUntilIdle();
170 EXPECT_TRUE(helper
.extension());
171 const Extension
* extension
=
172 service_
->GetInstalledExtension(helper
.extension()->id());
173 EXPECT_TRUE(extension
);
174 EXPECT_EQ(1u, service_
->extensions()->size());
175 EXPECT_TRUE(extension
->from_bookmark());
176 EXPECT_EQ(kAppTitle
, extension
->name());
177 EXPECT_EQ(kAppDescription
, extension
->description());
178 EXPECT_EQ(GURL(kAppUrl
), AppLaunchInfo::GetLaunchWebURL(extension
));
180 IconsInfo::GetIconResource(
181 extension
, kIconSizeSmall
, ExtensionIconSet::MATCH_EXACTLY
).empty());
184 TEST_F(BookmarkAppHelperExtensionServiceTest
, CreateBookmarkAppWithManifest
) {
185 WebApplicationInfo web_app_info
;
187 scoped_ptr
<content::WebContents
> contents(
188 content::WebContentsTester::CreateTestWebContents(profile_
.get(), NULL
));
189 TestBookmarkAppHelper
helper(service_
, web_app_info
, contents
.get());
190 helper
.Create(base::Bind(&TestBookmarkAppHelper::CreationComplete
,
191 base::Unretained(&helper
)));
193 content::Manifest manifest
;
194 manifest
.start_url
= GURL(kAppUrl
);
195 manifest
.name
= base::NullableString16(base::UTF8ToUTF16(kAppTitle
), false);
196 helper
.CompleteGetManifest(manifest
);
198 std::map
<GURL
, std::vector
<SkBitmap
> > icon_map
;
199 helper
.CompleteIconDownload(true, icon_map
);
201 base::RunLoop().RunUntilIdle();
202 EXPECT_TRUE(helper
.extension());
203 const Extension
* extension
=
204 service_
->GetInstalledExtension(helper
.extension()->id());
205 EXPECT_TRUE(extension
);
206 EXPECT_EQ(1u, service_
->extensions()->size());
207 EXPECT_TRUE(extension
->from_bookmark());
208 EXPECT_EQ(kAppTitle
, extension
->name());
209 EXPECT_EQ(GURL(kAppUrl
), AppLaunchInfo::GetLaunchWebURL(extension
));
212 TEST_F(BookmarkAppHelperExtensionServiceTest
, CreateBookmarkAppNoContents
) {
213 WebApplicationInfo web_app_info
;
214 web_app_info
.app_url
= GURL(kAppUrl
);
215 web_app_info
.title
= base::UTF8ToUTF16(kAppTitle
);
216 web_app_info
.description
= base::UTF8ToUTF16(kAppDescription
);
217 web_app_info
.icons
.push_back(
218 CreateIconInfoWithBitmap(kIconSizeTiny
, SK_ColorRED
));
220 TestBookmarkAppHelper
helper(service_
, web_app_info
, NULL
);
221 helper
.Create(base::Bind(&TestBookmarkAppHelper::CreationComplete
,
222 base::Unretained(&helper
)));
224 base::RunLoop().RunUntilIdle();
225 EXPECT_TRUE(helper
.extension());
226 const Extension
* extension
=
227 service_
->GetInstalledExtension(helper
.extension()->id());
228 EXPECT_TRUE(extension
);
229 EXPECT_EQ(1u, service_
->extensions()->size());
230 EXPECT_TRUE(extension
->from_bookmark());
231 EXPECT_EQ(kAppTitle
, extension
->name());
232 EXPECT_EQ(kAppDescription
, extension
->description());
233 EXPECT_EQ(GURL(kAppUrl
), AppLaunchInfo::GetLaunchWebURL(extension
));
235 IconsInfo::GetIconResource(
236 extension
, kIconSizeTiny
, ExtensionIconSet::MATCH_EXACTLY
).empty());
238 IconsInfo::GetIconResource(
239 extension
, kIconSizeSmall
, ExtensionIconSet::MATCH_EXACTLY
).empty());
241 IconsInfo::GetIconResource(extension
,
243 ExtensionIconSet::MATCH_EXACTLY
).empty());
245 IconsInfo::GetIconResource(
246 extension
, kIconSizeMedium
, ExtensionIconSet::MATCH_EXACTLY
).empty());
248 IconsInfo::GetIconResource(extension
,
250 ExtensionIconSet::MATCH_EXACTLY
).empty());
253 TEST_F(BookmarkAppHelperExtensionServiceTest
, CreateAndUpdateBookmarkApp
) {
254 EXPECT_EQ(0u, registry()->enabled_extensions().size());
255 WebApplicationInfo web_app_info
;
256 web_app_info
.app_url
= GURL(kAppUrl
);
257 web_app_info
.title
= base::UTF8ToUTF16(kAppTitle
);
258 web_app_info
.description
= base::UTF8ToUTF16(kAppDescription
);
259 web_app_info
.icons
.push_back(
260 CreateIconInfoWithBitmap(kIconSizeSmall
, SK_ColorRED
));
262 extensions::CreateOrUpdateBookmarkApp(service_
, web_app_info
);
263 base::RunLoop().RunUntilIdle();
266 EXPECT_EQ(1u, registry()->enabled_extensions().size());
267 const Extension
* extension
= service_
->extensions()->begin()->get();
268 EXPECT_TRUE(extension
->from_bookmark());
269 EXPECT_EQ(kAppTitle
, extension
->name());
270 EXPECT_EQ(kAppDescription
, extension
->description());
271 EXPECT_EQ(GURL(kAppUrl
), AppLaunchInfo::GetLaunchWebURL(extension
));
272 EXPECT_FALSE(extensions::IconsInfo::GetIconResource(
273 extension
, kIconSizeSmall
, ExtensionIconSet::MATCH_EXACTLY
)
277 web_app_info
.title
= base::UTF8ToUTF16(kAlternativeAppTitle
);
278 web_app_info
.icons
[0] = CreateIconInfoWithBitmap(kIconSizeLarge
, SK_ColorRED
);
280 extensions::CreateOrUpdateBookmarkApp(service_
, web_app_info
);
281 base::RunLoop().RunUntilIdle();
284 EXPECT_EQ(1u, registry()->enabled_extensions().size());
285 const Extension
* extension
= service_
->extensions()->begin()->get();
286 EXPECT_TRUE(extension
->from_bookmark());
287 EXPECT_EQ(kAlternativeAppTitle
, extension
->name());
288 EXPECT_EQ(kAppDescription
, extension
->description());
289 EXPECT_EQ(GURL(kAppUrl
), AppLaunchInfo::GetLaunchWebURL(extension
));
290 EXPECT_TRUE(extensions::IconsInfo::GetIconResource(
291 extension
, kIconSizeSmall
, ExtensionIconSet::MATCH_EXACTLY
)
293 EXPECT_FALSE(extensions::IconsInfo::GetIconResource(
294 extension
, kIconSizeLarge
, ExtensionIconSet::MATCH_EXACTLY
)
299 TEST_F(BookmarkAppHelperExtensionServiceTest
, GetWebApplicationInfo
) {
300 WebApplicationInfo web_app_info
;
301 web_app_info
.app_url
= GURL(kAppUrl
);
302 web_app_info
.title
= base::UTF8ToUTF16(kAppTitle
);
303 web_app_info
.description
= base::UTF8ToUTF16(kAppDescription
);
305 web_app_info
.icons
.push_back(
306 CreateIconInfoWithBitmap(kIconSizeSmall
, SK_ColorRED
));
307 web_app_info
.icons
.push_back(
308 CreateIconInfoWithBitmap(kIconSizeLarge
, SK_ColorRED
));
310 extensions::CreateOrUpdateBookmarkApp(service_
, web_app_info
);
311 base::RunLoop().RunUntilIdle();
313 EXPECT_EQ(1u, registry()->enabled_extensions().size());
314 base::RunLoop run_loop
;
315 extensions::GetWebApplicationInfoFromApp(
317 service_
->extensions()->begin()->get(),
319 &ValidateWebApplicationInfo
, run_loop
.QuitClosure(), web_app_info
));
323 TEST_F(BookmarkAppHelperTest
, UpdateWebAppInfoFromManifest
) {
324 WebApplicationInfo web_app_info
;
325 web_app_info
.title
= base::UTF8ToUTF16(kAlternativeAppTitle
);
326 web_app_info
.app_url
= GURL(kAlternativeAppUrl
);
328 content::Manifest manifest
;
329 manifest
.start_url
= GURL(kAppUrl
);
330 manifest
.short_name
= base::NullableString16(base::UTF8ToUTF16(kAppShortName
),
333 BookmarkAppHelper::UpdateWebAppInfoFromManifest(manifest
, &web_app_info
);
334 EXPECT_EQ(base::UTF8ToUTF16(kAppShortName
), web_app_info
.title
);
335 EXPECT_EQ(GURL(kAppUrl
), web_app_info
.app_url
);
337 // Test that |manifest.name| takes priority over |manifest.short_name|
338 manifest
.name
= base::NullableString16(base::UTF8ToUTF16(kAppTitle
), false);
339 BookmarkAppHelper::UpdateWebAppInfoFromManifest(manifest
, &web_app_info
);
340 EXPECT_EQ(base::UTF8ToUTF16(kAppTitle
), web_app_info
.title
);
343 TEST_F(BookmarkAppHelperTest
, ConstrainBitmapsToSizes
) {
344 std::set
<int> desired_sizes
;
345 desired_sizes
.insert(16);
346 desired_sizes
.insert(32);
347 desired_sizes
.insert(128);
348 desired_sizes
.insert(256);
351 std::vector
<SkBitmap
> bitmaps
;
352 bitmaps
.push_back(CreateSquareBitmapWithColor(16, SK_ColorRED
));
353 bitmaps
.push_back(CreateSquareBitmapWithColor(32, SK_ColorGREEN
));
354 bitmaps
.push_back(CreateSquareBitmapWithColor(48, SK_ColorBLUE
));
355 bitmaps
.push_back(CreateSquareBitmapWithColor(144, SK_ColorYELLOW
));
357 std::map
<int, SkBitmap
> results(
358 BookmarkAppHelper::ConstrainBitmapsToSizes(bitmaps
, desired_sizes
));
360 EXPECT_EQ(3u, results
.size());
361 ValidateBitmapSizeAndColor(results
[16], 16, SK_ColorRED
);
362 ValidateBitmapSizeAndColor(results
[32], 32, SK_ColorGREEN
);
363 ValidateBitmapSizeAndColor(results
[128], 128, SK_ColorYELLOW
);
366 std::vector
<SkBitmap
> bitmaps
;
367 bitmaps
.push_back(CreateSquareBitmapWithColor(512, SK_ColorRED
));
368 bitmaps
.push_back(CreateSquareBitmapWithColor(18, SK_ColorGREEN
));
369 bitmaps
.push_back(CreateSquareBitmapWithColor(33, SK_ColorBLUE
));
370 bitmaps
.push_back(CreateSquareBitmapWithColor(17, SK_ColorYELLOW
));
372 std::map
<int, SkBitmap
> results(
373 BookmarkAppHelper::ConstrainBitmapsToSizes(bitmaps
, desired_sizes
));
375 EXPECT_EQ(3u, results
.size());
376 ValidateBitmapSizeAndColor(results
[16], 16, SK_ColorYELLOW
);
377 ValidateBitmapSizeAndColor(results
[32], 32, SK_ColorBLUE
);
378 ValidateBitmapSizeAndColor(results
[256], 256, SK_ColorRED
);
382 TEST_F(BookmarkAppHelperTest
, IsValidBookmarkAppUrl
) {
383 EXPECT_TRUE(IsValidBookmarkAppUrl(GURL("https://www.chromium.org")));
384 EXPECT_TRUE(IsValidBookmarkAppUrl(GURL("http://www.chromium.org/path")));
385 EXPECT_FALSE(IsValidBookmarkAppUrl(GURL("ftp://www.chromium.org")));
386 EXPECT_FALSE(IsValidBookmarkAppUrl(GURL("chrome://flags")));
389 } // namespace extensions