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

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

Issue 2859193005: Cache JumpList icons to avoid unnecessary creation and deletion (Closed)
Patch Set: 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
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 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 280
281 for (size_t i = 0; i < urls.size() && i < kMostVistedCount; i++) { 281 for (size_t i = 0; i < urls.size() && i < kMostVistedCount; i++) {
282 const history::MostVisitedURL& url = urls[i]; 282 const history::MostVisitedURL& url = urls[i];
283 scoped_refptr<ShellLinkItem> link = CreateShellLink(); 283 scoped_refptr<ShellLinkItem> link = CreateShellLink();
284 std::string url_string = url.url.spec(); 284 std::string url_string = url.url.spec();
285 base::string16 url_string_wide = base::UTF8ToUTF16(url_string); 285 base::string16 url_string_wide = base::UTF8ToUTF16(url_string);
286 link->GetCommandLine()->AppendArgNative(url_string_wide); 286 link->GetCommandLine()->AppendArgNative(url_string_wide);
287 link->GetCommandLine()->AppendSwitchASCII( 287 link->GetCommandLine()->AppendSwitchASCII(
288 switches::kWinJumplistAction, jumplist::kMostVisitedCategory); 288 switches::kWinJumplistAction, jumplist::kMostVisitedCategory);
289 link->set_title(!url.title.empty() ? url.title : url_string_wide); 289 link->set_title(!url.title.empty() ? url.title : url_string_wide);
290 link->set_url(url_string);
290 data->most_visited_pages_.push_back(link); 291 data->most_visited_pages_.push_back(link);
291 data->icon_urls_.push_back(std::make_pair(url_string, link)); 292 data->icon_urls_.push_back(std::make_pair(url_string, link));
292 } 293 }
293 data->most_visited_pages_have_updates_ = true; 294 data->most_visited_pages_have_updates_ = true;
294 } 295 }
295 296
296 // Send a query that retrieves the first favicon. 297 // Send a query that retrieves the first favicon.
297 StartLoadingFavicon(); 298 StartLoadingFavicon();
298 } 299 }
299 300
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 return false; 333 return false;
333 334
334 scoped_refptr<ShellLinkItem> link = CreateShellLink(); 335 scoped_refptr<ShellLinkItem> link = CreateShellLink();
335 const sessions::SerializedNavigationEntry& current_navigation = 336 const sessions::SerializedNavigationEntry& current_navigation =
336 tab.navigations.at(tab.current_navigation_index); 337 tab.navigations.at(tab.current_navigation_index);
337 std::string url = current_navigation.virtual_url().spec(); 338 std::string url = current_navigation.virtual_url().spec();
338 link->GetCommandLine()->AppendArgNative(base::UTF8ToUTF16(url)); 339 link->GetCommandLine()->AppendArgNative(base::UTF8ToUTF16(url));
339 link->GetCommandLine()->AppendSwitchASCII(switches::kWinJumplistAction, 340 link->GetCommandLine()->AppendSwitchASCII(switches::kWinJumplistAction,
340 jumplist::kRecentlyClosedCategory); 341 jumplist::kRecentlyClosedCategory);
341 link->set_title(current_navigation.title()); 342 link->set_title(current_navigation.title());
343 link->set_url(url);
342 data->recently_closed_pages_.push_back(link); 344 data->recently_closed_pages_.push_back(link);
343 data->icon_urls_.push_back(std::make_pair(std::move(url), std::move(link))); 345 data->icon_urls_.push_back(std::make_pair(std::move(url), std::move(link)));
344 346
345 return true; 347 return true;
346 } 348 }
347 349
348 void JumpList::AddWindow(const sessions::TabRestoreService::Window& window, 350 void JumpList::AddWindow(const sessions::TabRestoreService::Window& window,
349 size_t max_items, 351 size_t max_items,
350 JumpListData* data) { 352 JumpListData* data) {
351 DCHECK(CalledOnValidThread()); 353 DCHECK(CalledOnValidThread());
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 } 561 }
560 } 562 }
561 563
562 data->recently_closed_pages_have_updates_ = true; 564 data->recently_closed_pages_have_updates_ = true;
563 } 565 }
564 566
565 // Send a query that retrieves the first favicon. 567 // Send a query that retrieves the first favicon.
566 StartLoadingFavicon(); 568 StartLoadingFavicon();
567 } 569 }
568 570
571 void JumpList::DeleteIconFiles(const base::FilePath& icon_dir,
572 JumpListCategory category) {
573 std::set<base::FilePath> iconpath_set;
grt (UTC plus 2) 2017/05/11 20:29:13 iconpath_set -> cached_files here, too
chengx 2017/05/12 01:04:24 Done.
574
575 if (category == JumpListCategory::MOST_VISITED) {
grt (UTC plus 2) 2017/05/11 20:29:13 this is a great place for a case statement. if you
chengx 2017/05/12 01:04:24 Done. Thanks so so so much for this suggestion!
576 for (auto url_path_pair : most_visited_map_)
grt (UTC plus 2) 2017/05/11 20:29:13 const auto& url_path_pair
chengx 2017/05/12 01:04:24 Done.
577 iconpath_set.insert(url_path_pair.second);
grt (UTC plus 2) 2017/05/11 20:29:12 flat_set seems like a good choice here -- you can
chengx 2017/05/12 01:04:24 Thanks. I've changed to flat_set. fyi, it should
578 } else if (category == JumpListCategory::RECENTLY_CLOSED) {
579 for (auto url_path_pair : recently_closed_map_)
grt (UTC plus 2) 2017/05/11 20:29:12 const auto&
chengx 2017/05/12 01:04:24 Done.
580 iconpath_set.insert(url_path_pair.second);
581 }
582 DeleteNonCachedFiles(icon_dir, iconpath_set);
583 }
584
569 void JumpList::CreateIconFiles(const base::FilePath& icon_dir, 585 void JumpList::CreateIconFiles(const base::FilePath& icon_dir,
570 const ShellLinkItemList& item_list, 586 const ShellLinkItemList& item_list,
571 size_t max_items) { 587 size_t max_items,
588 JumpListCategory category) {
572 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407. 589 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407.
573 SCOPED_UMA_HISTOGRAM_TIMER("WinJumplist.CreateIconFilesDuration"); 590 SCOPED_UMA_HISTOGRAM_TIMER("WinJumplist.CreateIconFilesDuration");
574 591
575 for (ShellLinkItemList::const_iterator item = item_list.begin(); 592 // If the current URL is cached which means there's already an icon for this
576 item != item_list.end() && max_items > 0; ++item, --max_items) { 593 // URL, then we simply re-use the icon. Otherwise, we need to create a new
577 base::FilePath icon_path; 594 // icon for this URL.
578 if (CreateIconFile((*item)->icon_image(), icon_dir, &icon_path)) 595
579 (*item)->set_icon(icon_path.value(), 0); 596 if (category == JumpListCategory::MOST_VISITED) {
grt (UTC plus 2) 2017/05/11 20:29:12 please use the technique above to collapse the dup
chengx 2017/05/12 01:04:24 Done. Again, thanks so much for this suggestion!
597 base::flat_map<std::string, base::FilePath> most_visited_map_updated;
598 for (ShellLinkItemList::const_iterator item = item_list.begin();
599 item != item_list.end() && max_items > 0; ++item, --max_items) {
600 if (most_visited_map_.find((*item)->url()) != most_visited_map_.end()) {
601 base::FilePath path = most_visited_map_[(*item)->url()];
602 (*item)->set_icon(most_visited_map_[(*item)->url()].value(), 0);
603 most_visited_map_updated[(*item)->url()] = path;
604 } else {
605 base::FilePath icon_path;
606 if (CreateIconFile((*item)->icon_image(), icon_dir, &icon_path)) {
607 (*item)->set_icon(icon_path.value(), 0);
608 most_visited_map_updated[(*item)->url()] = icon_path;
609 }
610 }
611 }
612 most_visited_map_.swap(most_visited_map_updated);
613 } else if (category == JumpListCategory::RECENTLY_CLOSED) {
614 base::flat_map<std::string, base::FilePath> recently_closed_map_updated;
615 for (ShellLinkItemList::const_iterator item = item_list.begin();
616 item != item_list.end() && max_items > 0; ++item, --max_items) {
617 if (recently_closed_map_.find((*item)->url()) !=
618 recently_closed_map_.end()) {
619 base::FilePath path = recently_closed_map_[(*item)->url()];
620 (*item)->set_icon(path.value(), 0);
621 recently_closed_map_updated[(*item)->url()] = path;
622 } else {
623 base::FilePath icon_path;
624 if (CreateIconFile((*item)->icon_image(), icon_dir, &icon_path)) {
625 (*item)->set_icon(icon_path.value(), 0);
626 recently_closed_map_updated[(*item)->url()] = icon_path;
627 }
628 }
629 }
630 recently_closed_map_.swap(recently_closed_map_updated);
580 } 631 }
581 } 632 }
582 633
583 void JumpList::UpdateIconFiles(const base::FilePath& icon_dir, 634 void JumpList::UpdateIconFiles(const base::FilePath& icon_dir,
584 const ShellLinkItemList& page_list, 635 const ShellLinkItemList& page_list,
585 size_t slot_limit) { 636 size_t slot_limit,
586 DeleteDirectoryContentAndLogRuntime(icon_dir, kFileDeleteLimit); 637 JumpListCategory category) {
638 // Maximum number of icon files that each JumpList icon folder allows to hold.
639 size_t icon_limit = (category == JumpListCategory::MOST_VISITED) ? 12 : 6;
587 640
588 // Create new icons only when the directory exists and is empty. 641 // Clear the JumpList icon folder at |icon_dir| and the cache when
589 if (base::CreateDirectory(icon_dir) && base::IsDirectoryEmpty(icon_dir)) 642 // 1) "Most visited" category updates for the 1st time after Chrome is
590 CreateIconFiles(icon_dir, page_list, slot_limit); 643 // launched. This actually happens right after Chrome is launched.
644 // 2) "Recently closed" category updates for the 1st time after Chrome is
645 // launched.
646 // 3) The number of icons in |icon_dir| has exceeded the limit.
647 if ((category == JumpListCategory::MOST_VISITED &&
648 most_visited_map_.empty()) ||
649 (category == JumpListCategory::RECENTLY_CLOSED &&
650 recently_closed_map_.empty()) ||
651 FilesExceedLimitInDir(icon_dir, icon_limit)) {
652 DeleteDirectoryContentAndLogRuntime(icon_dir, kFileDeleteLimit);
653 most_visited_map_.clear();
654 recently_closed_map_.clear();
655 // Create new icons only when the directory exists and is empty.
656 if (base::CreateDirectory(icon_dir) && base::IsDirectoryEmpty(icon_dir))
657 CreateIconFiles(icon_dir, page_list, slot_limit, category);
658 } else if (base::CreateDirectory(icon_dir)) {
659 CreateIconFiles(icon_dir, page_list, slot_limit, category);
660 DeleteIconFiles(icon_dir, category);
661 }
591 } 662 }
592 663
593 bool JumpList::UpdateJumpList( 664 bool JumpList::UpdateJumpList(
594 const base::string16& app_id, 665 const base::string16& app_id,
595 const base::FilePath& profile_dir, 666 const base::FilePath& profile_dir,
596 const ShellLinkItemList& most_visited_pages, 667 const ShellLinkItemList& most_visited_pages,
597 const ShellLinkItemList& recently_closed_pages, 668 const ShellLinkItemList& recently_closed_pages,
598 bool most_visited_pages_have_updates, 669 bool most_visited_pages_have_updates,
599 bool recently_closed_pages_have_updates, 670 bool recently_closed_pages_have_updates,
600 IncognitoModePrefs::Availability incognito_availability) { 671 IncognitoModePrefs::Availability incognito_availability) {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
647 718
648 // Record the desired number of icons to create in this JumpList update. 719 // Record the desired number of icons to create in this JumpList update.
649 int icons_to_create = 0; 720 int icons_to_create = 0;
650 721
651 // Update the icons for "Most Visisted" category of the JumpList if needed. 722 // Update the icons for "Most Visisted" category of the JumpList if needed.
652 if (most_visited_pages_have_updates) { 723 if (most_visited_pages_have_updates) {
653 base::FilePath icon_dir_most_visited = GenerateJumplistIconDirName( 724 base::FilePath icon_dir_most_visited = GenerateJumplistIconDirName(
654 profile_dir, FILE_PATH_LITERAL("MostVisited")); 725 profile_dir, FILE_PATH_LITERAL("MostVisited"));
655 726
656 UpdateIconFiles(icon_dir_most_visited, most_visited_pages, 727 UpdateIconFiles(icon_dir_most_visited, most_visited_pages,
657 most_visited_items); 728 most_visited_items, JumpListCategory::MOST_VISITED);
658 729
659 icons_to_create += std::min(most_visited_pages.size(), most_visited_items); 730 icons_to_create += std::min(most_visited_pages.size(), most_visited_items);
660 } 731 }
661 732
662 // Update the icons for "Recently Closed" category of the JumpList if needed. 733 // Update the icons for "Recently Closed" category of the JumpList if needed.
663 if (recently_closed_pages_have_updates) { 734 if (recently_closed_pages_have_updates) {
664 base::FilePath icon_dir_recent_closed = GenerateJumplistIconDirName( 735 base::FilePath icon_dir_recent_closed = GenerateJumplistIconDirName(
665 profile_dir, FILE_PATH_LITERAL("RecentClosed")); 736 profile_dir, FILE_PATH_LITERAL("RecentClosed"));
666 737
667 UpdateIconFiles(icon_dir_recent_closed, recently_closed_pages, 738 UpdateIconFiles(icon_dir_recent_closed, recently_closed_pages,
668 recently_closed_items); 739 recently_closed_items, JumpListCategory::RECENTLY_CLOSED);
669 740
670 icons_to_create += 741 icons_to_create +=
671 std::min(recently_closed_pages.size(), recently_closed_items); 742 std::min(recently_closed_pages.size(), recently_closed_items);
672 } 743 }
673 744
674 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407. 745 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407.
675 UMA_HISTOGRAM_COUNTS_100("WinJumplist.CreateIconFilesCount", icons_to_create); 746 UMA_HISTOGRAM_COUNTS_100("WinJumplist.CreateIconFilesCount", icons_to_create);
676 747
677 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407. 748 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407.
678 SCOPED_UMA_HISTOGRAM_TIMER("WinJumplist.UpdateJumpListDuration"); 749 SCOPED_UMA_HISTOGRAM_TIMER("WinJumplist.UpdateJumpListDuration");
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
742 app_id, profile_dir, local_most_visited_pages, 813 app_id, profile_dir, local_most_visited_pages,
743 local_recently_closed_pages, most_visited_pages_have_updates, 814 local_recently_closed_pages, most_visited_pages_have_updates,
744 recently_closed_pages_have_updates, incognito_availability)) { 815 recently_closed_pages_have_updates, incognito_availability)) {
745 base::AutoLock auto_lock(data->list_lock_); 816 base::AutoLock auto_lock(data->list_lock_);
746 if (most_visited_pages_have_updates) 817 if (most_visited_pages_have_updates)
747 data->most_visited_pages_have_updates_ = true; 818 data->most_visited_pages_have_updates_ = true;
748 if (recently_closed_pages_have_updates) 819 if (recently_closed_pages_have_updates)
749 data->recently_closed_pages_have_updates_ = true; 820 data->recently_closed_pages_have_updates_ = true;
750 } 821 }
751 } 822 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698