OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 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/win/jumplist.h" | 5 #include "chrome/browser/win/jumplist.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
(...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
434 void JumpList::CancelPendingUpdate() { | 434 void JumpList::CancelPendingUpdate() { |
435 DCHECK(CalledOnValidThread()); | 435 DCHECK(CalledOnValidThread()); |
436 if (task_id_ != base::CancelableTaskTracker::kBadTaskId) { | 436 if (task_id_ != base::CancelableTaskTracker::kBadTaskId) { |
437 cancelable_task_tracker_.TryCancel(task_id_); | 437 cancelable_task_tracker_.TryCancel(task_id_); |
438 task_id_ = base::CancelableTaskTracker::kBadTaskId; | 438 task_id_ = base::CancelableTaskTracker::kBadTaskId; |
439 } | 439 } |
440 } | 440 } |
441 | 441 |
442 void JumpList::Terminate() { | 442 void JumpList::Terminate() { |
443 DCHECK(CalledOnValidThread()); | 443 DCHECK(CalledOnValidThread()); |
| 444 timer_most_visited_.Stop(); |
| 445 timer_recently_closed_.Stop(); |
444 CancelPendingUpdate(); | 446 CancelPendingUpdate(); |
445 if (profile_) { | 447 if (profile_) { |
446 sessions::TabRestoreService* tab_restore_service = | 448 sessions::TabRestoreService* tab_restore_service = |
447 TabRestoreServiceFactory::GetForProfile(profile_); | 449 TabRestoreServiceFactory::GetForProfile(profile_); |
448 if (tab_restore_service) | 450 if (tab_restore_service) |
449 tab_restore_service->RemoveObserver(this); | 451 tab_restore_service->RemoveObserver(this); |
450 scoped_refptr<history::TopSites> top_sites = | 452 scoped_refptr<history::TopSites> top_sites = |
451 TopSitesFactory::GetForProfile(profile_); | 453 TopSitesFactory::GetForProfile(profile_); |
452 if (top_sites) | 454 if (top_sites) |
453 top_sites->RemoveObserver(this); | 455 top_sites->RemoveObserver(this); |
454 pref_change_registrar_.reset(); | 456 pref_change_registrar_.reset(); |
455 } | 457 } |
456 profile_ = NULL; | 458 profile_ = NULL; |
457 } | 459 } |
458 | 460 |
459 void JumpList::ShutdownOnUIThread() { | 461 void JumpList::ShutdownOnUIThread() { |
460 DCHECK(CalledOnValidThread()); | 462 DCHECK(CalledOnValidThread()); |
461 Terminate(); | 463 Terminate(); |
462 } | 464 } |
463 | 465 |
464 void JumpList::OnMostVisitedURLsAvailable( | 466 void JumpList::OnMostVisitedURLsAvailable( |
465 const history::MostVisitedURLList& urls) { | 467 const history::MostVisitedURLList& urls) { |
466 DCHECK(CalledOnValidThread()); | 468 DCHECK(CalledOnValidThread()); |
467 // If we have a pending favicon request, cancel it here (it is out of date). | |
468 CancelPendingUpdate(); | |
469 | 469 |
| 470 // At most 9 JumpList items can be displayed for the "Most Visited" |
| 471 // category. |
| 472 const int kMostVistedCount = 9; |
470 { | 473 { |
471 JumpListData* data = &jumplist_data_->data; | 474 JumpListData* data = &jumplist_data_->data; |
472 base::AutoLock auto_lock(data->list_lock_); | 475 base::AutoLock auto_lock(data->list_lock_); |
473 data->most_visited_pages_.clear(); | 476 data->most_visited_pages_.clear(); |
474 for (size_t i = 0; i < urls.size(); i++) { | 477 |
| 478 for (size_t i = 0; i < urls.size() && i < kMostVistedCount; i++) { |
475 const history::MostVisitedURL& url = urls[i]; | 479 const history::MostVisitedURL& url = urls[i]; |
476 scoped_refptr<ShellLinkItem> link = CreateShellLink(); | 480 scoped_refptr<ShellLinkItem> link = CreateShellLink(); |
477 std::string url_string = url.url.spec(); | 481 std::string url_string = url.url.spec(); |
478 std::wstring url_string_wide = base::UTF8ToWide(url_string); | 482 std::wstring url_string_wide = base::UTF8ToWide(url_string); |
479 link->GetCommandLine()->AppendArgNative(url_string_wide); | 483 link->GetCommandLine()->AppendArgNative(url_string_wide); |
480 link->GetCommandLine()->AppendSwitchASCII( | 484 link->GetCommandLine()->AppendSwitchASCII( |
481 switches::kWinJumplistAction, jumplist::kMostVisitedCategory); | 485 switches::kWinJumplistAction, jumplist::kMostVisitedCategory); |
482 link->set_title(!url.title.empty() ? url.title : url_string_wide); | 486 link->set_title(!url.title.empty() ? url.title : url_string_wide); |
483 data->most_visited_pages_.push_back(link); | 487 data->most_visited_pages_.push_back(link); |
484 data->icon_urls_.push_back(std::make_pair(url_string, link)); | 488 data->icon_urls_.push_back(std::make_pair(url_string, link)); |
485 } | 489 } |
486 data->most_visited_pages_have_updates_ = true; | 490 data->most_visited_pages_have_updates_ = true; |
487 } | 491 } |
488 | 492 |
489 // Send a query that retrieves the first favicon. | 493 // Send a query that retrieves the first favicon. |
490 StartLoadingFavicon(); | 494 StartLoadingFavicon(); |
491 } | 495 } |
492 | 496 |
493 void JumpList::TabRestoreServiceChanged(sessions::TabRestoreService* service) { | 497 void JumpList::TabRestoreServiceChanged(sessions::TabRestoreService* service) { |
494 DCHECK(CalledOnValidThread()); | 498 DCHECK(CalledOnValidThread()); |
| 499 |
495 // if we have a pending favicon request, cancel it here (it is out of date). | 500 // if we have a pending favicon request, cancel it here (it is out of date). |
496 CancelPendingUpdate(); | 501 CancelPendingUpdate(); |
497 | 502 |
| 503 // Initialize the one-shot timer to update the the "Recently Closed" category |
| 504 // in a while. If there is already a request queued then cancel it and post |
| 505 // the new request. This ensures that JumpList update of the "Recently Closed" |
| 506 // category won't happen until there has been a brief quiet period, thus |
| 507 // avoiding update storms. |
| 508 if (timer_recently_closed_.IsRunning()) { |
| 509 timer_recently_closed_.Reset(); |
| 510 } else { |
| 511 timer_recently_closed_.Start( |
| 512 FROM_HERE, kDelayForJumplistUpdate, |
| 513 base::Bind(&JumpList::DeferredTabRestoreServiceChanged, |
| 514 base::Unretained(this))); |
| 515 } |
| 516 } |
| 517 |
| 518 void JumpList::DeferredTabRestoreServiceChanged() { |
498 // Create a list of ShellLinkItems from the "Recently Closed" pages. | 519 // Create a list of ShellLinkItems from the "Recently Closed" pages. |
499 // As noted above, we create a ShellLinkItem objects with the following | 520 // As noted above, we create a ShellLinkItem objects with the following |
500 // parameters. | 521 // parameters. |
501 // * arguments | 522 // * arguments |
502 // The last URL of the tab object. | 523 // The last URL of the tab object. |
503 // * title | 524 // * title |
504 // The title of the last URL. | 525 // The title of the last URL. |
505 // * icon | 526 // * icon |
506 // An empty string. This value is to be updated in OnFaviconDataAvailable(). | 527 // An empty string. This value is to be updated in OnFaviconDataAvailable(). |
507 // This code is copied from | 528 // This code is copied from |
508 // RecentlyClosedTabsHandler::TabRestoreServiceChanged() to emulate it. | 529 // RecentlyClosedTabsHandler::TabRestoreServiceChanged() to emulate it. |
509 const int kRecentlyClosedCount = 3; | 530 const int kRecentlyClosedCount = 3; |
510 sessions::TabRestoreService* tab_restore_service = | 531 sessions::TabRestoreService* tab_restore_service = |
511 TabRestoreServiceFactory::GetForProfile(profile_); | 532 TabRestoreServiceFactory::GetForProfile(profile_); |
512 | 533 |
513 { | 534 { |
514 JumpListData* data = &jumplist_data_->data; | 535 JumpListData* data = &jumplist_data_->data; |
515 base::AutoLock auto_lock(data->list_lock_); | 536 base::AutoLock auto_lock(data->list_lock_); |
516 data->recently_closed_pages_.clear(); | 537 data->recently_closed_pages_.clear(); |
517 | 538 |
518 for (const auto& entry : tab_restore_service->entries()) { | 539 for (const auto& entry : tab_restore_service->entries()) { |
| 540 if (data->recently_closed_pages_.size() >= kRecentlyClosedCount) |
| 541 break; |
519 switch (entry->type) { | 542 switch (entry->type) { |
520 case sessions::TabRestoreService::TAB: | 543 case sessions::TabRestoreService::TAB: |
521 AddTab(static_cast<const sessions::TabRestoreService::Tab&>(*entry), | 544 AddTab(static_cast<const sessions::TabRestoreService::Tab&>(*entry), |
522 kRecentlyClosedCount, data); | 545 kRecentlyClosedCount, data); |
523 break; | 546 break; |
524 case sessions::TabRestoreService::WINDOW: | 547 case sessions::TabRestoreService::WINDOW: |
525 AddWindow( | 548 AddWindow( |
526 static_cast<const sessions::TabRestoreService::Window&>(*entry), | 549 static_cast<const sessions::TabRestoreService::Window&>(*entry), |
527 kRecentlyClosedCount, data); | 550 kRecentlyClosedCount, data); |
528 break; | 551 break; |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
654 // category changes, mark the flags so that icon files for those categories | 677 // category changes, mark the flags so that icon files for those categories |
655 // won't be updated later on. | 678 // won't be updated later on. |
656 if (!waiting_for_icons) | 679 if (!waiting_for_icons) |
657 PostRunUpdate(); | 680 PostRunUpdate(); |
658 } | 681 } |
659 | 682 |
660 void JumpList::PostRunUpdate() { | 683 void JumpList::PostRunUpdate() { |
661 DCHECK(CalledOnValidThread()); | 684 DCHECK(CalledOnValidThread()); |
662 | 685 |
663 TRACE_EVENT0("browser", "JumpList::PostRunUpdate"); | 686 TRACE_EVENT0("browser", "JumpList::PostRunUpdate"); |
664 // Initialize the one-shot timer to update the jumplists in a while. | |
665 // If there is already a request queued then cancel it and post the new | |
666 // request. This ensures that JumpListUpdates won't happen until there has | |
667 // been a brief quiet period, thus avoiding update storms. | |
668 if (timer_.IsRunning()) { | |
669 timer_.Reset(); | |
670 } else { | |
671 timer_.Start(FROM_HERE, kDelayForJumplistUpdate, this, | |
672 &JumpList::DeferredRunUpdate); | |
673 } | |
674 } | |
675 | |
676 void JumpList::DeferredRunUpdate() { | |
677 DCHECK(CalledOnValidThread()); | |
678 | |
679 TRACE_EVENT0("browser", "JumpList::DeferredRunUpdate"); | |
680 // Check if incognito windows (or normal windows) are disabled by policy. | 687 // Check if incognito windows (or normal windows) are disabled by policy. |
681 IncognitoModePrefs::Availability incognito_availability = | 688 IncognitoModePrefs::Availability incognito_availability = |
682 profile_ ? IncognitoModePrefs::GetAvailability(profile_->GetPrefs()) | 689 profile_ ? IncognitoModePrefs::GetAvailability(profile_->GetPrefs()) |
683 : IncognitoModePrefs::ENABLED; | 690 : IncognitoModePrefs::ENABLED; |
684 | 691 |
685 // Post a task to update the JumpList, which consists of 1) delete old icons, | 692 // Post a task to update the JumpList, which consists of 1) delete old icons, |
686 // 2) create new icons, 3) notify the OS. | 693 // 2) create new icons, 3) notify the OS. |
687 update_jumplist_task_runner_->PostTask( | 694 update_jumplist_task_runner_->PostTask( |
688 FROM_HERE, base::Bind(&RunUpdateJumpList, incognito_availability, app_id_, | 695 FROM_HERE, base::Bind(&RunUpdateJumpList, incognito_availability, app_id_, |
689 icon_dir_, base::RetainedRef(jumplist_data_))); | 696 icon_dir_, base::RetainedRef(jumplist_data_))); |
(...skipping 11 matching lines...) Expand all Loading... |
701 delete_jumplisticons_task_runner_->PostTask( | 708 delete_jumplisticons_task_runner_->PostTask( |
702 FROM_HERE, | 709 FROM_HERE, |
703 base::Bind(&DeleteDirectory, std::move(icon_dir_old), kFileDeleteLimit)); | 710 base::Bind(&DeleteDirectory, std::move(icon_dir_old), kFileDeleteLimit)); |
704 } | 711 } |
705 | 712 |
706 void JumpList::TopSitesLoaded(history::TopSites* top_sites) { | 713 void JumpList::TopSitesLoaded(history::TopSites* top_sites) { |
707 } | 714 } |
708 | 715 |
709 void JumpList::TopSitesChanged(history::TopSites* top_sites, | 716 void JumpList::TopSitesChanged(history::TopSites* top_sites, |
710 ChangeReason change_reason) { | 717 ChangeReason change_reason) { |
711 top_sites->GetMostVisitedURLs( | 718 // If we have a pending favicon request, cancel it here (it is out of date). |
712 base::Bind(&JumpList::OnMostVisitedURLsAvailable, | 719 CancelPendingUpdate(); |
713 weak_ptr_factory_.GetWeakPtr()), | 720 |
714 false); | 721 // Initialize the one-shot timer to update the the "Most visited" category in |
| 722 // a while. If there is already a request queued then cancel it and post the |
| 723 // new request. This ensures that JumpList update of the "Most visited" |
| 724 // category won't happen until there has been a brief quiet period, thus |
| 725 // avoiding update storms. |
| 726 if (timer_most_visited_.IsRunning()) { |
| 727 timer_most_visited_.Reset(); |
| 728 } else { |
| 729 timer_most_visited_.Start( |
| 730 FROM_HERE, kDelayForJumplistUpdate, |
| 731 base::Bind(&JumpList::DeferredTopSitesChanged, base::Unretained(this))); |
| 732 } |
715 } | 733 } |
| 734 |
| 735 void JumpList::DeferredTopSitesChanged() { |
| 736 scoped_refptr<history::TopSites> top_sites = |
| 737 TopSitesFactory::GetForProfile(profile_); |
| 738 if (top_sites) { |
| 739 top_sites->GetMostVisitedURLs( |
| 740 base::Bind(&JumpList::OnMostVisitedURLsAvailable, |
| 741 weak_ptr_factory_.GetWeakPtr()), |
| 742 false); |
| 743 } |
| 744 } |
OLD | NEW |