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

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

Issue 2347173002: Extend FaviconService to support fetching favicons from a Google server (Closed)
Patch Set: Requiring minimum_size Created 4 years 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/favicon_service.cc
diff --git a/components/favicon/core/favicon_service.cc b/components/favicon/core/favicon_service.cc
index 57a29deaf5fe69c7250a85ef799d064bab7ffe7a..71cef81a9cdc75735fdc962121ac7a33561b087f 100644
--- a/components/favicon/core/favicon_service.cc
+++ b/components/favicon/core/favicon_service.cc
@@ -5,17 +5,20 @@
#include "components/favicon/core/favicon_service.h"
#include <stddef.h>
+#include <algorithm>
#include <cmath>
#include <utility>
#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 +28,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};
+
pkotwicz 2016/12/19 00:03:28 Perhaps GetClosestGoogleFaviconServerSupportedSize
jkrcal 2016/12/19 17:07:19 Done.
+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];
+}
+
pkotwicz 2016/12/19 00:03:28 How about: GetGoogleFaviconServerURLForPageURL()
jkrcal 2016/12/19 17:07:19 Done.
+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 +80,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 +231,30 @@ base::CancelableTaskTracker::TaskId FaviconService::GetFaviconForPageURL(
}
base::CancelableTaskTracker::TaskId
+FaviconService::GetRawFaviconForPageURLDownloadFromGoogleServerIfNeeded(
pkotwicz 2016/12/19 00:03:28 How about Get1xFaviconForPageURLDownloadFromGoogle
pkotwicz 2016/12/19 00:03:28 We should add a TODO to switch FaviconHelper#ensur
jkrcal 2016/12/19 17:07:19 Done.
+ const GURL& page_url,
+ int minimum_size_in_pixel,
+ int desired_size_in_pixel,
+ 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_pixel);
+ return GetFaviconForPageURLImpl(
+ page_url, favicon_base::IconType::FAVICON, desired_sizes_in_pixel,
+ base::Bind(&FaviconService::
+ RunFaviconImageCallbackOrDownloadFromGoogleFaviconServer,
+ base::Unretained(this), page_url, minimum_size_in_pixel,
+ desired_size_in_pixel, 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 +404,104 @@ void FaviconService::RunFaviconRawBitmapCallbackWithBitmapResults(
ResizeFaviconBitmapResult(favicon_bitmap_results, desired_size_in_pixel));
}
+void FaviconService::RunFaviconImageCallbackOrDownloadFromGoogleFaviconServer(
+ const GURL& page_url,
+ int minimum_size_in_pixel,
+ 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");
pkotwicz 2016/12/19 00:03:28 Shouldn't the second argument be "FaviconService::
jkrcal 2016/12/19 17:07:19 Sure, thanks!
+
+ // Ensure we do not get an icon upscaled from a smaller png than
+ // |minimum_size_in_pixel|.
+ int max_size_in_pixel = 0;
+ for (const auto& bitmap : favicon_bitmap_results) {
pkotwicz 2016/12/19 00:03:28 Can you make |max_size_in_pixel| a boolean and ear
jkrcal 2016/12/19 17:07:19 Done.
+ max_size_in_pixel =
+ std::max(max_size_in_pixel, std::max(bitmap.pixel_size_in_db.width(),
+ bitmap.pixel_size_in_db.height()));
+ }
+
+ // If there are some cached bitmaps but none is large enough, we cannot return
+ // any of them as the result and we also do not want to overwrite them by an
+ // icon from the Google server. Thus, return an empty result.
+ if (max_size_in_pixel > 0 && max_size_in_pixel < minimum_size_in_pixel) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
pkotwicz 2016/12/19 00:03:28 What's the reason for posting a task? It looks lik
jkrcal 2016/12/19 17:07:19 Ah, sure, thanks!
+ FROM_HERE, base::Bind(callback, favicon_base::FaviconImageResult()));
+ return;
+ }
+
+ gfx::Image image;
+ image = favicon_base::SelectFaviconFramesFromPNGs(
+ favicon_bitmap_results,
pkotwicz 2016/12/19 00:03:28 You should set the desired scale to be 1.0f and no
jkrcal 2016/12/19 17:07:19 Done.
+ {static_cast<float>(desired_size_in_pixel) / gfx::kFaviconSize},
+ gfx::kFaviconSize);
+
+ if (!image.IsEmpty()) {
+ // If a large enough cached bitmap is successfully rescaled, serve it!
+ 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 good enough favicon in the cache. Download it from the server.
+
+ if (!image_fetcher_.get()) {
pkotwicz 2016/12/19 00:03:28 You don't need to post a task
jkrcal 2016/12/19 17:07:19 Done.
+ // No fetcher available (e.g. in unittests), return an empty result.
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(callback, favicon_base::FaviconImageResult()));
+ return;
+ }
+
+ // TODO(jkrcal): When we use the other server backend, require
+ // |minimum_size_in_pixel|.
+ 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,
+ desired_size_in_pixel));
+}
+
+void FaviconService::StoreFaviconFromGoogleServiceAndRunFaviconImageCallback(
pkotwicz 2016/12/19 00:03:28 How about: StoreFaviconFromGoogleServerAndRunFavic
jkrcal 2016/12/19 17:07:19 Done.
+ const favicon_base::FaviconImageCallback& callback,
+ const GURL& page_url,
+ int desired_size_in_pixel,
+ const std::string& icon_url,
+ const gfx::Image& image) {
+ if (image.IsEmpty())
+ callback.Run(favicon_base::FaviconImageResult());
+
+ // Resize the icon to the desired size.
pkotwicz 2016/12/19 00:03:28 Nuke this comment. What ResizeBitmapByDownsampling
jkrcal 2016/12/19 17:07:19 Done.
+ SkBitmap icon = image.AsBitmap();
+ SkBitmap icon_resized = favicon_base::ResizeBitmapByDownsamplingIfPossible(
+ {icon}, desired_size_in_pixel);
+
+ favicon_base::FaviconImageResult image_result;
+ image_result.icon_url = GURL(icon_url);
+ image_result.image = gfx::Image::CreateFrom1xBitmap(icon_resized);
+ favicon_base::SetFaviconColorSpace(&image_result.image);
+ // Store the favicon in the cache.
pkotwicz 2016/12/19 00:03:28 Nuke this comment. What the function does should b
jkrcal 2016/12/19 17:07:19 Done.
+ 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
pkotwicz 2016/12/19 00:03:28 Nit: "them" -> "the icons"
+ // original page any time in the future.
+ SetFaviconOutOfDateForPage(page_url);
+
+ callback.Run(image_result);
+}
+
} // namespace favicon

Powered by Google App Engine
This is Rietveld 408576698