| 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 fa42fe4d8f54f4189fc24d6595e9cd38b4369110..dba7bcab20d36b41b094e7dab725612beaf85e69 100644
|
| --- a/components/favicon/core/large_icon_service.cc
|
| +++ b/components/favicon/core/large_icon_service.cc
|
| @@ -4,201 +4,457 @@
|
|
|
| #include "components/favicon/core/large_icon_service.h"
|
|
|
| +#include <algorithm>
|
| #include <memory>
|
|
|
| #include "base/bind.h"
|
| +#include "base/feature_list.h"
|
| #include "base/location.h"
|
| #include "base/logging.h"
|
| #include "base/macros.h"
|
| +#include "base/memory/ptr_util.h"
|
| #include "base/memory/ref_counted.h"
|
| +#include "base/strings/stringprintf.h"
|
| #include "base/task_runner.h"
|
| +#include "base/task_runner_util.h"
|
| #include "base/threading/sequenced_worker_pool.h"
|
| +#include "base/threading/thread_task_runner_handle.h"
|
| +#include "components/data_use_measurement/core/data_use_user_data.h"
|
| #include "components/favicon/core/favicon_service.h"
|
| +#include "components/favicon/core/features.h"
|
| #include "components/favicon_base/fallback_icon_style.h"
|
| #include "components/favicon_base/favicon_types.h"
|
| +#include "components/favicon_base/favicon_util.h"
|
| +#include "components/image_fetcher/image_fetcher.h"
|
| #include "skia/ext/image_operations.h"
|
| #include "ui/gfx/codec/png_codec.h"
|
| #include "ui/gfx/geometry/size.h"
|
|
|
| +using image_fetcher::ImageFetcher;
|
| +
|
| +namespace favicon {
|
| +
|
| namespace {
|
|
|
| -// Processes the bitmap data returned from the FaviconService as part of a
|
| +const char kGoogleServer1RequestFormat[] =
|
| + "https://s2.googleusercontent.com/s2/"
|
| + "favicons?domain=%s&src=chrome_large_icons&sz=%d&alt=404";
|
| +const int kGoogleServer1DesiredSizeInPixel = 32;
|
| +
|
| +// Type APPLE_TOUCH includes TOUCH_ICONs as well as FAVICONs as fallback.
|
| +const char kGoogleServer2RequestFormat[] =
|
| + "https://t0.gstatic.com/"
|
| + "faviconV2?url=%s&type=APPLE_TOUCH&size=%d&min_size=%d&max_size=%d";
|
| +const int kGoogleServer2MinSizeInPixel = 48;
|
| +const int kGoogleServer2MaxSizeInPixel = 256;
|
| +const int kGoogleServer2DesiredSizeInPixel = 192;
|
| +
|
| +struct LargeIconRequest {
|
| + const GURL& page_url;
|
| + int min_source_size_in_pixel;
|
| + int desired_size_in_pixel;
|
| + const favicon_base::LargeIconCallback& callback;
|
| +};
|
| +
|
| +std::unique_ptr<favicon_base::LargeIconResult> CreateLargeIconResult(
|
| + const favicon_base::FaviconRawBitmapResult* bitmap_result,
|
| + bool create_bitmap) {
|
| + if (create_bitmap && bitmap_result && bitmap_result->is_valid()) {
|
| + return base::MakeUnique<favicon_base::LargeIconResult>(*bitmap_result);
|
| + } else {
|
| + // Compute fallback icon style.
|
| + std::unique_ptr<favicon_base::FallbackIconStyle> fallback_icon_style =
|
| + base::MakeUnique<favicon_base::FallbackIconStyle>();
|
| + if (bitmap_result && bitmap_result->is_valid()) {
|
| + favicon_base::SetDominantColorAsBackground(bitmap_result->bitmap_data,
|
| + fallback_icon_style.get());
|
| + }
|
| + return base::MakeUnique<favicon_base::LargeIconResult>(
|
| + std::move(fallback_icon_style));
|
| + }
|
| +}
|
| +
|
| +// Must run on the owner (UI) thread in production.
|
| +void RunCallback(const favicon_base::LargeIconCallback& callback,
|
| + std::unique_ptr<favicon_base::LargeIconResult> result) {
|
| + callback.Run(*result);
|
| +}
|
| +
|
| +// 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 ResizeRawBitmapOnBackgroundThreadIfValid(
|
| + LargeIconRequest* request,
|
| + const favicon_base::FaviconRawBitmapResult& bitmap_result,
|
| + favicon_base::FaviconRawBitmapResult* resized_bitmap_result) {
|
| + // Require bitmap to be valid and square.
|
| + if (!bitmap_result.is_valid() ||
|
| + bitmap_result.pixel_size.width() != 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() < request->min_source_size_in_pixel)
|
| + return false;
|
| +
|
| + *resized_bitmap_result = bitmap_result;
|
| +
|
| + // Special case: Can use |bitmap_result| as is.
|
| + if (request->desired_size_in_pixel_ == 0 ||
|
| + bitmap_result.pixel_size.width() == request->desired_size_in_pixel)
|
| + 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))
|
| + return false;
|
| +
|
| + SkBitmap bitmap = skia::ImageOperations::Resize(
|
| + decoded_bitmap, skia::ImageOperations::RESIZE_LANCZOS3,
|
| + request->desired_size_in_pixel, request->desired_size_in_pixel);
|
| +
|
| + std::vector<unsigned char> bitmap_data;
|
| + if (!gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, &bitmap_data))
|
| + return false;
|
| +
|
| + resized_bitmap_result->pixel_size =
|
| + gfx::Size(request->desired_size_in_pixel, request->desired_size_in_pixel);
|
| + resized_bitmap_result->bitmap_data =
|
| + base::RefCountedBytes::TakeVector(&bitmap_data);
|
| + return true;
|
| +}
|
| +
|
| +// Must run on a background thread in production.
|
| +// If |image| 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 ResizeImageOnBackgroundThreadIfValid(
|
| + LargeIconRequest* request,
|
| + const GURL& icon_url,
|
| + const gfx::Image image,
|
| + favicon_base::FaviconRawBitmapResult* resized_bitmap_result) {
|
| + // Require bitmap to be valid and square.
|
| + if (!image.IsEmpty() || image.Width() != image.Height())
|
| + return false;
|
| +
|
| + // Require bitmap to be large enough. It's square, so just check width.
|
| + if (image.Width() < request->min_source_size_in_pixel)
|
| + return false;
|
| +
|
| + SkBitmap bitmap = image.AsBitmap();
|
| +
|
| + // Resize if necessary.
|
| + if (request->desired_size_in_pixel != 0 &&
|
| + image.Width() != request->desired_size_in_pixel) {
|
| + bitmap = skia::ImageOperations::Resize(
|
| + bitmap, skia::ImageOperations::RESIZE_LANCZOS3,
|
| + request->desired_size_in_pixel, request->desired_size_in_pixel);
|
| + }
|
| +
|
| + std::vector<unsigned char> bitmap_data;
|
| + if (!gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, &bitmap_data))
|
| + return false;
|
| +
|
| + resized_bitmap_result->pixel_size =
|
| + gfx::Size(request->desired_size_in_pixel, request->desired_size_in_pixel);
|
| + resized_bitmap_result->bitmap_data =
|
| + base::RefCountedBytes::TakeVector(&bitmap_data);
|
| + resized_bitmap_result->expired = true;
|
| + resized_bitmap_result->icon_url = icon_url;
|
| + resized_bitmap_result->icon_type = favicon_base::IconType::TOUCH_ICON;
|
| +
|
| + return true;
|
| +}
|
| +
|
| +// Processes the bitmap data returned from a Google favicon server as part of a
|
| // LargeIconService request.
|
| -class LargeIconWorker : public base::RefCountedThreadSafe<LargeIconWorker> {
|
| +class LargeIconCacheWorker
|
| + : public base::RefCountedThreadSafe<LargeIconCacheWorker> {
|
| public:
|
| - LargeIconWorker(int min_source_size_in_pixel,
|
| - int desired_size_in_pixel,
|
| - favicon_base::LargeIconCallback callback,
|
| - scoped_refptr<base::TaskRunner> background_task_runner,
|
| - base::CancelableTaskTracker* tracker);
|
| + LargeIconCacheWorker(scoped_refptr<base::TaskRunner> background_task_runner);
|
| +
|
| + base::CancelableTaskTracker::TaskId Start(
|
| + base::CancelableTaskTracker* tracker,
|
| + FaviconService* favicon_service,
|
| + LargeIconRequest* request);
|
| +
|
| + private:
|
| + friend class base::RefCountedThreadSafe<LargeIconCacheWorker>;
|
| + ~LargeIconCacheWorker() = default;
|
|
|
| // Must run on the owner (UI) thread in production.
|
| // Intermediate callback for GetLargeIconOrFallbackStyle(). Invokes
|
| // ProcessIconOnBackgroundThread() so we do not perform complex image
|
| // operations on the UI thread.
|
| - void OnIconLookupComplete(
|
| + void OnCachedIconLookupComplete(
|
| + LargeIconRequest* request,
|
| const favicon_base::FaviconRawBitmapResult& bitmap_result);
|
|
|
| - private:
|
| - friend class base::RefCountedThreadSafe<LargeIconWorker>;
|
| -
|
| - ~LargeIconWorker();
|
| -
|
| // Must run on a background thread in production.
|
| - // Tries to resize |bitmap_result_| and pass the output to |callback_|. If
|
| + // Tries to resize |bitmap_result| and pass the output to |callback_|. If
|
| // 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();
|
| -
|
| - // 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);
|
| -
|
| - // Must run on the owner (UI) thread in production.
|
| - // Invoked when ProcessIconOnBackgroundThread() is done.
|
| - void OnIconProcessingComplete();
|
| + std::unique_ptr<favicon_base::LargeIconResult>
|
| + ProcessCachedIconOnBackgroundThread(
|
| + LargeIconRequest* request,
|
| + const favicon_base::FaviconRawBitmapResult& bitmap_result);
|
|
|
| - int min_source_size_in_pixel_;
|
| - int desired_size_in_pixel_;
|
| - favicon_base::LargeIconCallback callback_;
|
| scoped_refptr<base::TaskRunner> background_task_runner_;
|
| - base::CancelableTaskTracker* tracker_;
|
| - favicon_base::FaviconRawBitmapResult bitmap_result_;
|
| - std::unique_ptr<favicon_base::LargeIconResult> result_;
|
| + FaviconService* favicon_service_;
|
|
|
| - DISALLOW_COPY_AND_ASSIGN(LargeIconWorker);
|
| + DISALLOW_COPY_AND_ASSIGN(LargeIconCacheWorker);
|
| };
|
|
|
| -LargeIconWorker::LargeIconWorker(
|
| - int min_source_size_in_pixel,
|
| - int desired_size_in_pixel,
|
| - favicon_base::LargeIconCallback callback,
|
| +LargeIconCacheWorker::LargeIconCacheWorker(
|
| 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),
|
| - background_task_runner_(background_task_runner),
|
| - tracker_(tracker) {
|
| -}
|
| -
|
| -LargeIconWorker::~LargeIconWorker() {
|
| + FaviconService* favicon_service)
|
| + : background_task_runner_(background_task_runner),
|
| + favicon_service_(favicon_service) {}
|
| +
|
| +base::CancelableTaskTracker::TaskId LargeIconCacheWorker::Start(
|
| + base::CancelableTaskTracker* tracker,
|
| + LargeIconRequest* request) {
|
| + return favicon_service->GetRawFaviconForPageURL(
|
| + request->page_url,
|
| + favicon_base::IconType::FAVICON | favicon_base::IconType::TOUCH_ICON |
|
| + favicon_base::IconType::TOUCH_PRECOMPOSED_ICON,
|
| + request->desired_size_in_pixel,
|
| + base::Bind(&LargeIconCacheWorker::OnCachedIconLookupComplete, this,
|
| + request),
|
| + tracker);
|
| }
|
|
|
| -void LargeIconWorker::OnIconLookupComplete(
|
| +void LargeIconCacheWorker::OnCachedIconLookupComplete(
|
| + LargeIconRequest* request,
|
| const favicon_base::FaviconRawBitmapResult& bitmap_result) {
|
| - bitmap_result_ = bitmap_result;
|
| - tracker_->PostTaskAndReply(
|
| + // Prepare the data for the callback and run it.
|
| + base::PostTaskAndReplyWithResult(
|
| background_task_runner_.get(), FROM_HERE,
|
| - base::Bind(&LargeIconWorker::ProcessIconOnBackgroundThread, this),
|
| - base::Bind(&LargeIconWorker::OnIconProcessingComplete, this));
|
| + base::Bind(&LargeIconCacheWorker::ProcessCachedIconOnBackgroundThread,
|
| + this, request, bitmap_result),
|
| + base::Bind(&RunCallback, request->callback));
|
| }
|
|
|
| -void LargeIconWorker::ProcessIconOnBackgroundThread() {
|
| +std::unique_ptr<favicon_base::LargeIconResult>
|
| +LargeIconCacheWorker::ProcessCachedIconOnBackgroundThread(
|
| + LargeIconRequest* request,
|
| + const favicon_base::FaviconRawBitmapResult& bitmap_result) {
|
| favicon_base::FaviconRawBitmapResult resized_bitmap_result;
|
| - if (ResizeLargeIconOnBackgroundThreadIfValid(&resized_bitmap_result)) {
|
| - result_.reset(
|
| - new favicon_base::LargeIconResult(resized_bitmap_result));
|
| - } else {
|
| - // 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());
|
| - }
|
| - result_.reset(
|
| - new favicon_base::LargeIconResult(fallback_icon_style.release()));
|
| + bool create_bitmap = ResizeRawBitmapOnBackgroundThreadIfValid(
|
| + request, bitmap_result, &resized_bitmap_result);
|
| + return CreateLargeIconResult(&resized_bitmap_result, create_bitmap);
|
| +}
|
| +
|
| +// Processes the bitmap data returned from the FaviconService as part of a
|
| +// LargeIconService request.
|
| +class LargeIconGoogleServerWorker
|
| + : public base::RefCountedThreadSafe<LargeIconGoogleServerWorker> {
|
| + public:
|
| + LargeIconGoogleServerWorker(
|
| + scoped_refptr<base::TaskRunner> background_task_runner,
|
| + base::CancelableTaskTracker* tracker,
|
| + FaviconService* favicon_service,
|
| + ImageFetcher* image_fetcher);
|
| +
|
| + base::CancelableTaskTracker::TaskId Start(LargeIconRequest* request);
|
| +
|
| + private:
|
| + friend class base::RefCountedThreadSafe<LargeIconGoogleServerWorker>;
|
| + ~LargeIconGoogleServerWorker() = default;
|
| +
|
| + // Create the GET URL that requests the desired favicon from a Google favicon
|
| + // server (version 1 / version 2).
|
| + GURL GetIconUrlForGoogleServer1(LargeIconRequest* request) const;
|
| + GURL GetIconUrlForGoogleServer2(LargeIconRequest* request) const;
|
| +
|
| + // Fetches an icon for the given |icon_url| and stores it in the favicon DB.
|
| + void FetchIconFromGoogleServer(LargeIconRequest* request,
|
| + const GURL& icon_url);
|
| + void OnFetchIconFromGoogleServerComplete(LargeIconRequest* request,
|
| + const std::string& icon_url,
|
| + const gfx::Image& image);
|
| +
|
| + void ProcessIconFromGoogleServerOnBackgroundThread(LargeIconRequest* request,
|
| + const GURL& icon_url,
|
| + const gfx::Image& image);
|
| +
|
| + scoped_refptr<base::TaskRunner> background_task_runner_;
|
| + FaviconService* favicon_service_;
|
| + ImageFetcher* image_fetcher_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(LargeIconGoogleServerWorker);
|
| +};
|
| +
|
| +LargeIconGoogleServerWorker::LargeIconGoogleServerWorker(
|
| + scoped_refptr<base::TaskRunner> background_task_runner,
|
| + FaviconService* favicon_service,
|
| + ImageFetcher* image_fetcher)
|
| + : background_task_runner_(background_task_runner),
|
| + favicon_service_(favicon_service),
|
| + image_fetcher_(image_fetcher) {}
|
| +
|
| +base::CancelableTaskTracker::TaskId LargeIconGoogleServerWorker::Start(
|
| + base::CancelableTaskTracker* tracker,
|
| + LargeIconRequest* request) {
|
| + GURL server_url;
|
| + if (base::FeatureList::IsEnabled(kFaviconFetchLargeIconFromGoogleServer2)) {
|
| + server_url = GetIconUrlForGoogleServer2(request);
|
| + } else if (request->min_source_size_in_pixel <= 16 &&
|
| + base::FeatureList::IsEnabled(
|
| + kFaviconFetchLargeIconFromGoogleServer1)) {
|
| + // Server 1 cannot guarantee that the served icon has original size >=16px
|
| + // as it upscales images to fill in empty spots for missing sizes (32px,
|
| + // 64px) when indexing.
|
| + server_url = GetIconUrlForGoogleServer1(request);
|
| }
|
| +
|
| + DLOG(WARNING) << "large min " << min_source_size_in_pixel_ << " url "
|
| + << page_url_.spec();
|
| + DLOG(WARNING) << "large server " << server_url.spec();
|
| +
|
| + // Run on the current thread as this is needed for posting the I/O task.
|
| + return tracker->PostTask(
|
| + base::ThreadTaskRunnerHandle::Get().get(), FROM_HERE,
|
| + base::Bind(&LargeIconGoogleServerWorker::FetchIconFromGoogleServer, this,
|
| + request, server_url));
|
| }
|
|
|
| -bool LargeIconWorker::ResizeLargeIconOnBackgroundThreadIfValid(
|
| - favicon_base::FaviconRawBitmapResult* resized_bitmap_result) {
|
| - // Require bitmap to be valid and square.
|
| - if (!bitmap_result_.is_valid() ||
|
| - bitmap_result_.pixel_size.width() != bitmap_result_.pixel_size.height())
|
| - return false;
|
| +GURL LargeIconGoogleServerWorker::GetIconUrlForGoogleServer1(
|
| + LargeIconRequest* request) const {
|
| + return GURL(base::StringPrintf(kGoogleServer1RequestFormat,
|
| + request->page_url.spec().c_str(),
|
| + kGoogleServer1DesiredSizeInPixel));
|
| +}
|
|
|
| - // Require bitmap to be large enough. It's square, so just check width.
|
| - if (bitmap_result_.pixel_size.width() < min_source_size_in_pixel_)
|
| - return false;
|
| +GURL LargeIconGoogleServerWorker::GetIconUrlForGoogleServer2(
|
| + LargeIconRequest* request) const {
|
| + // TODO(jkrcal): make the desired/min/max sizes depend on the device (its
|
| + // scale factor, etc).
|
| + return GURL(base::StringPrintf(
|
| + kGoogleServer2RequestFormat, request->page_url.spec().c_str(),
|
| + kGoogleServer2DesiredSizeInPixel, kGoogleServer2MinSizeInPixel,
|
| + kGoogleServer2MaxSizeInPixel));
|
| +}
|
|
|
| - *resized_bitmap_result = bitmap_result_;
|
| +void LargeIconGoogleServerWorker::FetchIconFromGoogleServer(
|
| + LargeIconRequest* request,
|
| + const GURL& icon_url) {
|
| + if (icon_url.is_empty() // Do not fetch if fetching is disabled.
|
| + || favicon_service_->WasUnableToDownloadFavicon(icon_url)
|
| + // Do not retry if there is a previous cache miss recorded for |icon_url|.
|
| + ) {
|
| + DLOG(WARNING) << "large server fetch cannot proceed " << icon_url;
|
| + CreateLargeIconResult(nullptr, /*create_bitmap=*/false);
|
| + RunCallback();
|
| + return;
|
| + }
|
|
|
| - // Special case: Can use |bitmap_result_| as is.
|
| - if (desired_size_in_pixel_ == 0 ||
|
| - bitmap_result_.pixel_size.width() == desired_size_in_pixel_)
|
| - return true;
|
| + image_fetcher_->SetDataUseServiceName(
|
| + data_use_measurement::DataUseUserData::LARGE_ICON_SERVICE);
|
| + image_fetcher_->StartOrQueueNetworkRequest(
|
| + icon_url.spec(), icon_url,
|
| + base::Bind(
|
| + &LargeIconGoogleServerWorker::OnFetchIconFromGoogleServerComplete,
|
| + this, request));
|
| +}
|
|
|
| - // 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))
|
| - return false;
|
| +void LargeIconGoogleServerWorker::OnFetchIconFromGoogleServerComplete(
|
| + LargeIconRequest* request,
|
| + const std::string& icon_url,
|
| + const gfx::Image& image) {
|
| + if (image.IsEmpty()) {
|
| + DLOG(WARNING) << "large server fetch empty " << icon_url;
|
| + favicon_service_->UnableToDownloadFavicon(GURL(icon_url));
|
| + CreateLargeIconResult(nullptr, /*create_bitmap=*/false);
|
| + RunCallback();
|
| + return;
|
| + }
|
| + DLOG(WARNING) << "large server fetch successful " << icon_url << " "
|
| + << image.Width();
|
|
|
| - SkBitmap resized_bitmap = skia::ImageOperations::Resize(
|
| - decoded_bitmap, skia::ImageOperations::RESIZE_LANCZOS3,
|
| - desired_size_in_pixel_, desired_size_in_pixel_);
|
| + // TODO(jkrcal): Extract the original icon url from the response headers if
|
| + // available and use it instead of |icon_url|.
|
|
|
| - std::vector<unsigned char> bitmap_data;
|
| - if (!gfx::PNGCodec::EncodeBGRASkBitmap(resized_bitmap, false, &bitmap_data))
|
| - return false;
|
| + // TODO(jkrcal): never overwrite favicons. Fix in this CL!
|
| + favicon_service_->SetFavicons(request->page_url, GURL(icon_url),
|
| + favicon_base::IconType::TOUCH_ICON, image);
|
| + // Mark the icons as out-of-date so that they are refetched when we visit the
|
| + // original page any time in the future.
|
| + favicon_service_->SetFaviconOutOfDateForPage(request->page_url);
|
|
|
| - resized_bitmap_result->pixel_size =
|
| - gfx::Size(desired_size_in_pixel_, desired_size_in_pixel_);
|
| - resized_bitmap_result->bitmap_data =
|
| - base::RefCountedBytes::TakeVector(&bitmap_data);
|
| - return true;
|
| + base::PostTaskAndReplyWithResult(
|
| + background_task_runner_.get(), FROM_HERE,
|
| + base::Bind(&LargeIconGoogleServerWorker::
|
| + ProcessIconFromGoogleServerOnBackgroundThread,
|
| + this, request, GURL(icon_url), image),
|
| + base::Bind(&RunCallback, this, request->callback));
|
| }
|
|
|
| -void LargeIconWorker::OnIconProcessingComplete() {
|
| - callback_.Run(*result_);
|
| +void LargeIconGoogleServerWorker::ProcessIconFromGoogleServerOnBackgroundThread(
|
| + LargeIconRequest* request,
|
| + const GURL& icon_url,
|
| + const gfx::Image& image) {
|
| + favicon_base::FaviconRawBitmapResult resized_bitmap_result;
|
| + bool create_bitmap = ResizeImageOnBackgroundThreadIfValid(
|
| + request, icon_url, image, &resized_bitmap_result);
|
| + return CreateLargeIconResult(&resized_bitmap_result, create_bitmap);
|
| }
|
|
|
| } // namespace
|
|
|
| -namespace favicon {
|
| -
|
| LargeIconService::LargeIconService(
|
| FaviconService* favicon_service,
|
| - const scoped_refptr<base::TaskRunner>& background_task_runner)
|
| + const scoped_refptr<base::TaskRunner>& background_task_runner,
|
| + std::unique_ptr<image_fetcher::ImageFetcher> image_fetcher)
|
| : favicon_service_(favicon_service),
|
| - background_task_runner_(background_task_runner) {
|
| - large_icon_types_.push_back(favicon_base::IconType::FAVICON);
|
| - large_icon_types_.push_back(favicon_base::IconType::TOUCH_ICON);
|
| - large_icon_types_.push_back(favicon_base::IconType::TOUCH_PRECOMPOSED_ICON);
|
| -}
|
| + background_task_runner_(background_task_runner),
|
| + image_fetcher_(std::move(image_fetcher)) {}
|
|
|
| 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) {
|
| - DCHECK_LE(1, min_source_size_in_pixel);
|
| +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) {
|
| + DCHECK_LE(0, 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);
|
| -
|
| - // 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);
|
| + std::unique_ptr<LargeIconRequest> request =
|
| + base::MakeUnique<favicon_base::FallbackIconStyle>(
|
| + page_url, min_source_size_in_pixel, desired_size_in_pixel, callback);
|
| +
|
| + scoped_refptr<LargeIconCacheWorker> worker =
|
| + new LargeIconCacheWorker(background_task_runner_);
|
| + return worker->Start(tracker, favicon_service_, request.get());
|
| +}
|
| +
|
| +base::CancelableTaskTracker::TaskId
|
| +LargeIconService::GetLargeIconOrFallbackStyleFromGoogleServerSkippingLocalCache(
|
| + const GURL& page_url,
|
| + int min_source_size_in_pixel,
|
| + int desired_size_in_pixel,
|
| + const favicon_base::LargeIconCallback& callback,
|
| + base::CancelableTaskTracker* tracker) {
|
| + DCHECK_LE(0, min_source_size_in_pixel);
|
| + DCHECK_LE(0, desired_size_in_pixel);
|
| +
|
| + std::unique_ptr<LargeIconRequest> request =
|
| + base::MakeUnique<favicon_base::FallbackIconStyle>(
|
| + page_url, min_source_size_in_pixel, desired_size_in_pixel, callback);
|
| +
|
| + scoped_refptr<LargeIconGoogleServerWorker> worker =
|
| + new LargeIconGoogleServerWorker(background_task_runner_, tracker,
|
| + favicon_service_, image_fetcher_.get());
|
| + return worker->Start(request.get());
|
| }
|
|
|
| } // namespace favicon
|
|
|