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

Side by Side Diff: components/favicon/core/favicon_handler.cc

Issue 1295733002: Ignore duplicate FaviconHandler::OnUpdateFaviconURL() calls (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@page_changed_under_us
Patch Set: Created 5 years, 2 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
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 "components/favicon/core/favicon_handler.h" 5 #include "components/favicon/core/favicon_handler.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cmath> 8 #include <cmath>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 if (!b1.icon_sizes.empty()) 144 if (!b1.icon_sizes.empty())
145 area1 = b1.icon_sizes.front().GetArea(); 145 area1 = b1.icon_sizes.front().GetArea();
146 146
147 int area2 = 0; 147 int area2 = 0;
148 if (!b2.icon_sizes.empty()) 148 if (!b2.icon_sizes.empty())
149 area2 = b2.icon_sizes.front().GetArea(); 149 area2 = b2.icon_sizes.front().GetArea();
150 150
151 return area1 > area2; 151 return area1 > area2;
152 } 152 }
153 153
154 // Checks whether two FaviconURLs are equal ignoring the icon sizes.
155 bool FaviconURLsEqualIgnoringSizes(const FaviconURL& u1, const FaviconURL& u2) {
156 return u1.icon_type == u2.icon_type && u1.icon_url == u2.icon_url;
157 }
158
154 } // namespace 159 } // namespace
155 160
156 //////////////////////////////////////////////////////////////////////////////// 161 ////////////////////////////////////////////////////////////////////////////////
157 162
158 FaviconHandler::DownloadRequest::DownloadRequest() 163 FaviconHandler::DownloadRequest::DownloadRequest()
159 : icon_type(favicon_base::INVALID_ICON) { 164 : icon_type(favicon_base::INVALID_ICON) {
160 } 165 }
161 166
162 FaviconHandler::DownloadRequest::~DownloadRequest() { 167 FaviconHandler::DownloadRequest::~DownloadRequest() {
163 } 168 }
(...skipping 28 matching lines...) Expand all
192 FaviconHandler::FaviconHandler(FaviconService* service, 197 FaviconHandler::FaviconHandler(FaviconService* service,
193 FaviconDriver* driver, 198 FaviconDriver* driver,
194 Type handler_type, 199 Type handler_type,
195 bool download_largest_icon) 200 bool download_largest_icon)
196 : got_favicon_from_history_(false), 201 : got_favicon_from_history_(false),
197 favicon_expired_or_incomplete_(false), 202 favicon_expired_or_incomplete_(false),
198 handler_type_(handler_type), 203 handler_type_(handler_type),
199 icon_types_(FaviconHandler::GetIconTypesFromHandlerType(handler_type)), 204 icon_types_(FaviconHandler::GetIconTypesFromHandlerType(handler_type)),
200 download_largest_icon_(download_largest_icon), 205 download_largest_icon_(download_largest_icon),
201 service_(service), 206 service_(service),
202 driver_(driver) { 207 driver_(driver),
208 current_candidate_index_(0u) {
203 DCHECK(driver_); 209 DCHECK(driver_);
204 } 210 }
205 211
206 FaviconHandler::~FaviconHandler() { 212 FaviconHandler::~FaviconHandler() {
207 } 213 }
208 214
209 // static 215 // static
210 int FaviconHandler::GetIconTypesFromHandlerType( 216 int FaviconHandler::GetIconTypesFromHandlerType(
211 FaviconHandler::Type handler_type) { 217 FaviconHandler::Type handler_type) {
212 switch (handler_type) { 218 switch (handler_type) {
(...skipping 10 matching lines...) Expand all
223 229
224 void FaviconHandler::FetchFavicon(const GURL& url) { 230 void FaviconHandler::FetchFavicon(const GURL& url) {
225 cancelable_task_tracker_.TryCancelAll(); 231 cancelable_task_tracker_.TryCancelAll();
226 232
227 url_ = url; 233 url_ = url;
228 234
229 favicon_expired_or_incomplete_ = got_favicon_from_history_ = false; 235 favicon_expired_or_incomplete_ = got_favicon_from_history_ = false;
230 download_requests_.clear(); 236 download_requests_.clear();
231 image_urls_.clear(); 237 image_urls_.clear();
232 history_results_.clear(); 238 history_results_.clear();
239 current_candidate_index_ = 0u;
233 best_favicon_candidate_ = FaviconCandidate(); 240 best_favicon_candidate_ = FaviconCandidate();
234 241
235 // 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
236 // 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
237 // available. 244 // available.
238 GetFaviconForURLFromFaviconService( 245 GetFaviconForURLFromFaviconService(
239 url_, icon_types_, 246 url_, icon_types_,
240 base::Bind(&FaviconHandler::OnFaviconDataForInitialURLFromFaviconService, 247 base::Bind(&FaviconHandler::OnFaviconDataForInitialURLFromFaviconService,
241 base::Unretained(this)), 248 base::Unretained(this)),
242 &cancelable_task_tracker_); 249 &cancelable_task_tracker_);
(...skipping 16 matching lines...) Expand all
259 266
260 // The size of the downloaded icon may not match the declared size. Stop 267 // The size of the downloaded icon may not match the declared size. Stop
261 // downloading if: 268 // downloading if:
262 // - current candidate is only candidate. 269 // - current candidate is only candidate.
263 // - next candidate doesn't have sizes attributes, in this case, the rest 270 // - next candidate doesn't have sizes attributes, in this case, the rest
264 // candidates don't have sizes attribute either, stop downloading now, 271 // candidates don't have sizes attribute either, stop downloading now,
265 // otherwise, all favicon without sizes attribute are downloaded. 272 // otherwise, all favicon without sizes attribute are downloaded.
266 // - next candidate has sizes attribute and it is not larger than largest, 273 // - next candidate has sizes attribute and it is not larger than largest,
267 // - current candidate is maximal one we want. 274 // - current candidate is maximal one we want.
268 const int maximal_size = GetMaximalIconSize(icon_type); 275 const int maximal_size = GetMaximalIconSize(icon_type);
269 exact_match = image_urls_.size() == 1 || 276 if (current_candidate_index_ + 1 >= image_urls_.size()) {
270 image_urls_[1].icon_sizes.empty() || 277 exact_match = true;
271 image_urls_[1].icon_sizes[0].GetArea() <= largest.GetArea() || 278 } else {
272 (image.Size().width() == maximal_size && 279 FaviconURL next_image_url = image_urls_[current_candidate_index_ + 1];
273 image.Size().height() == maximal_size); 280 exact_match = next_image_url.icon_sizes.empty() ||
281 next_image_url.icon_sizes[0].GetArea() <= largest.GetArea() ||
282 (image.Size().width() == maximal_size &&
283 image.Size().height() == maximal_size);
284 }
274 } else { 285 } else {
275 exact_match = score == 1 || preferred_icon_size() == 0; 286 exact_match = score == 1 || preferred_icon_size() == 0;
276 replace_best_favicon_candidate = 287 replace_best_favicon_candidate =
277 exact_match || 288 exact_match ||
278 best_favicon_candidate_.icon_type == favicon_base::INVALID_ICON || 289 best_favicon_candidate_.icon_type == favicon_base::INVALID_ICON ||
279 score > best_favicon_candidate_.score; 290 score > best_favicon_candidate_.score;
280 } 291 }
281 if (replace_best_favicon_candidate) { 292 if (replace_best_favicon_candidate) {
282 best_favicon_candidate_ = 293 best_favicon_candidate_ =
283 FaviconCandidate(image_url, image, score, icon_type); 294 FaviconCandidate(image_url, image, score, icon_type);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
319 driver_->OnFaviconAvailable( 330 driver_->OnFaviconAvailable(
320 url_, icon_url, image_with_adjusted_colorspace, is_active_favicon); 331 url_, icon_url, image_with_adjusted_colorspace, is_active_favicon);
321 } 332 }
322 333
323 void FaviconHandler::OnUpdateFaviconURL( 334 void FaviconHandler::OnUpdateFaviconURL(
324 const GURL& page_url, 335 const GURL& page_url,
325 const std::vector<FaviconURL>& candidates) { 336 const std::vector<FaviconURL>& candidates) {
326 if (page_url != url_) 337 if (page_url != url_)
327 return; 338 return;
328 339
329 download_requests_.clear(); 340 std::vector<FaviconURL> pruned_candidates;
330 image_urls_.clear();
331 best_favicon_candidate_ = FaviconCandidate();
332
333 for (const FaviconURL& candidate : candidates) { 341 for (const FaviconURL& candidate : candidates) {
334 if (!candidate.icon_url.is_empty() && (candidate.icon_type & icon_types_)) 342 if (!candidate.icon_url.is_empty() && (candidate.icon_type & icon_types_))
335 image_urls_.push_back(candidate); 343 pruned_candidates.push_back(candidate);
336 } 344 }
337 345
338 if (download_largest_icon_) 346 if (download_largest_icon_)
339 SortAndPruneImageUrls(); 347 SortAndPruneImageUrls(&pruned_candidates);
348
349 // Ignore FaviconURL::icon_sizes because FaviconURL::icon_sizes is not stored
350 // in the history database.
351 if (image_urls_.size() == pruned_candidates.size() &&
352 std::equal(pruned_candidates.begin(), pruned_candidates.end(),
353 image_urls_.begin(), FaviconURLsEqualIgnoringSizes)) {
354 return;
355 }
356
357 download_requests_.clear();
358 image_urls_ = pruned_candidates;
359 current_candidate_index_ = 0u;
360 best_favicon_candidate_ = FaviconCandidate();
340 361
341 // TODO(davemoore) Should clear on empty url. Currently we ignore it. 362 // TODO(davemoore) Should clear on empty url. Currently we ignore it.
342 // This appears to be what FF does as well. 363 // This appears to be what FF does as well.
343 if (!image_urls_.empty()) 364 if (current_candidate())
344 ProcessCurrentUrl(); 365 ProcessCurrentUrl();
345 } 366 }
346 367
347 void FaviconHandler::ProcessCurrentUrl() { 368 void FaviconHandler::ProcessCurrentUrl() {
348 DCHECK(!image_urls_.empty()); 369 DCHECK(!image_urls_.empty());
349 370
350 // current_candidate() may return NULL if download_largest_icon_ is true and
351 // all the sizes are larger than the max.
352 if (!current_candidate())
353 return;
354
355 if (current_candidate()->icon_type == favicon_base::FAVICON && 371 if (current_candidate()->icon_type == favicon_base::FAVICON &&
356 !download_largest_icon_) { 372 !download_largest_icon_) {
357 if (!favicon_expired_or_incomplete_ && 373 if (!favicon_expired_or_incomplete_ &&
358 driver_->GetActiveFaviconValidity() && 374 driver_->GetActiveFaviconValidity() &&
359 DoUrlAndIconMatch(*current_candidate(), 375 DoUrlAndIconMatch(*current_candidate(),
360 driver_->GetActiveFaviconURL(), 376 driver_->GetActiveFaviconURL(),
361 favicon_base::FAVICON)) 377 favicon_base::FAVICON))
362 return; 378 return;
363 } else if (!favicon_expired_or_incomplete_ && got_favicon_from_history_ && 379 } else if (!favicon_expired_or_incomplete_ && got_favicon_from_history_ &&
364 HasValidResult(history_results_) && 380 HasValidResult(history_results_) &&
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
419 435
420 if (!image_skia.isNull()) { 436 if (!image_skia.isNull()) {
421 gfx::Image image(image_skia); 437 gfx::Image image(image_skia);
422 // The downloaded icon is still valid when there is no FaviconURL update 438 // The downloaded icon is still valid when there is no FaviconURL update
423 // during the downloading. 439 // during the downloading.
424 request_next_icon = !UpdateFaviconCandidate(image_url, image, score, 440 request_next_icon = !UpdateFaviconCandidate(image_url, image, score,
425 download_request.icon_type); 441 download_request.icon_type);
426 } 442 }
427 } 443 }
428 444
429 if (request_next_icon && image_urls_.size() > 1) { 445 if (request_next_icon && current_candidate_index_ + 1 < image_urls_.size()) {
430 // Remove the first member of image_urls_ and process the remaining. 446 // Process the next candidate.
431 image_urls_.erase(image_urls_.begin()); 447 ++current_candidate_index_;
432 ProcessCurrentUrl(); 448 ProcessCurrentUrl();
433 } else { 449 } else {
434 // We have either found the ideal candidate or run out of candidates. 450 // We have either found the ideal candidate or run out of candidates.
435 if (best_favicon_candidate_.icon_type != favicon_base::INVALID_ICON) { 451 if (best_favicon_candidate_.icon_type != favicon_base::INVALID_ICON) {
436 // No more icons to request, set the favicon from the candidate. 452 // No more icons to request, set the favicon from the candidate.
437 SetFavicon(best_favicon_candidate_.image_url, 453 SetFavicon(best_favicon_candidate_.image_url,
438 best_favicon_candidate_.image, 454 best_favicon_candidate_.image,
439 best_favicon_candidate_.icon_type); 455 best_favicon_candidate_.icon_type);
440 } 456 }
441 // Clear download related state. 457 // Clear download related state.
442 image_urls_.clear();
443 download_requests_.clear(); 458 download_requests_.clear();
459 current_candidate_index_ = image_urls_.size();
444 best_favicon_candidate_ = FaviconCandidate(); 460 best_favicon_candidate_ = FaviconCandidate();
445 } 461 }
446 } 462 }
447 463
448 bool FaviconHandler::HasPendingTasksForTest() { 464 bool FaviconHandler::HasPendingTasksForTest() {
449 return !download_requests_.empty() || 465 return !download_requests_.empty() ||
450 cancelable_task_tracker_.HasTrackedTasks(); 466 cancelable_task_tracker_.HasTrackedTasks();
451 } 467 }
452 468
453 int FaviconHandler::DownloadFavicon(const GURL& image_url, 469 int FaviconHandler::DownloadFavicon(const GURL& image_url,
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
657 if (download_id == 0) { 673 if (download_id == 0) {
658 // If DownloadFavicon() did not start a download, it returns a download id 674 // If DownloadFavicon() did not start a download, it returns a download id
659 // of 0. We still need to call OnDidDownloadFavicon() because the method is 675 // of 0. We still need to call OnDidDownloadFavicon() because the method is
660 // responsible for initiating the data request for the next candidate. 676 // responsible for initiating the data request for the next candidate.
661 OnDidDownloadFavicon(download_id, image_url, std::vector<SkBitmap>(), 677 OnDidDownloadFavicon(download_id, image_url, std::vector<SkBitmap>(),
662 std::vector<gfx::Size>()); 678 std::vector<gfx::Size>());
663 679
664 } 680 }
665 } 681 }
666 682
667 void FaviconHandler::SortAndPruneImageUrls() { 683 void FaviconHandler::SortAndPruneImageUrls(
684 std::vector<FaviconURL>* image_urls) {
sky 2015/10/05 17:22:43 Move this into anonymous namespace as it no longer
668 // Not using const-reference since the loop mutates FaviconURL::icon_sizes. 685 // Not using const-reference since the loop mutates FaviconURL::icon_sizes.
669 for (FaviconURL& image_url : image_urls_) { 686 for (FaviconURL& image_url : *image_urls) {
670 if (image_url.icon_sizes.empty()) 687 if (image_url.icon_sizes.empty())
671 continue; 688 continue;
672 689
673 gfx::Size largest = 690 gfx::Size largest =
674 image_url.icon_sizes[GetLargestSizeIndex(image_url.icon_sizes)]; 691 image_url.icon_sizes[GetLargestSizeIndex(image_url.icon_sizes)];
675 image_url.icon_sizes.clear(); 692 image_url.icon_sizes.clear();
676 image_url.icon_sizes.push_back(largest); 693 image_url.icon_sizes.push_back(largest);
677 } 694 }
678 std::stable_sort(image_urls_.begin(), image_urls_.end(), 695 std::stable_sort(image_urls->begin(), image_urls->end(), CompareIconSize);
679 CompareIconSize);
680 } 696 }
681 697
682 } // namespace favicon 698 } // namespace favicon
OLDNEW
« no previous file with comments | « components/favicon/core/favicon_handler.h ('k') | components/favicon/core/favicon_handler_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698