| 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 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 87 // Return true if |bitmap_result| is expired. | 87 // Return true if |bitmap_result| is expired. |
| 88 bool IsExpired(const history::FaviconBitmapResult& bitmap_result) { | 88 bool IsExpired(const history::FaviconBitmapResult& bitmap_result) { |
| 89 return bitmap_result.expired; | 89 return bitmap_result.expired; |
| 90 } | 90 } |
| 91 | 91 |
| 92 // Return true if |bitmap_result| is valid. | 92 // Return true if |bitmap_result| is valid. |
| 93 bool IsValid(const history::FaviconBitmapResult& bitmap_result) { | 93 bool IsValid(const history::FaviconBitmapResult& bitmap_result) { |
| 94 return bitmap_result.is_valid(); | 94 return bitmap_result.is_valid(); |
| 95 } | 95 } |
| 96 | 96 |
| 97 // Return list with the current value and historical values of | |
| 98 // history::GetDefaultFaviconSizes(). | |
| 99 const std::vector<history::FaviconSizes>& GetHistoricalDefaultFaviconSizes() { | |
| 100 CR_DEFINE_STATIC_LOCAL( | |
| 101 std::vector<history::FaviconSizes>, kHistoricalFaviconSizes, ()); | |
| 102 if (kHistoricalFaviconSizes.empty()) { | |
| 103 kHistoricalFaviconSizes.push_back(history::GetDefaultFaviconSizes()); | |
| 104 // The default favicon sizes used to be a single empty size. | |
| 105 history::FaviconSizes old_favicon_sizes; | |
| 106 old_favicon_sizes.push_back(gfx::Size()); | |
| 107 kHistoricalFaviconSizes.push_back(old_favicon_sizes); | |
| 108 } | |
| 109 return kHistoricalFaviconSizes; | |
| 110 } | |
| 111 | |
| 112 // Returns true if at least one of the bitmaps in |bitmap_results| is expired or | 97 // Returns true if at least one of the bitmaps in |bitmap_results| is expired or |
| 113 // if |bitmap_results| is known to be incomplete. | 98 // if |bitmap_results| is missing favicons for |desired_size_in_dip| and one of |
| 99 // the scale factors in FaviconUtil::GetFaviconScaleFactors(). |
| 114 bool HasExpiredOrIncompleteResult( | 100 bool HasExpiredOrIncompleteResult( |
| 115 const std::vector<history::FaviconBitmapResult>& bitmap_results, | 101 int desired_size_in_dip, |
| 116 const history::IconURLSizesMap& icon_url_sizes) { | 102 const std::vector<history::FaviconBitmapResult>& bitmap_results) { |
| 117 // Check if at least one of the bitmaps is expired. | 103 // Check if at least one of the bitmaps is expired. |
| 118 std::vector<history::FaviconBitmapResult>::const_iterator it = | 104 std::vector<history::FaviconBitmapResult>::const_iterator it = |
| 119 std::find_if(bitmap_results.begin(), bitmap_results.end(), IsExpired); | 105 std::find_if(bitmap_results.begin(), bitmap_results.end(), IsExpired); |
| 120 if (it != bitmap_results.end()) | 106 if (it != bitmap_results.end()) |
| 121 return true; | 107 return true; |
| 122 | 108 |
| 123 // |bitmap_results| is known to be incomplete if the favicon sizes in | 109 // Any favicon size is good if the desired size is 0. |
| 124 // |icon_url_sizes| for any of the icon URLs in |bitmap_results| are unknown. | 110 if (desired_size_in_dip == 0) |
| 125 // The favicon sizes for an icon URL are unknown if MergeFavicon() has set | 111 return false; |
| 126 // them to the default favicon sizes. | |
| 127 | 112 |
| 128 std::set<GURL> icon_urls; | 113 // Check if the favicon for at least one of the scale factors is missing. |
| 114 // |bitmap_results| should always be complete for data inserted by |
| 115 // FaviconHandler as the FaviconHandler stores favicons resized to all |
| 116 // of FaviconUtil::GetFaviconScaleFactors() into the history backend. |
| 117 // Examples of when |bitmap_results| can be incomplete: |
| 118 // - Favicons inserted into the history backend by sync. |
| 119 // - Favicons for imported bookmarks. |
| 120 std::vector<gfx::Size> favicon_sizes; |
| 129 for (size_t i = 0; i < bitmap_results.size(); ++i) | 121 for (size_t i = 0; i < bitmap_results.size(); ++i) |
| 130 icon_urls.insert(bitmap_results[i].icon_url); | 122 favicon_sizes.push_back(bitmap_results[i].pixel_size); |
| 131 | 123 |
| 132 for (std::set<GURL>::iterator it = icon_urls.begin(); it != icon_urls.end(); | 124 std::vector<ui::ScaleFactor> scale_factors = |
| 133 ++it) { | 125 FaviconUtil::GetFaviconScaleFactors(); |
| 134 const GURL& icon_url = *it; | 126 for (size_t i = 0; i < scale_factors.size(); ++i) { |
| 135 history::IconURLSizesMap::const_iterator icon_url_sizes_it = | 127 int edge_size_in_pixel = floor( |
| 136 icon_url_sizes.find(icon_url); | 128 desired_size_in_dip * ui::GetScaleFactorScale(scale_factors[i])); |
| 137 if (icon_url_sizes_it == icon_url_sizes.end()) { | 129 std::vector<gfx::Size>::iterator it = std::find(favicon_sizes.begin(), |
| 138 // |icon_url_sizes| should have an entry for each icon URL in | 130 favicon_sizes.end(), gfx::Size(edge_size_in_pixel, edge_size_in_pixel)); |
| 139 // |bitmap_results|. | 131 if (it == favicon_sizes.end()) |
| 140 NOTREACHED(); | |
| 141 return true; | |
| 142 } | |
| 143 | |
| 144 const history::FaviconSizes& sizes = icon_url_sizes_it->second; | |
| 145 const std::vector<history::FaviconSizes>& historical_sizes = | |
| 146 GetHistoricalDefaultFaviconSizes(); | |
| 147 std::vector<history::FaviconSizes>::const_iterator historical_it = | |
| 148 std::find(historical_sizes.begin(), historical_sizes.end(), sizes); | |
| 149 if (historical_it != historical_sizes.end()) | |
| 150 return true; | 132 return true; |
| 151 } | 133 } |
| 152 return false; | 134 return false; |
| 153 } | 135 } |
| 154 | 136 |
| 155 // Returns true if at least one of |bitmap_results| is valid. | 137 // Returns true if at least one of |bitmap_results| is valid. |
| 156 bool HasValidResult( | 138 bool HasValidResult( |
| 157 const std::vector<history::FaviconBitmapResult>& bitmap_results) { | 139 const std::vector<history::FaviconBitmapResult>& bitmap_results) { |
| 158 std::vector<history::FaviconBitmapResult>::const_iterator it = | 140 std::vector<history::FaviconBitmapResult>::const_iterator it = |
| 159 std::find_if(bitmap_results.begin(), bitmap_results.end(), IsValid); | 141 std::find_if(bitmap_results.begin(), bitmap_results.end(), IsValid); |
| (...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 476 if (!profile_->IsOffTheRecord()) | 458 if (!profile_->IsOffTheRecord()) |
| 477 return true; | 459 return true; |
| 478 | 460 |
| 479 // Otherwise store the favicon if the page is bookmarked. | 461 // Otherwise store the favicon if the page is bookmarked. |
| 480 BookmarkService* bookmark_service = | 462 BookmarkService* bookmark_service = |
| 481 BookmarkService::FromBrowserContext(profile_); | 463 BookmarkService::FromBrowserContext(profile_); |
| 482 return bookmark_service && bookmark_service->IsBookmarked(url); | 464 return bookmark_service && bookmark_service->IsBookmarked(url); |
| 483 } | 465 } |
| 484 | 466 |
| 485 void FaviconHandler::OnFaviconDataForInitialURL( | 467 void FaviconHandler::OnFaviconDataForInitialURL( |
| 486 const std::vector<history::FaviconBitmapResult>& favicon_bitmap_results, | 468 const std::vector<history::FaviconBitmapResult>& favicon_bitmap_results) { |
| 487 const history::IconURLSizesMap& icon_url_sizes) { | |
| 488 NavigationEntry* entry = GetEntry(); | 469 NavigationEntry* entry = GetEntry(); |
| 489 if (!entry) | 470 if (!entry) |
| 490 return; | 471 return; |
| 491 | 472 |
| 492 got_favicon_from_history_ = true; | 473 got_favicon_from_history_ = true; |
| 493 history_results_ = favicon_bitmap_results; | 474 history_results_ = favicon_bitmap_results; |
| 494 | 475 |
| 495 bool has_results = !favicon_bitmap_results.empty(); | 476 bool has_results = !favicon_bitmap_results.empty(); |
| 496 favicon_expired_or_incomplete_ = has_results && HasExpiredOrIncompleteResult( | 477 favicon_expired_or_incomplete_ = has_results && HasExpiredOrIncompleteResult( |
| 497 favicon_bitmap_results, icon_url_sizes); | 478 preferred_icon_size(), favicon_bitmap_results); |
| 498 | 479 |
| 499 if (has_results && icon_types_ == history::FAVICON && | 480 if (has_results && icon_types_ == history::FAVICON && |
| 500 !entry->GetFavicon().valid && | 481 !entry->GetFavicon().valid && |
| 501 (!current_candidate() || | 482 (!current_candidate() || |
| 502 DoUrlsAndIconsMatch(*current_candidate(), favicon_bitmap_results))) { | 483 DoUrlsAndIconsMatch(*current_candidate(), favicon_bitmap_results))) { |
| 503 // The db knows the favicon (although it may be out of date) and the entry | 484 // The db knows the favicon (although it may be out of date) and the entry |
| 504 // doesn't have an icon. Set the favicon now, and if the favicon turns out | 485 // doesn't have an icon. Set the favicon now, and if the favicon turns out |
| 505 // to be expired (or the wrong url) we'll fetch later on. This way the | 486 // to be expired (or the wrong url) we'll fetch later on. This way the |
| 506 // user doesn't see a flash of the default favicon. | 487 // user doesn't see a flash of the default favicon. |
| 507 | 488 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 559 // Issue the request and associate the current page ID with it. | 540 // Issue the request and associate the current page ID with it. |
| 560 UpdateFaviconMappingAndFetch( | 541 UpdateFaviconMappingAndFetch( |
| 561 page_url, icon_url, icon_type, | 542 page_url, icon_url, icon_type, |
| 562 base::Bind(&FaviconHandler::OnFaviconData, base::Unretained(this)), | 543 base::Bind(&FaviconHandler::OnFaviconData, base::Unretained(this)), |
| 563 &cancelable_task_tracker_); | 544 &cancelable_task_tracker_); |
| 564 } | 545 } |
| 565 } | 546 } |
| 566 } | 547 } |
| 567 | 548 |
| 568 void FaviconHandler::OnFaviconData( | 549 void FaviconHandler::OnFaviconData( |
| 569 const std::vector<history::FaviconBitmapResult>& favicon_bitmap_results, | 550 const std::vector<history::FaviconBitmapResult>& favicon_bitmap_results) { |
| 570 const history::IconURLSizesMap& icon_url_sizes) { | |
| 571 NavigationEntry* entry = GetEntry(); | 551 NavigationEntry* entry = GetEntry(); |
| 572 if (!entry) | 552 if (!entry) |
| 573 return; | 553 return; |
| 574 | 554 |
| 575 bool has_results = !favicon_bitmap_results.empty(); | 555 bool has_results = !favicon_bitmap_results.empty(); |
| 576 bool has_expired_or_incomplete_result = HasExpiredOrIncompleteResult( | 556 bool has_expired_or_incomplete_result = HasExpiredOrIncompleteResult( |
| 577 favicon_bitmap_results, icon_url_sizes); | 557 preferred_icon_size(), favicon_bitmap_results); |
| 578 | 558 |
| 579 // No need to update the favicon url. By the time we get here | 559 // No need to update the favicon url. By the time we get here |
| 580 // UpdateFaviconURL will have set the favicon url. | 560 // UpdateFaviconURL will have set the favicon url. |
| 581 if (has_results && icon_types_ == history::FAVICON) { | 561 if (has_results && icon_types_ == history::FAVICON) { |
| 582 if (HasValidResult(favicon_bitmap_results)) { | 562 if (HasValidResult(favicon_bitmap_results)) { |
| 583 // There is a favicon, set it now. If expired we'll download the current | 563 // There is a favicon, set it now. If expired we'll download the current |
| 584 // one again, but at least the user will get some icon instead of the | 564 // one again, but at least the user will get some icon instead of the |
| 585 // default and most likely the current one is fine anyway. | 565 // default and most likely the current one is fine anyway. |
| 586 UpdateFavicon(entry, favicon_bitmap_results); | 566 UpdateFavicon(entry, favicon_bitmap_results); |
| 587 } | 567 } |
| (...skipping 23 matching lines...) Expand all Loading... |
| 611 const int download_id = DownloadFavicon(image_url, image_size); | 591 const int download_id = DownloadFavicon(image_url, image_size); |
| 612 if (download_id) { | 592 if (download_id) { |
| 613 // Download ids should be unique. | 593 // Download ids should be unique. |
| 614 DCHECK(download_requests_.find(download_id) == download_requests_.end()); | 594 DCHECK(download_requests_.find(download_id) == download_requests_.end()); |
| 615 download_requests_[download_id] = | 595 download_requests_[download_id] = |
| 616 DownloadRequest(url, image_url, icon_type); | 596 DownloadRequest(url, image_url, icon_type); |
| 617 } | 597 } |
| 618 | 598 |
| 619 return download_id; | 599 return download_id; |
| 620 } | 600 } |
| OLD | NEW |