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

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

Issue 2752063002: Remove JumpListIconsOld directory and set upper limit for delete attempts (Closed)
Patch Set: Address comments. Created 3 years, 9 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 <Shlwapi.h> 7 #include <Shlwapi.h>
8 #include <windows.h> 8 #include <windows.h>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/bind_helpers.h" 11 #include "base/bind_helpers.h"
12 #include "base/callback_helpers.h" 12 #include "base/callback_helpers.h"
13 #include "base/command_line.h" 13 #include "base/command_line.h"
14 #include "base/files/file_enumerator.h"
14 #include "base/files/file_util.h" 15 #include "base/files/file_util.h"
15 #include "base/macros.h" 16 #include "base/macros.h"
16 #include "base/metrics/histogram_macros.h" 17 #include "base/metrics/histogram_macros.h"
17 #include "base/path_service.h" 18 #include "base/path_service.h"
18 #include "base/strings/string_util.h" 19 #include "base/strings/string_util.h"
19 #include "base/strings/utf_string_conversions.h" 20 #include "base/strings/utf_string_conversions.h"
21 #include "base/task_scheduler/post_task.h"
20 #include "base/threading/thread.h" 22 #include "base/threading/thread.h"
21 #include "base/threading/thread_restrictions.h" 23 #include "base/threading/thread_restrictions.h"
22 #include "base/trace_event/trace_event.h" 24 #include "base/trace_event/trace_event.h"
23 #include "chrome/browser/chrome_notification_types.h" 25 #include "chrome/browser/chrome_notification_types.h"
24 #include "chrome/browser/favicon/favicon_service_factory.h" 26 #include "chrome/browser/favicon/favicon_service_factory.h"
25 #include "chrome/browser/history/top_sites_factory.h" 27 #include "chrome/browser/history/top_sites_factory.h"
26 #include "chrome/browser/metrics/jumplist_metrics_win.h" 28 #include "chrome/browser/metrics/jumplist_metrics_win.h"
27 #include "chrome/browser/profiles/profile.h" 29 #include "chrome/browser/profiles/profile.h"
28 #include "chrome/browser/sessions/tab_restore_service_factory.h" 30 #include "chrome/browser/sessions/tab_restore_service_factory.h"
29 #include "chrome/browser/shell_integration_win.h" 31 #include "chrome/browser/shell_integration_win.h"
(...skipping 26 matching lines...) Expand all
56 #include "url/gurl.h" 58 #include "url/gurl.h"
57 59
58 using content::BrowserThread; 60 using content::BrowserThread;
59 using JumpListData = JumpList::JumpListData; 61 using JumpListData = JumpList::JumpListData;
60 62
61 namespace { 63 namespace {
62 64
63 // Delay jumplist updates to allow collapsing of redundant update requests. 65 // Delay jumplist updates to allow collapsing of redundant update requests.
64 const int kDelayForJumplistUpdateInMS = 3500; 66 const int kDelayForJumplistUpdateInMS = 3500;
65 67
68 // Maximum number of icon files allowed to delete per update
69 const int kMaxIconFilesDeletedPerUpdate = 100;
70
66 // Append the common switches to each shell link. 71 // Append the common switches to each shell link.
67 void AppendCommonSwitches(ShellLinkItem* shell_link) { 72 void AppendCommonSwitches(ShellLinkItem* shell_link) {
68 const char* kSwitchNames[] = { switches::kUserDataDir }; 73 const char* kSwitchNames[] = { switches::kUserDataDir };
69 const base::CommandLine& command_line = 74 const base::CommandLine& command_line =
70 *base::CommandLine::ForCurrentProcess(); 75 *base::CommandLine::ForCurrentProcess();
71 shell_link->GetCommandLine()->CopySwitchesFrom(command_line, 76 shell_link->GetCommandLine()->CopySwitchesFrom(command_line,
72 kSwitchNames, 77 kSwitchNames,
73 arraysize(kSwitchNames)); 78 arraysize(kSwitchNames));
74 } 79 }
75 80
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
222 if (!UpdateTaskCategory(&jumplist_updater, incognito_availability)) 227 if (!UpdateTaskCategory(&jumplist_updater, incognito_availability))
223 return false; 228 return false;
224 229
225 // Commit this transaction and send the updated JumpList to Windows. 230 // Commit this transaction and send the updated JumpList to Windows.
226 if (!jumplist_updater.CommitUpdate()) 231 if (!jumplist_updater.CommitUpdate())
227 return false; 232 return false;
228 233
229 return true; 234 return true;
230 } 235 }
231 236
232 // Renames the directory |from_dir| to |to_path|. This method fails if any 237 // Folder delete status enumeration, used in Delete* methods below.
233 // process has a handle open in |from_dir| or if |to_path| exists. Base::Move() 238 // This is used for UMA. Do not delete entries, and keep in sync with
234 // tries to rename a file and if this fails, it tries copy-n-delete; This 239 // histograms.xml.
235 // RenameDirectory method only does the rename part. 240 enum FolderDeleteResult {
236 bool RenameDirectory(const base::FilePath& from_path, 241 SUCCEED = 0,
237 const base::FilePath& to_path) { 242 // File name's length exceeds MAX_PATH. This won't happen.
243 FAIL_INVALID_FILE_PATH,
244 // JumpListIcons{,Old} directories are read-only. This may heppen.
245 FAIL_READ_ONLY_DIRECTORY,
246 // Since JumpListIcons{,Old} are directories, this won't happen.
247 FAIL_DELETE_SINGLE_FILE,
248 // Delete maximum files allowed succeeds. However, in the process of deleting
249 // these files, it fails to delete some other files. This may happen.
250 FAIL_DELETE_MAX_FILE_PERFECTLY,
251 // Fail to delete maximum files allowed when the maximum attempts allowed
252 // have been used. This may heppen.
253 FAIL_DELETE_MAX_FILES_ANYWAY,
254 // Add new items before this one, always keep this one at the end.
255 END
256 };
257
258 // This method is similar to base::DeleteFileRecursive in
259 // file_util_win.cc with the following differences.
260 // 1) It forces deleting files recursively.
261 // 2) It has a boolean input parameter |has_upper_limit|. When it is set to
262 // true, this method returns false when the files deleted exceeds
263 // |kMaxIconFilesDeletedPerUpdate| or the files failed to be deleted exceeds
264 // |kMaxIconFilesDeletedPerUpdate| per directory (e.g., |path| if it is
265 // a directory or any of its sub-directories). When it is set to false, all
266 // files under |path| are deleted.
267 // 3) Failure cause is recored in |delete_status|.
268 bool DeleteFileRecursive(const base::FilePath& path,
grt (UTC plus 2) 2017/03/21 08:40:26 if this is only called to do recursive deletes on
chengx 2017/03/22 06:46:28 Done. Renamed to "DeleteDirectoryRecursive".
269 const base::FilePath::StringType& pattern,
270 bool has_upper_limit,
271 int* delete_status) {
grt (UTC plus 2) 2017/03/21 08:40:27 int* -> FolderDeleteResult*
chengx 2017/03/22 06:46:27 Done.
272 base::FileEnumerator traversal(
273 path, false,
274 base::FileEnumerator::FILES | base::FileEnumerator::DIRECTORIES, pattern);
275 int file_deleted = 0, file_fail_to_deted = 0;
grt (UTC plus 2) 2017/03/21 08:40:26 file_fail_to_deted -> failure_count
grt (UTC plus 2) 2017/03/21 08:40:27 file_deleted -> attempt_count
grt (UTC plus 2) 2017/03/21 08:40:27 nit: one definition per line, please
chengx 2017/03/22 06:46:28 I will rename it to |success_count|. I think if we
chengx 2017/03/22 06:46:28 Done.
chengx 2017/03/22 06:46:28 Done.
276 for (base::FilePath current = traversal.Next(); !current.empty();
277 current = traversal.Next(), file_deleted++) {
278 // Try to clear the read-only bit if we find it.
279 base::FileEnumerator::FileInfo info = traversal.GetInfo();
280 if (info.find_data().dwFileAttributes & FILE_ATTRIBUTE_READONLY) {
281 SetFileAttributes(
282 current.value().c_str(),
283 info.find_data().dwFileAttributes & ~FILE_ATTRIBUTE_READONLY);
284 }
285
286 if (info.IsDirectory()) {
287 // If DeleteFileRecursive or RemoveDirectory fails, return false
288 // intermediately.
289 if (!DeleteFileRecursive(current, pattern, has_upper_limit,
290 delete_status) ||
291 !::RemoveDirectory(current.value().c_str())) {
292 return false;
293 }
294 } else if (!::DeleteFile(current.value().c_str())) {
295 // If there is no upper limit, return false intermediately. Otherwise,
296 // increment |file_fail_to_deted| until it hits the upper limit.
297 if (!has_upper_limit)
298 return false;
299 file_fail_to_deted++;
grt (UTC plus 2) 2017/03/21 08:40:27 since you don't decrement file_deleted here, it's
chengx 2017/03/22 06:46:27 You are right. It's actually a count of the # of a
300 }
301 // If it successfully deletes |kMaxIconFilesDeletedPerUpdate| files, return
302 // true. If some files fail to be delete, record this information in
303 // |delete_status|.
304 if (has_upper_limit && file_deleted > kMaxIconFilesDeletedPerUpdate) {
grt (UTC plus 2) 2017/03/21 08:40:26 ? file_deleted >= kMaxIconFilesDeletedPerUpdate ?
chengx 2017/03/22 06:46:28 Done.
305 if (file_fail_to_deted > 0)
306 *delete_status = FAIL_DELETE_MAX_FILE_PERFECTLY;
307 return true;
308 }
309 // Return false when failing to delete |kMaxIconFilesDeletedPerUpdate| files
310 // comes before successfully deleting |kMaxIconFilesDeletedPerUpdate| files.
311 if (has_upper_limit && file_fail_to_deted > kMaxIconFilesDeletedPerUpdate) {
312 *delete_status = FAIL_DELETE_MAX_FILES_ANYWAY;
313 return false;
314 }
315 }
316 return true;
317 }
318
319 // This method is similar to base::DeleteFile in file_util_win.cc
320 // with the following differences.
321 // 1) It forces deleting files recursively.
322 // 2) If |path| is a directory, it won't be deleted even if all its contents are
323 // deleted successfully.
324 // 3) It has a boolean input parameter |has_upper_limit|. When it is set to
325 // true, this method returns false when the files deleted exceeds
326 // |kMaxIconFilesDeletedPerUpdate| or the files fail to be deleted exceeds
327 // |kMaxIconFilesDeletedPerUpdate| per directory (e.g., under path if it is
328 // a directory or any of its sub-directory). When it is set to false, all
329 // files under path are trying to be deleted.
330 // 4) Failure cause is recored in |delete_status|.
331 bool DeleteDirectoryContent(const base::FilePath& path,
332 bool has_upper_limit,
333 int* delete_status) {
grt (UTC plus 2) 2017/03/21 08:40:26 int* -> FolderDeleteResult*
chengx 2017/03/22 06:46:27 Done.
238 base::ThreadRestrictions::AssertIOAllowed(); 334 base::ThreadRestrictions::AssertIOAllowed();
239 if (from_path.ReferencesParent() || to_path.ReferencesParent()) 335
240 return false; 336 if (path.empty())
241 if (from_path.value().length() >= MAX_PATH || 337 return true;
242 to_path.value().length() >= MAX_PATH) { 338
339 if (path.value().length() >= MAX_PATH) {
340 *delete_status = FAIL_INVALID_FILE_PATH;
243 return false; 341 return false;
244 } 342 }
245 return MoveFileEx(from_path.value().c_str(), to_path.value().c_str(), 0) != 0; 343
344 DWORD attr = GetFileAttributes(path.value().c_str());
345 // We're done if we can't find the path.
346 if (attr == INVALID_FILE_ATTRIBUTES)
347 return true;
348 // We may need to clear the read-only bit.
349 if ((attr & FILE_ATTRIBUTE_READONLY) &&
350 !SetFileAttributes(path.value().c_str(),
351 attr & ~FILE_ATTRIBUTE_READONLY)) {
352 *delete_status = FAIL_READ_ONLY_DIRECTORY;
353 return false;
354 }
355 // If |path| is a file, simply delete it.
grt (UTC plus 2) 2017/03/21 08:40:26 this is never expected to be hit, but i agree that
chengx 2017/03/22 06:46:27 Done.
356 if (!(attr & FILE_ATTRIBUTE_DIRECTORY)) {
357 bool delete_result = !!::DeleteFile(path.value().c_str());
358 if (!delete_result)
359 *delete_status = FAIL_DELETE_SINGLE_FILE;
360 return delete_result;
361 }
362 // If |path| is a directory, delete all its content but save the raw
363 // directory.
364 return DeleteFileRecursive(path, L"*", has_upper_limit, delete_status);
365 }
366
367 // This method is similar to base::DeleteFile in file_util_win.cc
368 // with the following differences.
369 // 1) It forces deleting files recursively.
370 // 2) It runs in the asynchronous manner, so there is no return value.
371 // 3) It has a boolean input parameter |has_upper_limit|. When it is set to
372 // true, this method returns false when the files deleted exceeds
373 // |kMaxIconFilesDeletedPerUpdate| or the files fail to be deleted exceeds
374 // |kMaxIconFilesDeletedPerUpdate| per directory (e.g., under path if it is
375 // a directory or any of its sub-directory). When it is set to false, all
376 // files under path are trying to be deleted.
377 // 4) Failure cause is recored in |delete_status|.
378 void DeleteDirectory(const base::FilePath& path,
379 bool has_upper_limit,
380 int* delete_status) {
grt (UTC plus 2) 2017/03/21 08:40:26 int* -> FolderDeleteResult*
chengx 2017/03/22 06:46:28 Done.
381 base::ThreadRestrictions::AssertIOAllowed();
382
383 if (path.empty())
384 return;
385
386 if (path.value().length() >= MAX_PATH) {
387 *delete_status = FAIL_INVALID_FILE_PATH;
388 return;
389 }
390
391 DWORD attr = GetFileAttributes(path.value().c_str());
392 // We're done if we can't find the path.
393 if (attr == INVALID_FILE_ATTRIBUTES)
394 return;
395 // We may need to clear the read-only bit.
396 if ((attr & FILE_ATTRIBUTE_READONLY) &&
397 !SetFileAttributes(path.value().c_str(),
398 attr & ~FILE_ATTRIBUTE_READONLY)) {
399 *delete_status = FAIL_READ_ONLY_DIRECTORY;
400 return;
401 }
402 // If |path| is a file, delete it.
403 if (!(attr & FILE_ATTRIBUTE_DIRECTORY)) {
404 ::DeleteFile(path.value().c_str());
405 *delete_status = FAIL_DELETE_SINGLE_FILE;
406 return;
407 }
408 // If |path| is a directory, delete its contents and if it succeeds, remove
409 // the raw directory.
410 if (DeleteFileRecursive(path, L"*", has_upper_limit, delete_status))
411 ::RemoveDirectory(path.value().c_str());
412 return;
413 }
414
415 // Call DeleteDirectory method and then log the delete status using
416 // UMA_HISTOGRAM_ENUMERATION.
Ilya Sherman 2017/03/21 20:56:44 This comment literally just repeats the code, whic
chengx 2017/03/22 06:46:27 Done.
417 void DeleteDirectoryAndLogResults(const base::FilePath& path,
418 bool has_upper_limit,
419 int* delete_status,
420 std::string histogram_name) {
Ilya Sherman 2017/03/21 20:56:45 Why are you passing this string by copy?
chengx 2017/03/22 06:46:28 This parameter is removed in the new patch set.
421 DeleteDirectory(path, has_upper_limit, delete_status);
422 UMA_HISTOGRAM_ENUMERATION(histogram_name, *delete_status, END);
grt (UTC plus 2) 2017/03/21 08:40:26 the UMA macros cannot be used with a generated his
Ilya Sherman 2017/03/21 20:56:44 You can also use UmaHistogramEnumeration() from hi
chengx 2017/03/22 06:46:27 The name parameter is removed.
chengx 2017/03/22 06:46:28 I have changed to use "WinJumplist.DeleteStatusJum
246 } 423 }
247 424
248 // Updates the jumplist, once all the data has been fetched. 425 // Updates the jumplist, once all the data has been fetched.
249 void RunUpdateOnFileThread( 426 void RunUpdateOnFileThread(
250 IncognitoModePrefs::Availability incognito_availability, 427 IncognitoModePrefs::Availability incognito_availability,
251 const std::wstring& app_id, 428 const std::wstring& app_id,
252 const base::FilePath& icon_dir, 429 const base::FilePath& icon_dir,
253 base::RefCountedData<JumpListData>* ref_counted_data) { 430 base::RefCountedData<JumpListData>* ref_counted_data) {
254 JumpListData* data = &ref_counted_data->data; 431 JumpListData* data = &ref_counted_data->data;
255 ShellLinkItemList local_most_visited_pages; 432 ShellLinkItemList local_most_visited_pages;
256 ShellLinkItemList local_recently_closed_pages; 433 ShellLinkItemList local_recently_closed_pages;
257 434
258 { 435 {
259 base::AutoLock auto_lock(data->list_lock_); 436 base::AutoLock auto_lock(data->list_lock_);
260 // Make sure we are not out of date: if icon_urls_ is not empty, then 437 // Make sure we are not out of date: if icon_urls_ is not empty, then
261 // another notification has been received since we processed this one 438 // another notification has been received since we processed this one
262 if (!data->icon_urls_.empty()) 439 if (!data->icon_urls_.empty())
263 return; 440 return;
264 441
265 // Make local copies of lists so we can release the lock. 442 // Make local copies of lists so we can release the lock.
266 local_most_visited_pages = data->most_visited_pages_; 443 local_most_visited_pages = data->most_visited_pages_;
267 local_recently_closed_pages = data->recently_closed_pages_; 444 local_recently_closed_pages = data->recently_closed_pages_;
268 } 445 }
269 446
270 // Delete the directory which contains old icon files, rename the current 447 // This variable records the delete status of folder JumpListIcons.
271 // icon directory, and create a new directory which contains new JumpList 448 int folder_delete_status = SUCCEED;
grt (UTC plus 2) 2017/03/21 08:40:26 int -> FolderDeleteResult
chengx 2017/03/22 06:46:28 Done.
272 // icon files.
273 base::FilePath icon_dir_old = icon_dir.DirName().Append(
274 icon_dir.BaseName().value() + FILE_PATH_LITERAL("Old"));
275
276 enum FolderOperationResult {
277 SUCCESS = 0,
278 DELETE_DEST_FAILED = 1 << 0,
279 RENAME_FAILED = 1 << 1,
280 DELETE_SRC_CONTENT_FAILED = 1 << 2,
281 DELETE_SRC_DIR_FAILED = 1 << 3,
282 CREATE_SRC_FAILED = 1 << 4,
283 // This value is beyond the sum of all bit fields above and
284 // should remain last (shifted by one more than the last value)
285 END = 1 << 5
286 };
287
288 // This variable records the status of three folder operations.
289 uint32_t folder_operation_status = FolderOperationResult::SUCCESS;
290 449
291 base::ScopedClosureRunner log_operation_status_when_done(base::Bind( 450 base::ScopedClosureRunner log_operation_status_when_done(base::Bind(
292 [](uint32_t* folder_operation_status_ptr) { 451 [](int* folder_delete_status_ptr) {
293 UMA_HISTOGRAM_ENUMERATION( 452 UMA_HISTOGRAM_ENUMERATION("WinJumplist.DeleteStatusJumpListIcons",
294 "WinJumplist.DetailedFolderResultsDeleteUpdated", 453 *folder_delete_status_ptr, END);
295 *folder_operation_status_ptr, FolderOperationResult::END);
296 }, 454 },
297 base::Unretained(&folder_operation_status))); 455 base::Unretained(&folder_delete_status)));
298 456
299 // If deletion of |icon_dir_old| fails, do not rename |icon_dir| to 457 // If failing to delete the content in |icon_dir|, exit early.
300 // |icon_dir_old|, instead, delete |icon_dir| directly to avoid bloating 458 if (!DeleteDirectoryContent(icon_dir, true, &folder_delete_status)) {
301 // |icon_dir_old| by moving more things to it.
302 if (!base::DeleteFile(icon_dir_old, true)) {
303 folder_operation_status |= FolderOperationResult::DELETE_DEST_FAILED;
304 // If deletion of any item in |icon_dir| fails, exit early. If deletion of
305 // all the items succeeds while only deletion of the dir fails, it is okay
306 // to proceed. This skips creating the same directory and updating jumplist
307 // icons to avoid bloating the JumplistIcons folder.
308 if (!base::DeleteFile(icon_dir, true)) {
309 if (!::PathIsDirectoryEmpty(icon_dir.value().c_str())) {
310 folder_operation_status |=
311 FolderOperationResult::DELETE_SRC_CONTENT_FAILED;
312 return;
313 }
314 folder_operation_status |= FolderOperationResult::DELETE_SRC_DIR_FAILED;
315 }
316 } else if (!RenameDirectory(icon_dir, icon_dir_old)) {
317 // If RenameDirectory() fails, delete |icon_dir| to avoid file accumulation
318 // in this directory, which can eventually lead the folder to be huge.
319 folder_operation_status |= FolderOperationResult::RENAME_FAILED;
320 // If deletion of any item in |icon_dir| fails, exit early. If deletion of
321 // all the items succeeds while only deletion of the dir fails, it is okay
322 // to proceed. This skips creating the same directory and updating jumplist
323 // icons to avoid bloating the JumplistIcons folder.
324 if (!base::DeleteFile(icon_dir, true)) {
325 if (!::PathIsDirectoryEmpty(icon_dir.value().c_str())) {
326 folder_operation_status |=
327 FolderOperationResult::DELETE_SRC_CONTENT_FAILED;
328 return;
329 }
330 folder_operation_status |= FolderOperationResult::DELETE_SRC_DIR_FAILED;
331 }
332 }
333
334 // If CreateDirectory() fails, exit early.
335 if (!base::CreateDirectory(icon_dir)) {
336 folder_operation_status |= FolderOperationResult::CREATE_SRC_FAILED;
337 return; 459 return;
338 } 460 }
339 461
340 // Create temporary icon files for shortcuts in the "Most Visited" category. 462 // Create temporary icon files for shortcuts in the "Most Visited" category.
341 CreateIconFiles(icon_dir, local_most_visited_pages); 463 CreateIconFiles(icon_dir, local_most_visited_pages);
342 464
343 // Create temporary icon files for shortcuts in the "Recently Closed" 465 // Create temporary icon files for shortcuts in the "Recently Closed"
344 // category. 466 // category.
345 CreateIconFiles(icon_dir, local_recently_closed_pages); 467 CreateIconFiles(icon_dir, local_recently_closed_pages);
346 468
347 // We finished collecting all resources needed for updating an application 469 // We finished collecting all resources needed for updating an application
348 // JumpList. So, create a new JumpList and replace the current JumpList 470 // JumpList. So, create a new JumpList and replace the current JumpList
349 // with it. 471 // with it.
350 UpdateJumpList(app_id.c_str(), local_most_visited_pages, 472 UpdateJumpList(app_id.c_str(), local_most_visited_pages,
351 local_recently_closed_pages, incognito_availability); 473 local_recently_closed_pages, incognito_availability);
474
475 // Post a background task to delete JumpListIconsOld folder if it exists and
476 // log the delete results to UMA.
477 base::FilePath icon_dir_old = icon_dir.DirName().Append(
478 icon_dir.BaseName().value() + FILE_PATH_LITERAL("Old"));
479
480 if (::PathFileExists(icon_dir_old.value().c_str())) {
481 int jumplisticons_old_delete_status = SUCCEED;
grt (UTC plus 2) 2017/03/21 08:40:26 move the definition of this |delete_status| variab
chengx 2017/03/22 06:46:28 Done.
482 std::string histogram_name = "WinJumplist.DeleteStatusJumpListIconsOld";
483 base::PostTaskWithTraits(
grt (UTC plus 2) 2017/03/21 08:40:26 since a new task is posted for each jumplist icon
chengx 2017/03/22 06:46:28 Thanks for the suggestion. I have added a member n
484 FROM_HERE,
485 base::TaskTraits()
486 .WithPriority(base::TaskPriority::BACKGROUND)
487 .WithShutdownBehavior(
488 base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)
489 .MayBlock(),
490 base::Bind(&DeleteDirectoryAndLogResults, icon_dir_old, true,
491 &jumplisticons_old_delete_status, histogram_name));
492 }
352 } 493 }
353 494
354 } // namespace 495 } // namespace
355 496
356 JumpList::JumpListData::JumpListData() {} 497 JumpList::JumpListData::JumpListData() {}
357 498
358 JumpList::JumpListData::~JumpListData() {} 499 JumpList::JumpListData::~JumpListData() {}
359 500
360 JumpList::JumpList(Profile* profile) 501 JumpList::JumpList(Profile* profile)
361 : RefcountedKeyedService(content::BrowserThread::GetTaskRunnerForThread( 502 : RefcountedKeyedService(content::BrowserThread::GetTaskRunnerForThread(
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
671 void JumpList::TopSitesLoaded(history::TopSites* top_sites) { 812 void JumpList::TopSitesLoaded(history::TopSites* top_sites) {
672 } 813 }
673 814
674 void JumpList::TopSitesChanged(history::TopSites* top_sites, 815 void JumpList::TopSitesChanged(history::TopSites* top_sites,
675 ChangeReason change_reason) { 816 ChangeReason change_reason) {
676 top_sites->GetMostVisitedURLs( 817 top_sites->GetMostVisitedURLs(
677 base::Bind(&JumpList::OnMostVisitedURLsAvailable, 818 base::Bind(&JumpList::OnMostVisitedURLsAvailable,
678 weak_ptr_factory_.GetWeakPtr()), 819 weak_ptr_factory_.GetWeakPtr()),
679 false); 820 false);
680 } 821 }
OLDNEW
« no previous file with comments | « no previous file | tools/metrics/histograms/histograms.xml » ('j') | tools/metrics/histograms/histograms.xml » ('J')

Powered by Google App Engine
This is Rietveld 408576698