| 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 "chrome/browser/favicon/favicon_handler.h" | 5 #include "chrome/browser/favicon/favicon_handler.h" |
| 6 | 6 |
| 7 #include "build/build_config.h" | 7 #include "build/build_config.h" |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 54 const GURL& url, | 54 const GURL& url, |
| 55 favicon_base::IconType icon_type) { | 55 favicon_base::IconType icon_type) { |
| 56 return favicon_url.icon_url == url && favicon_url.icon_type == icon_type; | 56 return favicon_url.icon_url == url && favicon_url.icon_type == icon_type; |
| 57 } | 57 } |
| 58 | 58 |
| 59 // Returns true if all of the icon URLs and icon types in |bitmap_results| are | 59 // Returns true if all of the icon URLs and icon types in |bitmap_results| are |
| 60 // identical and if they match the icon URL and icon type in |favicon_url|. | 60 // identical and if they match the icon URL and icon type in |favicon_url|. |
| 61 // Returns false if |bitmap_results| is empty. | 61 // Returns false if |bitmap_results| is empty. |
| 62 bool DoUrlsAndIconsMatch( | 62 bool DoUrlsAndIconsMatch( |
| 63 const FaviconURL& favicon_url, | 63 const FaviconURL& favicon_url, |
| 64 const std::vector<favicon_base::FaviconBitmapResult>& bitmap_results) { | 64 const std::vector<favicon_base::FaviconRawBitmapResult>& bitmap_results) { |
| 65 if (bitmap_results.empty()) | 65 if (bitmap_results.empty()) |
| 66 return false; | 66 return false; |
| 67 | 67 |
| 68 const favicon_base::IconType icon_type = favicon_url.icon_type; | 68 const favicon_base::IconType icon_type = favicon_url.icon_type; |
| 69 | 69 |
| 70 for (size_t i = 0; i < bitmap_results.size(); ++i) { | 70 for (size_t i = 0; i < bitmap_results.size(); ++i) { |
| 71 if (favicon_url.icon_url != bitmap_results[i].icon_url || | 71 if (favicon_url.icon_url != bitmap_results[i].icon_url || |
| 72 icon_type != bitmap_results[i].icon_type) { | 72 icon_type != bitmap_results[i].icon_type) { |
| 73 return false; | 73 return false; |
| 74 } | 74 } |
| 75 } | 75 } |
| 76 return true; | 76 return true; |
| 77 } | 77 } |
| 78 | 78 |
| 79 std::string UrlWithoutFragment(const GURL& gurl) { | 79 std::string UrlWithoutFragment(const GURL& gurl) { |
| 80 GURL::Replacements replacements; | 80 GURL::Replacements replacements; |
| 81 replacements.ClearRef(); | 81 replacements.ClearRef(); |
| 82 return gurl.ReplaceComponents(replacements).spec(); | 82 return gurl.ReplaceComponents(replacements).spec(); |
| 83 } | 83 } |
| 84 | 84 |
| 85 bool UrlMatches(const GURL& gurl_a, const GURL& gurl_b) { | 85 bool UrlMatches(const GURL& gurl_a, const GURL& gurl_b) { |
| 86 return UrlWithoutFragment(gurl_a) == UrlWithoutFragment(gurl_b); | 86 return UrlWithoutFragment(gurl_a) == UrlWithoutFragment(gurl_b); |
| 87 } | 87 } |
| 88 | 88 |
| 89 // Return true if |bitmap_result| is expired. | 89 // Return true if |bitmap_result| is expired. |
| 90 bool IsExpired(const favicon_base::FaviconBitmapResult& bitmap_result) { | 90 bool IsExpired(const favicon_base::FaviconRawBitmapResult& bitmap_result) { |
| 91 return bitmap_result.expired; | 91 return bitmap_result.expired; |
| 92 } | 92 } |
| 93 | 93 |
| 94 // Return true if |bitmap_result| is valid. | 94 // Return true if |bitmap_result| is valid. |
| 95 bool IsValid(const favicon_base::FaviconBitmapResult& bitmap_result) { | 95 bool IsValid(const favicon_base::FaviconRawBitmapResult& bitmap_result) { |
| 96 return bitmap_result.is_valid(); | 96 return bitmap_result.is_valid(); |
| 97 } | 97 } |
| 98 | 98 |
| 99 // Returns true if at least one of the bitmaps in |bitmap_results| is expired or | 99 // Returns true if at least one of the bitmaps in |bitmap_results| is expired or |
| 100 // if |bitmap_results| is missing favicons for |desired_size_in_dip| and one of | 100 // if |bitmap_results| is missing favicons for |desired_size_in_dip| and one of |
| 101 // the scale factors in FaviconUtil::GetFaviconScaleFactors(). | 101 // the scale factors in FaviconUtil::GetFaviconScaleFactors(). |
| 102 bool HasExpiredOrIncompleteResult( | 102 bool HasExpiredOrIncompleteResult( |
| 103 int desired_size_in_dip, | 103 int desired_size_in_dip, |
| 104 const std::vector<favicon_base::FaviconBitmapResult>& bitmap_results) { | 104 const std::vector<favicon_base::FaviconRawBitmapResult>& bitmap_results) { |
| 105 // Check if at least one of the bitmaps is expired. | 105 // Check if at least one of the bitmaps is expired. |
| 106 std::vector<favicon_base::FaviconBitmapResult>::const_iterator it = | 106 std::vector<favicon_base::FaviconRawBitmapResult>::const_iterator it = |
| 107 std::find_if(bitmap_results.begin(), bitmap_results.end(), IsExpired); | 107 std::find_if(bitmap_results.begin(), bitmap_results.end(), IsExpired); |
| 108 if (it != bitmap_results.end()) | 108 if (it != bitmap_results.end()) |
| 109 return true; | 109 return true; |
| 110 | 110 |
| 111 // Any favicon size is good if the desired size is 0. | 111 // Any favicon size is good if the desired size is 0. |
| 112 if (desired_size_in_dip == 0) | 112 if (desired_size_in_dip == 0) |
| 113 return false; | 113 return false; |
| 114 | 114 |
| 115 // Check if the favicon for at least one of the scale factors is missing. | 115 // Check if the favicon for at least one of the scale factors is missing. |
| 116 // |bitmap_results| should always be complete for data inserted by | 116 // |bitmap_results| should always be complete for data inserted by |
| (...skipping 14 matching lines...) Expand all Loading... |
| 131 std::vector<gfx::Size>::iterator it = std::find(favicon_sizes.begin(), | 131 std::vector<gfx::Size>::iterator it = std::find(favicon_sizes.begin(), |
| 132 favicon_sizes.end(), gfx::Size(edge_size_in_pixel, edge_size_in_pixel)); | 132 favicon_sizes.end(), gfx::Size(edge_size_in_pixel, edge_size_in_pixel)); |
| 133 if (it == favicon_sizes.end()) | 133 if (it == favicon_sizes.end()) |
| 134 return true; | 134 return true; |
| 135 } | 135 } |
| 136 return false; | 136 return false; |
| 137 } | 137 } |
| 138 | 138 |
| 139 // Returns true if at least one of |bitmap_results| is valid. | 139 // Returns true if at least one of |bitmap_results| is valid. |
| 140 bool HasValidResult( | 140 bool HasValidResult( |
| 141 const std::vector<favicon_base::FaviconBitmapResult>& bitmap_results) { | 141 const std::vector<favicon_base::FaviconRawBitmapResult>& bitmap_results) { |
| 142 return std::find_if(bitmap_results.begin(), bitmap_results.end(), IsValid) != | 142 return std::find_if(bitmap_results.begin(), bitmap_results.end(), IsValid) != |
| 143 bitmap_results.end(); | 143 bitmap_results.end(); |
| 144 } | 144 } |
| 145 | 145 |
| 146 // Returns the index of the entry with the largest area that is not larger than | 146 // Returns the index of the entry with the largest area that is not larger than |
| 147 // |max_area|; -1 if there is no such match. | 147 // |max_area|; -1 if there is no such match. |
| 148 int GetLargestSizeIndex(const std::vector<gfx::Size>& sizes, int max_area) { | 148 int GetLargestSizeIndex(const std::vector<gfx::Size>& sizes, int max_area) { |
| 149 DCHECK(!sizes.empty()); | 149 DCHECK(!sizes.empty()); |
| 150 int ret = -1; | 150 int ret = -1; |
| 151 for (size_t i = 0; i < sizes.size(); ++i) { | 151 for (size_t i = 0; i < sizes.size(); ++i) { |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 307 if (client_->GetFaviconService() && ShouldSaveFavicon(url)) | 307 if (client_->GetFaviconService() && ShouldSaveFavicon(url)) |
| 308 SetHistoryFavicons(url, icon_url, icon_type, image); | 308 SetHistoryFavicons(url, icon_url, icon_type, image); |
| 309 | 309 |
| 310 if (UrlMatches(url, url_) && icon_type == favicon_base::FAVICON) { | 310 if (UrlMatches(url, url_) && icon_type == favicon_base::FAVICON) { |
| 311 if (!PageChangedSinceFaviconWasRequested()) | 311 if (!PageChangedSinceFaviconWasRequested()) |
| 312 SetFaviconOnActivePage(icon_url, image); | 312 SetFaviconOnActivePage(icon_url, image); |
| 313 } | 313 } |
| 314 } | 314 } |
| 315 | 315 |
| 316 void FaviconHandler::SetFaviconOnActivePage(const std::vector< | 316 void FaviconHandler::SetFaviconOnActivePage(const std::vector< |
| 317 favicon_base::FaviconBitmapResult>& favicon_bitmap_results) { | 317 favicon_base::FaviconRawBitmapResult>& favicon_bitmap_results) { |
| 318 gfx::Image resized_image = FaviconUtil::SelectFaviconFramesFromPNGs( | 318 gfx::Image resized_image = FaviconUtil::SelectFaviconFramesFromPNGs( |
| 319 favicon_bitmap_results, | 319 favicon_bitmap_results, |
| 320 FaviconUtil::GetFaviconScaleFactors(), | 320 FaviconUtil::GetFaviconScaleFactors(), |
| 321 preferred_icon_size()); | 321 preferred_icon_size()); |
| 322 // The history service sends back results for a single icon URL, so it does | 322 // The history service sends back results for a single icon URL, so it does |
| 323 // not matter which result we get the |icon_url| from. | 323 // not matter which result we get the |icon_url| from. |
| 324 const GURL icon_url = favicon_bitmap_results.empty() ? | 324 const GURL icon_url = favicon_bitmap_results.empty() ? |
| 325 GURL() : favicon_bitmap_results[0].icon_url; | 325 GURL() : favicon_bitmap_results[0].icon_url; |
| 326 SetFaviconOnActivePage(icon_url, resized_image); | 326 SetFaviconOnActivePage(icon_url, resized_image); |
| 327 } | 327 } |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 505 base::CancelableTaskTracker* tracker) { | 505 base::CancelableTaskTracker* tracker) { |
| 506 client_->GetFaviconService()->GetFavicon( | 506 client_->GetFaviconService()->GetFavicon( |
| 507 icon_url, icon_type, preferred_icon_size(), callback, tracker); | 507 icon_url, icon_type, preferred_icon_size(), callback, tracker); |
| 508 } | 508 } |
| 509 | 509 |
| 510 void FaviconHandler::GetFaviconForURLFromFaviconService( | 510 void FaviconHandler::GetFaviconForURLFromFaviconService( |
| 511 const GURL& page_url, | 511 const GURL& page_url, |
| 512 int icon_types, | 512 int icon_types, |
| 513 const favicon_base::FaviconResultsCallback& callback, | 513 const favicon_base::FaviconResultsCallback& callback, |
| 514 base::CancelableTaskTracker* tracker) { | 514 base::CancelableTaskTracker* tracker) { |
| 515 client_->GetFaviconService()->GetFaviconForURL( | 515 client_->GetFaviconService()->GetFaviconForPageURL( |
| 516 FaviconService::FaviconForURLParams( | 516 FaviconService::FaviconForPageURLParams( |
| 517 page_url, icon_types, preferred_icon_size()), | 517 page_url, icon_types, preferred_icon_size()), |
| 518 callback, | 518 callback, |
| 519 tracker); | 519 tracker); |
| 520 } | 520 } |
| 521 | 521 |
| 522 void FaviconHandler::SetHistoryFavicons(const GURL& page_url, | 522 void FaviconHandler::SetHistoryFavicons(const GURL& page_url, |
| 523 const GURL& icon_url, | 523 const GURL& icon_url, |
| 524 favicon_base::IconType icon_type, | 524 favicon_base::IconType icon_type, |
| 525 const gfx::Image& image) { | 525 const gfx::Image& image) { |
| 526 client_->GetFaviconService()->SetFavicons( | 526 client_->GetFaviconService()->SetFavicons( |
| 527 page_url, icon_url, icon_type, image); | 527 page_url, icon_url, icon_type, image); |
| 528 } | 528 } |
| 529 | 529 |
| 530 bool FaviconHandler::ShouldSaveFavicon(const GURL& url) { | 530 bool FaviconHandler::ShouldSaveFavicon(const GURL& url) { |
| 531 if (!driver_->IsOffTheRecord()) | 531 if (!driver_->IsOffTheRecord()) |
| 532 return true; | 532 return true; |
| 533 | 533 |
| 534 // Otherwise store the favicon if the page is bookmarked. | 534 // Otherwise store the favicon if the page is bookmarked. |
| 535 return client_->IsBookmarked(url); | 535 return client_->IsBookmarked(url); |
| 536 } | 536 } |
| 537 | 537 |
| 538 void FaviconHandler::NotifyFaviconUpdated(bool icon_url_changed) { | 538 void FaviconHandler::NotifyFaviconUpdated(bool icon_url_changed) { |
| 539 driver_->NotifyFaviconUpdated(icon_url_changed); | 539 driver_->NotifyFaviconUpdated(icon_url_changed); |
| 540 } | 540 } |
| 541 | 541 |
| 542 void FaviconHandler::OnFaviconDataForInitialURLFromFaviconService( | 542 void FaviconHandler::OnFaviconDataForInitialURLFromFaviconService( |
| 543 const std::vector<favicon_base::FaviconBitmapResult>& | 543 const std::vector<favicon_base::FaviconRawBitmapResult>& |
| 544 favicon_bitmap_results) { | 544 favicon_bitmap_results) { |
| 545 if (PageChangedSinceFaviconWasRequested()) | 545 if (PageChangedSinceFaviconWasRequested()) |
| 546 return; | 546 return; |
| 547 got_favicon_from_history_ = true; | 547 got_favicon_from_history_ = true; |
| 548 history_results_ = favicon_bitmap_results; | 548 history_results_ = favicon_bitmap_results; |
| 549 bool has_results = !favicon_bitmap_results.empty(); | 549 bool has_results = !favicon_bitmap_results.empty(); |
| 550 favicon_expired_or_incomplete_ = has_results && HasExpiredOrIncompleteResult( | 550 favicon_expired_or_incomplete_ = has_results && HasExpiredOrIncompleteResult( |
| 551 preferred_icon_size(), favicon_bitmap_results); | 551 preferred_icon_size(), favicon_bitmap_results); |
| 552 if (has_results && icon_types_ == favicon_base::FAVICON && | 552 if (has_results && icon_types_ == favicon_base::FAVICON && |
| 553 !driver_->GetActiveFaviconValidity() && | 553 !driver_->GetActiveFaviconValidity() && |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 612 // This is asynchronous. The history service will call back when done. | 612 // This is asynchronous. The history service will call back when done. |
| 613 UpdateFaviconMappingAndFetch( | 613 UpdateFaviconMappingAndFetch( |
| 614 page_url, icon_url, icon_type, | 614 page_url, icon_url, icon_type, |
| 615 base::Bind(&FaviconHandler::OnFaviconData, base::Unretained(this)), | 615 base::Bind(&FaviconHandler::OnFaviconData, base::Unretained(this)), |
| 616 &cancelable_task_tracker_); | 616 &cancelable_task_tracker_); |
| 617 } | 617 } |
| 618 } | 618 } |
| 619 } | 619 } |
| 620 | 620 |
| 621 void FaviconHandler::OnFaviconData(const std::vector< | 621 void FaviconHandler::OnFaviconData(const std::vector< |
| 622 favicon_base::FaviconBitmapResult>& favicon_bitmap_results) { | 622 favicon_base::FaviconRawBitmapResult>& favicon_bitmap_results) { |
| 623 if (PageChangedSinceFaviconWasRequested()) | 623 if (PageChangedSinceFaviconWasRequested()) |
| 624 return; | 624 return; |
| 625 | 625 |
| 626 bool has_results = !favicon_bitmap_results.empty(); | 626 bool has_results = !favicon_bitmap_results.empty(); |
| 627 bool has_expired_or_incomplete_result = HasExpiredOrIncompleteResult( | 627 bool has_expired_or_incomplete_result = HasExpiredOrIncompleteResult( |
| 628 preferred_icon_size(), favicon_bitmap_results); | 628 preferred_icon_size(), favicon_bitmap_results); |
| 629 | 629 |
| 630 if (has_results && icon_types_ == favicon_base::FAVICON) { | 630 if (has_results && icon_types_ == favicon_base::FAVICON) { |
| 631 if (HasValidResult(favicon_bitmap_results)) { | 631 if (HasValidResult(favicon_bitmap_results)) { |
| 632 // There is a favicon, set it now. If expired we'll download the current | 632 // There is a favicon, set it now. If expired we'll download the current |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 684 } else { | 684 } else { |
| 685 gfx::Size largest = i->icon_sizes[index]; | 685 gfx::Size largest = i->icon_sizes[index]; |
| 686 i->icon_sizes.clear(); | 686 i->icon_sizes.clear(); |
| 687 i->icon_sizes.push_back(largest); | 687 i->icon_sizes.push_back(largest); |
| 688 ++i; | 688 ++i; |
| 689 } | 689 } |
| 690 } | 690 } |
| 691 std::stable_sort(image_urls_.begin(), image_urls_.end(), | 691 std::stable_sort(image_urls_.begin(), image_urls_.end(), |
| 692 CompareIconSize); | 692 CompareIconSize); |
| 693 } | 693 } |
| OLD | NEW |