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

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

Issue 2859193005: Cache JumpList icons to avoid unnecessary creation and deletion (Closed)
Patch Set: Fix nits. Created 3 years, 7 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') | chrome/browser/win/jumplist_file_util.h » ('j') | 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"
11 #include "base/containers/flat_set.h"
11 #include "base/files/file_util.h" 12 #include "base/files/file_util.h"
12 #include "base/metrics/histogram_macros.h" 13 #include "base/metrics/histogram_macros.h"
13 #include "base/path_service.h" 14 #include "base/path_service.h"
14 #include "base/sequenced_task_runner.h" 15 #include "base/sequenced_task_runner.h"
15 #include "base/single_thread_task_runner.h" 16 #include "base/single_thread_task_runner.h"
16 #include "base/strings/string_piece.h" 17 #include "base/strings/string_piece.h"
17 #include "base/strings/string_util.h" 18 #include "base/strings/string_util.h"
18 #include "base/strings/utf_string_conversions.h" 19 #include "base/strings/utf_string_conversions.h"
19 #include "base/task_scheduler/post_task.h" 20 #include "base/task_scheduler/post_task.h"
20 #include "base/task_scheduler/task_traits.h" 21 #include "base/task_scheduler/task_traits.h"
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
293 294
294 for (size_t i = 0; i < urls.size() && i < kMostVistedCount; i++) { 295 for (size_t i = 0; i < urls.size() && i < kMostVistedCount; i++) {
295 const history::MostVisitedURL& url = urls[i]; 296 const history::MostVisitedURL& url = urls[i];
296 scoped_refptr<ShellLinkItem> link = CreateShellLink(); 297 scoped_refptr<ShellLinkItem> link = CreateShellLink();
297 std::string url_string = url.url.spec(); 298 std::string url_string = url.url.spec();
298 base::string16 url_string_wide = base::UTF8ToUTF16(url_string); 299 base::string16 url_string_wide = base::UTF8ToUTF16(url_string);
299 link->GetCommandLine()->AppendArgNative(url_string_wide); 300 link->GetCommandLine()->AppendArgNative(url_string_wide);
300 link->GetCommandLine()->AppendSwitchASCII( 301 link->GetCommandLine()->AppendSwitchASCII(
301 switches::kWinJumplistAction, jumplist::kMostVisitedCategory); 302 switches::kWinJumplistAction, jumplist::kMostVisitedCategory);
302 link->set_title(!url.title.empty() ? url.title : url_string_wide); 303 link->set_title(!url.title.empty() ? url.title : url_string_wide);
304 link->set_url(url_string);
303 data->most_visited_pages_.push_back(link); 305 data->most_visited_pages_.push_back(link);
304 data->icon_urls_.push_back(std::make_pair(url_string, link)); 306 data->icon_urls_.push_back(std::make_pair(url_string, link));
305 } 307 }
306 data->most_visited_pages_have_updates_ = true; 308 data->most_visited_pages_have_updates_ = true;
307 } 309 }
308 310
309 // Send a query that retrieves the first favicon. 311 // Send a query that retrieves the first favicon.
310 StartLoadingFavicon(); 312 StartLoadingFavicon();
311 } 313 }
312 314
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 return false; 347 return false;
346 348
347 scoped_refptr<ShellLinkItem> link = CreateShellLink(); 349 scoped_refptr<ShellLinkItem> link = CreateShellLink();
348 const sessions::SerializedNavigationEntry& current_navigation = 350 const sessions::SerializedNavigationEntry& current_navigation =
349 tab.navigations.at(tab.current_navigation_index); 351 tab.navigations.at(tab.current_navigation_index);
350 std::string url = current_navigation.virtual_url().spec(); 352 std::string url = current_navigation.virtual_url().spec();
351 link->GetCommandLine()->AppendArgNative(base::UTF8ToUTF16(url)); 353 link->GetCommandLine()->AppendArgNative(base::UTF8ToUTF16(url));
352 link->GetCommandLine()->AppendSwitchASCII(switches::kWinJumplistAction, 354 link->GetCommandLine()->AppendSwitchASCII(switches::kWinJumplistAction,
353 jumplist::kRecentlyClosedCategory); 355 jumplist::kRecentlyClosedCategory);
354 link->set_title(current_navigation.title()); 356 link->set_title(current_navigation.title());
357 link->set_url(url);
355 data->recently_closed_pages_.push_back(link); 358 data->recently_closed_pages_.push_back(link);
356 data->icon_urls_.push_back(std::make_pair(std::move(url), std::move(link))); 359 data->icon_urls_.push_back(std::make_pair(std::move(url), std::move(link)));
357 360
358 return true; 361 return true;
359 } 362 }
360 363
361 void JumpList::AddWindow(const sessions::TabRestoreService::Window& window, 364 void JumpList::AddWindow(const sessions::TabRestoreService::Window& window,
362 size_t max_items, 365 size_t max_items,
363 JumpListData* data) { 366 JumpListData* data) {
364 DCHECK(CalledOnValidThread()); 367 DCHECK(CalledOnValidThread());
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
582 } 585 }
583 } 586 }
584 587
585 data->recently_closed_pages_have_updates_ = true; 588 data->recently_closed_pages_have_updates_ = true;
586 } 589 }
587 590
588 // Send a query that retrieves the first favicon. 591 // Send a query that retrieves the first favicon.
589 StartLoadingFavicon(); 592 StartLoadingFavicon();
590 } 593 }
591 594
595 void JumpList::DeleteIconFiles(const base::FilePath& icon_dir,
596 JumpListCategory category) {
597 base::flat_map<std::string, base::FilePath>* source_map = nullptr;
598 switch (category) {
599 case JumpListCategory::kMostVisited:
600 source_map = &most_visited_icons_;
601 break;
602 case JumpListCategory::kRecentlyClosed:
603 source_map = &recently_closed_icons_;
604 break;
605 }
606
607 // Put all cached icon file paths into a set.
608 base::flat_set<base::FilePath> cached_files;
609 cached_files.reserve(source_map->size());
610
611 for (const auto& url_path_pair : *source_map)
612 cached_files.insert(url_path_pair.second);
613
614 DeleteNonCachedFiles(icon_dir, cached_files);
615 }
616
592 void JumpList::CreateIconFiles(const base::FilePath& icon_dir, 617 void JumpList::CreateIconFiles(const base::FilePath& icon_dir,
593 const ShellLinkItemList& item_list, 618 const ShellLinkItemList& item_list,
594 size_t max_items) { 619 size_t max_items,
620 JumpListCategory category) {
595 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407. 621 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407.
596 SCOPED_UMA_HISTOGRAM_TIMER("WinJumplist.CreateIconFilesDuration"); 622 SCOPED_UMA_HISTOGRAM_TIMER("WinJumplist.CreateIconFilesDuration");
597 623
598 for (ShellLinkItemList::const_iterator item = item_list.begin(); 624 // Reuse icons for urls that were already present in the jumplist for this
599 item != item_list.end() && max_items > 0; ++item, --max_items) { 625 // category.
600 base::FilePath icon_path; 626
601 if (CreateIconFile((*item)->icon_image(), icon_dir, &icon_path)) 627 base::flat_map<std::string, base::FilePath>* source_map = nullptr;
602 (*item)->set_icon(icon_path.value(), 0); 628 switch (category) {
629 case JumpListCategory::kMostVisited:
630 source_map = &most_visited_icons_;
631 break;
632 case JumpListCategory::kRecentlyClosed:
633 source_map = &recently_closed_icons_;
634 break;
603 } 635 }
636
637 base::flat_map<std::string, base::FilePath> updated_map;
638
639 for (ShellLinkItemList::const_iterator iter = item_list.begin();
640 iter != item_list.end() && max_items > 0; ++iter, --max_items) {
641 ShellLinkItem* item = iter->get();
642 auto cache_iter = source_map->find(item->url());
643 if (cache_iter != source_map->end()) {
644 item->set_icon(cache_iter->second.value(), 0);
645 updated_map[item->url()] = cache_iter->second;
646 } else {
647 base::FilePath icon_path;
648 if (CreateIconFile(item->icon_image(), icon_dir, &icon_path)) {
649 item->set_icon(icon_path.value(), 0);
650 updated_map[item->url()] = icon_path;
651 }
652 }
653 }
654 source_map->swap(updated_map);
604 } 655 }
605 656
606 void JumpList::UpdateIconFiles(const base::FilePath& icon_dir, 657 void JumpList::UpdateIconFiles(const base::FilePath& icon_dir,
607 const ShellLinkItemList& page_list, 658 const ShellLinkItemList& page_list,
608 size_t slot_limit) { 659 size_t slot_limit,
609 DeleteDirectoryContentAndLogRuntime(icon_dir, kFileDeleteLimit); 660 JumpListCategory category) {
661 // Maximum number of icon files that each JumpList icon folder may hold.
662 size_t icon_limit = (category == JumpListCategory::kMostVisited) ? 10 : 6;
610 663
611 // Create new icons only when the directory exists and is empty. 664 // Clear the JumpList icon folder at |icon_dir| and the cache when
612 if (base::CreateDirectory(icon_dir) && base::IsDirectoryEmpty(icon_dir)) 665 // 1) "Most visited" category updates for the 1st time after Chrome is
613 CreateIconFiles(icon_dir, page_list, slot_limit); 666 // launched. This actually happens right after Chrome is launched.
667 // 2) "Recently closed" category updates for the 1st time after Chrome is
668 // launched.
669 // 3) The number of icons in |icon_dir| has exceeded the limit.
670 if ((category == JumpListCategory::kMostVisited &&
671 most_visited_icons_.empty()) ||
672 (category == JumpListCategory::kRecentlyClosed &&
673 recently_closed_icons_.empty()) ||
674 FilesExceedLimitInDir(icon_dir, icon_limit)) {
675 DeleteDirectoryContentAndLogRuntime(icon_dir, kFileDeleteLimit);
676 most_visited_icons_.clear();
677 recently_closed_icons_.clear();
678 // Create new icons only when the directory exists and is empty.
679 if (base::CreateDirectory(icon_dir) && base::IsDirectoryEmpty(icon_dir))
680 CreateIconFiles(icon_dir, page_list, slot_limit, category);
681 } else if (base::CreateDirectory(icon_dir)) {
682 CreateIconFiles(icon_dir, page_list, slot_limit, category);
683 DeleteIconFiles(icon_dir, category);
684 }
614 } 685 }
615 686
616 bool JumpList::UpdateJumpList( 687 bool JumpList::UpdateJumpList(
617 const base::string16& app_id, 688 const base::string16& app_id,
618 const base::FilePath& profile_dir, 689 const base::FilePath& profile_dir,
619 const ShellLinkItemList& most_visited_pages, 690 const ShellLinkItemList& most_visited_pages,
620 const ShellLinkItemList& recently_closed_pages, 691 const ShellLinkItemList& recently_closed_pages,
621 bool most_visited_pages_have_updates, 692 bool most_visited_pages_have_updates,
622 bool recently_closed_pages_have_updates, 693 bool recently_closed_pages_have_updates,
623 IncognitoModePrefs::Availability incognito_availability) { 694 IncognitoModePrefs::Availability incognito_availability) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
673 744
674 // Record the desired number of icons to create in this JumpList update. 745 // Record the desired number of icons to create in this JumpList update.
675 int icons_to_create = 0; 746 int icons_to_create = 0;
676 747
677 // Update the icons for "Most Visisted" category of the JumpList if needed. 748 // Update the icons for "Most Visisted" category of the JumpList if needed.
678 if (most_visited_pages_have_updates) { 749 if (most_visited_pages_have_updates) {
679 base::FilePath icon_dir_most_visited = GenerateJumplistIconDirName( 750 base::FilePath icon_dir_most_visited = GenerateJumplistIconDirName(
680 profile_dir, FILE_PATH_LITERAL("MostVisited")); 751 profile_dir, FILE_PATH_LITERAL("MostVisited"));
681 752
682 UpdateIconFiles(icon_dir_most_visited, most_visited_pages, 753 UpdateIconFiles(icon_dir_most_visited, most_visited_pages,
683 most_visited_items); 754 most_visited_items, JumpListCategory::kMostVisited);
684 755
685 icons_to_create += std::min(most_visited_pages.size(), most_visited_items); 756 icons_to_create += std::min(most_visited_pages.size(), most_visited_items);
686 } 757 }
687 758
688 // Update the icons for "Recently Closed" category of the JumpList if needed. 759 // Update the icons for "Recently Closed" category of the JumpList if needed.
689 if (recently_closed_pages_have_updates) { 760 if (recently_closed_pages_have_updates) {
690 base::FilePath icon_dir_recent_closed = GenerateJumplistIconDirName( 761 base::FilePath icon_dir_recent_closed = GenerateJumplistIconDirName(
691 profile_dir, FILE_PATH_LITERAL("RecentClosed")); 762 profile_dir, FILE_PATH_LITERAL("RecentClosed"));
692 763
693 UpdateIconFiles(icon_dir_recent_closed, recently_closed_pages, 764 UpdateIconFiles(icon_dir_recent_closed, recently_closed_pages,
694 recently_closed_items); 765 recently_closed_items, JumpListCategory::kRecentlyClosed);
695 766
696 icons_to_create += 767 icons_to_create +=
697 std::min(recently_closed_pages.size(), recently_closed_items); 768 std::min(recently_closed_pages.size(), recently_closed_items);
698 } 769 }
699 770
700 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407. 771 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407.
701 UMA_HISTOGRAM_COUNTS_100("WinJumplist.CreateIconFilesCount", icons_to_create); 772 UMA_HISTOGRAM_COUNTS_100("WinJumplist.CreateIconFilesCount", icons_to_create);
702 773
703 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407. 774 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407.
704 SCOPED_UMA_HISTOGRAM_TIMER("WinJumplist.UpdateJumpListDuration"); 775 SCOPED_UMA_HISTOGRAM_TIMER("WinJumplist.UpdateJumpListDuration");
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
788 app_id, profile_dir, local_most_visited_pages, 859 app_id, profile_dir, local_most_visited_pages,
789 local_recently_closed_pages, most_visited_pages_have_updates, 860 local_recently_closed_pages, most_visited_pages_have_updates,
790 recently_closed_pages_have_updates, incognito_availability)) { 861 recently_closed_pages_have_updates, incognito_availability)) {
791 base::AutoLock auto_lock(data->list_lock_); 862 base::AutoLock auto_lock(data->list_lock_);
792 if (most_visited_pages_have_updates) 863 if (most_visited_pages_have_updates)
793 data->most_visited_pages_have_updates_ = true; 864 data->most_visited_pages_have_updates_ = true;
794 if (recently_closed_pages_have_updates) 865 if (recently_closed_pages_have_updates)
795 data->recently_closed_pages_have_updates_ = true; 866 data->recently_closed_pages_have_updates_ = true;
796 } 867 }
797 } 868 }
OLDNEW
« no previous file with comments | « chrome/browser/win/jumplist.h ('k') | chrome/browser/win/jumplist_file_util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698