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 "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 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
256 download_requests_.clear(); | 256 download_requests_.clear(); |
257 image_urls_.clear(); | 257 image_urls_.clear(); |
258 notification_icon_url_ = GURL(); | 258 notification_icon_url_ = GURL(); |
259 notification_icon_type_ = favicon_base::INVALID_ICON; | 259 notification_icon_type_ = favicon_base::INVALID_ICON; |
260 current_candidate_index_ = 0u; | 260 current_candidate_index_ = 0u; |
261 best_favicon_candidate_ = FaviconCandidate(); | 261 best_favicon_candidate_ = FaviconCandidate(); |
262 | 262 |
263 // Request the favicon from the history service. In parallel to this the | 263 // Request the favicon from the history service. In parallel to this the |
264 // renderer is going to notify us (well WebContents) when the favicon url is | 264 // renderer is going to notify us (well WebContents) when the favicon url is |
265 // available. | 265 // available. |
266 GetFaviconForURLFromFaviconService( | 266 if (service_) { |
267 url_, icon_types_, | 267 service_->GetFaviconForPageURL( |
268 base::Bind(&FaviconHandler::OnFaviconDataForInitialURLFromFaviconService, | 268 url_, icon_types_, preferred_icon_size(), |
269 base::Unretained(this)), | 269 base::Bind( |
270 &cancelable_task_tracker_); | 270 &FaviconHandler::OnFaviconDataForInitialURLFromFaviconService, |
| 271 base::Unretained(this)), |
| 272 &cancelable_task_tracker_); |
| 273 } |
271 } | 274 } |
272 | 275 |
273 bool FaviconHandler::UpdateFaviconCandidate(const GURL& image_url, | 276 bool FaviconHandler::UpdateFaviconCandidate(const GURL& image_url, |
274 const gfx::Image& image, | 277 const gfx::Image& image, |
275 float score, | 278 float score, |
276 favicon_base::IconType icon_type) { | 279 favicon_base::IconType icon_type) { |
277 bool replace_best_favicon_candidate = false; | 280 bool replace_best_favicon_candidate = false; |
278 bool exact_match = false; | 281 bool exact_match = false; |
279 if (download_largest_icon_) { | 282 if (download_largest_icon_) { |
280 replace_best_favicon_candidate = | 283 replace_best_favicon_candidate = |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
313 if (replace_best_favicon_candidate) { | 316 if (replace_best_favicon_candidate) { |
314 best_favicon_candidate_ = | 317 best_favicon_candidate_ = |
315 FaviconCandidate(image_url, image, score, icon_type); | 318 FaviconCandidate(image_url, image, score, icon_type); |
316 } | 319 } |
317 return exact_match; | 320 return exact_match; |
318 } | 321 } |
319 | 322 |
320 void FaviconHandler::SetFavicon(const GURL& icon_url, | 323 void FaviconHandler::SetFavicon(const GURL& icon_url, |
321 const gfx::Image& image, | 324 const gfx::Image& image, |
322 favicon_base::IconType icon_type) { | 325 favicon_base::IconType icon_type) { |
323 if (ShouldSaveFavicon()) | 326 if (service_ && ShouldSaveFavicon()) |
324 SetHistoryFavicons(url_, icon_url, icon_type, image); | 327 service_->SetFavicons(url_, icon_url, icon_type, image); |
325 | 328 |
326 NotifyFaviconUpdated(icon_url, icon_type, image); | 329 NotifyFaviconUpdated(icon_url, icon_type, image); |
327 } | 330 } |
328 | 331 |
329 void FaviconHandler::NotifyFaviconUpdated( | 332 void FaviconHandler::NotifyFaviconUpdated( |
330 const std::vector<favicon_base::FaviconRawBitmapResult>& | 333 const std::vector<favicon_base::FaviconRawBitmapResult>& |
331 favicon_bitmap_results) { | 334 favicon_bitmap_results) { |
332 if (favicon_bitmap_results.empty()) | 335 if (favicon_bitmap_results.empty()) |
333 return; | 336 return; |
334 | 337 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
388 image_urls_ = pruned_candidates; | 391 image_urls_ = pruned_candidates; |
389 current_candidate_index_ = 0u; | 392 current_candidate_index_ = 0u; |
390 best_favicon_candidate_ = FaviconCandidate(); | 393 best_favicon_candidate_ = FaviconCandidate(); |
391 | 394 |
392 // TODO(davemoore) Should clear on empty url. Currently we ignore it. | 395 // TODO(davemoore) Should clear on empty url. Currently we ignore it. |
393 // This appears to be what FF does as well. | 396 // This appears to be what FF does as well. |
394 if (current_candidate() && got_favicon_from_history_) | 397 if (current_candidate() && got_favicon_from_history_) |
395 OnGotInitialHistoryDataAndIconURLCandidates(); | 398 OnGotInitialHistoryDataAndIconURLCandidates(); |
396 } | 399 } |
397 | 400 |
| 401 int FaviconHandler::GetMaximalIconSize(favicon_base::IconType icon_type) { |
| 402 switch (icon_type) { |
| 403 case favicon_base::FAVICON: |
| 404 #if defined(OS_ANDROID) |
| 405 return 192; |
| 406 #else |
| 407 return gfx::ImageSkia::GetMaxSupportedScale() * gfx::kFaviconSize; |
| 408 #endif |
| 409 case favicon_base::TOUCH_ICON: |
| 410 case favicon_base::TOUCH_PRECOMPOSED_ICON: |
| 411 return kTouchIconSize; |
| 412 case favicon_base::INVALID_ICON: |
| 413 return 0; |
| 414 } |
| 415 NOTREACHED(); |
| 416 return 0; |
| 417 } |
| 418 |
398 void FaviconHandler::OnGotInitialHistoryDataAndIconURLCandidates() { | 419 void FaviconHandler::OnGotInitialHistoryDataAndIconURLCandidates() { |
399 if (!initial_history_result_expired_or_incomplete_ && | 420 if (!initial_history_result_expired_or_incomplete_ && |
400 DoUrlAndIconMatch(*current_candidate(), notification_icon_url_, | 421 DoUrlAndIconMatch(*current_candidate(), notification_icon_url_, |
401 notification_icon_type_)) { | 422 notification_icon_type_)) { |
402 // - The data from history is valid and not expired. | 423 // - The data from history is valid and not expired. |
403 // - The icon URL of the history data matches one of the page's icon URLs. | 424 // - The icon URL of the history data matches one of the page's icon URLs. |
404 // - The icon URL of the history data matches the icon URL of the last | 425 // - The icon URL of the history data matches the icon URL of the last |
405 // OnFaviconAvailable() notification. | 426 // OnFaviconAvailable() notification. |
406 // We are done. No additional downloads or history requests are needed. | 427 // We are done. No additional downloads or history requests are needed. |
407 // TODO: Store all of the icon URLs associated with a page in history so | 428 // TODO: Store all of the icon URLs associated with a page in history so |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
492 current_candidate_index_ = image_urls_.size(); | 513 current_candidate_index_ = image_urls_.size(); |
493 best_favicon_candidate_ = FaviconCandidate(); | 514 best_favicon_candidate_ = FaviconCandidate(); |
494 } | 515 } |
495 } | 516 } |
496 | 517 |
497 bool FaviconHandler::HasPendingTasksForTest() { | 518 bool FaviconHandler::HasPendingTasksForTest() { |
498 return !download_requests_.empty() || | 519 return !download_requests_.empty() || |
499 cancelable_task_tracker_.HasTrackedTasks(); | 520 cancelable_task_tracker_.HasTrackedTasks(); |
500 } | 521 } |
501 | 522 |
502 void FaviconHandler::UpdateFaviconMappingAndFetch( | |
503 const GURL& page_url, | |
504 const GURL& icon_url, | |
505 favicon_base::IconType icon_type, | |
506 const favicon_base::FaviconResultsCallback& callback, | |
507 base::CancelableTaskTracker* tracker) { | |
508 // TODO(pkotwicz): pass in all of |image_urls_| to | |
509 // UpdateFaviconMappingsAndFetch(). | |
510 if (service_) { | |
511 std::vector<GURL> icon_urls; | |
512 icon_urls.push_back(icon_url); | |
513 service_->UpdateFaviconMappingsAndFetch(page_url, icon_urls, icon_type, | |
514 preferred_icon_size(), callback, | |
515 tracker); | |
516 } | |
517 } | |
518 | |
519 void FaviconHandler::GetFaviconFromFaviconService( | |
520 const GURL& icon_url, | |
521 favicon_base::IconType icon_type, | |
522 const favicon_base::FaviconResultsCallback& callback, | |
523 base::CancelableTaskTracker* tracker) { | |
524 if (service_) { | |
525 service_->GetFavicon(icon_url, icon_type, preferred_icon_size(), callback, | |
526 tracker); | |
527 } | |
528 } | |
529 | |
530 void FaviconHandler::GetFaviconForURLFromFaviconService( | |
531 const GURL& page_url, | |
532 int icon_types, | |
533 const favicon_base::FaviconResultsCallback& callback, | |
534 base::CancelableTaskTracker* tracker) { | |
535 if (service_) { | |
536 service_->GetFaviconForPageURL(page_url, icon_types, preferred_icon_size(), | |
537 callback, tracker); | |
538 } | |
539 } | |
540 | |
541 void FaviconHandler::SetHistoryFavicons(const GURL& page_url, | |
542 const GURL& icon_url, | |
543 favicon_base::IconType icon_type, | |
544 const gfx::Image& image) { | |
545 if (service_) { | |
546 service_->SetFavicons(page_url, icon_url, icon_type, image); | |
547 } | |
548 } | |
549 | |
550 bool FaviconHandler::ShouldSaveFavicon() { | 523 bool FaviconHandler::ShouldSaveFavicon() { |
551 if (!delegate_->IsOffTheRecord()) | 524 if (!delegate_->IsOffTheRecord()) |
552 return true; | 525 return true; |
553 | 526 |
554 // Always save favicon if the page is bookmarked. | 527 // Always save favicon if the page is bookmarked. |
555 return delegate_->IsBookmarked(url_); | 528 return delegate_->IsBookmarked(url_); |
556 } | 529 } |
557 | 530 |
558 int FaviconHandler::GetMaximalIconSize(favicon_base::IconType icon_type) { | |
559 switch (icon_type) { | |
560 case favicon_base::FAVICON: | |
561 #if defined(OS_ANDROID) | |
562 return 192; | |
563 #else | |
564 return gfx::ImageSkia::GetMaxSupportedScale() * gfx::kFaviconSize; | |
565 #endif | |
566 case favicon_base::TOUCH_ICON: | |
567 case favicon_base::TOUCH_PRECOMPOSED_ICON: | |
568 return kTouchIconSize; | |
569 case favicon_base::INVALID_ICON: | |
570 return 0; | |
571 } | |
572 NOTREACHED(); | |
573 return 0; | |
574 } | |
575 | |
576 void FaviconHandler::OnFaviconDataForInitialURLFromFaviconService( | 531 void FaviconHandler::OnFaviconDataForInitialURLFromFaviconService( |
577 const std::vector<favicon_base::FaviconRawBitmapResult>& | 532 const std::vector<favicon_base::FaviconRawBitmapResult>& |
578 favicon_bitmap_results) { | 533 favicon_bitmap_results) { |
579 got_favicon_from_history_ = true; | 534 got_favicon_from_history_ = true; |
580 bool has_valid_result = HasValidResult(favicon_bitmap_results); | 535 bool has_valid_result = HasValidResult(favicon_bitmap_results); |
581 initial_history_result_expired_or_incomplete_ = | 536 initial_history_result_expired_or_incomplete_ = |
582 !has_valid_result || | 537 !has_valid_result || |
583 HasExpiredOrIncompleteResult(preferred_icon_size(), | 538 HasExpiredOrIncompleteResult(preferred_icon_size(), |
584 favicon_bitmap_results); | 539 favicon_bitmap_results); |
585 redownload_icons_ = initial_history_result_expired_or_incomplete_ && | 540 redownload_icons_ = initial_history_result_expired_or_incomplete_ && |
(...skipping 13 matching lines...) Expand all Loading... |
599 OnGotInitialHistoryDataAndIconURLCandidates(); | 554 OnGotInitialHistoryDataAndIconURLCandidates(); |
600 } | 555 } |
601 | 556 |
602 void FaviconHandler::DownloadCurrentCandidateOrAskFaviconService() { | 557 void FaviconHandler::DownloadCurrentCandidateOrAskFaviconService() { |
603 GURL icon_url = current_candidate()->icon_url; | 558 GURL icon_url = current_candidate()->icon_url; |
604 favicon_base::IconType icon_type = current_candidate()->icon_type; | 559 favicon_base::IconType icon_type = current_candidate()->icon_type; |
605 | 560 |
606 if (redownload_icons_) { | 561 if (redownload_icons_) { |
607 // We have the mapping, but the favicon is out of date. Download it now. | 562 // We have the mapping, but the favicon is out of date. Download it now. |
608 ScheduleDownload(icon_url, icon_type); | 563 ScheduleDownload(icon_url, icon_type); |
609 } else { | 564 } else if (service_) { |
610 // We don't know the favicon, but we may have previously downloaded the | 565 // We don't know the favicon, but we may have previously downloaded the |
611 // favicon for another page that shares the same favicon. Ask for the | 566 // favicon for another page that shares the same favicon. Ask for the |
612 // favicon given the favicon URL. | 567 // favicon given the favicon URL. |
613 if (delegate_->IsOffTheRecord()) { | 568 if (delegate_->IsOffTheRecord()) { |
614 GetFaviconFromFaviconService( | 569 service_->GetFavicon( |
615 icon_url, icon_type, | 570 icon_url, icon_type, preferred_icon_size(), |
616 base::Bind(&FaviconHandler::OnFaviconData, base::Unretained(this)), | 571 base::Bind(&FaviconHandler::OnFaviconData, base::Unretained(this)), |
617 &cancelable_task_tracker_); | 572 &cancelable_task_tracker_); |
618 } else { | 573 } else { |
619 // Ask the history service for the icon. This does two things: | 574 // Ask the history service for the icon. This does two things: |
620 // 1. Attempts to fetch the favicon data from the database. | 575 // 1. Attempts to fetch the favicon data from the database. |
621 // 2. If the favicon exists in the database, this updates the database to | 576 // 2. If the favicon exists in the database, this updates the database to |
622 // include the mapping between the page url and the favicon url. | 577 // include the mapping between the page url and the favicon url. |
623 // This is asynchronous. The history service will call back when done. | 578 // This is asynchronous. The history service will call back when done. |
624 UpdateFaviconMappingAndFetch( | 579 // TODO(pkotwicz): pass in all of |image_urls_| to |
625 url_, icon_url, icon_type, | 580 // UpdateFaviconMappingsAndFetch(). |
| 581 service_->UpdateFaviconMappingsAndFetch( |
| 582 url_, {icon_url}, icon_type, preferred_icon_size(), |
626 base::Bind(&FaviconHandler::OnFaviconData, base::Unretained(this)), | 583 base::Bind(&FaviconHandler::OnFaviconData, base::Unretained(this)), |
627 &cancelable_task_tracker_); | 584 &cancelable_task_tracker_); |
628 } | 585 } |
629 } | 586 } |
630 } | 587 } |
631 | 588 |
632 void FaviconHandler::OnFaviconData(const std::vector< | 589 void FaviconHandler::OnFaviconData(const std::vector< |
633 favicon_base::FaviconRawBitmapResult>& favicon_bitmap_results) { | 590 favicon_base::FaviconRawBitmapResult>& favicon_bitmap_results) { |
634 bool has_results = !favicon_bitmap_results.empty(); | 591 bool has_results = !favicon_bitmap_results.empty(); |
635 bool has_valid_result = HasValidResult(favicon_bitmap_results); | 592 bool has_valid_result = HasValidResult(favicon_bitmap_results); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
670 std::vector<gfx::Size>()); | 627 std::vector<gfx::Size>()); |
671 return; | 628 return; |
672 } | 629 } |
673 // A max bitmap size is specified to avoid receiving huge bitmaps in | 630 // A max bitmap size is specified to avoid receiving huge bitmaps in |
674 // OnDidDownloadFavicon(). See FaviconDriver::StartDownload() | 631 // OnDidDownloadFavicon(). See FaviconDriver::StartDownload() |
675 // for more details about the max bitmap size. | 632 // for more details about the max bitmap size. |
676 const int download_id = | 633 const int download_id = |
677 delegate_->DownloadImage(image_url, GetMaximalIconSize(icon_type), | 634 delegate_->DownloadImage(image_url, GetMaximalIconSize(icon_type), |
678 base::Bind(&FaviconHandler::OnDidDownloadFavicon, | 635 base::Bind(&FaviconHandler::OnDidDownloadFavicon, |
679 weak_ptr_factory_.GetWeakPtr())); | 636 weak_ptr_factory_.GetWeakPtr())); |
| 637 DCHECK_NE(download_id, 0); |
680 | 638 |
681 // Download ids should be unique. | 639 // Download ids should be unique. |
682 DCHECK(download_requests_.find(download_id) == download_requests_.end()); | 640 DCHECK(download_requests_.find(download_id) == download_requests_.end()); |
683 download_requests_[download_id] = DownloadRequest(image_url, icon_type); | 641 download_requests_[download_id] = DownloadRequest(image_url, icon_type); |
684 | |
685 // TODO(mastiz): Remove the download_id == 0 handling because it's not used | |
686 // in production code, only tests. | |
687 if (download_id == 0) { | |
688 // If DownloadFavicon() did not start a download, it returns a download id | |
689 // of 0. We still need to call OnDidDownloadFavicon() because the method is | |
690 // responsible for initiating the data request for the next candidate. | |
691 OnDidDownloadFavicon(download_id, 0, image_url, std::vector<SkBitmap>(), | |
692 std::vector<gfx::Size>()); | |
693 } | |
694 } | 642 } |
695 | 643 |
696 } // namespace favicon | 644 } // namespace favicon |
OLD | NEW |