| OLD | NEW |
| 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 <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 208 score(score), | 208 score(score), |
| 209 icon_type(icon_type) {} | 209 icon_type(icon_type) {} |
| 210 | 210 |
| 211 //////////////////////////////////////////////////////////////////////////////// | 211 //////////////////////////////////////////////////////////////////////////////// |
| 212 | 212 |
| 213 FaviconHandler::FaviconHandler(FaviconService* service, | 213 FaviconHandler::FaviconHandler(FaviconService* service, |
| 214 FaviconDriver* driver, | 214 FaviconDriver* driver, |
| 215 Type handler_type) | 215 Type handler_type) |
| 216 : got_favicon_from_history_(false), | 216 : got_favicon_from_history_(false), |
| 217 initial_history_result_expired_or_incomplete_(false), | 217 initial_history_result_expired_or_incomplete_(false), |
| 218 redownload_icons_(false), |
| 218 icon_types_(FaviconHandler::GetIconTypesFromHandlerType(handler_type)), | 219 icon_types_(FaviconHandler::GetIconTypesFromHandlerType(handler_type)), |
| 219 download_largest_icon_(handler_type == LARGEST_FAVICON || | 220 download_largest_icon_(handler_type == LARGEST_FAVICON || |
| 220 handler_type == LARGEST_TOUCH), | 221 handler_type == LARGEST_TOUCH), |
| 221 notification_icon_type_(favicon_base::INVALID_ICON), | 222 notification_icon_type_(favicon_base::INVALID_ICON), |
| 222 service_(service), | 223 service_(service), |
| 223 driver_(driver), | 224 driver_(driver), |
| 224 current_candidate_index_(0u) { | 225 current_candidate_index_(0u) { |
| 225 DCHECK(driver_); | 226 DCHECK(driver_); |
| 226 } | 227 } |
| 227 | 228 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 240 } | 241 } |
| 241 return 0; | 242 return 0; |
| 242 } | 243 } |
| 243 | 244 |
| 244 void FaviconHandler::FetchFavicon(const GURL& url) { | 245 void FaviconHandler::FetchFavicon(const GURL& url) { |
| 245 cancelable_task_tracker_.TryCancelAll(); | 246 cancelable_task_tracker_.TryCancelAll(); |
| 246 | 247 |
| 247 url_ = url; | 248 url_ = url; |
| 248 | 249 |
| 249 initial_history_result_expired_or_incomplete_ = false; | 250 initial_history_result_expired_or_incomplete_ = false; |
| 251 redownload_icons_ = false; |
| 250 got_favicon_from_history_ = false; | 252 got_favicon_from_history_ = false; |
| 251 download_requests_.clear(); | 253 download_requests_.clear(); |
| 252 image_urls_.clear(); | 254 image_urls_.clear(); |
| 253 notification_icon_url_ = GURL(); | 255 notification_icon_url_ = GURL(); |
| 254 notification_icon_type_ = favicon_base::INVALID_ICON; | 256 notification_icon_type_ = favicon_base::INVALID_ICON; |
| 255 current_candidate_index_ = 0u; | 257 current_candidate_index_ = 0u; |
| 256 best_favicon_candidate_ = FaviconCandidate(); | 258 best_favicon_candidate_ = FaviconCandidate(); |
| 257 | 259 |
| 258 // Request the favicon from the history service. In parallel to this the | 260 // Request the favicon from the history service. In parallel to this the |
| 259 // renderer is going to notify us (well WebContents) when the favicon url is | 261 // renderer is going to notify us (well WebContents) when the favicon url is |
| (...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 565 return 0; | 567 return 0; |
| 566 } | 568 } |
| 567 NOTREACHED(); | 569 NOTREACHED(); |
| 568 return 0; | 570 return 0; |
| 569 } | 571 } |
| 570 | 572 |
| 571 void FaviconHandler::OnFaviconDataForInitialURLFromFaviconService( | 573 void FaviconHandler::OnFaviconDataForInitialURLFromFaviconService( |
| 572 const std::vector<favicon_base::FaviconRawBitmapResult>& | 574 const std::vector<favicon_base::FaviconRawBitmapResult>& |
| 573 favicon_bitmap_results) { | 575 favicon_bitmap_results) { |
| 574 got_favicon_from_history_ = true; | 576 got_favicon_from_history_ = true; |
| 575 bool has_results = !favicon_bitmap_results.empty(); | |
| 576 initial_history_result_expired_or_incomplete_ = HasExpiredOrIncompleteResult( | |
| 577 preferred_icon_size(), favicon_bitmap_results); | |
| 578 bool has_valid_result = HasValidResult(favicon_bitmap_results); | 577 bool has_valid_result = HasValidResult(favicon_bitmap_results); |
| 578 initial_history_result_expired_or_incomplete_ = |
| 579 !has_valid_result || |
| 580 HasExpiredOrIncompleteResult(preferred_icon_size(), |
| 581 favicon_bitmap_results); |
| 582 redownload_icons_ = initial_history_result_expired_or_incomplete_ && |
| 583 !favicon_bitmap_results.empty(); |
| 579 | 584 |
| 580 if (has_results && !download_largest_icon_ && | 585 if (has_valid_result && |
| 581 (!current_candidate() || | 586 (!current_candidate() || |
| 582 DoUrlsAndIconsMatch(*current_candidate(), favicon_bitmap_results))) { | 587 DoUrlsAndIconsMatch(*current_candidate(), favicon_bitmap_results))) { |
| 583 if (has_valid_result) { | 588 // The db knows the favicon (although it may be out of date) and the entry |
| 584 // The db knows the favicon (although it may be out of date) and the entry | 589 // doesn't have an icon. Set the favicon now, and if the favicon turns out |
| 585 // doesn't have an icon. Set the favicon now, and if the favicon turns out | 590 // to be expired (or the wrong url) we'll fetch later on. This way the |
| 586 // to be expired (or the wrong url) we'll fetch later on. This way the | 591 // user doesn't see a flash of the default favicon. |
| 587 // user doesn't see a flash of the default favicon. | 592 |
| 588 NotifyFaviconAvailable(favicon_bitmap_results); | 593 NotifyFaviconAvailable(favicon_bitmap_results); |
| 589 } else { | |
| 590 // If |favicon_bitmap_results| does not have any valid results, treat the | |
| 591 // favicon as if it's expired. | |
| 592 // TODO(pkotwicz): Do something better. | |
| 593 initial_history_result_expired_or_incomplete_ = true; | |
| 594 } | |
| 595 } | 594 } |
| 596 | 595 |
| 597 if (has_valid_result && download_largest_icon_) | |
| 598 NotifyFaviconAvailable(favicon_bitmap_results); | |
| 599 | |
| 600 if (current_candidate()) | 596 if (current_candidate()) |
| 601 OnGotInitialHistoryDataAndIconURLCandidates(); | 597 OnGotInitialHistoryDataAndIconURLCandidates(); |
| 602 } | 598 } |
| 603 | 599 |
| 604 void FaviconHandler::DownloadCurrentCandidateOrAskFaviconService() { | 600 void FaviconHandler::DownloadCurrentCandidateOrAskFaviconService() { |
| 605 GURL icon_url = current_candidate()->icon_url; | 601 GURL icon_url = current_candidate()->icon_url; |
| 606 favicon_base::IconType icon_type = current_candidate()->icon_type; | 602 favicon_base::IconType icon_type = current_candidate()->icon_type; |
| 607 | 603 |
| 608 if (initial_history_result_expired_or_incomplete_) { | 604 if (redownload_icons_) { |
| 609 // We have the mapping, but the favicon is out of date. Download it now. | 605 // We have the mapping, but the favicon is out of date. Download it now. |
| 610 ScheduleDownload(icon_url, icon_type); | 606 ScheduleDownload(icon_url, icon_type); |
| 611 } else { | 607 } else { |
| 612 // We don't know the favicon, but we may have previously downloaded the | 608 // We don't know the favicon, but we may have previously downloaded the |
| 613 // favicon for another page that shares the same favicon. Ask for the | 609 // favicon for another page that shares the same favicon. Ask for the |
| 614 // favicon given the favicon URL. | 610 // favicon given the favicon URL. |
| 615 if (driver_->IsOffTheRecord()) { | 611 if (driver_->IsOffTheRecord()) { |
| 616 GetFaviconFromFaviconService( | 612 GetFaviconFromFaviconService( |
| 617 icon_url, icon_type, | 613 icon_url, icon_type, |
| 618 base::Bind(&FaviconHandler::OnFaviconData, base::Unretained(this)), | 614 base::Bind(&FaviconHandler::OnFaviconData, base::Unretained(this)), |
| 619 &cancelable_task_tracker_); | 615 &cancelable_task_tracker_); |
| 620 } else { | 616 } else { |
| 621 // Ask the history service for the icon. This does two things: | 617 // Ask the history service for the icon. This does two things: |
| 622 // 1. Attempts to fetch the favicon data from the database. | 618 // 1. Attempts to fetch the favicon data from the database. |
| 623 // 2. If the favicon exists in the database, this updates the database to | 619 // 2. If the favicon exists in the database, this updates the database to |
| 624 // include the mapping between the page url and the favicon url. | 620 // include the mapping between the page url and the favicon url. |
| 625 // This is asynchronous. The history service will call back when done. | 621 // This is asynchronous. The history service will call back when done. |
| 626 UpdateFaviconMappingAndFetch( | 622 UpdateFaviconMappingAndFetch( |
| 627 url_, icon_url, icon_type, | 623 url_, icon_url, icon_type, |
| 628 base::Bind(&FaviconHandler::OnFaviconData, base::Unretained(this)), | 624 base::Bind(&FaviconHandler::OnFaviconData, base::Unretained(this)), |
| 629 &cancelable_task_tracker_); | 625 &cancelable_task_tracker_); |
| 630 } | 626 } |
| 631 } | 627 } |
| 632 } | 628 } |
| 633 | 629 |
| 634 void FaviconHandler::OnFaviconData(const std::vector< | 630 void FaviconHandler::OnFaviconData(const std::vector< |
| 635 favicon_base::FaviconRawBitmapResult>& favicon_bitmap_results) { | 631 favicon_base::FaviconRawBitmapResult>& favicon_bitmap_results) { |
| 636 bool has_results = !favicon_bitmap_results.empty(); | 632 bool has_results = !favicon_bitmap_results.empty(); |
| 637 bool has_expired_or_incomplete_result = HasExpiredOrIncompleteResult( | |
| 638 preferred_icon_size(), favicon_bitmap_results); | |
| 639 bool has_valid_result = HasValidResult(favicon_bitmap_results); | 633 bool has_valid_result = HasValidResult(favicon_bitmap_results); |
| 634 bool has_expired_or_incomplete_result = |
| 635 !has_valid_result || HasExpiredOrIncompleteResult(preferred_icon_size(), |
| 636 favicon_bitmap_results); |
| 640 | 637 |
| 641 if (has_valid_result) { | 638 if (has_valid_result) { |
| 642 // There is a valid favicon. Notify any observers. It is useful to notify | 639 // There is a valid favicon. Notify any observers. It is useful to notify |
| 643 // the observers even if the favicon is expired or incomplete (incorrect | 640 // the observers even if the favicon is expired or incomplete (incorrect |
| 644 // size) because temporarily showing the user an expired favicon or | 641 // size) because temporarily showing the user an expired favicon or |
| 645 // streched favicon is preferable to showing the user the default favicon. | 642 // streched favicon is preferable to showing the user the default favicon. |
| 646 NotifyFaviconAvailable(favicon_bitmap_results); | 643 NotifyFaviconAvailable(favicon_bitmap_results); |
| 647 } | 644 } |
| 648 | 645 |
| 649 if (!current_candidate() || | 646 if (!current_candidate() || |
| 650 (has_results && | 647 (has_results && |
| 651 !DoUrlsAndIconsMatch(*current_candidate(), favicon_bitmap_results))) { | 648 !DoUrlsAndIconsMatch(*current_candidate(), favicon_bitmap_results))) { |
| 652 // The icon URLs have been updated since the favicon data was requested. | 649 // The icon URLs have been updated since the favicon data was requested. |
| 653 return; | 650 return; |
| 654 } | 651 } |
| 655 | 652 |
| 656 if (!has_results || has_expired_or_incomplete_result) { | 653 if (has_expired_or_incomplete_result) { |
| 657 ScheduleDownload(current_candidate()->icon_url, | 654 ScheduleDownload(current_candidate()->icon_url, |
| 658 current_candidate()->icon_type); | 655 current_candidate()->icon_type); |
| 659 } | 656 } |
| 660 } | 657 } |
| 661 | 658 |
| 662 void FaviconHandler::ScheduleDownload(const GURL& image_url, | 659 void FaviconHandler::ScheduleDownload(const GURL& image_url, |
| 663 favicon_base::IconType icon_type) { | 660 favicon_base::IconType icon_type) { |
| 664 // A max bitmap size is specified to avoid receiving huge bitmaps in | 661 // A max bitmap size is specified to avoid receiving huge bitmaps in |
| 665 // OnDidDownloadFavicon(). See FaviconDriver::StartDownload() | 662 // OnDidDownloadFavicon(). See FaviconDriver::StartDownload() |
| 666 // for more details about the max bitmap size. | 663 // for more details about the max bitmap size. |
| 667 const int download_id = DownloadFavicon(image_url, | 664 const int download_id = DownloadFavicon(image_url, |
| 668 GetMaximalIconSize(icon_type)); | 665 GetMaximalIconSize(icon_type)); |
| 669 | 666 |
| 670 // Download ids should be unique. | 667 // Download ids should be unique. |
| 671 DCHECK(download_requests_.find(download_id) == download_requests_.end()); | 668 DCHECK(download_requests_.find(download_id) == download_requests_.end()); |
| 672 download_requests_[download_id] = DownloadRequest(image_url, icon_type); | 669 download_requests_[download_id] = DownloadRequest(image_url, icon_type); |
| 673 | 670 |
| 674 if (download_id == 0) { | 671 if (download_id == 0) { |
| 675 // If DownloadFavicon() did not start a download, it returns a download id | 672 // If DownloadFavicon() did not start a download, it returns a download id |
| 676 // of 0. We still need to call OnDidDownloadFavicon() because the method is | 673 // of 0. We still need to call OnDidDownloadFavicon() because the method is |
| 677 // responsible for initiating the data request for the next candidate. | 674 // responsible for initiating the data request for the next candidate. |
| 678 OnDidDownloadFavicon(download_id, image_url, std::vector<SkBitmap>(), | 675 OnDidDownloadFavicon(download_id, image_url, std::vector<SkBitmap>(), |
| 679 std::vector<gfx::Size>()); | 676 std::vector<gfx::Size>()); |
| 680 | 677 |
| 681 } | 678 } |
| 682 } | 679 } |
| 683 | 680 |
| 684 } // namespace favicon | 681 } // namespace favicon |
| OLD | NEW |