| 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..042abc17a61c79f2d4ea48777780048f95cb6fa8 100644
|
| --- a/chrome/browser/favicon/favicon_handler.cc
|
| +++ b/chrome/browser/favicon/favicon_handler.cc
|
| @@ -101,6 +101,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 +125,52 @@ FaviconService* FaviconHandler::GetFaviconService() {
|
| return profile_->GetFaviconService(Profile::EXPLICIT_ACCESS);
|
| }
|
|
|
| +void FaviconHandler::AddFaviconCandidate(
|
| + const GURL& url,
|
| + const GURL& image_url,
|
| + const gfx::Image& image,
|
| + history::IconType icon_type) {
|
| + FaviconCandidate candidate;
|
| + candidate.url = url;
|
| + candidate.image_url = image_url;
|
| + candidate.image = image;
|
| + candidate.icon_type = icon_type;
|
| + favicon_candidates_.push_back(candidate);
|
| +}
|
| +
|
| +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_, 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;
|
| + }
|
| + }
|
| + }
|
| + 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())) ?
|
| @@ -236,12 +277,17 @@ 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,
|
| + AddFaviconCandidate(i->second.url, image_url, image, i->second.icon_type);
|
| + }
|
| + 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);
|
|
|