summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/favicon/large_icon_service_factory.cc46
-rw-r--r--chrome/browser/favicon/large_icon_service_factory.h43
-rw-r--r--chrome/browser/search/instant_service.cc14
-rw-r--r--chrome/browser/ui/webui/large_icon_source.cc105
-rw-r--r--chrome/browser/ui/webui/large_icon_source.h60
-rw-r--r--chrome/browser/ui/webui/ntp/most_visited_handler.cc17
-rw-r--r--chrome/chrome_browser.gypi2
-rw-r--r--chrome/common/favicon/fallback_icon_url_parser_unittest.cc10
-rw-r--r--components/favicon.gypi2
-rw-r--r--components/favicon/core/BUILD.gn2
-rw-r--r--components/favicon/core/large_icon_service.cc77
-rw-r--r--components/favicon/core/large_icon_service.h65
-rw-r--r--components/favicon_base/fallback_icon_style.cc34
-rw-r--r--components/favicon_base/fallback_icon_style.h8
-rw-r--r--components/favicon_base/favicon_callback.h6
-rw-r--r--components/favicon_base/favicon_types.cc12
-rw-r--r--components/favicon_base/favicon_types.h19
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_