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/test_web_contents_factory.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"
23 namespace extensions
{
27 const char kAppUrl
[] = "http://www.chromium.org";
28 const char kAlternativeAppUrl
[] = "http://www.notchromium.org";
29 const char kAppTitle
[] = "Test title";
30 const char kAppShortName
[] = "Test short name";
31 const char kAlternativeAppTitle
[] = "Different test title";
32 const char kAppDescription
[] = "Test description";
33 const char kAppIcon1
[] = "fav1.png";
34 const char kAppIcon2
[] = "fav2.png";
35 const char kAppIcon3
[] = "fav3.png";
36 const char kAppIconURL1
[] = "http://foo.com/1.png";
37 const char kAppIconURL2
[] = "http://foo.com/2.png";
38 const char kAppIconURL3
[] = "http://foo.com/3.png";
39 const char kAppIconURL4
[] = "http://foo.com/4.png";
41 const int kIconSizeTiny
= extension_misc::EXTENSION_ICON_BITTY
;
42 const int kIconSizeSmall
= extension_misc::EXTENSION_ICON_SMALL
;
43 const int kIconSizeMedium
= extension_misc::EXTENSION_ICON_MEDIUM
;
44 const int kIconSizeLarge
= extension_misc::EXTENSION_ICON_LARGE
;
45 const int kIconSizeGigantor
= extension_misc::EXTENSION_ICON_GIGANTOR
;
46 const int kIconSizeUnsupported
= 123;
48 const int kIconSizeSmallBetweenMediumAndLarge
= 63;
49 const int kIconSizeLargeBetweenMediumAndLarge
= 96;
51 class BookmarkAppHelperTest
: public testing::Test
{
53 BookmarkAppHelperTest() {}
54 ~BookmarkAppHelperTest() override
{}
57 DISALLOW_COPY_AND_ASSIGN(BookmarkAppHelperTest
);
60 class BookmarkAppHelperExtensionServiceTest
61 : public extensions::ExtensionServiceTestBase
{
63 BookmarkAppHelperExtensionServiceTest() {}
64 ~BookmarkAppHelperExtensionServiceTest() override
{}
66 void SetUp() override
{
67 extensions::ExtensionServiceTestBase::SetUp();
68 InitializeEmptyExtensionService();
70 EXPECT_EQ(0u, registry()->enabled_extensions().size());
73 void TearDown() override
{
74 ExtensionServiceTestBase::TearDown();
75 for (content::RenderProcessHost::iterator
i(
76 content::RenderProcessHost::AllHostsIterator());
79 content::RenderProcessHost
* host
= i
.GetCurrentValue();
80 if (Profile::FromBrowserContext(host
->GetBrowserContext()) ==
87 DISALLOW_COPY_AND_ASSIGN(BookmarkAppHelperExtensionServiceTest
);
90 SkBitmap
CreateSquareBitmapWithColor(int size
, SkColor color
) {
92 bitmap
.allocN32Pixels(size
, size
);
93 bitmap
.eraseColor(color
);
97 BookmarkAppHelper::BitmapAndSource
CreateSquareBitmapAndSourceWithColor(
100 return BookmarkAppHelper::BitmapAndSource(
101 GURL(), CreateSquareBitmapWithColor(size
, color
));
104 void ValidateBitmapSizeAndColor(SkBitmap bitmap
, int size
, SkColor color
) {
105 // Obtain pixel lock to access pixels.
106 SkAutoLockPixels
lock(bitmap
);
107 EXPECT_EQ(color
, bitmap
.getColor(0, 0));
108 EXPECT_EQ(size
, bitmap
.width());
109 EXPECT_EQ(size
, bitmap
.height());
112 WebApplicationInfo::IconInfo
CreateIconInfoWithBitmap(int size
, SkColor color
) {
113 WebApplicationInfo::IconInfo icon_info
;
114 icon_info
.width
= size
;
115 icon_info
.height
= size
;
116 icon_info
.data
= CreateSquareBitmapWithColor(size
, color
);
120 std::set
<int> TestSizesToGenerate() {
121 const int kIconSizesToGenerate
[] = {
122 extension_misc::EXTENSION_ICON_SMALL
,
123 extension_misc::EXTENSION_ICON_MEDIUM
,
124 extension_misc::EXTENSION_ICON_LARGE
,
126 return std::set
<int>(kIconSizesToGenerate
,
127 kIconSizesToGenerate
+ arraysize(kIconSizesToGenerate
));
130 void ValidateAllIconsWithURLsArePresent(const WebApplicationInfo
& info_to_check
,
131 const WebApplicationInfo
& other_info
) {
132 for (const auto& icon
: info_to_check
.icons
) {
133 if (!icon
.url
.is_empty()) {
135 for (const auto& other_icon
: info_to_check
.icons
) {
136 if (other_icon
.url
== icon
.url
&& other_icon
.width
== icon
.width
) {
146 std::vector
<BookmarkAppHelper::BitmapAndSource
>::const_iterator
147 FindMatchingBitmapAndSourceVector(
148 const std::vector
<BookmarkAppHelper::BitmapAndSource
>& bitmap_vector
,
150 for (std::vector
<BookmarkAppHelper::BitmapAndSource
>::const_iterator it
=
151 bitmap_vector
.begin();
152 it
!= bitmap_vector
.end(); ++it
) {
153 if (it
->bitmap
.width() == size
) {
157 return bitmap_vector
.end();
160 std::vector
<BookmarkAppHelper::BitmapAndSource
>::const_iterator
161 FindEqualOrLargerBitmapAndSourceVector(
162 const std::vector
<BookmarkAppHelper::BitmapAndSource
>& bitmap_vector
,
164 for (std::vector
<BookmarkAppHelper::BitmapAndSource
>::const_iterator it
=
165 bitmap_vector
.begin();
166 it
!= bitmap_vector
.end(); ++it
) {
167 if (it
->bitmap
.width() >= size
) {
171 return bitmap_vector
.end();
174 void ValidateWebApplicationInfo(base::Closure callback
,
175 const WebApplicationInfo
& original
,
176 const WebApplicationInfo
& newly_made
) {
177 EXPECT_EQ(original
.title
, newly_made
.title
);
178 EXPECT_EQ(original
.description
, newly_made
.description
);
179 EXPECT_EQ(original
.app_url
, newly_made
.app_url
);
180 // There should be 6 icons, as there are three sizes which need to be
181 // generated, and each will generate a 1x and 2x icon.
182 EXPECT_EQ(6u, newly_made
.icons
.size());
186 void ValidateIconsGeneratedAndResizedCorrectly(
187 std::vector
<BookmarkAppHelper::BitmapAndSource
> downloaded
,
188 std::map
<int, BookmarkAppHelper::BitmapAndSource
> size_map
,
189 std::set
<int> sizes_to_generate
,
190 int expected_generated
) {
192 int number_generated
= 0;
194 for (const auto& size
: sizes_to_generate
) {
195 auto icon_downloaded
= FindMatchingBitmapAndSourceVector(downloaded
, size
);
196 auto icon_larger
= FindEqualOrLargerBitmapAndSourceVector(downloaded
, size
);
197 if (icon_downloaded
== downloaded
.end()) {
198 auto icon_resized
= size_map
.find(size
);
199 if (icon_larger
== downloaded
.end()) {
200 // There is no larger downloaded icon. Expect an icon to be generated.
201 EXPECT_NE(icon_resized
, size_map
.end());
202 EXPECT_EQ(icon_resized
->second
.bitmap
.width(), size
);
203 EXPECT_EQ(icon_resized
->second
.bitmap
.height(), size
);
204 EXPECT_EQ(icon_resized
->second
.bitmap
.height(), size
);
205 EXPECT_EQ(icon_resized
->second
.source_url
, empty_url
);
208 // There is a larger downloaded icon. Expect the larger icon to be
209 // resized down to fit this size.
210 EXPECT_NE(icon_resized
, size_map
.end());
211 EXPECT_EQ(icon_resized
->second
.bitmap
.width(), size
);
212 EXPECT_EQ(icon_resized
->second
.bitmap
.height(), size
);
213 EXPECT_EQ(icon_resized
->second
.bitmap
.height(), size
);
214 EXPECT_EQ(icon_resized
->second
.source_url
, icon_larger
->source_url
);
217 // There is an icon of exactly this size downloaded. Expect no icon to be
218 // generated, and the existing downloaded icon to be used.
219 auto icon_resized
= size_map
.find(size
);
220 EXPECT_NE(icon_resized
, size_map
.end());
221 EXPECT_EQ(icon_resized
->second
.bitmap
.width(), size
);
222 EXPECT_EQ(icon_resized
->second
.bitmap
.height(), size
);
223 EXPECT_EQ(icon_downloaded
->bitmap
.width(), size
);
224 EXPECT_EQ(icon_downloaded
->bitmap
.height(), size
);
225 EXPECT_EQ(icon_resized
->second
.source_url
, icon_downloaded
->source_url
);
228 EXPECT_EQ(number_generated
, expected_generated
);
231 void TestIconGeneration(int icon_size
, int expected_generated
) {
232 std::vector
<BookmarkAppHelper::BitmapAndSource
> downloaded
;
234 // Add an icon with a URL and bitmap. 'Download' it.
235 WebApplicationInfo::IconInfo icon_info
=
236 CreateIconInfoWithBitmap(icon_size
, SK_ColorRED
);
237 icon_info
.url
= GURL(kAppIconURL1
);
238 downloaded
.push_back(BookmarkAppHelper::BitmapAndSource(
239 icon_info
.url
, icon_info
.data
));
241 // Now run the resizing/generation and validation.
242 WebApplicationInfo web_app_info
;
243 std::map
<int, BookmarkAppHelper::BitmapAndSource
> size_map
=
244 BookmarkAppHelper::ResizeIconsAndGenerateMissing(
245 downloaded
, TestSizesToGenerate(), &web_app_info
);
247 ValidateIconsGeneratedAndResizedCorrectly(downloaded
, size_map
,
248 TestSizesToGenerate(),
254 class TestBookmarkAppHelper
: public BookmarkAppHelper
{
256 TestBookmarkAppHelper(ExtensionService
* service
,
257 WebApplicationInfo web_app_info
,
258 content::WebContents
* contents
)
259 : BookmarkAppHelper(service
->profile(), web_app_info
, contents
) {}
261 ~TestBookmarkAppHelper() override
{}
263 void CreationComplete(const extensions::Extension
* extension
,
264 const WebApplicationInfo
& web_app_info
) {
265 extension_
= extension
;
268 void CompleteGetManifest(const content::Manifest
& manifest
) {
269 BookmarkAppHelper::OnDidGetManifest(manifest
);
272 void CompleteIconDownload(
274 const std::map
<GURL
, std::vector
<SkBitmap
> >& bitmaps
) {
275 BookmarkAppHelper::OnIconsDownloaded(success
, bitmaps
);
278 const Extension
* extension() { return extension_
; }
281 const Extension
* extension_
;
283 DISALLOW_COPY_AND_ASSIGN(TestBookmarkAppHelper
);
286 TEST_F(BookmarkAppHelperExtensionServiceTest
, CreateBookmarkApp
) {
287 WebApplicationInfo web_app_info
;
288 web_app_info
.app_url
= GURL(kAppUrl
);
289 web_app_info
.title
= base::UTF8ToUTF16(kAppTitle
);
290 web_app_info
.description
= base::UTF8ToUTF16(kAppDescription
);
292 content::TestWebContentsFactory web_contents_factory
;
293 content::WebContents
* contents
=
294 web_contents_factory
.CreateWebContents(profile());
295 TestBookmarkAppHelper
helper(service_
, web_app_info
, contents
);
296 helper
.Create(base::Bind(&TestBookmarkAppHelper::CreationComplete
,
297 base::Unretained(&helper
)));
299 std::map
<GURL
, std::vector
<SkBitmap
> > icon_map
;
300 icon_map
[GURL(kAppUrl
)].push_back(
301 CreateSquareBitmapWithColor(kIconSizeSmall
, SK_ColorRED
));
302 helper
.CompleteIconDownload(true, icon_map
);
304 base::RunLoop().RunUntilIdle();
305 EXPECT_TRUE(helper
.extension());
306 const Extension
* extension
=
307 service_
->GetInstalledExtension(helper
.extension()->id());
308 EXPECT_TRUE(extension
);
309 EXPECT_EQ(1u, registry()->enabled_extensions().size());
310 EXPECT_TRUE(extension
->from_bookmark());
311 EXPECT_EQ(kAppTitle
, extension
->name());
312 EXPECT_EQ(kAppDescription
, extension
->description());
313 EXPECT_EQ(GURL(kAppUrl
), AppLaunchInfo::GetLaunchWebURL(extension
));
315 IconsInfo::GetIconResource(
316 extension
, kIconSizeSmall
, ExtensionIconSet::MATCH_EXACTLY
).empty());
319 TEST_F(BookmarkAppHelperExtensionServiceTest
, CreateBookmarkAppWithManifest
) {
320 WebApplicationInfo web_app_info
;
322 content::TestWebContentsFactory web_contents_factory
;
323 content::WebContents
* contents
=
324 web_contents_factory
.CreateWebContents(profile());
325 TestBookmarkAppHelper
helper(service_
, web_app_info
, contents
);
326 helper
.Create(base::Bind(&TestBookmarkAppHelper::CreationComplete
,
327 base::Unretained(&helper
)));
329 content::Manifest manifest
;
330 manifest
.start_url
= GURL(kAppUrl
);
331 manifest
.name
= base::NullableString16(base::UTF8ToUTF16(kAppTitle
), false);
332 helper
.CompleteGetManifest(manifest
);
334 std::map
<GURL
, std::vector
<SkBitmap
> > icon_map
;
335 helper
.CompleteIconDownload(true, icon_map
);
337 base::RunLoop().RunUntilIdle();
338 EXPECT_TRUE(helper
.extension());
339 const Extension
* extension
=
340 service_
->GetInstalledExtension(helper
.extension()->id());
341 EXPECT_TRUE(extension
);
342 EXPECT_EQ(1u, registry()->enabled_extensions().size());
343 EXPECT_TRUE(extension
->from_bookmark());
344 EXPECT_EQ(kAppTitle
, extension
->name());
345 EXPECT_EQ(GURL(kAppUrl
), AppLaunchInfo::GetLaunchWebURL(extension
));
348 TEST_F(BookmarkAppHelperExtensionServiceTest
, CreateBookmarkAppNoContents
) {
349 WebApplicationInfo web_app_info
;
350 web_app_info
.app_url
= GURL(kAppUrl
);
351 web_app_info
.title
= base::UTF8ToUTF16(kAppTitle
);
352 web_app_info
.description
= base::UTF8ToUTF16(kAppDescription
);
353 web_app_info
.icons
.push_back(
354 CreateIconInfoWithBitmap(kIconSizeTiny
, SK_ColorRED
));
356 TestBookmarkAppHelper
helper(service_
, web_app_info
, NULL
);
357 helper
.Create(base::Bind(&TestBookmarkAppHelper::CreationComplete
,
358 base::Unretained(&helper
)));
360 base::RunLoop().RunUntilIdle();
361 EXPECT_TRUE(helper
.extension());
362 const Extension
* extension
=
363 service_
->GetInstalledExtension(helper
.extension()->id());
364 EXPECT_TRUE(extension
);
365 EXPECT_EQ(1u, registry()->enabled_extensions().size());
366 EXPECT_TRUE(extension
->from_bookmark());
367 EXPECT_EQ(kAppTitle
, extension
->name());
368 EXPECT_EQ(kAppDescription
, extension
->description());
369 EXPECT_EQ(GURL(kAppUrl
), AppLaunchInfo::GetLaunchWebURL(extension
));
371 IconsInfo::GetIconResource(extension
, kIconSizeTiny
,
372 ExtensionIconSet::MATCH_EXACTLY
).empty());
374 IconsInfo::GetIconResource(
375 extension
, kIconSizeSmall
, ExtensionIconSet::MATCH_EXACTLY
).empty());
377 IconsInfo::GetIconResource(extension
,
379 ExtensionIconSet::MATCH_EXACTLY
).empty());
381 IconsInfo::GetIconResource(
382 extension
, kIconSizeMedium
, ExtensionIconSet::MATCH_EXACTLY
).empty());
384 IconsInfo::GetIconResource(extension
,
386 ExtensionIconSet::MATCH_EXACTLY
).empty());
389 TEST_F(BookmarkAppHelperExtensionServiceTest
, CreateAndUpdateBookmarkApp
) {
390 EXPECT_EQ(0u, registry()->enabled_extensions().size());
391 WebApplicationInfo web_app_info
;
392 web_app_info
.app_url
= GURL(kAppUrl
);
393 web_app_info
.title
= base::UTF8ToUTF16(kAppTitle
);
394 web_app_info
.description
= base::UTF8ToUTF16(kAppDescription
);
395 web_app_info
.icons
.push_back(
396 CreateIconInfoWithBitmap(kIconSizeSmall
, SK_ColorRED
));
398 extensions::CreateOrUpdateBookmarkApp(service_
, &web_app_info
);
399 base::RunLoop().RunUntilIdle();
402 EXPECT_EQ(1u, registry()->enabled_extensions().size());
403 const Extension
* extension
=
404 registry()->enabled_extensions().begin()->get();
405 EXPECT_TRUE(extension
->from_bookmark());
406 EXPECT_EQ(kAppTitle
, extension
->name());
407 EXPECT_EQ(kAppDescription
, extension
->description());
408 EXPECT_EQ(GURL(kAppUrl
), AppLaunchInfo::GetLaunchWebURL(extension
));
409 EXPECT_FALSE(extensions::IconsInfo::GetIconResource(
410 extension
, kIconSizeSmall
, ExtensionIconSet::MATCH_EXACTLY
)
414 web_app_info
.title
= base::UTF8ToUTF16(kAlternativeAppTitle
);
415 web_app_info
.icons
[0] = CreateIconInfoWithBitmap(kIconSizeLarge
, SK_ColorRED
);
417 extensions::CreateOrUpdateBookmarkApp(service_
, &web_app_info
);
418 base::RunLoop().RunUntilIdle();
421 EXPECT_EQ(1u, registry()->enabled_extensions().size());
422 const Extension
* extension
=
423 registry()->enabled_extensions().begin()->get();
424 EXPECT_TRUE(extension
->from_bookmark());
425 EXPECT_EQ(kAlternativeAppTitle
, extension
->name());
426 EXPECT_EQ(kAppDescription
, extension
->description());
427 EXPECT_EQ(GURL(kAppUrl
), AppLaunchInfo::GetLaunchWebURL(extension
));
428 EXPECT_FALSE(extensions::IconsInfo::GetIconResource(
429 extension
, kIconSizeSmall
, ExtensionIconSet::MATCH_EXACTLY
)
431 EXPECT_FALSE(extensions::IconsInfo::GetIconResource(
432 extension
, kIconSizeLarge
, ExtensionIconSet::MATCH_EXACTLY
)
437 TEST_F(BookmarkAppHelperExtensionServiceTest
, GetWebApplicationInfo
) {
438 WebApplicationInfo web_app_info
;
439 web_app_info
.app_url
= GURL(kAppUrl
);
440 web_app_info
.title
= base::UTF8ToUTF16(kAppTitle
);
441 web_app_info
.description
= base::UTF8ToUTF16(kAppDescription
);
443 extensions::CreateOrUpdateBookmarkApp(service_
, &web_app_info
);
444 base::RunLoop().RunUntilIdle();
446 EXPECT_EQ(1u, registry()->enabled_extensions().size());
447 base::RunLoop run_loop
;
448 extensions::GetWebApplicationInfoFromApp(
449 profile_
.get(), registry()->enabled_extensions().begin()->get(),
450 base::Bind(&ValidateWebApplicationInfo
, run_loop
.QuitClosure(),
455 TEST_F(BookmarkAppHelperExtensionServiceTest
, LinkedAppIconsAreNotChanged
) {
456 WebApplicationInfo web_app_info
;
458 // Add two icons with a URL and bitmap, two icons with just a bitmap, an
459 // icon with just URL and an icon in an unsupported size with just a URL.
460 WebApplicationInfo::IconInfo icon_info
=
461 CreateIconInfoWithBitmap(kIconSizeSmall
, SK_ColorRED
);
462 icon_info
.url
= GURL(kAppIconURL1
);
463 web_app_info
.icons
.push_back(icon_info
);
465 icon_info
= CreateIconInfoWithBitmap(kIconSizeMedium
, SK_ColorRED
);
466 icon_info
.url
= GURL(kAppIconURL2
);
467 web_app_info
.icons
.push_back(icon_info
);
469 icon_info
.data
= SkBitmap();
470 icon_info
.url
= GURL(kAppIconURL3
);
472 icon_info
.height
= 0;
473 web_app_info
.icons
.push_back(icon_info
);
475 icon_info
.url
= GURL(kAppIconURL4
);
476 web_app_info
.icons
.push_back(icon_info
);
478 icon_info
= CreateIconInfoWithBitmap(kIconSizeLarge
, SK_ColorRED
);
479 web_app_info
.icons
.push_back(icon_info
);
481 icon_info
= CreateIconInfoWithBitmap(kIconSizeUnsupported
, SK_ColorRED
);
482 web_app_info
.icons
.push_back(icon_info
);
484 // 'Download' one of the icons without a size or bitmap.
485 std::vector
<BookmarkAppHelper::BitmapAndSource
> downloaded
;
486 downloaded
.push_back(BookmarkAppHelper::BitmapAndSource(
488 CreateSquareBitmapWithColor(kIconSizeLarge
, SK_ColorBLACK
)));
490 // Now run the resizing and generation into a new web app info.
491 WebApplicationInfo new_web_app_info
;
492 std::map
<int, BookmarkAppHelper::BitmapAndSource
> size_map
=
493 BookmarkAppHelper::ResizeIconsAndGenerateMissing(
494 downloaded
, TestSizesToGenerate(), &new_web_app_info
);
496 // Now check that the linked app icons (i.e. those with URLs) are matching in
498 ValidateAllIconsWithURLsArePresent(web_app_info
, new_web_app_info
);
499 ValidateAllIconsWithURLsArePresent(new_web_app_info
, web_app_info
);
502 TEST_F(BookmarkAppHelperTest
, UpdateWebAppInfoFromManifest
) {
503 WebApplicationInfo web_app_info
;
504 web_app_info
.title
= base::UTF8ToUTF16(kAlternativeAppTitle
);
505 web_app_info
.app_url
= GURL(kAlternativeAppUrl
);
506 WebApplicationInfo::IconInfo info
;
507 info
.url
= GURL(kAppIcon1
);
508 web_app_info
.icons
.push_back(info
);
510 content::Manifest manifest
;
511 manifest
.start_url
= GURL(kAppUrl
);
512 manifest
.short_name
= base::NullableString16(base::UTF8ToUTF16(kAppShortName
),
515 BookmarkAppHelper::UpdateWebAppInfoFromManifest(manifest
, &web_app_info
);
516 EXPECT_EQ(base::UTF8ToUTF16(kAppShortName
), web_app_info
.title
);
517 EXPECT_EQ(GURL(kAppUrl
), web_app_info
.app_url
);
519 // The icon info from |web_app_info| should be left as is, since the manifest
520 // doesn't have any icon information.
521 EXPECT_EQ(1u, web_app_info
.icons
.size());
522 EXPECT_EQ(GURL(kAppIcon1
), web_app_info
.icons
[0].url
);
524 // Test that |manifest.name| takes priority over |manifest.short_name|, and
525 // that icons provided by the manifest replace icons in |web_app_info|.
526 manifest
.name
= base::NullableString16(base::UTF8ToUTF16(kAppTitle
), false);
528 content::Manifest::Icon icon
;
529 icon
.src
= GURL(kAppIcon2
);
530 manifest
.icons
.push_back(icon
);
531 icon
.src
= GURL(kAppIcon3
);
532 manifest
.icons
.push_back(icon
);
534 BookmarkAppHelper::UpdateWebAppInfoFromManifest(manifest
, &web_app_info
);
535 EXPECT_EQ(base::UTF8ToUTF16(kAppTitle
), web_app_info
.title
);
537 EXPECT_EQ(2u, web_app_info
.icons
.size());
538 EXPECT_EQ(GURL(kAppIcon2
), web_app_info
.icons
[0].url
);
539 EXPECT_EQ(GURL(kAppIcon3
), web_app_info
.icons
[1].url
);
542 TEST_F(BookmarkAppHelperTest
, ConstrainBitmapsToSizes
) {
543 std::set
<int> desired_sizes
;
544 desired_sizes
.insert(16);
545 desired_sizes
.insert(32);
546 desired_sizes
.insert(48);
547 desired_sizes
.insert(96);
548 desired_sizes
.insert(128);
549 desired_sizes
.insert(256);
552 std::vector
<BookmarkAppHelper::BitmapAndSource
> bitmaps
;
553 bitmaps
.push_back(CreateSquareBitmapAndSourceWithColor(16, SK_ColorRED
));
554 bitmaps
.push_back(CreateSquareBitmapAndSourceWithColor(32, SK_ColorGREEN
));
556 CreateSquareBitmapAndSourceWithColor(144, SK_ColorYELLOW
));
558 std::map
<int, BookmarkAppHelper::BitmapAndSource
> results(
559 BookmarkAppHelper::ConstrainBitmapsToSizes(bitmaps
, desired_sizes
));
561 EXPECT_EQ(5u, results
.size());
562 ValidateBitmapSizeAndColor(results
[16].bitmap
, 16, SK_ColorRED
);
563 ValidateBitmapSizeAndColor(results
[32].bitmap
, 32, SK_ColorGREEN
);
564 ValidateBitmapSizeAndColor(results
[48].bitmap
, 48, SK_ColorYELLOW
);
565 ValidateBitmapSizeAndColor(results
[96].bitmap
, 96, SK_ColorYELLOW
);
566 ValidateBitmapSizeAndColor(results
[128].bitmap
, 128, SK_ColorYELLOW
);
569 std::vector
<BookmarkAppHelper::BitmapAndSource
> bitmaps
;
570 bitmaps
.push_back(CreateSquareBitmapAndSourceWithColor(512, SK_ColorRED
));
571 bitmaps
.push_back(CreateSquareBitmapAndSourceWithColor(18, SK_ColorGREEN
));
572 bitmaps
.push_back(CreateSquareBitmapAndSourceWithColor(33, SK_ColorBLUE
));
573 bitmaps
.push_back(CreateSquareBitmapAndSourceWithColor(17, SK_ColorYELLOW
));
575 std::map
<int, BookmarkAppHelper::BitmapAndSource
> results(
576 BookmarkAppHelper::ConstrainBitmapsToSizes(bitmaps
, desired_sizes
));
578 EXPECT_EQ(6u, results
.size());
579 ValidateBitmapSizeAndColor(results
[16].bitmap
, 16, SK_ColorYELLOW
);
580 ValidateBitmapSizeAndColor(results
[32].bitmap
, 32, SK_ColorBLUE
);
581 ValidateBitmapSizeAndColor(results
[48].bitmap
, 48, SK_ColorRED
);
582 ValidateBitmapSizeAndColor(results
[96].bitmap
, 96, SK_ColorRED
);
583 ValidateBitmapSizeAndColor(results
[128].bitmap
, 128, SK_ColorRED
);
584 ValidateBitmapSizeAndColor(results
[256].bitmap
, 256, SK_ColorRED
);
588 TEST_F(BookmarkAppHelperTest
, IsValidBookmarkAppUrl
) {
589 EXPECT_TRUE(IsValidBookmarkAppUrl(GURL("https://chromium.org")));
590 EXPECT_TRUE(IsValidBookmarkAppUrl(GURL("https://www.chromium.org")));
591 EXPECT_TRUE(IsValidBookmarkAppUrl(
592 GURL("https://www.chromium.org/path/to/page.html")));
593 EXPECT_TRUE(IsValidBookmarkAppUrl(GURL("http://chromium.org")));
594 EXPECT_TRUE(IsValidBookmarkAppUrl(GURL("http://www.chromium.org")));
596 IsValidBookmarkAppUrl(GURL("http://www.chromium.org/path/to/page.html")));
597 EXPECT_TRUE(IsValidBookmarkAppUrl(
598 GURL("chrome-extension://oafaagfgbdpldilgjjfjocjglfbolmac")));
600 EXPECT_FALSE(IsValidBookmarkAppUrl(GURL("ftp://www.chromium.org")));
601 EXPECT_FALSE(IsValidBookmarkAppUrl(GURL("chrome://flags")));
602 EXPECT_FALSE(IsValidBookmarkAppUrl(GURL("about:blank")));
603 EXPECT_FALSE(IsValidBookmarkAppUrl(
604 GURL("file://mhjfbmdgcfjbbpaeojofohoefgiehjai")));
605 EXPECT_FALSE(IsValidBookmarkAppUrl(GURL("chrome://extensions")));
608 TEST_F(BookmarkAppHelperTest
, IconsGeneratedOnlyWhenNoneLarger
) {
609 std::vector
<BookmarkAppHelper::BitmapAndSource
> downloaded
;
611 // Add three icons with a URL and bitmap. 'Download' each of them.
612 WebApplicationInfo::IconInfo icon_info
=
613 CreateIconInfoWithBitmap(kIconSizeSmall
, SK_ColorRED
);
614 icon_info
.url
= GURL(kAppIconURL1
);
615 downloaded
.push_back(BookmarkAppHelper::BitmapAndSource(
616 icon_info
.url
, icon_info
.data
));
618 icon_info
= CreateIconInfoWithBitmap(kIconSizeSmallBetweenMediumAndLarge
,
620 icon_info
.url
= GURL(kAppIconURL2
);
621 downloaded
.push_back(BookmarkAppHelper::BitmapAndSource(
622 icon_info
.url
, icon_info
.data
));
624 icon_info
= CreateIconInfoWithBitmap(kIconSizeLargeBetweenMediumAndLarge
,
626 icon_info
.url
= GURL(kAppIconURL3
);
627 downloaded
.push_back(BookmarkAppHelper::BitmapAndSource(
628 icon_info
.url
, icon_info
.data
));
630 // Now run the resizing and generation.
631 WebApplicationInfo web_app_info
;
632 std::map
<int, BookmarkAppHelper::BitmapAndSource
> size_map
=
633 BookmarkAppHelper::ResizeIconsAndGenerateMissing(
634 downloaded
, TestSizesToGenerate(), &web_app_info
);
636 // The largest icon downloaded is smaller than EXTENSION_ICON_LARGE, so one
637 // icon should be generated.
638 ValidateIconsGeneratedAndResizedCorrectly(
639 downloaded
, size_map
, TestSizesToGenerate(), 1);
642 TEST_F(BookmarkAppHelperTest
, IconsGeneratedWhenNotDownloaded
) {
643 std::vector
<BookmarkAppHelper::BitmapAndSource
> downloaded
;
645 // Add three icons with a URL and bitmap. 'Download' two of them and pretend
646 // the third failed to download.
647 WebApplicationInfo::IconInfo icon_info
=
648 CreateIconInfoWithBitmap(kIconSizeSmall
, SK_ColorRED
);
649 icon_info
.url
= GURL(kAppIconURL1
);
650 downloaded
.push_back(BookmarkAppHelper::BitmapAndSource(
651 icon_info
.url
, icon_info
.data
));
653 icon_info
= CreateIconInfoWithBitmap(kIconSizeLarge
, SK_ColorBLUE
);
654 icon_info
.url
= GURL(kAppIconURL2
);
656 icon_info
= CreateIconInfoWithBitmap(kIconSizeGigantor
, SK_ColorBLACK
);
657 icon_info
.url
= GURL(kAppIconURL3
);
658 downloaded
.push_back(BookmarkAppHelper::BitmapAndSource(
659 icon_info
.url
, icon_info
.data
));
661 // Now run the resizing and generation.
662 WebApplicationInfo web_app_info
;
663 std::map
<int, BookmarkAppHelper::BitmapAndSource
> size_map
=
664 BookmarkAppHelper::ResizeIconsAndGenerateMissing(
665 downloaded
, TestSizesToGenerate(), &web_app_info
);
667 // Expect icon for EXTENSION_ICON_LARGE to be resized from the gigantor icon
668 // as it was not downloaded.
669 ValidateIconsGeneratedAndResizedCorrectly(
670 downloaded
, size_map
, TestSizesToGenerate(), 0);
672 // Verify specifically that the EXTENSION_ICON_LARGE icon was resized.
673 const auto it
= size_map
.find(kIconSizeLarge
);
674 EXPECT_NE(it
, size_map
.end());
675 EXPECT_EQ(it
->second
.source_url
, GURL(kAppIconURL3
));
678 TEST_F(BookmarkAppHelperTest
, AllIconsGeneratedWhenNotDownloaded
) {
679 std::vector
<BookmarkAppHelper::BitmapAndSource
> downloaded
;
681 // Add three icons with a URL and bitmap. 'Download' none of them.
682 WebApplicationInfo::IconInfo icon_info
=
683 CreateIconInfoWithBitmap(kIconSizeSmall
, SK_ColorRED
);
684 icon_info
.url
= GURL(kAppIconURL1
);
686 icon_info
= CreateIconInfoWithBitmap(kIconSizeLarge
, SK_ColorBLUE
);
687 icon_info
.url
= GURL(kAppIconURL2
);
689 icon_info
= CreateIconInfoWithBitmap(kIconSizeGigantor
, SK_ColorBLACK
);
690 icon_info
.url
= GURL(kAppIconURL3
);
692 // Now run the resizing and generation.
693 WebApplicationInfo web_app_info
;
694 std::map
<int, BookmarkAppHelper::BitmapAndSource
> size_map
=
695 BookmarkAppHelper::ResizeIconsAndGenerateMissing(
696 downloaded
, TestSizesToGenerate(), &web_app_info
);
698 // Expect all icons to be generated.
699 ValidateIconsGeneratedAndResizedCorrectly(
700 downloaded
, size_map
, TestSizesToGenerate(), 3);
704 TEST_F(BookmarkAppHelperTest
, LargeIconGeneratedWhenNotDownloaded
) {
705 std::vector
<BookmarkAppHelper::BitmapAndSource
> downloaded
;
707 // Pretend the huge icon wasn't downloaded but two smaller ones were.
708 WebApplicationInfo::IconInfo icon_info
=
709 CreateIconInfoWithBitmap(kIconSizeTiny
, SK_ColorRED
);
710 icon_info
.url
= GURL(kAppIconURL1
);
711 downloaded
.push_back(BookmarkAppHelper::BitmapAndSource(
712 icon_info
.url
, icon_info
.data
));
714 icon_info
= CreateIconInfoWithBitmap(kIconSizeMedium
, SK_ColorBLUE
);
715 icon_info
.url
= GURL(kAppIconURL2
);
716 downloaded
.push_back(BookmarkAppHelper::BitmapAndSource(
717 icon_info
.url
, icon_info
.data
));
719 icon_info
= CreateIconInfoWithBitmap(kIconSizeGigantor
, SK_ColorBLACK
);
720 icon_info
.url
= GURL(kAppIconURL3
);
722 // Now run the resizing and generation.
723 WebApplicationInfo web_app_info
;
724 std::map
<int, BookmarkAppHelper::BitmapAndSource
> size_map
=
725 BookmarkAppHelper::ResizeIconsAndGenerateMissing(
726 downloaded
, TestSizesToGenerate(), &web_app_info
);
728 // Expect icon for EXTENSION_ICON_LARGE to be generated as the gigantor icon
729 // was not downloaded.
730 ValidateIconsGeneratedAndResizedCorrectly(
731 downloaded
, size_map
, TestSizesToGenerate(), 1);
733 // Verify specifically that the LARGE icons was generated.
734 const auto it
= size_map
.find(kIconSizeLarge
);
735 EXPECT_NE(it
, size_map
.end());
736 EXPECT_EQ(it
->second
.source_url
, GURL());
739 TEST_F(BookmarkAppHelperTest
, AllIconsGeneratedWhenOnlyASmallOneIsProvided
) {
740 // When only a tiny icon is downloaded (smaller than the three desired
741 // sizes), 3 icons should be generated.
742 TestIconGeneration(kIconSizeTiny
, 3);
745 TEST_F(BookmarkAppHelperTest
, NoIconsGeneratedWhenAVeryLargeOneIsProvided
) {
746 // When an enormous icon is provided, each desired icon size should fall back
747 // to it, and no icons should be generated.
748 TestIconGeneration(kIconSizeGigantor
, 0);
751 } // namespace extensions