| 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 "chrome/browser/favicon/favicon_handler.h" | 5 #include "chrome/browser/favicon/favicon_handler.h" |
| 6 | 6 |
| 7 #include "build/build_config.h" | 7 #include "build/build_config.h" |
| 8 | 8 |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 54 std::string UrlWithoutFragment(const GURL& gurl) { | 54 std::string UrlWithoutFragment(const GURL& gurl) { |
| 55 GURL::Replacements replacements; | 55 GURL::Replacements replacements; |
| 56 replacements.ClearRef(); | 56 replacements.ClearRef(); |
| 57 return gurl.ReplaceComponents(replacements).spec(); | 57 return gurl.ReplaceComponents(replacements).spec(); |
| 58 } | 58 } |
| 59 | 59 |
| 60 bool UrlMatches(const GURL& gurl_a, const GURL& gurl_b) { | 60 bool UrlMatches(const GURL& gurl_a, const GURL& gurl_b) { |
| 61 return UrlWithoutFragment(gurl_a) == UrlWithoutFragment(gurl_b); | 61 return UrlWithoutFragment(gurl_a) == UrlWithoutFragment(gurl_b); |
| 62 } | 62 } |
| 63 | 63 |
| 64 // Returns true if at least one of the bitmaps in |favicon_bitmap_results| is |
| 65 // expired. |
| 66 bool HasExpiredFaviconResult( |
| 67 const std::vector<history::FaviconBitmapResult>& favicon_bitmap_results) { |
| 68 for (size_t i = 0; i < favicon_bitmap_results.size(); ++i) { |
| 69 if (favicon_bitmap_results[i].expired) |
| 70 return true; |
| 71 } |
| 72 return false; |
| 73 } |
| 74 |
| 64 } // namespace | 75 } // namespace |
| 65 | 76 |
| 66 //////////////////////////////////////////////////////////////////////////////// | 77 //////////////////////////////////////////////////////////////////////////////// |
| 67 | 78 |
| 68 FaviconHandler::DownloadRequest::DownloadRequest() | 79 FaviconHandler::DownloadRequest::DownloadRequest() |
| 69 : icon_type(history::INVALID_ICON) { | 80 : icon_type(history::INVALID_ICON) { |
| 70 } | 81 } |
| 71 | 82 |
| 72 FaviconHandler::DownloadRequest::~DownloadRequest() { | 83 FaviconHandler::DownloadRequest::~DownloadRequest() { |
| 73 } | 84 } |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 271 | 282 |
| 272 // For FAVICON. | 283 // For FAVICON. |
| 273 if (current_candidate()->icon_type == FaviconURL::FAVICON) { | 284 if (current_candidate()->icon_type == FaviconURL::FAVICON) { |
| 274 if (!favicon_expired_ && entry->GetFavicon().valid && | 285 if (!favicon_expired_ && entry->GetFavicon().valid && |
| 275 DoUrlAndIconMatch(*current_candidate(), entry->GetFavicon().url, | 286 DoUrlAndIconMatch(*current_candidate(), entry->GetFavicon().url, |
| 276 history::FAVICON)) | 287 history::FAVICON)) |
| 277 return; | 288 return; |
| 278 | 289 |
| 279 entry->GetFavicon().url = current_candidate()->icon_url; | 290 entry->GetFavicon().url = current_candidate()->icon_url; |
| 280 } else if (!favicon_expired_ && got_favicon_from_history_ && | 291 } else if (!favicon_expired_ && got_favicon_from_history_ && |
| 281 history_icon_.is_valid() && | 292 !history_results_.empty()) { |
| 282 DoUrlAndIconMatch( | 293 history::FaviconBitmapResult bitmap_result = history_results_[0]; |
| 283 *current_candidate(), | 294 if (bitmap_result.is_valid() && |
| 284 history_icon_.icon_url, history_icon_.icon_type)) { | 295 DoUrlAndIconMatch(*current_candidate(), bitmap_result.icon_url, |
| 285 return; | 296 bitmap_result.icon_type)) { |
| 297 return; |
| 298 } |
| 286 } | 299 } |
| 287 | 300 |
| 288 if (got_favicon_from_history_) | 301 if (got_favicon_from_history_) |
| 289 DownloadFaviconOrAskHistory(entry->GetURL(), current_candidate()->icon_url, | 302 DownloadFaviconOrAskHistory(entry->GetURL(), current_candidate()->icon_url, |
| 290 ToHistoryIconType(current_candidate()->icon_type)); | 303 ToHistoryIconType(current_candidate()->icon_type)); |
| 291 } | 304 } |
| 292 | 305 |
| 293 void FaviconHandler::OnDidDownloadFavicon(int id, | 306 void FaviconHandler::OnDidDownloadFavicon(int id, |
| 294 const GURL& image_url, | 307 const GURL& image_url, |
| 295 bool errored, | 308 bool errored, |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 349 } | 362 } |
| 350 int id = delegate_->StartDownload(image_url, image_size); | 363 int id = delegate_->StartDownload(image_url, image_size); |
| 351 return id; | 364 return id; |
| 352 } | 365 } |
| 353 | 366 |
| 354 void FaviconHandler::UpdateFaviconMappingAndFetch( | 367 void FaviconHandler::UpdateFaviconMappingAndFetch( |
| 355 const GURL& page_url, | 368 const GURL& page_url, |
| 356 const GURL& icon_url, | 369 const GURL& icon_url, |
| 357 history::IconType icon_type, | 370 history::IconType icon_type, |
| 358 CancelableRequestConsumerBase* consumer, | 371 CancelableRequestConsumerBase* consumer, |
| 359 const FaviconService::FaviconDataCallback& callback) { | 372 const FaviconService::FaviconResultsCallback& callback) { |
| 360 GetFaviconService()->UpdateFaviconMappingAndFetch(page_url, icon_url, | 373 GetFaviconService()->UpdateFaviconMappingAndFetch(page_url, icon_url, |
| 361 icon_type, consumer, callback); | 374 icon_type, consumer, callback); |
| 362 } | 375 } |
| 363 | 376 |
| 364 void FaviconHandler::GetFavicon( | 377 void FaviconHandler::GetFavicon( |
| 365 const GURL& icon_url, | 378 const GURL& icon_url, |
| 366 history::IconType icon_type, | 379 history::IconType icon_type, |
| 367 CancelableRequestConsumerBase* consumer, | 380 CancelableRequestConsumerBase* consumer, |
| 368 const FaviconService::FaviconDataCallback& callback) { | 381 const FaviconService::FaviconResultsCallback& callback) { |
| 369 GetFaviconService()->GetFavicon(icon_url, icon_type, consumer, callback); | 382 GetFaviconService()->GetFavicon(icon_url, icon_type, preferred_icon_size(), |
| 383 ui::GetSupportedScaleFactors(), consumer, callback); |
| 370 } | 384 } |
| 371 | 385 |
| 372 void FaviconHandler::GetFaviconForURL( | 386 void FaviconHandler::GetFaviconForURL( |
| 373 const GURL& page_url, | 387 const GURL& page_url, |
| 374 int icon_types, | 388 int icon_types, |
| 375 CancelableRequestConsumerBase* consumer, | 389 CancelableRequestConsumerBase* consumer, |
| 376 const FaviconService::FaviconDataCallback& callback) { | 390 const FaviconService::FaviconResultsCallback& callback) { |
| 377 GetFaviconService()->GetFaviconForURL(profile_, page_url, icon_types, | 391 GetFaviconService()->GetFaviconForURL(profile_, page_url, icon_types, |
| 378 consumer, callback); | 392 preferred_icon_size(), ui::GetSupportedScaleFactors(), consumer, |
| 393 callback); |
| 379 } | 394 } |
| 380 | 395 |
| 381 void FaviconHandler::SetHistoryFavicon( | 396 void FaviconHandler::SetHistoryFavicon( |
| 382 const GURL& page_url, | 397 const GURL& page_url, |
| 383 const GURL& icon_url, | 398 const GURL& icon_url, |
| 384 const std::vector<unsigned char>& image_data, | 399 const std::vector<unsigned char>& image_data, |
| 385 history::IconType icon_type) { | 400 history::IconType icon_type) { |
| 386 GetFaviconService()->SetFavicon(page_url, icon_url, image_data, icon_type); | 401 GetFaviconService()->SetFavicon(page_url, icon_url, image_data, icon_type); |
| 387 } | 402 } |
| 388 | 403 |
| 389 bool FaviconHandler::ShouldSaveFavicon(const GURL& url) { | 404 bool FaviconHandler::ShouldSaveFavicon(const GURL& url) { |
| 390 if (!profile_->IsOffTheRecord()) | 405 if (!profile_->IsOffTheRecord()) |
| 391 return true; | 406 return true; |
| 392 | 407 |
| 393 // Otherwise store the favicon if the page is bookmarked. | 408 // Otherwise store the favicon if the page is bookmarked. |
| 394 BookmarkModel* bookmark_model = | 409 BookmarkModel* bookmark_model = |
| 395 BookmarkModelFactory::GetForProfile(profile_); | 410 BookmarkModelFactory::GetForProfile(profile_); |
| 396 return bookmark_model && bookmark_model->IsBookmarked(url); | 411 return bookmark_model && bookmark_model->IsBookmarked(url); |
| 397 } | 412 } |
| 398 | 413 |
| 399 void FaviconHandler::OnFaviconDataForInitialURL( | 414 void FaviconHandler::OnFaviconDataForInitialURL( |
| 400 FaviconService::Handle handle, | 415 FaviconService::Handle handle, |
| 401 history::FaviconData favicon) { | 416 std::vector<history::FaviconBitmapResult> favicon_bitmap_results, |
| 417 history::IconURLSizesMap icon_url_sizes) { |
| 402 NavigationEntry* entry = GetEntry(); | 418 NavigationEntry* entry = GetEntry(); |
| 403 if (!entry) | 419 if (!entry) |
| 404 return; | 420 return; |
| 405 | 421 |
| 406 got_favicon_from_history_ = true; | 422 got_favicon_from_history_ = true; |
| 407 history_icon_ = favicon; | 423 history_results_ = favicon_bitmap_results; |
| 408 | 424 |
| 409 favicon_expired_ = (favicon.known_icon && favicon.expired); | 425 bool has_results = !favicon_bitmap_results.empty(); |
| 426 favicon_expired_ = (has_results && |
| 427 HasExpiredFaviconResult(favicon_bitmap_results)); |
| 410 | 428 |
| 411 if (favicon.known_icon && favicon.icon_type == history::FAVICON && | 429 history::FaviconBitmapResult bitmap_result; |
| 430 if (has_results) |
| 431 bitmap_result = favicon_bitmap_results[0]; |
| 432 |
| 433 if (has_results && bitmap_result.icon_type == history::FAVICON && |
| 412 !entry->GetFavicon().valid && | 434 !entry->GetFavicon().valid && |
| 413 (!current_candidate() || | 435 (!current_candidate() || |
| 414 DoUrlAndIconMatch( | 436 DoUrlAndIconMatch(*current_candidate(), |
| 415 *current_candidate(), favicon.icon_url, favicon.icon_type))) { | 437 bitmap_result.icon_url, bitmap_result.icon_type))) { |
| 416 // The db knows the favicon (although it may be out of date) and the entry | 438 // The db knows the favicon (although it may be out of date) and the entry |
| 417 // doesn't have an icon. Set the favicon now, and if the favicon turns out | 439 // doesn't have an icon. Set the favicon now, and if the favicon turns out |
| 418 // to be expired (or the wrong url) we'll fetch later on. This way the | 440 // to be expired (or the wrong url) we'll fetch later on. This way the |
| 419 // user doesn't see a flash of the default favicon. | 441 // user doesn't see a flash of the default favicon. |
| 420 entry->GetFavicon().url = favicon.icon_url; | 442 entry->GetFavicon().url = bitmap_result.icon_url; |
| 421 if (favicon.is_valid()) | 443 if (bitmap_result.is_valid()) |
| 422 UpdateFavicon(entry, favicon.image_data); | 444 UpdateFavicon(entry, bitmap_result.bitmap_data); |
| 423 entry->GetFavicon().valid = true; | 445 entry->GetFavicon().valid = true; |
| 424 } | 446 } |
| 425 | 447 |
| 426 if (favicon.known_icon && !favicon.expired) { | 448 if (has_results && !bitmap_result.expired) { |
| 427 if (current_candidate() && | 449 if (current_candidate() && |
| 428 !DoUrlAndIconMatch( | 450 !DoUrlAndIconMatch(*current_candidate(), |
| 429 *current_candidate(), favicon.icon_url, favicon.icon_type)) { | 451 bitmap_result.icon_url, bitmap_result.icon_type)) { |
| 430 // Mapping in the database is wrong. DownloadFavIconOrAskHistory will | 452 // Mapping in the database is wrong. DownloadFavIconOrAskHistory will |
| 431 // update the mapping for this url and download the favicon if we don't | 453 // update the mapping for this url and download the favicon if we don't |
| 432 // already have it. | 454 // already have it. |
| 433 DownloadFaviconOrAskHistory(entry->GetURL(), | 455 DownloadFaviconOrAskHistory(entry->GetURL(), |
| 434 current_candidate()->icon_url, | 456 current_candidate()->icon_url, |
| 435 static_cast<history::IconType>(current_candidate()->icon_type)); | 457 static_cast<history::IconType>(current_candidate()->icon_type)); |
| 436 } | 458 } |
| 437 } else if (current_candidate()) { | 459 } else if (current_candidate()) { |
| 438 // We know the official url for the favicon, by either don't have the | 460 // We know the official url for the favicon, by either don't have the |
| 439 // favicon or its expired. Continue on to DownloadFaviconOrAskHistory to | 461 // favicon or its expired. Continue on to DownloadFaviconOrAskHistory to |
| (...skipping 27 matching lines...) Expand all Loading... |
| 467 // include the mapping between the page url and the favicon url. | 489 // include the mapping between the page url and the favicon url. |
| 468 // This is asynchronous. The history service will call back when done. | 490 // This is asynchronous. The history service will call back when done. |
| 469 // Issue the request and associate the current page ID with it. | 491 // Issue the request and associate the current page ID with it. |
| 470 UpdateFaviconMappingAndFetch(page_url, icon_url, icon_type, | 492 UpdateFaviconMappingAndFetch(page_url, icon_url, icon_type, |
| 471 &cancelable_consumer_, | 493 &cancelable_consumer_, |
| 472 base::Bind(&FaviconHandler::OnFaviconData, base::Unretained(this))); | 494 base::Bind(&FaviconHandler::OnFaviconData, base::Unretained(this))); |
| 473 } | 495 } |
| 474 } | 496 } |
| 475 } | 497 } |
| 476 | 498 |
| 477 void FaviconHandler::OnFaviconData(FaviconService::Handle handle, | 499 void FaviconHandler::OnFaviconData( |
| 478 history::FaviconData favicon) { | 500 FaviconService::Handle handle, |
| 501 std::vector<history::FaviconBitmapResult> favicon_bitmap_results, |
| 502 history::IconURLSizesMap icon_url_sizes) { |
| 479 NavigationEntry* entry = GetEntry(); | 503 NavigationEntry* entry = GetEntry(); |
| 480 if (!entry) | 504 if (!entry) |
| 481 return; | 505 return; |
| 482 | 506 |
| 507 bool has_results = !favicon_bitmap_results.empty(); |
| 508 history::FaviconBitmapResult bitmap_result; |
| 509 if (has_results) |
| 510 bitmap_result = favicon_bitmap_results[0]; |
| 511 |
| 483 // No need to update the favicon url. By the time we get here | 512 // No need to update the favicon url. By the time we get here |
| 484 // UpdateFaviconURL will have set the favicon url. | 513 // UpdateFaviconURL will have set the favicon url. |
| 485 if (favicon.icon_type == history::FAVICON) { | 514 if (icon_types_ == history::FAVICON) { |
| 486 if (favicon.is_valid()) { | 515 if (has_results && bitmap_result.is_valid()) { |
| 516 DCHECK_EQ(history::FAVICON, bitmap_result.icon_type); |
| 517 |
| 487 // There is a favicon, set it now. If expired we'll download the current | 518 // There is a favicon, set it now. If expired we'll download the current |
| 488 // one again, but at least the user will get some icon instead of the | 519 // one again, but at least the user will get some icon instead of the |
| 489 // default and most likely the current one is fine anyway. | 520 // default and most likely the current one is fine anyway. |
| 490 UpdateFavicon(entry, favicon.image_data); | 521 UpdateFavicon(entry, bitmap_result.bitmap_data); |
| 491 } | 522 } |
| 492 if (!favicon.known_icon || favicon.expired) { | 523 if (!has_results || HasExpiredFaviconResult(favicon_bitmap_results)) { |
| 493 // We don't know the favicon, or it is out of date. Request the current | 524 // We don't know the favicon, or it is out of date. Request the current |
| 494 // one. | 525 // one. |
| 495 ScheduleDownload(entry->GetURL(), entry->GetFavicon().url, | 526 ScheduleDownload(entry->GetURL(), entry->GetFavicon().url, |
| 496 preferred_icon_size(), | 527 preferred_icon_size(), |
| 497 history::FAVICON, | 528 history::FAVICON, |
| 498 FaviconTabHelper::ImageDownloadCallback()); | 529 FaviconTabHelper::ImageDownloadCallback()); |
| 499 } | 530 } |
| 500 } else if (current_candidate() && (!favicon.known_icon || favicon.expired || | 531 } else if (current_candidate() && |
| 501 !(DoUrlAndIconMatch( | 532 (!has_results || HasExpiredFaviconResult(favicon_bitmap_results) || |
| 502 *current_candidate(), favicon.icon_url, favicon.icon_type)))) { | 533 !(DoUrlAndIconMatch(*current_candidate(), bitmap_result.icon_url, |
| 534 bitmap_result.icon_type)))) { |
| 503 // We don't know the favicon, it is out of date or its type is not same as | 535 // We don't know the favicon, it is out of date or its type is not same as |
| 504 // one got from page. Request the current one. | 536 // one got from page. Request the current one. |
| 505 ScheduleDownload(entry->GetURL(), current_candidate()->icon_url, | 537 ScheduleDownload(entry->GetURL(), current_candidate()->icon_url, |
| 506 preferred_icon_size(), | 538 preferred_icon_size(), |
| 507 ToHistoryIconType(current_candidate()->icon_type), | 539 ToHistoryIconType(current_candidate()->icon_type), |
| 508 FaviconTabHelper::ImageDownloadCallback()); | 540 FaviconTabHelper::ImageDownloadCallback()); |
| 509 } | 541 } |
| 510 history_icon_ = favicon; | 542 history_results_ = favicon_bitmap_results; |
| 511 } | 543 } |
| 512 | 544 |
| 513 int FaviconHandler::ScheduleDownload( | 545 int FaviconHandler::ScheduleDownload( |
| 514 const GURL& url, | 546 const GURL& url, |
| 515 const GURL& image_url, | 547 const GURL& image_url, |
| 516 int image_size, | 548 int image_size, |
| 517 history::IconType icon_type, | 549 history::IconType icon_type, |
| 518 const FaviconTabHelper::ImageDownloadCallback& callback) { | 550 const FaviconTabHelper::ImageDownloadCallback& callback) { |
| 519 const int download_id = DownloadFavicon(image_url, image_size); | 551 const int download_id = DownloadFavicon(image_url, image_size); |
| 520 if (download_id) { | 552 if (download_id) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 534 int height = bitmap.height(); | 566 int height = bitmap.height(); |
| 535 if (width > 0 && height > 0) { | 567 if (width > 0 && height > 0) { |
| 536 gfx::CalculateFaviconTargetSize(&width, &height); | 568 gfx::CalculateFaviconTargetSize(&width, &height); |
| 537 return gfx::Image(skia::ImageOperations::Resize( | 569 return gfx::Image(skia::ImageOperations::Resize( |
| 538 bitmap, skia::ImageOperations::RESIZE_LANCZOS3, | 570 bitmap, skia::ImageOperations::RESIZE_LANCZOS3, |
| 539 width, height)); | 571 width, height)); |
| 540 } | 572 } |
| 541 | 573 |
| 542 return image; | 574 return image; |
| 543 } | 575 } |
| OLD | NEW |