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

Side by Side Diff: components/favicon/core/favicon_handler.cc

Issue 2799273002: Add support to process favicons from Web Manifests (Closed)
Patch Set: Added comment. Created 3 years, 8 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/favicon/core/favicon_handler.h" 5 #include "components/favicon/core/favicon_handler.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cmath> 8 #include <cmath>
9 #include <utility> 9 #include <utility>
10 #include <vector> 10 #include <vector>
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 } 188 }
189 189
190 void FaviconHandler::FetchFavicon(const GURL& url) { 190 void FaviconHandler::FetchFavicon(const GURL& url) {
191 cancelable_task_tracker_.TryCancelAll(); 191 cancelable_task_tracker_.TryCancelAll();
192 192
193 url_ = url; 193 url_ = url;
194 194
195 initial_history_result_expired_or_incomplete_ = false; 195 initial_history_result_expired_or_incomplete_ = false;
196 redownload_icons_ = false; 196 redownload_icons_ = false;
197 got_favicon_from_history_ = false; 197 got_favicon_from_history_ = false;
198 download_request_.Cancel(); 198 manifest_download_request_.Cancel();
199 image_download_request_.Cancel();
200 manifest_url_.reset();
199 candidates_.clear(); 201 candidates_.clear();
200 notification_icon_url_ = GURL(); 202 notification_icon_url_ = GURL();
201 notification_icon_type_ = favicon_base::INVALID_ICON; 203 notification_icon_type_ = favicon_base::INVALID_ICON;
202 current_candidate_index_ = 0u; 204 current_candidate_index_ = 0u;
203 best_favicon_ = DownloadedFavicon(); 205 best_favicon_ = DownloadedFavicon();
204 206
205 // Request the favicon from the history service. In parallel to this the 207 // Request the favicon from the history service. In parallel to this the
206 // renderer is going to notify us (well WebContents) when the favicon url is 208 // renderer is going to notify us (well WebContents) when the favicon url is
207 // available. 209 // available.
208 if (service_) { 210 if (service_) {
(...skipping 28 matching lines...) Expand all
237 best_favicon_.candidate.score; 239 best_favicon_.candidate.score;
238 } else { 240 } else {
239 return best_favicon_.candidate.score == 1; 241 return best_favicon_.candidate.score == 1;
240 } 242 }
241 } 243 }
242 244
243 void FaviconHandler::SetFavicon(const GURL& icon_url, 245 void FaviconHandler::SetFavicon(const GURL& icon_url,
244 const gfx::Image& image, 246 const gfx::Image& image,
245 favicon_base::IconType icon_type) { 247 favicon_base::IconType icon_type) {
246 if (service_ && ShouldSaveFavicon()) 248 if (service_ && ShouldSaveFavicon())
247 service_->SetFavicons(url_, icon_url, icon_type, image); 249 service_->SetFavicons(url_, manifest_url_.value_or(icon_url), icon_type,
250 image);
248 251
249 NotifyFaviconUpdated(icon_url, icon_type, image); 252 NotifyFaviconUpdated(icon_url, icon_type, image);
250 } 253 }
251 254
252 void FaviconHandler::NotifyFaviconUpdated( 255 void FaviconHandler::NotifyFaviconUpdated(
253 const std::vector<favicon_base::FaviconRawBitmapResult>& 256 const std::vector<favicon_base::FaviconRawBitmapResult>&
254 favicon_bitmap_results) { 257 favicon_bitmap_results) {
255 if (favicon_bitmap_results.empty()) 258 if (favicon_bitmap_results.empty())
256 return; 259 return;
257 260
258 gfx::Image resized_image = favicon_base::SelectFaviconFramesFromPNGs( 261 gfx::Image resized_image = favicon_base::SelectFaviconFramesFromPNGs(
259 favicon_bitmap_results, 262 favicon_bitmap_results,
260 favicon_base::GetFaviconScales(), 263 favicon_base::GetFaviconScales(),
261 preferred_icon_size()); 264 preferred_icon_size());
262 // The history service sends back results for a single icon URL and icon 265 // The history service sends back results for a single icon URL and icon
263 // type, so it does not matter which result we get |icon_url| and |icon_type| 266 // type, so it does not matter which result we get |icon_url| and |icon_type|
264 // from. 267 // from.
265 const GURL icon_url = favicon_bitmap_results[0].icon_url; 268 const GURL icon_url = favicon_bitmap_results[0].icon_url;
266 favicon_base::IconType icon_type = favicon_bitmap_results[0].icon_type; 269 favicon_base::IconType icon_type = favicon_bitmap_results[0].icon_type;
267 NotifyFaviconUpdated(icon_url, icon_type, resized_image); 270 NotifyFaviconUpdated(icon_url, icon_type, resized_image);
268 } 271 }
269 272
270 void FaviconHandler::NotifyFaviconUpdated(const GURL& icon_url, 273 void FaviconHandler::NotifyFaviconUpdated(const GURL& icon_url,
271 favicon_base::IconType icon_type, 274 favicon_base::IconType icon_type,
272 const gfx::Image& image) { 275 const gfx::Image& image) {
273 if (image.IsEmpty()) 276 if (image.IsEmpty())
274 return; 277 return;
275 278
279 // If a manifest is being processed, it's URL overrides the icon URL.
280 const GURL& notification_icon_url = manifest_url_.value_or(icon_url);
281
276 gfx::Image image_with_adjusted_colorspace = image; 282 gfx::Image image_with_adjusted_colorspace = image;
277 favicon_base::SetFaviconColorSpace(&image_with_adjusted_colorspace); 283 favicon_base::SetFaviconColorSpace(&image_with_adjusted_colorspace);
278 284
279 delegate_->OnFaviconUpdated(url_, handler_type_, icon_url, 285 delegate_->OnFaviconUpdated(url_, handler_type_, notification_icon_url,
280 icon_url != notification_icon_url_, 286 notification_icon_url != notification_icon_url_,
281 image_with_adjusted_colorspace); 287 image_with_adjusted_colorspace);
282 288
283 notification_icon_url_ = icon_url; 289 notification_icon_url_ = notification_icon_url;
284 notification_icon_type_ = icon_type; 290 notification_icon_type_ = icon_type;
285 } 291 }
286 292
287 void FaviconHandler::OnUpdateFaviconURL( 293 void FaviconHandler::OnUpdateCandidates(
288 const GURL& page_url, 294 const GURL& page_url,
289 const std::vector<FaviconURL>& candidates) { 295 const std::vector<FaviconURL>& candidates,
296 const base::Optional<GURL>& manifest_url) {
297 DCHECK_EQ(page_url, url_);
290 if (page_url != url_) 298 if (page_url != url_)
291 return; 299 return;
292 300
pkotwicz 2017/04/12 22:10:06 Shouldn't the TOUCH_LARGEST FaviconHandler complet
mastiz 2017/04/20 18:06:33 This happens in upper layers: the manifest URL is
pkotwicz 2017/04/24 14:42:14 I see. This is done in FaviconDriverImpl
301 // |candidates| or |manifest_url| could have been modified via Javascript.
302 if (manifest_url_ && manifest_url_ == manifest_url)
303 return;
304
305 manifest_url_ = manifest_url;
306 non_manifest_original_candidates_ = candidates;
307
308 // Check if the manifest previously returned a 404 (or a 200 but contained no
309 // icons), and ignore the manifest URL if that's the case.
310 if (manifest_url_ && service_ &&
311 service_->WasUnableToDownloadFavicon(*manifest_url_)) {
312 DVLOG(1) << "Skip failed Manifest: " << *manifest_url_;
313 manifest_url_.reset();
314 }
315
316 // If no manifest available, proceed with the regular candidates only.
317 if (!manifest_url_) {
318 OnGotFinalIconURLCandidates(candidates);
319 return;
320 }
321
322 if (redownload_icons_) {
323 // Note that |redownload_icons_| can only be true after the database lookup
324 // for the page URL is completed.
325 ScheduleManifestDownload();
326 } else {
327 // See if there is a cached favicon for the manifest.
328 GetFaviconAndUpdateMappingsUnlessIncognito(
329 /*icon_url=*/*manifest_url_, favicon_base::FAVICON,
330 base::Bind(&FaviconHandler::OnFaviconDataForManifestFromFaviconService,
331 base::Unretained(this)));
332 }
333 }
334
335 void FaviconHandler::OnFaviconDataForManifestFromFaviconService(
336 const std::vector<favicon_base::FaviconRawBitmapResult>&
337 favicon_bitmap_results) {
338 bool has_valid_result = HasValidResult(favicon_bitmap_results);
339 bool has_expired_or_incomplete_result =
340 !has_valid_result || HasExpiredOrIncompleteResult(preferred_icon_size(),
341 favicon_bitmap_results);
342
343 if (has_valid_result) {
344 // There is a valid favicon. Notify any observers. It is useful to notify
345 // the observers even if the favicon is expired or incomplete (incorrect
346 // size) because temporarily showing the user an expired favicon or
347 // streched favicon is preferable to showing the user the default favicon.
348 NotifyFaviconUpdated(favicon_bitmap_results);
349 }
350
351 if (has_expired_or_incomplete_result)
352 ScheduleManifestDownload();
353 }
354
355 void FaviconHandler::ScheduleManifestDownload() {
356 manifest_download_request_.Reset(base::Bind(
357 &FaviconHandler::OnDidDownloadManifest, base::Unretained(this)));
358 delegate_->DownloadManifest(*manifest_url_,
359 manifest_download_request_.callback());
360 }
361
362 void FaviconHandler::OnDidDownloadManifest(
363 int status_code,
364 const std::vector<FaviconURL>& candidates) {
365 // Mark manifest download as finished.
366 manifest_download_request_.Cancel();
367
368 if (!candidates.empty()) {
369 DCHECK(status_code == 200);
pkotwicz 2017/04/12 22:10:06 Why the DCHECK() ?
mastiz 2017/04/20 18:06:33 To add clarity, but I realize you're not a big fan
370 OnGotFinalIconURLCandidates(candidates);
pkotwicz 2017/04/12 22:10:07 You want to return here?
mastiz 2017/04/20 18:06:33 Correct, done (btw tests were failing due to this)
371 }
372
373 // If either the downloading of the manifest failed, OR the manifest contains
374 // no icons, proceed with the list of icons listed in the HTML.
375 DVLOG(1) << "Could not fetch Manifest icons from " << *manifest_url_
376 << ", falling back to inlined ones, which are "
377 << non_manifest_original_candidates_.size();
378
379 if (service_ && (status_code == 404 || status_code == 200))
pkotwicz 2017/04/12 22:10:07 Why is this if() checking the status code?
mastiz 2017/04/20 18:06:33 We shouldn't call UnableToDownloadFavicon() for al
pkotwicz 2017/04/24 14:42:15 Perhaps FaviconHandler::OnDidDownloadManifest() sh
mastiz 2017/04/27 13:54:50 How would that distinguish a 404 from 503?
pkotwicz 2017/05/01 04:56:53 I suggest doing this: if (status_code == 404 || (
mastiz 2017/05/04 10:57:53 Would that work for a manifest that returns a 200
pkotwicz 2017/05/04 17:28:24 Black listing anything other than 5xx sounds reaso
mastiz 2017/05/10 10:03:51 Done.
pkotwicz 2017/05/12 06:13:28 Did you forget to upload a patch set. There does n
mastiz 2017/05/12 13:31:32 This was done previously but I've reverted it (in
pkotwicz 2017/05/12 15:37:41 Fair enough. You will need to delete the tests whi
mastiz 2017/05/15 14:06:59 404 behavior hasn't changed, only 5xx. That is, an
pkotwicz 2017/05/16 06:36:34 Ok, I see now
380 service_->UnableToDownloadFavicon(*manifest_url_);
pkotwicz 2017/04/12 22:10:07 If we end up download the Web Manifest on each pag
mastiz 2017/04/20 18:06:33 If we were to always load and parse manifests, thi
pkotwicz 2017/04/24 14:42:15 It might not be that nice because: - Web Manifest
mastiz 2017/04/27 13:54:50 Acknowledged, makes sense. We'd need to see how th
381
382 manifest_url_.reset();
383 OnGotFinalIconURLCandidates(non_manifest_original_candidates_);
384 }
385
386 void FaviconHandler::OnGotFinalIconURLCandidates(
387 const std::vector<FaviconURL>& candidates) {
293 std::vector<FaviconCandidate> sorted_candidates; 388 std::vector<FaviconCandidate> sorted_candidates;
294 const std::vector<int> desired_pixel_sizes = 389 const std::vector<int> desired_pixel_sizes =
295 GetDesiredPixelSizes(handler_type_); 390 GetDesiredPixelSizes(handler_type_);
296 for (const FaviconURL& candidate : candidates) { 391 for (const FaviconURL& candidate : candidates) {
297 if (!candidate.icon_url.is_empty() && (candidate.icon_type & icon_types_)) { 392 if (!candidate.icon_url.is_empty() && (candidate.icon_type & icon_types_)) {
298 sorted_candidates.push_back( 393 sorted_candidates.push_back(
299 FaviconCandidate::FromFaviconURL(candidate, desired_pixel_sizes)); 394 FaviconCandidate::FromFaviconURL(candidate, desired_pixel_sizes));
300 } 395 }
301 } 396 }
302 397
303 std::stable_sort(sorted_candidates.begin(), sorted_candidates.end(), 398 std::stable_sort(sorted_candidates.begin(), sorted_candidates.end(),
304 &FaviconCandidate::CompareScore); 399 &FaviconCandidate::CompareScore);
305 400
306 if (candidates_.size() == sorted_candidates.size() && 401 if (candidates_.size() == sorted_candidates.size() &&
307 std::equal(sorted_candidates.begin(), sorted_candidates.end(), 402 std::equal(sorted_candidates.begin(), sorted_candidates.end(),
308 candidates_.begin())) { 403 candidates_.begin())) {
309 return; 404 return;
310 } 405 }
311 406
312 download_request_.Cancel(); 407 image_download_request_.Cancel();
313 candidates_ = std::move(sorted_candidates); 408 candidates_ = std::move(sorted_candidates);
314 current_candidate_index_ = 0u; 409 current_candidate_index_ = 0u;
315 best_favicon_ = DownloadedFavicon(); 410 best_favicon_ = DownloadedFavicon();
316 411
317 // TODO(davemoore) Should clear on empty url. Currently we ignore it. 412 // TODO(davemoore) Should clear on empty url. Currently we ignore it.
318 // This appears to be what FF does as well. 413 // This appears to be what FF does as well.
319 if (current_candidate() && got_favicon_from_history_) 414 if (current_candidate() && got_favicon_from_history_)
320 OnGotInitialHistoryDataAndIconURLCandidates(); 415 OnGotInitialHistoryDataAndIconURLCandidates();
321 } 416 }
322 417
(...skipping 25 matching lines...) Expand all
348 } 443 }
349 444
350 void FaviconHandler::OnDidDownloadFavicon( 445 void FaviconHandler::OnDidDownloadFavicon(
351 favicon_base::IconType icon_type, 446 favicon_base::IconType icon_type,
352 int id, 447 int id,
353 int http_status_code, 448 int http_status_code,
354 const GURL& image_url, 449 const GURL& image_url,
355 const std::vector<SkBitmap>& bitmaps, 450 const std::vector<SkBitmap>& bitmaps,
356 const std::vector<gfx::Size>& original_bitmap_sizes) { 451 const std::vector<gfx::Size>& original_bitmap_sizes) {
357 // Mark download as finished. 452 // Mark download as finished.
358 download_request_.Cancel(); 453 image_download_request_.Cancel();
359 454
360 if (bitmaps.empty() && http_status_code == 404) { 455 if (bitmaps.empty() && http_status_code == 404) {
361 DVLOG(1) << "Failed to Download Favicon:" << image_url; 456 DVLOG(1) << "Failed to Download Favicon:" << image_url;
362 if (service_) 457 if (service_)
363 service_->UnableToDownloadFavicon(image_url); 458 service_->UnableToDownloadFavicon(image_url);
364 } 459 }
365 460
366 bool request_next_icon = true; 461 bool request_next_icon = true;
367 if (!bitmaps.empty()) { 462 if (!bitmaps.empty()) {
368 float score = 0.0f; 463 float score = 0.0f;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 } 507 }
413 508
414 const std::vector<GURL> FaviconHandler::GetIconURLs() const { 509 const std::vector<GURL> FaviconHandler::GetIconURLs() const {
415 std::vector<GURL> icon_urls; 510 std::vector<GURL> icon_urls;
416 for (const FaviconCandidate& candidate : candidates_) 511 for (const FaviconCandidate& candidate : candidates_)
417 icon_urls.push_back(candidate.icon_url); 512 icon_urls.push_back(candidate.icon_url);
418 return icon_urls; 513 return icon_urls;
419 } 514 }
420 515
421 bool FaviconHandler::HasPendingTasksForTest() { 516 bool FaviconHandler::HasPendingTasksForTest() {
422 return !download_request_.IsCancelled() || 517 return !manifest_download_request_.IsCancelled() ||
518 !image_download_request_.IsCancelled() ||
423 cancelable_task_tracker_.HasTrackedTasks(); 519 cancelable_task_tracker_.HasTrackedTasks();
424 } 520 }
425 521
426 bool FaviconHandler::ShouldSaveFavicon() { 522 bool FaviconHandler::ShouldSaveFavicon() {
427 if (!delegate_->IsOffTheRecord()) 523 if (!delegate_->IsOffTheRecord())
428 return true; 524 return true;
429 525
430 // Always save favicon if the page is bookmarked. 526 // Always save favicon if the page is bookmarked.
431 return delegate_->IsBookmarked(url_); 527 return delegate_->IsBookmarked(url_);
432 } 528 }
433 529
434 void FaviconHandler::OnFaviconDataForInitialURLFromFaviconService( 530 void FaviconHandler::OnFaviconDataForInitialURLFromFaviconService(
435 const std::vector<favicon_base::FaviconRawBitmapResult>& 531 const std::vector<favicon_base::FaviconRawBitmapResult>&
436 favicon_bitmap_results) { 532 favicon_bitmap_results) {
437 got_favicon_from_history_ = true; 533 got_favicon_from_history_ = true;
438 bool has_valid_result = HasValidResult(favicon_bitmap_results); 534 bool has_valid_result = HasValidResult(favicon_bitmap_results);
439 initial_history_result_expired_or_incomplete_ = 535 initial_history_result_expired_or_incomplete_ =
440 !has_valid_result || 536 !has_valid_result ||
441 HasExpiredOrIncompleteResult(preferred_icon_size(), 537 HasExpiredOrIncompleteResult(preferred_icon_size(),
442 favicon_bitmap_results); 538 favicon_bitmap_results);
443 redownload_icons_ = initial_history_result_expired_or_incomplete_ && 539 redownload_icons_ = initial_history_result_expired_or_incomplete_ &&
444 !favicon_bitmap_results.empty(); 540 !favicon_bitmap_results.empty();
445 541
446 if (has_valid_result && (!current_candidate() || 542 if (has_valid_result && (!current_candidate() ||
447 DoUrlsAndIconsMatch(current_candidate()->icon_url, 543 DoUrlsAndIconsMatch(current_candidate()->icon_url,
448 current_candidate()->icon_type, 544 current_candidate()->icon_type,
449 favicon_bitmap_results))) { 545 favicon_bitmap_results))) {
pkotwicz 2017/04/12 22:10:06 I think that this should be changed to: if (has_v
mastiz 2017/04/20 18:06:33 Done.
450 // The db knows the favicon (although it may be out of date) and the entry 546 // The db knows the favicon (although it may be out of date) and the entry
451 // doesn't have an icon. Set the favicon now, and if the favicon turns out 547 // doesn't have an icon. Set the favicon now, and if the favicon turns out
452 // to be expired (or the wrong url) we'll fetch later on. This way the 548 // to be expired (or the wrong url) we'll fetch later on. This way the
453 // user doesn't see a flash of the default favicon. 549 // user doesn't see a flash of the default favicon.
454 NotifyFaviconUpdated(favicon_bitmap_results); 550 NotifyFaviconUpdated(favicon_bitmap_results);
455 } 551 }
456 552
457 if (current_candidate()) 553 if (current_candidate())
458 OnGotInitialHistoryDataAndIconURLCandidates(); 554 OnGotInitialHistoryDataAndIconURLCandidates();
459 } 555 }
460 556
461 void FaviconHandler::DownloadCurrentCandidateOrAskFaviconService() { 557 void FaviconHandler::DownloadCurrentCandidateOrAskFaviconService() {
462 GURL icon_url = current_candidate()->icon_url; 558 const GURL icon_url = current_candidate()->icon_url;
463 favicon_base::IconType icon_type = current_candidate()->icon_type; 559 const favicon_base::IconType icon_type = current_candidate()->icon_type;
464 560 // If the icons listed in a manifest are being processed, skip the cache
465 if (redownload_icons_) { 561 // lookup for |icon_url| since the manifest's URL is used for caching anyway,
562 // and this lookup has happened earlier.
563 if (redownload_icons_ || manifest_url_) {
466 // We have the mapping, but the favicon is out of date. Download it now. 564 // We have the mapping, but the favicon is out of date. Download it now.
467 ScheduleDownload(icon_url, icon_type); 565 ScheduleFaviconDownload(icon_url, icon_type);
468 } else if (service_) { 566 } else {
469 // We don't know the favicon, but we may have previously downloaded the 567 GetFaviconAndUpdateMappingsUnlessIncognito(
470 // favicon for another page that shares the same favicon. Ask for the 568 icon_url, icon_type,
471 // favicon given the favicon URL. 569 base::Bind(&FaviconHandler::OnFaviconData, base::Unretained(this)));
472 if (delegate_->IsOffTheRecord()) {
473 service_->GetFavicon(
474 icon_url, icon_type, preferred_icon_size(),
475 base::Bind(&FaviconHandler::OnFaviconData, base::Unretained(this)),
476 &cancelable_task_tracker_);
477 } else {
478 // Ask the history service for the icon. This does two things:
479 // 1. Attempts to fetch the favicon data from the database.
480 // 2. If the favicon exists in the database, this updates the database to
481 // include the mapping between the page url and the favicon url.
482 // This is asynchronous. The history service will call back when done.
483 // TODO(pkotwicz): pass in all of |image_urls_| to
484 // UpdateFaviconMappingsAndFetch().
485 service_->UpdateFaviconMappingsAndFetch(
486 url_, {icon_url}, icon_type, preferred_icon_size(),
487 base::Bind(&FaviconHandler::OnFaviconData, base::Unretained(this)),
488 &cancelable_task_tracker_);
489 }
490 } 570 }
491 } 571 }
492 572
573 void FaviconHandler::GetFaviconAndUpdateMappingsUnlessIncognito(
574 const GURL& icon_url,
575 favicon_base::IconType icon_type,
576 const favicon_base::FaviconResultsCallback& callback) {
577 if (!service_)
578 return;
579
580 // We don't know the favicon, but we may have previously downloaded the
581 // favicon for another page that shares the same favicon. Ask for the
582 // favicon given the favicon URL.
583 if (delegate_->IsOffTheRecord()) {
584 service_->GetFavicon(icon_url, icon_type, preferred_icon_size(), callback,
585 &cancelable_task_tracker_);
586 } else {
587 // Ask the history service for the icon. This does two things:
588 // 1. Attempts to fetch the favicon data from the database.
589 // 2. If the favicon exists in the database, this updates the database to
590 // include the mapping between the page url and the favicon url.
591 // This is asynchronous. The history service will call back when done.
592 // TODO(pkotwicz): pass in all of |image_urls_| to
593 // UpdateFaviconMappingsAndFetch().
594 service_->UpdateFaviconMappingsAndFetch(url_, {icon_url}, icon_type,
595 preferred_icon_size(), callback,
596 &cancelable_task_tracker_);
597 }
598 }
599
493 void FaviconHandler::OnFaviconData(const std::vector< 600 void FaviconHandler::OnFaviconData(const std::vector<
494 favicon_base::FaviconRawBitmapResult>& favicon_bitmap_results) { 601 favicon_base::FaviconRawBitmapResult>& favicon_bitmap_results) {
495 bool has_results = !favicon_bitmap_results.empty(); 602 bool has_results = !favicon_bitmap_results.empty();
496 bool has_valid_result = HasValidResult(favicon_bitmap_results); 603 bool has_valid_result = HasValidResult(favicon_bitmap_results);
497 bool has_expired_or_incomplete_result = 604 bool has_expired_or_incomplete_result =
498 !has_valid_result || HasExpiredOrIncompleteResult(preferred_icon_size(), 605 !has_valid_result || HasExpiredOrIncompleteResult(preferred_icon_size(),
499 favicon_bitmap_results); 606 favicon_bitmap_results);
500 607
501 if (has_valid_result) { 608 if (has_valid_result) {
502 // There is a valid favicon. Notify any observers. It is useful to notify 609 // There is a valid favicon. Notify any observers. It is useful to notify
503 // the observers even if the favicon is expired or incomplete (incorrect 610 // the observers even if the favicon is expired or incomplete (incorrect
504 // size) because temporarily showing the user an expired favicon or 611 // size) because temporarily showing the user an expired favicon or
505 // streched favicon is preferable to showing the user the default favicon. 612 // streched favicon is preferable to showing the user the default favicon.
506 NotifyFaviconUpdated(favicon_bitmap_results); 613 NotifyFaviconUpdated(favicon_bitmap_results);
507 } 614 }
508 615
509 if (!current_candidate() || 616 if (!current_candidate() ||
510 (has_results && !DoUrlsAndIconsMatch(current_candidate()->icon_url, 617 (has_results && !DoUrlsAndIconsMatch(current_candidate()->icon_url,
511 current_candidate()->icon_type, 618 current_candidate()->icon_type,
512 favicon_bitmap_results))) { 619 favicon_bitmap_results))) {
513 // The icon URLs have been updated since the favicon data was requested. 620 // The icon URLs have been updated since the favicon data was requested.
621 NOTREACHED(); // DONOTSUBMIT
514 return; 622 return;
515 } 623 }
516 624
517 if (has_expired_or_incomplete_result) { 625 if (has_expired_or_incomplete_result) {
518 ScheduleDownload(current_candidate()->icon_url, 626 ScheduleFaviconDownload(current_candidate()->icon_url,
519 current_candidate()->icon_type); 627 current_candidate()->icon_type);
520 } 628 }
521 } 629 }
522 630
523 void FaviconHandler::ScheduleDownload(const GURL& image_url, 631 void FaviconHandler::ScheduleFaviconDownload(const GURL& image_url,
524 favicon_base::IconType icon_type) { 632 favicon_base::IconType icon_type) {
525 DCHECK(image_url.is_valid()); 633 DCHECK(image_url.is_valid());
526 // Note that CancelableCallback starts cancelled. 634 // Note that CancelableCallback starts cancelled.
527 DCHECK(download_request_.IsCancelled()) << "More than one ongoing download"; 635 DCHECK(image_download_request_.IsCancelled())
636 << "More than one ongoing download";
528 if (service_ && service_->WasUnableToDownloadFavicon(image_url)) { 637 if (service_ && service_->WasUnableToDownloadFavicon(image_url)) {
529 DVLOG(1) << "Skip Failed FavIcon: " << image_url; 638 DVLOG(1) << "Skip Failed FavIcon: " << image_url;
530 OnDidDownloadFavicon(icon_type, 0, 0, image_url, std::vector<SkBitmap>(), 639 OnDidDownloadFavicon(icon_type, 0, 0, image_url, std::vector<SkBitmap>(),
531 std::vector<gfx::Size>()); 640 std::vector<gfx::Size>());
532 return; 641 return;
533 } 642 }
534 download_request_.Reset(base::Bind(&FaviconHandler::OnDidDownloadFavicon, 643 image_download_request_.Reset(
535 base::Unretained(this), icon_type)); 644 base::Bind(&FaviconHandler::OnDidDownloadFavicon, base::Unretained(this),
645 icon_type));
536 // A max bitmap size is specified to avoid receiving huge bitmaps in 646 // A max bitmap size is specified to avoid receiving huge bitmaps in
537 // OnDidDownloadFavicon(). See FaviconDriver::StartDownload() 647 // OnDidDownloadFavicon(). See FaviconDriver::StartDownload()
538 // for more details about the max bitmap size. 648 // for more details about the max bitmap size.
539 const int download_id = 649 const int download_id =
540 delegate_->DownloadImage(image_url, GetMaximalIconSize(handler_type_), 650 delegate_->DownloadImage(image_url, GetMaximalIconSize(handler_type_),
541 download_request_.callback()); 651 image_download_request_.callback());
542 DCHECK_NE(download_id, 0); 652 DCHECK_NE(download_id, 0);
543 } 653 }
544 654
545 } // namespace favicon 655 } // namespace favicon
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698