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

Unified Diff: chrome/browser/win/jumplist.cc

Issue 2836873003: Update different JumpList categories on demand (Closed)
Patch Set: Fix nits Created 3 years, 8 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/win/jumplist.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/win/jumplist.cc
diff --git a/chrome/browser/win/jumplist.cc b/chrome/browser/win/jumplist.cc
index 54d4fb989cacb1a56e5e6e63197ca69ff00df41f..6dad5579697389d68a137d050de08c7ae6b97199 100644
--- a/chrome/browser/win/jumplist.cc
+++ b/chrome/browser/win/jumplist.cc
@@ -187,25 +187,27 @@ bool UpdateTaskCategory(
// Note that any timeout error along the way results in the old jumplist being
// left as-is, while any non-timeout error results in the old jumplist being
// left as-is, but without icon files.
-void UpdateJumpList(const wchar_t* app_id,
+bool UpdateJumpList(const wchar_t* app_id,
const base::FilePath& icon_dir,
const ShellLinkItemList& most_visited_pages,
const ShellLinkItemList& recently_closed_pages,
+ bool most_visited_pages_have_updates,
+ bool recently_closed_pages_have_updates,
IncognitoModePrefs::Availability incognito_availability) {
if (!JumpListUpdater::IsEnabled())
- return;
+ return true;
// Records the time cost of starting a JumpListUpdater.
base::ElapsedTimer begin_update_timer;
JumpListUpdater jumplist_updater(app_id);
if (!jumplist_updater.BeginUpdate())
- return;
+ return false;
// Stops jumplist update if JumpListUpdater's start times out, as it's very
// likely the following update steps will also take a long time.
if (begin_update_timer.Elapsed() >= kTimeOutForJumplistUpdate)
- return;
+ return false;
// The default maximum number of items to display in JumpList is 10.
// https://msdn.microsoft.com/library/windows/desktop/dd378398.aspx
@@ -216,6 +218,8 @@ void UpdateJumpList(const wchar_t* app_id,
// For the remaining slots, we allocate 5/8 (i.e., 5 slots if both categories
// present) to "most-visited" items and 3/8 (i.e., 3 slots if both categories
// present) to "recently-closed" items, respectively.
+ // Nevertheless, if there are not so many items in |recently_closed_pages|,
+ // we give the remaining slots to "most-visited" items.
const int kMostVisited = 50;
const int kRecentlyClosed = 30;
@@ -236,20 +240,47 @@ void UpdateJumpList(const wchar_t* app_id,
recently_closed_items = recently_closed_pages.size();
}
- // Delete the content in JumpListIcons folder and log the results to UMA.
- DeleteDirectoryContentAndLogResults(icon_dir, kFileDeleteLimit);
+ if (most_visited_pages_have_updates) {
+ // Delete the content in JumpListIconsMostVisited folder and log the results
+ // to UMA.
+ base::FilePath icon_dir_most_visited = icon_dir.DirName().Append(
+ icon_dir.BaseName().value() + FILE_PATH_LITERAL("MostVisited"));
+
+ DeleteDirectoryContentAndLogResults(icon_dir_most_visited,
+ kFileDeleteLimit);
+
+ // If the directory doesn't exist (we have tried to create it in
+ // DeleteDirectoryContentAndLogResults) or is not empty, skip updating the
+ // jumplist icons. The jumplist links should be updated anyway, as it
+ // doesn't involve disk IO. In this case, Chrome's icon will be used for the
+ // new links.
+ if (base::DirectoryExists(icon_dir_most_visited) &&
+ base::IsDirectoryEmpty(icon_dir_most_visited)) {
+ // Create icon files for shortcuts in the "Most Visited" category.
+ CreateIconFiles(icon_dir_most_visited, most_visited_pages,
+ most_visited_items);
+ }
+ }
- // If JumpListIcons directory doesn't exist (we have tried to create it
- // already) or is not empty, skip updating the jumplist icons. The jumplist
- // links should be updated anyway, as it doesn't involve disk IO. In this
- // case, Chrome's icon will be used for the new links.
+ if (recently_closed_pages_have_updates) {
+ // Delete the content in JumpListIconsRecentClosed folder and log the
+ // results to UMA.
+ base::FilePath icon_dir_recent_closed = icon_dir.DirName().Append(
+ icon_dir.BaseName().value() + FILE_PATH_LITERAL("RecentClosed"));
- bool should_create_icons =
- base::DirectoryExists(icon_dir) && base::IsDirectoryEmpty(icon_dir);
+ DeleteDirectoryContentAndLogResults(icon_dir_recent_closed,
+ kFileDeleteLimit);
- // Create icon files for shortcuts in the "Most Visited" category.
- if (should_create_icons)
- CreateIconFiles(icon_dir, most_visited_pages, most_visited_items);
+ if (base::DirectoryExists(icon_dir_recent_closed) &&
+ base::IsDirectoryEmpty(icon_dir_recent_closed)) {
+ // Create icon files for shortcuts in the "Recently Closed" category.
+ CreateIconFiles(icon_dir_recent_closed, recently_closed_pages,
+ recently_closed_items);
+ }
+ }
+
+ // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407.
+ SCOPED_UMA_HISTOGRAM_TIMER("WinJumplist.UpdateJumpListDuration");
// Update the "Most Visited" category of the JumpList if it exists.
// This update request is applied into the JumpList when we commit this
@@ -257,26 +288,22 @@ void UpdateJumpList(const wchar_t* app_id,
if (!jumplist_updater.AddCustomCategory(
l10n_util::GetStringUTF16(IDS_NEW_TAB_MOST_VISITED),
most_visited_pages, most_visited_items)) {
- return;
+ return false;
}
- // Create icon files for shortcuts in the "Recently Closed" category.
- if (should_create_icons)
- CreateIconFiles(icon_dir, recently_closed_pages, recently_closed_items);
-
// Update the "Recently Closed" category of the JumpList.
if (!jumplist_updater.AddCustomCategory(
l10n_util::GetStringUTF16(IDS_RECENTLY_CLOSED),
recently_closed_pages, recently_closed_items)) {
- return;
+ return false;
}
// Update the "Tasks" category of the JumpList.
if (!UpdateTaskCategory(&jumplist_updater, incognito_availability))
- return;
+ return false;
// Commit this transaction and send the updated JumpList to Windows.
- jumplist_updater.CommitUpdate();
+ return jumplist_updater.CommitUpdate();
}
// Updates the jumplist, once all the data has been fetched.
@@ -287,6 +314,8 @@ void RunUpdateJumpList(IncognitoModePrefs::Availability incognito_availability,
JumpListData* data = &ref_counted_data->data;
ShellLinkItemList local_most_visited_pages;
ShellLinkItemList local_recently_closed_pages;
+ bool most_visited_pages_have_updates;
+ bool recently_closed_pages_have_updates;
{
base::AutoLock auto_lock(data->list_lock_);
@@ -295,14 +324,35 @@ void RunUpdateJumpList(IncognitoModePrefs::Availability incognito_availability,
if (!data->icon_urls_.empty())
return;
- // Make local copies of lists so we can release the lock.
+ // Make local copies of lists and flags so we can release the lock.
local_most_visited_pages = data->most_visited_pages_;
local_recently_closed_pages = data->recently_closed_pages_;
+
+ most_visited_pages_have_updates = data->most_visited_pages_have_updates_;
+ recently_closed_pages_have_updates =
+ data->recently_closed_pages_have_updates_;
+
+ // Clear the flags to reflect that we'll take actions on these updates.
+ data->most_visited_pages_have_updates_ = false;
+ data->recently_closed_pages_have_updates_ = false;
}
- // Updates the application JumpList.
- UpdateJumpList(app_id.c_str(), icon_dir, local_most_visited_pages,
- local_recently_closed_pages, incognito_availability);
+ if (!most_visited_pages_have_updates && !recently_closed_pages_have_updates)
+ return;
+
+ // Updates the application JumpList. If it fails, reset the flags to true if
+ // they were so that the corresponding JumpList categories will be tried to
+ // update again in the next run.
+ if (!UpdateJumpList(
+ app_id.c_str(), icon_dir, local_most_visited_pages,
+ local_recently_closed_pages, most_visited_pages_have_updates,
+ recently_closed_pages_have_updates, incognito_availability)) {
+ base::AutoLock auto_lock(data->list_lock_);
+ if (most_visited_pages_have_updates)
+ data->most_visited_pages_have_updates_ = true;
+ if (recently_closed_pages_have_updates)
+ data->recently_closed_pages_have_updates_ = true;
+ }
}
} // namespace
@@ -317,13 +367,13 @@ JumpList::JumpList(Profile* profile)
profile_(profile),
jumplist_data_(new base::RefCountedData<JumpListData>),
task_id_(base::CancelableTaskTracker::kBadTaskId),
- update_jumplisticons_task_runner_(base::CreateCOMSTATaskRunnerWithTraits(
+ update_jumplist_task_runner_(base::CreateCOMSTATaskRunnerWithTraits(
base::TaskTraits()
.WithPriority(base::TaskPriority::USER_VISIBLE)
.WithShutdownBehavior(
base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)
.MayBlock())),
- delete_jumplisticonsold_task_runner_(
+ delete_jumplisticons_task_runner_(
base::CreateSequencedTaskRunnerWithTraits(
base::TaskTraits()
.WithPriority(base::TaskPriority::BACKGROUND)
@@ -425,8 +475,9 @@ void JumpList::OnMostVisitedURLsAvailable(
switches::kWinJumplistAction, jumplist::kMostVisitedCategory);
link->set_title(!url.title.empty() ? url.title : url_string_wide);
data->most_visited_pages_.push_back(link);
- data->icon_urls_.push_back(make_pair(url_string, link));
+ data->icon_urls_.push_back(std::make_pair(url_string, link));
}
+ data->most_visited_pages_have_updates_ = true;
}
// Send a query that retrieves the first favicon.
@@ -435,12 +486,9 @@ void JumpList::OnMostVisitedURLsAvailable(
void JumpList::TabRestoreServiceChanged(sessions::TabRestoreService* service) {
DCHECK(CalledOnValidThread());
- // if we have a pending handle request, cancel it here (it is out of date).
+ // if we have a pending favicon request, cancel it here (it is out of date).
CancelPendingUpdate();
- // local list to pass to methods
- ShellLinkItemList temp_list;
-
// Create a list of ShellLinkItems from the "Recently Closed" pages.
// As noted above, we create a ShellLinkItem objects with the following
// parameters.
@@ -455,24 +503,27 @@ void JumpList::TabRestoreServiceChanged(sessions::TabRestoreService* service) {
const int kRecentlyClosedCount = 3;
sessions::TabRestoreService* tab_restore_service =
TabRestoreServiceFactory::GetForProfile(profile_);
- for (const auto& entry : tab_restore_service->entries()) {
- switch (entry->type) {
- case sessions::TabRestoreService::TAB:
- AddTab(static_cast<const sessions::TabRestoreService::Tab&>(*entry),
- &temp_list, kRecentlyClosedCount);
- break;
- case sessions::TabRestoreService::WINDOW:
- AddWindow(
- static_cast<const sessions::TabRestoreService::Window&>(*entry),
- &temp_list, kRecentlyClosedCount);
- break;
- }
- }
- // Lock recently_closed_pages and copy temp_list into it.
+
{
JumpListData* data = &jumplist_data_->data;
base::AutoLock auto_lock(data->list_lock_);
- data->recently_closed_pages_ = temp_list;
+ data->recently_closed_pages_.clear();
+
+ for (const auto& entry : tab_restore_service->entries()) {
+ switch (entry->type) {
+ case sessions::TabRestoreService::TAB:
+ AddTab(static_cast<const sessions::TabRestoreService::Tab&>(*entry),
+ kRecentlyClosedCount, data);
+ break;
+ case sessions::TabRestoreService::WINDOW:
+ AddWindow(
+ static_cast<const sessions::TabRestoreService::Window&>(*entry),
+ kRecentlyClosedCount, data);
+ break;
+ }
+ }
+
+ data->recently_closed_pages_have_updates_ = true;
}
// Send a query that retrieves the first favicon.
@@ -483,13 +534,13 @@ void JumpList::TabRestoreServiceDestroyed(
sessions::TabRestoreService* service) {}
bool JumpList::AddTab(const sessions::TabRestoreService::Tab& tab,
- ShellLinkItemList* list,
- size_t max_items) {
+ size_t max_items,
+ JumpListData* data) {
DCHECK(CalledOnValidThread());
+ data->list_lock_.AssertAcquired();
- // This code adds the URL and the title strings of the given tab to the
- // specified list.
- if (list->size() >= max_items)
+ // This code adds the URL and the title strings of the given tab to |data|.
+ if (data->recently_closed_pages_.size() >= max_items)
return false;
scoped_refptr<ShellLinkItem> link = CreateShellLink();
@@ -497,29 +548,27 @@ bool JumpList::AddTab(const sessions::TabRestoreService::Tab& tab,
tab.navigations.at(tab.current_navigation_index);
std::string url = current_navigation.virtual_url().spec();
link->GetCommandLine()->AppendArgNative(base::UTF8ToWide(url));
- link->GetCommandLine()->AppendSwitchASCII(
- switches::kWinJumplistAction, jumplist::kRecentlyClosedCategory);
+ link->GetCommandLine()->AppendSwitchASCII(switches::kWinJumplistAction,
+ jumplist::kRecentlyClosedCategory);
link->set_title(current_navigation.title());
- list->push_back(link);
- {
- JumpListData* data = &jumplist_data_->data;
- base::AutoLock auto_lock(data->list_lock_);
- data->icon_urls_.push_back(std::make_pair(std::move(url), std::move(link)));
- }
+ data->recently_closed_pages_.push_back(link);
+ data->icon_urls_.push_back(std::make_pair(std::move(url), std::move(link)));
+
return true;
}
void JumpList::AddWindow(const sessions::TabRestoreService::Window& window,
- ShellLinkItemList* list,
- size_t max_items) {
+ size_t max_items,
+ JumpListData* data) {
DCHECK(CalledOnValidThread());
+ data->list_lock_.AssertAcquired();
- // This code enumerates al the tabs in the given window object and add their
- // URLs and titles to the list.
+ // This code enumerates all the tabs in the given window object and add their
+ // URLs and titles to |data|.
DCHECK(!window.tabs.empty());
for (const auto& tab : window.tabs) {
- if (!AddTab(*tab, list, max_items))
+ if (!AddTab(*tab, max_items, data))
return;
}
}
@@ -594,10 +643,12 @@ void JumpList::OnIncognitoAvailabilityChanged() {
base::AutoLock auto_lock(data->list_lock_);
waiting_for_icons = !data->icon_urls_.empty();
}
+
+ // Since neither the "Most Visited" category nor the "Recently Closed"
+ // category changes, mark the flags so that icon files for those categories
+ // won't be updated later on.
if (!waiting_for_icons)
PostRunUpdate();
- // If |icon_urls_| isn't empty then OnFaviconDataAvailable will eventually
- // call PostRunUpdate().
}
void JumpList::PostRunUpdate() {
@@ -625,17 +676,24 @@ void JumpList::DeferredRunUpdate() {
profile_ ? IncognitoModePrefs::GetAvailability(profile_->GetPrefs())
: IncognitoModePrefs::ENABLED;
- // Post a task to update the jumplist in JumpListIcons folder, which consists
- // of 1) delete old icons, 2) create new icons, 3) notify the OS.
- update_jumplisticons_task_runner_->PostTask(
+ // Post a task to update the JumpList, which consists of 1) delete old icons,
+ // 2) create new icons, 3) notify the OS.
+ update_jumplist_task_runner_->PostTask(
FROM_HERE, base::Bind(&RunUpdateJumpList, incognito_availability, app_id_,
icon_dir_, base::RetainedRef(jumplist_data_)));
- // Post a task to delete JumpListIconsOld folder and log the results to UMA.
+ // Post a task to delete JumpListIcons folder as it's no longer needed.
+ // Now we have JumpListIconsMostVisited folder and JumpListIconsRecentClosed
+ // folder instead.
+ delete_jumplisticons_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&DeleteDirectoryAndLogResults, icon_dir_, kFileDeleteLimit));
+
+ // Post a task to delete JumpListIconsOld folder as it's no longer needed.
base::FilePath icon_dir_old = icon_dir_.DirName().Append(
icon_dir_.BaseName().value() + FILE_PATH_LITERAL("Old"));
- delete_jumplisticonsold_task_runner_->PostTask(
+ delete_jumplisticons_task_runner_->PostTask(
FROM_HERE, base::Bind(&DeleteDirectoryAndLogResults,
std::move(icon_dir_old), kFileDeleteLimit));
}
« 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