diff options
-rw-r--r-- | chrome/browser/favicon/large_icon_service_factory.cc | 46 | ||||
-rw-r--r-- | chrome/browser/favicon/large_icon_service_factory.h | 43 | ||||
-rw-r--r-- | chrome/browser/search/instant_service.cc | 14 | ||||
-rw-r--r-- | chrome/browser/ui/webui/large_icon_source.cc | 105 | ||||
-rw-r--r-- | chrome/browser/ui/webui/large_icon_source.h | 60 | ||||
-rw-r--r-- | chrome/browser/ui/webui/ntp/most_visited_handler.cc | 17 | ||||
-rw-r--r-- | chrome/chrome_browser.gypi | 2 | ||||
-rw-r--r-- | chrome/common/favicon/fallback_icon_url_parser_unittest.cc | 10 | ||||
-rw-r--r-- | components/favicon.gypi | 2 | ||||
-rw-r--r-- | components/favicon/core/BUILD.gn | 2 | ||||
-rw-r--r-- | components/favicon/core/large_icon_service.cc | 77 | ||||
-rw-r--r-- | components/favicon/core/large_icon_service.h | 65 | ||||
-rw-r--r-- | components/favicon_base/fallback_icon_style.cc | 34 | ||||
-rw-r--r-- | components/favicon_base/fallback_icon_style.h | 8 | ||||
-rw-r--r-- | components/favicon_base/favicon_callback.h | 6 | ||||
-rw-r--r-- | components/favicon_base/favicon_types.cc | 12 | ||||
-rw-r--r-- | components/favicon_base/favicon_types.h | 19 |
17 files changed, 371 insertions, 151 deletions
diff --git a/chrome/browser/favicon/large_icon_service_factory.cc b/chrome/browser/favicon/large_icon_service_factory.cc new file mode 100644 index 0000000..56890cb --- /dev/null +++ b/chrome/browser/favicon/large_icon_service_factory.cc @@ -0,0 +1,46 @@ +// Copyright 2015 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 "chrome/browser/favicon/large_icon_service_factory.h" + +#include "base/memory/singleton.h" +#include "chrome/browser/favicon/favicon_service_factory.h" +#include "chrome/browser/profiles/profile.h" +#include "components/favicon/core/favicon_service.h" +#include "components/favicon/core/large_icon_service.h" +#include "components/keyed_service/content/browser_context_dependency_manager.h" +#include "content/public/browser/browser_context.h" + +// static +favicon::LargeIconService* LargeIconServiceFactory::GetForBrowserContext( + content::BrowserContext* context) { + return static_cast<favicon::LargeIconService*>( + GetInstance()->GetServiceForBrowserContext(context, true)); +} + +// static +LargeIconServiceFactory* LargeIconServiceFactory::GetInstance() { + return Singleton<LargeIconServiceFactory>::get(); +} + +LargeIconServiceFactory::LargeIconServiceFactory() + : BrowserContextKeyedServiceFactory( + "LargeIconService", + BrowserContextDependencyManager::GetInstance()) { + DependsOn(FaviconServiceFactory::GetInstance()); +} + +LargeIconServiceFactory::~LargeIconServiceFactory() {} + +KeyedService* LargeIconServiceFactory::BuildServiceInstanceFor( + content::BrowserContext* context) const { + favicon::FaviconService* favicon_service = + FaviconServiceFactory::GetForProfile(Profile::FromBrowserContext(context), + ServiceAccessType::EXPLICIT_ACCESS); + return new favicon::LargeIconService(favicon_service); +} + +bool LargeIconServiceFactory::ServiceIsNULLWhileTesting() const { + return true; +} diff --git a/chrome/browser/favicon/large_icon_service_factory.h b/chrome/browser/favicon/large_icon_service_factory.h new file mode 100644 index 0000000..46a9e5b --- /dev/null +++ b/chrome/browser/favicon/large_icon_service_factory.h @@ -0,0 +1,43 @@ +// Copyright 2015 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. + +#ifndef CHROME_BROWSER_FAVICON_LARGE_ICON_SERVICE_FACTORY_H_ +#define CHROME_BROWSER_FAVICON_LARGE_ICON_SERVICE_FACTORY_H_ + +#include "components/keyed_service/content/browser_context_keyed_service_factory.h" + +template <typename T> struct DefaultSingletonTraits; + +namespace content { +class BrowserContext; +} + +namespace favicon { +class LargeIconService; +} + +// Singleton that owns all LargeIconService and associates them with +// BrowserContext instances. +class LargeIconServiceFactory : public BrowserContextKeyedServiceFactory { + public: + static favicon::LargeIconService* GetForBrowserContext( + content::BrowserContext* context); + + static LargeIconServiceFactory* GetInstance(); + + private: + friend struct DefaultSingletonTraits<LargeIconServiceFactory>; + + LargeIconServiceFactory(); + ~LargeIconServiceFactory() override; + + // BrowserContextKeyedServiceFactory: + KeyedService* BuildServiceInstanceFor( + content::BrowserContext* context) const override; + bool ServiceIsNULLWhileTesting() const override; + + DISALLOW_COPY_AND_ASSIGN(LargeIconServiceFactory); +}; + +#endif // CHROME_BROWSER_FAVICON_LARGE_ICON_SERVICE_FACTORY_H_ diff --git a/chrome/browser/search/instant_service.cc b/chrome/browser/search/instant_service.cc index bf75e9a..573c415 100644 --- a/chrome/browser/search/instant_service.cc +++ b/chrome/browser/search/instant_service.cc @@ -6,7 +6,7 @@ #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/favicon/fallback_icon_service_factory.h" -#include "chrome/browser/favicon/favicon_service_factory.h" +#include "chrome/browser/favicon/large_icon_service_factory.h" #include "chrome/browser/history/top_sites_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/search/instant_io_context.h" @@ -25,7 +25,7 @@ #include "chrome/browser/ui/webui/theme_source.h" #include "chrome/common/render_messages.h" #include "components/favicon/core/fallback_icon_service.h" -#include "components/favicon/core/favicon_service.h" +#include "components/favicon/core/large_icon_service.h" #include "components/history/core/browser/top_sites.h" #include "components/keyed_service/core/service_access_type.h" #include "components/search_engines/template_url_service.h" @@ -118,18 +118,16 @@ InstantService::InstantService(Profile* profile) content::URLDataSource::Add(profile_, new ThumbnailListSource(profile_)); #endif // !defined(OS_ANDROID) - favicon::FaviconService* favicon_service = - FaviconServiceFactory::GetForProfile(profile_, - ServiceAccessType::EXPLICIT_ACCESS); favicon::FallbackIconService* fallback_icon_service = FallbackIconServiceFactory::GetForBrowserContext(profile_); - - content::URLDataSource::Add(profile_, - new LargeIconSource(favicon_service, fallback_icon_service)); + favicon::LargeIconService* large_icon_service = + LargeIconServiceFactory::GetForBrowserContext(profile_); content::URLDataSource::Add( profile_, new FallbackIconSource(fallback_icon_service)); content::URLDataSource::Add( profile_, new FaviconSource(profile_, FaviconSource::FAVICON)); + content::URLDataSource::Add( + profile_, new LargeIconSource(fallback_icon_service, large_icon_service)); content::URLDataSource::Add(profile_, new MostVisitedIframeSource()); content::URLDataSource::Add( profile_, new suggestions::SuggestionsSource(profile_)); diff --git a/chrome/browser/ui/webui/large_icon_source.cc b/chrome/browser/ui/webui/large_icon_source.cc index df1e285f..6c74b0e 100644 --- a/chrome/browser/ui/webui/large_icon_source.cc +++ b/chrome/browser/ui/webui/large_icon_source.cc @@ -4,53 +4,29 @@ #include "chrome/browser/ui/webui/large_icon_source.h" +#include <vector> + #include "base/memory/ref_counted_memory.h" #include "chrome/browser/search/instant_io_context.h" #include "chrome/common/favicon/large_icon_url_parser.h" #include "chrome/common/url_constants.h" #include "components/favicon/core/fallback_icon_service.h" -#include "components/favicon/core/favicon_service.h" +#include "components/favicon/core/large_icon_service.h" #include "components/favicon_base/fallback_icon_style.h" +#include "components/favicon_base/favicon_types.h" #include "net/url_request/url_request.h" -#include "third_party/skia/include/core/SkColor.h" -#include "ui/gfx/color_analysis.h" -#include "ui/gfx/color_utils.h" namespace { -const int kDefaultLargeIconSize = 96; const int kMaxLargeIconSize = 192; // Arbitrary bound to safeguard endpoint. -const double kMaxBackgroundLuminance = 0.67; -const SkColor kDarkGray = SkColorSetRGB(0x78, 0x78, 0x78); -const SkColor kTextColor = SK_ColorWHITE; -const SkColor kDefaultBackgroundColor = kDarkGray; - } // namespace -LargeIconSource::IconRequest::IconRequest() : size(kDefaultLargeIconSize) { -} - -LargeIconSource::IconRequest::IconRequest( - const content::URLDataSource::GotDataCallback& callback_in, - const GURL& url_in, - int size_in) - : callback(callback_in), - url(url_in), - size(size_in) { -} - -LargeIconSource::IconRequest::~IconRequest() { -} - LargeIconSource::LargeIconSource( - favicon::FaviconService* favicon_service, - favicon::FallbackIconService* fallback_icon_service) - : favicon_service_(favicon_service), - fallback_icon_service_(fallback_icon_service) { - 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); + favicon::FallbackIconService* fallback_icon_service, + favicon::LargeIconService* large_icon_service) + : fallback_icon_service_(fallback_icon_service), + large_icon_service_(large_icon_service) { } LargeIconSource::~LargeIconSource() { @@ -65,7 +41,7 @@ void LargeIconSource::StartDataRequest( int render_process_id, int render_frame_id, const content::URLDataSource::GotDataCallback& callback) { - if (!favicon_service_) { + if (!large_icon_service_) { SendNotFoundResponse(callback); return; } @@ -85,14 +61,12 @@ void LargeIconSource::StartDataRequest( return; } - favicon_service_->GetLargestRawFaviconForPageURL( + large_icon_service_->GetLargeIconOrFallbackStyle( url, - large_icon_types_, parser.size_in_pixels(), - base::Bind( - &LargeIconSource::OnIconDataAvailable, - base::Unretained(this), - IconRequest(callback, url, parser.size_in_pixels())), + base::Bind(&LargeIconSource::OnLargeIconDataAvailable, + base::Unretained(this), callback, url, + parser.size_in_pixels()), &cancelable_task_tracker_); } @@ -115,54 +89,25 @@ bool LargeIconSource::ShouldServiceRequest( return URLDataSource::ShouldServiceRequest(request); } -void LargeIconSource::OnIconDataAvailable( - const IconRequest& request, - const favicon_base::FaviconRawBitmapResult& bitmap_result) { - if (!bitmap_result.is_valid()) { - SendDefaultFallbackIcon(request); +void LargeIconSource::OnLargeIconDataAvailable( + const content::URLDataSource::GotDataCallback& callback, + const GURL& url, + int size, + const favicon_base::LargeIconResult& result) { + if (result.bitmap.is_valid()) { + callback.Run(result.bitmap.bitmap_data.get()); return; } - // If we found a bitmap, but it's smaller than the requested size, we - // generate a fallback using the dominant color from the too-small bitmap. - // We adjust the luminance of the background so we can put light text over it. - if (bitmap_result.pixel_size.width() < request.size || - bitmap_result.pixel_size.height() < request.size) { - SkColor background = - color_utils::CalculateKMeanColorOfPNG(bitmap_result.bitmap_data); - color_utils::HSL background_hsl; - color_utils::SkColorToHSL(background, &background_hsl); - background_hsl.l = std::min(background_hsl.l, kMaxBackgroundLuminance); - background = color_utils::HSLToSkColor(background_hsl, SK_AlphaOPAQUE); - - // Now we can construct the fallback icon. - SendFallbackIcon(request, kTextColor, background); - return; - } - - request.callback.Run(bitmap_result.bitmap_data.get()); -} - -void LargeIconSource::SendDefaultFallbackIcon(const IconRequest& request) { - SendFallbackIcon(request, kTextColor, kDefaultBackgroundColor); -} - -void LargeIconSource::SendFallbackIcon(const IconRequest& request, - SkColor text_color, - SkColor background_color) { - if (!fallback_icon_service_) { - SendNotFoundResponse(request.callback); + // Bitmap is invalid, use the fallback if service is available. + if (!fallback_icon_service_ || !result.fallback_icon_style) { + SendNotFoundResponse(callback); return; } - favicon_base::FallbackIconStyle style; - style.background_color = background_color; - style.text_color = text_color; - style.font_size_ratio = 0.44; - style.roundness = 0; // Square. Round corners can be applied by JavaScript. std::vector<unsigned char> bitmap_data = fallback_icon_service_->RenderFallbackIconBitmap( - request.url, request.size, style); - request.callback.Run(base::RefCountedBytes::TakeVector(&bitmap_data)); + url, size, *result.fallback_icon_style); + callback.Run(base::RefCountedBytes::TakeVector(&bitmap_data)); } void LargeIconSource::SendNotFoundResponse( diff --git a/chrome/browser/ui/webui/large_icon_source.h b/chrome/browser/ui/webui/large_icon_source.h index 05872d2..fb573ea 100644 --- a/chrome/browser/ui/webui/large_icon_source.h +++ b/chrome/browser/ui/webui/large_icon_source.h @@ -6,18 +6,19 @@ #define CHROME_BROWSER_UI_WEBUI_LARGE_ICON_SOURCE_H_ #include <string> -#include <vector> #include "base/memory/scoped_ptr.h" #include "base/task/cancelable_task_tracker.h" #include "components/favicon/core/fallback_icon_service.h" -#include "components/favicon_base/favicon_types.h" #include "content/public/browser/url_data_source.h" -#include "third_party/skia/include/core/SkColor.h" namespace favicon { class FallbackIconService; -class FaviconService; +class LargeIconService; +} + +namespace favicon_base { +struct LargeIconResult; } // LargeIconSource services explicit chrome:// requests for large icons. @@ -35,10 +36,10 @@ class FaviconService; // This requests a 48x48 large icon for http://www.google.com. class LargeIconSource : public content::URLDataSource { public: - // |favicon_service| and |fallback_icon_service| are owned by caller and may - // be null. - LargeIconSource(favicon::FaviconService* favicon_service, - favicon::FallbackIconService* fallback_icon_service); + // |fallback_icon_service| and |large_icon_service| are owned by caller and + // may be null. + LargeIconSource(favicon::FallbackIconService* fallback_icon_service, + favicon::LargeIconService* large_icon_service); ~LargeIconSource() override; @@ -53,34 +54,13 @@ class LargeIconSource : public content::URLDataSource { bool ShouldReplaceExistingSource() const override; bool ShouldServiceRequest(const net::URLRequest* request) const override; - protected: - struct IconRequest { - IconRequest(); - IconRequest(const content::URLDataSource::GotDataCallback& callback_in, - const GURL& path_in, - int size_in); - ~IconRequest(); - - content::URLDataSource::GotDataCallback callback; - GURL url; - int size; - }; - private: - // Callback for icon data retrieval request. - void OnIconDataAvailable( - const IconRequest& request, - const favicon_base::FaviconRawBitmapResult& bitmap_result); - - // Renders and sends a default fallback icon. This is used when there is no - // known text and/or foreground color to use for the generated icon (it - // defaults to a light text color on a dark gray background). - void SendDefaultFallbackIcon(const IconRequest& request); - - // Renders and sends a fallback icon using the given colors. - void SendFallbackIcon(const IconRequest& request, - SkColor text_color, - SkColor background_color); + // Called with results of large icon retrieval request. + void OnLargeIconDataAvailable( + const content::URLDataSource::GotDataCallback& callback, + const GURL& url, + int size, + const favicon_base::LargeIconResult& bitmap_result); // Returns null to trigger "Not Found" response. void SendNotFoundResponse( @@ -88,15 +68,11 @@ class LargeIconSource : public content::URLDataSource { base::CancelableTaskTracker cancelable_task_tracker_; - favicon::FaviconService* favicon_service_; - + // Owned by client. favicon::FallbackIconService* fallback_icon_service_; - // A pre-populated list of the types of icon files to consider when looking - // for the largest matching icon. - // Note: this is simply an optimization over populating an icon type vector - // on each request. - std::vector<int> large_icon_types_; + // Owned by client. + favicon::LargeIconService* large_icon_service_; DISALLOW_COPY_AND_ASSIGN(LargeIconSource); }; diff --git a/chrome/browser/ui/webui/ntp/most_visited_handler.cc b/chrome/browser/ui/webui/ntp/most_visited_handler.cc index cff19a6..e8e8a3f 100644 --- a/chrome/browser/ui/webui/ntp/most_visited_handler.cc +++ b/chrome/browser/ui/webui/ntp/most_visited_handler.cc @@ -21,7 +21,7 @@ #include "base/threading/thread.h" #include "base/values.h" #include "chrome/browser/favicon/fallback_icon_service_factory.h" -#include "chrome/browser/favicon/favicon_service_factory.h" +#include "chrome/browser/favicon/large_icon_service_factory.h" #include "chrome/browser/history/top_sites_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/thumbnails/thumbnail_list_source.h" @@ -38,7 +38,7 @@ #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" #include "components/favicon/core/fallback_icon_service.h" -#include "components/favicon/core/favicon_service.h" +#include "components/favicon/core/large_icon_service.h" #include "components/history/core/browser/page_usage_data.h" #include "components/history/core/browser/top_sites.h" #include "components/keyed_service/core/service_access_type.h" @@ -86,15 +86,12 @@ void MostVisitedHandler::RegisterMessages() { // Set up our sources for top-sites data. content::URLDataSource::Add(profile, new ThumbnailListSource(profile)); - favicon::FaviconService* favicon_service = - FaviconServiceFactory::GetForProfile(profile, - ServiceAccessType::EXPLICIT_ACCESS); favicon::FallbackIconService* fallback_icon_service = FallbackIconServiceFactory::GetForBrowserContext(profile); + favicon::LargeIconService* large_icon_service = + LargeIconServiceFactory::GetForBrowserContext(profile); - // Register chrome://large-icon as a data source for large icons. - content::URLDataSource::Add(profile, - new LargeIconSource(favicon_service, fallback_icon_service)); + // Register chrome://fallback-icon as a data source for fallback icons. content::URLDataSource::Add(profile, new FallbackIconSource(fallback_icon_service)); @@ -102,6 +99,10 @@ void MostVisitedHandler::RegisterMessages() { content::URLDataSource::Add( profile, new FaviconSource(profile, FaviconSource::FAVICON)); + // Register chrome://large-icon as a data source for large icons. + content::URLDataSource::Add( + profile, new LargeIconSource(fallback_icon_service, large_icon_service)); + scoped_refptr<history::TopSites> top_sites = TopSitesFactory::GetForProfile(profile); if (top_sites) { diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 82d534d..692ff72 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -1552,6 +1552,8 @@ 'browser/favicon/favicon_helper.h', 'browser/favicon/favicon_service_factory.cc', 'browser/favicon/favicon_service_factory.h', + 'browser/favicon/large_icon_service_factory.cc', + 'browser/favicon/large_icon_service_factory.h', ], 'chrome_browser_gnome_keyring_sources': [ 'browser/password_manager/native_backend_gnome_x.cc', diff --git a/chrome/common/favicon/fallback_icon_url_parser_unittest.cc b/chrome/common/favicon/fallback_icon_url_parser_unittest.cc index f22bb95..2d88f3e 100644 --- a/chrome/common/favicon/fallback_icon_url_parser_unittest.cc +++ b/chrome/common/favicon/fallback_icon_url_parser_unittest.cc @@ -20,11 +20,11 @@ namespace { // Default values for FallbackIconStyle, from // /components/favicon_base/fallback_icon_style.h -SkColor kDefaultBackgroundColor = SkColorSetRGB(0x80, 0x80, 0x80); -SkColor kDefaultTextColorDark = SK_ColorBLACK; -SkColor kDefaultTextColorLight = SK_ColorWHITE; -double kDefaultFontSizeRatio = 0.8; -double kDefaultRoundness = 0.125; // 1 / 8. +const SkColor kDefaultBackgroundColor = SkColorSetRGB(0x78, 0x78, 0x78); +const SkColor kDefaultTextColorDark = SK_ColorBLACK; +const SkColor kDefaultTextColorLight = SK_ColorWHITE; +const double kDefaultFontSizeRatio = 0.44; +const double kDefaultRoundness = 0; const char kTestUrlStr[] = "https://www.google.ca/imghp?hl=en&tab=wi"; diff --git a/components/favicon.gypi b/components/favicon.gypi index d150316..d2f9195 100644 --- a/components/favicon.gypi +++ b/components/favicon.gypi @@ -36,6 +36,8 @@ 'favicon/core/favicon_service.h', 'favicon/core/favicon_url.cc', 'favicon/core/favicon_url.h', + 'favicon/core/large_icon_service.cc', + 'favicon/core/large_icon_service.h', ], 'include_dirs': [ '..', diff --git a/components/favicon/core/BUILD.gn b/components/favicon/core/BUILD.gn index 7f9b762..f4e8a15e 100644 --- a/components/favicon/core/BUILD.gn +++ b/components/favicon/core/BUILD.gn @@ -19,6 +19,8 @@ static_library("core") { "favicon_service.h", "favicon_url.cc", "favicon_url.h", + "large_icon_service.cc", + "large_icon_service.h", ] deps = [ diff --git a/components/favicon/core/large_icon_service.cc b/components/favicon/core/large_icon_service.cc new file mode 100644 index 0000000..702761c --- /dev/null +++ b/components/favicon/core/large_icon_service.cc @@ -0,0 +1,77 @@ +// Copyright 2015 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/large_icon_service.h" + +#include "components/favicon/core/favicon_service.h" +#include "components/favicon_base/fallback_icon_style.h" +#include "components/favicon_base/favicon_types.h" + +namespace favicon { + +LargeIconService::LargeIconService(FaviconService* favicon_service) + : favicon_service_(favicon_service) { + 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); +} + +LargeIconService::~LargeIconService() { +} + +base::CancelableTaskTracker::TaskId + LargeIconService::GetLargeIconOrFallbackStyle( + const GURL& page_url, + int desired_size_in_pixel, + const favicon_base::LargeIconCallback& callback, + base::CancelableTaskTracker* 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_, + desired_size_in_pixel, + base::Bind(&LargeIconService::RunLargeIconCallback, + base::Unretained(this), callback, desired_size_in_pixel), + tracker); +} + +void LargeIconService::RunLargeIconCallback( + const favicon_base::LargeIconCallback& callback, + int desired_size_in_pixel, + const favicon_base::FaviconRawBitmapResult& bitmap_result) { + // If there are no bitmaps, return a result with an empty |bitmap| and a + // default |fallback_icon_style|. + favicon_base::LargeIconResult result; + if (!bitmap_result.is_valid()) { + callback.Run(result); + return; + } + + // If there is a bitmap but it's smaller than the requested size or + // non-square, compute its dominant color and use it as background in + // |fallback_icon_style|. + if (bitmap_result.pixel_size.width() < desired_size_in_pixel || + bitmap_result.pixel_size.height() < desired_size_in_pixel || + bitmap_result.pixel_size.width() != bitmap_result.pixel_size.height()) { + // TODO(beaudoin): Resize the icon if it's large enough. Alternatively, + // return it and let the HTML resize it. + result.fallback_icon_style.reset(new favicon_base::FallbackIconStyle()); + favicon_base::SetDominantColorAsBackground( + bitmap_result.bitmap_data, result.fallback_icon_style.get()); + callback.Run(result); + return; + } + + // The bitmap is square and at least as large as the requested one, return + // it. + // TODO(beaudoin): Resize the icon if it's too large. Alternatively, return + // it and let the HTML resize it. + result.bitmap = bitmap_result; + callback.Run(result); +} + +} // namespace favicon diff --git a/components/favicon/core/large_icon_service.h b/components/favicon/core/large_icon_service.h new file mode 100644 index 0000000..1063fd7 --- /dev/null +++ b/components/favicon/core/large_icon_service.h @@ -0,0 +1,65 @@ +// Copyright (c) 2015 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. + +#ifndef COMPONENTS_FAVICON_CORE_LARGE_ICON_SERVICE_H_ +#define COMPONENTS_FAVICON_CORE_LARGE_ICON_SERVICE_H_ + +#include <vector> + +#include "base/task/cancelable_task_tracker.h" +#include "components/favicon_base/favicon_callback.h" +#include "components/keyed_service/core/keyed_service.h" + +class GURL; + +namespace favicon_base { +struct FaviconRawBitmapResult; +} + +namespace favicon { + +class FaviconService; + +// The large icon service provides methods to access large icons. It relies on +// the favicon service. +class LargeIconService : public KeyedService { + public: + explicit LargeIconService(FaviconService* favicon_service); + + ~LargeIconService() override; + + // Requests the best large icon for the page at |page_url| given the requested + // |desired_size_in_pixel|. If no good large icon can be found, returns the + // fallback style to use, for which the background is set to the dominant + // color of a smaller icon when one is available. This function returns the + // style of the fallback icon rather than the rendered version so that clients + // can render the icon themselves. + base::CancelableTaskTracker::TaskId GetLargeIconOrFallbackStyle( + const GURL& page_url, + int desired_size_in_pixel, + const favicon_base::LargeIconCallback& callback, + base::CancelableTaskTracker* tracker); + + private: + // Intermediate callback for GetLargeIconOrFallbackStyle(). Ensures the large + // icon is at least the desired size, if not compute the icon fallback style + // and use it to invoke |callback|. + void RunLargeIconCallback( + const favicon_base::LargeIconCallback& callback, + int desired_size_in_pixel, + const favicon_base::FaviconRawBitmapResult& bitmap_result); + + FaviconService* favicon_service_; + + // A pre-populated list of the types of icon files to consider when looking + // for large icons. This is an optimization over populating an icon type + // vector on each request. + std::vector<int> large_icon_types_; + + DISALLOW_COPY_AND_ASSIGN(LargeIconService); +}; + +} // namespace favicon + +#endif // COMPONENTS_FAVICON_CORE_LARGE_ICON_SERVICE_H_ diff --git a/components/favicon_base/fallback_icon_style.cc b/components/favicon_base/fallback_icon_style.cc index e620613..d3e395b 100644 --- a/components/favicon_base/fallback_icon_style.cc +++ b/components/favicon_base/fallback_icon_style.cc @@ -4,6 +4,9 @@ #include "components/favicon_base/fallback_icon_style.h" +#include <algorithm> + +#include "ui/gfx/color_analysis.h" #include "ui/gfx/color_utils.h" namespace favicon_base { @@ -12,14 +15,19 @@ namespace { // Luminance threshold for background color determine whether to use dark or // light text color. -int kDarkTextLuminanceThreshold = 190; +const int kDarkTextLuminanceThreshold = 190; + +// The maximum luminance of the background color to ensure light text is +// readable. +const double kMaxBackgroundColorLuminance = 0.67; // Default values for FallbackIconStyle. -SkColor kDefaultBackgroundColor = SkColorSetRGB(0x80, 0x80, 0x80); -SkColor kDefaultTextColorDark = SK_ColorBLACK; -SkColor kDefaultTextColorLight = SK_ColorWHITE; -double kDefaultFontSizeRatio = 0.8; -double kDefaultRoundness = 0.125; // 1 / 8. +const SkColor kDefaultBackgroundColor = SkColorSetRGB(0x78, 0x78, 0x78); +const SkColor kDefaultTextColorDark = SK_ColorBLACK; +const SkColor kDefaultTextColorLight = SK_ColorWHITE; +const double kDefaultFontSizeRatio = 0.44; +const double kDefaultRoundness = 0; // Square. Round corners are applied + // externally (Javascript or Java). } // namespace @@ -45,4 +53,18 @@ bool ValidateFallbackIconStyle(const FallbackIconStyle& style) { style.roundness >= 0.0 && style.roundness <= 1.0; } +void SetDominantColorAsBackground( + const scoped_refptr<base::RefCountedMemory>& bitmap_data, + FallbackIconStyle* style) { + SkColor dominant_color = + color_utils::CalculateKMeanColorOfPNG(bitmap_data); + // Assumes |style.text_color| is light, and clamps luminance down to a + // reasonable maximum value so text is readable. + color_utils::HSL color_hsl; + color_utils::SkColorToHSL(dominant_color, &color_hsl); + color_hsl.l = std::min(color_hsl.l, kMaxBackgroundColorLuminance); + style->background_color = + color_utils::HSLToSkColor(color_hsl, SK_AlphaOPAQUE); +} + } // namespace favicon_base diff --git a/components/favicon_base/fallback_icon_style.h b/components/favicon_base/fallback_icon_style.h index 097636b..84842ed 100644 --- a/components/favicon_base/fallback_icon_style.h +++ b/components/favicon_base/fallback_icon_style.h @@ -5,6 +5,7 @@ #ifndef COMPONENTS_FAVICON_BASE_FALLBACK_ICON_STYLE_H_ #define COMPONENTS_FAVICON_BASE_FALLBACK_ICON_STYLE_H_ +#include "base/memory/ref_counted_memory.h" #include "third_party/skia/include/core/SkColor.h" namespace favicon_base { @@ -37,6 +38,13 @@ void MatchFallbackIconTextColorAgainstBackgroundColor(FallbackIconStyle* style); // Returns whether |style| values are within bounds. bool ValidateFallbackIconStyle(const FallbackIconStyle& style); +// Set |style|'s background color to the dominant color of |bitmap_data|, +// clamping luminance down to a reasonable maximum value so that light text is +// readable. +void SetDominantColorAsBackground( + const scoped_refptr<base::RefCountedMemory>& bitmap_data, + FallbackIconStyle* style); + } // namespace favicon_base #endif // COMPONENTS_FAVICON_BASE_FALLBACK_ICON_STYLE_H_ diff --git a/components/favicon_base/favicon_callback.h b/components/favicon_base/favicon_callback.h index 7616a11..96029f1 100644 --- a/components/favicon_base/favicon_callback.h +++ b/components/favicon_base/favicon_callback.h @@ -13,6 +13,7 @@ namespace favicon_base { struct FaviconRawBitmapResult; struct FaviconImageResult; +struct LargeIconResult; // Callback for functions that can be used to return a |gfx::Image| and the // |GURL| it is loaded from. They are returned as a |FaviconImageResult| object. @@ -29,6 +30,11 @@ typedef base::Callback<void(const FaviconRawBitmapResult&)> typedef base::Callback<void(const std::vector<FaviconRawBitmapResult>&)> FaviconResultsCallback; +// Callback for functions returning data for a large icon. |LargeIconResult| +// will contain either the raw bitmap for a large icon or the style of the +// fallback to use if a sufficiently large icon could not be found. +typedef base::Callback<void(const LargeIconResult&)> LargeIconCallback; + } // namespace favicon_base #endif // COMPONENTS_FAVICON_BASE_FAVICON_CALLBACK_H_ diff --git a/components/favicon_base/favicon_types.cc b/components/favicon_base/favicon_types.cc index 0188f1e..e69f1d7 100644 --- a/components/favicon_base/favicon_types.cc +++ b/components/favicon_base/favicon_types.cc @@ -4,6 +4,8 @@ #include "components/favicon_base/favicon_types.h" +#include "components/favicon_base/fallback_icon_style.h" + namespace favicon_base { // --------------------------------------------------------- @@ -20,7 +22,13 @@ FaviconRawBitmapResult::FaviconRawBitmapResult() : expired(false), icon_type(INVALID_ICON) { } -FaviconRawBitmapResult::~FaviconRawBitmapResult() { -} +FaviconRawBitmapResult::~FaviconRawBitmapResult() {} + +// -------------------------------------------------------- +// LargeIconResult + +LargeIconResult::LargeIconResult() {} + +LargeIconResult::~LargeIconResult() {} } // namespace favicon_base diff --git a/components/favicon_base/favicon_types.h b/components/favicon_base/favicon_types.h index ea64754..f7c812a 100644 --- a/components/favicon_base/favicon_types.h +++ b/components/favicon_base/favicon_types.h @@ -6,12 +6,15 @@ #define COMPONENTS_FAVICON_BASE_FAVICON_TYPES_H_ #include "base/memory/ref_counted_memory.h" +#include "base/memory/scoped_ptr.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/image/image.h" #include "url/gurl.h" namespace favicon_base { +struct FallbackIconStyle; + typedef int64 FaviconID; // Defines the icon types. They are also stored in icon_type field of favicons @@ -72,6 +75,22 @@ struct FaviconRawBitmapResult { // HistoryBackend::SetFavicons(). typedef FaviconRawBitmapResult FaviconRawBitmapData; +// Result returned by LargeIconService::GetLargeIconOrFallbackStyle(). Contains +// either the bitmap data if the favicon database has a sufficiently large +// favicon bitmap and the style of the fallback icon otherwise. +struct LargeIconResult { + LargeIconResult(); + ~LargeIconResult(); + + // The bitmap from the favicon database if the database has a sufficiently + // large one. + FaviconRawBitmapResult bitmap; + + // The fallback icon style if a sufficiently large icon isn't available. This + // uses the dominant color of a smaller icon as the background if available. + scoped_ptr<FallbackIconStyle> fallback_icon_style; +}; + } // namespace favicon_base #endif // COMPONENTS_FAVICON_BASE_FAVICON_TYPES_H_ |