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

Side by Side Diff: chrome/browser/downgrade/user_data_downgrade.cc

Issue 1986823002: Reset user data directory and disk cache directory after downgrade. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 6 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 2016 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/downgrade/user_data_downgrade.h"
6
7 #include <string>
8
9 #include "base/bind.h"
10 #include "base/command_line.h"
11 #include "base/files/file_enumerator.h"
12 #include "base/files/file_path.h"
13 #include "base/files/file_util.h"
14 #include "base/path_service.h"
15 #include "base/strings/string_util.h"
16 #include "base/strings/stringprintf.h"
17 #include "base/strings/utf_string_conversions.h"
18 #include "base/time/time.h"
19 #include "base/version.h"
20 #include "base/win/registry.h"
21 #include "chrome/browser/policy/policy_path_parser.h"
22 #include "chrome/common/chrome_constants.h"
23 #include "chrome/common/chrome_paths.h"
24 #include "chrome/common/chrome_switches.h"
25 #include "chrome/common/chrome_version.h"
26 #include "chrome/installer/util/install_util.h"
27 #include "content/public/browser/browser_thread.h"
28
29 namespace {
30
31 constexpr base::FilePath::CharType g_delete_suffix[] =
32 FILE_PATH_LITERAL(".CHROME_DELETE");
33 bool g_is_browser_test = false;
34
35 // Return the disk cache dir override value if exists or empty path for default
36 // disk cache dir.
37 base::FilePath GetDiskCacheDir() {
38 base::FilePath disk_cache_dir;
39 policy::path_parser::CheckDiskCacheDirPolicy(&disk_cache_dir);
40 if (disk_cache_dir.empty()) {
41 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
42 disk_cache_dir = command_line->GetSwitchValuePath(switches::kDiskCacheDir);
43 }
44 if (disk_cache_dir.ReferencesParent())
45 return base::MakeAbsoluteFilePath(disk_cache_dir);
46 return disk_cache_dir;
47 }
48
49 base::FilePath GetLastChromeVersionFile(const base::FilePath& user_data_dir) {
50 const base::FilePath::StringType last_chrome_version =
51 FILE_PATH_LITERAL("Last Chrome Version");
sky 2016/06/03 00:04:24 nit: Chrome Version? Generally we don't use 'Last'
zmin 2016/06/03 15:46:52 I use 'Last' here because this file is used to ind
sky 2016/06/03 18:18:03 I'm still of the opinion 'Last' is unnecessary her
52 return user_data_dir.Append(last_chrome_version);
53 }
54
55 base::Version GetLastChromeVersion(const base::FilePath& user_data_dir) {
56 std::string last_chrome_version_str;
57 if (base::ReadFileToString(GetLastChromeVersionFile(user_data_dir),
58 &last_chrome_version_str)) {
59 return base::Version(
60 base::TrimWhitespaceASCII(last_chrome_version_str, base::TRIM_ALL)
61 .as_string());
62 }
63 return base::Version();
64 }
65
66 // Return the temporary path that |source_path| will be renamed to later.
67 base::FilePath GetTempDirNameForDelete(const base::FilePath& source_path) {
68 if (source_path.empty())
69 return base::FilePath();
70
71 base::FilePath target_path(source_path.AddExtension(g_delete_suffix));
72 int uniquifier = base::GetUniquePathNumber(source_path, g_delete_suffix);
73 if (uniquifier < 0)
74 return base::FilePath();
75 if (uniquifier > 0) {
76 return target_path.InsertBeforeExtensionASCII(
77 base::StringPrintf(" (%d)", uniquifier));
78 }
79
80 return target_path;
81 }
82
83 // Rename the |source| directory to |target|. Create |source| directory after
84 // rename if |recreate| is true.
85 void RenameDirectory(const base::FilePath& source,
86 const base::FilePath& target,
87 bool recreate) {
88 if (!source.empty() && !target.empty() && base::Move(source, target) &&
sky 2016/06/03 00:04:24 What if Move fails? Doesn't that leave things in a
zmin 2016/06/03 15:46:52 If move failed, we just end up with a higher versi
sky 2016/06/03 18:18:03 That's assuming every file deals with a version fr
89 recreate) {
90 base::CreateDirectory(source);
91 }
92 }
93
94 void DeleteAllRenamedUserDirectories(const base::FilePath& path) {
95 if (path.empty())
96 return;
97 base::FilePath dir_name = path.DirName();
98 // Does not support root directory
99 if (dir_name == path)
100 return;
101
102 base::FilePath::StringType pattern =
103 path.BaseName().value() + FILE_PATH_LITERAL("*") + g_delete_suffix;
104 base::FileEnumerator enumerator(dir_name, false,
105 base::FileEnumerator::DIRECTORIES, pattern);
106 for (base::FilePath dir = enumerator.Next(); !dir.empty();
107 dir = enumerator.Next()) {
108 base::DeleteFile(dir, true);
109 }
110 }
111
112 void DeleteMovedUserData(const base::FilePath& user_data_dir,
113 const base::FilePath& disk_cache_dir) {
114 DeleteAllRenamedUserDirectories(user_data_dir);
115 DeleteAllRenamedUserDirectories(disk_cache_dir);
116 }
117
118 } // namespace
119
120 void MoveUserDataForFirstRunAfterDowngrade() {
121 base::FilePath user_data_dir;
122 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
sky 2016/06/03 00:04:23 Check return value.
zmin 2016/06/03 15:46:52 Done.
123 base::Version current_version(chrome::kChromeVersion);
124 base::FilePath cur_chrome_exe;
125 if (!PathService::Get(base::FILE_EXE, &cur_chrome_exe))
126 return;
127 base::Version downgrade_version = InstallUtil::GetDowngradeVersion(
128 !InstallUtil::IsPerUserInstall(cur_chrome_exe),
129 BrowserDistribution::GetDistribution());
130 if (downgrade_version.IsValid() && downgrade_version > current_version) {
131 base::FilePath disk_cache_dir(GetDiskCacheDir());
132 // Without the browser process singleton protection, the directory may be
133 // copied multiple times. In order to prevent that from happening, the temp
134 // directory's name will be computed before the LastChromeVersion file is
135 // read. Because the deletion will be scheduled after the singleton is
136 // acquired, the directory can only be moved twice in the worst case.
137 // Also, doing this after the downgrade version check to reduce performance
138 // cost for the normal launch.
139 base::FilePath temp_disk_cache_dir(GetTempDirNameForDelete(disk_cache_dir));
140 base::FilePath temp_user_data_dir(GetTempDirNameForDelete(user_data_dir));
141 base::Version last_chrome_version = GetLastChromeVersion(user_data_dir);
142 if (last_chrome_version.IsValid() &&
sky 2016/06/03 00:04:24 Move this earlier on. You don't need to figure out
zmin 2016/06/03 15:46:52 Finding temp dir name is put before this on purpos
143 last_chrome_version > current_version) {
144 // Do not recreate |disk_cache_dir| as it will be initialized later.
145 RenameDirectory(disk_cache_dir, temp_disk_cache_dir, false);
146 RenameDirectory(user_data_dir, temp_user_data_dir, true);
147 }
148 }
149 base::WriteFile(GetLastChromeVersionFile(user_data_dir),
sky 2016/06/03 00:04:23 I find it confusing that a function named MoveUser
zmin 2016/06/03 15:46:52 Done.
150 chrome::kChromeVersion, strlen(chrome::kChromeVersion));
151 }
152
153 void DeleteMovedUserDataSoon() {
154 base::FilePath user_data_dir;
155 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
156 if (g_is_browser_test) {
157 // Delete task will always be posted and executed for browser test.
158 content::BrowserThread::PostBlockingPoolTask(
159 FROM_HERE,
160 base::Bind(&DeleteMovedUserData, user_data_dir, GetDiskCacheDir()));
161 } else {
162 content::BrowserThread::PostAfterStartupTask(
163 FROM_HERE, content::BrowserThread::GetBlockingPool()
164 ->GetTaskRunnerWithShutdownBehavior(
165 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN),
166 base::Bind(&DeleteMovedUserData, user_data_dir, GetDiskCacheDir()));
167 }
168 }
169
170 void SimulateDowngradeForTest(bool is_browser_test) {
171 g_is_browser_test = is_browser_test;
172 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698