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

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

Issue 2752063002: Remove JumpListIconsOld directory and set upper limit for delete attempts (Closed)
Patch Set: Add jumplist_util_file* and unit tests, plus address other 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "chrome/browser/win/jumplist_file_util.h"
6
7 #include <windows.h>
8
9 #include "base/files/file_enumerator.h"
10 #include "base/metrics/histogram_macros.h"
11 #include "base/threading/thread_restrictions.h"
12
13 bool DeleteFiles(const base::FilePath& path,
14 const base::FilePath::StringType& pattern,
15 bool has_upper_limit,
16 FolderDeleteResult* delete_status) {
17 base::FileEnumerator traversal(
18 path, false,
19 base::FileEnumerator::FILES | base::FileEnumerator::DIRECTORIES, pattern);
20 int succees_count = 0;
21 int failure_count = 0;
22 for (base::FilePath current = traversal.Next(); !current.empty();
23 current = traversal.Next()) {
24 // Try to clear the read-only bit if we find it.
25 base::FileEnumerator::FileInfo info = traversal.GetInfo();
26 if (info.find_data().dwFileAttributes & FILE_ATTRIBUTE_READONLY) {
27 SetFileAttributes(
28 current.value().c_str(),
29 info.find_data().dwFileAttributes & ~FILE_ATTRIBUTE_READONLY);
30 }
31
32 if (info.IsDirectory()) {
33 // JumpListIcons{,Old} directories shouldn't have sub-directories.
34 // If it does for unknown reasons, don't try to delete it. Instead,
35 // increment failure count if |has_upper_limit| is true and record this
36 // information in |delete_status|.
37 *delete_status = FAIL_SUBDIRECTORY_EXISTS;
38 if (!has_upper_limit)
39 return false;
40 failure_count++;
41 } else if (!::DeleteFile(current.value().c_str())) {
42 // If there is no upper limit, return false intermediately. Otherwise,
43 // increment |failure_count| until it hits the upper limit.
44 if (!has_upper_limit)
45 return false;
46 failure_count++;
47 } else {
48 succees_count++;
49 }
50 // If it successfully deletes |kMaxIconFilesDeletedPerUpdate| files without
grt (UTC plus 2) 2017/03/22 12:07:21 i think this is more clear with both limit checks
chengx 2017/03/22 21:16:36 Agreed and updated accordingly.
51 // any failures, return true. If some files fail to be delete, record this
52 // information in |delete_status| and returns false.
53 if (has_upper_limit && succees_count >= kMaxIconFilesDeletedPerUpdate) {
54 if (failure_count > 0) {
55 *delete_status = FAIL_DELETE_MAX_FILE_PERFECTLY;
grt (UTC plus 2) 2017/03/22 12:07:22 this reads to me like "we failed because we perfec
chengx 2017/03/22 21:16:36 Done.
56 }
57 return failure_count == 0;
58 }
59 // Return false when failing to delete |kMaxIconFilesDeletedPerUpdate| files
60 // comes before successfully deleting |kMaxIconFilesDeletedPerUpdate| files.
61 if (has_upper_limit && failure_count >= kMaxIconFilesDeletedPerUpdate) {
62 *delete_status = FAIL_DELETE_MAX_FILES_ANYWAY;
grt (UTC plus 2) 2017/03/22 12:07:21 FAIL_MAX_DELETE_FAILURES -> "we failed because we
chengx 2017/03/22 21:16:36 Sounds good.
63 return false;
64 }
65 }
66 return true;
67 }
68
69 bool DeleteDirectoryContent(const base::FilePath& path,
grt (UTC plus 2) 2017/03/22 12:07:21 return FolderDeleteResult rather than bool (which
chengx 2017/03/22 21:16:36 Done.
70 bool has_upper_limit,
71 FolderDeleteResult* delete_status) {
72 base::ThreadRestrictions::AssertIOAllowed();
grt (UTC plus 2) 2017/03/22 12:07:21 this function seems to assume that |delete_status|
chengx 2017/03/22 21:16:36 Changed to explicitly set it.
73
74 if (path.empty())
75 return true;
76
77 // For JumpListIcons{,Old} directories, since their names are shorter than
78 // MAX_PATH, hitting the code block below is unexpected.
79 if (path.value().length() >= MAX_PATH) {
80 *delete_status = FAIL_INVALID_FILE_PATH;
81 return false;
82 }
83
84 DWORD attr = GetFileAttributes(path.value().c_str());
85 // We're done if we can't find the path.
86 if (attr == INVALID_FILE_ATTRIBUTES)
87 return true;
88 // We may need to clear the read-only bit.
89 if ((attr & FILE_ATTRIBUTE_READONLY) &&
90 !SetFileAttributes(path.value().c_str(),
91 attr & ~FILE_ATTRIBUTE_READONLY)) {
92 *delete_status = FAIL_READ_ONLY_DIRECTORY;
93 return false;
94 }
95
96 // If |path| is a file, simply delete it.
97 // Since JumpListIcons{,Old} are directories, hitting the code block below is
98 // unexpected.
99 if (!(attr & FILE_ATTRIBUTE_DIRECTORY)) {
100 bool delete_result = !!::DeleteFile(path.value().c_str());
101 if (!delete_result)
102 *delete_status = FAIL_DELETE_SINGLE_FILE;
103 return delete_result;
104 }
105
106 // If |path| is a directory, delete all its content but save the raw
107 // directory.
108 return DeleteFiles(path, L"*", has_upper_limit, delete_status);
109 }
110
111 void DeleteDirectory(const base::FilePath& path,
grt (UTC plus 2) 2017/03/22 12:07:21 return FolderDeleteResult rather than void w/ out
chengx 2017/03/22 21:16:36 Done.
112 bool has_upper_limit,
113 FolderDeleteResult* delete_status) {
114 base::ThreadRestrictions::AssertIOAllowed();
115
116 if (path.empty())
117 return;
118
119 // For JumpListIcons{,Old} directories, since their names are shorter than
120 // MAX_PATH, hitting the code block below is unexpected.
121 if (path.value().length() >= MAX_PATH) {
122 *delete_status = FAIL_INVALID_FILE_PATH;
123 return;
124 }
125
126 DWORD attr = GetFileAttributes(path.value().c_str());
127 // We're done if we can't find the path.
128 if (attr == INVALID_FILE_ATTRIBUTES)
129 return;
130 // We may need to clear the read-only bit.
131 if ((attr & FILE_ATTRIBUTE_READONLY) &&
132 !SetFileAttributes(path.value().c_str(),
133 attr & ~FILE_ATTRIBUTE_READONLY)) {
134 *delete_status = FAIL_READ_ONLY_DIRECTORY;
135 return;
136 }
137 // If |path| is a file, delete it.
138 // Since JumpListIcons{,Old} are directories, hitting the code block below is
139 // unexpected.
140 if (!(attr & FILE_ATTRIBUTE_DIRECTORY)) {
141 ::DeleteFile(path.value().c_str());
142 *delete_status = FAIL_DELETE_SINGLE_FILE;
143 return;
144 }
145 // If |path| is a directory, delete its contents and if it succeeds, remove
146 // the raw directory.
147 if (DeleteFiles(path, L"*", has_upper_limit, delete_status))
148 ::RemoveDirectory(path.value().c_str());
149 return;
150 }
151
152 void DeleteDirectoryAndLogResults(const base::FilePath& path,
153 bool has_upper_limit) {
154 FolderDeleteResult delete_status = SUCCEED;
155 DeleteDirectory(path, has_upper_limit, &delete_status);
156 UMA_HISTOGRAM_ENUMERATION("WinJumplist.DeleteStatusJumpListIconsOld",
157 static_cast<int>(delete_status), END);
grt (UTC plus 2) 2017/03/22 12:07:21 since FolderDeleteResult is an old-school enum and
chengx 2017/03/22 21:16:36 You are right. It is not needed.
158 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698