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

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

Issue 2941323002: Delete the right JumpList icons conditional on shell notification (Closed)
Patch Set: Address comments, record timeout info for failed steps in shell notification 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
« no previous file with comments | « 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 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 kTimeOutForJumplistBeginUpdate =
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 the "most visited" category via
80 // closed" categories via JumpListUpdater::AddCustomCategory. 80 // JumpListUpdater::AddCustomCategory.
81 constexpr base::TimeDelta kTimeOutForAddCustomCategory = 81 constexpr base::TimeDelta kTimeOutForAddCustomCategory =
82 base::TimeDelta::FromMilliseconds(500); 82 base::TimeDelta::FromMilliseconds(300);
grt (UTC plus 2) 2017/06/24 20:40:28 is this change worth mentioning in the CL descript
chengx 2017/06/25 02:32:09 Originally we were monitoring the total runtime of
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 kTimeOutForJumplistCommitUpdate =
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();
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 base::FilePath GenerateJumplistIconDirName( 187 base::FilePath GenerateJumplistIconDirName(
188 const base::FilePath& profile_dir, 188 const base::FilePath& profile_dir,
189 const base::FilePath::StringPieceType& suffix) { 189 const base::FilePath::StringPieceType& suffix) {
190 base::FilePath::StringType dir_name(chrome::kJumpListIconDirname); 190 base::FilePath::StringType dir_name(chrome::kJumpListIconDirname);
191 suffix.AppendToString(&dir_name); 191 suffix.AppendToString(&dir_name);
192 return profile_dir.Append(dir_name); 192 return profile_dir.Append(dir_name);
193 } 193 }
194 194
195 } // namespace 195 } // namespace
196 196
197 JumpList::UpdateResults::UpdateResults() {} 197 JumpList::UpdateTransaction::UpdateTransaction() {}
198 198
199 JumpList::UpdateResults::~UpdateResults() {} 199 JumpList::UpdateTransaction::~UpdateTransaction() {}
200 200
201 // static 201 // static
202 bool JumpList::Enabled() { 202 bool JumpList::Enabled() {
203 return JumpListUpdater::IsEnabled(); 203 return JumpListUpdater::IsEnabled();
204 } 204 }
205 205
206 void JumpList::Shutdown() { 206 void JumpList::Shutdown() {
207 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 207 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
208 Terminate(); 208 Terminate();
209 } 209 }
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 sessions::TabRestoreService* service) {} 299 sessions::TabRestoreService* service) {}
300 300
301 void JumpList::OnIncognitoAvailabilityChanged() { 301 void JumpList::OnIncognitoAvailabilityChanged() {
302 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 302 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
303 303
304 if (icon_urls_.empty()) 304 if (icon_urls_.empty())
305 PostRunUpdate(); 305 PostRunUpdate();
306 } 306 }
307 307
308 void JumpList::InitializeTimerForUpdate() { 308 void JumpList::InitializeTimerForUpdate() {
309 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
310
309 if (timer_.IsRunning()) { 311 if (timer_.IsRunning()) {
310 timer_.Reset(); 312 timer_.Reset();
311 } else { 313 } else {
312 // base::Unretained is safe since |this| is guaranteed to outlive timer_. 314 // base::Unretained is safe since |this| is guaranteed to outlive timer_.
313 timer_.Start(FROM_HERE, kDelayForJumplistUpdate, 315 timer_.Start(FROM_HERE, kDelayForJumplistUpdate,
314 base::Bind(&JumpList::OnDelayTimer, base::Unretained(this))); 316 base::Bind(&JumpList::OnDelayTimer, base::Unretained(this)));
315 } 317 }
316 } 318 }
317 319
318 void JumpList::OnDelayTimer() { 320 void JumpList::OnDelayTimer() {
319 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 321 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
322 DCHECK(!update_in_progress_);
320 323
321 if (updates_to_skip_ > 0) { 324 if (updates_to_skip_ > 0) {
322 --updates_to_skip_; 325 --updates_to_skip_;
323 return; 326 return;
324 } 327 }
325 328
326 // Retrieve the recently closed URLs synchronously. 329 // Retrieve the recently closed URLs synchronously.
327 if (tab_restore_has_pending_notification_) { 330 if (tab_restore_has_pending_notification_) {
328 tab_restore_has_pending_notification_ = false; 331 tab_restore_has_pending_notification_ = false;
329 ProcessTabRestoreServiceNotification(); 332 ProcessTabRestoreServiceNotification();
330 } 333 }
331 334
332 // If TopSites has updates, retrieve the URLs asynchronously, and on its 335 // If TopSites has updates, retrieve the URLs asynchronously, and on its
333 // completion, trigger favicon loading. 336 // completion, trigger favicon loading.
334 // Otherwise, call StartLoadingFavicon directly to start favicon loading. 337 // Otherwise, call StartLoadingFavicon directly to start favicon loading.
335 if (top_sites_has_pending_notification_) 338 if (top_sites_has_pending_notification_)
336 ProcessTopSitesNotification(); 339 ProcessTopSitesNotification();
337 else 340 else
338 StartLoadingFavicon(); 341 StartLoadingFavicon();
339 } 342 }
340 343
341 void JumpList::ProcessTopSitesNotification() { 344 void JumpList::ProcessTopSitesNotification() {
342 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 345 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
346 DCHECK(!update_in_progress_);
343 347
344 // Opening the first tab in one session triggers a TopSite history sync. 348 // Opening the first tab in one session triggers a TopSite history sync.
345 // Delay this sync till the first tab is closed to allow the "recently closed" 349 // Delay this sync till the first tab is closed to allow the "recently closed"
346 // category from last session to stay longer. All previous pending 350 // category from last session to stay longer. All previous pending
347 // notifications from TopSites are ignored. 351 // notifications from TopSites are ignored.
348 if (!has_tab_closed_) { 352 if (!has_tab_closed_) {
349 top_sites_has_pending_notification_ = false; 353 top_sites_has_pending_notification_ = false;
350 return; 354 return;
351 } 355 }
352 356
353 scoped_refptr<history::TopSites> top_sites = 357 scoped_refptr<history::TopSites> top_sites =
354 TopSitesFactory::GetForProfile(profile_); 358 TopSitesFactory::GetForProfile(profile_);
355 if (top_sites) { 359 if (top_sites) {
356 top_sites->GetMostVisitedURLs( 360 top_sites->GetMostVisitedURLs(
357 base::Bind(&JumpList::OnMostVisitedURLsAvailable, 361 base::Bind(&JumpList::OnMostVisitedURLsAvailable,
358 weak_ptr_factory_.GetWeakPtr()), 362 weak_ptr_factory_.GetWeakPtr()),
359 false); 363 false);
360 } 364 }
361 } 365 }
362 366
363 void JumpList::ProcessTabRestoreServiceNotification() { 367 void JumpList::ProcessTabRestoreServiceNotification() {
364 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 368 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
369 DCHECK(!update_in_progress_);
365 370
366 // Create a list of ShellLinkItems from the "Recently Closed" pages. 371 // Create a list of ShellLinkItems from the "Recently Closed" pages.
367 // As noted above, we create a ShellLinkItem objects with the following 372 // As noted above, we create a ShellLinkItem objects with the following
368 // parameters. 373 // parameters.
369 // * arguments 374 // * arguments
370 // The last URL of the tab object. 375 // The last URL of the tab object.
371 // * title 376 // * title
372 // The title of the last URL. 377 // The title of the last URL.
373 // * icon 378 // * icon
374 // An empty string. This value is to be updated in OnFaviconDataAvailable(). 379 // An empty string. This value is to be updated in OnFaviconDataAvailable().
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
545 550
546 base::FilePath profile_dir = profile_->GetPath(); 551 base::FilePath profile_dir = profile_->GetPath();
547 552
548 // Check if incognito windows (or normal windows) are disabled by policy. 553 // Check if incognito windows (or normal windows) are disabled by policy.
549 IncognitoModePrefs::Availability incognito_availability = 554 IncognitoModePrefs::Availability incognito_availability =
550 IncognitoModePrefs::GetAvailability(profile_->GetPrefs()); 555 IncognitoModePrefs::GetAvailability(profile_->GetPrefs());
551 556
552 // Make local copies of JumpList member variables and use them for an update. 557 // Make local copies of JumpList member variables and use them for an update.
553 ShellLinkItemList local_most_visited_pages = most_visited_pages_; 558 ShellLinkItemList local_most_visited_pages = most_visited_pages_;
554 ShellLinkItemList local_recently_closed_pages = recently_closed_pages_; 559 ShellLinkItemList local_recently_closed_pages = recently_closed_pages_;
555
556 bool most_visited_should_update = most_visited_should_update_; 560 bool most_visited_should_update = most_visited_should_update_;
557 bool recently_closed_should_update = recently_closed_should_update_; 561 bool recently_closed_should_update = recently_closed_should_update_;
558 562
559 auto update_results = base::MakeUnique<UpdateResults>(); 563 auto update_transaction = base::MakeUnique<UpdateTransaction>();
560 update_results->most_visited_icons_in_update = most_visited_icons_; 564 update_transaction->most_visited_icons = most_visited_icons_;
561 update_results->recently_closed_icons_in_update = recently_closed_icons_; 565 update_transaction->recently_closed_icons = recently_closed_icons_;
562 566
563 // Parameter evaluation order is unspecified in C++. Ensure the pointer value 567 // Parameter evaluation order is unspecified in C++. Do the first bind and
564 // is obtained before base::Passed() is called. 568 // then move it into PostTaskAndReply to ensure the pointer value is obtained
565 auto* update_results_raw = update_results.get(); 569 // before base::Passed() is called.
570 auto run_update =
571 base::Bind(&JumpList::RunUpdateJumpList, app_id_, profile_dir,
572 local_most_visited_pages, local_recently_closed_pages,
573 most_visited_should_update, recently_closed_should_update,
574 incognito_availability, update_transaction.get());
566 575
567 // Post a task to update the JumpList, which consists of 1) create new icons, 576 // Post a task to update the JumpList, which consists of 1) create new icons,
568 // 2) delete old icons, 3) notify the OS. 577 // 2) notify the OS, 3) delete old icons.
569 if (!update_jumplist_task_runner_->PostTaskAndReply( 578 if (!update_jumplist_task_runner_->PostTaskAndReply(
570 FROM_HERE, 579 FROM_HERE, std::move(run_update),
571 base::Bind(&JumpList::RunUpdateJumpList, app_id_, profile_dir,
572 local_most_visited_pages, local_recently_closed_pages,
573 most_visited_should_update, recently_closed_should_update,
574 incognito_availability, update_results_raw),
575 base::Bind(&JumpList::OnRunUpdateCompletion, 580 base::Bind(&JumpList::OnRunUpdateCompletion,
576 weak_ptr_factory_.GetWeakPtr(), 581 weak_ptr_factory_.GetWeakPtr(),
577 base::Passed(std::move(update_results))))) { 582 base::Passed(std::move(update_transaction))))) {
578 OnRunUpdateCompletion(base::MakeUnique<UpdateResults>()); 583 OnRunUpdateCompletion(base::MakeUnique<UpdateTransaction>());
579 } 584 }
580 } 585 }
581 586
582 void JumpList::OnRunUpdateCompletion( 587 void JumpList::OnRunUpdateCompletion(
583 std::unique_ptr<UpdateResults> update_results) { 588 std::unique_ptr<UpdateTransaction> update_transaction) {
584 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 589 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
585 590
586 // Update JumpList member variables based on the results from the update run 591 // Update JumpList member variables based on the results from the update run
587 // just finished. 592 // just finished.
588 if (update_results->update_timeout) 593 if (update_transaction->update_timeout)
589 updates_to_skip_ = kUpdatesToSkipUnderHeavyLoad; 594 updates_to_skip_ = kUpdatesToSkipUnderHeavyLoad;
590 595
591 if (update_results->update_success) { 596 if (update_transaction->update_success) {
592 most_visited_icons_.swap(update_results->most_visited_icons_in_update); 597 if (most_visited_should_update_) {
593 recently_closed_icons_.swap( 598 most_visited_icons_ = std::move(update_transaction->most_visited_icons);
594 update_results->recently_closed_icons_in_update); 599 most_visited_should_update_ = false;
595 most_visited_should_update_ = false; 600 }
596 recently_closed_should_update_ = false; 601 if (recently_closed_should_update_) {
602 recently_closed_icons_ =
603 std::move(update_transaction->recently_closed_icons);
604 recently_closed_should_update_ = false;
605 }
597 } 606 }
598 607
599 update_in_progress_ = false; 608 update_in_progress_ = false;
600 609
601 // If there is any new notification during the update run just finished, start 610 // If there is any new notification during the update run just finished, start
602 // another JumpList update. 611 // another JumpList update.
603 // Otherwise, post tasks to delete the JumpListIcons and JumpListIconsOld 612 // Otherwise, post tasks to delete the JumpListIcons and JumpListIconsOld
604 // folders as they are no longer needed. Now we have the 613 // folders as they are no longer needed. Now we have the
605 // JumpListIcons{MostVisited, RecentClosed} folders instead. 614 // JumpListIcons{MostVisited, RecentClosed} folders instead.
606 if (top_sites_has_pending_notification_ || 615 if (top_sites_has_pending_notification_ ||
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
656 665
657 // static 666 // static
658 void JumpList::RunUpdateJumpList( 667 void JumpList::RunUpdateJumpList(
659 const base::string16& app_id, 668 const base::string16& app_id,
660 const base::FilePath& profile_dir, 669 const base::FilePath& profile_dir,
661 const ShellLinkItemList& most_visited_pages, 670 const ShellLinkItemList& most_visited_pages,
662 const ShellLinkItemList& recently_closed_pages, 671 const ShellLinkItemList& recently_closed_pages,
663 bool most_visited_should_update, 672 bool most_visited_should_update,
664 bool recently_closed_should_update, 673 bool recently_closed_should_update,
665 IncognitoModePrefs::Availability incognito_availability, 674 IncognitoModePrefs::Availability incognito_availability,
666 UpdateResults* update_results) { 675 UpdateTransaction* update_transaction) {
667 if (!JumpListUpdater::IsEnabled()) 676 if (!JumpListUpdater::IsEnabled())
668 return; 677 return;
669 678
670 DCHECK(update_results); 679 DCHECK(update_transaction);
680
681 base::FilePath most_visited_icon_dir = GenerateJumplistIconDirName(
682 profile_dir, FILE_PATH_LITERAL("MostVisited"));
683 base::FilePath recently_closed_icon_dir = GenerateJumplistIconDirName(
684 profile_dir, FILE_PATH_LITERAL("RecentClosed"));
685
686 CreateNewJumpListAndNotifyOS(
687 app_id, most_visited_icon_dir, recently_closed_icon_dir,
688 most_visited_pages, recently_closed_pages, most_visited_should_update,
689 recently_closed_should_update, incognito_availability,
690 update_transaction);
691
692 // Delete any obsolete icon files.
693 if (most_visited_should_update) {
694 DeleteIconFiles(most_visited_icon_dir,
695 update_transaction->most_visited_icons);
696 }
697 if (recently_closed_should_update) {
698 DeleteIconFiles(recently_closed_icon_dir,
699 update_transaction->recently_closed_icons);
700 }
701 }
702
703 // static
704 void JumpList::CreateNewJumpListAndNotifyOS(
705 const base::string16& app_id,
706 const base::FilePath& most_visited_icon_dir,
707 const base::FilePath& recently_closed_icon_dir,
708 const ShellLinkItemList& most_visited_pages,
709 const ShellLinkItemList& recently_closed_pages,
710 bool most_visited_should_update,
711 bool recently_closed_should_update,
712 IncognitoModePrefs::Availability incognito_availability,
713 UpdateTransaction* update_transaction) {
714 DCHECK(update_transaction);
671 715
672 JumpListUpdater jumplist_updater(app_id); 716 JumpListUpdater jumplist_updater(app_id);
673 717
674 base::ElapsedTimer begin_update_timer; 718 base::ElapsedTimer begin_update_timer;
675 719
676 if (!jumplist_updater.BeginUpdate()) 720 bool begin_success = jumplist_updater.BeginUpdate();
677 return;
678 721
679 // Discard this JumpList update if JumpListUpdater::BeginUpdate takes longer 722 // Discard this JumpList update if JumpListUpdater::BeginUpdate takes longer
680 // than the maximum allowed time, as it's very likely the following update 723 // 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 724 // steps will also take a long time.
682 // disk, discarding this update wont't affect the current JumpList used by OS.
683 if (begin_update_timer.Elapsed() >= kTimeOutForJumplistBeginUpdate) { 725 if (begin_update_timer.Elapsed() >= kTimeOutForJumplistBeginUpdate) {
684 update_results->update_timeout = true; 726 update_transaction->update_timeout = true;
685 return; 727 return;
686 } 728 }
687 729
730 if (!begin_success)
731 return;
732
688 // Record the desired number of icons created in this JumpList update. 733 // Record the desired number of icons created in this JumpList update.
689 int icons_created = 0; 734 int icons_created = 0;
690 735
736 URLIconCache most_visited_icons_next;
737 URLIconCache recently_closed_icons_next;
738
691 // Update the icons for "Most Visisted" category of the JumpList if needed. 739 // Update the icons for "Most Visisted" category of the JumpList if needed.
692 if (most_visited_should_update) { 740 if (most_visited_should_update) {
693 base::FilePath icon_dir_most_visited = GenerateJumplistIconDirName(
694 profile_dir, FILE_PATH_LITERAL("MostVisited"));
695
696 icons_created += UpdateIconFiles( 741 icons_created += UpdateIconFiles(
697 icon_dir_most_visited, most_visited_pages, kMostVisitedItems, 742 most_visited_icon_dir, most_visited_pages, kMostVisitedItems,
698 &update_results->most_visited_icons_in_update); 743 &update_transaction->most_visited_icons, &most_visited_icons_next);
699 } 744 }
700 745
701 // Update the icons for "Recently Closed" category of the JumpList if needed. 746 // Update the icons for "Recently Closed" category of the JumpList if needed.
702 if (recently_closed_should_update) { 747 if (recently_closed_should_update) {
703 base::FilePath icon_dir_recent_closed = GenerateJumplistIconDirName(
704 profile_dir, FILE_PATH_LITERAL("RecentClosed"));
705
706 icons_created += UpdateIconFiles( 748 icons_created += UpdateIconFiles(
707 icon_dir_recent_closed, recently_closed_pages, kRecentlyClosedItems, 749 recently_closed_icon_dir, recently_closed_pages, kRecentlyClosedItems,
708 &update_results->recently_closed_icons_in_update); 750 &update_transaction->recently_closed_icons,
751 &recently_closed_icons_next);
709 } 752 }
710 753
711 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407. 754 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407.
712 UMA_HISTOGRAM_COUNTS_100("WinJumplist.CreateIconFilesCount", icons_created); 755 UMA_HISTOGRAM_COUNTS_100("WinJumplist.CreateIconFilesCount", icons_created);
713 756
714 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407. 757 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407.
715 SCOPED_UMA_HISTOGRAM_TIMER("WinJumplist.UpdateJumpListDuration"); 758 SCOPED_UMA_HISTOGRAM_TIMER("WinJumplist.UpdateJumpListDuration");
716 759
717 base::ElapsedTimer add_custom_category_timer; 760 base::ElapsedTimer add_custom_category_timer;
718 761
719 // Update the "Most Visited" category of the JumpList if it exists. 762 // Update the "Most Visited" category of the JumpList if it exists.
720 // This update request is applied into the JumpList when we commit this 763 // This update request is applied into the JumpList when we commit this
721 // transaction. 764 // transaction.
722 if (!jumplist_updater.AddCustomCategory( 765 bool add_category_success = jumplist_updater.AddCustomCategory(
723 l10n_util::GetStringUTF16(IDS_NEW_TAB_MOST_VISITED), 766 l10n_util::GetStringUTF16(IDS_NEW_TAB_MOST_VISITED), most_visited_pages,
724 most_visited_pages, kMostVisitedItems)) { 767 kMostVisitedItems);
768
769 // If AddCustomCategory takes longer than the maximum allowed time, abort the
770 // current update and skip the next |kUpdatesToSkipUnderHeavyLoad| updates.
771 if (add_custom_category_timer.Elapsed() >= kTimeOutForAddCustomCategory) {
772 update_transaction->update_timeout = true;
725 return; 773 return;
726 } 774 }
727 775
776 if (!add_category_success)
777 return;
778
728 // Update the "Recently Closed" category of the JumpList. 779 // Update the "Recently Closed" category of the JumpList.
780 // This update request is applied into the JumpList when we commit this
781 // transaction. We don't need to monitor the runtime of this AddCustomCategory
782 // call as it should be very similar to the previous one.
729 if (!jumplist_updater.AddCustomCategory( 783 if (!jumplist_updater.AddCustomCategory(
730 l10n_util::GetStringUTF16(IDS_RECENTLY_CLOSED), recently_closed_pages, 784 l10n_util::GetStringUTF16(IDS_RECENTLY_CLOSED), recently_closed_pages,
731 kRecentlyClosedItems)) { 785 kRecentlyClosedItems)) {
732 return; 786 return;
733 } 787 }
734 788
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. 789 // Update the "Tasks" category of the JumpList.
747 if (!UpdateTaskCategory(&jumplist_updater, incognito_availability)) 790 if (!UpdateTaskCategory(&jumplist_updater, incognito_availability))
748 return; 791 return;
749 792
750 base::ElapsedTimer commit_update_timer; 793 base::ElapsedTimer commit_update_timer;
751 794
752 // Commit this transaction and send the updated JumpList to Windows. 795 // Commit this transaction and send the updated JumpList to Windows.
753 if (jumplist_updater.CommitUpdate()) 796 bool commit_success = jumplist_updater.CommitUpdate();
754 update_results->update_success = true;
755 797
798 // If CommitUpdate call takes longer than the maximum allowed time, skip the
799 // next |kUpdatesToSkipUnderHeavyLoad| updates.
756 if (commit_update_timer.Elapsed() >= kTimeOutForJumplistCommitUpdate) 800 if (commit_update_timer.Elapsed() >= kTimeOutForJumplistCommitUpdate)
757 update_results->update_timeout = true; 801 update_transaction->update_timeout = true;
802
803 if (commit_success) {
804 update_transaction->update_success = true;
805
806 // The move assignments below ensure update_transaction always has the icons
807 // to keep.
808 if (most_visited_should_update) {
809 update_transaction->most_visited_icons =
810 std::move(most_visited_icons_next);
811 }
812 if (recently_closed_should_update) {
813 update_transaction->recently_closed_icons =
814 std::move(recently_closed_icons_next);
815 }
816 }
758 } 817 }
759 818
760 // static 819 // static
761 int JumpList::UpdateIconFiles(const base::FilePath& icon_dir, 820 int JumpList::UpdateIconFiles(const base::FilePath& icon_dir,
762 const ShellLinkItemList& page_list, 821 const ShellLinkItemList& item_list,
763 size_t slot_limit, 822 size_t max_items,
764 URLIconCache* icon_cache) { 823 URLIconCache* icon_cur,
824 URLIconCache* icon_next) {
825 DCHECK(icon_cur);
826 DCHECK(icon_next);
827
828 // Clear the JumpList icon folder at |icon_dir| and the caches when
829 // 1) |icon_cur| is empty. This happens when "Most visited" or "Recently
830 // closed" category updates for the 1st time after Chrome is launched.
831 // 2) The number of icons in |icon_dir| has exceeded the limit.
832 if (icon_cur->empty() || FilesExceedLimitInDir(icon_dir, max_items * 2)) {
833 DeleteDirectoryContentAndLogRuntime(icon_dir, kFileDeleteLimit);
834 icon_cur->clear();
835 icon_next->clear();
836 // Create new icons only when the directory exists and is empty.
837 if (!base::CreateDirectory(icon_dir) || !base::IsDirectoryEmpty(icon_dir))
838 return 0;
839 } else if (!base::CreateDirectory(icon_dir)) {
840 return 0;
841 }
842
843 return CreateIconFiles(icon_dir, item_list, max_items, *icon_cur, icon_next);
844 }
845
846 // static
847 int JumpList::CreateIconFiles(const base::FilePath& icon_dir,
848 const ShellLinkItemList& item_list,
849 size_t max_items,
850 const URLIconCache& icon_cur,
851 URLIconCache* icon_next) {
852 DCHECK(icon_next);
853
854 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407.
855 SCOPED_UMA_HISTOGRAM_TIMER("WinJumplist.CreateIconFilesDuration");
856
765 int icons_created = 0; 857 int icons_created = 0;
766 858
767 // Clear the JumpList icon folder at |icon_dir| and the cache when 859 // Reuse icons for urls that already present in the current JumpList.
768 // 1) |icon_cache| is empty. This happens when "Most visited" or "Recently 860 for (ShellLinkItemList::const_iterator iter = item_list.begin();
769 // closed" category updates for the 1st time after Chrome is launched. 861 iter != item_list.end() && max_items > 0; ++iter, --max_items) {
770 // 2) The number of icons in |icon_dir| has exceeded the limit. 862 ShellLinkItem* item = iter->get();
771 if (icon_cache->empty() || FilesExceedLimitInDir(icon_dir, slot_limit * 2)) { 863 auto cache_iter = icon_cur.find(item->url());
772 DeleteDirectoryContentAndLogRuntime(icon_dir, kFileDeleteLimit); 864 if (cache_iter != icon_cur.end()) {
773 icon_cache->clear(); 865 item->set_icon(cache_iter->second.value(), 0);
774 // Create new icons only when the directory exists and is empty. 866 (*icon_next)[item->url()] = cache_iter->second;
775 if (base::CreateDirectory(icon_dir) && base::IsDirectoryEmpty(icon_dir)) 867 } else {
776 icons_created += 868 base::FilePath icon_path;
777 CreateIconFiles(icon_dir, page_list, slot_limit, icon_cache); 869 if (CreateIconFile(item->icon_image(), icon_dir, &icon_path)) {
778 } else if (base::CreateDirectory(icon_dir)) { 870 ++icons_created;
779 icons_created += 871 item->set_icon(icon_path.value(), 0);
780 CreateIconFiles(icon_dir, page_list, slot_limit, icon_cache); 872 (*icon_next)[item->url()] = icon_path;
781 DeleteIconFiles(icon_dir, icon_cache); 873 }
874 }
782 } 875 }
783 876
784 return icons_created; 877 return icons_created;
785 } 878 }
786 879
787 // static 880 // static
788 int JumpList::CreateIconFiles(const base::FilePath& icon_dir,
789 const ShellLinkItemList& item_list,
790 size_t max_items,
791 URLIconCache* icon_cache) {
792 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407.
793 SCOPED_UMA_HISTOGRAM_TIMER("WinJumplist.CreateIconFilesDuration");
794
795 int icons_created = 0;
796
797 // Reuse icons for urls that already present in the current JumpList.
798 URLIconCache updated_map;
799 for (ShellLinkItemList::const_iterator iter = item_list.begin();
800 iter != item_list.end() && max_items > 0; ++iter, --max_items) {
801 ShellLinkItem* item = iter->get();
802 auto cache_iter = icon_cache->find(item->url());
803 if (cache_iter != icon_cache->end()) {
804 item->set_icon(cache_iter->second.value(), 0);
805 updated_map[item->url()] = cache_iter->second;
806 } else {
807 base::FilePath icon_path;
808 if (CreateIconFile(item->icon_image(), icon_dir, &icon_path)) {
809 ++icons_created;
810 item->set_icon(icon_path.value(), 0);
811 updated_map[item->url()] = icon_path;
812 }
813 }
814 }
815 icon_cache->swap(updated_map);
816
817 return icons_created;
818 }
819
820 // static
821 void JumpList::DeleteIconFiles(const base::FilePath& icon_dir, 881 void JumpList::DeleteIconFiles(const base::FilePath& icon_dir,
822 URLIconCache* icon_cache) { 882 const URLIconCache& icons_cache) {
823 // Put all cached icon file paths into a set. 883 // Put all cached icon file paths into a set.
824 base::flat_set<base::FilePath> cached_files; 884 base::flat_set<base::FilePath> cached_files;
825 cached_files.reserve(icon_cache->size()); 885 cached_files.reserve(icons_cache.size());
826 886
827 for (const auto& url_path_pair : *icon_cache) 887 for (const auto& url_path_pair : icons_cache)
828 cached_files.insert(url_path_pair.second); 888 cached_files.insert(url_path_pair.second);
829 889
830 DeleteNonCachedFiles(icon_dir, cached_files); 890 DeleteNonCachedFiles(icon_dir, cached_files);
831 } 891 }
OLDNEW
« no previous file with comments | « chrome/browser/win/jumplist.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698