Chromium Code Reviews| Index: components/favicon/core/favicon_service.cc |
| diff --git a/components/favicon/core/favicon_service.cc b/components/favicon/core/favicon_service.cc |
| index 57a29deaf5fe69c7250a85ef799d064bab7ffe7a..e6f666882807ec95a043d9f61ccaf6b57075fbb4 100644 |
| --- a/components/favicon/core/favicon_service.cc |
| +++ b/components/favicon/core/favicon_service.cc |
| @@ -10,12 +10,14 @@ |
| #include "base/hash.h" |
| #include "base/single_thread_task_runner.h" |
| +#include "base/strings/stringprintf.h" |
| #include "base/threading/thread_task_runner_handle.h" |
| #include "base/trace_event/trace_event.h" |
| #include "components/favicon/core/favicon_client.h" |
| #include "components/favicon_base/favicon_util.h" |
| #include "components/favicon_base/select_favicon_frames.h" |
| #include "components/history/core/browser/history_service.h" |
| +#include "components/image_fetcher/image_fetcher.h" |
| #include "third_party/skia/include/core/SkBitmap.h" |
| #include "ui/gfx/codec/png_codec.h" |
| #include "ui/gfx/favicon_size.h" |
| @@ -25,6 +27,32 @@ |
| namespace favicon { |
| namespace { |
| +const char kGoogleFaviconServiceRequestFormat[] = |
| + "https://s2.googleusercontent.com/s2/" |
| + "favicons?domain=%s&src=%s&sz=%d&alt=404"; |
| + |
| +const int kGoogleFaviconServiceSupportedSizes[] = {16, 24, 32, 48, 64}; |
| + |
| +int GetGoogleFaviconServiceSupportedSize(int arbitrary_size) { |
| + // Take the smallest size larger than arbitrary_size. |
| + for (int size : kGoogleFaviconServiceSupportedSizes) { |
| + if (size >= arbitrary_size) |
| + return size; |
| + } |
| + // Or at least the largest available size. |
| + return kGoogleFaviconServiceSupportedSizes |
| + [arraysize(kGoogleFaviconServiceSupportedSizes) - 1]; |
| +} |
| + |
| +GURL GetGoogleFaviconServiceURL(GURL page_url, |
| + const std::string& client_id, |
| + int supported_size) { |
| + return GURL(base::StringPrintf(kGoogleFaviconServiceRequestFormat, |
| + page_url.spec().c_str(), |
| + client_id.c_str(), |
| + supported_size)); |
| +} |
| + |
| // Helper to run callback with empty results if we cannot get the history |
| // service. |
| base::CancelableTaskTracker::TaskId RunWithEmptyResultAsync( |
| @@ -51,10 +79,13 @@ std::vector<int> GetPixelSizesForFaviconScales(int size_in_dip) { |
| } // namespace |
| -FaviconService::FaviconService(std::unique_ptr<FaviconClient> favicon_client, |
| - history::HistoryService* history_service) |
| +FaviconService::FaviconService( |
| + std::unique_ptr<FaviconClient> favicon_client, |
| + history::HistoryService* history_service, |
| + std::unique_ptr<image_fetcher::ImageFetcher> image_fetcher) |
| : favicon_client_(std::move(favicon_client)), |
| - history_service_(history_service) {} |
| + history_service_(history_service), |
| + image_fetcher_(std::move(image_fetcher)) {} |
| FaviconService::~FaviconService() { |
| } |
| @@ -199,6 +230,30 @@ base::CancelableTaskTracker::TaskId FaviconService::GetFaviconForPageURL( |
| } |
| base::CancelableTaskTracker::TaskId |
| +FaviconService::GetRawFaviconForPageURLDownloadFromGoogleServerIfNeeded( |
| + const GURL& page_url, |
| + int minimum_size_in_pixels, |
| + int desired_size_in_pixels, |
| + std::string client_id, |
| + data_use_measurement::DataUseUserData::ServiceName data_use_service_name, |
| + const favicon_base::FaviconImageCallback& callback, |
| + base::CancelableTaskTracker* tracker) { |
| + TRACE_EVENT0("browser", |
| + "FaviconService::" |
| + "GetRawFaviconForPageURLDownloadFromGoogleServerIfNeeded"); |
| + std::vector<int> desired_sizes_in_pixel; |
| + desired_sizes_in_pixel.push_back(desired_size_in_pixels); |
| + return GetFaviconForPageURLImpl( |
| + page_url, favicon_base::IconType::FAVICON, desired_sizes_in_pixel, |
| + base::Bind(&FaviconService:: |
| + RunFaviconImageCallbackOrDownloadFromGoogleFaviconServer, |
| + base::Unretained(this), page_url, minimum_size_in_pixels, |
| + desired_size_in_pixels, client_id, data_use_service_name, |
| + callback), |
| + tracker); |
| +} |
| + |
| +base::CancelableTaskTracker::TaskId |
| FaviconService::UpdateFaviconMappingsAndFetch( |
| const GURL& page_url, |
| const std::vector<GURL>& icon_urls, |
| @@ -348,4 +403,83 @@ void FaviconService::RunFaviconRawBitmapCallbackWithBitmapResults( |
| ResizeFaviconBitmapResult(favicon_bitmap_results, desired_size_in_pixel)); |
| } |
| +void FaviconService::RunFaviconImageCallbackOrDownloadFromGoogleFaviconServer( |
| + const GURL& page_url, |
| + int minimum_size_in_pixels, |
| + int desired_size_in_pixel, |
| + std::string client_id, |
| + data_use_measurement::DataUseUserData::ServiceName data_use_service_name, |
| + const favicon_base::FaviconImageCallback& callback, |
| + const std::vector<favicon_base::FaviconRawBitmapResult>& |
| + favicon_bitmap_results) { |
| + TRACE_EVENT0( |
| + "browser", |
| + "FaviconService::DownloadFromGoogleServerFaviconImageForPageURL"); |
| + // TODO(jkrcal): Ensure we do not get an icon upscaled from a smaller png than |
| + // |minimum_size_in_pixels|. Is extending SelectFaviconFramesFromPNGs() the |
| + // simplest path? Or should I do it similarly to GetLargestRawFaviconForID()? |
|
jkrcal
2016/12/09 13:57:44
Peter, can you help me with this, please?
pkotwicz
2016/12/09 19:46:30
Things get complicated if you want to download a f
jkrcal
2016/12/14 15:18:50
I do not want to download anything in such a case.
pkotwicz
2016/12/15 01:22:27
I recomment adding FaviconRawBitmapResult::width_i
jkrcal
2016/12/15 18:17:27
Thanks for the hint!
When looking in the code, I
pkotwicz
2016/12/15 18:43:57
For the sake of clarity, I recommend adding width_
pkotwicz
2016/12/15 18:43:57
Sorry for the confusion.
FaviconRawBitmapResult::
jkrcal
2016/12/16 12:53:52
Thanks for the clarification!
I did not want to m
|
| + |
| + gfx::Image image = favicon_base::SelectFaviconFramesFromPNGs( |
| + favicon_bitmap_results, |
| + {static_cast<float>(desired_size_in_pixel) / gfx::kFaviconSize}, |
| + gfx::kFaviconSize); |
| + |
| + if (!image.IsEmpty()) { |
| + // Serve the favicon from the cache. |
| + favicon_base::FaviconImageResult image_result; |
| + image_result.image = image; |
| + favicon_base::SetFaviconColorSpace(&image_result.image); |
| + image_result.icon_url = favicon_bitmap_results[0].icon_url; |
| + callback.Run(image_result); |
| + return; |
| + } |
| + |
| + // No favicon in the cache. Download it from the server. |
| + |
| + if (!image_fetcher_.get()) { |
| + base::ThreadTaskRunnerHandle::Get()->PostTask( |
| + FROM_HERE, base::Bind(callback, favicon_base::FaviconImageResult())); |
| + return; |
| + } |
| + |
| + int supported_size = |
| + GetGoogleFaviconServiceSupportedSize(desired_size_in_pixel); |
| + GURL image_url = GetGoogleFaviconServiceURL(page_url, client_id, |
| + supported_size); |
| + |
| + image_fetcher_->SetDataUseServiceName(data_use_service_name); |
| + image_fetcher_->StartOrQueueNetworkRequest( |
| + image_url.spec(), image_url, |
| + base::Bind(&FaviconService:: |
| + StoreFaviconFromGoogleServiceAndRunFaviconImageCallback, |
| + base::Unretained(this), callback, page_url)); |
| +} |
| + |
| +void FaviconService::StoreFaviconFromGoogleServiceAndRunFaviconImageCallback( |
| + const favicon_base::FaviconImageCallback& callback, |
| + const GURL& page_url, |
| + const std::string& icon_url, |
| + const gfx::Image& image) { |
| + if (image.IsEmpty()) |
| + callback.Run(favicon_base::FaviconImageResult()); |
| + |
| + // TODO(jkrcal): No rescaling to desired_size_in_px. Should I fetch raw data |
| + // from ImageFetcher, construct |
| + // std::vector<favicon_base::FaviconRawBitmapResult> and use |
| + // SelectFaviconFramesFromPNGs(). |
|
jkrcal
2016/12/09 13:57:44
Peter, can you help me with this, please?
pkotwicz
2016/12/09 19:46:30
My understanding is that you are currently not res
jkrcal
2016/12/14 15:18:50
Sorry, the comment is a bit unclear :) Yes, I woul
pkotwicz
2016/12/15 01:22:27
You are right. Similar functions in FaviconService
jkrcal
2016/12/15 18:17:27
Done, thanks!
|
| + |
| + favicon_base::FaviconImageResult image_result; |
| + image_result.icon_url = GURL(icon_url); |
| + image_result.image = image; |
| + favicon_base::SetFaviconColorSpace(&image_result.image); |
| + // Store the favicon in the cache. |
| + SetFavicons(page_url, image_result.icon_url, |
| + favicon_base::IconType::FAVICON, image_result.image); |
| + // Mark them as out-of-date so that they are refetched when we visit the |
| + // original page any time in the future. |
| + SetFaviconOutOfDateForPage(page_url); |
| + |
| + callback.Run(image_result); |
| +} |
| + |
| } // namespace favicon |