123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264 |
- // Copyright 2020 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 "weblayer/browser/favicon/favicon_service_impl.h"
- #include <stddef.h>
- #include <vector>
- #include "base/bind.h"
- #include "base/files/file_path.h"
- #include "base/hash/hash.h"
- #include "base/task/task_traits.h"
- #include "base/task/thread_pool.h"
- #include "build/build_config.h"
- #include "components/favicon_base/favicon_util.h"
- #include "components/favicon_base/select_favicon_frames.h"
- #include "content/public/common/url_constants.h"
- #include "third_party/skia/include/core/SkBitmap.h"
- #include "ui/gfx/favicon_size.h"
- #include "url/gurl.h"
- #include "weblayer/browser/favicon/favicon_backend_wrapper.h"
- #include "weblayer/browser/favicon/favicon_service_impl_observer.h"
- namespace weblayer {
- namespace {
- bool CanAddUrl(const GURL& url) {
- if (!url.is_valid())
- return false;
- if (url.SchemeIs(url::kJavaScriptScheme) || url.SchemeIs(url::kAboutScheme) ||
- url.SchemeIs(url::kContentScheme) ||
- url.SchemeIs(content::kChromeDevToolsScheme) ||
- url.SchemeIs(content::kChromeUIScheme) ||
- url.SchemeIs(content::kViewSourceScheme)) {
- return false;
- }
- return true;
- }
- // Returns the IconTypeSet for the current platform. This matches the set
- // of favicon types that are requested for the platform (see
- // FaviconDriverImpl).
- favicon_base::IconTypeSet GetIconTypeSet() {
- #if BUILDFLAG(IS_ANDROID)
- return {favicon_base::IconType::kFavicon, favicon_base::IconType::kTouchIcon,
- favicon_base::IconType::kTouchPrecomposedIcon,
- favicon_base::IconType::kWebManifestIcon};
- #else
- return {favicon_base::IconType::kFavicon};
- #endif
- }
- int GetDesiredFaviconSizeInDips() {
- #if BUILDFLAG(IS_ANDROID)
- // This is treatest as the largest available icon.
- return 0;
- #else
- return gfx::kFaviconSize;
- #endif
- }
- void OnGotFaviconsForPageUrl(
- int desired_size_in_dip,
- base::OnceCallback<void(gfx::Image)> callback,
- std::vector<favicon_base::FaviconRawBitmapResult> results) {
- favicon_base::FaviconImageResult image_result;
- image_result.image = favicon_base::SelectFaviconFramesFromPNGs(
- results, favicon_base::GetFaviconScales(), desired_size_in_dip);
- favicon_base::SetFaviconColorSpace(&image_result.image);
- std::move(callback).Run(image_result.image);
- }
- } // namespace
- FaviconServiceImpl::FaviconServiceImpl() = default;
- FaviconServiceImpl::~FaviconServiceImpl() {
- backend_task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(&FaviconBackendWrapper::Shutdown, std::move(backend_)));
- }
- void FaviconServiceImpl::Init(const base::FilePath& db_path) {
- if (!backend_task_runner_) {
- // BLOCK_SHUTDOWN matches that of HistoryService. It's done in hopes of
- // preventing database corruption.
- backend_task_runner_ = base::ThreadPool::CreateSequencedTaskRunner(
- {base::MayBlock(), base::WithBaseSyncPrimitives(),
- base::TaskPriority::USER_BLOCKING,
- base::TaskShutdownBehavior::BLOCK_SHUTDOWN});
- }
- backend_ = base::MakeRefCounted<FaviconBackendWrapper>(backend_task_runner_);
- backend_task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(&FaviconBackendWrapper::Init, backend_, db_path));
- }
- void FaviconServiceImpl::DeleteAndRecreateDatabase(base::OnceClosure callback) {
- backend_task_runner_->PostTaskAndReply(
- FROM_HERE,
- base::BindOnce(&FaviconBackendWrapper::DeleteAndRecreateDatabase,
- backend_),
- std::move(callback));
- }
- base::CancelableTaskTracker::TaskId FaviconServiceImpl::GetFaviconForPageUrl(
- const GURL& page_url,
- base::OnceCallback<void(gfx::Image)> callback,
- base::CancelableTaskTracker* tracker) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- // The arguments supplied to this function should return an image matching
- // that returned by FaviconFetcher.
- return tracker->PostTaskAndReplyWithResult(
- backend_task_runner_.get(), FROM_HERE,
- base::BindOnce(&FaviconBackendWrapper::GetFaviconsForUrl, backend_,
- page_url, GetIconTypeSet(),
- GetDesiredFaviconSizesInPixels()),
- base::BindOnce(&OnGotFaviconsForPageUrl, GetDesiredFaviconSizeInDips(),
- std::move(callback)));
- }
- base::CancelableTaskTracker::TaskId
- FaviconServiceImpl::GetLargestRawFaviconForPageURL(
- const GURL& page_url,
- const std::vector<favicon_base::IconTypeSet>& icon_types,
- int minimum_size_in_pixels,
- favicon_base::FaviconRawBitmapCallback callback,
- base::CancelableTaskTracker* tracker) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- return tracker->PostTaskAndReplyWithResult(
- backend_task_runner_.get(), FROM_HERE,
- base::BindOnce(&FaviconBackendWrapper::GetLargestFaviconForUrl, backend_,
- page_url, icon_types, minimum_size_in_pixels),
- std::move(callback));
- }
- base::CancelableTaskTracker::TaskId FaviconServiceImpl::GetFaviconForPageURL(
- const GURL& page_url,
- const favicon_base::IconTypeSet& icon_types,
- int desired_size_in_dip,
- favicon_base::FaviconResultsCallback callback,
- base::CancelableTaskTracker* tracker) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- return tracker->PostTaskAndReplyWithResult(
- backend_task_runner_.get(), FROM_HERE,
- base::BindOnce(&FaviconBackendWrapper::GetFaviconsForUrl, backend_,
- page_url, icon_types,
- GetPixelSizesForFaviconScales(desired_size_in_dip)),
- std::move(callback));
- }
- void FaviconServiceImpl::SetFaviconOutOfDateForPage(const GURL& page_url) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- backend_task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(&FaviconBackendWrapper::SetFaviconsOutOfDateForPage,
- backend_, page_url));
- }
- void FaviconServiceImpl::SetFavicons(const base::flat_set<GURL>& page_urls,
- const GURL& icon_url,
- favicon_base::IconType icon_type,
- const gfx::Image& image) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- base::flat_set<GURL> page_urls_to_save;
- page_urls_to_save.reserve(page_urls.capacity());
- for (const GURL& page_url : page_urls) {
- if (CanAddUrl(page_url))
- page_urls_to_save.insert(page_url);
- }
- if (page_urls_to_save.empty())
- return;
- backend_task_runner_->PostTask(
- FROM_HERE, base::BindOnce(&FaviconBackendWrapper::SetFavicons, backend_,
- page_urls_to_save, icon_type, icon_url,
- ExtractSkBitmapsToStore(image)));
- }
- void FaviconServiceImpl::CloneFaviconMappingsForPages(
- const GURL& page_url_to_read,
- const favicon_base::IconTypeSet& icon_types,
- const base::flat_set<GURL>& page_urls_to_write) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- backend_task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(&FaviconBackendWrapper::CloneFaviconMappingsForPages,
- backend_, page_url_to_read, icon_types,
- page_urls_to_write));
- }
- base::CancelableTaskTracker::TaskId FaviconServiceImpl::GetFavicon(
- const GURL& icon_url,
- favicon_base::IconType icon_type,
- int desired_size_in_dip,
- favicon_base::FaviconResultsCallback callback,
- base::CancelableTaskTracker* tracker) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- return tracker->PostTaskAndReplyWithResult(
- backend_task_runner_.get(), FROM_HERE,
- base::BindOnce(&FaviconBackendWrapper::GetFavicon, backend_, icon_url,
- icon_type,
- GetPixelSizesForFaviconScales(desired_size_in_dip)),
- std::move(callback));
- }
- base::CancelableTaskTracker::TaskId
- FaviconServiceImpl::UpdateFaviconMappingsAndFetch(
- const base::flat_set<GURL>& page_urls,
- const GURL& icon_url,
- favicon_base::IconType icon_type,
- int desired_size_in_dip,
- favicon_base::FaviconResultsCallback callback,
- base::CancelableTaskTracker* tracker) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- return tracker->PostTaskAndReplyWithResult(
- backend_task_runner_.get(), FROM_HERE,
- base::BindOnce(&FaviconBackendWrapper::UpdateFaviconMappingsAndFetch,
- backend_, page_urls, icon_url, icon_type,
- GetPixelSizesForFaviconScales(desired_size_in_dip)),
- std::move(callback));
- }
- void FaviconServiceImpl::DeleteFaviconMappings(
- const base::flat_set<GURL>& page_urls,
- favicon_base::IconType icon_type) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- backend_task_runner_->PostTask(
- FROM_HERE, base::BindOnce(&FaviconBackendWrapper::DeleteFaviconMappings,
- backend_, page_urls, icon_type));
- }
- void FaviconServiceImpl::UnableToDownloadFavicon(const GURL& icon_url) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- missing_favicon_urls_.insert(base::FastHash(icon_url.spec()));
- if (observer_)
- observer_->OnUnableToDownloadFavicon();
- }
- void FaviconServiceImpl::ClearUnableToDownloadFavicons() {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- missing_favicon_urls_.clear();
- }
- bool FaviconServiceImpl::WasUnableToDownloadFavicon(
- const GURL& icon_url) const {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- MissingFaviconUrlHash url_hash = base::FastHash(icon_url.spec());
- return missing_favicon_urls_.find(url_hash) != missing_favicon_urls_.end();
- }
- // static
- std::vector<int> FaviconServiceImpl::GetDesiredFaviconSizesInPixels() {
- return GetPixelSizesForFaviconScales(GetDesiredFaviconSizeInDips());
- }
- } // namespace weblayer
|