Index: chrome/browser/favicon/favicon_handler.cc |
diff --git a/chrome/browser/favicon/favicon_handler.cc b/chrome/browser/favicon/favicon_handler.cc |
index cc19d92541f23d57081a84c2bf2027bfbd7343d1..f6f3e54d1aa432328462781724902248b6862889 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,28 @@ FaviconHandler::DownloadRequest::DownloadRequest( |
icon_type(icon_type) { |
} |
+//////////////////////////////////////////////////////////////////////////////// |
+ |
+FaviconHandler::FaviconCandidate::FaviconCandidate() |
+ : icon_type(history::INVALID_ICON) { |
+} |
+ |
+FaviconHandler::FaviconCandidate::~FaviconCandidate() { |
+} |
+ |
+FaviconHandler::FaviconCandidate::FaviconCandidate( |
+ const GURL& url, |
+ const GURL& image_url, |
+ const gfx::Image& image, |
+ history::IconType icon_type) |
+ : url(url), |
+ image_url(image_url), |
+ image(image), |
+ icon_type(icon_type) { |
+} |
+ |
+//////////////////////////////////////////////////////////////////////////////// |
+ |
FaviconHandler::FaviconHandler(Profile* profile, |
FaviconHandlerDelegate* delegate, |
Type icon_type) |
@@ -101,6 +125,7 @@ void FaviconHandler::FetchFavicon(const GURL& url) { |
favicon_expired_ = got_favicon_from_history_ = false; |
current_url_index_ = 0; |
urls_.clear(); |
+ favicon_candidates_.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 +149,42 @@ FaviconService* FaviconHandler::GetFaviconService() { |
return profile_->GetFaviconService(Profile::EXPLICIT_ACCESS); |
} |
+void FaviconHandler::SetFaviconFromCandidates() { |
+ if (favicon_candidates_.empty()) |
+ return; |
+ const int preferred_size = preferred_icon_size(); |
+ FaviconCandidates::iterator match; |
+ if (preferred_size == 0) { |
+ // No size preference, use the first icon. |
+ match = favicon_candidates_.begin(); |
+ } else { |
+ // Use the icon closest to preferred_size, favoring sizes >= preferred_size. |
+ int match_size = -1; |
+ for (FaviconCandidates::iterator iter = favicon_candidates_.begin(); |
+ iter != favicon_candidates_.end(); ++iter) { |
+ FaviconCandidate& candidate = *iter; |
+ SkBitmap bitmap = *candidate.image.ToSkBitmap(); |
+ int bitmap_size = std::max(bitmap.width(), bitmap.height()); |
+ if (match_size < 0 || |
+ (bitmap_size >= preferred_size && bitmap_size < match_size) || |
+ (match_size < preferred_size && bitmap_size > match_size)) { |
+ match = iter; |
+ match_size = bitmap_size; |
+ if (bitmap_size == preferred_size) |
+ break; |
+ } |
+ } |
+ } |
+ SetFavicon(match->url, match->image_url, match->image, match->icon_type); |
+ favicon_candidates_.clear(); |
+} |
+ |
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 +198,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); |
+ } |
} |
} |
@@ -236,12 +293,18 @@ void FaviconHandler::OnDidDownloadFavicon(int id, |
// The downloaded icon is still valid when there is no FaviconURL update |
// during the downloading. |
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, |
+ favicon_candidates_.push_back(FaviconCandidate( |
+ i->second.url, image_url, image, i->second.icon_type)); |
michaelbai
2012/03/14 22:34:14
Would you like stop fetch the rest of icons if the
stevenjb
2012/03/15 00:45:53
Yes that would be better. I thought of this but di
michaelbai
2012/03/15 01:12:00
It seemed you don't need favicon_candidates_ vecto
stevenjb
2012/03/15 21:05:10
That's a fair point. I did another round of re-fac
|
+ } |
+ if ((errored || preferred_icon_size() != 0) && |
+ (GetEntry() && ++current_url_index_ < urls_.size())) { |
+ // Copies all candidates except the first 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); |
+ } else { |
+ // We have all candidates, choose one and set the favicon. |
+ SetFaviconFromCandidates(); |
} |
} |
download_requests_.erase(i); |