Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(212)

Unified Diff: components/favicon/core/large_icon_service.cc

Issue 2784233003: [LargeIconService] Allow decoding of images in the service (Closed)
Patch Set: Minor changes #2 Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: components/favicon/core/large_icon_service.cc
diff --git a/components/favicon/core/large_icon_service.cc b/components/favicon/core/large_icon_service.cc
index 7d519677c51780055520e90d6e9a6f3a0217b1ff..8d7bde46990cbfed6ad0646641a65b794cb9b582 100644
--- a/components/favicon/core/large_icon_service.cc
+++ b/components/favicon/core/large_icon_service.cc
@@ -60,9 +60,11 @@ GURL GetIconUrlForGoogleServerV2(const GURL& page_url,
// LargeIconService request.
class LargeIconWorker : public base::RefCountedThreadSafe<LargeIconWorker> {
public:
+ // Exactly one of the callbacks is expected to be non-null.
LargeIconWorker(int min_source_size_in_pixel,
int desired_size_in_pixel,
- favicon_base::LargeIconCallback callback,
+ favicon_base::LargeIconCallback raw_bitmap_callback,
+ favicon_base::LargeIconImageCallback image_callback,
scoped_refptr<base::TaskRunner> background_task_runner,
base::CancelableTaskTracker* tracker);
@@ -71,7 +73,7 @@ class LargeIconWorker : public base::RefCountedThreadSafe<LargeIconWorker> {
// ProcessIconOnBackgroundThread() so we do not perform complex image
// operations on the UI thread.
void OnIconLookupComplete(
- const favicon_base::FaviconRawBitmapResult& bitmap_result);
+ const favicon_base::FaviconRawBitmapResult& raw_bitmap_result);
private:
friend class base::RefCountedThreadSafe<LargeIconWorker>;
@@ -83,15 +85,19 @@ class LargeIconWorker : public base::RefCountedThreadSafe<LargeIconWorker> {
// that does not work, computes the icon fallback style and uses it to
// invoke |callback_|. This must be run on a background thread because image
// resizing and dominant color extraction can be expensive.
- void ProcessIconOnBackgroundThread();
+ void ProcessIconOnBackgroundThread(bool return_raw,
+ bool return_original_size);
// Must run on a background thread in production.
// If |bitmap_result_| is square and large enough (>= |min_source_in_pixel_|),
// resizes it to |desired_size_in_pixel_| (but if |desired_size_in_pixel_| is
- // 0 then don't resize). If successful, stores the resulting bitmap data
- // into |resized_bitmap_result| and returns true.
- bool ResizeLargeIconOnBackgroundThreadIfValid(
- favicon_base::FaviconRawBitmapResult* resized_bitmap_result);
+ // 0 then don't resize). If successful, stores the resulting raw bitmap data
+ // into |raw_bitmap_result_| and image data in |image_result_| and returns
+ // true. The params |return_raw| and |return_original_size| allow early exit
+ // to skip steps that are not needed.
+ bool DecodeResizeAndEncodeLargeIconOnBackgroundThreadIfValid(
+ bool return_raw,
+ bool return_original_size);
// Must run on the owner (UI) thread in production.
// Invoked when ProcessIconOnBackgroundThread() is done.
@@ -99,11 +105,14 @@ class LargeIconWorker : public base::RefCountedThreadSafe<LargeIconWorker> {
int min_source_size_in_pixel_;
int desired_size_in_pixel_;
- favicon_base::LargeIconCallback callback_;
+ favicon_base::LargeIconCallback raw_bitmap_callback_;
+ favicon_base::LargeIconImageCallback image_callback_;
scoped_refptr<base::TaskRunner> background_task_runner_;
base::CancelableTaskTracker* tracker_;
- favicon_base::FaviconRawBitmapResult bitmap_result_;
- std::unique_ptr<favicon_base::LargeIconResult> result_;
+
+ favicon_base::FaviconRawBitmapResult raw_bitmap_result_;
+ SkBitmap image_result_;
+ std::unique_ptr<favicon_base::FallbackIconStyle> fallback_icon_style_;
DISALLOW_COPY_AND_ASSIGN(LargeIconWorker);
};
@@ -111,87 +120,118 @@ class LargeIconWorker : public base::RefCountedThreadSafe<LargeIconWorker> {
LargeIconWorker::LargeIconWorker(
int min_source_size_in_pixel,
int desired_size_in_pixel,
- favicon_base::LargeIconCallback callback,
+ favicon_base::LargeIconCallback raw_bitmap_callback,
+ favicon_base::LargeIconImageCallback image_callback,
scoped_refptr<base::TaskRunner> background_task_runner,
base::CancelableTaskTracker* tracker)
: min_source_size_in_pixel_(min_source_size_in_pixel),
desired_size_in_pixel_(desired_size_in_pixel),
- callback_(callback),
+ raw_bitmap_callback_(raw_bitmap_callback),
+ image_callback_(image_callback),
background_task_runner_(background_task_runner),
- tracker_(tracker) {
-}
+ tracker_(tracker) {}
LargeIconWorker::~LargeIconWorker() {
}
void LargeIconWorker::OnIconLookupComplete(
- const favicon_base::FaviconRawBitmapResult& bitmap_result) {
- bitmap_result_ = bitmap_result;
+ const favicon_base::FaviconRawBitmapResult& raw_bitmap_result) {
+ raw_bitmap_result_ = raw_bitmap_result;
+
+ bool return_raw = !raw_bitmap_callback_.is_null();
+ bool return_original_size =
+ (desired_size_in_pixel_ == 0 ||
+ raw_bitmap_result_.pixel_size.width() == desired_size_in_pixel_);
+
tracker_->PostTaskAndReply(
background_task_runner_.get(), FROM_HERE,
- base::Bind(&LargeIconWorker::ProcessIconOnBackgroundThread, this),
+ base::Bind(&LargeIconWorker::ProcessIconOnBackgroundThread, this,
+ return_raw, return_original_size),
base::Bind(&LargeIconWorker::OnIconProcessingComplete, this));
}
-void LargeIconWorker::ProcessIconOnBackgroundThread() {
- favicon_base::FaviconRawBitmapResult resized_bitmap_result;
- if (ResizeLargeIconOnBackgroundThreadIfValid(&resized_bitmap_result)) {
- result_.reset(
- new favicon_base::LargeIconResult(resized_bitmap_result));
- } else {
+void LargeIconWorker::ProcessIconOnBackgroundThread(bool return_raw,
+ bool return_original_size) {
+ if (!DecodeResizeAndEncodeLargeIconOnBackgroundThreadIfValid(
+ return_raw, return_original_size)) {
// Failed to resize |bitmap_result_|, so compute fallback icon style.
- std::unique_ptr<favicon_base::FallbackIconStyle> fallback_icon_style(
- new favicon_base::FallbackIconStyle());
- if (bitmap_result_.is_valid()) {
- favicon_base::SetDominantColorAsBackground(
- bitmap_result_.bitmap_data, fallback_icon_style.get());
+ fallback_icon_style_ =
+ base::WrapUnique(new favicon_base::FallbackIconStyle());
+ if (raw_bitmap_result_.is_valid()) {
+ favicon_base::SetDominantColorAsBackground(raw_bitmap_result_.bitmap_data,
+ fallback_icon_style_.get());
}
- result_.reset(
- new favicon_base::LargeIconResult(fallback_icon_style.release()));
}
}
-bool LargeIconWorker::ResizeLargeIconOnBackgroundThreadIfValid(
- favicon_base::FaviconRawBitmapResult* resized_bitmap_result) {
+bool LargeIconWorker::DecodeResizeAndEncodeLargeIconOnBackgroundThreadIfValid(
+ bool return_raw,
+ bool return_original_size) {
pkotwicz 2017/04/02 20:46:52 How about something like this: Some things about m
jkrcal 2017/04/03 17:44:55 Done.
// Require bitmap to be valid and square.
- if (!bitmap_result_.is_valid() ||
- bitmap_result_.pixel_size.width() != bitmap_result_.pixel_size.height())
+ if (!raw_bitmap_result_.is_valid() ||
+ raw_bitmap_result_.pixel_size.width() !=
+ raw_bitmap_result_.pixel_size.height()) {
return false;
+ }
// Require bitmap to be large enough. It's square, so just check width.
- if (bitmap_result_.pixel_size.width() < min_source_size_in_pixel_)
+ if (raw_bitmap_result_.pixel_size.width() < min_source_size_in_pixel_)
return false;
- *resized_bitmap_result = bitmap_result_;
-
- // Special case: Can use |bitmap_result_| as is.
- if (desired_size_in_pixel_ == 0 ||
- bitmap_result_.pixel_size.width() == desired_size_in_pixel_)
+ // Decoding is not needed, we are done.
+ if (return_original_size && return_raw)
return true;
- // Resize bitmap: decode PNG, resize, and re-encode PNG.
- SkBitmap decoded_bitmap;
- if (!gfx::PNGCodec::Decode(bitmap_result_.bitmap_data->front(),
- bitmap_result_.bitmap_data->size(), &decoded_bitmap))
+ // Decode the image.
+ if (!gfx::PNGCodec::Decode(raw_bitmap_result_.bitmap_data->front(),
+ raw_bitmap_result_.bitmap_data->size(),
+ &image_result_))
return false;
- SkBitmap resized_bitmap = skia::ImageOperations::Resize(
- decoded_bitmap, skia::ImageOperations::RESIZE_LANCZOS3,
+ // Resizing is not needed, we are done.
+ if (return_original_size)
+ return true;
+
+ image_result_ = skia::ImageOperations::Resize(
+ image_result_, skia::ImageOperations::RESIZE_LANCZOS3,
desired_size_in_pixel_, desired_size_in_pixel_);
+ // Encoding back is not needed, we are done.
+ if (!return_raw)
+ return true;
+
std::vector<unsigned char> bitmap_data;
- if (!gfx::PNGCodec::EncodeBGRASkBitmap(resized_bitmap, false, &bitmap_data))
+ if (!gfx::PNGCodec::EncodeBGRASkBitmap(image_result_, false, &bitmap_data))
return false;
- resized_bitmap_result->pixel_size =
+ // Write the results back into the original |raw_bitmap_result_|.
+ raw_bitmap_result_.pixel_size =
gfx::Size(desired_size_in_pixel_, desired_size_in_pixel_);
- resized_bitmap_result->bitmap_data =
+ raw_bitmap_result_.bitmap_data =
base::RefCountedBytes::TakeVector(&bitmap_data);
return true;
}
void LargeIconWorker::OnIconProcessingComplete() {
- callback_.Run(*result_);
+ // If fallback style is set, return that.
+ if (fallback_icon_style_) {
+ if (raw_bitmap_callback_) {
+ raw_bitmap_callback_.Run(
+ favicon_base::LargeIconResult(fallback_icon_style_.release()));
+ } else {
+ image_callback_.Run(
+ favicon_base::LargeIconImageResult(fallback_icon_style_.release()));
+ }
+ return;
+ }
+
+ // Return the large icon, otherwise.
+ if (raw_bitmap_callback_) {
+ raw_bitmap_callback_.Run(favicon_base::LargeIconResult(raw_bitmap_result_));
+ } else {
+ image_callback_.Run(favicon_base::LargeIconImageResult(
+ gfx::Image::CreateFrom1xBitmap(image_result_)));
+ }
}
void OnFetchIconFromGoogleServerComplete(
@@ -242,18 +282,42 @@ LargeIconService::~LargeIconService() {
}
base::CancelableTaskTracker::TaskId
- LargeIconService::GetLargeIconOrFallbackStyle(
- const GURL& page_url,
- int min_source_size_in_pixel,
- int desired_size_in_pixel,
- const favicon_base::LargeIconCallback& callback,
- base::CancelableTaskTracker* tracker) {
+LargeIconService::GetLargeIconOrFallbackStyle(
+ const GURL& page_url,
+ int min_source_size_in_pixel,
+ int desired_size_in_pixel,
+ const favicon_base::LargeIconCallback& raw_bitmap_callback,
+ base::CancelableTaskTracker* tracker) {
+ DCHECK_LE(1, min_source_size_in_pixel);
+ DCHECK_LE(0, desired_size_in_pixel);
+
+ scoped_refptr<LargeIconWorker> worker = new LargeIconWorker(
+ min_source_size_in_pixel, desired_size_in_pixel, raw_bitmap_callback,
+ favicon_base::LargeIconImageCallback(), background_task_runner_, tracker);
+
+ // TODO(beaudoin): For now this is just a wrapper around
+ // GetLargestRawFaviconForPageURL. Add the logic required to select the best
+ // possible large icon. Also add logic to fetch-on-demand when the URL of
+ // a large icon is known but its bitmap is not available.
+ return favicon_service_->GetLargestRawFaviconForPageURL(
+ page_url, large_icon_types_, min_source_size_in_pixel,
+ base::Bind(&LargeIconWorker::OnIconLookupComplete, worker), tracker);
+}
+
+base::CancelableTaskTracker::TaskId
+LargeIconService::GetLargeIconImageOrFallbackStyle(
+ const GURL& page_url,
+ int min_source_size_in_pixel,
+ int desired_size_in_pixel,
+ const favicon_base::LargeIconImageCallback& image_callback,
+ base::CancelableTaskTracker* tracker) {
DCHECK_LE(1, min_source_size_in_pixel);
DCHECK_LE(0, desired_size_in_pixel);
scoped_refptr<LargeIconWorker> worker =
new LargeIconWorker(min_source_size_in_pixel, desired_size_in_pixel,
- callback, background_task_runner_, tracker);
+ favicon_base::LargeIconCallback(), image_callback,
+ background_task_runner_, tracker);
// TODO(beaudoin): For now this is just a wrapper around
// GetLargestRawFaviconForPageURL. Add the logic required to select the best
« no previous file with comments | « components/favicon/core/large_icon_service.h ('k') | components/favicon/core/large_icon_service_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698