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 |