Commit 8c6d0c6c authored by pkotwicz's avatar pkotwicz Committed by Commit bot

Fix FaviconHandler when it has multiple icon URLs and one of them is invalid

This CL prevents FaviconHandler from stopping iteration over a page's icon URLs
if a download for one of the icon URLs previously returned a 404. In particular,
this CL makes FaviconHandler::ScheduleDownload() call the download callback
when FaviconDriver::StartDownload() does not start a download. This is important
because the download callback is responsible for initiating the fetch for the
data for the next favicon candidate.

Sample scenario:
  Page HTML snippet:
  <link rel="icon" href="www.google.com/nothingtoseehere.png" />
  <link rel="icon" href="www.google.com/favicon.ico" />

  A previous download for "www.google.com/nothingtoseehere.png" returned a 404
  (e.g. the user previously visited a different page which also makes use of
  www.google.com/nothingtoseehere.png)

  This CL makes FaviconHandler fetch data for "www.google.com/favicon.ico"
  despite the download for the first favicon candidate
  ("www.google.com/nothingtoseehere.png") having previously failed.

BUG=474429
TEST=FaviconHandlerTest.MultipleFavicons404,
     FaviconHandlerTest.MultipleFaviconsAll404

Review URL: https://codereview.chromium.org/1079523005

Cr-Commit-Position: refs/heads/master@{#327339}
parent 02bd8efd
......@@ -444,13 +444,15 @@ void FaviconHandler::OnDidDownloadFavicon(
// Remove the first member of image_urls_ and process the remaining.
image_urls_.erase(image_urls_.begin());
ProcessCurrentUrl();
} else if (best_favicon_candidate_.icon_type != favicon_base::INVALID_ICON) {
// No more icons to request, set the favicon from the candidate.
SetFavicon(best_favicon_candidate_.url,
best_favicon_candidate_.image_url,
best_favicon_candidate_.image,
best_favicon_candidate_.icon_type);
// Reset candidate.
} else {
// We have either found the ideal candidate or run out of candidates.
if (best_favicon_candidate_.icon_type != favicon_base::INVALID_ICON) {
// No more icons to request, set the favicon from the candidate.
SetFavicon(best_favicon_candidate_.url, best_favicon_candidate_.image_url,
best_favicon_candidate_.image,
best_favicon_candidate_.icon_type);
}
// Clear download related state.
image_urls_.clear();
download_requests_.clear();
best_favicon_candidate_ = FaviconCandidate();
......@@ -680,11 +682,18 @@ void FaviconHandler::ScheduleDownload(const GURL& url,
// for more details about the max bitmap size.
const int download_id = DownloadFavicon(image_url,
GetMaximalIconSize(icon_type));
if (download_id) {
// Download ids should be unique.
DCHECK(download_requests_.find(download_id) == download_requests_.end());
download_requests_[download_id] =
DownloadRequest(url, image_url, icon_type);
// Download ids should be unique.
DCHECK(download_requests_.find(download_id) == download_requests_.end());
download_requests_[download_id] = DownloadRequest(url, image_url, icon_type);
if (download_id == 0) {
// If DownloadFavicon() did not start a download, it returns a download id
// of 0. We still need to call OnDidDownloadFavicon() because the method is
// responsible for initiating the data request for the next candidate.
OnDidDownloadFavicon(download_id, image_url, std::vector<SkBitmap>(),
std::vector<gfx::Size>());
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment