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

Unified Diff: chrome/browser/favicon/favicon_handler.cc

Issue 9810023: Prioritize smaller favicons over larger ones for tabs, etc. (Take 3) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Reset image_urls_ after processing last candidate. Created 8 years, 9 months 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
« no previous file with comments | « chrome/browser/favicon/favicon_handler.h ('k') | chrome/browser/favicon/favicon_handler_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/favicon/favicon_handler.cc
diff --git a/chrome/browser/favicon/favicon_handler.cc b/chrome/browser/favicon/favicon_handler.cc
index 52e429c28a6886e33307cd5758e0e3bb29ea12f3..1e6d8aa2e4341be9140a9b8b633fb7f190f6c290 100644
--- a/chrome/browser/favicon/favicon_handler.cc
+++ b/chrome/browser/favicon/favicon_handler.cc
@@ -51,6 +51,8 @@ bool DoUrlAndIconMatch(const FaviconURL& favicon_url,
} // namespace
+////////////////////////////////////////////////////////////////////////////////
+
FaviconHandler::DownloadRequest::DownloadRequest()
: icon_type(history::INVALID_ICON) {
}
@@ -69,6 +71,31 @@ FaviconHandler::DownloadRequest::DownloadRequest(
icon_type(icon_type) {
}
+////////////////////////////////////////////////////////////////////////////////
+
+FaviconHandler::FaviconCandidate::FaviconCandidate()
+ : bitmap_size(0),
+ icon_type(history::INVALID_ICON) {
+}
+
+FaviconHandler::FaviconCandidate::~FaviconCandidate() {
+}
+
+FaviconHandler::FaviconCandidate::FaviconCandidate(
+ const GURL& url,
+ const GURL& image_url,
+ const gfx::Image& image,
+ int bitmap_size,
+ history::IconType icon_type)
+ : url(url),
+ image_url(image_url),
+ image(image),
+ bitmap_size(bitmap_size),
+ icon_type(icon_type) {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
FaviconHandler::FaviconHandler(Profile* profile,
FaviconHandlerDelegate* delegate,
Type icon_type)
@@ -76,7 +103,6 @@ FaviconHandler::FaviconHandler(Profile* profile,
favicon_expired_(false),
icon_types_(icon_type == FAVICON ? history::FAVICON :
history::TOUCH_ICON | history::TOUCH_PRECOMPOSED_ICON),
- current_url_index_(0),
profile_(profile),
delegate_(delegate) {
DCHECK(profile_);
@@ -99,8 +125,6 @@ void FaviconHandler::FetchFavicon(const GURL& url) {
url_ = url;
favicon_expired_ = got_favicon_from_history_ = false;
- current_url_index_ = 0;
- urls_.clear();
// Request the favicon from the history service. In parallel to this the
// renderer is going to notify us (well TabContents) when the favicon url is
@@ -124,12 +148,47 @@ FaviconService* FaviconHandler::GetFaviconService() {
return profile_->GetFaviconService(Profile::EXPLICIT_ACCESS);
}
+bool FaviconHandler::UpdateFaviconCandidate(const GURL& url,
+ const GURL& image_url,
+ const gfx::Image& image,
+ history::IconType icon_type) {
+ bool update_candidate = false;
+ bool exact_match = false;
+ SkBitmap bitmap = *(image.ToSkBitmap());
+ int bitmap_size = std::max(bitmap.width(), bitmap.height());
+ if (preferred_icon_size() == 0) {
+ update_candidate = true;
+ exact_match = true;
+ } else if (favicon_candidate_.icon_type == history::INVALID_ICON) {
+ // No current candidate, use this.
+ update_candidate = true;
+ } else {
+ if (bitmap_size == preferred_icon_size()) {
+ // Exact match, use this.
+ update_candidate = true;
+ exact_match = true;
+ } else {
+ // Compare against current candidate.
+ int cur_size = favicon_candidate_.bitmap_size;
+ if ((bitmap_size >= preferred_icon_size() && bitmap_size < cur_size) ||
+ (cur_size < preferred_icon_size() && bitmap_size > cur_size)) {
+ update_candidate = true;
+ }
+ }
+ }
+ if (update_candidate) {
+ favicon_candidate_ = FaviconCandidate(
+ url, image_url, image, bitmap_size, icon_type);
+ }
+ return exact_match;
+}
+
void FaviconHandler::SetFavicon(
const GURL& url,
const GURL& image_url,
const gfx::Image& image,
history::IconType icon_type) {
- const SkBitmap& bitmap = image;
+ SkBitmap bitmap = *(image.ToSkBitmap());
const gfx::Image& sized_image = (preferred_icon_size() == 0 ||
(preferred_icon_size() == bitmap.width() &&
preferred_icon_size() == bitmap.height())) ?
@@ -143,8 +202,10 @@ void FaviconHandler::SetFavicon(
if (url == url_ && icon_type == history::FAVICON) {
NavigationEntry* entry = GetEntry();
- if (entry)
+ if (entry) {
+ entry->GetFavicon().url = image_url;
UpdateFavicon(entry, &sized_image);
+ }
}
}
@@ -170,32 +231,33 @@ void FaviconHandler::UpdateFavicon(NavigationEntry* entry,
void FaviconHandler::OnUpdateFaviconURL(
int32 page_id,
const std::vector<FaviconURL>& candidates) {
- NavigationEntry* entry = GetEntry();
- if (!entry)
- return;
- bool got_favicon_url_update = false;
+ image_urls_.clear();
+ favicon_candidate_ = FaviconCandidate();
for (std::vector<FaviconURL>::const_iterator i = candidates.begin();
i != candidates.end(); ++i) {
- if (!i->icon_url.is_empty() && (i->icon_type & icon_types_)) {
- if (!got_favicon_url_update) {
- got_favicon_url_update = true;
- urls_.clear();
- current_url_index_ = 0;
- }
- urls_.push_back(*i);
- }
+ if (!i->icon_url.is_empty() && (i->icon_type & icon_types_))
+ image_urls_.push_back(*i);
}
// TODO(davemoore) Should clear on empty url. Currently we ignore it.
// This appears to be what FF does as well.
- // No URL was added.
- if (!got_favicon_url_update)
+ if (image_urls_.empty())
return;
if (!GetFaviconService())
return;
+ ProcessCurrentUrl();
+}
+
+void FaviconHandler::ProcessCurrentUrl() {
+ DCHECK(!image_urls_.empty());
+
+ NavigationEntry* entry = GetEntry();
+ if (!entry)
+ return;
+
// For FAVICON.
if (current_candidate()->icon_type == FaviconURL::FAVICON) {
if (!favicon_expired_ && entry->GetFavicon().valid &&
@@ -235,13 +297,24 @@ void FaviconHandler::OnDidDownloadFavicon(int id,
i->second.icon_type)) {
// The downloaded icon is still valid when there is no FaviconURL update
// during the downloading.
+ bool request_next_icon = true;
if (!errored) {
- SetFavicon(i->second.url, image_url, image, i->second.icon_type);
- } else if (GetEntry() && ++current_url_index_ < urls_.size()) {
- // Copies all candidate except first one and notifies the FaviconHandler,
- // so the next candidate can be processed.
- std::vector<FaviconURL> new_candidates(urls_.begin() + 1, urls_.end());
- OnUpdateFaviconURL(0, new_candidates);
+ request_next_icon = !UpdateFaviconCandidate(
+ i->second.url, image_url, image, i->second.icon_type);
+ }
+ if (request_next_icon && GetEntry() && image_urls_.size() > 1) {
+ // Remove the first member of image_urls_ and process the remaining.
+ image_urls_.pop_front();
+ ProcessCurrentUrl();
+ } else if (favicon_candidate_.icon_type != history::INVALID_ICON) {
+ // No more icons to request, set the favicon from the candidate.
+ SetFavicon(favicon_candidate_.url,
+ favicon_candidate_.image_url,
+ favicon_candidate_.image,
+ favicon_candidate_.icon_type);
+ // Reset candidate.
+ image_urls_.clear();
+ favicon_candidate_ = FaviconCandidate();
}
}
download_requests_.erase(i);
« no previous file with comments | « chrome/browser/favicon/favicon_handler.h ('k') | chrome/browser/favicon/favicon_handler_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698