Chromium Code Reviews| 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 "base/base_paths.h" | 7 #include "base/base_paths.h" |
| 8 #include "base/bind.h" | 8 #include "base/bind.h" |
| 9 #include "base/bind_helpers.h" | 9 #include "base/bind_helpers.h" |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 66 // The number of updates to skip to alleviate the machine when a previous update | 66 // The number of updates to skip to alleviate the machine when a previous update |
| 67 // was too slow. | 67 // was too slow. |
| 68 constexpr int kUpdatesToSkipUnderHeavyLoad = 10; | 68 constexpr int kUpdatesToSkipUnderHeavyLoad = 10; |
| 69 | 69 |
| 70 // The delay before updating the JumpList to prevent update storms. | 70 // The delay before updating the JumpList to prevent update storms. |
| 71 constexpr base::TimeDelta kDelayForJumplistUpdate = | 71 constexpr base::TimeDelta kDelayForJumplistUpdate = |
| 72 base::TimeDelta::FromMilliseconds(3500); | 72 base::TimeDelta::FromMilliseconds(3500); |
| 73 | 73 |
| 74 // The maximum allowed time for JumpListUpdater::BeginUpdate. Updates taking | 74 // The maximum allowed time for JumpListUpdater::BeginUpdate. Updates taking |
| 75 // longer than this are discarded to prevent bogging down slow machines. | 75 // longer than this are discarded to prevent bogging down slow machines. |
| 76 constexpr base::TimeDelta kTimeOutForJumplistBeginUpdate = | 76 constexpr base::TimeDelta kTimeOutForBeginUpdate = |
| 77 base::TimeDelta::FromMilliseconds(500); | 77 base::TimeDelta::FromMilliseconds(500); |
| 78 | 78 |
| 79 // The maximum allowed time for updating both "most visited" and "recently | 79 // The maximum allowed time for updating both "most visited" and "recently |
| 80 // closed" categories via JumpListUpdater::AddCustomCategory. | 80 // closed" categories via JumpListUpdater::AddCustomCategory. |
| 81 constexpr base::TimeDelta kTimeOutForAddCustomCategory = | 81 constexpr base::TimeDelta kTimeOutForAddCategory = |
| 82 base::TimeDelta::FromMilliseconds(500); | 82 base::TimeDelta::FromMilliseconds(500); |
| 83 | 83 |
| 84 // The maximum allowed time for JumpListUpdater::CommitUpdate. | 84 // The maximum allowed time for JumpListUpdater::CommitUpdate. |
| 85 constexpr base::TimeDelta kTimeOutForJumplistCommitUpdate = | 85 constexpr base::TimeDelta kTimeOutForCommitUpdate = |
| 86 base::TimeDelta::FromMilliseconds(1000); | 86 base::TimeDelta::FromMilliseconds(1000); |
| 87 | 87 |
| 88 // Appends the common switches to each shell link. | 88 // Appends the common switches to each shell link. |
| 89 void AppendCommonSwitches(ShellLinkItem* shell_link) { | 89 void AppendCommonSwitches(ShellLinkItem* shell_link) { |
| 90 const char* kSwitchNames[] = { switches::kUserDataDir }; | 90 const char* kSwitchNames[] = { switches::kUserDataDir }; |
| 91 const base::CommandLine& command_line = | 91 const base::CommandLine& command_line = |
| 92 *base::CommandLine::ForCurrentProcess(); | 92 *base::CommandLine::ForCurrentProcess(); |
| 93 shell_link->GetCommandLine()->CopySwitchesFrom(command_line, | 93 shell_link->GetCommandLine()->CopySwitchesFrom(command_line, |
| 94 kSwitchNames, | 94 kSwitchNames, |
| 95 arraysize(kSwitchNames)); | 95 arraysize(kSwitchNames)); |
| (...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 545 | 545 |
| 546 base::FilePath profile_dir = profile_->GetPath(); | 546 base::FilePath profile_dir = profile_->GetPath(); |
| 547 | 547 |
| 548 // Check if incognito windows (or normal windows) are disabled by policy. | 548 // Check if incognito windows (or normal windows) are disabled by policy. |
| 549 IncognitoModePrefs::Availability incognito_availability = | 549 IncognitoModePrefs::Availability incognito_availability = |
| 550 IncognitoModePrefs::GetAvailability(profile_->GetPrefs()); | 550 IncognitoModePrefs::GetAvailability(profile_->GetPrefs()); |
| 551 | 551 |
| 552 // Make local copies of JumpList member variables and use them for an update. | 552 // Make local copies of JumpList member variables and use them for an update. |
| 553 ShellLinkItemList local_most_visited_pages = most_visited_pages_; | 553 ShellLinkItemList local_most_visited_pages = most_visited_pages_; |
| 554 ShellLinkItemList local_recently_closed_pages = recently_closed_pages_; | 554 ShellLinkItemList local_recently_closed_pages = recently_closed_pages_; |
| 555 | |
| 556 bool most_visited_should_update = most_visited_should_update_; | 555 bool most_visited_should_update = most_visited_should_update_; |
| 557 bool recently_closed_should_update = recently_closed_should_update_; | 556 bool recently_closed_should_update = recently_closed_should_update_; |
| 558 | 557 |
| 559 auto update_results = base::MakeUnique<UpdateResults>(); | 558 auto update_results = base::MakeUnique<UpdateResults>(); |
| 560 update_results->most_visited_icons_in_update = most_visited_icons_; | 559 update_results->most_visited_icons = most_visited_icons_; |
| 561 update_results->recently_closed_icons_in_update = recently_closed_icons_; | 560 update_results->recently_closed_icons = recently_closed_icons_; |
| 561 update_results->most_visited_icon_assoc = most_visited_icon_assoc_; | |
| 562 update_results->recently_closed_icon_assoc = recently_closed_icon_assoc_; | |
| 562 | 563 |
| 563 // Parameter evaluation order is unspecified in C++. Ensure the pointer value | 564 // Parameter evaluation order is unspecified in C++. Ensure the pointer value |
| 564 // is obtained before base::Passed() is called. | 565 // is obtained before base::Passed() is called. |
| 565 auto* update_results_raw = update_results.get(); | 566 auto* update_results_raw = update_results.get(); |
|
grt (UTC plus 2)
2017/06/21 10:57:29
wdyt of moving the first Bind out here now so that
chengx
2017/06/22 22:45:06
Done.
| |
| 566 | 567 |
| 567 // Post a task to update the JumpList, which consists of 1) create new icons, | 568 // Post a task to update the JumpList, which consists of 1) create new icons, |
| 568 // 2) delete old icons, 3) notify the OS. | 569 // 2) notify the OS, 3) delete old icons. |
| 569 if (!update_jumplist_task_runner_->PostTaskAndReply( | 570 if (!update_jumplist_task_runner_->PostTaskAndReply( |
| 570 FROM_HERE, | 571 FROM_HERE, |
| 571 base::Bind(&JumpList::RunUpdateJumpList, app_id_, profile_dir, | 572 base::Bind(&JumpList::RunUpdateJumpList, app_id_, profile_dir, |
| 572 local_most_visited_pages, local_recently_closed_pages, | 573 local_most_visited_pages, local_recently_closed_pages, |
| 573 most_visited_should_update, recently_closed_should_update, | 574 most_visited_should_update, recently_closed_should_update, |
| 574 incognito_availability, update_results_raw), | 575 incognito_availability, update_results_raw), |
| 575 base::Bind(&JumpList::OnRunUpdateCompletion, | 576 base::Bind( |
| 576 weak_ptr_factory_.GetWeakPtr(), | 577 &JumpList::OnRunUpdateCompletion, weak_ptr_factory_.GetWeakPtr(), |
| 577 base::Passed(std::move(update_results))))) { | 578 base::Passed(std::move(update_results)), |
| 578 OnRunUpdateCompletion(base::MakeUnique<UpdateResults>()); | 579 most_visited_should_update, recently_closed_should_update))) { |
| 580 OnRunUpdateCompletion(base::MakeUnique<UpdateResults>(), false, false); | |
| 579 } | 581 } |
| 580 } | 582 } |
| 581 | 583 |
| 582 void JumpList::OnRunUpdateCompletion( | 584 void JumpList::OnRunUpdateCompletion( |
| 583 std::unique_ptr<UpdateResults> update_results) { | 585 std::unique_ptr<UpdateResults> update_results, |
| 586 bool most_visited_should_update, | |
| 587 bool recently_closed_should_update) { | |
| 584 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | 588 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 585 | 589 |
| 586 // Update JumpList member variables based on the results from the update run | 590 // Update JumpList member variables based on the results from the update run |
| 587 // just finished. | 591 // just finished. |
| 588 if (update_results->update_timeout) | 592 if (update_results->update_timeout) |
| 589 updates_to_skip_ = kUpdatesToSkipUnderHeavyLoad; | 593 updates_to_skip_ = kUpdatesToSkipUnderHeavyLoad; |
| 590 | 594 |
| 591 if (update_results->update_success) { | 595 if (update_results->update_success) { |
| 592 most_visited_icons_.swap(update_results->most_visited_icons_in_update); | 596 if (most_visited_should_update) { |
| 593 recently_closed_icons_.swap( | 597 most_visited_icons_.swap(update_results->most_visited_icons); |
| 594 update_results->recently_closed_icons_in_update); | 598 most_visited_icon_assoc_.swap(update_results->most_visited_icon_assoc); |
| 595 most_visited_should_update_ = false; | 599 most_visited_should_update_ = false; |
| 596 recently_closed_should_update_ = false; | 600 } |
| 601 if (recently_closed_should_update) { | |
| 602 recently_closed_icons_.swap(update_results->recently_closed_icons); | |
| 603 recently_closed_icon_assoc_.swap( | |
| 604 update_results->recently_closed_icon_assoc); | |
| 605 recently_closed_should_update_ = false; | |
| 606 } | |
| 597 } | 607 } |
| 598 | 608 |
| 599 update_in_progress_ = false; | 609 update_in_progress_ = false; |
| 600 | 610 |
| 601 // If there is any new notification during the update run just finished, start | 611 // If there is any new notification during the update run just finished, start |
| 602 // another JumpList update. | 612 // another JumpList update. |
| 603 // Otherwise, post tasks to delete the JumpListIcons and JumpListIconsOld | 613 // Otherwise, post tasks to delete the JumpListIcons and JumpListIconsOld |
| 604 // folders as they are no longer needed. Now we have the | 614 // folders as they are no longer needed. Now we have the |
| 605 // JumpListIcons{MostVisited, RecentClosed} folders instead. | 615 // JumpListIcons{MostVisited, RecentClosed} folders instead. |
| 606 if (top_sites_has_pending_notification_ || | 616 if (top_sites_has_pending_notification_ || |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 673 | 683 |
| 674 base::ElapsedTimer begin_update_timer; | 684 base::ElapsedTimer begin_update_timer; |
| 675 | 685 |
| 676 if (!jumplist_updater.BeginUpdate()) | 686 if (!jumplist_updater.BeginUpdate()) |
| 677 return; | 687 return; |
| 678 | 688 |
| 679 // Discard this JumpList update if JumpListUpdater::BeginUpdate takes longer | 689 // Discard this JumpList update if JumpListUpdater::BeginUpdate takes longer |
| 680 // than the maximum allowed time, as it's very likely the following update | 690 // than the maximum allowed time, as it's very likely the following update |
| 681 // steps will also take a long time. As we've not updated the icons on the | 691 // steps will also take a long time. As we've not updated the icons on the |
| 682 // disk, discarding this update wont't affect the current JumpList used by OS. | 692 // disk, discarding this update wont't affect the current JumpList used by OS. |
| 683 if (begin_update_timer.Elapsed() >= kTimeOutForJumplistBeginUpdate) { | 693 if (begin_update_timer.Elapsed() >= kTimeOutForBeginUpdate) { |
| 684 update_results->update_timeout = true; | 694 update_results->update_timeout = true; |
| 685 return; | 695 return; |
| 686 } | 696 } |
| 687 | 697 |
| 688 // Record the desired number of icons created in this JumpList update. | 698 // Record the desired number of icons created in this JumpList update. |
| 689 int icons_created = 0; | 699 int icons_created = 0; |
| 690 | 700 |
| 701 URLIconCache most_visited_icons_next; | |
| 702 URLIconCache recently_closed_icons_next; | |
| 703 | |
| 704 base::FilePath most_visited_icon_dir = GenerateJumplistIconDirName( | |
| 705 profile_dir, FILE_PATH_LITERAL("MostVisited")); | |
| 706 base::FilePath recently_closed_icon_dir = GenerateJumplistIconDirName( | |
| 707 profile_dir, FILE_PATH_LITERAL("RecentClosed")); | |
| 708 | |
| 691 // Update the icons for "Most Visisted" category of the JumpList if needed. | 709 // Update the icons for "Most Visisted" category of the JumpList if needed. |
| 692 if (most_visited_should_update) { | 710 if (most_visited_should_update) { |
| 693 base::FilePath icon_dir_most_visited = GenerateJumplistIconDirName( | 711 icons_created += SafeCreateIconFiles( |
|
grt (UTC plus 2)
2017/06/21 10:57:29
if i understand correctly, here and on line 719 yo
chengx
2017/06/22 22:45:06
Thanks a lot for the suggestion and your understan
| |
| 694 profile_dir, FILE_PATH_LITERAL("MostVisited")); | 712 most_visited_icon_dir, most_visited_pages, kMostVisitedItems, |
| 695 | 713 &update_results->most_visited_icon_assoc, |
| 696 icons_created += UpdateIconFiles( | 714 &update_results->most_visited_icons, &most_visited_icons_next); |
| 697 icon_dir_most_visited, most_visited_pages, kMostVisitedItems, | |
| 698 &update_results->most_visited_icons_in_update); | |
| 699 } | 715 } |
| 700 | 716 |
| 701 // Update the icons for "Recently Closed" category of the JumpList if needed. | 717 // Update the icons for "Recently Closed" category of the JumpList if needed. |
| 702 if (recently_closed_should_update) { | 718 if (recently_closed_should_update) { |
| 703 base::FilePath icon_dir_recent_closed = GenerateJumplistIconDirName( | 719 icons_created += SafeCreateIconFiles( |
| 704 profile_dir, FILE_PATH_LITERAL("RecentClosed")); | 720 recently_closed_icon_dir, recently_closed_pages, kRecentlyClosedItems, |
| 705 | 721 &update_results->recently_closed_icon_assoc, |
| 706 icons_created += UpdateIconFiles( | 722 &update_results->recently_closed_icons, &recently_closed_icons_next); |
| 707 icon_dir_recent_closed, recently_closed_pages, kRecentlyClosedItems, | |
| 708 &update_results->recently_closed_icons_in_update); | |
| 709 } | 723 } |
| 710 | 724 |
| 711 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407. | 725 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407. |
| 712 UMA_HISTOGRAM_COUNTS_100("WinJumplist.CreateIconFilesCount", icons_created); | 726 UMA_HISTOGRAM_COUNTS_100("WinJumplist.CreateIconFilesCount", icons_created); |
| 713 | 727 |
| 714 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407. | 728 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407. |
| 715 SCOPED_UMA_HISTOGRAM_TIMER("WinJumplist.UpdateJumpListDuration"); | 729 SCOPED_UMA_HISTOGRAM_TIMER("WinJumplist.UpdateJumpListDuration"); |
| 716 | 730 |
| 717 base::ElapsedTimer add_custom_category_timer; | 731 base::ElapsedTimer add_custom_category_timer; |
| 718 | 732 |
| 719 // Update the "Most Visited" category of the JumpList if it exists. | 733 // Update the JumpList categories. This update request is applied into the |
| 720 // This update request is applied into the JumpList when we commit this | 734 // JumpList when we commit this transaction. |
| 721 // transaction. | 735 bool add_category_success = |
| 722 if (!jumplist_updater.AddCustomCategory( | 736 jumplist_updater.AddCustomCategory( |
| 723 l10n_util::GetStringUTF16(IDS_NEW_TAB_MOST_VISITED), | 737 l10n_util::GetStringUTF16(IDS_NEW_TAB_MOST_VISITED), |
| 724 most_visited_pages, kMostVisitedItems)) { | 738 most_visited_pages, kMostVisitedItems) && |
| 739 jumplist_updater.AddCustomCategory( | |
| 740 l10n_util::GetStringUTF16(IDS_RECENTLY_CLOSED), recently_closed_pages, | |
| 741 kRecentlyClosedItems); | |
| 742 | |
| 743 // If AddCustomCategory call takes longer than the maximum allowed time, abort | |
| 744 // the current update and skip the next |kUpdatesToSkipUnderHeavyLoad| | |
| 745 // updates. | |
| 746 bool timeout = add_custom_category_timer.Elapsed() >= kTimeOutForAddCategory; | |
| 747 if (timeout) | |
| 748 update_results->update_timeout = true; | |
| 749 | |
| 750 if (!add_category_success || timeout) { | |
| 751 DeleteIconFilesUnified(most_visited_should_update, | |
| 752 recently_closed_should_update, most_visited_icon_dir, | |
| 753 recently_closed_icon_dir, update_results, | |
| 754 JumpListVersion::kNext); | |
| 725 return; | 755 return; |
| 726 } | 756 } |
| 727 | 757 |
| 728 // Update the "Recently Closed" category of the JumpList. | 758 // Update the "Tasks" category of the JumpList. |
| 729 if (!jumplist_updater.AddCustomCategory( | 759 if (!UpdateTaskCategory(&jumplist_updater, incognito_availability)) { |
| 730 l10n_util::GetStringUTF16(IDS_RECENTLY_CLOSED), recently_closed_pages, | 760 DeleteIconFilesUnified(most_visited_should_update, |
| 731 kRecentlyClosedItems)) { | 761 recently_closed_should_update, most_visited_icon_dir, |
| 762 recently_closed_icon_dir, update_results, | |
| 763 JumpListVersion::kNext); | |
| 732 return; | 764 return; |
| 733 } | 765 } |
| 734 | 766 |
| 735 // If JumpListUpdater::AddCustomCategory or JumpListUpdater::CommitUpdate | |
| 736 // takes longer than the maximum allowed time, skip the next | |
| 737 // |kUpdatesToSkipUnderHeavyLoad| updates. This update should be finished | |
| 738 // because we've already updated the icons on the disk. If discarding this | |
| 739 // update from here, some items in the current JumpList may not have icons | |
| 740 // as they've been delete from the disk. In this case, the background color of | |
| 741 // the JumpList panel is used instead, which doesn't look nice. | |
| 742 | |
| 743 if (add_custom_category_timer.Elapsed() >= kTimeOutForAddCustomCategory) | |
| 744 update_results->update_timeout = true; | |
| 745 | |
| 746 // Update the "Tasks" category of the JumpList. | |
| 747 if (!UpdateTaskCategory(&jumplist_updater, incognito_availability)) | |
| 748 return; | |
| 749 | |
| 750 base::ElapsedTimer commit_update_timer; | 767 base::ElapsedTimer commit_update_timer; |
| 751 | 768 |
| 752 // Commit this transaction and send the updated JumpList to Windows. | 769 // Commit this transaction and send the updated JumpList to Windows. |
| 753 if (jumplist_updater.CommitUpdate()) | 770 bool commit_success = jumplist_updater.CommitUpdate(); |
| 771 | |
| 772 // If CommitUpdate call takes longer than the maximum allowed time, abort the | |
| 773 // current update and skip the next |kUpdatesToSkipUnderHeavyLoad| updates. | |
| 774 if (commit_update_timer.Elapsed() >= kTimeOutForCommitUpdate) | |
| 775 update_results->update_timeout = true; | |
| 776 | |
| 777 if (commit_success) { | |
| 754 update_results->update_success = true; | 778 update_results->update_success = true; |
| 779 if (most_visited_should_update) | |
| 780 update_results->most_visited_icons.swap(most_visited_icons_next); | |
| 781 if (recently_closed_should_update) | |
| 782 update_results->recently_closed_icons.swap(recently_closed_icons_next); | |
| 783 } | |
| 755 | 784 |
| 756 if (commit_update_timer.Elapsed() >= kTimeOutForJumplistCommitUpdate) | 785 // Delete the set of icons based on commit status. |
| 757 update_results->update_timeout = true; | 786 JumpListVersion version = |
| 787 commit_success ? JumpListVersion::kCurrent : JumpListVersion::kNext; | |
| 788 | |
| 789 DeleteIconFilesUnified(most_visited_should_update, | |
| 790 recently_closed_should_update, most_visited_icon_dir, | |
| 791 recently_closed_icon_dir, update_results, version); | |
| 758 } | 792 } |
| 759 | 793 |
| 760 // static | 794 // static |
| 761 int JumpList::UpdateIconFiles(const base::FilePath& icon_dir, | 795 int JumpList::SafeCreateIconFiles(const base::FilePath& icon_dir, |
| 762 const ShellLinkItemList& page_list, | 796 const ShellLinkItemList& page_list, |
| 763 size_t slot_limit, | 797 size_t slot_limit, |
| 764 URLIconCache* icon_cache) { | 798 IconAssociation* icon_assoc, |
| 799 URLIconCache* icon_cur, | |
| 800 URLIconCache* icon_next) { | |
| 801 DCHECK(icon_assoc); | |
| 802 DCHECK(icon_cur); | |
| 803 DCHECK(icon_next); | |
| 804 | |
| 765 int icons_created = 0; | 805 int icons_created = 0; |
| 766 | 806 |
| 767 // Clear the JumpList icon folder at |icon_dir| and the cache when | 807 // Clear the JumpList icon folder at |icon_dir| and the caches when |
| 768 // 1) |icon_cache| is empty. This happens when "Most visited" or "Recently | 808 // 1) |icon_cur| is empty. This happens when "Most visited" or "Recently |
| 769 // closed" category updates for the 1st time after Chrome is launched. | 809 // closed" category updates for the 1st time after Chrome is launched. |
| 770 // 2) The number of icons in |icon_dir| has exceeded the limit. | 810 // 2) The number of icons in |icon_dir| has exceeded the limit. |
| 771 if (icon_cache->empty() || FilesExceedLimitInDir(icon_dir, slot_limit * 2)) { | 811 if (icon_cur->empty() || FilesExceedLimitInDir(icon_dir, slot_limit * 2)) { |
| 772 DeleteDirectoryContentAndLogRuntime(icon_dir, kFileDeleteLimit); | 812 DeleteDirectoryContentAndLogRuntime(icon_dir, kFileDeleteLimit); |
| 773 icon_cache->clear(); | 813 icon_assoc->clear(); |
| 814 icon_cur->clear(); | |
| 815 icon_next->clear(); | |
| 816 | |
| 774 // Create new icons only when the directory exists and is empty. | 817 // Create new icons only when the directory exists and is empty. |
| 775 if (base::CreateDirectory(icon_dir) && base::IsDirectoryEmpty(icon_dir)) | 818 if (base::CreateDirectory(icon_dir) && base::IsDirectoryEmpty(icon_dir)) { |
| 776 icons_created += | 819 icons_created += CreateIconFiles(icon_dir, page_list, slot_limit, |
| 777 CreateIconFiles(icon_dir, page_list, slot_limit, icon_cache); | 820 icon_assoc, icon_cur, icon_next); |
| 821 } | |
| 778 } else if (base::CreateDirectory(icon_dir)) { | 822 } else if (base::CreateDirectory(icon_dir)) { |
| 779 icons_created += | 823 icons_created += CreateIconFiles(icon_dir, page_list, slot_limit, |
| 780 CreateIconFiles(icon_dir, page_list, slot_limit, icon_cache); | 824 icon_assoc, icon_cur, icon_next); |
| 781 DeleteIconFiles(icon_dir, icon_cache); | |
| 782 } | 825 } |
| 783 | 826 |
| 784 return icons_created; | 827 return icons_created; |
| 785 } | 828 } |
| 786 | 829 |
| 787 // static | 830 // static |
| 788 int JumpList::CreateIconFiles(const base::FilePath& icon_dir, | 831 int JumpList::CreateIconFiles(const base::FilePath& icon_dir, |
| 789 const ShellLinkItemList& item_list, | 832 const ShellLinkItemList& item_list, |
| 790 size_t max_items, | 833 size_t max_items, |
| 791 URLIconCache* icon_cache) { | 834 IconAssociation* icon_assoc, |
| 835 URLIconCache* icon_cur, | |
| 836 URLIconCache* icon_next) { | |
| 837 DCHECK(icon_assoc); | |
| 838 DCHECK(icon_cur); | |
| 839 DCHECK(icon_next); | |
| 840 | |
| 792 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407. | 841 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407. |
| 793 SCOPED_UMA_HISTOGRAM_TIMER("WinJumplist.CreateIconFilesDuration"); | 842 SCOPED_UMA_HISTOGRAM_TIMER("WinJumplist.CreateIconFilesDuration"); |
| 794 | 843 |
| 795 int icons_created = 0; | 844 int icons_created = 0; |
| 796 | 845 |
| 846 // Mark all the icons kCurrent as they are used by the current JumpList. | |
| 847 for (auto iter = icon_assoc->begin(); iter != icon_assoc->end(); ++iter) | |
|
grt (UTC plus 2)
2017/06/21 10:57:29
std::for_each(std::begin(*icon_assoc), std::end(*i
chengx
2017/06/22 22:45:06
Done. I'll go with the second method.
| |
| 848 iter->second = JumpListVersion::kCurrent; | |
| 849 | |
| 797 // Reuse icons for urls that already present in the current JumpList. | 850 // Reuse icons for urls that already present in the current JumpList. |
| 798 URLIconCache updated_map; | |
| 799 for (ShellLinkItemList::const_iterator iter = item_list.begin(); | 851 for (ShellLinkItemList::const_iterator iter = item_list.begin(); |
| 800 iter != item_list.end() && max_items > 0; ++iter, --max_items) { | 852 iter != item_list.end() && max_items > 0; ++iter, --max_items) { |
| 801 ShellLinkItem* item = iter->get(); | 853 ShellLinkItem* item = iter->get(); |
| 802 auto cache_iter = icon_cache->find(item->url()); | 854 auto cache_iter = icon_cur->find(item->url()); |
| 803 if (cache_iter != icon_cache->end()) { | 855 if (cache_iter != icon_cur->end()) { |
| 804 item->set_icon(cache_iter->second.value(), 0); | 856 item->set_icon(cache_iter->second.value(), 0); |
| 805 updated_map[item->url()] = cache_iter->second; | 857 (*icon_next)[item->url()] = cache_iter->second; |
| 858 (*icon_assoc)[cache_iter->second] = JumpListVersion::kShared; | |
| 806 } else { | 859 } else { |
| 807 base::FilePath icon_path; | 860 base::FilePath icon_path; |
| 808 if (CreateIconFile(item->icon_image(), icon_dir, &icon_path)) { | 861 if (CreateIconFile(item->icon_image(), icon_dir, &icon_path)) { |
| 809 ++icons_created; | 862 ++icons_created; |
| 810 item->set_icon(icon_path.value(), 0); | 863 item->set_icon(icon_path.value(), 0); |
| 811 updated_map[item->url()] = icon_path; | 864 (*icon_next)[item->url()] = icon_path; |
| 865 (*icon_assoc)[icon_path] = JumpListVersion::kNext; | |
| 812 } | 866 } |
| 813 } | 867 } |
| 814 } | 868 } |
| 815 icon_cache->swap(updated_map); | |
| 816 | 869 |
| 817 return icons_created; | 870 return icons_created; |
| 818 } | 871 } |
| 819 | 872 |
| 820 // static | 873 // static |
| 874 void JumpList::DeleteIconFilesUnified( | |
| 875 bool most_visited_should_update, | |
| 876 bool recently_closed_should_update, | |
| 877 const base::FilePath& most_visited_icon_dir, | |
| 878 const base::FilePath& recently_closed_icon_dir, | |
| 879 UpdateResults* update_results, | |
| 880 JumpListVersion version) { | |
| 881 DCHECK(update_results); | |
| 882 | |
| 883 if (most_visited_should_update) { | |
| 884 DeleteIconFiles(most_visited_icon_dir, | |
| 885 &update_results->most_visited_icon_assoc, version); | |
| 886 } | |
| 887 if (recently_closed_should_update) { | |
| 888 DeleteIconFiles(recently_closed_icon_dir, | |
| 889 &update_results->recently_closed_icon_assoc, version); | |
| 890 } | |
| 891 } | |
| 892 | |
| 893 // static | |
| 821 void JumpList::DeleteIconFiles(const base::FilePath& icon_dir, | 894 void JumpList::DeleteIconFiles(const base::FilePath& icon_dir, |
| 822 URLIconCache* icon_cache) { | 895 IconAssociation* icon_assoc, |
| 823 // Put all cached icon file paths into a set. | 896 JumpListVersion version) { |
| 897 DCHECK(icon_assoc); | |
| 898 | |
| 899 IconAssociation icon_assoc_updated; | |
| 900 | |
| 901 // Put paths of icon files to keep into a set. | |
| 824 base::flat_set<base::FilePath> cached_files; | 902 base::flat_set<base::FilePath> cached_files; |
| 825 cached_files.reserve(icon_cache->size()); | 903 cached_files.reserve(icon_assoc->size()); |
| 826 | 904 for (const auto& path_version_pair : *icon_assoc) { |
| 827 for (const auto& url_path_pair : *icon_cache) | 905 if (path_version_pair.second != version) { |
| 828 cached_files.insert(url_path_pair.second); | 906 cached_files.insert(path_version_pair.first); |
| 907 icon_assoc_updated[path_version_pair.first] = path_version_pair.second; | |
| 908 } | |
| 909 } | |
| 829 | 910 |
| 830 DeleteNonCachedFiles(icon_dir, cached_files); | 911 DeleteNonCachedFiles(icon_dir, cached_files); |
| 912 | |
| 913 // Keep icon_assoc up-to-date after deleting obsolete icons. | |
| 914 icon_assoc->swap(icon_assoc_updated); | |
| 831 } | 915 } |
| OLD | NEW |