| 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 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 57 #include "ui/gfx/image/image_family.h" | 57 #include "ui/gfx/image/image_family.h" |
| 58 #include "ui/gfx/image/image_skia.h" | 58 #include "ui/gfx/image/image_skia.h" |
| 59 #include "ui/gfx/image/image_skia_rep.h" | 59 #include "ui/gfx/image/image_skia_rep.h" |
| 60 #include "url/gurl.h" | 60 #include "url/gurl.h" |
| 61 | 61 |
| 62 using content::BrowserThread; | 62 using content::BrowserThread; |
| 63 using JumpListData = JumpList::JumpListData; | 63 using JumpListData = JumpList::JumpListData; |
| 64 | 64 |
| 65 namespace { | 65 namespace { |
| 66 | 66 |
| 67 // The number of updates to skip to alleviate the machine when a previous update |
| 68 // was too slow. |
| 69 constexpr int kUpdatesToSkipUnderHeavyLoad = 10; |
| 70 |
| 67 // The delay before updating the JumpList to prevent update storms. | 71 // The delay before updating the JumpList to prevent update storms. |
| 68 constexpr base::TimeDelta kDelayForJumplistUpdate = | 72 constexpr base::TimeDelta kDelayForJumplistUpdate = |
| 69 base::TimeDelta::FromMilliseconds(3500); | 73 base::TimeDelta::FromMilliseconds(3500); |
| 70 | 74 |
| 71 // The maximum allowed time for JumpListUpdater::BeginUpdate. Updates taking | 75 // The maximum allowed time for JumpListUpdater::BeginUpdate. Updates taking |
| 72 // longer than this are discarded to prevent bogging down slow machines. | 76 // longer than this are discarded to prevent bogging down slow machines. |
| 73 constexpr base::TimeDelta kTimeOutForJumplistUpdate = | 77 constexpr base::TimeDelta kTimeOutForJumplistBeginUpdate = |
| 74 base::TimeDelta::FromMilliseconds(500); | 78 base::TimeDelta::FromMilliseconds(500); |
| 75 | 79 |
| 80 // The maximum allowed time for updating both "most visited" and "recently |
| 81 // closed" categories via JumpListUpdater::AddCustomCategory. |
| 82 constexpr base::TimeDelta kTimeOutForAddCustomCategory = |
| 83 base::TimeDelta::FromMilliseconds(500); |
| 84 |
| 85 // The maximum allowed time for JumpListUpdater::CommitUpdate. |
| 86 constexpr base::TimeDelta kTimeOutForJumplistCommitUpdate = |
| 87 base::TimeDelta::FromMilliseconds(1000); |
| 88 |
| 76 // Appends the common switches to each shell link. | 89 // Appends the common switches to each shell link. |
| 77 void AppendCommonSwitches(ShellLinkItem* shell_link) { | 90 void AppendCommonSwitches(ShellLinkItem* shell_link) { |
| 78 const char* kSwitchNames[] = { switches::kUserDataDir }; | 91 const char* kSwitchNames[] = { switches::kUserDataDir }; |
| 79 const base::CommandLine& command_line = | 92 const base::CommandLine& command_line = |
| 80 *base::CommandLine::ForCurrentProcess(); | 93 *base::CommandLine::ForCurrentProcess(); |
| 81 shell_link->GetCommandLine()->CopySwitchesFrom(command_line, | 94 shell_link->GetCommandLine()->CopySwitchesFrom(command_line, |
| 82 kSwitchNames, | 95 kSwitchNames, |
| 83 arraysize(kSwitchNames)); | 96 arraysize(kSwitchNames)); |
| 84 } | 97 } |
| 85 | 98 |
| (...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 516 if (timer_most_visited_.IsRunning()) { | 529 if (timer_most_visited_.IsRunning()) { |
| 517 timer_most_visited_.Reset(); | 530 timer_most_visited_.Reset(); |
| 518 } else { | 531 } else { |
| 519 timer_most_visited_.Start( | 532 timer_most_visited_.Start( |
| 520 FROM_HERE, kDelayForJumplistUpdate, | 533 FROM_HERE, kDelayForJumplistUpdate, |
| 521 base::Bind(&JumpList::DeferredTopSitesChanged, base::Unretained(this))); | 534 base::Bind(&JumpList::DeferredTopSitesChanged, base::Unretained(this))); |
| 522 } | 535 } |
| 523 } | 536 } |
| 524 | 537 |
| 525 void JumpList::DeferredTopSitesChanged() { | 538 void JumpList::DeferredTopSitesChanged() { |
| 539 if (updates_to_skip_ > 0) { |
| 540 --updates_to_skip_; |
| 541 return; |
| 542 } |
| 543 |
| 526 scoped_refptr<history::TopSites> top_sites = | 544 scoped_refptr<history::TopSites> top_sites = |
| 527 TopSitesFactory::GetForProfile(profile_); | 545 TopSitesFactory::GetForProfile(profile_); |
| 528 if (top_sites) { | 546 if (top_sites) { |
| 529 top_sites->GetMostVisitedURLs( | 547 top_sites->GetMostVisitedURLs( |
| 530 base::Bind(&JumpList::OnMostVisitedURLsAvailable, | 548 base::Bind(&JumpList::OnMostVisitedURLsAvailable, |
| 531 weak_ptr_factory_.GetWeakPtr()), | 549 weak_ptr_factory_.GetWeakPtr()), |
| 532 false); | 550 false); |
| 533 } | 551 } |
| 534 } | 552 } |
| 535 | 553 |
| 536 void JumpList::DeferredTabRestoreServiceChanged() { | 554 void JumpList::DeferredTabRestoreServiceChanged() { |
| 555 if (updates_to_skip_ > 0) { |
| 556 --updates_to_skip_; |
| 557 return; |
| 558 } |
| 559 |
| 537 // Create a list of ShellLinkItems from the "Recently Closed" pages. | 560 // Create a list of ShellLinkItems from the "Recently Closed" pages. |
| 538 // As noted above, we create a ShellLinkItem objects with the following | 561 // As noted above, we create a ShellLinkItem objects with the following |
| 539 // parameters. | 562 // parameters. |
| 540 // * arguments | 563 // * arguments |
| 541 // The last URL of the tab object. | 564 // The last URL of the tab object. |
| 542 // * title | 565 // * title |
| 543 // The title of the last URL. | 566 // The title of the last URL. |
| 544 // * icon | 567 // * icon |
| 545 // An empty string. This value is to be updated in OnFaviconDataAvailable(). | 568 // An empty string. This value is to be updated in OnFaviconDataAvailable(). |
| 546 const int kRecentlyClosedCount = 3; | 569 const int kRecentlyClosedCount = 3; |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 612 | 635 |
| 613 JumpListUpdater jumplist_updater(app_id); | 636 JumpListUpdater jumplist_updater(app_id); |
| 614 | 637 |
| 615 base::ElapsedTimer begin_update_timer; | 638 base::ElapsedTimer begin_update_timer; |
| 616 | 639 |
| 617 if (!jumplist_updater.BeginUpdate()) | 640 if (!jumplist_updater.BeginUpdate()) |
| 618 return false; | 641 return false; |
| 619 | 642 |
| 620 // Discard this JumpList update if JumpListUpdater::BeginUpdate takes longer | 643 // Discard this JumpList update if JumpListUpdater::BeginUpdate takes longer |
| 621 // than the maximum allowed time, as it's very likely the following update | 644 // than the maximum allowed time, as it's very likely the following update |
| 622 // steps will also take a long time. | 645 // steps will also take a long time. As we've not updated the icons on the |
| 623 if (begin_update_timer.Elapsed() >= kTimeOutForJumplistUpdate) | 646 // disk, discarding this update wont't affect the current JumpList used by OS. |
| 647 if (begin_update_timer.Elapsed() >= kTimeOutForJumplistBeginUpdate) { |
| 648 updates_to_skip_ = kUpdatesToSkipUnderHeavyLoad; |
| 624 return false; | 649 return false; |
| 650 } |
| 625 | 651 |
| 626 // The default maximum number of items to display in JumpList is 10. | 652 // The default maximum number of items to display in JumpList is 10. |
| 627 // https://msdn.microsoft.com/library/windows/desktop/dd378398.aspx | 653 // https://msdn.microsoft.com/library/windows/desktop/dd378398.aspx |
| 628 // The "Most visited" category title always takes 1 of the JumpList slots if | 654 // The "Most visited" category title always takes 1 of the JumpList slots if |
| 629 // |most_visited_pages| isn't empty. | 655 // |most_visited_pages| isn't empty. |
| 630 // The "Recently closed" category title will also take 1 if | 656 // The "Recently closed" category title will also take 1 if |
| 631 // |recently_closed_pages| isn't empty. | 657 // |recently_closed_pages| isn't empty. |
| 632 // For the remaining slots, we allocate 5/8 (i.e., 5 slots if both categories | 658 // For the remaining slots, we allocate 5/8 (i.e., 5 slots if both categories |
| 633 // present) to "most-visited" items and 3/8 (i.e., 3 slots if both categories | 659 // present) to "most-visited" items and 3/8 (i.e., 3 slots if both categories |
| 634 // present) to "recently-closed" items, respectively. | 660 // present) to "recently-closed" items, respectively. |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 679 icons_to_create += | 705 icons_to_create += |
| 680 std::min(recently_closed_pages.size(), recently_closed_items); | 706 std::min(recently_closed_pages.size(), recently_closed_items); |
| 681 } | 707 } |
| 682 | 708 |
| 683 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407. | 709 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407. |
| 684 UMA_HISTOGRAM_COUNTS_100("WinJumplist.CreateIconFilesCount", icons_to_create); | 710 UMA_HISTOGRAM_COUNTS_100("WinJumplist.CreateIconFilesCount", icons_to_create); |
| 685 | 711 |
| 686 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407. | 712 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407. |
| 687 SCOPED_UMA_HISTOGRAM_TIMER("WinJumplist.UpdateJumpListDuration"); | 713 SCOPED_UMA_HISTOGRAM_TIMER("WinJumplist.UpdateJumpListDuration"); |
| 688 | 714 |
| 715 base::ElapsedTimer add_custom_category_timer; |
| 716 |
| 689 // Update the "Most Visited" category of the JumpList if it exists. | 717 // Update the "Most Visited" category of the JumpList if it exists. |
| 690 // This update request is applied into the JumpList when we commit this | 718 // This update request is applied into the JumpList when we commit this |
| 691 // transaction. | 719 // transaction. |
| 692 if (!jumplist_updater.AddCustomCategory( | 720 if (!jumplist_updater.AddCustomCategory( |
| 693 l10n_util::GetStringUTF16(IDS_NEW_TAB_MOST_VISITED), | 721 l10n_util::GetStringUTF16(IDS_NEW_TAB_MOST_VISITED), |
| 694 most_visited_pages, most_visited_items)) { | 722 most_visited_pages, most_visited_items)) { |
| 695 return false; | 723 return false; |
| 696 } | 724 } |
| 697 | 725 |
| 698 // Update the "Recently Closed" category of the JumpList. | 726 // Update the "Recently Closed" category of the JumpList. |
| 699 if (!jumplist_updater.AddCustomCategory( | 727 if (!jumplist_updater.AddCustomCategory( |
| 700 l10n_util::GetStringUTF16(IDS_RECENTLY_CLOSED), recently_closed_pages, | 728 l10n_util::GetStringUTF16(IDS_RECENTLY_CLOSED), recently_closed_pages, |
| 701 recently_closed_items)) { | 729 recently_closed_items)) { |
| 702 return false; | 730 return false; |
| 703 } | 731 } |
| 704 | 732 |
| 733 // If JumpListUpdater::AddCustomCategory or JumpListUpdater::CommitUpdate |
| 734 // takes longer than the maximum allowed time, skip the next |
| 735 // |kUpdatesToSkipUnderHeavyLoad| updates. This update should be finished |
| 736 // because we've already updated the icons on the disk. If discarding this |
| 737 // update from here, some items in the current JumpList may not have icons |
| 738 // as they've been delete from the disk. In this case, the background color of |
| 739 // the JumpList panel is used instead, which doesn't look nice. |
| 740 |
| 741 if (add_custom_category_timer.Elapsed() >= kTimeOutForAddCustomCategory) |
| 742 updates_to_skip_ = kUpdatesToSkipUnderHeavyLoad; |
| 743 |
| 705 // Update the "Tasks" category of the JumpList. | 744 // Update the "Tasks" category of the JumpList. |
| 706 if (!UpdateTaskCategory(&jumplist_updater, incognito_availability)) | 745 if (!UpdateTaskCategory(&jumplist_updater, incognito_availability)) |
| 707 return false; | 746 return false; |
| 708 | 747 |
| 748 base::ElapsedTimer commit_update_timer; |
| 749 |
| 709 // Commit this transaction and send the updated JumpList to Windows. | 750 // Commit this transaction and send the updated JumpList to Windows. |
| 710 return jumplist_updater.CommitUpdate(); | 751 bool commit_result = jumplist_updater.CommitUpdate(); |
| 752 |
| 753 if (commit_update_timer.Elapsed() >= kTimeOutForJumplistCommitUpdate) |
| 754 updates_to_skip_ = kUpdatesToSkipUnderHeavyLoad; |
| 755 |
| 756 return commit_result; |
| 711 } | 757 } |
| 712 | 758 |
| 713 void JumpList::RunUpdateJumpList( | 759 void JumpList::RunUpdateJumpList( |
| 714 IncognitoModePrefs::Availability incognito_availability, | 760 IncognitoModePrefs::Availability incognito_availability, |
| 715 const base::string16& app_id, | 761 const base::string16& app_id, |
| 716 const base::FilePath& profile_dir, | 762 const base::FilePath& profile_dir, |
| 717 base::RefCountedData<JumpListData>* ref_counted_data) { | 763 base::RefCountedData<JumpListData>* ref_counted_data) { |
| 718 JumpListData* data = &ref_counted_data->data; | 764 JumpListData* data = &ref_counted_data->data; |
| 719 ShellLinkItemList local_most_visited_pages; | 765 ShellLinkItemList local_most_visited_pages; |
| 720 ShellLinkItemList local_recently_closed_pages; | 766 ShellLinkItemList local_recently_closed_pages; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 751 app_id, profile_dir, local_most_visited_pages, | 797 app_id, profile_dir, local_most_visited_pages, |
| 752 local_recently_closed_pages, most_visited_pages_have_updates, | 798 local_recently_closed_pages, most_visited_pages_have_updates, |
| 753 recently_closed_pages_have_updates, incognito_availability)) { | 799 recently_closed_pages_have_updates, incognito_availability)) { |
| 754 base::AutoLock auto_lock(data->list_lock_); | 800 base::AutoLock auto_lock(data->list_lock_); |
| 755 if (most_visited_pages_have_updates) | 801 if (most_visited_pages_have_updates) |
| 756 data->most_visited_pages_have_updates_ = true; | 802 data->most_visited_pages_have_updates_ = true; |
| 757 if (recently_closed_pages_have_updates) | 803 if (recently_closed_pages_have_updates) |
| 758 data->recently_closed_pages_have_updates_ = true; | 804 data->recently_closed_pages_have_updates_ = true; |
| 759 } | 805 } |
| 760 } | 806 } |
| OLD | NEW |