Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(14)

Side by Side Diff: chrome/browser/win/jumplist.cc

Issue 2941323002: Delete the right JumpList icons conditional on shell notification (Closed)
Patch Set: Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« chrome/browser/win/jumplist.h ('K') | « chrome/browser/win/jumplist.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 #include "url/gurl.h" 54 #include "url/gurl.h"
55 55
56 namespace { 56 namespace {
57 57
58 // The default maximum number of items to display in JumpList is 10. 58 // The default maximum number of items to display in JumpList is 10.
59 // https://msdn.microsoft.com/library/windows/desktop/dd378398.aspx 59 // https://msdn.microsoft.com/library/windows/desktop/dd378398.aspx
60 // The "Most visited" and "Recently closed" category titles always take 2 slots. 60 // The "Most visited" and "Recently closed" category titles always take 2 slots.
61 // For the remaining 8 slots, we allocate 5 slots to "most-visited" items and 3 61 // For the remaining 8 slots, we allocate 5 slots to "most-visited" items and 3
62 // slots to "recently-closed" items, respectively. 62 // slots to "recently-closed" items, respectively.
63 constexpr size_t kMostVisitedItems = 5; 63 constexpr size_t kMostVisitedItems = 5;
64 constexpr size_t kRecentlyClosedItems = 3; 64 constexpr size_t kRecentClosedItems = 3;
65 65
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 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 // * arguments 369 // * arguments
370 // The last URL of the tab object. 370 // The last URL of the tab object.
371 // * title 371 // * title
372 // The title of the last URL. 372 // The title of the last URL.
373 // * icon 373 // * icon
374 // An empty string. This value is to be updated in OnFaviconDataAvailable(). 374 // An empty string. This value is to be updated in OnFaviconDataAvailable().
375 375
376 sessions::TabRestoreService* tab_restore_service = 376 sessions::TabRestoreService* tab_restore_service =
377 TabRestoreServiceFactory::GetForProfile(profile_); 377 TabRestoreServiceFactory::GetForProfile(profile_);
378 378
379 recently_closed_pages_.clear(); 379 recent_closed_pages_.clear();
380 380
381 for (const auto& entry : tab_restore_service->entries()) { 381 for (const auto& entry : tab_restore_service->entries()) {
382 if (recently_closed_pages_.size() >= kRecentlyClosedItems) 382 if (recent_closed_pages_.size() >= kRecentClosedItems)
383 break; 383 break;
384 switch (entry->type) { 384 switch (entry->type) {
385 case sessions::TabRestoreService::TAB: 385 case sessions::TabRestoreService::TAB:
386 AddTab(static_cast<const sessions::TabRestoreService::Tab&>(*entry), 386 AddTab(static_cast<const sessions::TabRestoreService::Tab&>(*entry),
387 kRecentlyClosedItems); 387 kRecentClosedItems);
388 break; 388 break;
389 case sessions::TabRestoreService::WINDOW: 389 case sessions::TabRestoreService::WINDOW:
390 AddWindow( 390 AddWindow(
391 static_cast<const sessions::TabRestoreService::Window&>(*entry), 391 static_cast<const sessions::TabRestoreService::Window&>(*entry),
392 kRecentlyClosedItems); 392 kRecentClosedItems);
393 break; 393 break;
394 } 394 }
395 } 395 }
396 396
397 recently_closed_should_update_ = true; 397 recent_closed_should_update_ = true;
398 398
399 // Force a TopSite history sync when closing a first tab in one session. 399 // Force a TopSite history sync when closing a first tab in one session.
400 if (!has_tab_closed_) { 400 if (!has_tab_closed_) {
401 has_tab_closed_ = true; 401 has_tab_closed_ = true;
402 scoped_refptr<history::TopSites> top_sites = 402 scoped_refptr<history::TopSites> top_sites =
403 TopSitesFactory::GetForProfile(profile_); 403 TopSitesFactory::GetForProfile(profile_);
404 if (top_sites) 404 if (top_sites)
405 top_sites->SyncWithHistory(); 405 top_sites->SyncWithHistory();
406 } 406 }
407 } 407 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
440 // Send a query that retrieves the first favicon. 440 // Send a query that retrieves the first favicon.
441 StartLoadingFavicon(); 441 StartLoadingFavicon();
442 } 442 }
443 443
444 bool JumpList::AddTab(const sessions::TabRestoreService::Tab& tab, 444 bool JumpList::AddTab(const sessions::TabRestoreService::Tab& tab,
445 size_t max_items) { 445 size_t max_items) {
446 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 446 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
447 447
448 // This code adds the URL and the title strings of the given tab to the 448 // This code adds the URL and the title strings of the given tab to the
449 // JumpList variables. 449 // JumpList variables.
450 if (recently_closed_pages_.size() >= max_items) 450 if (recent_closed_pages_.size() >= max_items)
451 return false; 451 return false;
452 452
453 scoped_refptr<ShellLinkItem> link = CreateShellLink(); 453 scoped_refptr<ShellLinkItem> link = CreateShellLink();
454 const sessions::SerializedNavigationEntry& current_navigation = 454 const sessions::SerializedNavigationEntry& current_navigation =
455 tab.navigations.at(tab.current_navigation_index); 455 tab.navigations.at(tab.current_navigation_index);
456 std::string url = current_navigation.virtual_url().spec(); 456 std::string url = current_navigation.virtual_url().spec();
457 link->GetCommandLine()->AppendArgNative(base::UTF8ToUTF16(url)); 457 link->GetCommandLine()->AppendArgNative(base::UTF8ToUTF16(url));
458 link->GetCommandLine()->AppendSwitchASCII(switches::kWinJumplistAction, 458 link->GetCommandLine()->AppendSwitchASCII(switches::kWinJumplistAction,
459 jumplist::kRecentlyClosedCategory); 459 jumplist::kRecentlyClosedCategory);
460 link->set_title(current_navigation.title()); 460 link->set_title(current_navigation.title());
461 link->set_url(url); 461 link->set_url(url);
462 recently_closed_pages_.push_back(link); 462 recent_closed_pages_.push_back(link);
463 if (recently_closed_icons_.find(url) == recently_closed_icons_.end()) 463 if (recent_closed_icons_.find(url) == recent_closed_icons_.end())
464 icon_urls_.emplace_back(std::move(url), std::move(link)); 464 icon_urls_.emplace_back(std::move(url), std::move(link));
465 465
466 return true; 466 return true;
467 } 467 }
468 468
469 void JumpList::AddWindow(const sessions::TabRestoreService::Window& window, 469 void JumpList::AddWindow(const sessions::TabRestoreService::Window& window,
470 size_t max_items) { 470 size_t max_items) {
471 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 471 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
472 DCHECK(!window.tabs.empty()); 472 DCHECK(!window.tabs.empty());
473 473
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
544 update_in_progress_ = true; 544 update_in_progress_ = true;
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_recent_closed_pages = recent_closed_pages_;
555
556 bool most_visited_should_update = most_visited_should_update_;
557 bool recently_closed_should_update = recently_closed_should_update_;
558 555
559 auto update_results = base::MakeUnique<UpdateResults>(); 556 auto update_results = base::MakeUnique<UpdateResults>();
grt (UTC plus 2) 2017/06/20 10:29:18 meta comment: this object does more than just carr
chengx 2017/06/20 19:33:59 The two lists above, i.e., *_pages_, are not updat
grt (UTC plus 2) 2017/06/21 10:57:29 So they're in-out params, yes? I can see how they
chengx 2017/06/22 22:45:06 Yes, they're in-out params. I've renamed the enum
560 update_results->most_visited_icons_in_update = most_visited_icons_; 557 update_results->most_visited_icons = most_visited_icons_;
561 update_results->recently_closed_icons_in_update = recently_closed_icons_; 558 update_results->recent_closed_icons = recent_closed_icons_;
559 update_results->most_visited_icon_assoc = most_visited_icon_assoc_;
560 update_results->recent_closed_icon_assoc = recent_closed_icon_assoc_;
561 update_results->most_visited_should_update = most_visited_should_update_;
562 update_results->recent_closed_should_update = recent_closed_should_update_;
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();
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_recent_closed_pages,
573 most_visited_should_update, recently_closed_should_update,
574 incognito_availability, update_results_raw), 574 incognito_availability, update_results_raw),
575 base::Bind(&JumpList::OnRunUpdateCompletion, 575 base::Bind(&JumpList::OnRunUpdateCompletion,
576 weak_ptr_factory_.GetWeakPtr(), 576 weak_ptr_factory_.GetWeakPtr(),
577 base::Passed(std::move(update_results))))) { 577 base::Passed(std::move(update_results))))) {
578 OnRunUpdateCompletion(base::MakeUnique<UpdateResults>()); 578 OnRunUpdateCompletion(base::MakeUnique<UpdateResults>());
579 } 579 }
580 } 580 }
581 581
582 void JumpList::OnRunUpdateCompletion( 582 void JumpList::OnRunUpdateCompletion(
583 std::unique_ptr<UpdateResults> update_results) { 583 std::unique_ptr<UpdateResults> update_results) {
584 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 584 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
585 585
586 // Update JumpList member variables based on the results from the update run 586 // Update JumpList member variables based on the results from the update run
587 // just finished. 587 // just finished.
588 if (update_results->update_timeout) 588 if (update_results->update_timeout)
589 updates_to_skip_ = kUpdatesToSkipUnderHeavyLoad; 589 updates_to_skip_ = kUpdatesToSkipUnderHeavyLoad;
590 590
591 if (update_results->update_success) { 591 if (update_results->update_success) {
592 most_visited_icons_.swap(update_results->most_visited_icons_in_update); 592 if (update_results->most_visited_should_update) {
593 recently_closed_icons_.swap( 593 most_visited_icons_.swap(update_results->most_visited_icons);
594 update_results->recently_closed_icons_in_update); 594 most_visited_icon_assoc_.swap(update_results->most_visited_icon_assoc);
595 most_visited_should_update_ = false; 595 most_visited_should_update_ = false;
596 recently_closed_should_update_ = false; 596 }
597 if (update_results->recent_closed_should_update) {
598 recent_closed_icons_.swap(update_results->recent_closed_icons);
599 recent_closed_icon_assoc_.swap(update_results->recent_closed_icon_assoc);
600 recent_closed_should_update_ = false;
601 }
597 } 602 }
598 603
599 update_in_progress_ = false; 604 update_in_progress_ = false;
600 605
601 // If there is any new notification during the update run just finished, start 606 // If there is any new notification during the update run just finished, start
602 // another JumpList update. 607 // another JumpList update.
603 // Otherwise, post tasks to delete the JumpListIcons and JumpListIconsOld 608 // Otherwise, post tasks to delete the JumpListIcons and JumpListIconsOld
604 // folders as they are no longer needed. Now we have the 609 // folders as they are no longer needed. Now we have the
605 // JumpListIcons{MostVisited, RecentClosed} folders instead. 610 // JumpListIcons{MostVisited, RecentClosed} folders instead.
606 if (top_sites_has_pending_notification_ || 611 if (top_sites_has_pending_notification_ ||
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
652 pref_change_registrar_.reset(); 657 pref_change_registrar_.reset();
653 } 658 }
654 profile_ = nullptr; 659 profile_ = nullptr;
655 } 660 }
656 661
657 // static 662 // static
658 void JumpList::RunUpdateJumpList( 663 void JumpList::RunUpdateJumpList(
659 const base::string16& app_id, 664 const base::string16& app_id,
660 const base::FilePath& profile_dir, 665 const base::FilePath& profile_dir,
661 const ShellLinkItemList& most_visited_pages, 666 const ShellLinkItemList& most_visited_pages,
662 const ShellLinkItemList& recently_closed_pages, 667 const ShellLinkItemList& recent_closed_pages,
663 bool most_visited_should_update,
664 bool recently_closed_should_update,
665 IncognitoModePrefs::Availability incognito_availability, 668 IncognitoModePrefs::Availability incognito_availability,
666 UpdateResults* update_results) { 669 UpdateResults* update_results) {
667 if (!JumpListUpdater::IsEnabled()) 670 if (!JumpListUpdater::IsEnabled())
668 return; 671 return;
669 672
670 DCHECK(update_results); 673 DCHECK(update_results);
671 674
672 JumpListUpdater jumplist_updater(app_id); 675 JumpListUpdater jumplist_updater(app_id);
673 676
674 base::ElapsedTimer begin_update_timer; 677 base::ElapsedTimer begin_update_timer;
675 678
676 if (!jumplist_updater.BeginUpdate()) 679 if (!jumplist_updater.BeginUpdate())
677 return; 680 return;
678 681
679 // Discard this JumpList update if JumpListUpdater::BeginUpdate takes longer 682 // Discard this JumpList update if JumpListUpdater::BeginUpdate takes longer
680 // than the maximum allowed time, as it's very likely the following update 683 // 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 684 // 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. 685 // disk, discarding this update wont't affect the current JumpList used by OS.
683 if (begin_update_timer.Elapsed() >= kTimeOutForJumplistBeginUpdate) { 686 if (begin_update_timer.Elapsed() >= kTimeOutForBeginUpdate) {
684 update_results->update_timeout = true; 687 update_results->update_timeout = true;
685 return; 688 return;
686 } 689 }
687 690
688 // Record the desired number of icons created in this JumpList update. 691 // Record the desired number of icons created in this JumpList update.
689 int icons_created = 0; 692 int icons_created = 0;
690 693
694 URLIconCache most_visited_icons_next;
695 URLIconCache recent_closed_icons_next;
696
697 base::FilePath most_visited_icon_dir = GenerateJumplistIconDirName(
698 profile_dir, FILE_PATH_LITERAL("MostVisited"));
699 base::FilePath recent_closed_icon_dir = GenerateJumplistIconDirName(
700 profile_dir, FILE_PATH_LITERAL("RecentClosed"));
701
691 // Update the icons for "Most Visisted" category of the JumpList if needed. 702 // Update the icons for "Most Visisted" category of the JumpList if needed.
692 if (most_visited_should_update) { 703 if (update_results->most_visited_should_update) {
693 base::FilePath icon_dir_most_visited = GenerateJumplistIconDirName( 704 icons_created += SafeCreateIconFiles(
694 profile_dir, FILE_PATH_LITERAL("MostVisited")); 705 most_visited_icon_dir, most_visited_pages, kMostVisitedItems,
695 706 &update_results->most_visited_icon_assoc,
696 icons_created += UpdateIconFiles( 707 &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 } 708 }
700 709
701 // Update the icons for "Recently Closed" category of the JumpList if needed. 710 // Update the icons for "Recently Closed" category of the JumpList if needed.
702 if (recently_closed_should_update) { 711 if (update_results->recent_closed_should_update) {
703 base::FilePath icon_dir_recent_closed = GenerateJumplistIconDirName( 712 icons_created += SafeCreateIconFiles(
704 profile_dir, FILE_PATH_LITERAL("RecentClosed")); 713 recent_closed_icon_dir, recent_closed_pages, kRecentClosedItems,
705 714 &update_results->recent_closed_icon_assoc,
706 icons_created += UpdateIconFiles( 715 &update_results->recent_closed_icons, &recent_closed_icons_next);
707 icon_dir_recent_closed, recently_closed_pages, kRecentlyClosedItems,
708 &update_results->recently_closed_icons_in_update);
709 } 716 }
710 717
711 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407. 718 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407.
712 UMA_HISTOGRAM_COUNTS_100("WinJumplist.CreateIconFilesCount", icons_created); 719 UMA_HISTOGRAM_COUNTS_100("WinJumplist.CreateIconFilesCount", icons_created);
713 720
714 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407. 721 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407.
715 SCOPED_UMA_HISTOGRAM_TIMER("WinJumplist.UpdateJumpListDuration"); 722 SCOPED_UMA_HISTOGRAM_TIMER("WinJumplist.UpdateJumpListDuration");
716 723
717 base::ElapsedTimer add_custom_category_timer; 724 base::ElapsedTimer add_custom_category_timer;
718 725
719 // Update the "Most Visited" category of the JumpList if it exists. 726 // Update the JumpList categories. This update request is applied into the
720 // This update request is applied into the JumpList when we commit this 727 // JumpList when we commit this transaction.
721 // transaction. 728 bool add_category_success =
722 if (!jumplist_updater.AddCustomCategory( 729 jumplist_updater.AddCustomCategory(
723 l10n_util::GetStringUTF16(IDS_NEW_TAB_MOST_VISITED), 730 l10n_util::GetStringUTF16(IDS_NEW_TAB_MOST_VISITED),
724 most_visited_pages, kMostVisitedItems)) { 731 most_visited_pages, kMostVisitedItems) &&
732 jumplist_updater.AddCustomCategory(
733 l10n_util::GetStringUTF16(IDS_RECENTLY_CLOSED), recent_closed_pages,
734 kRecentClosedItems);
735
736 // If AddCustomCategory call takes longer than the maximum allowed time, abort
737 // the current update and skip the next |kUpdatesToSkipUnderHeavyLoad|
738 // updates.
739 bool timeout = add_custom_category_timer.Elapsed() >= kTimeOutForAddCategory;
740 if (timeout)
741 update_results->update_timeout = true;
742
743 if (!add_category_success || timeout) {
744 DeleteIconFilesUnified(most_visited_icon_dir, recent_closed_icon_dir,
745 update_results, JumpListVersion::kNext);
725 return; 746 return;
726 } 747 }
727 748
728 // Update the "Recently Closed" category of the JumpList. 749 // Update the "Tasks" category of the JumpList.
729 if (!jumplist_updater.AddCustomCategory( 750 if (!UpdateTaskCategory(&jumplist_updater, incognito_availability)) {
730 l10n_util::GetStringUTF16(IDS_RECENTLY_CLOSED), recently_closed_pages, 751 DeleteIconFilesUnified(most_visited_icon_dir, recent_closed_icon_dir,
731 kRecentlyClosedItems)) { 752 update_results, JumpListVersion::kNext);
732 return; 753 return;
733 } 754 }
734 755
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; 756 base::ElapsedTimer commit_update_timer;
751 757
752 // Commit this transaction and send the updated JumpList to Windows. 758 // Commit this transaction and send the updated JumpList to Windows.
753 if (jumplist_updater.CommitUpdate()) 759 bool commit_success = jumplist_updater.CommitUpdate();
760
761 // If CommitUpdate call takes longer than the maximum allowed time, abort the
762 // current update and skip the next |kUpdatesToSkipUnderHeavyLoad| updates.
763 if (commit_update_timer.Elapsed() >= kTimeOutForCommitUpdate)
764 update_results->update_timeout = true;
765
766 if (commit_success) {
754 update_results->update_success = true; 767 update_results->update_success = true;
768 if (update_results->most_visited_should_update)
769 update_results->most_visited_icons.swap(most_visited_icons_next);
770 if (update_results->recent_closed_should_update)
771 update_results->recent_closed_icons.swap(recent_closed_icons_next);
772 }
755 773
756 if (commit_update_timer.Elapsed() >= kTimeOutForJumplistCommitUpdate) 774 // Delete the set of icons based on commit status.
757 update_results->update_timeout = true; 775 JumpListVersion version =
776 commit_success ? JumpListVersion::kCurrent : JumpListVersion::kNext;
777
778 DeleteIconFilesUnified(most_visited_icon_dir, recent_closed_icon_dir,
779 update_results, version);
758 } 780 }
759 781
760 // static 782 // static
761 int JumpList::UpdateIconFiles(const base::FilePath& icon_dir, 783 int JumpList::SafeCreateIconFiles(const base::FilePath& icon_dir,
762 const ShellLinkItemList& page_list, 784 const ShellLinkItemList& page_list,
763 size_t slot_limit, 785 size_t slot_limit,
764 URLIconCache* icon_cache) { 786 IconAssociation* icon_assoc,
787 URLIconCache* icon_cur,
788 URLIconCache* icon_next) {
789 DCHECK(icon_assoc);
790 DCHECK(icon_cur);
791 DCHECK(icon_next);
792
765 int icons_created = 0; 793 int icons_created = 0;
766 794
767 // Clear the JumpList icon folder at |icon_dir| and the cache when 795 // 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 796 // 1) |icon_cur| is empty. This happens when "Most visited" or "Recently
769 // closed" category updates for the 1st time after Chrome is launched. 797 // closed" category updates for the 1st time after Chrome is launched.
770 // 2) The number of icons in |icon_dir| has exceeded the limit. 798 // 2) The number of icons in |icon_dir| has exceeded the limit.
771 if (icon_cache->empty() || FilesExceedLimitInDir(icon_dir, slot_limit * 2)) { 799 if (icon_cur->empty() || FilesExceedLimitInDir(icon_dir, slot_limit * 2)) {
772 DeleteDirectoryContentAndLogRuntime(icon_dir, kFileDeleteLimit); 800 DeleteDirectoryContentAndLogRuntime(icon_dir, kFileDeleteLimit);
773 icon_cache->clear(); 801 icon_assoc->clear();
802 icon_cur->clear();
803 icon_next->clear();
804
774 // Create new icons only when the directory exists and is empty. 805 // Create new icons only when the directory exists and is empty.
775 if (base::CreateDirectory(icon_dir) && base::IsDirectoryEmpty(icon_dir)) 806 if (base::CreateDirectory(icon_dir) && base::IsDirectoryEmpty(icon_dir)) {
776 icons_created += 807 icons_created += CreateIconFiles(icon_dir, page_list, slot_limit,
777 CreateIconFiles(icon_dir, page_list, slot_limit, icon_cache); 808 icon_assoc, icon_cur, icon_next);
809 }
778 } else if (base::CreateDirectory(icon_dir)) { 810 } else if (base::CreateDirectory(icon_dir)) {
779 icons_created += 811 icons_created += CreateIconFiles(icon_dir, page_list, slot_limit,
780 CreateIconFiles(icon_dir, page_list, slot_limit, icon_cache); 812 icon_assoc, icon_cur, icon_next);
781 DeleteIconFiles(icon_dir, icon_cache);
782 } 813 }
783 814
784 return icons_created; 815 return icons_created;
785 } 816 }
786 817
787 // static 818 // static
788 int JumpList::CreateIconFiles(const base::FilePath& icon_dir, 819 int JumpList::CreateIconFiles(const base::FilePath& icon_dir,
789 const ShellLinkItemList& item_list, 820 const ShellLinkItemList& item_list,
790 size_t max_items, 821 size_t max_items,
791 URLIconCache* icon_cache) { 822 IconAssociation* icon_assoc,
823 URLIconCache* icon_cur,
824 URLIconCache* icon_next) {
825 DCHECK(icon_assoc);
826 DCHECK(icon_cur);
827 DCHECK(icon_next);
828
792 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407. 829 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407.
793 SCOPED_UMA_HISTOGRAM_TIMER("WinJumplist.CreateIconFilesDuration"); 830 SCOPED_UMA_HISTOGRAM_TIMER("WinJumplist.CreateIconFilesDuration");
794 831
795 int icons_created = 0; 832 int icons_created = 0;
796 833
834 // Mark all the icons kCurrent as they are used by the current JumpList.
835 for (auto iter = icon_assoc->begin(); iter != icon_assoc->end(); ++iter)
836 iter->second = JumpListVersion::kCurrent;
837
797 // Reuse icons for urls that already present in the current JumpList. 838 // Reuse icons for urls that already present in the current JumpList.
798 URLIconCache updated_map;
799 for (ShellLinkItemList::const_iterator iter = item_list.begin(); 839 for (ShellLinkItemList::const_iterator iter = item_list.begin();
800 iter != item_list.end() && max_items > 0; ++iter, --max_items) { 840 iter != item_list.end() && max_items > 0; ++iter, --max_items) {
801 ShellLinkItem* item = iter->get(); 841 ShellLinkItem* item = iter->get();
802 auto cache_iter = icon_cache->find(item->url()); 842 auto cache_iter = icon_cur->find(item->url());
803 if (cache_iter != icon_cache->end()) { 843 if (cache_iter != icon_cur->end()) {
804 item->set_icon(cache_iter->second.value(), 0); 844 item->set_icon(cache_iter->second.value(), 0);
805 updated_map[item->url()] = cache_iter->second; 845 (*icon_next)[item->url()] = cache_iter->second;
846 (*icon_assoc)[cache_iter->second] = JumpListVersion::kShared;
806 } else { 847 } else {
807 base::FilePath icon_path; 848 base::FilePath icon_path;
808 if (CreateIconFile(item->icon_image(), icon_dir, &icon_path)) { 849 if (CreateIconFile(item->icon_image(), icon_dir, &icon_path)) {
809 ++icons_created; 850 ++icons_created;
810 item->set_icon(icon_path.value(), 0); 851 item->set_icon(icon_path.value(), 0);
811 updated_map[item->url()] = icon_path; 852 (*icon_next)[item->url()] = icon_path;
853 (*icon_assoc)[icon_path] = JumpListVersion::kNext;
812 } 854 }
813 } 855 }
814 } 856 }
815 icon_cache->swap(updated_map);
816 857
817 return icons_created; 858 return icons_created;
818 } 859 }
819 860
820 // static 861 // static
862 void JumpList::DeleteIconFilesUnified(
863 const base::FilePath& most_visited_icon_dir,
864 const base::FilePath& recent_closed_icon_dir,
865 UpdateResults* update_results,
866 JumpListVersion version) {
867 DCHECK(update_results);
868
869 if (update_results->most_visited_should_update) {
870 DeleteIconFiles(most_visited_icon_dir,
871 &update_results->most_visited_icon_assoc, version);
872 }
873 if (update_results->recent_closed_should_update) {
874 DeleteIconFiles(recent_closed_icon_dir,
875 &update_results->recent_closed_icon_assoc, version);
876 }
877 }
878
879 // static
821 void JumpList::DeleteIconFiles(const base::FilePath& icon_dir, 880 void JumpList::DeleteIconFiles(const base::FilePath& icon_dir,
822 URLIconCache* icon_cache) { 881 IconAssociation* icon_assoc,
823 // Put all cached icon file paths into a set. 882 JumpListVersion version) {
883 DCHECK(icon_assoc);
884
885 IconAssociation icon_assoc_updated;
886
887 // Put paths of icon files to keep into a set.
824 base::flat_set<base::FilePath> cached_files; 888 base::flat_set<base::FilePath> cached_files;
825 cached_files.reserve(icon_cache->size()); 889 cached_files.reserve(icon_assoc->size());
826 890 for (const auto& path_version_pair : *icon_assoc) {
827 for (const auto& url_path_pair : *icon_cache) 891 if (path_version_pair.second != version) {
828 cached_files.insert(url_path_pair.second); 892 cached_files.insert(path_version_pair.first);
893 icon_assoc_updated[path_version_pair.first] = path_version_pair.second;
894 }
895 }
829 896
830 DeleteNonCachedFiles(icon_dir, cached_files); 897 DeleteNonCachedFiles(icon_dir, cached_files);
898
899 // Keep icon_assoc up-to-date after deleting obsolete icons.
900 icon_assoc->swap(icon_assoc_updated);
831 } 901 }
OLDNEW
« chrome/browser/win/jumplist.h ('K') | « chrome/browser/win/jumplist.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698