Commit f0e79eb5 authored by nancylingwang@google.com's avatar nancylingwang@google.com Committed by Commit Bot

Modify ArcAppIcon to fetch two layer icons.

This is the preparing for the adaptive icon feature. For kUncompressed
and kCompressed, no change, just refactor.

Add a new type kAdaptive for ArcAppIcon to fetch both the foreground and
background image, which will be used for adaptive icons. Currently no
one uses the new type yet. There will be some follow up CLs to change
other code to use the new type kAdaptive, hidden with the flag for M85.

BUG=1083331

Change-Id: I0c078d6d9c821aa810c849bda04875a4a3155a60
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2249201
Commit-Queue: Nancy Wang <nancylingwang@chromium.org>
Reviewed-by: default avatarLong Cheng <lgcheng@google.com>
Reviewed-by: default avatarDominick Ng <dominickn@chromium.org>
Cr-Commit-Position: refs/heads/master@{#781210}
parent 483bd143
......@@ -19,6 +19,7 @@
#include "base/task/post_task.h"
#include "base/task/thread_pool.h"
#include "chrome/browser/image_decoder/image_decoder.h"
#include "chrome/browser/ui/app_list/arc/arc_app_icon_descriptor.h"
#include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h"
#include "chrome/browser/ui/app_list/arc/arc_app_utils.h"
#include "chrome/browser/ui/ash/launcher/arc_app_shelf_id.h"
......@@ -45,18 +46,18 @@ struct ArcAppIcon::ReadResult {
bool request_to_install,
ui::ScaleFactor scale_factor,
bool resize_allowed,
std::string unsafe_icon_data)
std::vector<std::string> unsafe_icon_data)
: error(error),
request_to_install(request_to_install),
scale_factor(scale_factor),
resize_allowed(resize_allowed),
unsafe_icon_data(unsafe_icon_data) {}
unsafe_icon_data(std::move(unsafe_icon_data)) {}
const bool error;
const bool request_to_install;
const ui::ScaleFactor scale_factor;
const bool resize_allowed;
const std::string unsafe_icon_data;
const std::vector<std::string> unsafe_icon_data;
};
////////////////////////////////////////////////////////////////////////////////
......@@ -141,9 +142,12 @@ gfx::ImageSkiaRep ArcAppIcon::Source::GetImageForScale(float scale) {
class ArcAppIcon::DecodeRequest : public ImageDecoder::ImageRequest {
public:
DecodeRequest(const base::WeakPtr<ArcAppIcon>& host,
const ArcAppIconDescriptor& descriptor,
bool resize_allowed);
DecodeRequest(
ArcAppIcon& host,
const ArcAppIconDescriptor& descriptor,
bool resize_allowed,
gfx::ImageSkia& image_skia,
std::map<ui::ScaleFactor, base::Time>& incomplete_scale_factors);
~DecodeRequest() override;
// ImageDecoder::ImageRequest
......@@ -151,56 +155,61 @@ class ArcAppIcon::DecodeRequest : public ImageDecoder::ImageRequest {
void OnDecodeImageFailed() override;
private:
base::WeakPtr<ArcAppIcon> host_;
ArcAppIcon& host_;
const ArcAppIconDescriptor descriptor_;
const bool resize_allowed_;
gfx::ImageSkia& image_skia_;
std::map<ui::ScaleFactor, base::Time>& incomplete_scale_factors_;
DISALLOW_COPY_AND_ASSIGN(DecodeRequest);
};
////////////////////////////////////////////////////////////////////////////////
// ArcAppIcon::DecodeRequest
ArcAppIcon::DecodeRequest::DecodeRequest(const base::WeakPtr<ArcAppIcon>& host,
const ArcAppIconDescriptor& descriptor,
bool resize_allowed)
: host_(host), descriptor_(descriptor), resize_allowed_(resize_allowed) {}
ArcAppIcon::DecodeRequest::DecodeRequest(
ArcAppIcon& host,
const ArcAppIconDescriptor& descriptor,
bool resize_allowed,
gfx::ImageSkia& image_skia,
std::map<ui::ScaleFactor, base::Time>& incomplete_scale_factors)
: host_(host),
descriptor_(descriptor),
resize_allowed_(resize_allowed),
image_skia_(image_skia),
incomplete_scale_factors_(incomplete_scale_factors) {}
ArcAppIcon::DecodeRequest::~DecodeRequest() = default;
ArcAppIcon::DecodeRequest::~DecodeRequest() {
ImageDecoder::Cancel(this);
}
void ArcAppIcon::DecodeRequest::OnImageDecoded(const SkBitmap& bitmap) {
DCHECK(!bitmap.isNull() && !bitmap.empty());
if (!host_)
return;
const int expected_dim = descriptor_.GetSizeInPixels();
if (bitmap.width() != expected_dim || bitmap.height() != expected_dim) {
if (!resize_allowed_) {
VLOG(2) << "Decoded ARC icon has unexpected dimension " << bitmap.width()
<< "x" << bitmap.height() << ". Expected " << expected_dim << ".";
host_->MaybeRequestIcon(descriptor_.scale_factor);
host_.MaybeRequestIcon(descriptor_.scale_factor);
} else {
host_->UpdateUncompressed(descriptor_.scale_factor,
skia::ImageOperations::Resize(
bitmap, skia::ImageOperations::RESIZE_BEST,
expected_dim, expected_dim));
host_.UpdateImageSkia(descriptor_.scale_factor,
skia::ImageOperations::Resize(
bitmap, skia::ImageOperations::RESIZE_BEST,
expected_dim, expected_dim),
image_skia_, incomplete_scale_factors_);
}
} else {
host_->UpdateUncompressed(descriptor_.scale_factor, bitmap);
host_.UpdateImageSkia(descriptor_.scale_factor, bitmap, image_skia_,
incomplete_scale_factors_);
}
host_->DiscardDecodeRequest(this);
host_.DiscardDecodeRequest(this);
}
void ArcAppIcon::DecodeRequest::OnDecodeImageFailed() {
VLOG(2) << "Failed to decode ARC icon.";
if (!host_)
return;
host_->MaybeRequestIcon(descriptor_.scale_factor);
host_->DiscardDecodeRequest(this);
host_.MaybeRequestIcon(descriptor_.scale_factor);
host_.DiscardDecodeRequest(this);
}
////////////////////////////////////////////////////////////////////////////////
......@@ -229,38 +238,82 @@ ArcAppIcon::ArcAppIcon(content::BrowserContext* context,
icon_type_(icon_type) {
CHECK(observer_);
if (icon_type == IconType::kUncompressed) {
auto source = std::make_unique<Source>(weak_ptr_factory_.GetWeakPtr(),
resource_size_in_dip);
gfx::Size resource_size(resource_size_in_dip, resource_size_in_dip);
image_skia_ = gfx::ImageSkia(std::move(source), resource_size);
}
gfx::Size resource_size(resource_size_in_dip, resource_size_in_dip);
const std::vector<ui::ScaleFactor>& scale_factors =
ui::GetSupportedScaleFactors();
for (const auto& scale_factor : scale_factors)
incomplete_scale_factors_.insert({scale_factor, base::Time::Now()});
switch (icon_type) {
case IconType::kUncompressed:
image_skia_ = gfx::ImageSkia(
std::make_unique<Source>(weak_ptr_factory_.GetWeakPtr(),
resource_size_in_dip),
resource_size);
// Deliberately fall through to IconType::kCompressed to update
// |incomplete_scale_factors_|.
FALLTHROUGH;
case IconType::kCompressed:
for (const auto& scale_factor : scale_factors)
incomplete_scale_factors_.insert({scale_factor, base::Time::Now()});
break;
case IconType::kAdaptive:
foreground_image_skia_ = gfx::ImageSkia(
std::make_unique<Source>(weak_ptr_factory_.GetWeakPtr(),
resource_size_in_dip),
resource_size);
background_image_skia_ = gfx::ImageSkia(
std::make_unique<Source>(weak_ptr_factory_.GetWeakPtr(),
resource_size_in_dip),
resource_size);
for (const auto& scale_factor : scale_factors) {
foreground_incomplete_scale_factors_.insert(
{scale_factor, base::Time::Now()});
background_incomplete_scale_factors_.insert(
{scale_factor, base::Time::Now()});
}
break;
}
}
ArcAppIcon::~ArcAppIcon() {
}
void ArcAppIcon::LoadSupportedScaleFactors() {
if (icon_type_ == IconType::kCompressed) {
for (auto scale_factor : incomplete_scale_factors_)
LoadForScaleFactor(scale_factor.first);
} else {
// Calling GetRepresentation indirectly calls LoadForScaleFactor but also
// first initializes image_skia_ with the placeholder icons (e.g.
// IDR_APP_DEFAULT_ICON), via ArcAppIcon::Source::GetImageForScale.
for (auto scale_factor : incomplete_scale_factors_)
image_skia_.GetRepresentation(
ui::GetScaleForScaleFactor(scale_factor.first));
switch (icon_type_) {
case IconType::kUncompressed:
// Calling GetRepresentation indirectly calls LoadForScaleFactor but also
// first initializes image_skia_ with the placeholder icons (e.g.
// IDR_APP_DEFAULT_ICON), via ArcAppIcon::Source::GetImageForScale.
for (auto scale_factor : incomplete_scale_factors_) {
image_skia_.GetRepresentation(
ui::GetScaleForScaleFactor(scale_factor.first));
}
break;
case IconType::kCompressed:
for (auto scale_factor : incomplete_scale_factors_)
LoadForScaleFactor(scale_factor.first);
break;
case IconType::kAdaptive:
for (auto scale_factor : incomplete_scale_factors_) {
foreground_image_skia_.GetRepresentation(
ui::GetScaleForScaleFactor(scale_factor.first));
background_image_skia_.GetRepresentation(
ui::GetScaleForScaleFactor(scale_factor.first));
}
break;
}
}
bool ArcAppIcon::EverySupportedScaleFactorIsLoaded() const {
return incomplete_scale_factors_.empty();
switch (icon_type_) {
case IconType::kUncompressed:
// Deliberately fall through to IconType::kCompressed to check
// |incomplete_scale_factors_|.
FALLTHROUGH;
case IconType::kCompressed:
return incomplete_scale_factors_.empty();
case IconType::kAdaptive:
return foreground_incomplete_scale_factors_.empty() &&
background_incomplete_scale_factors_.empty();
}
}
void ArcAppIcon::LoadForScaleFactor(ui::ScaleFactor scale_factor) {
......@@ -272,14 +325,37 @@ void ArcAppIcon::LoadForScaleFactor(ui::ScaleFactor scale_factor) {
DCHECK(prefs);
const ArcAppIconDescriptor descriptor(resource_size_in_dip_, scale_factor);
const base::FilePath path = prefs->GetIconPath(mapped_app_id_, descriptor);
if (path.empty())
return;
std::vector<base::FilePath> paths;
switch (icon_type_) {
case IconType::kUncompressed: {
// Deliberately fall through to IconType::kCompressed to add |path| to
// |paths|.
FALLTHROUGH;
}
case IconType::kCompressed: {
base::FilePath path = prefs->GetIconPath(mapped_app_id_, descriptor);
if (path.empty())
return;
paths.emplace_back(path);
break;
}
case IconType::kAdaptive: {
base::FilePath foreground_path =
prefs->GetForegroundIconPath(mapped_app_id_, descriptor);
base::FilePath background_path =
prefs->GetBackgroundIconPath(mapped_app_id_, descriptor);
if (foreground_path.empty() || background_path.empty())
return;
paths.emplace_back(foreground_path);
paths.emplace_back(background_path);
break;
}
}
base::ThreadPool::PostTaskAndReplyWithResult(
FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_VISIBLE},
base::BindOnce(
&ArcAppIcon::ReadOnFileThread, scale_factor, path,
&ArcAppIcon::ReadOnBackgroundThread, icon_type_, scale_factor, paths,
prefs->MaybeGetIconPathForDefaultApp(mapped_app_id_, descriptor)),
base::BindOnce(&ArcAppIcon::OnIconRead, weak_ptr_factory_.GetWeakPtr()));
}
......@@ -299,7 +375,29 @@ void ArcAppIcon::MaybeRequestIcon(ui::ScaleFactor scale_factor) {
}
// static
std::unique_ptr<ArcAppIcon::ReadResult> ArcAppIcon::ReadOnFileThread(
std::unique_ptr<ArcAppIcon::ReadResult> ArcAppIcon::ReadOnBackgroundThread(
ArcAppIcon::IconType icon_type,
ui::ScaleFactor scale_factor,
const std::vector<base::FilePath>& paths,
const base::FilePath& default_app_path) {
DCHECK(!paths.empty());
switch (icon_type) {
case IconType::kUncompressed:
// Deliberately fall through to IconType::kCompressed.
FALLTHROUGH;
case IconType::kCompressed:
DCHECK_EQ(1u, paths.size());
return ArcAppIcon::ReadSingleIconFile(scale_factor, paths[0],
default_app_path);
case IconType::kAdaptive:
return ArcAppIcon::ReadAdaptiveIconFiles(scale_factor, paths,
default_app_path);
}
}
// static
std::unique_ptr<ArcAppIcon::ReadResult> ArcAppIcon::ReadSingleIconFile(
ui::ScaleFactor scale_factor,
const base::FilePath& path,
const base::FilePath& default_app_path) {
......@@ -315,17 +413,83 @@ std::unique_ptr<ArcAppIcon::ReadResult> ArcAppIcon::ReadOnFileThread(
if (default_app_path.empty() || !base::PathExists(default_app_path)) {
return std::make_unique<ArcAppIcon::ReadResult>(
false /* error */, true /* request_to_install */, scale_factor,
false /* resize_allowed */, std::string() /* unsafe_icon_data */);
false /* resize_allowed */,
std::vector<std::string>() /* unsafe_icon_data */);
}
path_to_read = default_app_path;
resize_allowed = true;
}
bool request_to_install = path_to_read != path;
return ArcAppIcon::ReadFile(request_to_install, scale_factor, resize_allowed,
path_to_read);
}
// static
std::unique_ptr<ArcAppIcon::ReadResult> ArcAppIcon::ReadAdaptiveIconFiles(
ui::ScaleFactor scale_factor,
const std::vector<base::FilePath>& paths,
const base::FilePath& default_app_path) {
DCHECK_EQ(2u, paths.size());
const base::FilePath& foreground_path = paths[0];
const base::FilePath& background_path = paths[1];
if (!base::PathExists(foreground_path) ||
!base::PathExists(background_path)) {
if (default_app_path.empty() || !base::PathExists(default_app_path)) {
return std::make_unique<ArcAppIcon::ReadResult>(
false /* error */, true /* request_to_install */, scale_factor,
false /* resize_allowed */,
std::vector<std::string>() /* unsafe_icon_data */);
}
return ArcAppIcon::ReadFile(true /* request_to_install */, scale_factor,
true /* resize_allowed */, default_app_path);
}
// Read the file from disk.
std::string unsafe_foreground_icon_data;
std::string unsafe_background_icon_data;
if (!base::ReadFileToString(foreground_path, &unsafe_foreground_icon_data) ||
unsafe_foreground_icon_data.empty()) {
VLOG(2) << "Failed to read an ARC icon from file "
<< foreground_path.MaybeAsASCII();
return std::make_unique<ArcAppIcon::ReadResult>(
true /* error */, true /* request_to_install */, scale_factor,
false /* resize_allowed */,
std::vector<std::string>() /* unsafe_icon_data */);
}
if (!base::ReadFileToString(background_path, &unsafe_background_icon_data) ||
unsafe_background_icon_data.empty()) {
VLOG(2) << "Failed to read an ARC icon from file "
<< background_path.MaybeAsASCII();
return std::make_unique<ArcAppIcon::ReadResult>(
true /* error */, true /* request_to_install */, scale_factor,
false /* resize_allowed */,
std::vector<std::string>() /* unsafe_icon_data */);
}
return std::make_unique<ArcAppIcon::ReadResult>(
false /* error */, false /* request_to_install */, scale_factor,
false /* resize_allowed */,
std::vector<std::string>{std::move(unsafe_foreground_icon_data),
std::move(unsafe_background_icon_data)});
}
// static
std::unique_ptr<ArcAppIcon::ReadResult> ArcAppIcon::ReadFile(
bool request_to_install,
ui::ScaleFactor scale_factor,
bool resize_allowed,
const base::FilePath& path) {
DCHECK(!path.empty());
DCHECK(base::PathExists(path));
// Read the file from disk.
std::string unsafe_icon_data;
if (!base::ReadFileToString(path_to_read, &unsafe_icon_data) ||
if (!base::ReadFileToString(path, &unsafe_icon_data) ||
unsafe_icon_data.empty()) {
VLOG(2) << "Failed to read an ARC icon from file " << path.MaybeAsASCII();
......@@ -334,12 +498,13 @@ std::unique_ptr<ArcAppIcon::ReadResult> ArcAppIcon::ReadOnFileThread(
request_to_install |= unsafe_icon_data.empty();
return std::make_unique<ArcAppIcon::ReadResult>(
true /* error */, request_to_install, scale_factor,
false /* resize_allowed */, std::string() /* unsafe_icon_data */);
false /* resize_allowed */,
std::vector<std::string>() /* unsafe_icon_data */);
}
return std::make_unique<ArcAppIcon::ReadResult>(
false /* error */, request_to_install, scale_factor, resize_allowed,
unsafe_icon_data);
std::vector<std::string>{std::move(unsafe_icon_data)});
}
void ArcAppIcon::OnIconRead(
......@@ -349,57 +514,91 @@ void ArcAppIcon::OnIconRead(
if (read_result->request_to_install)
MaybeRequestIcon(read_result->scale_factor);
if (!read_result->unsafe_icon_data.empty()) {
if (icon_type_ == IconType::kCompressed) {
if (read_result->unsafe_icon_data.empty())
return;
switch (icon_type_) {
case IconType::kUncompressed: {
DCHECK_EQ(1u, read_result->unsafe_icon_data.size());
DecodeImage(read_result->unsafe_icon_data[0],
ArcAppIconDescriptor(resource_size_in_dip_,
read_result->scale_factor),
read_result->resize_allowed, image_skia_,
incomplete_scale_factors_);
return;
}
case IconType::kCompressed: {
DCHECK_EQ(1u, read_result->unsafe_icon_data.size());
UpdateCompressed(read_result->scale_factor,
std::move(read_result->unsafe_icon_data));
std::move(read_result->unsafe_icon_data[0]));
return;
}
case IconType::kAdaptive: {
DCHECK_EQ(2u, read_result->unsafe_icon_data.size());
DecodeImage(read_result->unsafe_icon_data[0],
ArcAppIconDescriptor(resource_size_in_dip_,
read_result->scale_factor),
read_result->resize_allowed, foreground_image_skia_,
foreground_incomplete_scale_factors_);
DecodeImage(read_result->unsafe_icon_data[1],
ArcAppIconDescriptor(resource_size_in_dip_,
read_result->scale_factor),
read_result->resize_allowed, background_image_skia_,
background_incomplete_scale_factors_);
return;
}
}
}
decode_requests_.emplace_back(std::make_unique<DecodeRequest>(
weak_ptr_factory_.GetWeakPtr(),
ArcAppIconDescriptor(resource_size_in_dip_, read_result->scale_factor),
read_result->resize_allowed));
if (disable_safe_decoding_for_testing) {
SkBitmap bitmap;
if (!read_result->unsafe_icon_data.empty() &&
gfx::PNGCodec::Decode(
reinterpret_cast<const unsigned char*>(
&read_result->unsafe_icon_data.front()),
read_result->unsafe_icon_data.length(),
&bitmap)) {
decode_requests_.back()->OnImageDecoded(bitmap);
} else {
decode_requests_.back()->OnDecodeImageFailed();
}
void ArcAppIcon::DecodeImage(
const std::string& unsafe_icon_data,
const ArcAppIconDescriptor& descriptor,
bool resize_allowed,
gfx::ImageSkia& image_skia,
std::map<ui::ScaleFactor, base::Time>& incomplete_scale_factors) {
decode_requests_.emplace_back(std::make_unique<DecodeRequest>(
*this, descriptor, resize_allowed, image_skia, incomplete_scale_factors));
if (disable_safe_decoding_for_testing) {
SkBitmap bitmap;
if (!unsafe_icon_data.empty() &&
gfx::PNGCodec::Decode(
reinterpret_cast<const unsigned char*>(&unsafe_icon_data.front()),
unsafe_icon_data.length(), &bitmap)) {
decode_requests_.back()->OnImageDecoded(bitmap);
} else {
ImageDecoder::Start(decode_requests_.back().get(),
read_result->unsafe_icon_data);
decode_requests_.back()->OnDecodeImageFailed();
}
} else {
ImageDecoder::Start(decode_requests_.back().get(), unsafe_icon_data);
}
}
void ArcAppIcon::UpdateUncompressed(ui::ScaleFactor scale_factor,
const SkBitmap& bitmap) {
void ArcAppIcon::UpdateImageSkia(
ui::ScaleFactor scale_factor,
const SkBitmap& bitmap,
gfx::ImageSkia& image_skia,
std::map<ui::ScaleFactor, base::Time>& incomplete_scale_factors) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
gfx::ImageSkiaRep image_rep(bitmap, ui::GetScaleForScaleFactor(scale_factor));
DCHECK(ui::IsSupportedScale(image_rep.scale()));
image_skia_.RemoveRepresentation(image_rep.scale());
image_skia_.AddRepresentation(image_rep);
image_skia_.RemoveUnsupportedRepresentationsForScale(image_rep.scale());
image_skia.RemoveRepresentation(image_rep.scale());
image_skia.AddRepresentation(image_rep);
image_skia.RemoveUnsupportedRepresentationsForScale(image_rep.scale());
// TODO(crbug.com/1083331): Track the adaptive icon load time in a separate
// UMA.
if (icon_loaded_count_++ < 5) {
base::UmaHistogramTimes(
"Arc.IconLoadFromFileTime.uncompressedFirst5",
base::Time::Now() - incomplete_scale_factors_[scale_factor]);
base::Time::Now() - incomplete_scale_factors[scale_factor]);
} else {
base::UmaHistogramTimes(
"Arc.IconLoadFromFileTime.uncompressedOthers",
base::Time::Now() - incomplete_scale_factors_[scale_factor]);
base::Time::Now() - incomplete_scale_factors[scale_factor]);
}
incomplete_scale_factors_.erase(scale_factor);
incomplete_scale_factors.erase(scale_factor);
observer_->OnIconUpdated(this);
}
......
......@@ -17,6 +17,8 @@
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_skia.h"
struct ArcAppIconDescriptor;
namespace apps {
class ArcIconOnceLoader;
}
......@@ -52,6 +54,7 @@ class ArcAppIcon {
enum IconType {
kUncompressed,
kCompressed,
kAdaptive,
};
ArcAppIcon(content::BrowserContext* context,
......@@ -84,6 +87,18 @@ class ArcAppIcon {
DCHECK_EQ(IconType::kCompressed, icon_type_);
return compressed_images_;
}
// Returns |foreground_image_skia_| and valid if the |icon_type_| is
// IconType::kAdaptive.
const gfx::ImageSkia& foreground_image_skia() const {
DCHECK_EQ(IconType::kAdaptive, icon_type_);
return foreground_image_skia_;
}
// Returns |background_image_skia_| and valid if the |icon_type_| is
// IconType::kAdaptive.
const gfx::ImageSkia& background_image_skia() const {
DCHECK_EQ(IconType::kAdaptive, icon_type_);
return background_image_skia_;
}
// Disables async safe decoding requests when unit tests are executed. This is
// done to avoid two problems. Problems come because icons are decoded at a
......@@ -124,12 +139,36 @@ class ArcAppIcon {
void LoadForScaleFactor(ui::ScaleFactor scale_factor);
void MaybeRequestIcon(ui::ScaleFactor scale_factor);
static std::unique_ptr<ArcAppIcon::ReadResult> ReadOnFileThread(
static std::unique_ptr<ArcAppIcon::ReadResult> ReadOnBackgroundThread(
ArcAppIcon::IconType icon_type,
ui::ScaleFactor scale_factor,
const std::vector<base::FilePath>& paths,
const base::FilePath& default_app_path);
static std::unique_ptr<ArcAppIcon::ReadResult> ReadSingleIconFile(
ui::ScaleFactor scale_factor,
const base::FilePath& path,
const base::FilePath& default_app_path);
static std::unique_ptr<ArcAppIcon::ReadResult> ReadAdaptiveIconFiles(
ui::ScaleFactor scale_factor,
const std::vector<base::FilePath>& paths,
const base::FilePath& default_app_path);
static std::unique_ptr<ArcAppIcon::ReadResult> ReadFile(
bool request_to_install,
ui::ScaleFactor scale_factor,
bool resize_allowed,
const base::FilePath& path);
void OnIconRead(std::unique_ptr<ArcAppIcon::ReadResult> read_result);
void UpdateUncompressed(ui::ScaleFactor scale_factor, const SkBitmap& bitmap);
void DecodeImage(
const std::string& unsafe_icon_data,
const ArcAppIconDescriptor& descriptor,
bool resize_allowed,
gfx::ImageSkia& image_skia,
std::map<ui::ScaleFactor, base::Time>& incomplete_scale_factors);
void UpdateImageSkia(
ui::ScaleFactor scale_factor,
const SkBitmap& bitmap,
gfx::ImageSkia& image_skia,
std::map<ui::ScaleFactor, base::Time>& incomplete_scale_factors);
void UpdateCompressed(ui::ScaleFactor scale_factor, std::string data);
void DiscardDecodeRequest(DecodeRequest* request);
......@@ -148,7 +187,12 @@ class ArcAppIcon {
gfx::ImageSkia image_skia_;
std::map<ui::ScaleFactor, std::string> compressed_images_;
gfx::ImageSkia foreground_image_skia_;
gfx::ImageSkia background_image_skia_;
std::map<ui::ScaleFactor, base::Time> incomplete_scale_factors_;
std::map<ui::ScaleFactor, base::Time> foreground_incomplete_scale_factors_;
std::map<ui::ScaleFactor, base::Time> background_incomplete_scale_factors_;
// Contains pending image decode requests.
std::vector<std::unique_ptr<DecodeRequest>> decode_requests_;
......
......@@ -18,6 +18,8 @@ int GetScalePercent(ui::ScaleFactor scale_factor) {
// Template for the icon name. First part is scale percent and second is
// resource size in dip.
constexpr char kIconNameTemplate[] = "icon_%dp_%d.png";
constexpr char kForegroundIconNameTemplate[] = "foreground_icon_%dp_%d.png";
constexpr char kBackgroundIconNameTemplate[] = "background_icon_%dp_%d.png";
} // namespace
......@@ -38,6 +40,16 @@ std::string ArcAppIconDescriptor::GetName() const {
dip_size);
}
std::string ArcAppIconDescriptor::GetForegroundIconName() const {
return base::StringPrintf(kForegroundIconNameTemplate,
GetScalePercent(scale_factor), dip_size);
}
std::string ArcAppIconDescriptor::GetBackgroundIconName() const {
return base::StringPrintf(kBackgroundIconNameTemplate,
GetScalePercent(scale_factor), dip_size);
}
bool ArcAppIconDescriptor::operator==(const ArcAppIconDescriptor& other) const {
return scale_factor == other.scale_factor && dip_size == other.dip_size;
}
......
......@@ -16,6 +16,10 @@ struct ArcAppIconDescriptor {
int GetSizeInPixels() const;
// Used as a file name to store icon on the disk.
std::string GetName() const;
// Used as a file name to store the foreground icon on the disk.
std::string GetForegroundIconName() const;
// Used as a file name to store the background icon on the disk.
std::string GetBackgroundIconName() const;
bool operator==(const ArcAppIconDescriptor& other) const;
bool operator!=(const ArcAppIconDescriptor& other) const;
......
......@@ -413,6 +413,20 @@ base::FilePath ArcAppListPrefs::GetIconPath(
return GetAppPath(app_id).AppendASCII(descriptor.GetName());
}
base::FilePath ArcAppListPrefs::GetForegroundIconPath(
const std::string& app_id,
const ArcAppIconDescriptor& descriptor) {
active_icons_[app_id].insert(descriptor);
return GetAppPath(app_id).AppendASCII(descriptor.GetForegroundIconName());
}
// Constructs path to the app background icon for specific scale factor.
base::FilePath ArcAppListPrefs::GetBackgroundIconPath(
const std::string& app_id,
const ArcAppIconDescriptor& descriptor) {
active_icons_[app_id].insert(descriptor);
return GetAppPath(app_id).AppendASCII(descriptor.GetBackgroundIconName());
}
bool ArcAppListPrefs::IsIconRequestRecorded(
const std::string& app_id,
const ArcAppIconDescriptor& descriptor) const {
......
......@@ -273,6 +273,12 @@ class ArcAppListPrefs : public KeyedService,
// Constructs path to app icon for specific scale factor.
base::FilePath GetIconPath(const std::string& app_id,
const ArcAppIconDescriptor& descriptor);
// Constructs path to the app foreground icon for specific scale factor.
base::FilePath GetForegroundIconPath(const std::string& app_id,
const ArcAppIconDescriptor& descriptor);
// Constructs path to the app background icon for specific scale factor.
base::FilePath GetBackgroundIconPath(const std::string& app_id,
const ArcAppIconDescriptor& descriptor);
// Constructs path to default app icon for specific scale factor. This path
// is used to resolve icon if no icon is available at |GetIconPath|.
base::FilePath MaybeGetIconPathForDefaultApp(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment