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> |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 95 for (float favicon_scale : favicon_scales) { | 95 for (float favicon_scale : favicon_scales) { |
| 96 int edge_size_in_pixel = std::ceil(desired_size_in_dip * favicon_scale); | 96 int edge_size_in_pixel = std::ceil(desired_size_in_dip * favicon_scale); |
| 97 auto it = std::find(favicon_sizes.begin(), favicon_sizes.end(), | 97 auto it = std::find(favicon_sizes.begin(), favicon_sizes.end(), |
| 98 gfx::Size(edge_size_in_pixel, edge_size_in_pixel)); | 98 gfx::Size(edge_size_in_pixel, edge_size_in_pixel)); |
| 99 if (it == favicon_sizes.end()) | 99 if (it == favicon_sizes.end()) |
| 100 return true; | 100 return true; |
| 101 } | 101 } |
| 102 return false; | 102 return false; |
| 103 } | 103 } |
| 104 | 104 |
| 105 // Returns true if at least one of |bitmap_results| is valid. | 105 // Finds a valid bitmap in |bitmap_results| or returns nullptr otherwise. |
| 106 bool HasValidResult( | 106 const favicon_base::FaviconRawBitmapResult* FindValidResult( |
| 107 const std::vector<favicon_base::FaviconRawBitmapResult>& bitmap_results) { | 107 const std::vector<favicon_base::FaviconRawBitmapResult>& bitmap_results) { |
| 108 return std::find_if(bitmap_results.begin(), bitmap_results.end(), IsValid) != | 108 for (const favicon_base::FaviconRawBitmapResult& result : bitmap_results) { |
| 109 bitmap_results.end(); | 109 if (IsValid(result)) |
| 110 return &result; | |
| 111 } | |
| 112 return nullptr; | |
| 110 } | 113 } |
| 111 | 114 |
| 112 std::vector<int> GetDesiredPixelSizes( | 115 std::vector<int> GetDesiredPixelSizes( |
| 113 FaviconDriverObserver::NotificationIconType handler_type) { | 116 FaviconDriverObserver::NotificationIconType handler_type) { |
| 114 switch (handler_type) { | 117 switch (handler_type) { |
| 115 case FaviconDriverObserver::NON_TOUCH_16_DIP: { | 118 case FaviconDriverObserver::NON_TOUCH_16_DIP: { |
| 116 std::vector<int> pixel_sizes; | 119 std::vector<int> pixel_sizes; |
| 117 for (float scale_factor : favicon_base::GetFaviconScales()) { | 120 for (float scale_factor : favicon_base::GetFaviconScales()) { |
| 118 pixel_sizes.push_back( | 121 pixel_sizes.push_back( |
| 119 static_cast<int>(ceil(scale_factor * gfx::kFaviconSize))); | 122 static_cast<int>(ceil(scale_factor * gfx::kFaviconSize))); |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 188 } | 191 } |
| 189 | 192 |
| 190 void FaviconHandler::FetchFavicon(const GURL& url) { | 193 void FaviconHandler::FetchFavicon(const GURL& url) { |
| 191 cancelable_task_tracker_.TryCancelAll(); | 194 cancelable_task_tracker_.TryCancelAll(); |
| 192 | 195 |
| 193 url_ = url; | 196 url_ = url; |
| 194 | 197 |
| 195 initial_history_result_expired_or_incomplete_ = false; | 198 initial_history_result_expired_or_incomplete_ = false; |
| 196 redownload_icons_ = false; | 199 redownload_icons_ = false; |
| 197 got_favicon_from_history_ = false; | 200 got_favicon_from_history_ = false; |
| 198 download_request_.Cancel(); | 201 manifest_download_request_.Cancel(); |
| 202 image_download_request_.Cancel(); | |
| 203 manifest_url_.reset(); | |
| 199 candidates_.clear(); | 204 candidates_.clear(); |
| 200 notification_icon_url_ = GURL(); | 205 notification_icon_url_ = GURL(); |
| 201 notification_icon_type_ = favicon_base::INVALID_ICON; | 206 notification_icon_type_ = favicon_base::INVALID_ICON; |
| 202 current_candidate_index_ = 0u; | 207 current_candidate_index_ = 0u; |
| 203 best_favicon_ = DownloadedFavicon(); | 208 best_favicon_ = DownloadedFavicon(); |
| 204 | 209 |
| 205 // Request the favicon from the history service. In parallel to this the | 210 // Request the favicon from the history service. In parallel to this the |
| 206 // renderer is going to notify us (well WebContents) when the favicon url is | 211 // renderer is going to notify us (well WebContents) when the favicon url is |
| 207 // available. | 212 // available. |
| 208 if (service_) { | 213 if (service_) { |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 236 candidates_[current_candidate_index_ + 1].score <= | 241 candidates_[current_candidate_index_ + 1].score <= |
| 237 best_favicon_.candidate.score; | 242 best_favicon_.candidate.score; |
| 238 } else { | 243 } else { |
| 239 return best_favicon_.candidate.score == 1; | 244 return best_favicon_.candidate.score == 1; |
| 240 } | 245 } |
| 241 } | 246 } |
| 242 | 247 |
| 243 void FaviconHandler::SetFavicon(const GURL& icon_url, | 248 void FaviconHandler::SetFavicon(const GURL& icon_url, |
| 244 const gfx::Image& image, | 249 const gfx::Image& image, |
| 245 favicon_base::IconType icon_type) { | 250 favicon_base::IconType icon_type) { |
| 246 if (service_ && ShouldSaveFavicon()) | 251 if (service_ && ShouldSaveFavicon()) { |
| 247 service_->SetFavicons(url_, icon_url, icon_type, image); | 252 service_->SetFavicons(url_, icon_url, icon_type, image); |
| 253 // If the icon list was coming from a Web Manifest, let's also store | |
| 254 // the association using the manifest's URL as page URL. | |
| 255 if (manifest_url_) | |
| 256 service_->SetFavicons(*manifest_url_, icon_url, icon_type, image); | |
|
pkotwicz
2017/04/07 14:13:04
- We will need to add expiry logic specifically fo
mastiz
2017/04/10 15:34:12
The first argument above is convincing to go for i
| |
| 257 } | |
| 248 | 258 |
| 249 NotifyFaviconUpdated(icon_url, icon_type, image); | 259 NotifyFaviconUpdated(icon_url, icon_type, image); |
| 250 } | 260 } |
| 251 | 261 |
| 252 void FaviconHandler::NotifyFaviconUpdated( | 262 void FaviconHandler::NotifyFaviconUpdated( |
| 253 const std::vector<favicon_base::FaviconRawBitmapResult>& | 263 const std::vector<favicon_base::FaviconRawBitmapResult>& |
| 254 favicon_bitmap_results) { | 264 favicon_bitmap_results) { |
| 255 if (favicon_bitmap_results.empty()) | 265 if (favicon_bitmap_results.empty()) |
| 256 return; | 266 return; |
| 257 | 267 |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 277 favicon_base::SetFaviconColorSpace(&image_with_adjusted_colorspace); | 287 favicon_base::SetFaviconColorSpace(&image_with_adjusted_colorspace); |
| 278 | 288 |
| 279 delegate_->OnFaviconUpdated(url_, handler_type_, icon_url, | 289 delegate_->OnFaviconUpdated(url_, handler_type_, icon_url, |
| 280 icon_url != notification_icon_url_, | 290 icon_url != notification_icon_url_, |
| 281 image_with_adjusted_colorspace); | 291 image_with_adjusted_colorspace); |
| 282 | 292 |
| 283 notification_icon_url_ = icon_url; | 293 notification_icon_url_ = icon_url; |
| 284 notification_icon_type_ = icon_type; | 294 notification_icon_type_ = icon_type; |
| 285 } | 295 } |
| 286 | 296 |
| 287 void FaviconHandler::OnUpdateFaviconURL( | 297 void FaviconHandler::OnUpdateCandidates( |
| 288 const GURL& page_url, | 298 const GURL& page_url, |
| 299 const std::vector<FaviconURL>& candidates, | |
| 300 const base::Optional<GURL>& manifest_url) { | |
| 301 DCHECK_EQ(page_url, url_); | |
| 302 | |
| 303 manifest_url_ = manifest_url; | |
| 304 | |
| 305 // If no manifest available, proceed with the regular candidates only. | |
| 306 if (!manifest_url.has_value()) { | |
| 307 OnGotFinalIconURLCandidates(candidates); | |
| 308 return; | |
| 309 } | |
| 310 | |
| 311 // See if there is a cached favicon for the manifest. | |
| 312 service_->GetFaviconForPageURL( | |
| 313 *manifest_url, icon_types_, preferred_icon_size(), | |
| 314 base::Bind(&FaviconHandler::OnFaviconDataForManifestURLFromFaviconService, | |
| 315 base::Unretained(this)), | |
| 316 &cancelable_task_tracker_); | |
| 317 } | |
| 318 | |
| 319 void FaviconHandler::OnGotFinalIconURLCandidates( | |
| 289 const std::vector<FaviconURL>& candidates) { | 320 const std::vector<FaviconURL>& candidates) { |
| 290 if (page_url != url_) | 321 // Mark manifest download as finished, if there was one. |
| 291 return; | 322 manifest_download_request_.Cancel(); |
| 292 | 323 |
| 293 std::vector<FaviconCandidate> sorted_candidates; | 324 std::vector<FaviconCandidate> sorted_candidates; |
| 294 const std::vector<int> desired_pixel_sizes = | 325 const std::vector<int> desired_pixel_sizes = |
| 295 GetDesiredPixelSizes(handler_type_); | 326 GetDesiredPixelSizes(handler_type_); |
| 296 for (const FaviconURL& candidate : candidates) { | 327 for (const FaviconURL& candidate : candidates) { |
| 297 if (!candidate.icon_url.is_empty() && (candidate.icon_type & icon_types_)) { | 328 if (!candidate.icon_url.is_empty() && (candidate.icon_type & icon_types_)) { |
| 298 sorted_candidates.push_back( | 329 sorted_candidates.push_back( |
| 299 FaviconCandidate::FromFaviconURL(candidate, desired_pixel_sizes)); | 330 FaviconCandidate::FromFaviconURL(candidate, desired_pixel_sizes)); |
| 300 } | 331 } |
| 301 } | 332 } |
| 302 | 333 |
| 303 std::stable_sort(sorted_candidates.begin(), sorted_candidates.end(), | 334 std::stable_sort(sorted_candidates.begin(), sorted_candidates.end(), |
| 304 &FaviconCandidate::CompareScore); | 335 &FaviconCandidate::CompareScore); |
| 305 | 336 |
| 306 if (candidates_.size() == sorted_candidates.size() && | 337 if (candidates_.size() == sorted_candidates.size() && |
| 307 std::equal(sorted_candidates.begin(), sorted_candidates.end(), | 338 std::equal(sorted_candidates.begin(), sorted_candidates.end(), |
| 308 candidates_.begin())) { | 339 candidates_.begin())) { |
| 309 return; | 340 return; |
| 310 } | 341 } |
| 311 | 342 |
| 312 download_request_.Cancel(); | 343 image_download_request_.Cancel(); |
| 313 candidates_ = std::move(sorted_candidates); | 344 candidates_ = std::move(sorted_candidates); |
| 314 current_candidate_index_ = 0u; | 345 current_candidate_index_ = 0u; |
| 315 best_favicon_ = DownloadedFavicon(); | 346 best_favicon_ = DownloadedFavicon(); |
| 316 | 347 |
| 317 // TODO(davemoore) Should clear on empty url. Currently we ignore it. | 348 // TODO(davemoore) Should clear on empty url. Currently we ignore it. |
| 318 // This appears to be what FF does as well. | 349 // This appears to be what FF does as well. |
| 319 if (current_candidate() && got_favicon_from_history_) | 350 if (current_candidate() && got_favicon_from_history_) |
| 320 OnGotInitialHistoryDataAndIconURLCandidates(); | 351 OnGotInitialHistoryDataAndIconURLCandidates(); |
| 321 } | 352 } |
| 322 | 353 |
| 323 // static | 354 // static |
| 324 int FaviconHandler::GetMaximalIconSize( | 355 int FaviconHandler::GetMaximalIconSize( |
| 325 FaviconDriverObserver::NotificationIconType handler_type) { | 356 FaviconDriverObserver::NotificationIconType handler_type) { |
| 326 int max_size = 0; | 357 int max_size = 0; |
| 327 for (int size : GetDesiredPixelSizes(handler_type)) | 358 for (int size : GetDesiredPixelSizes(handler_type)) |
| 328 max_size = std::max(max_size, size); | 359 max_size = std::max(max_size, size); |
| 329 return max_size; | 360 return max_size; |
| 330 } | 361 } |
| 331 | 362 |
| 332 void FaviconHandler::OnGotInitialHistoryDataAndIconURLCandidates() { | 363 void FaviconHandler::OnGotInitialHistoryDataAndIconURLCandidates() { |
| 333 if (!initial_history_result_expired_or_incomplete_ && | 364 if (!initial_history_result_expired_or_incomplete_ && |
| 334 current_candidate()->icon_url == notification_icon_url_ && | 365 current_candidate()->icon_url == notification_icon_url_ && |
|
pkotwicz
2017/04/07 14:13:04
This check will fail if the database icon URL is f
mastiz
2017/04/10 15:34:12
Can you please elaborate this? I can see how this
pkotwicz
2017/04/11 03:47:07
Looks like I was wrong. I was thinking that this c
| |
| 335 current_candidate()->icon_type == notification_icon_type_) { | 366 current_candidate()->icon_type == notification_icon_type_) { |
| 336 // - The data from history is valid and not expired. | 367 // - The data from history is valid and not expired. |
| 337 // - The icon URL of the history data matches one of the page's icon URLs. | 368 // - The icon URL of the history data matches one of the page's icon URLs. |
| 338 // - The icon URL of the history data matches the icon URL of the last | 369 // - The icon URL of the history data matches the icon URL of the last |
| 339 // OnFaviconAvailable() notification. | 370 // OnFaviconAvailable() notification. |
| 340 // We are done. No additional downloads or history requests are needed. | 371 // We are done. No additional downloads or history requests are needed. |
| 341 // TODO: Store all of the icon URLs associated with a page in history so | 372 // TODO: Store all of the icon URLs associated with a page in history so |
| 342 // that we can check whether the page's icon URLs match the page's icon URLs | 373 // that we can check whether the page's icon URLs match the page's icon URLs |
| 343 // at the time that the favicon data was stored to the history database. | 374 // at the time that the favicon data was stored to the history database. |
| 344 return; | 375 return; |
| 345 } | 376 } |
| 346 | 377 |
| 347 DownloadCurrentCandidateOrAskFaviconService(); | 378 DownloadCurrentCandidateOrAskFaviconService(); |
| 348 } | 379 } |
| 349 | 380 |
| 381 void FaviconHandler::OnFaviconDataForManifestURLFromFaviconService( | |
| 382 const std::vector<favicon_base::FaviconRawBitmapResult>& | |
| 383 favicon_bitmap_results) { | |
| 384 DCHECK(manifest_download_request_.IsCancelled()); | |
| 385 | |
| 386 const favicon_base::FaviconRawBitmapResult* valid_result = | |
| 387 FindValidResult(favicon_bitmap_results); | |
| 388 | |
| 389 if (valid_result) { | |
| 390 // There is a valid favicon. Notify any observers. It is useful to notify | |
| 391 // the observers even if the favicon is expired or incomplete (incorrect | |
| 392 // size) because temporarily showing the user an expired favicon or | |
| 393 // streched favicon is preferable to showing the user the default favicon. | |
| 394 NotifyFaviconUpdated(favicon_bitmap_results); | |
| 395 } | |
| 396 | |
| 397 if (valid_result && !HasExpiredOrIncompleteResult(preferred_icon_size(), | |
| 398 favicon_bitmap_results)) { | |
| 399 // Register a direct mapping between the page URL and the icons listed in | |
| 400 // the manifest. | |
| 401 if (service_ && ShouldSaveFavicon()) { | |
| 402 service_->MergeFavicon(url_, {valid_result->icon_url}, | |
| 403 valid_result->icon_type, valid_result->bitmap_data, | |
| 404 valid_result->pixel_size); | |
|
pkotwicz
2017/04/07 14:13:04
Why are you calling FaviconService::MergeFavicon()
mastiz
2017/04/10 15:34:12
I could explain why but this is a moot point anywa
| |
| 405 } | |
| 406 } else { | |
| 407 manifest_download_request_.Reset(base::Bind( | |
| 408 &FaviconHandler::OnGotFinalIconURLCandidates, base::Unretained(this))); | |
| 409 delegate_->DownloadManifest(*manifest_url_, | |
| 410 manifest_download_request_.callback()); | |
| 411 } | |
| 412 } | |
| 413 | |
| 350 void FaviconHandler::OnDidDownloadFavicon( | 414 void FaviconHandler::OnDidDownloadFavicon( |
| 351 favicon_base::IconType icon_type, | 415 favicon_base::IconType icon_type, |
| 352 int id, | 416 int id, |
| 353 int http_status_code, | 417 int http_status_code, |
| 354 const GURL& image_url, | 418 const GURL& image_url, |
| 355 const std::vector<SkBitmap>& bitmaps, | 419 const std::vector<SkBitmap>& bitmaps, |
| 356 const std::vector<gfx::Size>& original_bitmap_sizes) { | 420 const std::vector<gfx::Size>& original_bitmap_sizes) { |
| 357 // Mark download as finished. | 421 // Mark download as finished. |
| 358 download_request_.Cancel(); | 422 image_download_request_.Cancel(); |
| 359 | 423 |
| 360 if (bitmaps.empty() && http_status_code == 404) { | 424 if (bitmaps.empty() && http_status_code == 404) { |
| 361 DVLOG(1) << "Failed to Download Favicon:" << image_url; | 425 DVLOG(1) << "Failed to Download Favicon:" << image_url; |
| 362 if (service_) | 426 if (service_) |
| 363 service_->UnableToDownloadFavicon(image_url); | 427 service_->UnableToDownloadFavicon(image_url); |
| 364 } | 428 } |
| 365 | 429 |
| 366 bool request_next_icon = true; | 430 bool request_next_icon = true; |
| 367 if (!bitmaps.empty()) { | 431 if (!bitmaps.empty()) { |
| 368 float score = 0.0f; | 432 float score = 0.0f; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 412 } | 476 } |
| 413 | 477 |
| 414 const std::vector<GURL> FaviconHandler::GetIconURLs() const { | 478 const std::vector<GURL> FaviconHandler::GetIconURLs() const { |
| 415 std::vector<GURL> icon_urls; | 479 std::vector<GURL> icon_urls; |
| 416 for (const FaviconCandidate& candidate : candidates_) | 480 for (const FaviconCandidate& candidate : candidates_) |
| 417 icon_urls.push_back(candidate.icon_url); | 481 icon_urls.push_back(candidate.icon_url); |
| 418 return icon_urls; | 482 return icon_urls; |
| 419 } | 483 } |
| 420 | 484 |
| 421 bool FaviconHandler::HasPendingTasksForTest() { | 485 bool FaviconHandler::HasPendingTasksForTest() { |
| 422 return !download_request_.IsCancelled() || | 486 return !manifest_download_request_.IsCancelled() || |
| 487 !image_download_request_.IsCancelled() || | |
| 423 cancelable_task_tracker_.HasTrackedTasks(); | 488 cancelable_task_tracker_.HasTrackedTasks(); |
| 424 } | 489 } |
| 425 | 490 |
| 426 bool FaviconHandler::ShouldSaveFavicon() { | 491 bool FaviconHandler::ShouldSaveFavicon() { |
| 427 if (!delegate_->IsOffTheRecord()) | 492 if (!delegate_->IsOffTheRecord()) |
| 428 return true; | 493 return true; |
| 429 | 494 |
| 430 // Always save favicon if the page is bookmarked. | 495 // Always save favicon if the page is bookmarked. |
| 431 return delegate_->IsBookmarked(url_); | 496 return delegate_->IsBookmarked(url_); |
| 432 } | 497 } |
| 433 | 498 |
| 434 void FaviconHandler::OnFaviconDataForInitialURLFromFaviconService( | 499 void FaviconHandler::OnFaviconDataForInitialURLFromFaviconService( |
| 435 const std::vector<favicon_base::FaviconRawBitmapResult>& | 500 const std::vector<favicon_base::FaviconRawBitmapResult>& |
| 436 favicon_bitmap_results) { | 501 favicon_bitmap_results) { |
| 437 got_favicon_from_history_ = true; | 502 got_favicon_from_history_ = true; |
| 438 bool has_valid_result = HasValidResult(favicon_bitmap_results); | 503 bool has_valid_result = FindValidResult(favicon_bitmap_results) != nullptr; |
| 439 initial_history_result_expired_or_incomplete_ = | 504 initial_history_result_expired_or_incomplete_ = |
| 440 !has_valid_result || | 505 !has_valid_result || |
| 441 HasExpiredOrIncompleteResult(preferred_icon_size(), | 506 HasExpiredOrIncompleteResult(preferred_icon_size(), |
| 442 favicon_bitmap_results); | 507 favicon_bitmap_results); |
| 443 redownload_icons_ = initial_history_result_expired_or_incomplete_ && | 508 redownload_icons_ = initial_history_result_expired_or_incomplete_ && |
| 444 !favicon_bitmap_results.empty(); | 509 !favicon_bitmap_results.empty(); |
| 445 | 510 |
| 446 if (has_valid_result && (!current_candidate() || | 511 if (has_valid_result && (!current_candidate() || |
| 447 DoUrlsAndIconsMatch(current_candidate()->icon_url, | 512 DoUrlsAndIconsMatch(current_candidate()->icon_url, |
| 448 current_candidate()->icon_type, | 513 current_candidate()->icon_type, |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 486 url_, {icon_url}, icon_type, preferred_icon_size(), | 551 url_, {icon_url}, icon_type, preferred_icon_size(), |
| 487 base::Bind(&FaviconHandler::OnFaviconData, base::Unretained(this)), | 552 base::Bind(&FaviconHandler::OnFaviconData, base::Unretained(this)), |
| 488 &cancelable_task_tracker_); | 553 &cancelable_task_tracker_); |
| 489 } | 554 } |
| 490 } | 555 } |
| 491 } | 556 } |
| 492 | 557 |
| 493 void FaviconHandler::OnFaviconData(const std::vector< | 558 void FaviconHandler::OnFaviconData(const std::vector< |
| 494 favicon_base::FaviconRawBitmapResult>& favicon_bitmap_results) { | 559 favicon_base::FaviconRawBitmapResult>& favicon_bitmap_results) { |
| 495 bool has_results = !favicon_bitmap_results.empty(); | 560 bool has_results = !favicon_bitmap_results.empty(); |
| 496 bool has_valid_result = HasValidResult(favicon_bitmap_results); | 561 const favicon_base::FaviconRawBitmapResult* valid_result = |
| 562 FindValidResult(favicon_bitmap_results); | |
| 497 bool has_expired_or_incomplete_result = | 563 bool has_expired_or_incomplete_result = |
| 498 !has_valid_result || HasExpiredOrIncompleteResult(preferred_icon_size(), | 564 !valid_result || HasExpiredOrIncompleteResult(preferred_icon_size(), |
| 499 favicon_bitmap_results); | 565 favicon_bitmap_results); |
| 500 | 566 |
| 501 if (has_valid_result) { | 567 if (valid_result) { |
| 502 // There is a valid favicon. Notify any observers. It is useful to notify | 568 // There is a valid favicon. Notify any observers. It is useful to notify |
| 503 // the observers even if the favicon is expired or incomplete (incorrect | 569 // the observers even if the favicon is expired or incomplete (incorrect |
| 504 // size) because temporarily showing the user an expired favicon or | 570 // size) because temporarily showing the user an expired favicon or |
| 505 // streched favicon is preferable to showing the user the default favicon. | 571 // streched favicon is preferable to showing the user the default favicon. |
| 506 NotifyFaviconUpdated(favicon_bitmap_results); | 572 NotifyFaviconUpdated(favicon_bitmap_results); |
| 573 // If a manifest is being used, let's also store the association using the | |
| 574 // manifest's URL as page URL. | |
| 575 if (manifest_url_ && service_ && ShouldSaveFavicon()) { | |
| 576 service_->MergeFavicon(*manifest_url_, {valid_result->icon_url}, | |
| 577 valid_result->icon_type, valid_result->bitmap_data, | |
| 578 valid_result->pixel_size); | |
| 579 } | |
| 507 } | 580 } |
| 508 | 581 |
| 509 if (!current_candidate() || | 582 if (!current_candidate() || |
| 510 (has_results && !DoUrlsAndIconsMatch(current_candidate()->icon_url, | 583 (has_results && !DoUrlsAndIconsMatch(current_candidate()->icon_url, |
| 511 current_candidate()->icon_type, | 584 current_candidate()->icon_type, |
| 512 favicon_bitmap_results))) { | 585 favicon_bitmap_results))) { |
| 513 // The icon URLs have been updated since the favicon data was requested. | 586 // The icon URLs have been updated since the favicon data was requested. |
| 514 return; | 587 return; |
| 515 } | 588 } |
| 516 | 589 |
| 517 if (has_expired_or_incomplete_result) { | 590 if (has_expired_or_incomplete_result) { |
| 518 ScheduleDownload(current_candidate()->icon_url, | 591 ScheduleDownload(current_candidate()->icon_url, |
| 519 current_candidate()->icon_type); | 592 current_candidate()->icon_type); |
| 520 } | 593 } |
| 521 } | 594 } |
| 522 | 595 |
| 523 void FaviconHandler::ScheduleDownload(const GURL& image_url, | 596 void FaviconHandler::ScheduleDownload(const GURL& image_url, |
| 524 favicon_base::IconType icon_type) { | 597 favicon_base::IconType icon_type) { |
| 525 DCHECK(image_url.is_valid()); | 598 DCHECK(image_url.is_valid()); |
| 526 // Note that CancelableCallback starts cancelled. | 599 // Note that CancelableCallback starts cancelled. |
| 527 DCHECK(download_request_.IsCancelled()) << "More than one ongoing download"; | 600 DCHECK(image_download_request_.IsCancelled()) |
| 601 << "More than one ongoing download"; | |
| 528 if (service_ && service_->WasUnableToDownloadFavicon(image_url)) { | 602 if (service_ && service_->WasUnableToDownloadFavicon(image_url)) { |
| 529 DVLOG(1) << "Skip Failed FavIcon: " << image_url; | 603 DVLOG(1) << "Skip Failed FavIcon: " << image_url; |
| 530 OnDidDownloadFavicon(icon_type, 0, 0, image_url, std::vector<SkBitmap>(), | 604 OnDidDownloadFavicon(icon_type, 0, 0, image_url, std::vector<SkBitmap>(), |
| 531 std::vector<gfx::Size>()); | 605 std::vector<gfx::Size>()); |
| 532 return; | 606 return; |
| 533 } | 607 } |
| 534 download_request_.Reset(base::Bind(&FaviconHandler::OnDidDownloadFavicon, | 608 image_download_request_.Reset( |
| 535 base::Unretained(this), icon_type)); | 609 base::Bind(&FaviconHandler::OnDidDownloadFavicon, base::Unretained(this), |
| 610 icon_type)); | |
| 536 // A max bitmap size is specified to avoid receiving huge bitmaps in | 611 // A max bitmap size is specified to avoid receiving huge bitmaps in |
| 537 // OnDidDownloadFavicon(). See FaviconDriver::StartDownload() | 612 // OnDidDownloadFavicon(). See FaviconDriver::StartDownload() |
| 538 // for more details about the max bitmap size. | 613 // for more details about the max bitmap size. |
| 539 const int download_id = | 614 const int download_id = |
| 540 delegate_->DownloadImage(image_url, GetMaximalIconSize(handler_type_), | 615 delegate_->DownloadImage(image_url, GetMaximalIconSize(handler_type_), |
| 541 download_request_.callback()); | 616 image_download_request_.callback()); |
| 542 DCHECK_NE(download_id, 0); | 617 DCHECK_NE(download_id, 0); |
| 543 } | 618 } |
| 544 | 619 |
| 545 } // namespace favicon | 620 } // namespace favicon |
| OLD | NEW |