| Index: components/favicon/core/favicon_handler.cc
|
| diff --git a/components/favicon/core/favicon_handler.cc b/components/favicon/core/favicon_handler.cc
|
| index 58c0c8cba78f19ecd5f4614fd0b6dcd3ca98db09..aea23c5e7415086ab53d7f60925c0d7e9f1e3108 100644
|
| --- a/components/favicon/core/favicon_handler.cc
|
| +++ b/components/favicon/core/favicon_handler.cc
|
| @@ -151,6 +151,27 @@ bool CompareIconSize(const FaviconURL& b1, const FaviconURL& b2) {
|
| return area1 > area2;
|
| }
|
|
|
| +// Sorts the entries in |image_urls| by icon size in descending order.
|
| +// Discards all but the largest size for each FaviconURL.
|
| +void SortAndPruneImageUrls(std::vector<FaviconURL>* image_urls) {
|
| + // Not using const-reference since the loop mutates FaviconURL::icon_sizes.
|
| + for (FaviconURL& image_url : *image_urls) {
|
| + if (image_url.icon_sizes.empty())
|
| + continue;
|
| +
|
| + gfx::Size largest =
|
| + image_url.icon_sizes[GetLargestSizeIndex(image_url.icon_sizes)];
|
| + image_url.icon_sizes.clear();
|
| + image_url.icon_sizes.push_back(largest);
|
| + }
|
| + std::stable_sort(image_urls->begin(), image_urls->end(), CompareIconSize);
|
| +}
|
| +
|
| +// Checks whether two FaviconURLs are equal ignoring the icon sizes.
|
| +bool FaviconURLsEqualIgnoringSizes(const FaviconURL& u1, const FaviconURL& u2) {
|
| + return u1.icon_type == u2.icon_type && u1.icon_url == u2.icon_url;
|
| +}
|
| +
|
| } // namespace
|
|
|
| ////////////////////////////////////////////////////////////////////////////////
|
| @@ -199,7 +220,8 @@ FaviconHandler::FaviconHandler(FaviconService* service,
|
| icon_types_(FaviconHandler::GetIconTypesFromHandlerType(handler_type)),
|
| download_largest_icon_(download_largest_icon),
|
| service_(service),
|
| - driver_(driver) {
|
| + driver_(driver),
|
| + current_candidate_index_(0u) {
|
| DCHECK(driver_);
|
| }
|
|
|
| @@ -230,6 +252,7 @@ void FaviconHandler::FetchFavicon(const GURL& url) {
|
| download_requests_.clear();
|
| image_urls_.clear();
|
| history_results_.clear();
|
| + current_candidate_index_ = 0u;
|
| best_favicon_candidate_ = FaviconCandidate();
|
|
|
| // Request the favicon from the history service. In parallel to this the
|
| @@ -266,11 +289,15 @@ bool FaviconHandler::UpdateFaviconCandidate(const GURL& image_url,
|
| // - next candidate has sizes attribute and it is not larger than largest,
|
| // - current candidate is maximal one we want.
|
| const int maximal_size = GetMaximalIconSize(icon_type);
|
| - exact_match = image_urls_.size() == 1 ||
|
| - image_urls_[1].icon_sizes.empty() ||
|
| - image_urls_[1].icon_sizes[0].GetArea() <= largest.GetArea() ||
|
| - (image.Size().width() == maximal_size &&
|
| - image.Size().height() == maximal_size);
|
| + if (current_candidate_index_ + 1 >= image_urls_.size()) {
|
| + exact_match = true;
|
| + } else {
|
| + FaviconURL next_image_url = image_urls_[current_candidate_index_ + 1];
|
| + exact_match = next_image_url.icon_sizes.empty() ||
|
| + next_image_url.icon_sizes[0].GetArea() <= largest.GetArea() ||
|
| + (image.Size().width() == maximal_size &&
|
| + image.Size().height() == maximal_size);
|
| + }
|
| } else {
|
| exact_match = score == 1 || preferred_icon_size() == 0;
|
| replace_best_favicon_candidate =
|
| @@ -326,32 +353,37 @@ void FaviconHandler::OnUpdateFaviconURL(
|
| if (page_url != url_)
|
| return;
|
|
|
| - download_requests_.clear();
|
| - image_urls_.clear();
|
| - best_favicon_candidate_ = FaviconCandidate();
|
| -
|
| + std::vector<FaviconURL> pruned_candidates;
|
| for (const FaviconURL& candidate : candidates) {
|
| if (!candidate.icon_url.is_empty() && (candidate.icon_type & icon_types_))
|
| - image_urls_.push_back(candidate);
|
| + pruned_candidates.push_back(candidate);
|
| }
|
|
|
| if (download_largest_icon_)
|
| - SortAndPruneImageUrls();
|
| + SortAndPruneImageUrls(&pruned_candidates);
|
| +
|
| + // Ignore FaviconURL::icon_sizes because FaviconURL::icon_sizes is not stored
|
| + // in the history database.
|
| + if (image_urls_.size() == pruned_candidates.size() &&
|
| + std::equal(pruned_candidates.begin(), pruned_candidates.end(),
|
| + image_urls_.begin(), FaviconURLsEqualIgnoringSizes)) {
|
| + return;
|
| + }
|
| +
|
| + download_requests_.clear();
|
| + image_urls_ = pruned_candidates;
|
| + current_candidate_index_ = 0u;
|
| + best_favicon_candidate_ = FaviconCandidate();
|
|
|
| // TODO(davemoore) Should clear on empty url. Currently we ignore it.
|
| // This appears to be what FF does as well.
|
| - if (!image_urls_.empty())
|
| + if (current_candidate())
|
| ProcessCurrentUrl();
|
| }
|
|
|
| void FaviconHandler::ProcessCurrentUrl() {
|
| DCHECK(!image_urls_.empty());
|
|
|
| - // current_candidate() may return NULL if download_largest_icon_ is true and
|
| - // all the sizes are larger than the max.
|
| - if (!current_candidate())
|
| - return;
|
| -
|
| if (current_candidate()->icon_type == favicon_base::FAVICON &&
|
| !download_largest_icon_) {
|
| if (!favicon_expired_or_incomplete_ &&
|
| @@ -426,9 +458,9 @@ void FaviconHandler::OnDidDownloadFavicon(
|
| }
|
| }
|
|
|
| - if (request_next_icon && image_urls_.size() > 1) {
|
| - // Remove the first member of image_urls_ and process the remaining.
|
| - image_urls_.erase(image_urls_.begin());
|
| + if (request_next_icon && current_candidate_index_ + 1 < image_urls_.size()) {
|
| + // Process the next candidate.
|
| + ++current_candidate_index_;
|
| ProcessCurrentUrl();
|
| } else {
|
| // We have either found the ideal candidate or run out of candidates.
|
| @@ -439,8 +471,8 @@ void FaviconHandler::OnDidDownloadFavicon(
|
| best_favicon_candidate_.icon_type);
|
| }
|
| // Clear download related state.
|
| - image_urls_.clear();
|
| download_requests_.clear();
|
| + current_candidate_index_ = image_urls_.size();
|
| best_favicon_candidate_ = FaviconCandidate();
|
| }
|
| }
|
| @@ -664,19 +696,4 @@ void FaviconHandler::ScheduleDownload(const GURL& image_url,
|
| }
|
| }
|
|
|
| -void FaviconHandler::SortAndPruneImageUrls() {
|
| - // Not using const-reference since the loop mutates FaviconURL::icon_sizes.
|
| - for (FaviconURL& image_url : image_urls_) {
|
| - if (image_url.icon_sizes.empty())
|
| - continue;
|
| -
|
| - gfx::Size largest =
|
| - image_url.icon_sizes[GetLargestSizeIndex(image_url.icon_sizes)];
|
| - image_url.icon_sizes.clear();
|
| - image_url.icon_sizes.push_back(largest);
|
| - }
|
| - std::stable_sort(image_urls_.begin(), image_urls_.end(),
|
| - CompareIconSize);
|
| -}
|
| -
|
| } // namespace favicon
|
|
|