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

Side by Side Diff: chrome/browser/favicon/favicon_handler.cc

Issue 934693002: Reload favicon from HTTP cache on Ctrl+Refresh (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 10 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 "chrome/browser/favicon/favicon_handler.h" 5 #include "chrome/browser/favicon/favicon_handler.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cmath> 8 #include <cmath>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 image(image), 193 image(image),
194 score(score), 194 score(score),
195 icon_type(icon_type) {} 195 icon_type(icon_type) {}
196 196
197 //////////////////////////////////////////////////////////////////////////////// 197 ////////////////////////////////////////////////////////////////////////////////
198 198
199 FaviconHandler::FaviconHandler(FaviconClient* client, 199 FaviconHandler::FaviconHandler(FaviconClient* client,
200 FaviconDriver* driver, 200 FaviconDriver* driver,
201 Type icon_type, 201 Type icon_type,
202 bool download_largest_icon) 202 bool download_largest_icon)
203 : got_favicon_from_history_(false), 203 : waiting_for_favicon_service_data_(false),
204 got_favicon_from_history_(false),
204 favicon_expired_or_incomplete_(false), 205 favicon_expired_or_incomplete_(false),
205 icon_types_(icon_type == FAVICON 206 icon_types_(icon_type == FAVICON
206 ? favicon_base::FAVICON 207 ? favicon_base::FAVICON
207 : favicon_base::TOUCH_ICON | 208 : favicon_base::TOUCH_ICON |
208 favicon_base::TOUCH_PRECOMPOSED_ICON), 209 favicon_base::TOUCH_PRECOMPOSED_ICON),
209 download_largest_icon_(download_largest_icon), 210 download_largest_icon_(download_largest_icon),
210 client_(client), 211 client_(client),
211 driver_(driver) { 212 driver_(driver) {
212 DCHECK(driver_); 213 DCHECK(driver_);
213 } 214 }
214 215
215 FaviconHandler::~FaviconHandler() { 216 FaviconHandler::~FaviconHandler() {
216 } 217 }
217 218
218 void FaviconHandler::FetchFavicon(const GURL& url) { 219 void FaviconHandler::FetchFavicon(const GURL& url) {
219 cancelable_task_tracker_.TryCancelAll(); 220 cancelable_task_tracker_.TryCancelAll();
220 221
221 url_ = url; 222 url_ = url;
222 223
224 waiting_for_favicon_service_data_ = true;
223 favicon_expired_or_incomplete_ = got_favicon_from_history_ = false; 225 favicon_expired_or_incomplete_ = got_favicon_from_history_ = false;
224 image_urls_.clear(); 226 image_urls_.clear();
225 227
226 // Request the favicon from the history service. In parallel to this the 228 // Request the favicon from the history service. In parallel to this the
227 // renderer is going to notify us (well WebContents) when the favicon url is 229 // renderer is going to notify us (well WebContents) when the favicon url is
228 // available. 230 // available.
229 if (client_->GetFaviconService()) { 231 if (client_->GetFaviconService()) {
230 GetFaviconForURLFromFaviconService( 232 GetFaviconForURLFromFaviconService(
231 url_, 233 url_,
232 icon_types_, 234 icon_types_,
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
377 const GURL& image_url, 379 const GURL& image_url,
378 const std::vector<SkBitmap>& bitmaps, 380 const std::vector<SkBitmap>& bitmaps,
379 const std::vector<gfx::Size>& original_bitmap_sizes) { 381 const std::vector<gfx::Size>& original_bitmap_sizes) {
380 DownloadRequests::iterator i = download_requests_.find(id); 382 DownloadRequests::iterator i = download_requests_.find(id);
381 if (i == download_requests_.end()) { 383 if (i == download_requests_.end()) {
382 // Currently WebContents notifies us of ANY downloads so that it is 384 // Currently WebContents notifies us of ANY downloads so that it is
383 // possible to get here. 385 // possible to get here.
384 return; 386 return;
385 } 387 }
386 388
389 DownloadRequest download_request = i->second;
sky 2015/02/19 18:08:10 I'm assuming you didn't make this a const & becaus
387 if (current_candidate() && 390 if (current_candidate() &&
388 DoUrlAndIconMatch(*current_candidate(), image_url, i->second.icon_type)) { 391 DoUrlAndIconMatch(*current_candidate(),
392 image_url,
393 download_request.icon_type)) {
389 bool request_next_icon = true; 394 bool request_next_icon = true;
390 float score = 0.0f; 395 float score = 0.0f;
391 gfx::ImageSkia image_skia; 396 gfx::ImageSkia image_skia;
392 if (download_largest_icon_ && !bitmaps.empty()) { 397 if (download_largest_icon_ && !bitmaps.empty()) {
393 int index = -1; 398 int index = -1;
394 // Use the largest bitmap if FaviconURL doesn't have sizes attribute. 399 // Use the largest bitmap if FaviconURL doesn't have sizes attribute.
395 if (current_candidate()->icon_sizes.empty()) { 400 if (current_candidate()->icon_sizes.empty()) {
396 index = GetLargestSizeIndex(original_bitmap_sizes); 401 index = GetLargestSizeIndex(original_bitmap_sizes);
397 } else { 402 } else {
398 index = GetIndexBySize(original_bitmap_sizes, 403 index = GetIndexBySize(original_bitmap_sizes,
399 current_candidate()->icon_sizes[0]); 404 current_candidate()->icon_sizes[0]);
400 // Find largest bitmap if there is no one exactly matched. 405 // Find largest bitmap if there is no one exactly matched.
401 if (index == -1) 406 if (index == -1)
402 index = GetLargestSizeIndex(original_bitmap_sizes); 407 index = GetLargestSizeIndex(original_bitmap_sizes);
403 } 408 }
404 image_skia = gfx::ImageSkia(gfx::ImageSkiaRep(bitmaps[index], 1)); 409 image_skia = gfx::ImageSkia(gfx::ImageSkiaRep(bitmaps[index], 1));
405 } else { 410 } else {
406 image_skia = CreateFaviconImageSkia(bitmaps, 411 image_skia = CreateFaviconImageSkia(bitmaps,
407 original_bitmap_sizes, 412 original_bitmap_sizes,
408 preferred_icon_size(), 413 preferred_icon_size(),
409 &score); 414 &score);
410 } 415 }
411 416
412 if (!image_skia.isNull()) { 417 if (!image_skia.isNull()) {
413 gfx::Image image(image_skia); 418 gfx::Image image(image_skia);
414 // The downloaded icon is still valid when there is no FaviconURL update 419 // The downloaded icon is still valid when there is no FaviconURL update
415 // during the downloading. 420 // during the downloading.
416 if (!bitmaps.empty()) { 421 if (!bitmaps.empty()) {
417 request_next_icon = !UpdateFaviconCandidate( 422 request_next_icon = !UpdateFaviconCandidate(
418 i->second.url, image_url, image, score, i->second.icon_type); 423 download_request.url, image_url, image, score,
424 download_request.icon_type);
419 } 425 }
420 } 426 }
421 if (request_next_icon && !PageChangedSinceFaviconWasRequested() && 427 if (request_next_icon && !PageChangedSinceFaviconWasRequested() &&
422 image_urls_.size() > 1) { 428 image_urls_.size() > 1) {
423 // Remove the first member of image_urls_ and process the remaining. 429 // Remove the first member of image_urls_ and process the remaining.
424 image_urls_.erase(image_urls_.begin()); 430 image_urls_.erase(image_urls_.begin());
425 ProcessCurrentUrl(); 431 ProcessCurrentUrl();
426 } else if (best_favicon_candidate_.icon_type != 432 } else if (best_favicon_candidate_.icon_type !=
427 favicon_base::INVALID_ICON) { 433 favicon_base::INVALID_ICON) {
434 // Clear |download_requests_| so that a receiver of the notification
435 // sent by FaviconDriver::OnFaviconAvailable() can correctly compute
436 // HasPendingDownloadsForTest().
sky 2015/02/19 18:08:10 I'm confused. Why do we need to do this? If it's j
437 download_requests_.clear();
438
428 // No more icons to request, set the favicon from the candidate. 439 // No more icons to request, set the favicon from the candidate.
429 SetFavicon(best_favicon_candidate_.url, 440 SetFavicon(best_favicon_candidate_.url,
430 best_favicon_candidate_.image_url, 441 best_favicon_candidate_.image_url,
431 best_favicon_candidate_.image, 442 best_favicon_candidate_.image,
432 best_favicon_candidate_.icon_type); 443 best_favicon_candidate_.icon_type);
433 // Reset candidate. 444 // Reset candidate.
434 image_urls_.clear(); 445 image_urls_.clear();
435 best_favicon_candidate_ = FaviconCandidate(); 446 best_favicon_candidate_ = FaviconCandidate();
436 } 447 }
437 } 448 }
438 download_requests_.erase(i); 449 download_requests_.erase(id);
sky 2015/02/19 18:08:10 This is subtle too. |i| may have been invalidated.
450 }
451
452 bool FaviconHandler::HasPendingFaviconServiceRequestsForTest() const {
453 return waiting_for_favicon_service_data_;
454 }
455
456 bool FaviconHandler::HasPendingDownloadsForTest() const {
457 return !download_requests_.empty();
439 } 458 }
440 459
441 bool FaviconHandler::PageChangedSinceFaviconWasRequested() { 460 bool FaviconHandler::PageChangedSinceFaviconWasRequested() {
442 if (UrlMatches(driver_->GetActiveURL(), url_) && url_.is_valid()) { 461 if (UrlMatches(driver_->GetActiveURL(), url_) && url_.is_valid()) {
443 return false; 462 return false;
444 } 463 }
445 // If the URL has changed out from under us (as will happen with redirects) 464 // If the URL has changed out from under us (as will happen with redirects)
446 // return true. 465 // return true.
447 return true; 466 return true;
448 } 467 }
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
524 } 543 }
525 NOTREACHED(); 544 NOTREACHED();
526 return 0; 545 return 0;
527 } 546 }
528 547
529 void FaviconHandler::OnFaviconDataForInitialURLFromFaviconService( 548 void FaviconHandler::OnFaviconDataForInitialURLFromFaviconService(
530 const std::vector<favicon_base::FaviconRawBitmapResult>& 549 const std::vector<favicon_base::FaviconRawBitmapResult>&
531 favicon_bitmap_results) { 550 favicon_bitmap_results) {
532 if (PageChangedSinceFaviconWasRequested()) 551 if (PageChangedSinceFaviconWasRequested())
533 return; 552 return;
553 waiting_for_favicon_service_data_ = false;
534 got_favicon_from_history_ = true; 554 got_favicon_from_history_ = true;
535 history_results_ = favicon_bitmap_results; 555 history_results_ = favicon_bitmap_results;
536 bool has_results = !favicon_bitmap_results.empty(); 556 bool has_results = !favicon_bitmap_results.empty();
537 favicon_expired_or_incomplete_ = has_results && HasExpiredOrIncompleteResult( 557 favicon_expired_or_incomplete_ = has_results && HasExpiredOrIncompleteResult(
538 preferred_icon_size(), favicon_bitmap_results); 558 preferred_icon_size(), favicon_bitmap_results);
539 bool has_valid_result = HasValidResult(favicon_bitmap_results); 559 bool has_valid_result = HasValidResult(favicon_bitmap_results);
540 560
541 if (has_results && icon_types_ == favicon_base::FAVICON && 561 if (has_results && icon_types_ == favicon_base::FAVICON &&
542 !download_largest_icon_ && !driver_->GetActiveFaviconValidity() && 562 !download_largest_icon_ && !driver_->GetActiveFaviconValidity() &&
543 (!current_candidate() || 563 (!current_candidate() ||
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
586 const GURL& icon_url, 606 const GURL& icon_url,
587 favicon_base::IconType icon_type) { 607 favicon_base::IconType icon_type) {
588 if (favicon_expired_or_incomplete_) { 608 if (favicon_expired_or_incomplete_) {
589 // We have the mapping, but the favicon is out of date. Download it now. 609 // We have the mapping, but the favicon is out of date. Download it now.
590 ScheduleDownload(page_url, icon_url, icon_type); 610 ScheduleDownload(page_url, icon_url, icon_type);
591 } else if (client_->GetFaviconService()) { 611 } else if (client_->GetFaviconService()) {
592 // We don't know the favicon, but we may have previously downloaded the 612 // We don't know the favicon, but we may have previously downloaded the
593 // favicon for another page that shares the same favicon. Ask for the 613 // favicon for another page that shares the same favicon. Ask for the
594 // favicon given the favicon URL. 614 // favicon given the favicon URL.
595 if (driver_->IsOffTheRecord()) { 615 if (driver_->IsOffTheRecord()) {
616 waiting_for_favicon_service_data_ = true;
sky 2015/02/19 18:08:10 Is there a reason you don't want to move setting t
596 GetFaviconFromFaviconService( 617 GetFaviconFromFaviconService(
597 icon_url, icon_type, 618 icon_url, icon_type,
598 base::Bind(&FaviconHandler::OnFaviconData, base::Unretained(this)), 619 base::Bind(&FaviconHandler::OnFaviconData, base::Unretained(this)),
599 &cancelable_task_tracker_); 620 &cancelable_task_tracker_);
600 } else { 621 } else {
601 // Ask the history service for the icon. This does two things: 622 // Ask the history service for the icon. This does two things:
602 // 1. Attempts to fetch the favicon data from the database. 623 // 1. Attempts to fetch the favicon data from the database.
603 // 2. If the favicon exists in the database, this updates the database to 624 // 2. If the favicon exists in the database, this updates the database to
604 // include the mapping between the page url and the favicon url. 625 // include the mapping between the page url and the favicon url.
605 // This is asynchronous. The history service will call back when done. 626 // This is asynchronous. The history service will call back when done.
606 UpdateFaviconMappingAndFetch( 627 waiting_for_favicon_service_data_ = true;
628 UpdateFaviconMappingAndFetch(
607 page_url, icon_url, icon_type, 629 page_url, icon_url, icon_type,
608 base::Bind(&FaviconHandler::OnFaviconData, base::Unretained(this)), 630 base::Bind(&FaviconHandler::OnFaviconData, base::Unretained(this)),
609 &cancelable_task_tracker_); 631 &cancelable_task_tracker_);
610 } 632 }
611 } 633 }
612 } 634 }
613 635
614 void FaviconHandler::OnFaviconData(const std::vector< 636 void FaviconHandler::OnFaviconData(const std::vector<
615 favicon_base::FaviconRawBitmapResult>& favicon_bitmap_results) { 637 favicon_base::FaviconRawBitmapResult>& favicon_bitmap_results) {
616 if (PageChangedSinceFaviconWasRequested()) 638 if (PageChangedSinceFaviconWasRequested())
617 return; 639 return;
618 640
641 waiting_for_favicon_service_data_ = false;
642
619 bool has_results = !favicon_bitmap_results.empty(); 643 bool has_results = !favicon_bitmap_results.empty();
620 bool has_expired_or_incomplete_result = HasExpiredOrIncompleteResult( 644 bool has_expired_or_incomplete_result = HasExpiredOrIncompleteResult(
621 preferred_icon_size(), favicon_bitmap_results); 645 preferred_icon_size(), favicon_bitmap_results);
622 bool has_valid_result = HasValidResult(favicon_bitmap_results); 646 bool has_valid_result = HasValidResult(favicon_bitmap_results);
623 647
624 if (has_results && icon_types_ == favicon_base::FAVICON && 648 if (has_results && icon_types_ == favicon_base::FAVICON &&
625 !download_largest_icon_) { 649 !download_largest_icon_) {
626 if (has_valid_result) { 650 if (has_valid_result) {
627 // There is a favicon, set it now. If expired we'll download the current 651 // There is a favicon, set it now. If expired we'll download the current
628 // one again, but at least the user will get some icon instead of the 652 // one again, but at least the user will get some icon instead of the
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
676 if (i->icon_sizes.empty()) 700 if (i->icon_sizes.empty())
677 continue; 701 continue;
678 702
679 gfx::Size largest = i->icon_sizes[GetLargestSizeIndex(i->icon_sizes)]; 703 gfx::Size largest = i->icon_sizes[GetLargestSizeIndex(i->icon_sizes)];
680 i->icon_sizes.clear(); 704 i->icon_sizes.clear();
681 i->icon_sizes.push_back(largest); 705 i->icon_sizes.push_back(largest);
682 } 706 }
683 std::stable_sort(image_urls_.begin(), image_urls_.end(), 707 std::stable_sort(image_urls_.begin(), image_urls_.end(),
684 CompareIconSize); 708 CompareIconSize);
685 } 709 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698