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

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