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

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

Issue 2831433003: Time out jumplist update for very slow or busy OS (Closed)
Patch Set: Mark retired metrics obsolete in histograms.xml 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 unified diff | Download patch
« no previous file with comments | « chrome/browser/win/OWNERS ('k') | tools/metrics/histograms/histograms.xml » ('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 <utility> 7 #include <utility>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
11 #include "base/command_line.h" 11 #include "base/command_line.h"
12 #include "base/files/file_util.h" 12 #include "base/files/file_util.h"
13 #include "base/macros.h" 13 #include "base/macros.h"
14 #include "base/metrics/histogram_macros.h" 14 #include "base/metrics/histogram_macros.h"
15 #include "base/path_service.h" 15 #include "base/path_service.h"
16 #include "base/sequenced_task_runner.h" 16 #include "base/sequenced_task_runner.h"
17 #include "base/single_thread_task_runner.h" 17 #include "base/single_thread_task_runner.h"
18 #include "base/strings/string_util.h" 18 #include "base/strings/string_util.h"
19 #include "base/strings/utf_string_conversions.h" 19 #include "base/strings/utf_string_conversions.h"
20 #include "base/task_scheduler/post_task.h" 20 #include "base/task_scheduler/post_task.h"
21 #include "base/threading/thread.h" 21 #include "base/threading/thread.h"
22 #include "base/threading/thread_restrictions.h" 22 #include "base/threading/thread_restrictions.h"
23 #include "base/timer/elapsed_timer.h"
23 #include "base/trace_event/trace_event.h" 24 #include "base/trace_event/trace_event.h"
24 #include "chrome/browser/chrome_notification_types.h" 25 #include "chrome/browser/chrome_notification_types.h"
25 #include "chrome/browser/favicon/favicon_service_factory.h" 26 #include "chrome/browser/favicon/favicon_service_factory.h"
26 #include "chrome/browser/history/top_sites_factory.h" 27 #include "chrome/browser/history/top_sites_factory.h"
27 #include "chrome/browser/metrics/jumplist_metrics_win.h" 28 #include "chrome/browser/metrics/jumplist_metrics_win.h"
28 #include "chrome/browser/profiles/profile.h" 29 #include "chrome/browser/profiles/profile.h"
29 #include "chrome/browser/sessions/tab_restore_service_factory.h" 30 #include "chrome/browser/sessions/tab_restore_service_factory.h"
30 #include "chrome/browser/shell_integration_win.h" 31 #include "chrome/browser/shell_integration_win.h"
31 #include "chrome/browser/win/jumplist_file_util.h" 32 #include "chrome/browser/win/jumplist_file_util.h"
32 #include "chrome/common/chrome_constants.h" 33 #include "chrome/common/chrome_constants.h"
(...skipping 24 matching lines...) Expand all
57 #include "ui/gfx/image/image_skia.h" 58 #include "ui/gfx/image/image_skia.h"
58 #include "ui/gfx/image/image_skia_rep.h" 59 #include "ui/gfx/image/image_skia_rep.h"
59 #include "url/gurl.h" 60 #include "url/gurl.h"
60 61
61 using content::BrowserThread; 62 using content::BrowserThread;
62 using JumpListData = JumpList::JumpListData; 63 using JumpListData = JumpList::JumpListData;
63 64
64 namespace { 65 namespace {
65 66
66 // Delay jumplist updates to allow collapsing of redundant update requests. 67 // Delay jumplist updates to allow collapsing of redundant update requests.
67 const int kDelayForJumplistUpdateInMS = 3500; 68 constexpr base::TimeDelta kDelayForJumplistUpdateInMS =
grt (UTC plus 2) 2017/04/21 10:11:25 remove "InMS" since this is a TimeDelta (as i prop
chengx 2017/04/21 18:51:20 Done.
69 base::TimeDelta::FromMilliseconds(3500);
70
71 // Timeout jumplist updates for users with extremely slow OS.
72 constexpr base::TimeDelta kTimeOutForJumplistUpdateInMS =
73 base::TimeDelta::FromMilliseconds(500);
68 74
69 // Append the common switches to each shell link. 75 // Append the common switches to each shell link.
70 void AppendCommonSwitches(ShellLinkItem* shell_link) { 76 void AppendCommonSwitches(ShellLinkItem* shell_link) {
71 const char* kSwitchNames[] = { switches::kUserDataDir }; 77 const char* kSwitchNames[] = { switches::kUserDataDir };
72 const base::CommandLine& command_line = 78 const base::CommandLine& command_line =
73 *base::CommandLine::ForCurrentProcess(); 79 *base::CommandLine::ForCurrentProcess();
74 shell_link->GetCommandLine()->CopySwitchesFrom(command_line, 80 shell_link->GetCommandLine()->CopySwitchesFrom(command_line,
75 kSwitchNames, 81 kSwitchNames,
76 arraysize(kSwitchNames)); 82 arraysize(kSwitchNames));
77 } 83 }
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 base::ReplaceSubstringsAfterOffset( 175 base::ReplaceSubstringsAfterOffset(
170 &incognito_title, 0, L"&", base::StringPiece16()); 176 &incognito_title, 0, L"&", base::StringPiece16());
171 incognito->set_title(incognito_title); 177 incognito->set_title(incognito_title);
172 incognito->set_icon(chrome_path.value(), icon_resources::kIncognitoIndex); 178 incognito->set_icon(chrome_path.value(), icon_resources::kIncognitoIndex);
173 items.push_back(incognito); 179 items.push_back(incognito);
174 } 180 }
175 181
176 return jumplist_updater->AddTasks(items); 182 return jumplist_updater->AddTasks(items);
177 } 183 }
178 184
179 // Updates the application JumpList. 185 // Updates the application JumpList.
grt (UTC plus 2) 2017/04/21 10:11:25 please document that any error along the way resul
chengx 2017/04/21 18:51:20 Documentation added.
180 bool UpdateJumpList(const wchar_t* app_id, 186 bool UpdateJumpList(const wchar_t* app_id,
grt (UTC plus 2) 2017/04/21 10:11:25 this return value is undocumented and ignored. how
chengx 2017/04/21 18:51:20 I've updated it to return void.
181 const base::FilePath& icon_dir, 187 const base::FilePath& icon_dir,
182 const ShellLinkItemList& most_visited_pages, 188 const ShellLinkItemList& most_visited_pages,
183 const ShellLinkItemList& recently_closed_pages, 189 const ShellLinkItemList& recently_closed_pages,
184 IncognitoModePrefs::Availability incognito_availability) { 190 IncognitoModePrefs::Availability incognito_availability) {
185 // JumpList is implemented only on Windows 7 or later. 191 // JumpList is implemented only on Windows 7 or later.
grt (UTC plus 2) 2017/04/21 10:11:25 This comment is out-of-date -- Chrome doesn't run
chengx 2017/04/21 18:51:20 Comments removed.
186 // So, we should return now when this function is called on earlier versions 192 // So, we should return now when this function is called on earlier versions
187 // of Windows. 193 // of Windows.
188 if (!JumpListUpdater::IsEnabled()) 194 if (!JumpListUpdater::IsEnabled())
189 return true; 195 return true;
190 196
197 // Records the time cost of starting a JumpListUpdater.
198 base::ElapsedTimer begin_update_timer;
199
191 JumpListUpdater jumplist_updater(app_id); 200 JumpListUpdater jumplist_updater(app_id);
192 if (!jumplist_updater.BeginUpdate()) 201 if (!jumplist_updater.BeginUpdate())
193 return false; 202 return false;
194 203
204 // Stops jumplist update if JumpListUpdater's start times out, as it's very
205 // likely the following update steps will also take a long time.
206 if (begin_update_timer.Elapsed() >= kTimeOutForJumplistUpdateInMS)
207 return false;
208
195 // We allocate 60% of the given JumpList slots to "most-visited" items 209 // We allocate 60% of the given JumpList slots to "most-visited" items
196 // and 40% to "recently-closed" items, respectively. 210 // and 40% to "recently-closed" items, respectively.
197 // Nevertheless, if there are not so many items in |recently_closed_pages|, 211 // Nevertheless, if there are not so many items in |recently_closed_pages|,
198 // we give the remaining slots to "most-visited" items. 212 // we give the remaining slots to "most-visited" items.
199 // The default maximum number of items to display in JumpList is 10. 213 // The default maximum number of items to display in JumpList is 10.
200 // https://msdn.microsoft.com/en-us/library/windows/desktop/dd378398(v=vs.85). aspx 214 // https://msdn.microsoft.com/en-us/library/windows/desktop/dd378398(v=vs.85). aspx
201 const int kMostVisited = 60; 215 const int kMostVisited = 60;
202 const int kRecentlyClosed = 40; 216 const int kRecentlyClosed = 40;
203 const int kTotal = kMostVisited + kRecentlyClosed; 217 const int kTotal = kMostVisited + kRecentlyClosed;
204 size_t most_visited_items = 218 size_t most_visited_items =
205 MulDiv(jumplist_updater.user_max_items(), kMostVisited, kTotal); 219 MulDiv(jumplist_updater.user_max_items(), kMostVisited, kTotal);
206 size_t recently_closed_items = 220 size_t recently_closed_items =
207 jumplist_updater.user_max_items() - most_visited_items; 221 jumplist_updater.user_max_items() - most_visited_items;
208 if (recently_closed_pages.size() < recently_closed_items) { 222 if (recently_closed_pages.size() < recently_closed_items) {
209 most_visited_items += recently_closed_items - recently_closed_pages.size(); 223 most_visited_items += recently_closed_items - recently_closed_pages.size();
210 recently_closed_items = recently_closed_pages.size(); 224 recently_closed_items = recently_closed_pages.size();
211 } 225 }
212 226
213 // Delete the content in JumpListIcons folder and log the results to UMA. 227 // Delete the content in JumpListIcons folder and log the results to UMA.
214 DeleteDirectoryContentAndLogResults(icon_dir, kFileDeleteLimit); 228 DeleteDirectoryContentAndLogResults(icon_dir, kFileDeleteLimit);
215 229
216 // If JumpListIcons directory doesn't exist (we have tried to create it 230 // If JumpListIcons directory doesn't exist (we have tried to create it
217 // already) or is not empty, skip updating the jumplist icons. The jumplist 231 // already) or is not empty, skip updating the jumplist icons. The jumplist
218 // links should be updated anyway, as it doesn't involve disk IO. In this 232 // links should be updated anyway, as it doesn't involve disk IO. In this
219 // case, Chrome's icon will be used for the new links. 233 // case, Chrome's icon will be used for the new links.
220 234
221 if (base::DirectoryExists(icon_dir) && base::IsDirectoryEmpty(icon_dir)) { 235 bool is_dir_existed_and_empty =
grt (UTC plus 2) 2017/04/21 10:11:25 is_dir_existed_and_empty -> should_create_icons
chengx 2017/04/21 18:51:20 Done.
222 // TODO(chengx): Remove this UMA metric after fixing http://crbug.com/40407. 236 base::DirectoryExists(icon_dir) && base::IsDirectoryEmpty(icon_dir);
223 UMA_HISTOGRAM_COUNTS_100(
224 "WinJumplist.CreateIconFilesCount",
225 most_visited_pages.size() + recently_closed_pages.size());
226 237
227 // Create icon files for shortcuts in the "Most Visited" category. 238 // Create icon files for shortcuts in the "Most Visited" category.
239 if (is_dir_existed_and_empty)
228 CreateIconFiles(icon_dir, most_visited_pages, most_visited_items); 240 CreateIconFiles(icon_dir, most_visited_pages, most_visited_items);
229 241
230 // Create icon files for shortcuts in the "Recently Closed" category.
231 CreateIconFiles(icon_dir, recently_closed_pages, recently_closed_items);
232 }
233
234 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407.
235 SCOPED_UMA_HISTOGRAM_TIMER("WinJumplist.UpdateJumpListDuration");
236
237 // Update the "Most Visited" category of the JumpList if it exists. 242 // Update the "Most Visited" category of the JumpList if it exists.
238 // This update request is applied into the JumpList when we commit this 243 // This update request is applied into the JumpList when we commit this
239 // transaction. 244 // transaction.
240 if (!jumplist_updater.AddCustomCategory( 245 if (!jumplist_updater.AddCustomCategory(
241 l10n_util::GetStringUTF16(IDS_NEW_TAB_MOST_VISITED), 246 l10n_util::GetStringUTF16(IDS_NEW_TAB_MOST_VISITED),
242 most_visited_pages, most_visited_items)) { 247 most_visited_pages, most_visited_items)) {
243 return false; 248 return false;
244 } 249 }
245 250
251 // Create icon files for shortcuts in the "Recently Closed" category.
252 if (is_dir_existed_and_empty)
253 CreateIconFiles(icon_dir, recently_closed_pages, recently_closed_items);
254
246 // Update the "Recently Closed" category of the JumpList. 255 // Update the "Recently Closed" category of the JumpList.
247 if (!jumplist_updater.AddCustomCategory( 256 if (!jumplist_updater.AddCustomCategory(
248 l10n_util::GetStringUTF16(IDS_RECENTLY_CLOSED), 257 l10n_util::GetStringUTF16(IDS_RECENTLY_CLOSED),
249 recently_closed_pages, recently_closed_items)) { 258 recently_closed_pages, recently_closed_items)) {
250 return false; 259 return false;
251 } 260 }
252 261
253 // Update the "Tasks" category of the JumpList. 262 // Update the "Tasks" category of the JumpList.
254 if (!UpdateTaskCategory(&jumplist_updater, incognito_availability)) 263 if (!UpdateTaskCategory(&jumplist_updater, incognito_availability))
255 return false; 264 return false;
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
588 DCHECK(CalledOnValidThread()); 597 DCHECK(CalledOnValidThread());
589 598
590 TRACE_EVENT0("browser", "JumpList::PostRunUpdate"); 599 TRACE_EVENT0("browser", "JumpList::PostRunUpdate");
591 // Initialize the one-shot timer to update the jumplists in a while. 600 // Initialize the one-shot timer to update the jumplists in a while.
592 // If there is already a request queued then cancel it and post the new 601 // If there is already a request queued then cancel it and post the new
593 // request. This ensures that JumpListUpdates won't happen until there has 602 // request. This ensures that JumpListUpdates won't happen until there has
594 // been a brief quiet period, thus avoiding update storms. 603 // been a brief quiet period, thus avoiding update storms.
595 if (timer_.IsRunning()) { 604 if (timer_.IsRunning()) {
596 timer_.Reset(); 605 timer_.Reset();
597 } else { 606 } else {
598 timer_.Start(FROM_HERE, 607 timer_.Start(FROM_HERE, kDelayForJumplistUpdateInMS, this,
599 base::TimeDelta::FromMilliseconds(kDelayForJumplistUpdateInMS),
600 this,
601 &JumpList::DeferredRunUpdate); 608 &JumpList::DeferredRunUpdate);
602 } 609 }
603 } 610 }
604 611
605 void JumpList::DeferredRunUpdate() { 612 void JumpList::DeferredRunUpdate() {
606 DCHECK(CalledOnValidThread()); 613 DCHECK(CalledOnValidThread());
607 614
608 TRACE_EVENT0("browser", "JumpList::DeferredRunUpdate"); 615 TRACE_EVENT0("browser", "JumpList::DeferredRunUpdate");
609 // Check if incognito windows (or normal windows) are disabled by policy. 616 // Check if incognito windows (or normal windows) are disabled by policy.
610 IncognitoModePrefs::Availability incognito_availability = 617 IncognitoModePrefs::Availability incognito_availability =
(...skipping 18 matching lines...) Expand all
629 void JumpList::TopSitesLoaded(history::TopSites* top_sites) { 636 void JumpList::TopSitesLoaded(history::TopSites* top_sites) {
630 } 637 }
631 638
632 void JumpList::TopSitesChanged(history::TopSites* top_sites, 639 void JumpList::TopSitesChanged(history::TopSites* top_sites,
633 ChangeReason change_reason) { 640 ChangeReason change_reason) {
634 top_sites->GetMostVisitedURLs( 641 top_sites->GetMostVisitedURLs(
635 base::Bind(&JumpList::OnMostVisitedURLsAvailable, 642 base::Bind(&JumpList::OnMostVisitedURLsAvailable,
636 weak_ptr_factory_.GetWeakPtr()), 643 weak_ptr_factory_.GetWeakPtr()),
637 false); 644 false);
638 } 645 }
OLDNEW
« no previous file with comments | « chrome/browser/win/OWNERS ('k') | tools/metrics/histograms/histograms.xml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698