OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 allows to hold. | |
grt (UTC plus 2)
2017/05/18 08:59:59
"allows to" -> "may"
chengx
2017/05/18 17:21:55
Done.
| |
662 size_t icon_limit = (category == JumpListCategory::kMostVisited) ? 12 : 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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |