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 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 188 } | 188 } |
| 189 | 189 |
| 190 void FaviconHandler::FetchFavicon(const GURL& url) { | 190 void FaviconHandler::FetchFavicon(const GURL& url) { |
| 191 cancelable_task_tracker_.TryCancelAll(); | 191 cancelable_task_tracker_.TryCancelAll(); |
| 192 | 192 |
| 193 url_ = url; | 193 url_ = url; |
| 194 | 194 |
| 195 initial_history_result_expired_or_incomplete_ = false; | 195 initial_history_result_expired_or_incomplete_ = false; |
| 196 redownload_icons_ = false; | 196 redownload_icons_ = false; |
| 197 got_favicon_from_history_ = false; | 197 got_favicon_from_history_ = false; |
| 198 download_request_.Cancel(); | 198 manifest_download_request_.Cancel(); |
| 199 image_download_request_.Cancel(); | |
| 200 manifest_url_.reset(); | |
| 199 candidates_.clear(); | 201 candidates_.clear(); |
| 200 notification_icon_url_ = GURL(); | 202 notification_icon_url_ = GURL(); |
| 201 notification_icon_type_ = favicon_base::INVALID_ICON; | 203 notification_icon_type_ = favicon_base::INVALID_ICON; |
| 202 current_candidate_index_ = 0u; | 204 current_candidate_index_ = 0u; |
| 203 best_favicon_ = DownloadedFavicon(); | 205 best_favicon_ = DownloadedFavicon(); |
| 204 | 206 |
| 205 // Request the favicon from the history service. In parallel to this the | 207 // 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 | 208 // renderer is going to notify us (well WebContents) when the favicon url is |
| 207 // available. | 209 // available. |
| 208 if (service_) { | 210 if (service_) { |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 237 best_favicon_.candidate.score; | 239 best_favicon_.candidate.score; |
| 238 } else { | 240 } else { |
| 239 return best_favicon_.candidate.score == 1; | 241 return best_favicon_.candidate.score == 1; |
| 240 } | 242 } |
| 241 } | 243 } |
| 242 | 244 |
| 243 void FaviconHandler::SetFavicon(const GURL& icon_url, | 245 void FaviconHandler::SetFavicon(const GURL& icon_url, |
| 244 const gfx::Image& image, | 246 const gfx::Image& image, |
| 245 favicon_base::IconType icon_type) { | 247 favicon_base::IconType icon_type) { |
| 246 if (service_ && ShouldSaveFavicon()) | 248 if (service_ && ShouldSaveFavicon()) |
| 247 service_->SetFavicons(url_, icon_url, icon_type, image); | 249 service_->SetFavicons(url_, manifest_url_.value_or(icon_url), icon_type, |
| 250 image); | |
| 248 | 251 |
| 249 NotifyFaviconUpdated(icon_url, icon_type, image); | 252 NotifyFaviconUpdated(icon_url, icon_type, image); |
| 250 } | 253 } |
| 251 | 254 |
| 252 void FaviconHandler::NotifyFaviconUpdated( | 255 void FaviconHandler::NotifyFaviconUpdated( |
| 253 const std::vector<favicon_base::FaviconRawBitmapResult>& | 256 const std::vector<favicon_base::FaviconRawBitmapResult>& |
| 254 favicon_bitmap_results) { | 257 favicon_bitmap_results) { |
| 255 if (favicon_bitmap_results.empty()) | 258 if (favicon_bitmap_results.empty()) |
| 256 return; | 259 return; |
| 257 | 260 |
| 258 gfx::Image resized_image = favicon_base::SelectFaviconFramesFromPNGs( | 261 gfx::Image resized_image = favicon_base::SelectFaviconFramesFromPNGs( |
| 259 favicon_bitmap_results, | 262 favicon_bitmap_results, |
| 260 favicon_base::GetFaviconScales(), | 263 favicon_base::GetFaviconScales(), |
| 261 preferred_icon_size()); | 264 preferred_icon_size()); |
| 262 // The history service sends back results for a single icon URL and icon | 265 // The history service sends back results for a single icon URL and icon |
| 263 // type, so it does not matter which result we get |icon_url| and |icon_type| | 266 // type, so it does not matter which result we get |icon_url| and |icon_type| |
| 264 // from. | 267 // from. |
| 265 const GURL icon_url = favicon_bitmap_results[0].icon_url; | 268 const GURL icon_url = favicon_bitmap_results[0].icon_url; |
| 266 favicon_base::IconType icon_type = favicon_bitmap_results[0].icon_type; | 269 favicon_base::IconType icon_type = favicon_bitmap_results[0].icon_type; |
| 267 NotifyFaviconUpdated(icon_url, icon_type, resized_image); | 270 NotifyFaviconUpdated(icon_url, icon_type, resized_image); |
| 268 } | 271 } |
| 269 | 272 |
| 270 void FaviconHandler::NotifyFaviconUpdated(const GURL& icon_url, | 273 void FaviconHandler::NotifyFaviconUpdated(const GURL& icon_url, |
| 271 favicon_base::IconType icon_type, | 274 favicon_base::IconType icon_type, |
| 272 const gfx::Image& image) { | 275 const gfx::Image& image) { |
| 273 if (image.IsEmpty()) | 276 if (image.IsEmpty()) |
| 274 return; | 277 return; |
| 275 | 278 |
| 279 // If a manifest is being processed, it's URL overrides the icon URL. | |
| 280 const GURL& notification_icon_url = manifest_url_.value_or(icon_url); | |
| 281 | |
| 276 gfx::Image image_with_adjusted_colorspace = image; | 282 gfx::Image image_with_adjusted_colorspace = image; |
| 277 favicon_base::SetFaviconColorSpace(&image_with_adjusted_colorspace); | 283 favicon_base::SetFaviconColorSpace(&image_with_adjusted_colorspace); |
| 278 | 284 |
| 279 delegate_->OnFaviconUpdated(url_, handler_type_, icon_url, | 285 delegate_->OnFaviconUpdated(url_, handler_type_, notification_icon_url, |
| 280 icon_url != notification_icon_url_, | 286 notification_icon_url != notification_icon_url_, |
| 281 image_with_adjusted_colorspace); | 287 image_with_adjusted_colorspace); |
| 282 | 288 |
| 283 notification_icon_url_ = icon_url; | 289 notification_icon_url_ = notification_icon_url; |
| 284 notification_icon_type_ = icon_type; | 290 notification_icon_type_ = icon_type; |
| 285 } | 291 } |
| 286 | 292 |
| 287 void FaviconHandler::OnUpdateFaviconURL( | 293 void FaviconHandler::OnUpdateCandidates( |
| 288 const GURL& page_url, | 294 const GURL& page_url, |
| 289 const std::vector<FaviconURL>& candidates) { | 295 const std::vector<FaviconURL>& candidates, |
| 296 const base::Optional<GURL>& manifest_url) { | |
| 297 DCHECK_EQ(page_url, url_); | |
| 290 if (page_url != url_) | 298 if (page_url != url_) |
| 291 return; | 299 return; |
| 292 | 300 |
| 301 // TODO/DONOTSUBMIT(mastiz): Not sure if this is reachable at all: perhaps | |
| 302 // manifest URL can be specified via Javascript? | |
|
pkotwicz
2017/04/11 03:47:07
Yes, the manifest URL can be changed via JavaScrip
mastiz
2017/04/11 13:31:01
Ack, thanks. Added a new test.
| |
| 303 if (manifest_url_ && manifest_url_ == manifest_url) | |
| 304 return; | |
| 305 | |
| 306 manifest_url_ = manifest_url; | |
| 307 | |
| 308 // If no manifest available, proceed with the regular candidates only. | |
| 309 if (!manifest_url.has_value()) { | |
| 310 OnGotFinalIconURLCandidates(candidates); | |
| 311 return; | |
| 312 } | |
| 313 | |
| 314 if (redownload_icons_) { | |
|
pkotwicz
2017/04/11 03:47:07
Do we need to wait till OnFaviconDataForInitialURL
mastiz
2017/04/11 13:31:01
redownload_icons_ can only be true only after OnFa
pkotwicz
2017/04/12 22:10:06
I'd recommend getting rid of this if() statement a
mastiz
2017/04/20 18:06:33
Done.
| |
| 315 ScheduleManifestDownload(); | |
| 316 } else { | |
| 317 // See if there is a cached favicon for the manifest. | |
| 318 GetFaviconAndUpdateMappingsUnlessIncognito( | |
| 319 /*icon_url=*/*manifest_url, favicon_base::FAVICON, | |
| 320 base::Bind(&FaviconHandler::OnFaviconDataForManifestFromFaviconService, | |
| 321 base::Unretained(this))); | |
| 322 } | |
| 323 } | |
| 324 | |
| 325 void FaviconHandler::OnFaviconDataForManifestFromFaviconService( | |
| 326 const std::vector<favicon_base::FaviconRawBitmapResult>& | |
| 327 favicon_bitmap_results) { | |
| 328 bool has_valid_result = HasValidResult(favicon_bitmap_results); | |
| 329 bool has_expired_or_incomplete_result = | |
| 330 !has_valid_result || HasExpiredOrIncompleteResult(preferred_icon_size(), | |
| 331 favicon_bitmap_results); | |
| 332 | |
| 333 if (has_valid_result) { | |
| 334 // There is a valid favicon. Notify any observers. It is useful to notify | |
| 335 // the observers even if the favicon is expired or incomplete (incorrect | |
| 336 // size) because temporarily showing the user an expired favicon or | |
| 337 // streched favicon is preferable to showing the user the default favicon. | |
| 338 NotifyFaviconUpdated(favicon_bitmap_results); | |
| 339 } | |
| 340 | |
| 341 if (has_expired_or_incomplete_result) | |
| 342 ScheduleManifestDownload(); | |
| 343 } | |
| 344 | |
| 345 void FaviconHandler::ScheduleManifestDownload() { | |
| 346 manifest_download_request_.Reset(base::Bind( | |
| 347 &FaviconHandler::OnGotFinalIconURLCandidates, base::Unretained(this))); | |
| 348 // If we download a manifest, make need to bypass the lookups in the favicon | |
| 349 // cache because the manifest's URL is used as icon URL anyway. | |
| 350 redownload_icons_ = true; | |
| 351 delegate_->DownloadManifest(*manifest_url_, | |
| 352 manifest_download_request_.callback()); | |
|
pkotwicz
2017/04/11 03:47:07
We need to take into account that the Web Manifest
mastiz
2017/04/11 13:31:01
Done, implemented one proposal for this.
Unless y
pkotwicz
2017/04/12 22:10:06
This is OK for now
| |
| 353 } | |
| 354 | |
| 355 void FaviconHandler::OnGotFinalIconURLCandidates( | |
| 356 const std::vector<FaviconURL>& candidates) { | |
| 357 // Mark manifest download as finished, if there was one. | |
| 358 manifest_download_request_.Cancel(); | |
| 359 | |
| 293 std::vector<FaviconCandidate> sorted_candidates; | 360 std::vector<FaviconCandidate> sorted_candidates; |
| 294 const std::vector<int> desired_pixel_sizes = | 361 const std::vector<int> desired_pixel_sizes = |
| 295 GetDesiredPixelSizes(handler_type_); | 362 GetDesiredPixelSizes(handler_type_); |
| 296 for (const FaviconURL& candidate : candidates) { | 363 for (const FaviconURL& candidate : candidates) { |
| 297 if (!candidate.icon_url.is_empty() && (candidate.icon_type & icon_types_)) { | 364 if (!candidate.icon_url.is_empty() && (candidate.icon_type & icon_types_)) { |
| 298 sorted_candidates.push_back( | 365 sorted_candidates.push_back( |
| 299 FaviconCandidate::FromFaviconURL(candidate, desired_pixel_sizes)); | 366 FaviconCandidate::FromFaviconURL(candidate, desired_pixel_sizes)); |
| 300 } | 367 } |
| 301 } | 368 } |
| 302 | 369 |
| 303 std::stable_sort(sorted_candidates.begin(), sorted_candidates.end(), | 370 std::stable_sort(sorted_candidates.begin(), sorted_candidates.end(), |
| 304 &FaviconCandidate::CompareScore); | 371 &FaviconCandidate::CompareScore); |
| 305 | 372 |
| 306 if (candidates_.size() == sorted_candidates.size() && | 373 if (candidates_.size() == sorted_candidates.size() && |
| 307 std::equal(sorted_candidates.begin(), sorted_candidates.end(), | 374 std::equal(sorted_candidates.begin(), sorted_candidates.end(), |
| 308 candidates_.begin())) { | 375 candidates_.begin())) { |
| 309 return; | 376 return; |
| 310 } | 377 } |
| 311 | 378 |
| 312 download_request_.Cancel(); | 379 image_download_request_.Cancel(); |
| 313 candidates_ = std::move(sorted_candidates); | 380 candidates_ = std::move(sorted_candidates); |
| 314 current_candidate_index_ = 0u; | 381 current_candidate_index_ = 0u; |
| 315 best_favicon_ = DownloadedFavicon(); | 382 best_favicon_ = DownloadedFavicon(); |
| 316 | 383 |
| 317 // TODO(davemoore) Should clear on empty url. Currently we ignore it. | 384 // TODO(davemoore) Should clear on empty url. Currently we ignore it. |
| 318 // This appears to be what FF does as well. | 385 // This appears to be what FF does as well. |
| 319 if (current_candidate() && got_favicon_from_history_) | 386 if (current_candidate() && got_favicon_from_history_) |
| 320 OnGotInitialHistoryDataAndIconURLCandidates(); | 387 OnGotInitialHistoryDataAndIconURLCandidates(); |
| 321 } | 388 } |
| 322 | 389 |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 348 } | 415 } |
| 349 | 416 |
| 350 void FaviconHandler::OnDidDownloadFavicon( | 417 void FaviconHandler::OnDidDownloadFavicon( |
| 351 favicon_base::IconType icon_type, | 418 favicon_base::IconType icon_type, |
| 352 int id, | 419 int id, |
| 353 int http_status_code, | 420 int http_status_code, |
| 354 const GURL& image_url, | 421 const GURL& image_url, |
| 355 const std::vector<SkBitmap>& bitmaps, | 422 const std::vector<SkBitmap>& bitmaps, |
| 356 const std::vector<gfx::Size>& original_bitmap_sizes) { | 423 const std::vector<gfx::Size>& original_bitmap_sizes) { |
| 357 // Mark download as finished. | 424 // Mark download as finished. |
| 358 download_request_.Cancel(); | 425 image_download_request_.Cancel(); |
| 359 | 426 |
| 360 if (bitmaps.empty() && http_status_code == 404) { | 427 if (bitmaps.empty() && http_status_code == 404) { |
| 361 DVLOG(1) << "Failed to Download Favicon:" << image_url; | 428 DVLOG(1) << "Failed to Download Favicon:" << image_url; |
| 362 if (service_) | 429 if (service_) |
| 363 service_->UnableToDownloadFavicon(image_url); | 430 service_->UnableToDownloadFavicon(image_url); |
| 364 } | 431 } |
| 365 | 432 |
| 366 bool request_next_icon = true; | 433 bool request_next_icon = true; |
| 367 if (!bitmaps.empty()) { | 434 if (!bitmaps.empty()) { |
| 368 float score = 0.0f; | 435 float score = 0.0f; |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 396 | 463 |
| 397 if (request_next_icon && current_candidate_index_ + 1 < candidates_.size()) { | 464 if (request_next_icon && current_candidate_index_ + 1 < candidates_.size()) { |
| 398 // Process the next candidate. | 465 // Process the next candidate. |
| 399 ++current_candidate_index_; | 466 ++current_candidate_index_; |
| 400 DownloadCurrentCandidateOrAskFaviconService(); | 467 DownloadCurrentCandidateOrAskFaviconService(); |
| 401 } else { | 468 } else { |
| 402 // We have either found the ideal candidate or run out of candidates. | 469 // We have either found the ideal candidate or run out of candidates. |
| 403 if (best_favicon_.candidate.icon_type != favicon_base::INVALID_ICON) { | 470 if (best_favicon_.candidate.icon_type != favicon_base::INVALID_ICON) { |
| 404 // No more icons to request, set the favicon from the candidate. | 471 // No more icons to request, set the favicon from the candidate. |
| 405 SetFavicon(best_favicon_.candidate.icon_url, best_favicon_.image, | 472 SetFavicon(best_favicon_.candidate.icon_url, best_favicon_.image, |
| 406 best_favicon_.candidate.icon_type); | 473 best_favicon_.candidate.icon_type); |
|
pkotwicz
2017/04/11 03:47:07
If the |icon_url| is from the Web Manifest, we hav
mastiz
2017/04/11 13:31:01
This is implemented inside SetFavicon and NotifyFa
pkotwicz
2017/04/12 22:10:06
I think that it is clearer if you pass the correct
mastiz
2017/04/20 18:06:33
Done.
pkotwicz
2017/04/24 14:42:14
It looks like there is still the manifest_url_.val
mastiz
2017/04/27 13:54:50
There's at least one codepath (via OnFaviconDataFo
pkotwicz
2017/05/01 04:56:53
When NotifyFaviconUpdated() is called as a result
mastiz
2017/05/04 10:57:53
You're right, thanks. Done.
| |
| 407 } | 474 } |
| 408 // Clear download related state. | 475 // Clear download related state. |
| 409 current_candidate_index_ = candidates_.size(); | 476 current_candidate_index_ = candidates_.size(); |
| 410 best_favicon_ = DownloadedFavicon(); | 477 best_favicon_ = DownloadedFavicon(); |
| 411 } | 478 } |
| 412 } | 479 } |
| 413 | 480 |
| 414 const std::vector<GURL> FaviconHandler::GetIconURLs() const { | 481 const std::vector<GURL> FaviconHandler::GetIconURLs() const { |
| 415 std::vector<GURL> icon_urls; | 482 std::vector<GURL> icon_urls; |
| 416 for (const FaviconCandidate& candidate : candidates_) | 483 for (const FaviconCandidate& candidate : candidates_) |
| 417 icon_urls.push_back(candidate.icon_url); | 484 icon_urls.push_back(candidate.icon_url); |
| 418 return icon_urls; | 485 return icon_urls; |
| 419 } | 486 } |
| 420 | 487 |
| 421 bool FaviconHandler::HasPendingTasksForTest() { | 488 bool FaviconHandler::HasPendingTasksForTest() { |
| 422 return !download_request_.IsCancelled() || | 489 return !manifest_download_request_.IsCancelled() || |
| 490 !image_download_request_.IsCancelled() || | |
| 423 cancelable_task_tracker_.HasTrackedTasks(); | 491 cancelable_task_tracker_.HasTrackedTasks(); |
| 424 } | 492 } |
| 425 | 493 |
| 426 bool FaviconHandler::ShouldSaveFavicon() { | 494 bool FaviconHandler::ShouldSaveFavicon() { |
| 427 if (!delegate_->IsOffTheRecord()) | 495 if (!delegate_->IsOffTheRecord()) |
| 428 return true; | 496 return true; |
| 429 | 497 |
| 430 // Always save favicon if the page is bookmarked. | 498 // Always save favicon if the page is bookmarked. |
| 431 return delegate_->IsBookmarked(url_); | 499 return delegate_->IsBookmarked(url_); |
| 432 } | 500 } |
| 433 | 501 |
| 434 void FaviconHandler::OnFaviconDataForInitialURLFromFaviconService( | 502 void FaviconHandler::OnFaviconDataForInitialURLFromFaviconService( |
| 435 const std::vector<favicon_base::FaviconRawBitmapResult>& | 503 const std::vector<favicon_base::FaviconRawBitmapResult>& |
| 436 favicon_bitmap_results) { | 504 favicon_bitmap_results) { |
| 437 got_favicon_from_history_ = true; | 505 got_favicon_from_history_ = true; |
| 438 bool has_valid_result = HasValidResult(favicon_bitmap_results); | 506 bool has_valid_result = HasValidResult(favicon_bitmap_results); |
| 439 initial_history_result_expired_or_incomplete_ = | 507 initial_history_result_expired_or_incomplete_ = |
| 440 !has_valid_result || | 508 !has_valid_result || |
| 441 HasExpiredOrIncompleteResult(preferred_icon_size(), | 509 HasExpiredOrIncompleteResult(preferred_icon_size(), |
| 442 favicon_bitmap_results); | 510 favicon_bitmap_results); |
| 443 redownload_icons_ = initial_history_result_expired_or_incomplete_ && | 511 redownload_icons_ = initial_history_result_expired_or_incomplete_ && |
| 444 !favicon_bitmap_results.empty(); | 512 !favicon_bitmap_results.empty(); |
| 445 | 513 |
| 446 if (has_valid_result && (!current_candidate() || | 514 if (has_valid_result && (!current_candidate() || |
| 447 DoUrlsAndIconsMatch(current_candidate()->icon_url, | 515 DoUrlsAndIconsMatch(current_candidate()->icon_url, |
| 448 current_candidate()->icon_type, | 516 current_candidate()->icon_type, |
| 449 favicon_bitmap_results))) { | 517 favicon_bitmap_results))) { |
|
pkotwicz
2017/04/11 03:47:07
We should trigger this if() statement if the "data
mastiz
2017/04/11 13:31:01
This situation would cause current_candidate() ==
| |
| 450 // The db knows the favicon (although it may be out of date) and the entry | 518 // The db knows the favicon (although it may be out of date) and the entry |
| 451 // doesn't have an icon. Set the favicon now, and if the favicon turns out | 519 // doesn't have an icon. Set the favicon now, and if the favicon turns out |
| 452 // to be expired (or the wrong url) we'll fetch later on. This way the | 520 // to be expired (or the wrong url) we'll fetch later on. This way the |
| 453 // user doesn't see a flash of the default favicon. | 521 // user doesn't see a flash of the default favicon. |
| 454 NotifyFaviconUpdated(favicon_bitmap_results); | 522 NotifyFaviconUpdated(favicon_bitmap_results); |
| 455 } | 523 } |
| 456 | 524 |
| 457 if (current_candidate()) | 525 if (current_candidate()) |
| 458 OnGotInitialHistoryDataAndIconURLCandidates(); | 526 OnGotInitialHistoryDataAndIconURLCandidates(); |
| 459 } | 527 } |
| 460 | 528 |
| 461 void FaviconHandler::DownloadCurrentCandidateOrAskFaviconService() { | 529 void FaviconHandler::DownloadCurrentCandidateOrAskFaviconService() { |
| 462 GURL icon_url = current_candidate()->icon_url; | 530 const GURL icon_url = current_candidate()->icon_url; |
| 463 favicon_base::IconType icon_type = current_candidate()->icon_type; | 531 const favicon_base::IconType icon_type = current_candidate()->icon_type; |
| 464 | |
| 465 if (redownload_icons_) { | 532 if (redownload_icons_) { |
| 466 // We have the mapping, but the favicon is out of date. Download it now. | 533 // We have the mapping, but the favicon is out of date. Download it now. |
| 467 ScheduleDownload(icon_url, icon_type); | 534 ScheduleFaviconDownload(icon_url, icon_type); |
| 468 } else if (service_) { | 535 } else { |
| 469 // We don't know the favicon, but we may have previously downloaded the | 536 GetFaviconAndUpdateMappingsUnlessIncognito( |
| 470 // favicon for another page that shares the same favicon. Ask for the | 537 icon_url, icon_type, |
| 471 // favicon given the favicon URL. | 538 base::Bind(&FaviconHandler::OnFaviconData, base::Unretained(this))); |
| 472 if (delegate_->IsOffTheRecord()) { | |
| 473 service_->GetFavicon( | |
| 474 icon_url, icon_type, preferred_icon_size(), | |
| 475 base::Bind(&FaviconHandler::OnFaviconData, base::Unretained(this)), | |
| 476 &cancelable_task_tracker_); | |
| 477 } else { | |
| 478 // Ask the history service for the icon. This does two things: | |
| 479 // 1. Attempts to fetch the favicon data from the database. | |
| 480 // 2. If the favicon exists in the database, this updates the database to | |
| 481 // include the mapping between the page url and the favicon url. | |
| 482 // This is asynchronous. The history service will call back when done. | |
| 483 // TODO(pkotwicz): pass in all of |image_urls_| to | |
| 484 // UpdateFaviconMappingsAndFetch(). | |
| 485 service_->UpdateFaviconMappingsAndFetch( | |
| 486 url_, {icon_url}, icon_type, preferred_icon_size(), | |
| 487 base::Bind(&FaviconHandler::OnFaviconData, base::Unretained(this)), | |
| 488 &cancelable_task_tracker_); | |
| 489 } | |
| 490 } | 539 } |
| 491 } | 540 } |
| 492 | 541 |
| 542 void FaviconHandler::GetFaviconAndUpdateMappingsUnlessIncognito( | |
| 543 const GURL& icon_url, | |
| 544 favicon_base::IconType icon_type, | |
| 545 const favicon_base::FaviconResultsCallback& callback) { | |
| 546 if (!service_) | |
| 547 return; | |
| 548 | |
| 549 // We don't know the favicon, but we may have previously downloaded the | |
| 550 // favicon for another page that shares the same favicon. Ask for the | |
| 551 // favicon given the favicon URL. | |
| 552 if (delegate_->IsOffTheRecord()) { | |
| 553 service_->GetFavicon(icon_url, icon_type, preferred_icon_size(), callback, | |
| 554 &cancelable_task_tracker_); | |
| 555 } else { | |
| 556 // Ask the history service for the icon. This does two things: | |
| 557 // 1. Attempts to fetch the favicon data from the database. | |
| 558 // 2. If the favicon exists in the database, this updates the database to | |
| 559 // include the mapping between the page url and the favicon url. | |
| 560 // This is asynchronous. The history service will call back when done. | |
| 561 // TODO(pkotwicz): pass in all of |image_urls_| to | |
| 562 // UpdateFaviconMappingsAndFetch(). | |
| 563 service_->UpdateFaviconMappingsAndFetch(url_, {icon_url}, icon_type, | |
| 564 preferred_icon_size(), callback, | |
| 565 &cancelable_task_tracker_); | |
| 566 } | |
| 567 } | |
| 568 | |
| 493 void FaviconHandler::OnFaviconData(const std::vector< | 569 void FaviconHandler::OnFaviconData(const std::vector< |
| 494 favicon_base::FaviconRawBitmapResult>& favicon_bitmap_results) { | 570 favicon_base::FaviconRawBitmapResult>& favicon_bitmap_results) { |
| 495 bool has_results = !favicon_bitmap_results.empty(); | 571 bool has_results = !favicon_bitmap_results.empty(); |
| 496 bool has_valid_result = HasValidResult(favicon_bitmap_results); | 572 bool has_valid_result = HasValidResult(favicon_bitmap_results); |
| 497 bool has_expired_or_incomplete_result = | 573 bool has_expired_or_incomplete_result = |
| 498 !has_valid_result || HasExpiredOrIncompleteResult(preferred_icon_size(), | 574 !has_valid_result || HasExpiredOrIncompleteResult(preferred_icon_size(), |
| 499 favicon_bitmap_results); | 575 favicon_bitmap_results); |
| 500 | 576 |
| 501 if (has_valid_result) { | 577 if (has_valid_result) { |
| 502 // There is a valid favicon. Notify any observers. It is useful to notify | 578 // 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 | 579 // the observers even if the favicon is expired or incomplete (incorrect |
| 504 // size) because temporarily showing the user an expired favicon or | 580 // size) because temporarily showing the user an expired favicon or |
| 505 // streched favicon is preferable to showing the user the default favicon. | 581 // streched favicon is preferable to showing the user the default favicon. |
| 506 NotifyFaviconUpdated(favicon_bitmap_results); | 582 NotifyFaviconUpdated(favicon_bitmap_results); |
| 507 } | 583 } |
| 508 | 584 |
| 509 if (!current_candidate() || | 585 if (!current_candidate() || |
| 510 (has_results && !DoUrlsAndIconsMatch(current_candidate()->icon_url, | 586 (has_results && !DoUrlsAndIconsMatch(current_candidate()->icon_url, |
| 511 current_candidate()->icon_type, | 587 current_candidate()->icon_type, |
| 512 favicon_bitmap_results))) { | 588 favicon_bitmap_results))) { |
| 513 // The icon URLs have been updated since the favicon data was requested. | 589 // The icon URLs have been updated since the favicon data was requested. |
| 590 NOTREACHED(); // DONOTSUBMIT | |
| 514 return; | 591 return; |
| 515 } | 592 } |
| 516 | 593 |
| 517 if (has_expired_or_incomplete_result) { | 594 if (has_expired_or_incomplete_result) { |
| 518 ScheduleDownload(current_candidate()->icon_url, | 595 ScheduleFaviconDownload(current_candidate()->icon_url, |
| 519 current_candidate()->icon_type); | 596 current_candidate()->icon_type); |
| 520 } | 597 } |
| 521 } | 598 } |
| 522 | 599 |
| 523 void FaviconHandler::ScheduleDownload(const GURL& image_url, | 600 void FaviconHandler::ScheduleFaviconDownload(const GURL& image_url, |
| 524 favicon_base::IconType icon_type) { | 601 favicon_base::IconType icon_type) { |
| 525 DCHECK(image_url.is_valid()); | 602 DCHECK(image_url.is_valid()); |
| 526 // Note that CancelableCallback starts cancelled. | 603 // Note that CancelableCallback starts cancelled. |
| 527 DCHECK(download_request_.IsCancelled()) << "More than one ongoing download"; | 604 DCHECK(image_download_request_.IsCancelled()) |
| 605 << "More than one ongoing download"; | |
| 528 if (service_ && service_->WasUnableToDownloadFavicon(image_url)) { | 606 if (service_ && service_->WasUnableToDownloadFavicon(image_url)) { |
| 529 DVLOG(1) << "Skip Failed FavIcon: " << image_url; | 607 DVLOG(1) << "Skip Failed FavIcon: " << image_url; |
| 530 OnDidDownloadFavicon(icon_type, 0, 0, image_url, std::vector<SkBitmap>(), | 608 OnDidDownloadFavicon(icon_type, 0, 0, image_url, std::vector<SkBitmap>(), |
| 531 std::vector<gfx::Size>()); | 609 std::vector<gfx::Size>()); |
| 532 return; | 610 return; |
| 533 } | 611 } |
| 534 download_request_.Reset(base::Bind(&FaviconHandler::OnDidDownloadFavicon, | 612 image_download_request_.Reset( |
| 535 base::Unretained(this), icon_type)); | 613 base::Bind(&FaviconHandler::OnDidDownloadFavicon, base::Unretained(this), |
| 614 icon_type)); | |
| 536 // A max bitmap size is specified to avoid receiving huge bitmaps in | 615 // A max bitmap size is specified to avoid receiving huge bitmaps in |
| 537 // OnDidDownloadFavicon(). See FaviconDriver::StartDownload() | 616 // OnDidDownloadFavicon(). See FaviconDriver::StartDownload() |
| 538 // for more details about the max bitmap size. | 617 // for more details about the max bitmap size. |
| 539 const int download_id = | 618 const int download_id = |
| 540 delegate_->DownloadImage(image_url, GetMaximalIconSize(handler_type_), | 619 delegate_->DownloadImage(image_url, GetMaximalIconSize(handler_type_), |
| 541 download_request_.callback()); | 620 image_download_request_.callback()); |
| 542 DCHECK_NE(download_id, 0); | 621 DCHECK_NE(download_id, 0); |
| 543 } | 622 } |
| 544 | 623 |
| 545 } // namespace favicon | 624 } // namespace favicon |
| OLD | NEW |