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 |
|
pkotwicz
2017/04/12 22:10:06
Shouldn't the TOUCH_LARGEST FaviconHandler complet
mastiz
2017/04/20 18:06:33
This happens in upper layers: the manifest URL is
pkotwicz
2017/04/24 14:42:14
I see. This is done in FaviconDriverImpl
| |
| 301 // |candidates| or |manifest_url| could have been modified via Javascript. | |
| 302 if (manifest_url_ && manifest_url_ == manifest_url) | |
| 303 return; | |
| 304 | |
| 305 manifest_url_ = manifest_url; | |
| 306 non_manifest_original_candidates_ = candidates; | |
| 307 | |
| 308 // Check if the manifest previously returned a 404 (or a 200 but contained no | |
| 309 // icons), and ignore the manifest URL if that's the case. | |
| 310 if (manifest_url_ && service_ && | |
| 311 service_->WasUnableToDownloadFavicon(*manifest_url_)) { | |
| 312 DVLOG(1) << "Skip failed Manifest: " << *manifest_url_; | |
| 313 manifest_url_.reset(); | |
| 314 } | |
| 315 | |
| 316 // If no manifest available, proceed with the regular candidates only. | |
| 317 if (!manifest_url_) { | |
| 318 OnGotFinalIconURLCandidates(candidates); | |
| 319 return; | |
| 320 } | |
| 321 | |
| 322 if (redownload_icons_) { | |
| 323 // Note that |redownload_icons_| can only be true after the database lookup | |
| 324 // for the page URL is completed. | |
| 325 ScheduleManifestDownload(); | |
| 326 } else { | |
| 327 // See if there is a cached favicon for the manifest. | |
| 328 GetFaviconAndUpdateMappingsUnlessIncognito( | |
| 329 /*icon_url=*/*manifest_url_, favicon_base::FAVICON, | |
| 330 base::Bind(&FaviconHandler::OnFaviconDataForManifestFromFaviconService, | |
| 331 base::Unretained(this))); | |
| 332 } | |
| 333 } | |
| 334 | |
| 335 void FaviconHandler::OnFaviconDataForManifestFromFaviconService( | |
| 336 const std::vector<favicon_base::FaviconRawBitmapResult>& | |
| 337 favicon_bitmap_results) { | |
| 338 bool has_valid_result = HasValidResult(favicon_bitmap_results); | |
| 339 bool has_expired_or_incomplete_result = | |
| 340 !has_valid_result || HasExpiredOrIncompleteResult(preferred_icon_size(), | |
| 341 favicon_bitmap_results); | |
| 342 | |
| 343 if (has_valid_result) { | |
| 344 // There is a valid favicon. Notify any observers. It is useful to notify | |
| 345 // the observers even if the favicon is expired or incomplete (incorrect | |
| 346 // size) because temporarily showing the user an expired favicon or | |
| 347 // streched favicon is preferable to showing the user the default favicon. | |
| 348 NotifyFaviconUpdated(favicon_bitmap_results); | |
| 349 } | |
| 350 | |
| 351 if (has_expired_or_incomplete_result) | |
| 352 ScheduleManifestDownload(); | |
| 353 } | |
| 354 | |
| 355 void FaviconHandler::ScheduleManifestDownload() { | |
| 356 manifest_download_request_.Reset(base::Bind( | |
| 357 &FaviconHandler::OnDidDownloadManifest, base::Unretained(this))); | |
| 358 delegate_->DownloadManifest(*manifest_url_, | |
| 359 manifest_download_request_.callback()); | |
| 360 } | |
| 361 | |
| 362 void FaviconHandler::OnDidDownloadManifest( | |
| 363 int status_code, | |
| 364 const std::vector<FaviconURL>& candidates) { | |
| 365 // Mark manifest download as finished. | |
| 366 manifest_download_request_.Cancel(); | |
| 367 | |
| 368 if (!candidates.empty()) { | |
| 369 DCHECK(status_code == 200); | |
|
pkotwicz
2017/04/12 22:10:06
Why the DCHECK() ?
mastiz
2017/04/20 18:06:33
To add clarity, but I realize you're not a big fan
| |
| 370 OnGotFinalIconURLCandidates(candidates); | |
|
pkotwicz
2017/04/12 22:10:07
You want to return here?
mastiz
2017/04/20 18:06:33
Correct, done (btw tests were failing due to this)
| |
| 371 } | |
| 372 | |
| 373 // If either the downloading of the manifest failed, OR the manifest contains | |
| 374 // no icons, proceed with the list of icons listed in the HTML. | |
| 375 DVLOG(1) << "Could not fetch Manifest icons from " << *manifest_url_ | |
| 376 << ", falling back to inlined ones, which are " | |
| 377 << non_manifest_original_candidates_.size(); | |
| 378 | |
| 379 if (service_ && (status_code == 404 || status_code == 200)) | |
|
pkotwicz
2017/04/12 22:10:07
Why is this if() checking the status code?
mastiz
2017/04/20 18:06:33
We shouldn't call UnableToDownloadFavicon() for al
pkotwicz
2017/04/24 14:42:15
Perhaps FaviconHandler::OnDidDownloadManifest() sh
mastiz
2017/04/27 13:54:50
How would that distinguish a 404 from 503?
pkotwicz
2017/05/01 04:56:53
I suggest doing this:
if (status_code == 404 || (
mastiz
2017/05/04 10:57:53
Would that work for a manifest that returns a 200
pkotwicz
2017/05/04 17:28:24
Black listing anything other than 5xx sounds reaso
mastiz
2017/05/10 10:03:51
Done.
pkotwicz
2017/05/12 06:13:28
Did you forget to upload a patch set. There does n
mastiz
2017/05/12 13:31:32
This was done previously but I've reverted it (in
pkotwicz
2017/05/12 15:37:41
Fair enough. You will need to delete the tests whi
mastiz
2017/05/15 14:06:59
404 behavior hasn't changed, only 5xx. That is, an
pkotwicz
2017/05/16 06:36:34
Ok, I see now
| |
| 380 service_->UnableToDownloadFavicon(*manifest_url_); | |
|
pkotwicz
2017/04/12 22:10:07
If we end up download the Web Manifest on each pag
mastiz
2017/04/20 18:06:33
If we were to always load and parse manifests, thi
pkotwicz
2017/04/24 14:42:15
It might not be that nice because:
- Web Manifest
mastiz
2017/04/27 13:54:50
Acknowledged, makes sense. We'd need to see how th
| |
| 381 | |
| 382 manifest_url_.reset(); | |
| 383 OnGotFinalIconURLCandidates(non_manifest_original_candidates_); | |
| 384 } | |
| 385 | |
| 386 void FaviconHandler::OnGotFinalIconURLCandidates( | |
| 387 const std::vector<FaviconURL>& candidates) { | |
| 293 std::vector<FaviconCandidate> sorted_candidates; | 388 std::vector<FaviconCandidate> sorted_candidates; |
| 294 const std::vector<int> desired_pixel_sizes = | 389 const std::vector<int> desired_pixel_sizes = |
| 295 GetDesiredPixelSizes(handler_type_); | 390 GetDesiredPixelSizes(handler_type_); |
| 296 for (const FaviconURL& candidate : candidates) { | 391 for (const FaviconURL& candidate : candidates) { |
| 297 if (!candidate.icon_url.is_empty() && (candidate.icon_type & icon_types_)) { | 392 if (!candidate.icon_url.is_empty() && (candidate.icon_type & icon_types_)) { |
| 298 sorted_candidates.push_back( | 393 sorted_candidates.push_back( |
| 299 FaviconCandidate::FromFaviconURL(candidate, desired_pixel_sizes)); | 394 FaviconCandidate::FromFaviconURL(candidate, desired_pixel_sizes)); |
| 300 } | 395 } |
| 301 } | 396 } |
| 302 | 397 |
| 303 std::stable_sort(sorted_candidates.begin(), sorted_candidates.end(), | 398 std::stable_sort(sorted_candidates.begin(), sorted_candidates.end(), |
| 304 &FaviconCandidate::CompareScore); | 399 &FaviconCandidate::CompareScore); |
| 305 | 400 |
| 306 if (candidates_.size() == sorted_candidates.size() && | 401 if (candidates_.size() == sorted_candidates.size() && |
| 307 std::equal(sorted_candidates.begin(), sorted_candidates.end(), | 402 std::equal(sorted_candidates.begin(), sorted_candidates.end(), |
| 308 candidates_.begin())) { | 403 candidates_.begin())) { |
| 309 return; | 404 return; |
| 310 } | 405 } |
| 311 | 406 |
| 312 download_request_.Cancel(); | 407 image_download_request_.Cancel(); |
| 313 candidates_ = std::move(sorted_candidates); | 408 candidates_ = std::move(sorted_candidates); |
| 314 current_candidate_index_ = 0u; | 409 current_candidate_index_ = 0u; |
| 315 best_favicon_ = DownloadedFavicon(); | 410 best_favicon_ = DownloadedFavicon(); |
| 316 | 411 |
| 317 // TODO(davemoore) Should clear on empty url. Currently we ignore it. | 412 // TODO(davemoore) Should clear on empty url. Currently we ignore it. |
| 318 // This appears to be what FF does as well. | 413 // This appears to be what FF does as well. |
| 319 if (current_candidate() && got_favicon_from_history_) | 414 if (current_candidate() && got_favicon_from_history_) |
| 320 OnGotInitialHistoryDataAndIconURLCandidates(); | 415 OnGotInitialHistoryDataAndIconURLCandidates(); |
| 321 } | 416 } |
| 322 | 417 |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 348 } | 443 } |
| 349 | 444 |
| 350 void FaviconHandler::OnDidDownloadFavicon( | 445 void FaviconHandler::OnDidDownloadFavicon( |
| 351 favicon_base::IconType icon_type, | 446 favicon_base::IconType icon_type, |
| 352 int id, | 447 int id, |
| 353 int http_status_code, | 448 int http_status_code, |
| 354 const GURL& image_url, | 449 const GURL& image_url, |
| 355 const std::vector<SkBitmap>& bitmaps, | 450 const std::vector<SkBitmap>& bitmaps, |
| 356 const std::vector<gfx::Size>& original_bitmap_sizes) { | 451 const std::vector<gfx::Size>& original_bitmap_sizes) { |
| 357 // Mark download as finished. | 452 // Mark download as finished. |
| 358 download_request_.Cancel(); | 453 image_download_request_.Cancel(); |
| 359 | 454 |
| 360 if (bitmaps.empty() && http_status_code == 404) { | 455 if (bitmaps.empty() && http_status_code == 404) { |
| 361 DVLOG(1) << "Failed to Download Favicon:" << image_url; | 456 DVLOG(1) << "Failed to Download Favicon:" << image_url; |
| 362 if (service_) | 457 if (service_) |
| 363 service_->UnableToDownloadFavicon(image_url); | 458 service_->UnableToDownloadFavicon(image_url); |
| 364 } | 459 } |
| 365 | 460 |
| 366 bool request_next_icon = true; | 461 bool request_next_icon = true; |
| 367 if (!bitmaps.empty()) { | 462 if (!bitmaps.empty()) { |
| 368 float score = 0.0f; | 463 float score = 0.0f; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 412 } | 507 } |
| 413 | 508 |
| 414 const std::vector<GURL> FaviconHandler::GetIconURLs() const { | 509 const std::vector<GURL> FaviconHandler::GetIconURLs() const { |
| 415 std::vector<GURL> icon_urls; | 510 std::vector<GURL> icon_urls; |
| 416 for (const FaviconCandidate& candidate : candidates_) | 511 for (const FaviconCandidate& candidate : candidates_) |
| 417 icon_urls.push_back(candidate.icon_url); | 512 icon_urls.push_back(candidate.icon_url); |
| 418 return icon_urls; | 513 return icon_urls; |
| 419 } | 514 } |
| 420 | 515 |
| 421 bool FaviconHandler::HasPendingTasksForTest() { | 516 bool FaviconHandler::HasPendingTasksForTest() { |
| 422 return !download_request_.IsCancelled() || | 517 return !manifest_download_request_.IsCancelled() || |
| 518 !image_download_request_.IsCancelled() || | |
| 423 cancelable_task_tracker_.HasTrackedTasks(); | 519 cancelable_task_tracker_.HasTrackedTasks(); |
| 424 } | 520 } |
| 425 | 521 |
| 426 bool FaviconHandler::ShouldSaveFavicon() { | 522 bool FaviconHandler::ShouldSaveFavicon() { |
| 427 if (!delegate_->IsOffTheRecord()) | 523 if (!delegate_->IsOffTheRecord()) |
| 428 return true; | 524 return true; |
| 429 | 525 |
| 430 // Always save favicon if the page is bookmarked. | 526 // Always save favicon if the page is bookmarked. |
| 431 return delegate_->IsBookmarked(url_); | 527 return delegate_->IsBookmarked(url_); |
| 432 } | 528 } |
| 433 | 529 |
| 434 void FaviconHandler::OnFaviconDataForInitialURLFromFaviconService( | 530 void FaviconHandler::OnFaviconDataForInitialURLFromFaviconService( |
| 435 const std::vector<favicon_base::FaviconRawBitmapResult>& | 531 const std::vector<favicon_base::FaviconRawBitmapResult>& |
| 436 favicon_bitmap_results) { | 532 favicon_bitmap_results) { |
| 437 got_favicon_from_history_ = true; | 533 got_favicon_from_history_ = true; |
| 438 bool has_valid_result = HasValidResult(favicon_bitmap_results); | 534 bool has_valid_result = HasValidResult(favicon_bitmap_results); |
| 439 initial_history_result_expired_or_incomplete_ = | 535 initial_history_result_expired_or_incomplete_ = |
| 440 !has_valid_result || | 536 !has_valid_result || |
| 441 HasExpiredOrIncompleteResult(preferred_icon_size(), | 537 HasExpiredOrIncompleteResult(preferred_icon_size(), |
| 442 favicon_bitmap_results); | 538 favicon_bitmap_results); |
| 443 redownload_icons_ = initial_history_result_expired_or_incomplete_ && | 539 redownload_icons_ = initial_history_result_expired_or_incomplete_ && |
| 444 !favicon_bitmap_results.empty(); | 540 !favicon_bitmap_results.empty(); |
| 445 | 541 |
| 446 if (has_valid_result && (!current_candidate() || | 542 if (has_valid_result && (!current_candidate() || |
| 447 DoUrlsAndIconsMatch(current_candidate()->icon_url, | 543 DoUrlsAndIconsMatch(current_candidate()->icon_url, |
| 448 current_candidate()->icon_type, | 544 current_candidate()->icon_type, |
| 449 favicon_bitmap_results))) { | 545 favicon_bitmap_results))) { |
|
pkotwicz
2017/04/12 22:10:06
I think that this should be changed to:
if (has_v
mastiz
2017/04/20 18:06:33
Done.
| |
| 450 // The db knows the favicon (although it may be out of date) and the entry | 546 // 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 | 547 // 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 | 548 // 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. | 549 // user doesn't see a flash of the default favicon. |
| 454 NotifyFaviconUpdated(favicon_bitmap_results); | 550 NotifyFaviconUpdated(favicon_bitmap_results); |
| 455 } | 551 } |
| 456 | 552 |
| 457 if (current_candidate()) | 553 if (current_candidate()) |
| 458 OnGotInitialHistoryDataAndIconURLCandidates(); | 554 OnGotInitialHistoryDataAndIconURLCandidates(); |
| 459 } | 555 } |
| 460 | 556 |
| 461 void FaviconHandler::DownloadCurrentCandidateOrAskFaviconService() { | 557 void FaviconHandler::DownloadCurrentCandidateOrAskFaviconService() { |
| 462 GURL icon_url = current_candidate()->icon_url; | 558 const GURL icon_url = current_candidate()->icon_url; |
| 463 favicon_base::IconType icon_type = current_candidate()->icon_type; | 559 const favicon_base::IconType icon_type = current_candidate()->icon_type; |
| 464 | 560 // If the icons listed in a manifest are being processed, skip the cache |
| 465 if (redownload_icons_) { | 561 // lookup for |icon_url| since the manifest's URL is used for caching anyway, |
| 562 // and this lookup has happened earlier. | |
| 563 if (redownload_icons_ || manifest_url_) { | |
| 466 // We have the mapping, but the favicon is out of date. Download it now. | 564 // We have the mapping, but the favicon is out of date. Download it now. |
| 467 ScheduleDownload(icon_url, icon_type); | 565 ScheduleFaviconDownload(icon_url, icon_type); |
| 468 } else if (service_) { | 566 } else { |
| 469 // We don't know the favicon, but we may have previously downloaded the | 567 GetFaviconAndUpdateMappingsUnlessIncognito( |
| 470 // favicon for another page that shares the same favicon. Ask for the | 568 icon_url, icon_type, |
| 471 // favicon given the favicon URL. | 569 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 } | 570 } |
| 491 } | 571 } |
| 492 | 572 |
| 573 void FaviconHandler::GetFaviconAndUpdateMappingsUnlessIncognito( | |
| 574 const GURL& icon_url, | |
| 575 favicon_base::IconType icon_type, | |
| 576 const favicon_base::FaviconResultsCallback& callback) { | |
| 577 if (!service_) | |
| 578 return; | |
| 579 | |
| 580 // We don't know the favicon, but we may have previously downloaded the | |
| 581 // favicon for another page that shares the same favicon. Ask for the | |
| 582 // favicon given the favicon URL. | |
| 583 if (delegate_->IsOffTheRecord()) { | |
| 584 service_->GetFavicon(icon_url, icon_type, preferred_icon_size(), callback, | |
| 585 &cancelable_task_tracker_); | |
| 586 } else { | |
| 587 // Ask the history service for the icon. This does two things: | |
| 588 // 1. Attempts to fetch the favicon data from the database. | |
| 589 // 2. If the favicon exists in the database, this updates the database to | |
| 590 // include the mapping between the page url and the favicon url. | |
| 591 // This is asynchronous. The history service will call back when done. | |
| 592 // TODO(pkotwicz): pass in all of |image_urls_| to | |
| 593 // UpdateFaviconMappingsAndFetch(). | |
| 594 service_->UpdateFaviconMappingsAndFetch(url_, {icon_url}, icon_type, | |
| 595 preferred_icon_size(), callback, | |
| 596 &cancelable_task_tracker_); | |
| 597 } | |
| 598 } | |
| 599 | |
| 493 void FaviconHandler::OnFaviconData(const std::vector< | 600 void FaviconHandler::OnFaviconData(const std::vector< |
| 494 favicon_base::FaviconRawBitmapResult>& favicon_bitmap_results) { | 601 favicon_base::FaviconRawBitmapResult>& favicon_bitmap_results) { |
| 495 bool has_results = !favicon_bitmap_results.empty(); | 602 bool has_results = !favicon_bitmap_results.empty(); |
| 496 bool has_valid_result = HasValidResult(favicon_bitmap_results); | 603 bool has_valid_result = HasValidResult(favicon_bitmap_results); |
| 497 bool has_expired_or_incomplete_result = | 604 bool has_expired_or_incomplete_result = |
| 498 !has_valid_result || HasExpiredOrIncompleteResult(preferred_icon_size(), | 605 !has_valid_result || HasExpiredOrIncompleteResult(preferred_icon_size(), |
| 499 favicon_bitmap_results); | 606 favicon_bitmap_results); |
| 500 | 607 |
| 501 if (has_valid_result) { | 608 if (has_valid_result) { |
| 502 // There is a valid favicon. Notify any observers. It is useful to notify | 609 // 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 | 610 // the observers even if the favicon is expired or incomplete (incorrect |
| 504 // size) because temporarily showing the user an expired favicon or | 611 // size) because temporarily showing the user an expired favicon or |
| 505 // streched favicon is preferable to showing the user the default favicon. | 612 // streched favicon is preferable to showing the user the default favicon. |
| 506 NotifyFaviconUpdated(favicon_bitmap_results); | 613 NotifyFaviconUpdated(favicon_bitmap_results); |
| 507 } | 614 } |
| 508 | 615 |
| 509 if (!current_candidate() || | 616 if (!current_candidate() || |
| 510 (has_results && !DoUrlsAndIconsMatch(current_candidate()->icon_url, | 617 (has_results && !DoUrlsAndIconsMatch(current_candidate()->icon_url, |
| 511 current_candidate()->icon_type, | 618 current_candidate()->icon_type, |
| 512 favicon_bitmap_results))) { | 619 favicon_bitmap_results))) { |
| 513 // The icon URLs have been updated since the favicon data was requested. | 620 // The icon URLs have been updated since the favicon data was requested. |
| 621 NOTREACHED(); // DONOTSUBMIT | |
| 514 return; | 622 return; |
| 515 } | 623 } |
| 516 | 624 |
| 517 if (has_expired_or_incomplete_result) { | 625 if (has_expired_or_incomplete_result) { |
| 518 ScheduleDownload(current_candidate()->icon_url, | 626 ScheduleFaviconDownload(current_candidate()->icon_url, |
| 519 current_candidate()->icon_type); | 627 current_candidate()->icon_type); |
| 520 } | 628 } |
| 521 } | 629 } |
| 522 | 630 |
| 523 void FaviconHandler::ScheduleDownload(const GURL& image_url, | 631 void FaviconHandler::ScheduleFaviconDownload(const GURL& image_url, |
| 524 favicon_base::IconType icon_type) { | 632 favicon_base::IconType icon_type) { |
| 525 DCHECK(image_url.is_valid()); | 633 DCHECK(image_url.is_valid()); |
| 526 // Note that CancelableCallback starts cancelled. | 634 // Note that CancelableCallback starts cancelled. |
| 527 DCHECK(download_request_.IsCancelled()) << "More than one ongoing download"; | 635 DCHECK(image_download_request_.IsCancelled()) |
| 636 << "More than one ongoing download"; | |
| 528 if (service_ && service_->WasUnableToDownloadFavicon(image_url)) { | 637 if (service_ && service_->WasUnableToDownloadFavicon(image_url)) { |
| 529 DVLOG(1) << "Skip Failed FavIcon: " << image_url; | 638 DVLOG(1) << "Skip Failed FavIcon: " << image_url; |
| 530 OnDidDownloadFavicon(icon_type, 0, 0, image_url, std::vector<SkBitmap>(), | 639 OnDidDownloadFavicon(icon_type, 0, 0, image_url, std::vector<SkBitmap>(), |
| 531 std::vector<gfx::Size>()); | 640 std::vector<gfx::Size>()); |
| 532 return; | 641 return; |
| 533 } | 642 } |
| 534 download_request_.Reset(base::Bind(&FaviconHandler::OnDidDownloadFavicon, | 643 image_download_request_.Reset( |
| 535 base::Unretained(this), icon_type)); | 644 base::Bind(&FaviconHandler::OnDidDownloadFavicon, base::Unretained(this), |
| 645 icon_type)); | |
| 536 // A max bitmap size is specified to avoid receiving huge bitmaps in | 646 // A max bitmap size is specified to avoid receiving huge bitmaps in |
| 537 // OnDidDownloadFavicon(). See FaviconDriver::StartDownload() | 647 // OnDidDownloadFavicon(). See FaviconDriver::StartDownload() |
| 538 // for more details about the max bitmap size. | 648 // for more details about the max bitmap size. |
| 539 const int download_id = | 649 const int download_id = |
| 540 delegate_->DownloadImage(image_url, GetMaximalIconSize(handler_type_), | 650 delegate_->DownloadImage(image_url, GetMaximalIconSize(handler_type_), |
| 541 download_request_.callback()); | 651 image_download_request_.callback()); |
| 542 DCHECK_NE(download_id, 0); | 652 DCHECK_NE(download_id, 0); |
| 543 } | 653 } |
| 544 | 654 |
| 545 } // namespace favicon | 655 } // namespace favicon |
| OLD | NEW |