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

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. Created 3 years, 5 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 176 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 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 TRACE_EVENT0("browser", "JumpList::PostRunUpdate"); 547 TRACE_EVENT0("browser", "JumpList::PostRunUpdate");
543 548
544 update_in_progress_ = true; 549 update_in_progress_ = true;
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 auto update_transaction = base::MakeUnique<UpdateTransaction>();
553 ShellLinkItemList local_most_visited_pages = most_visited_pages_; 558 if (most_visited_should_update_)
554 ShellLinkItemList local_recently_closed_pages = recently_closed_pages_; 559 update_transaction->most_visited_icons = std::move(most_visited_icons_);
560 if (recently_closed_should_update_) {
561 update_transaction->recently_closed_icons =
562 std::move(recently_closed_icons_);
563 }
555 564
556 bool most_visited_should_update = most_visited_should_update_; 565 // Parameter evaluation order is unspecified in C++. Do the first bind and
557 bool recently_closed_should_update = recently_closed_should_update_; 566 // then move it into PostTaskAndReply to ensure the pointer value is obtained
558 567 // before base::Passed() is called.
559 auto update_results = base::MakeUnique<UpdateResults>(); 568 auto run_update =
560 update_results->most_visited_icons_in_update = most_visited_icons_; 569 base::Bind(&JumpList::RunUpdateJumpList, app_id_, profile_dir,
561 update_results->recently_closed_icons_in_update = recently_closed_icons_; 570 most_visited_pages_, recently_closed_pages_,
562 571 most_visited_should_update_, recently_closed_should_update_,
563 // Parameter evaluation order is unspecified in C++. Ensure the pointer value 572 incognito_availability, update_transaction.get());
564 // is obtained before base::Passed() is called.
565 auto* update_results_raw = update_results.get();
566 573
567 // Post a task to update the JumpList, which consists of 1) create new icons, 574 // Post a task to update the JumpList, which consists of 1) create new icons,
568 // 2) delete old icons, 3) notify the OS. 575 // 2) notify the OS, 3) delete old icons.
569 if (!update_jumplist_task_runner_->PostTaskAndReply( 576 if (!update_jumplist_task_runner_->PostTaskAndReply(
570 FROM_HERE, 577 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, 578 base::Bind(&JumpList::OnRunUpdateCompletion,
576 weak_ptr_factory_.GetWeakPtr(), 579 weak_ptr_factory_.GetWeakPtr(),
577 base::Passed(std::move(update_results))))) { 580 base::Passed(std::move(update_transaction))))) {
578 OnRunUpdateCompletion(base::MakeUnique<UpdateResults>()); 581 OnRunUpdateCompletion(base::MakeUnique<UpdateTransaction>());
579 } 582 }
580 } 583 }
581 584
582 void JumpList::OnRunUpdateCompletion( 585 void JumpList::OnRunUpdateCompletion(
583 std::unique_ptr<UpdateResults> update_results) { 586 std::unique_ptr<UpdateTransaction> update_transaction) {
584 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 587 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
585 588
586 // Update JumpList member variables based on the results from the update run 589 // Update JumpList member variables based on the results from the update run
587 // just finished. 590 // just finished.
588 if (update_results->update_timeout) 591 if (update_transaction->update_timeout)
589 updates_to_skip_ = kUpdatesToSkipUnderHeavyLoad; 592 updates_to_skip_ = kUpdatesToSkipUnderHeavyLoad;
590 593
591 if (update_results->update_success) { 594 if (update_transaction->update_success) {
592 most_visited_icons_.swap(update_results->most_visited_icons_in_update); 595 if (most_visited_should_update_) {
593 recently_closed_icons_.swap( 596 most_visited_icons_ = std::move(update_transaction->most_visited_icons);
594 update_results->recently_closed_icons_in_update); 597 most_visited_should_update_ = false;
595 most_visited_should_update_ = false; 598 }
596 recently_closed_should_update_ = false; 599 if (recently_closed_should_update_) {
600 recently_closed_icons_ =
601 std::move(update_transaction->recently_closed_icons);
602 recently_closed_should_update_ = false;
603 }
597 } 604 }
598 605
599 update_in_progress_ = false; 606 update_in_progress_ = false;
600 607
601 // If there is any new notification during the update run just finished, start 608 // If there is any new notification during the update run just finished, start
602 // another JumpList update. 609 // another JumpList update.
603 // Otherwise, post tasks to delete the JumpListIcons and JumpListIconsOld 610 // Otherwise, post tasks to delete the JumpListIcons and JumpListIconsOld
604 // folders as they are no longer needed. Now we have the 611 // folders as they are no longer needed. Now we have the
605 // JumpListIcons{MostVisited, RecentClosed} folders instead. 612 // JumpListIcons{MostVisited, RecentClosed} folders instead.
606 if (top_sites_has_pending_notification_ || 613 if (top_sites_has_pending_notification_ ||
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
656 663
657 // static 664 // static
658 void JumpList::RunUpdateJumpList( 665 void JumpList::RunUpdateJumpList(
659 const base::string16& app_id, 666 const base::string16& app_id,
660 const base::FilePath& profile_dir, 667 const base::FilePath& profile_dir,
661 const ShellLinkItemList& most_visited_pages, 668 const ShellLinkItemList& most_visited_pages,
662 const ShellLinkItemList& recently_closed_pages, 669 const ShellLinkItemList& recently_closed_pages,
663 bool most_visited_should_update, 670 bool most_visited_should_update,
664 bool recently_closed_should_update, 671 bool recently_closed_should_update,
665 IncognitoModePrefs::Availability incognito_availability, 672 IncognitoModePrefs::Availability incognito_availability,
666 UpdateResults* update_results) { 673 UpdateTransaction* update_transaction) {
667 if (!JumpListUpdater::IsEnabled()) 674 if (!JumpListUpdater::IsEnabled())
668 return; 675 return;
669 676
670 DCHECK(update_results); 677 DCHECK(update_transaction);
678
679 base::FilePath most_visited_icon_dir = GenerateJumplistIconDirName(
680 profile_dir, FILE_PATH_LITERAL("MostVisited"));
681 base::FilePath recently_closed_icon_dir = GenerateJumplistIconDirName(
682 profile_dir, FILE_PATH_LITERAL("RecentClosed"));
683
684 CreateNewJumpListAndNotifyOS(
685 app_id, most_visited_icon_dir, recently_closed_icon_dir,
686 most_visited_pages, recently_closed_pages, most_visited_should_update,
687 recently_closed_should_update, incognito_availability,
688 update_transaction);
689
690 // Delete any obsolete icon files.
691 if (most_visited_should_update) {
692 DeleteIconFiles(most_visited_icon_dir,
693 update_transaction->most_visited_icons);
694 }
695 if (recently_closed_should_update) {
696 DeleteIconFiles(recently_closed_icon_dir,
697 update_transaction->recently_closed_icons);
698 }
699 }
700
701 // static
702 void JumpList::CreateNewJumpListAndNotifyOS(
703 const base::string16& app_id,
704 const base::FilePath& most_visited_icon_dir,
705 const base::FilePath& recently_closed_icon_dir,
706 const ShellLinkItemList& most_visited_pages,
707 const ShellLinkItemList& recently_closed_pages,
708 bool most_visited_should_update,
709 bool recently_closed_should_update,
710 IncognitoModePrefs::Availability incognito_availability,
711 UpdateTransaction* update_transaction) {
712 DCHECK(update_transaction);
671 713
672 JumpListUpdater jumplist_updater(app_id); 714 JumpListUpdater jumplist_updater(app_id);
673 715
674 base::ElapsedTimer begin_update_timer; 716 base::ElapsedTimer begin_update_timer;
675 717
676 if (!jumplist_updater.BeginUpdate()) 718 if (!jumplist_updater.BeginUpdate())
677 return; 719 return;
678 720
679 // Discard this JumpList update if JumpListUpdater::BeginUpdate takes longer 721 // Discard this JumpList update if JumpListUpdater::BeginUpdate takes longer
680 // than the maximum allowed time, as it's very likely the following update 722 // 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 723 // 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) { 724 if (begin_update_timer.Elapsed() >= kTimeOutForJumplistBeginUpdate) {
684 update_results->update_timeout = true; 725 update_transaction->update_timeout = true;
685 return; 726 return;
686 } 727 }
687 728
688 // Record the desired number of icons created in this JumpList update. 729 // Record the desired number of icons created in this JumpList update.
689 int icons_created = 0; 730 int icons_created = 0;
690 731
732 URLIconCache most_visited_icons_next;
733 URLIconCache recently_closed_icons_next;
734
691 // Update the icons for "Most Visisted" category of the JumpList if needed. 735 // Update the icons for "Most Visisted" category of the JumpList if needed.
692 if (most_visited_should_update) { 736 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( 737 icons_created += UpdateIconFiles(
697 icon_dir_most_visited, most_visited_pages, kMostVisitedItems, 738 most_visited_icon_dir, most_visited_pages, kMostVisitedItems,
698 &update_results->most_visited_icons_in_update); 739 &update_transaction->most_visited_icons, &most_visited_icons_next);
699 } 740 }
700 741
701 // Update the icons for "Recently Closed" category of the JumpList if needed. 742 // Update the icons for "Recently Closed" category of the JumpList if needed.
702 if (recently_closed_should_update) { 743 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( 744 icons_created += UpdateIconFiles(
707 icon_dir_recent_closed, recently_closed_pages, kRecentlyClosedItems, 745 recently_closed_icon_dir, recently_closed_pages, kRecentlyClosedItems,
708 &update_results->recently_closed_icons_in_update); 746 &update_transaction->recently_closed_icons,
747 &recently_closed_icons_next);
709 } 748 }
710 749
711 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407. 750 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407.
712 UMA_HISTOGRAM_COUNTS_100("WinJumplist.CreateIconFilesCount", icons_created); 751 UMA_HISTOGRAM_COUNTS_100("WinJumplist.CreateIconFilesCount", icons_created);
713 752
714 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407. 753 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407.
715 SCOPED_UMA_HISTOGRAM_TIMER("WinJumplist.UpdateJumpListDuration"); 754 SCOPED_UMA_HISTOGRAM_TIMER("WinJumplist.UpdateJumpListDuration");
716 755
717 base::ElapsedTimer add_custom_category_timer; 756 base::ElapsedTimer add_custom_category_timer;
718 757
719 // Update the "Most Visited" category of the JumpList if it exists. 758 // Update the "Most Visited" category of the JumpList if it exists.
720 // This update request is applied into the JumpList when we commit this 759 // This update request is applied into the JumpList when we commit this
721 // transaction. 760 // transaction.
722 if (!jumplist_updater.AddCustomCategory( 761 if (!jumplist_updater.AddCustomCategory(
723 l10n_util::GetStringUTF16(IDS_NEW_TAB_MOST_VISITED), 762 l10n_util::GetStringUTF16(IDS_NEW_TAB_MOST_VISITED),
724 most_visited_pages, kMostVisitedItems)) { 763 most_visited_pages, kMostVisitedItems)) {
725 return; 764 return;
726 } 765 }
727 766
728 // Update the "Recently Closed" category of the JumpList. 767 // Update the "Recently Closed" category of the JumpList.
729 if (!jumplist_updater.AddCustomCategory( 768 if (!jumplist_updater.AddCustomCategory(
730 l10n_util::GetStringUTF16(IDS_RECENTLY_CLOSED), recently_closed_pages, 769 l10n_util::GetStringUTF16(IDS_RECENTLY_CLOSED), recently_closed_pages,
731 kRecentlyClosedItems)) { 770 kRecentlyClosedItems)) {
732 return; 771 return;
733 } 772 }
734 773
735 // If JumpListUpdater::AddCustomCategory or JumpListUpdater::CommitUpdate 774 // If AddCustomCategory takes longer than the maximum allowed time, abort the
736 // takes longer than the maximum allowed time, skip the next 775 // current update and skip the next |kUpdatesToSkipUnderHeavyLoad| updates.
737 // |kUpdatesToSkipUnderHeavyLoad| updates. This update should be finished 776 if (add_custom_category_timer.Elapsed() >= kTimeOutForAddCustomCategory) {
738 // because we've already updated the icons on the disk. If discarding this 777 update_transaction->update_timeout = true;
739 // update from here, some items in the current JumpList may not have icons 778 return;
740 // as they've been delete from the disk. In this case, the background color of 779 }
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 780
746 // Update the "Tasks" category of the JumpList. 781 // Update the "Tasks" category of the JumpList.
747 if (!UpdateTaskCategory(&jumplist_updater, incognito_availability)) 782 if (!UpdateTaskCategory(&jumplist_updater, incognito_availability))
748 return; 783 return;
749 784
750 base::ElapsedTimer commit_update_timer; 785 base::ElapsedTimer commit_update_timer;
751 786
752 // Commit this transaction and send the updated JumpList to Windows. 787 // Commit this transaction and send the updated JumpList to Windows.
753 if (jumplist_updater.CommitUpdate()) 788 bool commit_success = jumplist_updater.CommitUpdate();
754 update_results->update_success = true;
755 789
790 // If CommitUpdate call takes longer than the maximum allowed time, skip the
791 // next |kUpdatesToSkipUnderHeavyLoad| updates.
756 if (commit_update_timer.Elapsed() >= kTimeOutForJumplistCommitUpdate) 792 if (commit_update_timer.Elapsed() >= kTimeOutForJumplistCommitUpdate)
757 update_results->update_timeout = true; 793 update_transaction->update_timeout = true;
794
795 if (commit_success) {
796 update_transaction->update_success = true;
797
798 // The move assignments below ensure update_transaction always has the icons
799 // to keep.
800 if (most_visited_should_update) {
801 update_transaction->most_visited_icons =
802 std::move(most_visited_icons_next);
803 }
804 if (recently_closed_should_update) {
805 update_transaction->recently_closed_icons =
806 std::move(recently_closed_icons_next);
807 }
808 }
758 } 809 }
759 810
760 // static 811 // static
761 int JumpList::UpdateIconFiles(const base::FilePath& icon_dir, 812 int JumpList::UpdateIconFiles(const base::FilePath& icon_dir,
762 const ShellLinkItemList& page_list, 813 const ShellLinkItemList& item_list,
763 size_t slot_limit, 814 size_t max_items,
764 URLIconCache* icon_cache) { 815 URLIconCache* icon_cur,
816 URLIconCache* icon_next) {
817 DCHECK(icon_cur);
818 DCHECK(icon_next);
819
820 // Clear the JumpList icon folder at |icon_dir| and the caches when
821 // 1) |icon_cur| is empty. This happens when "Most visited" or "Recently
822 // closed" category updates for the 1st time after Chrome is launched.
823 // 2) The number of icons in |icon_dir| has exceeded the limit.
824 if (icon_cur->empty() || FilesExceedLimitInDir(icon_dir, max_items * 2)) {
825 DeleteDirectoryContentAndLogRuntime(icon_dir, kFileDeleteLimit);
826 icon_cur->clear();
827 icon_next->clear();
828 // Create new icons only when the directory exists and is empty.
829 if (!base::CreateDirectory(icon_dir) || !base::IsDirectoryEmpty(icon_dir))
830 return 0;
831 } else if (!base::CreateDirectory(icon_dir)) {
832 return 0;
833 }
834
835 return CreateIconFiles(icon_dir, item_list, max_items, *icon_cur, icon_next);
836 }
837
838 // static
839 int JumpList::CreateIconFiles(const base::FilePath& icon_dir,
840 const ShellLinkItemList& item_list,
841 size_t max_items,
842 const URLIconCache& icon_cur,
843 URLIconCache* icon_next) {
844 DCHECK(icon_next);
845
846 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407.
847 SCOPED_UMA_HISTOGRAM_TIMER("WinJumplist.CreateIconFilesDuration");
848
765 int icons_created = 0; 849 int icons_created = 0;
766 850
767 // Clear the JumpList icon folder at |icon_dir| and the cache when 851 // Reuse icons for urls that already present in the current JumpList.
768 // 1) |icon_cache| is empty. This happens when "Most visited" or "Recently 852 for (ShellLinkItemList::const_iterator iter = item_list.begin();
769 // closed" category updates for the 1st time after Chrome is launched. 853 iter != item_list.end() && max_items > 0; ++iter, --max_items) {
770 // 2) The number of icons in |icon_dir| has exceeded the limit. 854 ShellLinkItem* item = iter->get();
771 if (icon_cache->empty() || FilesExceedLimitInDir(icon_dir, slot_limit * 2)) { 855 auto cache_iter = icon_cur.find(item->url());
772 DeleteDirectoryContentAndLogRuntime(icon_dir, kFileDeleteLimit); 856 if (cache_iter != icon_cur.end()) {
773 icon_cache->clear(); 857 item->set_icon(cache_iter->second.value(), 0);
774 // Create new icons only when the directory exists and is empty. 858 (*icon_next)[item->url()] = cache_iter->second;
775 if (base::CreateDirectory(icon_dir) && base::IsDirectoryEmpty(icon_dir)) 859 } else {
776 icons_created += 860 base::FilePath icon_path;
777 CreateIconFiles(icon_dir, page_list, slot_limit, icon_cache); 861 if (CreateIconFile(item->icon_image(), icon_dir, &icon_path)) {
778 } else if (base::CreateDirectory(icon_dir)) { 862 ++icons_created;
779 icons_created += 863 item->set_icon(icon_path.value(), 0);
780 CreateIconFiles(icon_dir, page_list, slot_limit, icon_cache); 864 (*icon_next)[item->url()] = icon_path;
781 DeleteIconFiles(icon_dir, icon_cache); 865 }
866 }
782 } 867 }
783 868
784 return icons_created; 869 return icons_created;
785 } 870 }
786 871
787 // static 872 // 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, 873 void JumpList::DeleteIconFiles(const base::FilePath& icon_dir,
822 URLIconCache* icon_cache) { 874 const URLIconCache& icons_cache) {
823 // Put all cached icon file paths into a set. 875 // Put all cached icon file paths into a set.
824 base::flat_set<base::FilePath> cached_files; 876 base::flat_set<base::FilePath> cached_files;
825 cached_files.reserve(icon_cache->size()); 877 cached_files.reserve(icons_cache.size());
826 878
827 for (const auto& url_path_pair : *icon_cache) 879 for (const auto& url_path_pair : icons_cache)
828 cached_files.insert(url_path_pair.second); 880 cached_files.insert(url_path_pair.second);
829 881
830 DeleteNonCachedFiles(icon_dir, cached_files); 882 DeleteNonCachedFiles(icon_dir, cached_files);
831 } 883 }
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