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

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

Issue 2836363003: Retire some metrics and update file util methods for JumpList (Closed)
Patch Set: Merge branch 'master' of https://chromium.googlesource.com/chromium/src into retiresomejumplistmetrics 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 (c) 2017 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2017 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_file_util.h" 5 #include "chrome/browser/win/jumplist_file_util.h"
6 6
7 #include <windows.h> 7 #include <windows.h>
8 8
9 #include "base/files/file_enumerator.h" 9 #include "base/files/file_enumerator.h"
10 #include "base/files/file_util.h" 10 #include "base/files/file_util.h"
11 #include "base/metrics/histogram_macros.h" 11 #include "base/metrics/histogram_macros.h"
12 #include "base/threading/thread_restrictions.h" 12 #include "base/threading/thread_restrictions.h"
13 13
14 FolderDeleteResult DeleteFiles(const base::FilePath& path, 14 void DeleteFiles(const base::FilePath& path,
15 const base::FilePath::StringType& pattern, 15 const base::FilePath::StringType& pattern,
16 int max_file_deleted) { 16 int max_file_deleted) {
17 int success_count = 0; 17 int success_count = 0;
18 int failure_count = 0; 18 int failure_count = 0;
19 FolderDeleteResult delete_status = SUCCEED;
20 19
21 base::FileEnumerator traversal( 20 base::FileEnumerator traversal(
22 path, false, 21 path, false,
23 base::FileEnumerator::FILES | base::FileEnumerator::DIRECTORIES, pattern); 22 base::FileEnumerator::FILES | base::FileEnumerator::DIRECTORIES, pattern);
23
24 for (base::FilePath current = traversal.Next(); !current.empty(); 24 for (base::FilePath current = traversal.Next(); !current.empty();
25 current = traversal.Next()) { 25 current = traversal.Next()) {
26 // Try to clear the read-only bit if we find it. 26 // Try to clear the read-only bit if we find it.
27 base::FileEnumerator::FileInfo info = traversal.GetInfo(); 27 base::FileEnumerator::FileInfo info = traversal.GetInfo();
28 if (info.find_data().dwFileAttributes & FILE_ATTRIBUTE_READONLY) { 28 if (info.find_data().dwFileAttributes & FILE_ATTRIBUTE_READONLY) {
29 SetFileAttributes( 29 SetFileAttributes(
30 current.value().c_str(), 30 current.value().c_str(),
31 info.find_data().dwFileAttributes & ~FILE_ATTRIBUTE_READONLY); 31 info.find_data().dwFileAttributes & ~FILE_ATTRIBUTE_READONLY);
32 } 32 }
33 33
34 if (info.IsDirectory()) { 34 // JumpListIcons* directories shouldn't have sub-directories. If any of them
35 // JumpListIcons{,Old} directories shouldn't have sub-directories. 35 // does for unknown reasons, don't delete them. Instead, increment the
36 // If any of them does for unknown reasons, don't delete them. Instead, 36 // failure count.
37 // increment the failure count and record this information. 37 if (info.IsDirectory() || !::DeleteFile(current.value().c_str()))
38 delete_status = FAIL_SUBDIRECTORY_EXISTS;
39 failure_count++; 38 failure_count++;
40 } else if (!::DeleteFile(current.value().c_str())) { 39 else
41 failure_count++;
42 } else {
43 success_count++; 40 success_count++;
44 } 41
45 // If it deletes max_file_deleted files with any attempt failures, record 42 // The desired max number of files have been deleted, or the desired max
46 // this information in |delete_status|. 43 // number of failures have been hit.
47 if (success_count >= max_file_deleted) { 44 if (success_count >= max_file_deleted || failure_count >= max_file_deleted)
48 // The desired max number of files have been deleted. 45 break;
49 return failure_count ? FAIL_DELETE_MAX_FILES_WITH_ERRORS : delete_status;
50 }
51 if (failure_count >= max_file_deleted) {
52 // The desired max number of failures have been hit.
53 return FAIL_MAX_DELETE_FAILURES;
54 }
55 } 46 }
56 return delete_status;
57 } 47 }
58 48
59 FolderDeleteResult DeleteDirectoryContent(const base::FilePath& path, 49 void DeleteDirectoryContent(const base::FilePath& path, int max_file_deleted) {
60 int max_file_deleted) {
61 base::ThreadRestrictions::AssertIOAllowed(); 50 base::ThreadRestrictions::AssertIOAllowed();
62 51
63 if (path.empty()) 52 if (path.empty() || path.value().length() >= MAX_PATH)
64 return SUCCEED; 53 return;
65
66 // For JumpListIcons{,Old} directories, since their names are shorter than
67 // MAX_PATH, hitting the code in the if-block below is unexpected.
68 if (path.value().length() >= MAX_PATH)
69 return FAIL_INVALID_FILE_PATH;
70 54
71 DWORD attr = GetFileAttributes(path.value().c_str()); 55 DWORD attr = GetFileAttributes(path.value().c_str());
72 // We're done if we can't find the path. 56 // We're done if we can't find the path.
73 if (attr == INVALID_FILE_ATTRIBUTES) 57 if (attr == INVALID_FILE_ATTRIBUTES)
74 return SUCCEED; 58 return;
75 // Try to clear the read-only bit if we find it. 59 // Try to clear the read-only bit if we find it.
76 if ((attr & FILE_ATTRIBUTE_READONLY) && 60 if ((attr & FILE_ATTRIBUTE_READONLY) &&
77 !SetFileAttributes(path.value().c_str(), 61 !SetFileAttributes(path.value().c_str(),
78 attr & ~FILE_ATTRIBUTE_READONLY)) { 62 attr & ~FILE_ATTRIBUTE_READONLY)) {
79 return FAIL_READ_ONLY_DIRECTORY; 63 return;
80 } 64 }
81 65
82 // If |path| is a file, simply delete it. However, since JumpListIcons{,Old} 66 // If |path| is a file, simply delete it. However, since JumpListIcons* are
83 // are directories, hitting the code inside the if-block below is unexpected. 67 // directories, hitting the code inside the if-block below is unexpected.
84 if (!(attr & FILE_ATTRIBUTE_DIRECTORY)) { 68 if (!(attr & FILE_ATTRIBUTE_DIRECTORY)) {
85 ::DeleteFile(path.value().c_str()); 69 ::DeleteFile(path.value().c_str());
86 return FAIL_DELETE_SINGLE_FILE; 70 return;
87 } 71 }
88 72
89 // If |path| is a directory, delete at most |max_file_deleted| files in it. 73 // If |path| is a directory, delete at most |max_file_deleted| files in it.
90 return DeleteFiles(path, L"*", max_file_deleted); 74 DeleteFiles(path, L"*", max_file_deleted);
91 } 75 }
92 76
93 FolderDeleteResult DeleteDirectory(const base::FilePath& path, 77 void DeleteDirectory(const base::FilePath& path, int max_file_deleted) {
94 int max_file_deleted) {
95 base::ThreadRestrictions::AssertIOAllowed(); 78 base::ThreadRestrictions::AssertIOAllowed();
79
96 // Delete at most |max_file_deleted| files in |path|. 80 // Delete at most |max_file_deleted| files in |path|.
97 FolderDeleteResult delete_status = 81 DeleteDirectoryContent(path, max_file_deleted);
98 DeleteDirectoryContent(path, max_file_deleted); 82
99 // Since DeleteDirectoryContent() can only delete at most |max_file_deleted| 83 ::RemoveDirectory(path.value().c_str());
100 // files, its return value cannot indicate if |path| is empty or not.
101 // Instead, use PathIsDirectoryEmpty to check if |path| is empty and remove it
102 // if it is.
103 if (base::IsDirectoryEmpty(path) &&
104 !::RemoveDirectory(path.value().c_str())) {
105 delete_status = FAIL_REMOVE_RAW_DIRECTORY;
106 }
107 return delete_status;
108 } 84 }
109 85
110 void DeleteDirectoryAndLogResults(const base::FilePath& path, 86 void DeleteDirectoryContentAndLogRuntime(const base::FilePath& path,
111 int max_file_deleted) {
112 DirectoryStatus dir_status = NON_EXIST;
113
114 if (base::DirectoryExists(path)) {
115 FolderDeleteResult delete_status = DeleteDirectory(path, max_file_deleted);
116 UMA_HISTOGRAM_ENUMERATION("WinJumplist.DeleteStatusJumpListIconsOld",
117 delete_status, FolderDeleteResult::END);
118 if (base::DirectoryExists(path))
119 dir_status = base::IsDirectoryEmpty(path) ? EMPTY : NON_EMPTY;
120 }
121
122 UMA_HISTOGRAM_ENUMERATION("WinJumplist.DirectoryStatusJumpListIconsOld",
123 dir_status, DIRECTORY_STATUS_END);
124 }
125
126 void DeleteDirectoryContentAndLogResults(const base::FilePath& path,
127 int max_file_deleted) { 87 int max_file_deleted) {
128 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407.
129 SCOPED_UMA_HISTOGRAM_TIMER("WinJumplist.DeleteDirectoryContentDuration"); 88 SCOPED_UMA_HISTOGRAM_TIMER("WinJumplist.DeleteDirectoryContentDuration");
130 89
131 DirectoryStatus dir_status = NON_EXIST; 90 DeleteDirectoryContent(path, kFileDeleteLimit);
132
133 // Delete the content in |path|. If |path| doesn't exist, create one.
134 if (base::DirectoryExists(path)) {
135 FolderDeleteResult delete_status =
136 DeleteDirectoryContent(path, kFileDeleteLimit);
137
138 UMA_HISTOGRAM_ENUMERATION("WinJumplist.DeleteStatusJumpListIcons",
139 delete_status, FolderDeleteResult::END);
140
141 if (base::DirectoryExists(path))
142 dir_status = base::IsDirectoryEmpty(path) ? EMPTY : NON_EMPTY;
143 } else if (base::CreateDirectory(path)) {
144 dir_status = EMPTY;
145 }
146
147 UMA_HISTOGRAM_ENUMERATION("WinJumplist.DirectoryStatusJumpListIcons",
148 dir_status, DIRECTORY_STATUS_END);
149 } 91 }
OLDNEW
« no previous file with comments | « chrome/browser/win/jumplist_file_util.h ('k') | chrome/browser/win/jumplist_file_util_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698