Chromium Code Reviews| 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 <utility> | 9 #include <utility> |
| 10 #include <vector> | 10 #include <vector> |
| 11 | 11 |
| 12 #include "base/bind.h" | 12 #include "base/bind.h" |
| 13 #include "base/bind_helpers.h" | 13 #include "base/bind_helpers.h" |
| 14 #include "base/feature_list.h" | |
| 14 #include "base/memory/ref_counted_memory.h" | 15 #include "base/memory/ref_counted_memory.h" |
| 15 #include "base/metrics/histogram_macros.h" | 16 #include "base/metrics/histogram_macros.h" |
| 16 #include "build/build_config.h" | 17 #include "build/build_config.h" |
| 17 #include "components/favicon/core/favicon_service.h" | 18 #include "components/favicon/core/favicon_service.h" |
| 18 #include "components/favicon_base/favicon_util.h" | 19 #include "components/favicon_base/favicon_util.h" |
| 19 #include "components/favicon_base/select_favicon_frames.h" | 20 #include "components/favicon_base/select_favicon_frames.h" |
| 20 #include "skia/ext/image_operations.h" | 21 #include "skia/ext/image_operations.h" |
| 21 #include "ui/gfx/codec/png_codec.h" | 22 #include "ui/gfx/codec/png_codec.h" |
| 22 #include "ui/gfx/image/image_skia.h" | 23 #include "ui/gfx/image/image_skia.h" |
| 23 #include "ui/gfx/image/image_util.h" | 24 #include "ui/gfx/image/image_util.h" |
| 24 | 25 |
| 25 namespace favicon { | 26 namespace favicon { |
| 27 | |
| 28 const base::Feature kFaviconsFromWebManifest{"FaviconsFromWebManifest", | |
| 29 base::FEATURE_DISABLED_BY_DEFAULT}; | |
| 30 | |
| 26 namespace { | 31 namespace { |
| 27 | 32 |
| 28 const int kNonTouchLargestIconSize = 192; | 33 const int kNonTouchLargestIconSize = 192; |
| 29 | 34 |
| 30 // Size (along each axis) of a touch icon. This currently corresponds to | 35 // Size (along each axis) of a touch icon. This currently corresponds to |
| 31 // the apple touch icon for iPad. | 36 // the apple touch icon for iPad. |
| 32 const int kTouchIconSize = 144; | 37 const int kTouchIconSize = 144; |
| 33 | 38 |
| 34 // Return true if |bitmap_result| is expired. | 39 // Return true if |bitmap_result| is expired. |
| 35 bool IsExpired(const favicon_base::FaviconRawBitmapResult& bitmap_result) { | 40 bool IsExpired(const favicon_base::FaviconRawBitmapResult& bitmap_result) { |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 134 } | 139 } |
| 135 case FaviconDriverObserver::NON_TOUCH_LARGEST: | 140 case FaviconDriverObserver::NON_TOUCH_LARGEST: |
| 136 return std::vector<int>(1U, kNonTouchLargestIconSize); | 141 return std::vector<int>(1U, kNonTouchLargestIconSize); |
| 137 case FaviconDriverObserver::TOUCH_LARGEST: | 142 case FaviconDriverObserver::TOUCH_LARGEST: |
| 138 return std::vector<int>(1U, kTouchIconSize); | 143 return std::vector<int>(1U, kTouchIconSize); |
| 139 } | 144 } |
| 140 NOTREACHED(); | 145 NOTREACHED(); |
| 141 return std::vector<int>(); | 146 return std::vector<int>(); |
| 142 } | 147 } |
| 143 | 148 |
| 149 bool FaviconURLEquals(const FaviconURL& lhs, const FaviconURL& rhs) { | |
| 150 return lhs.icon_url == rhs.icon_url && lhs.icon_type == rhs.icon_type && | |
| 151 lhs.icon_sizes == rhs.icon_sizes; | |
| 152 } | |
| 153 | |
| 144 } // namespace | 154 } // namespace |
| 145 | 155 |
| 146 //////////////////////////////////////////////////////////////////////////////// | 156 //////////////////////////////////////////////////////////////////////////////// |
| 147 | 157 |
| 148 // static | 158 // static |
| 149 FaviconHandler::FaviconCandidate | 159 FaviconHandler::FaviconCandidate |
| 150 FaviconHandler::FaviconCandidate::FromFaviconURL( | 160 FaviconHandler::FaviconCandidate::FromFaviconURL( |
| 151 const favicon::FaviconURL& favicon_url, | 161 const favicon::FaviconURL& favicon_url, |
| 152 const std::vector<int>& desired_pixel_sizes) { | 162 const std::vector<int>& desired_pixel_sizes) { |
| 153 FaviconCandidate candidate; | 163 FaviconCandidate candidate; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 202 | 212 |
| 203 void FaviconHandler::FetchFavicon(const GURL& url) { | 213 void FaviconHandler::FetchFavicon(const GURL& url) { |
| 204 cancelable_task_tracker_for_page_url_.TryCancelAll(); | 214 cancelable_task_tracker_for_page_url_.TryCancelAll(); |
| 205 cancelable_task_tracker_for_candidates_.TryCancelAll(); | 215 cancelable_task_tracker_for_candidates_.TryCancelAll(); |
| 206 | 216 |
| 207 url_ = url; | 217 url_ = url; |
| 208 | 218 |
| 209 initial_history_result_expired_or_incomplete_ = false; | 219 initial_history_result_expired_or_incomplete_ = false; |
| 210 redownload_icons_ = false; | 220 redownload_icons_ = false; |
| 211 got_favicon_from_history_ = false; | 221 got_favicon_from_history_ = false; |
| 222 manifest_download_request_.Cancel(); | |
| 212 image_download_request_.Cancel(); | 223 image_download_request_.Cancel(); |
| 224 manifest_url_ = GURL(); | |
| 225 non_manifest_original_candidates_.clear(); | |
| 213 candidates_.clear(); | 226 candidates_.clear(); |
| 214 notification_icon_url_ = GURL(); | 227 notification_icon_url_ = GURL(); |
| 215 notification_icon_type_ = favicon_base::INVALID_ICON; | 228 notification_icon_type_ = favicon_base::INVALID_ICON; |
| 216 num_image_download_requests_ = 0; | 229 num_image_download_requests_ = 0; |
| 217 current_candidate_index_ = 0u; | 230 current_candidate_index_ = 0u; |
| 218 best_favicon_ = DownloadedFavicon(); | 231 best_favicon_ = DownloadedFavicon(); |
| 219 | 232 |
| 220 // Request the favicon from the history service. In parallel to this the | 233 // Request the favicon from the history service. In parallel to this the |
| 221 // renderer is going to notify us (well WebContents) when the favicon url is | 234 // renderer is going to notify us (well WebContents) when the favicon url is |
| 222 // available. | 235 // available. |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 290 delegate_->OnFaviconUpdated(url_, handler_type_, icon_url, | 303 delegate_->OnFaviconUpdated(url_, handler_type_, icon_url, |
| 291 icon_url != notification_icon_url_, | 304 icon_url != notification_icon_url_, |
| 292 image_with_adjusted_colorspace); | 305 image_with_adjusted_colorspace); |
| 293 | 306 |
| 294 notification_icon_url_ = icon_url; | 307 notification_icon_url_ = icon_url; |
| 295 notification_icon_type_ = icon_type; | 308 notification_icon_type_ = icon_type; |
| 296 } | 309 } |
| 297 | 310 |
| 298 void FaviconHandler::OnUpdateCandidates( | 311 void FaviconHandler::OnUpdateCandidates( |
| 299 const GURL& page_url, | 312 const GURL& page_url, |
| 300 const std::vector<FaviconURL>& candidates) { | 313 const std::vector<FaviconURL>& candidates, |
| 314 const GURL& manifest_url) { | |
| 301 if (page_url != url_) | 315 if (page_url != url_) |
| 302 return; | 316 return; |
| 303 | 317 |
| 318 bool manifests_feature_enabled = | |
| 319 base::FeatureList::IsEnabled(kFaviconsFromWebManifest); | |
| 320 | |
| 321 // |candidates| or |manifest_url| could have been modified via Javascript. If | |
| 322 // neither changed, ignore the call. | |
| 323 if ((!manifests_feature_enabled || manifest_url_ == manifest_url) && | |
| 324 non_manifest_original_candidates_.size() == candidates.size() && | |
| 325 std::equal(candidates.begin(), candidates.end(), | |
| 326 non_manifest_original_candidates_.begin(), | |
| 327 &FaviconURLEquals)) { | |
| 328 return; | |
| 329 } | |
| 330 | |
| 331 non_manifest_original_candidates_ = candidates; | |
| 332 cancelable_task_tracker_for_candidates_.TryCancelAll(); | |
| 333 manifest_download_request_.Cancel(); | |
| 334 image_download_request_.Cancel(); | |
| 335 num_image_download_requests_ = 0; | |
| 336 current_candidate_index_ = 0u; | |
| 337 best_favicon_ = DownloadedFavicon(); | |
| 338 | |
| 339 if (manifests_feature_enabled) | |
| 340 manifest_url_ = manifest_url; | |
| 341 | |
| 342 // Check if the manifest was previously blacklisted (e.g. returned a 404) and | |
| 343 // ignore the manifest URL if that's the case. | |
| 344 if (!manifest_url_.is_empty() && | |
| 345 service_->WasUnableToDownloadFavicon(manifest_url_)) { | |
| 346 DVLOG(1) << "Skip failed Manifest: " << manifest_url; | |
| 347 manifest_url_ = GURL(); | |
|
pkotwicz
2017/05/17 05:20:34
For a follow up CL. Setting |manifest_url_| here a
| |
| 348 } | |
| 349 | |
| 350 // If no manifest available, proceed with the regular candidates only. | |
| 351 if (manifest_url_.is_empty()) { | |
| 352 OnGotFinalIconURLCandidates(candidates); | |
| 353 return; | |
| 354 } | |
| 355 | |
| 356 // See if there is a cached favicon for the manifest. This will update the DB | |
| 357 // mappings only if the manifest URL is cached. | |
| 358 GetFaviconAndUpdateMappingsUnlessIncognito( | |
| 359 /*icon_url=*/manifest_url_, favicon_base::FAVICON, | |
| 360 base::Bind(&FaviconHandler::OnFaviconDataForManifestFromFaviconService, | |
| 361 base::Unretained(this))); | |
| 362 } | |
| 363 | |
| 364 void FaviconHandler::OnFaviconDataForManifestFromFaviconService( | |
| 365 const std::vector<favicon_base::FaviconRawBitmapResult>& | |
| 366 favicon_bitmap_results) { | |
| 367 // The database lookup for the page URL is guaranteed to be completed because | |
| 368 // the HistoryBackend uses a SequencedTaskRunner, and we also know that | |
| 369 // FetchFavicon() was called before OnUpdateCandidates(). | |
| 370 DCHECK(got_favicon_from_history_); | |
| 371 | |
| 372 bool has_valid_result = HasValidResult(favicon_bitmap_results); | |
| 373 bool has_expired_or_incomplete_result = | |
| 374 !has_valid_result || HasExpiredOrIncompleteResult(preferred_icon_size(), | |
| 375 favicon_bitmap_results); | |
| 376 | |
| 377 if (has_valid_result && (notification_icon_url_ != manifest_url_ || | |
| 378 notification_icon_type_ != favicon_base::FAVICON)) { | |
| 379 // There is a valid favicon. Notify any observers. It is useful to notify | |
| 380 // the observers even if the favicon is expired or incomplete (incorrect | |
| 381 // size) because temporarily showing the user an expired favicon or | |
| 382 // streched favicon is preferable to showing the user the default favicon. | |
| 383 NotifyFaviconUpdated(favicon_bitmap_results); | |
| 384 } | |
| 385 | |
| 386 if (has_expired_or_incomplete_result) { | |
| 387 manifest_download_request_.Reset(base::Bind( | |
| 388 &FaviconHandler::OnDidDownloadManifest, base::Unretained(this))); | |
| 389 delegate_->DownloadManifest(manifest_url_, | |
| 390 manifest_download_request_.callback()); | |
| 391 } | |
| 392 } | |
| 393 | |
| 394 void FaviconHandler::OnDidDownloadManifest( | |
| 395 const std::vector<FaviconURL>& candidates) { | |
| 396 // Mark manifest download as finished. | |
| 397 manifest_download_request_.Cancel(); | |
| 398 | |
| 399 if (!candidates.empty()) { | |
| 400 OnGotFinalIconURLCandidates(candidates); | |
| 401 return; | |
| 402 } | |
| 403 | |
| 404 // If either the downloading of the manifest failed, OR the manifest contains | |
| 405 // no icons, proceed with the list of icons listed in the HTML. | |
| 406 DVLOG(1) << "Could not fetch Manifest icons from " << manifest_url_ | |
| 407 << ", falling back to inlined ones, which are " | |
| 408 << non_manifest_original_candidates_.size(); | |
| 409 | |
| 410 service_->UnableToDownloadFavicon(manifest_url_); | |
| 411 manifest_url_ = GURL(); | |
| 412 | |
| 413 OnGotFinalIconURLCandidates(non_manifest_original_candidates_); | |
| 414 } | |
| 415 | |
| 416 void FaviconHandler::OnGotFinalIconURLCandidates( | |
| 417 const std::vector<FaviconURL>& candidates) { | |
| 304 std::vector<FaviconCandidate> sorted_candidates; | 418 std::vector<FaviconCandidate> sorted_candidates; |
| 305 const std::vector<int> desired_pixel_sizes = | 419 const std::vector<int> desired_pixel_sizes = |
| 306 GetDesiredPixelSizes(handler_type_); | 420 GetDesiredPixelSizes(handler_type_); |
| 307 for (const FaviconURL& candidate : candidates) { | 421 for (const FaviconURL& candidate : candidates) { |
| 308 if (!candidate.icon_url.is_empty() && (candidate.icon_type & icon_types_)) { | 422 if (!candidate.icon_url.is_empty() && (candidate.icon_type & icon_types_)) { |
| 309 sorted_candidates.push_back( | 423 sorted_candidates.push_back( |
| 310 FaviconCandidate::FromFaviconURL(candidate, desired_pixel_sizes)); | 424 FaviconCandidate::FromFaviconURL(candidate, desired_pixel_sizes)); |
| 311 } | 425 } |
| 312 } | 426 } |
| 313 | 427 |
| 314 std::stable_sort(sorted_candidates.begin(), sorted_candidates.end(), | 428 std::stable_sort(sorted_candidates.begin(), sorted_candidates.end(), |
| 315 &FaviconCandidate::CompareScore); | 429 &FaviconCandidate::CompareScore); |
| 316 | 430 |
| 317 if (candidates_.size() == sorted_candidates.size() && | |
| 318 std::equal(sorted_candidates.begin(), sorted_candidates.end(), | |
| 319 candidates_.begin())) { | |
| 320 return; | |
| 321 } | |
| 322 | |
| 323 cancelable_task_tracker_for_candidates_.TryCancelAll(); | |
| 324 image_download_request_.Cancel(); | |
| 325 candidates_ = std::move(sorted_candidates); | 431 candidates_ = std::move(sorted_candidates); |
| 326 num_image_download_requests_ = 0; | |
| 327 current_candidate_index_ = 0u; | |
| 328 best_favicon_ = DownloadedFavicon(); | |
| 329 | 432 |
| 330 // TODO(davemoore) Should clear on empty url. Currently we ignore it. | 433 // TODO(davemoore) Should clear on empty url. Currently we ignore it. |
| 331 // This appears to be what FF does as well. | 434 // This appears to be what FF does as well. |
| 332 if (current_candidate() && got_favicon_from_history_) | 435 if (current_candidate() && got_favicon_from_history_) |
| 333 OnGotInitialHistoryDataAndIconURLCandidates(); | 436 OnGotInitialHistoryDataAndIconURLCandidates(); |
| 334 } | 437 } |
| 335 | 438 |
| 336 // static | 439 // static |
| 337 int FaviconHandler::GetMaximalIconSize( | 440 int FaviconHandler::GetMaximalIconSize( |
| 338 FaviconDriverObserver::NotificationIconType handler_type) { | 441 FaviconDriverObserver::NotificationIconType handler_type) { |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 412 // Process the next candidate. | 515 // Process the next candidate. |
| 413 ++current_candidate_index_; | 516 ++current_candidate_index_; |
| 414 DownloadCurrentCandidateOrAskFaviconService(); | 517 DownloadCurrentCandidateOrAskFaviconService(); |
| 415 } else { | 518 } else { |
| 416 // OnDidDownloadFavicon() can only be called after requesting a download, so | 519 // OnDidDownloadFavicon() can only be called after requesting a download, so |
| 417 // |num_image_download_requests_| can never be 0. | 520 // |num_image_download_requests_| can never be 0. |
| 418 RecordDownloadAttemptsForHandlerType(handler_type_, | 521 RecordDownloadAttemptsForHandlerType(handler_type_, |
| 419 num_image_download_requests_); | 522 num_image_download_requests_); |
| 420 // We have either found the ideal candidate or run out of candidates. | 523 // We have either found the ideal candidate or run out of candidates. |
| 421 if (best_favicon_.candidate.icon_type != favicon_base::INVALID_ICON) { | 524 if (best_favicon_.candidate.icon_type != favicon_base::INVALID_ICON) { |
| 422 // No more icons to request, set the favicon from the candidate. | 525 // No more icons to request, set the favicon from the candidate. The |
| 423 SetFavicon(best_favicon_.candidate.icon_url, best_favicon_.image, | 526 // manifest URL, if available, is used instead of the icon URL. |
| 424 best_favicon_.candidate.icon_type); | 527 SetFavicon(manifest_url_.is_empty() ? best_favicon_.candidate.icon_url |
| 528 : manifest_url_, | |
| 529 best_favicon_.image, best_favicon_.candidate.icon_type); | |
| 425 } | 530 } |
| 426 // Clear download related state. | 531 // Clear download related state. |
| 427 current_candidate_index_ = candidates_.size(); | 532 current_candidate_index_ = candidates_.size(); |
| 428 num_image_download_requests_ = 0; | 533 num_image_download_requests_ = 0; |
| 429 best_favicon_ = DownloadedFavicon(); | 534 best_favicon_ = DownloadedFavicon(); |
| 430 } | 535 } |
| 431 } | 536 } |
| 432 | 537 |
| 433 const std::vector<GURL> FaviconHandler::GetIconURLs() const { | 538 const std::vector<GURL> FaviconHandler::GetIconURLs() const { |
| 434 std::vector<GURL> icon_urls; | 539 std::vector<GURL> icon_urls; |
| 435 for (const FaviconCandidate& candidate : candidates_) | 540 for (const FaviconCandidate& candidate : candidates_) |
| 436 icon_urls.push_back(candidate.icon_url); | 541 icon_urls.push_back(candidate.icon_url); |
| 437 return icon_urls; | 542 return icon_urls; |
| 438 } | 543 } |
| 439 | 544 |
| 440 bool FaviconHandler::HasPendingTasksForTest() { | 545 bool FaviconHandler::HasPendingTasksForTest() { |
| 441 return !image_download_request_.IsCancelled() || | 546 return !image_download_request_.IsCancelled() || |
| 547 !manifest_download_request_.IsCancelled() || | |
| 442 cancelable_task_tracker_for_page_url_.HasTrackedTasks() || | 548 cancelable_task_tracker_for_page_url_.HasTrackedTasks() || |
| 443 cancelable_task_tracker_for_candidates_.HasTrackedTasks(); | 549 cancelable_task_tracker_for_candidates_.HasTrackedTasks(); |
| 444 } | 550 } |
| 445 | 551 |
| 446 bool FaviconHandler::ShouldSaveFavicon() { | 552 bool FaviconHandler::ShouldSaveFavicon() { |
| 447 if (!delegate_->IsOffTheRecord()) | 553 if (!delegate_->IsOffTheRecord()) |
| 448 return true; | 554 return true; |
| 449 | 555 |
| 450 // Always save favicon if the page is bookmarked. | 556 // Always save favicon if the page is bookmarked. |
| 451 return delegate_->IsBookmarked(url_); | 557 return delegate_->IsBookmarked(url_); |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 469 // url) we'll fetch later on. This way the user doesn't see a flash of the | 575 // url) we'll fetch later on. This way the user doesn't see a flash of the |
| 470 // default favicon. | 576 // default favicon. |
| 471 NotifyFaviconUpdated(favicon_bitmap_results); | 577 NotifyFaviconUpdated(favicon_bitmap_results); |
| 472 } | 578 } |
| 473 | 579 |
| 474 if (current_candidate()) | 580 if (current_candidate()) |
| 475 OnGotInitialHistoryDataAndIconURLCandidates(); | 581 OnGotInitialHistoryDataAndIconURLCandidates(); |
| 476 } | 582 } |
| 477 | 583 |
| 478 void FaviconHandler::DownloadCurrentCandidateOrAskFaviconService() { | 584 void FaviconHandler::DownloadCurrentCandidateOrAskFaviconService() { |
| 479 GURL icon_url = current_candidate()->icon_url; | 585 const GURL icon_url = current_candidate()->icon_url; |
| 480 favicon_base::IconType icon_type = current_candidate()->icon_type; | 586 const favicon_base::IconType icon_type = current_candidate()->icon_type; |
| 481 | 587 // If the icons listed in a manifest are being processed, skip the cache |
| 482 if (redownload_icons_) { | 588 // lookup for |icon_url| since the manifest's URL is used for caching, not the |
| 589 // icon URL, and this lookup has happened earlier. | |
| 590 if (redownload_icons_ || !manifest_url_.is_empty()) { | |
| 483 // We have the mapping, but the favicon is out of date. Download it now. | 591 // We have the mapping, but the favicon is out of date. Download it now. |
| 484 ScheduleImageDownload(icon_url, icon_type); | 592 ScheduleImageDownload(icon_url, icon_type); |
| 485 } else { | 593 } else { |
| 486 // We don't know the favicon, but we may have previously downloaded the | 594 GetFaviconAndUpdateMappingsUnlessIncognito( |
| 487 // favicon for another page that shares the same favicon. Ask for the | 595 icon_url, icon_type, |
| 488 // favicon given the favicon URL. | 596 base::Bind(&FaviconHandler::OnFaviconData, base::Unretained(this))); |
| 489 if (delegate_->IsOffTheRecord()) { | |
| 490 service_->GetFavicon( | |
| 491 icon_url, icon_type, preferred_icon_size(), | |
| 492 base::Bind(&FaviconHandler::OnFaviconData, base::Unretained(this)), | |
| 493 &cancelable_task_tracker_for_candidates_); | |
| 494 } else { | |
| 495 // Ask the history service for the icon. This does two things: | |
| 496 // 1. Attempts to fetch the favicon data from the database. | |
| 497 // 2. If the favicon exists in the database, this updates the database to | |
| 498 // include the mapping between the page url and the favicon url. | |
| 499 // This is asynchronous. The history service will call back when done. | |
| 500 service_->UpdateFaviconMappingsAndFetch( | |
| 501 url_, icon_url, icon_type, preferred_icon_size(), | |
| 502 base::Bind(&FaviconHandler::OnFaviconData, base::Unretained(this)), | |
| 503 &cancelable_task_tracker_for_candidates_); | |
| 504 } | |
| 505 } | 597 } |
| 506 } | 598 } |
| 507 | 599 |
| 600 void FaviconHandler::GetFaviconAndUpdateMappingsUnlessIncognito( | |
| 601 const GURL& icon_url, | |
| 602 favicon_base::IconType icon_type, | |
| 603 const favicon_base::FaviconResultsCallback& callback) { | |
| 604 // We don't know the favicon, but we may have previously downloaded the | |
| 605 // favicon for another page that shares the same favicon. Ask for the | |
| 606 // favicon given the favicon URL. | |
| 607 if (delegate_->IsOffTheRecord()) { | |
| 608 service_->GetFavicon(icon_url, icon_type, preferred_icon_size(), callback, | |
| 609 &cancelable_task_tracker_for_candidates_); | |
| 610 } else { | |
| 611 // Ask the history service for the icon. This does two things: | |
| 612 // 1. Attempts to fetch the favicon data from the database. | |
| 613 // 2. If the favicon exists in the database, this updates the database to | |
| 614 // include the mapping between the page url and the favicon url. | |
| 615 // This is asynchronous. The history service will call back when done. | |
| 616 service_->UpdateFaviconMappingsAndFetch( | |
| 617 url_, icon_url, icon_type, preferred_icon_size(), callback, | |
| 618 &cancelable_task_tracker_for_candidates_); | |
| 619 } | |
| 620 } | |
| 621 | |
| 508 void FaviconHandler::OnFaviconData(const std::vector< | 622 void FaviconHandler::OnFaviconData(const std::vector< |
| 509 favicon_base::FaviconRawBitmapResult>& favicon_bitmap_results) { | 623 favicon_base::FaviconRawBitmapResult>& favicon_bitmap_results) { |
| 510 bool has_valid_result = HasValidResult(favicon_bitmap_results); | 624 bool has_valid_result = HasValidResult(favicon_bitmap_results); |
| 511 bool has_expired_or_incomplete_result = | 625 bool has_expired_or_incomplete_result = |
| 512 !has_valid_result || HasExpiredOrIncompleteResult(preferred_icon_size(), | 626 !has_valid_result || HasExpiredOrIncompleteResult(preferred_icon_size(), |
| 513 favicon_bitmap_results); | 627 favicon_bitmap_results); |
| 514 | 628 |
| 515 if (has_valid_result) { | 629 if (has_valid_result) { |
| 516 // There is a valid favicon. Notify any observers. It is useful to notify | 630 // There is a valid favicon. Notify any observers. It is useful to notify |
| 517 // the observers even if the favicon is expired or incomplete (incorrect | 631 // the observers even if the favicon is expired or incomplete (incorrect |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 549 // A max bitmap size is specified to avoid receiving huge bitmaps in | 663 // A max bitmap size is specified to avoid receiving huge bitmaps in |
| 550 // OnDidDownloadFavicon(). See FaviconDriver::StartDownload() | 664 // OnDidDownloadFavicon(). See FaviconDriver::StartDownload() |
| 551 // for more details about the max bitmap size. | 665 // for more details about the max bitmap size. |
| 552 const int download_id = | 666 const int download_id = |
| 553 delegate_->DownloadImage(image_url, GetMaximalIconSize(handler_type_), | 667 delegate_->DownloadImage(image_url, GetMaximalIconSize(handler_type_), |
| 554 image_download_request_.callback()); | 668 image_download_request_.callback()); |
| 555 DCHECK_NE(download_id, 0); | 669 DCHECK_NE(download_id, 0); |
| 556 } | 670 } |
| 557 | 671 |
| 558 } // namespace favicon | 672 } // namespace favicon |
| OLD | NEW |