Index: components/favicon/core/favicon_service_impl.cc |
diff --git a/components/favicon/core/favicon_service_impl.cc b/components/favicon/core/favicon_service_impl.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..a57c99e9ce2f2f23032ad4049aa7653ccae49337 |
--- /dev/null |
+++ b/components/favicon/core/favicon_service_impl.cc |
@@ -0,0 +1,295 @@ |
+// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "components/favicon/core/favicon_service_impl.h" |
+ |
+#include <stddef.h> |
+#include <cmath> |
+#include <utility> |
+ |
+#include "base/hash.h" |
+#include "base/single_thread_task_runner.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 "third_party/skia/include/core/SkBitmap.h" |
+#include "ui/gfx/codec/png_codec.h" |
+#include "ui/gfx/favicon_size.h" |
+#include "ui/gfx/image/image_skia.h" |
+#include "url/gurl.h" |
+ |
+namespace favicon { |
+namespace { |
+ |
+// Returns a vector of pixel edge sizes from |size_in_dip| and |
+// favicon_base::GetFaviconScales(). |
+std::vector<int> GetPixelSizesForFaviconScales(int size_in_dip) { |
+ std::vector<float> scales = favicon_base::GetFaviconScales(); |
+ std::vector<int> sizes_in_pixel; |
+ for (size_t i = 0; i < scales.size(); ++i) { |
+ sizes_in_pixel.push_back(std::ceil(size_in_dip * scales[i])); |
+ } |
+ return sizes_in_pixel; |
+} |
+ |
+} // namespace |
+ |
+FaviconServiceImpl::FaviconServiceImpl( |
+ std::unique_ptr<FaviconClient> favicon_client, |
+ history::HistoryService* history_service) |
+ : favicon_client_(std::move(favicon_client)), |
+ history_service_(history_service) { |
+ DCHECK(history_service_); |
+} |
+ |
+FaviconServiceImpl::~FaviconServiceImpl() {} |
+ |
+base::CancelableTaskTracker::TaskId FaviconServiceImpl::GetFaviconImage( |
+ const GURL& icon_url, |
+ const favicon_base::FaviconImageCallback& callback, |
+ base::CancelableTaskTracker* tracker) { |
+ TRACE_EVENT0("browser", "FaviconServiceImpl::GetFaviconImage"); |
+ favicon_base::FaviconResultsCallback callback_runner = |
+ base::Bind(&FaviconServiceImpl::RunFaviconImageCallbackWithBitmapResults, |
+ base::Unretained(this), callback, gfx::kFaviconSize); |
+ std::vector<GURL> icon_urls; |
+ icon_urls.push_back(icon_url); |
+ return history_service_->GetFavicons( |
+ icon_urls, favicon_base::FAVICON, |
+ GetPixelSizesForFaviconScales(gfx::kFaviconSize), callback_runner, |
+ tracker); |
+} |
+ |
+base::CancelableTaskTracker::TaskId FaviconServiceImpl::GetRawFavicon( |
+ const GURL& icon_url, |
+ favicon_base::IconType icon_type, |
+ int desired_size_in_pixel, |
+ const favicon_base::FaviconRawBitmapCallback& callback, |
+ base::CancelableTaskTracker* tracker) { |
+ TRACE_EVENT0("browser", "FaviconServiceImpl::GetRawFavicon"); |
+ favicon_base::FaviconResultsCallback callback_runner = base::Bind( |
+ &FaviconServiceImpl::RunFaviconRawBitmapCallbackWithBitmapResults, |
+ base::Unretained(this), callback, desired_size_in_pixel); |
+ |
+ std::vector<GURL> icon_urls; |
+ icon_urls.push_back(icon_url); |
+ std::vector<int> desired_sizes_in_pixel; |
+ desired_sizes_in_pixel.push_back(desired_size_in_pixel); |
+ |
+ return history_service_->GetFavicons( |
+ icon_urls, icon_type, desired_sizes_in_pixel, callback_runner, tracker); |
+} |
+ |
+base::CancelableTaskTracker::TaskId FaviconServiceImpl::GetFavicon( |
+ const GURL& icon_url, |
+ favicon_base::IconType icon_type, |
+ int desired_size_in_dip, |
+ const favicon_base::FaviconResultsCallback& callback, |
+ base::CancelableTaskTracker* tracker) { |
+ TRACE_EVENT0("browser", "FaviconServiceImpl::GetFavicon"); |
+ std::vector<GURL> icon_urls; |
+ icon_urls.push_back(icon_url); |
+ return history_service_->GetFavicons( |
+ icon_urls, icon_type, GetPixelSizesForFaviconScales(desired_size_in_dip), |
+ callback, tracker); |
+} |
+ |
+base::CancelableTaskTracker::TaskId |
+FaviconServiceImpl::GetFaviconImageForPageURL( |
+ const GURL& page_url, |
+ const favicon_base::FaviconImageCallback& callback, |
+ base::CancelableTaskTracker* tracker) { |
+ TRACE_EVENT0("browser", "FaviconServiceImpl::GetFaviconImageForPageURL"); |
+ return GetFaviconForPageURLImpl( |
+ page_url, favicon_base::FAVICON, |
+ GetPixelSizesForFaviconScales(gfx::kFaviconSize), |
+ base::Bind(&FaviconServiceImpl::RunFaviconImageCallbackWithBitmapResults, |
+ base::Unretained(this), callback, gfx::kFaviconSize), |
+ tracker); |
+} |
+ |
+base::CancelableTaskTracker::TaskId FaviconServiceImpl::GetRawFaviconForPageURL( |
+ const GURL& page_url, |
+ int icon_types, |
+ int desired_size_in_pixel, |
+ const favicon_base::FaviconRawBitmapCallback& callback, |
+ base::CancelableTaskTracker* tracker) { |
+ TRACE_EVENT0("browser", "FaviconServiceImpl::GetRawFaviconForPageURL"); |
+ std::vector<int> desired_sizes_in_pixel; |
+ desired_sizes_in_pixel.push_back(desired_size_in_pixel); |
+ return GetFaviconForPageURLImpl( |
+ page_url, icon_types, desired_sizes_in_pixel, |
+ base::Bind( |
+ &FaviconServiceImpl::RunFaviconRawBitmapCallbackWithBitmapResults, |
+ base::Unretained(this), callback, desired_size_in_pixel), |
+ tracker); |
+} |
+ |
+base::CancelableTaskTracker::TaskId |
+FaviconServiceImpl::GetLargestRawFaviconForPageURL( |
+ const GURL& page_url, |
+ const std::vector<int>& icon_types, |
+ int minimum_size_in_pixels, |
+ const favicon_base::FaviconRawBitmapCallback& callback, |
+ base::CancelableTaskTracker* tracker) { |
+ TRACE_EVENT0("browser", "FaviconServiceImpl::GetLargestRawFaviconForPageURL"); |
+ favicon_base::FaviconResultsCallback favicon_results_callback = base::Bind( |
+ &FaviconServiceImpl::RunFaviconRawBitmapCallbackWithBitmapResults, |
+ base::Unretained(this), callback, 0); |
+ if (favicon_client_ && favicon_client_->IsNativeApplicationURL(page_url)) { |
+ std::vector<int> desired_sizes_in_pixel; |
+ desired_sizes_in_pixel.push_back(0); |
+ return favicon_client_->GetFaviconForNativeApplicationURL( |
+ page_url, desired_sizes_in_pixel, favicon_results_callback, tracker); |
+ } |
+ return history_service_->GetLargestFaviconForURL( |
+ page_url, icon_types, minimum_size_in_pixels, callback, tracker); |
+} |
+ |
+base::CancelableTaskTracker::TaskId FaviconServiceImpl::GetFaviconForPageURL( |
+ const GURL& page_url, |
+ int icon_types, |
+ int desired_size_in_dip, |
+ const favicon_base::FaviconResultsCallback& callback, |
+ base::CancelableTaskTracker* tracker) { |
+ TRACE_EVENT0("browser", "FaviconServiceImpl::GetFaviconForPageURL"); |
+ return GetFaviconForPageURLImpl( |
+ page_url, icon_types, GetPixelSizesForFaviconScales(desired_size_in_dip), |
+ callback, tracker); |
+} |
+ |
+base::CancelableTaskTracker::TaskId |
+FaviconServiceImpl::UpdateFaviconMappingsAndFetch( |
+ const GURL& page_url, |
+ const std::vector<GURL>& icon_urls, |
+ int icon_types, |
+ int desired_size_in_dip, |
+ const favicon_base::FaviconResultsCallback& callback, |
+ base::CancelableTaskTracker* tracker) { |
+ return history_service_->UpdateFaviconMappingsAndFetch( |
+ page_url, icon_urls, icon_types, |
+ GetPixelSizesForFaviconScales(desired_size_in_dip), callback, tracker); |
+} |
+ |
+base::CancelableTaskTracker::TaskId |
+FaviconServiceImpl::GetLargestRawFaviconForID( |
+ favicon_base::FaviconID favicon_id, |
+ const favicon_base::FaviconRawBitmapCallback& callback, |
+ base::CancelableTaskTracker* tracker) { |
+ TRACE_EVENT0("browser", "FaviconServiceImpl::GetLargestRawFaviconForID"); |
+ // Use 0 as |desired_size| to get the largest bitmap for |favicon_id| without |
+ // any resizing. |
+ int desired_size = 0; |
+ favicon_base::FaviconResultsCallback callback_runner = base::Bind( |
+ &FaviconServiceImpl::RunFaviconRawBitmapCallbackWithBitmapResults, |
+ base::Unretained(this), callback, desired_size); |
+ |
+ return history_service_->GetFaviconForID(favicon_id, desired_size, |
+ callback_runner, tracker); |
+} |
+ |
+void FaviconServiceImpl::SetFaviconOutOfDateForPage(const GURL& page_url) { |
+ history_service_->SetFaviconsOutOfDateForPage(page_url); |
+} |
+ |
+void FaviconServiceImpl::SetImportedFavicons( |
+ const favicon_base::FaviconUsageDataList& favicon_usage) { |
+ history_service_->SetImportedFavicons(favicon_usage); |
+} |
+ |
+void FaviconServiceImpl::MergeFavicon( |
+ const GURL& page_url, |
+ const GURL& icon_url, |
+ favicon_base::IconType icon_type, |
+ scoped_refptr<base::RefCountedMemory> bitmap_data, |
+ const gfx::Size& pixel_size) { |
+ history_service_->MergeFavicon(page_url, icon_url, icon_type, bitmap_data, |
+ pixel_size); |
+} |
+ |
+void FaviconServiceImpl::SetFavicons(const GURL& page_url, |
+ const GURL& icon_url, |
+ favicon_base::IconType icon_type, |
+ const gfx::Image& image) { |
+ gfx::ImageSkia image_skia = image.AsImageSkia(); |
+ image_skia.EnsureRepsForSupportedScales(); |
+ const std::vector<gfx::ImageSkiaRep>& image_reps = image_skia.image_reps(); |
+ std::vector<SkBitmap> bitmaps; |
+ const std::vector<float> favicon_scales = favicon_base::GetFaviconScales(); |
+ for (size_t i = 0; i < image_reps.size(); ++i) { |
+ // Don't save if the scale isn't one of supported favicon scales. |
+ if (std::find(favicon_scales.begin(), favicon_scales.end(), |
+ image_reps[i].scale()) == favicon_scales.end()) { |
+ continue; |
+ } |
+ bitmaps.push_back(image_reps[i].sk_bitmap()); |
+ } |
+ history_service_->SetFavicons(page_url, icon_type, icon_url, bitmaps); |
+} |
+ |
+void FaviconServiceImpl::UnableToDownloadFavicon(const GURL& icon_url) { |
+ MissingFaviconURLHash url_hash = base::Hash(icon_url.spec()); |
+ missing_favicon_urls_.insert(url_hash); |
+} |
+ |
+bool FaviconServiceImpl::WasUnableToDownloadFavicon( |
+ const GURL& icon_url) const { |
+ MissingFaviconURLHash url_hash = base::Hash(icon_url.spec()); |
+ return missing_favicon_urls_.find(url_hash) != missing_favicon_urls_.end(); |
+} |
+ |
+void FaviconServiceImpl::ClearUnableToDownloadFavicons() { |
+ missing_favicon_urls_.clear(); |
+} |
+ |
+base::CancelableTaskTracker::TaskId |
+FaviconServiceImpl::GetFaviconForPageURLImpl( |
+ const GURL& page_url, |
+ int icon_types, |
+ const std::vector<int>& desired_sizes_in_pixel, |
+ const favicon_base::FaviconResultsCallback& callback, |
+ base::CancelableTaskTracker* tracker) { |
+ if (favicon_client_ && favicon_client_->IsNativeApplicationURL(page_url)) { |
+ return favicon_client_->GetFaviconForNativeApplicationURL( |
+ page_url, desired_sizes_in_pixel, callback, tracker); |
+ } |
+ return history_service_->GetFaviconsForURL( |
+ page_url, icon_types, desired_sizes_in_pixel, callback, tracker); |
+} |
+ |
+void FaviconServiceImpl::RunFaviconImageCallbackWithBitmapResults( |
+ const favicon_base::FaviconImageCallback& callback, |
+ int desired_size_in_dip, |
+ const std::vector<favicon_base::FaviconRawBitmapResult>& |
+ favicon_bitmap_results) { |
+ TRACE_EVENT0("browser", |
+ "FaviconServiceImpl::RunFaviconImageCallbackWithBitmapResults"); |
+ favicon_base::FaviconImageResult image_result; |
+ image_result.image = favicon_base::SelectFaviconFramesFromPNGs( |
+ favicon_bitmap_results, favicon_base::GetFaviconScales(), |
+ desired_size_in_dip); |
+ favicon_base::SetFaviconColorSpace(&image_result.image); |
+ |
+ image_result.icon_url = image_result.image.IsEmpty() |
+ ? GURL() |
+ : favicon_bitmap_results[0].icon_url; |
+ callback.Run(image_result); |
+} |
+ |
+void FaviconServiceImpl::RunFaviconRawBitmapCallbackWithBitmapResults( |
+ const favicon_base::FaviconRawBitmapCallback& callback, |
+ int desired_size_in_pixel, |
+ const std::vector<favicon_base::FaviconRawBitmapResult>& |
+ favicon_bitmap_results) { |
+ TRACE_EVENT0( |
+ "browser", |
+ "FaviconServiceImpl::RunFaviconRawBitmapCallbackWithBitmapResults"); |
+ callback.Run( |
+ ResizeFaviconBitmapResult(favicon_bitmap_results, desired_size_in_pixel)); |
+} |
+ |
+} // namespace favicon |