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

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

Issue 10918186: Expire favicons which were added with default favicon sizes (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 3 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 | Annotate | Revision Log
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 "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 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 // Return true if |bitmap_result| is expired. 88 // Return true if |bitmap_result| is expired.
89 bool IsExpired(const history::FaviconBitmapResult& bitmap_result) { 89 bool IsExpired(const history::FaviconBitmapResult& bitmap_result) {
90 return bitmap_result.expired; 90 return bitmap_result.expired;
91 } 91 }
92 92
93 // Return true if |bitmap_result| is valid. 93 // Return true if |bitmap_result| is valid.
94 bool IsValid(const history::FaviconBitmapResult& bitmap_result) { 94 bool IsValid(const history::FaviconBitmapResult& bitmap_result) {
95 return bitmap_result.is_valid(); 95 return bitmap_result.is_valid();
96 } 96 }
97 97
98 // Returns true if at least one of the bitmaps in |bitmap_results| is expired. 98 // Return list with the current value and historical values of
99 bool HasExpiredResult( 99 // history::GetDefaultFaviconSizes().
100 const std::vector<history::FaviconBitmapResult>& bitmap_results) { 100 const std::vector<history::FaviconSizes>& GetHistoricalDefaultFaviconSizes() {
101 CR_DEFINE_STATIC_LOCAL(
102 std::vector<history::FaviconSizes>, kHistoricalFaviconSizes, ());
103 if (kHistoricalFaviconSizes.empty()) {
104 kHistoricalFaviconSizes.push_back(history::GetDefaultFaviconSizes());
105 // The default favicon sizes used to be a single empty size.
106 history::FaviconSizes old_favicon_sizes;
107 old_favicon_sizes.push_back(gfx::Size());
108 kHistoricalFaviconSizes.push_back(old_favicon_sizes);
109 }
110 return kHistoricalFaviconSizes;
111 }
112
113 // Returns true if at least one of the bitmaps in |bitmap_results| is expired or
114 // if |bitmap_results| is known to be incomplete.
115 bool HasExpiredOrIncompleteResult(
116 const std::vector<history::FaviconBitmapResult>& bitmap_results,
117 const history::IconURLSizesMap& icon_url_sizes) {
118 // Check if at least one of the bitmaps is expired.
101 std::vector<history::FaviconBitmapResult>::const_iterator it = 119 std::vector<history::FaviconBitmapResult>::const_iterator it =
102 std::find_if(bitmap_results.begin(), bitmap_results.end(), IsExpired); 120 std::find_if(bitmap_results.begin(), bitmap_results.end(), IsExpired);
103 return it != bitmap_results.end(); 121 if (it != bitmap_results.end())
122 return true;
123
124 // |bitmap_results| is known to be incomplete if the favicon sizes in
125 // |icon_url_sizes| for any of the icon URLs in |bitmap_results| are unknown.
126 // The favicon sizes for an icon URL are unknown if MergeFavicon() has set
127 // them to the default favicon sizes.
128
129 std::set<GURL> icon_urls;
130 for (size_t i = 0; i < bitmap_results.size(); ++i)
131 icon_urls.insert(bitmap_results[i].icon_url);
132
133 for (std::set<GURL>::iterator it = icon_urls.begin(); it != icon_urls.end();
134 ++it) {
135 const GURL& icon_url = *it;
136 history::IconURLSizesMap::const_iterator icon_url_sizes_it =
137 icon_url_sizes.find(icon_url);
138 if (icon_url_sizes_it == icon_url_sizes.end()) {
139 // |icon_url_sizes| should have an entry for each icon URL in
140 // |bitmap_results|.
141 NOTREACHED();
142 return true;
143 }
144
145 const history::FaviconSizes& sizes = icon_url_sizes_it->second;
146 const std::vector<history::FaviconSizes>& historical_sizes =
147 GetHistoricalDefaultFaviconSizes();
148 std::vector<history::FaviconSizes>::const_iterator historical_it =
149 std::find(historical_sizes.begin(), historical_sizes.end(), sizes);
150 if (historical_it != historical_sizes.end())
151 return true;
152 }
153 return false;
104 } 154 }
105 155
106 // Returns true if at least one of |bitmap_results| is valid. 156 // Returns true if at least one of |bitmap_results| is valid.
107 bool HasValidResult( 157 bool HasValidResult(
108 const std::vector<history::FaviconBitmapResult>& bitmap_results) { 158 const std::vector<history::FaviconBitmapResult>& bitmap_results) {
109 std::vector<history::FaviconBitmapResult>::const_iterator it = 159 std::vector<history::FaviconBitmapResult>::const_iterator it =
110 std::find_if(bitmap_results.begin(), bitmap_results.end(), IsValid); 160 std::find_if(bitmap_results.begin(), bitmap_results.end(), IsValid);
111 return it != bitmap_results.end(); 161 return it != bitmap_results.end();
112 } 162 }
113 163
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 score(score), 205 score(score),
156 icon_type(icon_type) { 206 icon_type(icon_type) {
157 } 207 }
158 208
159 //////////////////////////////////////////////////////////////////////////////// 209 ////////////////////////////////////////////////////////////////////////////////
160 210
161 FaviconHandler::FaviconHandler(Profile* profile, 211 FaviconHandler::FaviconHandler(Profile* profile,
162 FaviconHandlerDelegate* delegate, 212 FaviconHandlerDelegate* delegate,
163 Type icon_type) 213 Type icon_type)
164 : got_favicon_from_history_(false), 214 : got_favicon_from_history_(false),
165 favicon_expired_(false), 215 favicon_expired_or_incomplete_(false),
166 icon_types_(icon_type == FAVICON ? history::FAVICON : 216 icon_types_(icon_type == FAVICON ? history::FAVICON :
167 history::TOUCH_ICON | history::TOUCH_PRECOMPOSED_ICON), 217 history::TOUCH_ICON | history::TOUCH_PRECOMPOSED_ICON),
168 profile_(profile), 218 profile_(profile),
169 delegate_(delegate) { 219 delegate_(delegate) {
170 DCHECK(profile_); 220 DCHECK(profile_);
171 DCHECK(delegate_); 221 DCHECK(delegate_);
172 } 222 }
173 223
174 FaviconHandler::~FaviconHandler() { 224 FaviconHandler::~FaviconHandler() {
175 // Call pending download callbacks with error to allow caller to clean up. 225 // Call pending download callbacks with error to allow caller to clean up.
176 for (DownloadRequests::iterator i = download_requests_.begin(); 226 for (DownloadRequests::iterator i = download_requests_.begin();
177 i != download_requests_.end(); ++i) { 227 i != download_requests_.end(); ++i) {
178 if (!i->second.callback.is_null()) { 228 if (!i->second.callback.is_null()) {
179 i->second.callback.Run(i->first, true, SkBitmap()); 229 i->second.callback.Run(i->first, true, SkBitmap());
180 } 230 }
181 } 231 }
182 } 232 }
183 233
184 void FaviconHandler::FetchFavicon(const GURL& url) { 234 void FaviconHandler::FetchFavicon(const GURL& url) {
185 cancelable_consumer_.CancelAllRequests(); 235 cancelable_consumer_.CancelAllRequests();
186 236
187 url_ = url; 237 url_ = url;
188 238
189 favicon_expired_ = got_favicon_from_history_ = false; 239 favicon_expired_or_incomplete_ = got_favicon_from_history_ = false;
190 image_urls_.clear(); 240 image_urls_.clear();
191 241
192 // Request the favicon from the history service. In parallel to this the 242 // Request the favicon from the history service. In parallel to this the
193 // renderer is going to notify us (well WebContents) when the favicon url is 243 // renderer is going to notify us (well WebContents) when the favicon url is
194 // available. 244 // available.
195 if (GetFaviconService()) { 245 if (GetFaviconService()) {
196 GetFaviconForURL(url_, icon_types_, &cancelable_consumer_, 246 GetFaviconForURL(url_, icon_types_, &cancelable_consumer_,
197 base::Bind(&FaviconHandler::OnFaviconDataForInitialURL, 247 base::Bind(&FaviconHandler::OnFaviconDataForInitialURL,
198 base::Unretained(this))); 248 base::Unretained(this)));
199 } 249 }
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 358
309 void FaviconHandler::ProcessCurrentUrl() { 359 void FaviconHandler::ProcessCurrentUrl() {
310 DCHECK(!image_urls_.empty()); 360 DCHECK(!image_urls_.empty());
311 361
312 NavigationEntry* entry = GetEntry(); 362 NavigationEntry* entry = GetEntry();
313 if (!entry) 363 if (!entry)
314 return; 364 return;
315 365
316 // For FAVICON. 366 // For FAVICON.
317 if (current_candidate()->icon_type == FaviconURL::FAVICON) { 367 if (current_candidate()->icon_type == FaviconURL::FAVICON) {
318 if (!favicon_expired_ && entry->GetFavicon().valid && 368 if (!favicon_expired_or_incomplete_ && entry->GetFavicon().valid &&
319 DoUrlAndIconMatch(*current_candidate(), entry->GetFavicon().url, 369 DoUrlAndIconMatch(*current_candidate(), entry->GetFavicon().url,
320 history::FAVICON)) 370 history::FAVICON))
321 return; 371 return;
322 372
323 entry->GetFavicon().url = current_candidate()->icon_url; 373 entry->GetFavicon().url = current_candidate()->icon_url;
324 } else if (!favicon_expired_ && got_favicon_from_history_ && 374 } else if (!favicon_expired_or_incomplete_ && got_favicon_from_history_ &&
325 !history_results_.empty()) { 375 HasValidResult(history_results_) &&
326 const history::FaviconBitmapResult& bitmap_result = history_results_[0]; 376 DoUrlsAndIconsMatch(*current_candidate(), history_results_)) {
327 if (bitmap_result.is_valid() && 377 return;
328 DoUrlAndIconMatch(*current_candidate(), bitmap_result.icon_url,
329 bitmap_result.icon_type)) {
330 return;
331 }
332 } 378 }
333 379
334 if (got_favicon_from_history_) 380 if (got_favicon_from_history_)
335 DownloadFaviconOrAskHistory(entry->GetURL(), current_candidate()->icon_url, 381 DownloadFaviconOrAskHistory(entry->GetURL(), current_candidate()->icon_url,
336 ToHistoryIconType(current_candidate()->icon_type)); 382 ToHistoryIconType(current_candidate()->icon_type));
337 } 383 }
338 384
339 void FaviconHandler::OnDidDownloadFavicon( 385 void FaviconHandler::OnDidDownloadFavicon(
340 int id, 386 int id,
341 const GURL& image_url, 387 const GURL& image_url,
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
472 std::vector<history::FaviconBitmapResult> favicon_bitmap_results, 518 std::vector<history::FaviconBitmapResult> favicon_bitmap_results,
473 history::IconURLSizesMap icon_url_sizes) { 519 history::IconURLSizesMap icon_url_sizes) {
474 NavigationEntry* entry = GetEntry(); 520 NavigationEntry* entry = GetEntry();
475 if (!entry) 521 if (!entry)
476 return; 522 return;
477 523
478 got_favicon_from_history_ = true; 524 got_favicon_from_history_ = true;
479 history_results_ = favicon_bitmap_results; 525 history_results_ = favicon_bitmap_results;
480 526
481 bool has_results = !favicon_bitmap_results.empty(); 527 bool has_results = !favicon_bitmap_results.empty();
482 favicon_expired_ = (has_results && HasExpiredResult(favicon_bitmap_results)); 528 favicon_expired_or_incomplete_ = has_results && HasExpiredOrIncompleteResult(
529 favicon_bitmap_results, icon_url_sizes);
483 530
484 if (has_results && icon_types_ == history::FAVICON && 531 if (has_results && icon_types_ == history::FAVICON &&
485 !entry->GetFavicon().valid && 532 !entry->GetFavicon().valid &&
486 (!current_candidate() || 533 (!current_candidate() ||
487 DoUrlsAndIconsMatch(*current_candidate(), favicon_bitmap_results))) { 534 DoUrlsAndIconsMatch(*current_candidate(), favicon_bitmap_results))) {
488 // The db knows the favicon (although it may be out of date) and the entry 535 // The db knows the favicon (although it may be out of date) and the entry
489 // doesn't have an icon. Set the favicon now, and if the favicon turns out 536 // doesn't have an icon. Set the favicon now, and if the favicon turns out
490 // to be expired (or the wrong url) we'll fetch later on. This way the 537 // to be expired (or the wrong url) we'll fetch later on. This way the
491 // user doesn't see a flash of the default favicon. 538 // user doesn't see a flash of the default favicon.
492 539
493 // The history service sends back results for a single icon URL, so it does 540 // The history service sends back results for a single icon URL, so it does
494 // not matter which result we get the |icon_url| from. 541 // not matter which result we get the |icon_url| from.
495 entry->GetFavicon().url = favicon_bitmap_results[0].icon_url; 542 entry->GetFavicon().url = favicon_bitmap_results[0].icon_url;
496 if (HasValidResult(favicon_bitmap_results)) 543 if (HasValidResult(favicon_bitmap_results))
497 UpdateFavicon(entry, favicon_bitmap_results); 544 UpdateFavicon(entry, favicon_bitmap_results);
498 entry->GetFavicon().valid = true; 545 entry->GetFavicon().valid = true;
499 } 546 }
500 547
501 if (has_results && !HasExpiredResult(favicon_bitmap_results)) { 548 if (has_results && !favicon_expired_or_incomplete_) {
502 if (current_candidate() && 549 if (current_candidate() &&
503 !DoUrlsAndIconsMatch(*current_candidate(), favicon_bitmap_results)) { 550 !DoUrlsAndIconsMatch(*current_candidate(), favicon_bitmap_results)) {
504 // Mapping in the database is wrong. DownloadFavIconOrAskHistory will 551 // Mapping in the database is wrong. DownloadFavIconOrAskHistory will
505 // update the mapping for this url and download the favicon if we don't 552 // update the mapping for this url and download the favicon if we don't
506 // already have it. 553 // already have it.
507 DownloadFaviconOrAskHistory(entry->GetURL(), 554 DownloadFaviconOrAskHistory(entry->GetURL(),
508 current_candidate()->icon_url, 555 current_candidate()->icon_url,
509 static_cast<history::IconType>(current_candidate()->icon_type)); 556 static_cast<history::IconType>(current_candidate()->icon_type));
510 } 557 }
511 } else if (current_candidate()) { 558 } else if (current_candidate()) {
512 // We know the official url for the favicon, by either don't have the 559 // We know the official url for the favicon, by either don't have the
513 // favicon or its expired. Continue on to DownloadFaviconOrAskHistory to 560 // favicon or its expired. Continue on to DownloadFaviconOrAskHistory to
514 // either download or check history again. 561 // either download or check history again.
515 DownloadFaviconOrAskHistory(entry->GetURL(), current_candidate()->icon_url, 562 DownloadFaviconOrAskHistory(entry->GetURL(), current_candidate()->icon_url,
516 ToHistoryIconType(current_candidate()->icon_type)); 563 ToHistoryIconType(current_candidate()->icon_type));
517 } 564 }
518 // else we haven't got the icon url. When we get it we'll ask the 565 // else we haven't got the icon url. When we get it we'll ask the
519 // renderer to download the icon. 566 // renderer to download the icon.
520 } 567 }
521 568
522 void FaviconHandler::DownloadFaviconOrAskHistory( 569 void FaviconHandler::DownloadFaviconOrAskHistory(
523 const GURL& page_url, 570 const GURL& page_url,
524 const GURL& icon_url, 571 const GURL& icon_url,
525 history::IconType icon_type) { 572 history::IconType icon_type) {
526 if (favicon_expired_) { 573 if (favicon_expired_or_incomplete_) {
527 // We have the mapping, but the favicon is out of date. Download it now. 574 // We have the mapping, but the favicon is out of date. Download it now.
528 ScheduleDownload(page_url, icon_url, preferred_icon_size(), icon_type, 575 ScheduleDownload(page_url, icon_url, preferred_icon_size(), icon_type,
529 FaviconTabHelper::ImageDownloadCallback()); 576 FaviconTabHelper::ImageDownloadCallback());
530 } else if (GetFaviconService()) { 577 } else if (GetFaviconService()) {
531 // We don't know the favicon, but we may have previously downloaded the 578 // We don't know the favicon, but we may have previously downloaded the
532 // favicon for another page that shares the same favicon. Ask for the 579 // favicon for another page that shares the same favicon. Ask for the
533 // favicon given the favicon URL. 580 // favicon given the favicon URL.
534 if (profile_->IsOffTheRecord()) { 581 if (profile_->IsOffTheRecord()) {
535 GetFavicon(icon_url, icon_type, &cancelable_consumer_, 582 GetFavicon(icon_url, icon_type, &cancelable_consumer_,
536 base::Bind(&FaviconHandler::OnFaviconData, base::Unretained(this))); 583 base::Bind(&FaviconHandler::OnFaviconData, base::Unretained(this)));
(...skipping 13 matching lines...) Expand all
550 597
551 void FaviconHandler::OnFaviconData( 598 void FaviconHandler::OnFaviconData(
552 FaviconService::Handle handle, 599 FaviconService::Handle handle,
553 std::vector<history::FaviconBitmapResult> favicon_bitmap_results, 600 std::vector<history::FaviconBitmapResult> favicon_bitmap_results,
554 history::IconURLSizesMap icon_url_sizes) { 601 history::IconURLSizesMap icon_url_sizes) {
555 NavigationEntry* entry = GetEntry(); 602 NavigationEntry* entry = GetEntry();
556 if (!entry) 603 if (!entry)
557 return; 604 return;
558 605
559 bool has_results = !favicon_bitmap_results.empty(); 606 bool has_results = !favicon_bitmap_results.empty();
607 bool has_expired_or_incomplete_result = HasExpiredOrIncompleteResult(
608 favicon_bitmap_results, icon_url_sizes);
560 609
561 // No need to update the favicon url. By the time we get here 610 // No need to update the favicon url. By the time we get here
562 // UpdateFaviconURL will have set the favicon url. 611 // UpdateFaviconURL will have set the favicon url.
563 if (has_results && icon_types_ == history::FAVICON) { 612 if (has_results && icon_types_ == history::FAVICON) {
564 if (HasValidResult(favicon_bitmap_results)) { 613 if (HasValidResult(favicon_bitmap_results)) {
565 // There is a favicon, set it now. If expired we'll download the current 614 // There is a favicon, set it now. If expired we'll download the current
566 // one again, but at least the user will get some icon instead of the 615 // one again, but at least the user will get some icon instead of the
567 // default and most likely the current one is fine anyway. 616 // default and most likely the current one is fine anyway.
568 UpdateFavicon(entry, favicon_bitmap_results); 617 UpdateFavicon(entry, favicon_bitmap_results);
569 } 618 }
570 if (HasExpiredResult(favicon_bitmap_results)) { 619 if (has_expired_or_incomplete_result) {
571 // The favicon is out of date. Request the current one. 620 // The favicon is out of date. Request the current one.
572 ScheduleDownload(entry->GetURL(), entry->GetFavicon().url, 621 ScheduleDownload(entry->GetURL(), entry->GetFavicon().url,
573 preferred_icon_size(), 622 preferred_icon_size(),
574 history::FAVICON, 623 history::FAVICON,
575 FaviconTabHelper::ImageDownloadCallback()); 624 FaviconTabHelper::ImageDownloadCallback());
576 } 625 }
577 } else if (current_candidate() && 626 } else if (current_candidate() &&
578 (!has_results || HasExpiredResult(favicon_bitmap_results) || 627 (!has_results || has_expired_or_incomplete_result ||
579 !(DoUrlsAndIconsMatch(*current_candidate(), favicon_bitmap_results)))) { 628 !(DoUrlsAndIconsMatch(*current_candidate(), favicon_bitmap_results)))) {
580 // We don't know the favicon, it is out of date or its type is not same as 629 // We don't know the favicon, it is out of date or its type is not same as
581 // one got from page. Request the current one. 630 // one got from page. Request the current one.
582 ScheduleDownload(entry->GetURL(), current_candidate()->icon_url, 631 ScheduleDownload(entry->GetURL(), current_candidate()->icon_url,
583 preferred_icon_size(), 632 preferred_icon_size(),
584 ToHistoryIconType(current_candidate()->icon_type), 633 ToHistoryIconType(current_candidate()->icon_type),
585 FaviconTabHelper::ImageDownloadCallback()); 634 FaviconTabHelper::ImageDownloadCallback());
586 } 635 }
587 history_results_ = favicon_bitmap_results; 636 history_results_ = favicon_bitmap_results;
588 } 637 }
589 638
590 int FaviconHandler::ScheduleDownload( 639 int FaviconHandler::ScheduleDownload(
591 const GURL& url, 640 const GURL& url,
592 const GURL& image_url, 641 const GURL& image_url,
593 int image_size, 642 int image_size,
594 history::IconType icon_type, 643 history::IconType icon_type,
595 const FaviconTabHelper::ImageDownloadCallback& callback) { 644 const FaviconTabHelper::ImageDownloadCallback& callback) {
596 const int download_id = DownloadFavicon(image_url, image_size); 645 const int download_id = DownloadFavicon(image_url, image_size);
597 if (download_id) { 646 if (download_id) {
598 // Download ids should be unique. 647 // Download ids should be unique.
599 DCHECK(download_requests_.find(download_id) == download_requests_.end()); 648 DCHECK(download_requests_.find(download_id) == download_requests_.end());
600 download_requests_[download_id] = 649 download_requests_[download_id] =
601 DownloadRequest(url, image_url, callback, icon_type); 650 DownloadRequest(url, image_url, callback, icon_type);
602 } 651 }
603 652
604 return download_id; 653 return download_id;
605 } 654 }
OLDNEW
« no previous file with comments | « chrome/browser/favicon/favicon_handler.h ('k') | chrome/browser/favicon/favicon_handler_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698