#include "chrome/browser/web_applications/web_app_icon_manager.h"
#include <algorithm>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include "base/containers/contains.h"
#include "base/files/file_enumerator.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/scoped_refptr.h"
#include "base/run_loop.h"
#include "base/test/bind.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/test_future.h"
#include "base/time/time.h"
#include "chrome/browser/web_applications/test/fake_web_app_database_factory.h"
#include "chrome/browser/web_applications/test/fake_web_app_provider.h"
#include "chrome/browser/web_applications/test/test_file_utils.h"
#include "chrome/browser/web_applications/test/web_app_icon_test_utils.h"
#include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
#include "chrome/browser/web_applications/test/web_app_test.h"
#include "chrome/browser/web_applications/test/web_app_test_utils.h"
#include "chrome/browser/web_applications/web_app.h"
#include "chrome/browser/web_applications/web_app_constants.h"
#include "chrome/browser/web_applications/web_app_helpers.h"
#include "chrome/browser/web_applications/web_app_icon_generator.h"
#include "chrome/browser/web_applications/web_app_install_info.h"
#include "chrome/browser/web_applications/web_app_install_manager.h"
#include "chrome/browser/web_applications/web_app_registrar.h"
#include "chrome/browser/web_applications/web_app_registry_update.h"
#include "chrome/browser/web_applications/web_app_sync_bridge.h"
#include "chrome/browser/web_applications/web_app_utils.h"
#include "chrome/common/chrome_features.h"
#include "chrome/test/base/testing_profile.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/base/resource/resource_scale_factor.h"
#include "ui/gfx/favicon_size.h"
namespace web_app {
namespace {
IconSizeAndPurpose;
const int kMinimumHomeTabIconSizeInPx = …;
std::vector<WebAppShortcutsMenuItemInfo> CreateShortcutsMenuItemInfos(
int num_menu_items,
const IconSizes& icon_sizes) { … }
}
class WebAppIconManagerTest : public WebAppTest { … };
TEST_F(WebAppIconManagerTest, WriteAndReadIcons_AnyOnly) { … }
TEST_F(WebAppIconManagerTest, WriteAndReadIcons_MaskableOnly) { … }
TEST_F(WebAppIconManagerTest, WriteAndReadIcons_MonochromeOnly) { … }
TEST_F(WebAppIconManagerTest, WriteAndReadIcons_AnyAndMaskable) { … }
TEST_F(WebAppIconManagerTest, WriteAndReadIcons_AnyAndMonochrome) { … }
TEST_F(WebAppIconManagerTest, OverwriteIcons) { … }
TEST_F(WebAppIconManagerTest, ReadAllIcons_AnyOnly) { … }
TEST_F(WebAppIconManagerTest, ReadAllIconsLastUpdateTime) { … }
TEST_F(WebAppIconManagerTest, ReadAllShortcutMenuIconsWithTimestamp) { … }
TEST_F(WebAppIconManagerTest, NoHomeTabIcons) { … }
TEST_F(WebAppIconManagerTest, ReadAllIcons_AnyAndMaskable) { … }
TEST_F(WebAppIconManagerTest, ReadShortcutsMenuIconsFailed) { … }
TEST_F(WebAppIconManagerTest, WriteAndReadAllShortcutsMenuIcons) { … }
TEST_F(WebAppIconManagerTest, WriteNonProductIconsEmptyMaps) { … }
TEST_F(WebAppIconManagerTest, WriteOtherIconsToDisk) { … }
TEST_F(WebAppIconManagerTest, ReadIconsFailed) { … }
TEST_F(WebAppIconManagerTest, FindExact) { … }
bool operator==(const IconSizeAndPurpose& a, const IconSizeAndPurpose& b) { … }
TEST_F(WebAppIconManagerTest, FindSmallest) { … }
TEST_F(WebAppIconManagerTest, DeleteData_Success) { … }
TEST_F(WebAppIconManagerTest, DeleteData_Failure) { … }
TEST_F(WebAppIconManagerTest, ReadSmallestCompressedIcon_Success_AnyOnly) { … }
TEST_F(WebAppIconManagerTest, ReadSmallestCompressedIcon_Success) { … }
TEST_F(WebAppIconManagerTest, ReadSmallestCompressedIcon_Failure) { … }
TEST_F(WebAppIconManagerTest, ReadIconAndResize_Success_AnyOnly) { … }
TEST_F(WebAppIconManagerTest, ReadIconAndResize_Success_AnyAndMaskable) { … }
TEST_F(WebAppIconManagerTest, ReadIconAndResize_Failure) { … }
TEST_F(WebAppIconManagerTest, CacheExistingAppFavicon) { … }
TEST_F(WebAppIconManagerTest, CacheAppFaviconWithResize) { … }
TEST_F(WebAppIconManagerTest, CacheNewAppFavicon) { … }
TEST_F(WebAppIconManagerTest, CacheAppFavicon_UiScaleFactors_NoMissingIcons) { … }
TEST_F(WebAppIconManagerTest, CacheAppFavicon_UiScaleFactors_DownsizingIcons) { … }
TEST_F(WebAppIconManagerTest, CacheAppFavicon_UiScaleFactors_NoIcons) { … }
TEST_F(WebAppIconManagerTest, CacheAppFavicon_UiScaleFactors_NoMatchSmaller) { … }
TEST_F(WebAppIconManagerTest,
CacheAppFavicon_UiScaleFactors_DownsizingFromSingleIcon) { … }
TEST_F(WebAppIconManagerTest,
CacheAppFavicon_UiScaleFactors_BiggerUiScaleFactorIconMissing) { … }
#if BUILDFLAG(IS_CHROMEOS)
using WebAppIconManagerTest_NotificationIconAndTitle = WebAppIconManagerTest;
TEST_F(WebAppIconManagerTest_NotificationIconAndTitle,
DISABLED_CacheAppMonochromeFavicon_NoMissingIcons) {
std::unique_ptr<WebApp> web_app = test::CreateWebApp();
web_app->SetThemeColor(std::make_optional(SK_ColorBLUE));
const webapps::AppId app_id = web_app->app_id();
const std::vector<int> sizes_px{icon_size::k16, icon_size::k32,
icon_size::k64};
ASSERT_TRUE(base::Contains(sizes_px, gfx::kFaviconSize));
const std::vector<SkColor> colors{SK_ColorYELLOW, SK_ColorTRANSPARENT,
SK_ColorRED};
IconManagerWriteGeneratedIcons(icon_manager(), app_id,
{{IconPurpose::MONOCHROME, sizes_px, colors}});
web_app->SetDownloadedIconSizes(IconPurpose::MONOCHROME, sizes_px);
AwaitReadFaviconMonochromeOnAddingWebApp(std::move(web_app));
gfx::ImageSkia monochrome_image = icon_manager().GetMonochromeFavicon(app_id);
ASSERT_FALSE(monochrome_image.isNull());
EXPECT_EQ(gfx::kFaviconSize, monochrome_image.width());
EXPECT_EQ(gfx::kFaviconSize, monochrome_image.height());
{
SCOPED_TRACE(icon_size::k16);
ExpectImageSkiaRep(monochrome_image, 1.0f,
icon_size::k16, SK_ColorBLUE);
}
{
SCOPED_TRACE(icon_size::k32);
ExpectImageSkiaRep(monochrome_image, 2.0f,
icon_size::k32, SK_ColorTRANSPARENT);
}
{
SCOPED_TRACE(icon_size::k64);
ExpectImageSkiaRep(monochrome_image, 4.0f,
icon_size::k64, SK_ColorBLUE);
}
}
TEST_F(WebAppIconManagerTest_NotificationIconAndTitle,
CacheAppMonochromeFavicon_CacheAfterAppInstall) {
std::unique_ptr<WebApp> web_app = test::CreateWebApp();
web_app->SetThemeColor(std::make_optional(SK_ColorGREEN));
const webapps::AppId app_id = web_app->app_id();
const std::vector<int> sizes_px{icon_size::k512};
const std::vector<SkColor> colors{SK_ColorRED};
IconManagerWriteGeneratedIcons(icon_manager(), app_id,
{{IconPurpose::MONOCHROME, sizes_px, colors}});
web_app->SetDownloadedIconSizes(IconPurpose::MONOCHROME, sizes_px);
AwaitReadFaviconMonochromeOnAddingWebApp(std::move(web_app));
gfx::ImageSkia monochrome_image = icon_manager().GetMonochromeFavicon(app_id);
ASSERT_FALSE(monochrome_image.isNull());
EXPECT_EQ(gfx::kFaviconSize, monochrome_image.width());
EXPECT_EQ(gfx::kFaviconSize, monochrome_image.height());
{
SCOPED_TRACE(icon_size::k16);
ExpectImageSkiaRep(monochrome_image, 1.0f,
icon_size::k16, SK_ColorGREEN);
}
{
SCOPED_TRACE(icon_size::k64);
ExpectImageSkiaRep(monochrome_image, 4.0f,
icon_size::k64, SK_ColorGREEN);
}
EXPECT_FALSE(monochrome_image.HasRepresentation(2.0f));
EXPECT_FALSE(monochrome_image.HasRepresentation(3.0f));
EXPECT_FALSE(monochrome_image.HasRepresentation(32.0f));
}
TEST_F(WebAppIconManagerTest_NotificationIconAndTitle,
CacheAppMonochromeFavicon_NoThemeColor) {
std::unique_ptr<WebApp> web_app = test::CreateWebApp();
web_app->SetThemeColor(std::nullopt);
const webapps::AppId app_id = web_app->app_id();
const std::vector<int> sizes_px{icon_size::k32};
const std::vector<SkColor> colors{SK_ColorRED};
IconManagerWriteGeneratedIcons(icon_manager(), app_id,
{{IconPurpose::MONOCHROME, sizes_px, colors}});
web_app->SetDownloadedIconSizes(IconPurpose::MONOCHROME, sizes_px);
AwaitReadFaviconMonochromeOnAddingWebApp(std::move(web_app));
gfx::ImageSkia monochrome_image = icon_manager().GetMonochromeFavicon(app_id);
ASSERT_FALSE(monochrome_image.isNull());
EXPECT_EQ(gfx::kFaviconSize, monochrome_image.width());
EXPECT_EQ(gfx::kFaviconSize, monochrome_image.height());
{
SCOPED_TRACE(icon_size::k16);
ExpectImageSkiaRep(monochrome_image, 1.0f,
icon_size::k16, SK_ColorDKGRAY);
}
{
SCOPED_TRACE(icon_size::k32);
ExpectImageSkiaRep(monochrome_image, 2.0f,
icon_size::k32, SK_ColorDKGRAY);
}
EXPECT_FALSE(monochrome_image.HasRepresentation(3.0));
}
TEST_F(WebAppIconManagerTest_NotificationIconAndTitle,
CacheAppMonochromeFavicon_NoIcons) {
std::unique_ptr<WebApp> web_app = test::CreateWebApp();
const webapps::AppId app_id = web_app->app_id();
AwaitReadFaviconMonochromeOnAddingWebApp(std::move(web_app));
gfx::ImageSkia monochrome_image = icon_manager().GetMonochromeFavicon(app_id);
EXPECT_TRUE(monochrome_image.isNull());
}
#endif
}