#include <string>
#include <vector>
#include "base/barrier_callback.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/run_loop.h"
#include "base/test/test_future.h"
#include "chrome/browser/apps/app_service/app_icon/app_icon_factory.h"
#include "chrome/browser/apps/app_service/app_icon/app_icon_test_util.h"
#include "chrome/browser/apps/icon_standardizer.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_service_test_base.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_constants.h"
#include "components/services/app_service/public/cpp/icon_types.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/image_loader.h"
#include "extensions/common/manifest_handlers/icons_handler.h"
#include "services/data_decoder/public/cpp/test_support/in_process_data_decoder.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/codec/png_codec.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/image/image_skia_operations.h"
#include "ui/gfx/image/image_skia_rep.h"
#include "ui/gfx/image/image_unittest_util.h"
#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "chrome/browser/apps/app_service/app_icon/app_icon_decoder.h"
#include "chrome/browser/apps/app_service/app_service_proxy.h"
#include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
#endif
namespace apps {
const char kPackagedApp1Id[] = …;
class ChromeAppsIconFactoryTest : public extensions::ExtensionServiceTestBase { … };
TEST_F(ChromeAppsIconFactoryTest, LoadUncompressedIcon) { … }
TEST_F(ChromeAppsIconFactoryTest, LoadStandardIcon) { … }
TEST_F(ChromeAppsIconFactoryTest, LoadCompressedIcon) { … }
TEST_F(ChromeAppsIconFactoryTest, LoadCompressedIconWithoutEffect) { … }
#if BUILDFLAG(IS_CHROMEOS_ASH)
TEST_F(ChromeAppsIconFactoryTest, GetCompressedIconData) {
std::vector<uint8_t> src_data1;
std::vector<uint8_t> src_data2;
GenerateExtensionAppCompressedIcon(kPackagedApp1Id, 1.0, src_data1,
true);
GenerateExtensionAppCompressedIcon(kPackagedApp1Id, 2.0, src_data2,
true);
IconValuePtr icon1 = GetCompressedIconData(
kPackagedApp1Id, ui::ResourceScaleFactor::k100Percent);
IconValuePtr icon2 = GetCompressedIconData(
kPackagedApp1Id, ui::ResourceScaleFactor::k200Percent);
VerifyCompressedIcon(src_data1, *icon1);
VerifyCompressedIcon(src_data2, *icon2);
}
class AppServiceChromeAppIconTest : public ChromeAppsIconFactoryTest {
public:
void SetUp() override {
ChromeAppsIconFactoryTest::SetUp();
proxy_ = AppServiceProxyFactory::GetForProfile(profile());
fake_icon_loader_ = std::make_unique<apps::FakeIconLoader>(proxy_);
OverrideAppServiceProxyInnerIconLoader(fake_icon_loader_.get());
}
void OverrideAppServiceProxyInnerIconLoader(apps::IconLoader* icon_loader) {
app_service_proxy().OverrideInnerIconLoaderForTesting(icon_loader);
}
apps::IconValuePtr LoadIcon(const std::string& app_id, IconType icon_type) {
base::test::TestFuture<apps::IconValuePtr> result;
app_service_proxy().LoadIcon(app_id, icon_type, kSizeInDip,
false,
result.GetCallback());
return result.Take();
}
apps::IconValuePtr LoadIconWithIconEffects(const std::string& app_id,
uint32_t icon_effects,
IconType icon_type) {
base::test::TestFuture<apps::IconValuePtr> result;
app_service_proxy().LoadIconWithIconEffects(
app_id, icon_effects, icon_type, kSizeInDip,
false, result.GetCallback());
return result.Take();
}
std::vector<apps::IconValuePtr> MultipleLoadIconWithIconEffects(
const std::string& app_id,
uint32_t icon_effects,
IconType icon_type) {
base::test::TestFuture<std::vector<apps::IconValuePtr>> result;
auto barrier_callback =
base::BarrierCallback<apps::IconValuePtr>(2, result.GetCallback());
app_service_proxy().LoadIconWithIconEffects(
app_id, icon_effects, icon_type, kSizeInDip,
false, barrier_callback);
app_service_proxy().LoadIconWithIconEffects(
app_id, icon_effects, icon_type, kSizeInDip,
false, barrier_callback);
return result.Take();
}
AppServiceProxy& app_service_proxy() { return *proxy_; }
private:
raw_ptr<AppServiceProxy> proxy_;
std::unique_ptr<apps::FakeIconLoader> fake_icon_loader_;
data_decoder::test::InProcessDataDecoder in_process_data_decoder_;
};
TEST_F(AppServiceChromeAppIconTest, GetCompressedIconDataForCompressedIcon) {
std::vector<uint8_t> src_data;
GenerateExtensionAppCompressedIcon(kPackagedApp1Id, 1.0, src_data,
true);
VerifyCompressedIcon(src_data,
*LoadIcon(kPackagedApp1Id, IconType::kCompressed));
}
TEST_F(AppServiceChromeAppIconTest, GetCompressedIconDataForStandardIcon) {
gfx::ImageSkia src_image_skia;
GenerateExtensionAppIcon(kPackagedApp1Id, src_image_skia);
auto ret = MultipleLoadIconWithIconEffects(
kPackagedApp1Id, IconEffects::kCrOsStandardIcon, IconType::kStandard);
ASSERT_EQ(2U, ret.size());
ASSERT_EQ(apps::IconType::kStandard, ret[0]->icon_type);
VerifyIcon(src_image_skia, ret[0]->uncompressed);
ASSERT_EQ(apps::IconType::kStandard, ret[1]->icon_type);
VerifyIcon(src_image_skia, ret[1]->uncompressed);
}
TEST_F(AppServiceChromeAppIconTest, GetCompressedIconDataForUncompressedIcon) {
gfx::ImageSkia src_image_skia;
GenerateExtensionAppIcon(kPackagedApp1Id, src_image_skia,
true);
auto ret = LoadIconWithIconEffects(kPackagedApp1Id, IconEffects::kNone,
IconType::kUncompressed);
ASSERT_EQ(apps::IconType::kUncompressed, ret->icon_type);
VerifyIcon(src_image_skia, ret->uncompressed);
}
#endif
}