OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "components/component_updater/default_component_installer.h" | 5 #include "components/component_updater/default_component_installer.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/files/file_enumerator.h" | 11 #include "base/files/file_enumerator.h" |
12 #include "base/files/file_path.h" | 12 #include "base/files/file_path.h" |
13 #include "base/files/file_util.h" | 13 #include "base/files/file_util.h" |
14 #include "base/location.h" | 14 #include "base/location.h" |
15 #include "base/path_service.h" | |
15 #include "base/sequenced_task_runner.h" | 16 #include "base/sequenced_task_runner.h" |
16 #include "base/single_thread_task_runner.h" | 17 #include "base/single_thread_task_runner.h" |
17 #include "base/thread_task_runner_handle.h" | 18 #include "base/thread_task_runner_handle.h" |
18 #include "base/values.h" | 19 #include "base/values.h" |
19 #include "base/version.h" | 20 #include "base/version.h" |
21 #include "components/component_updater/component_updater_paths.h" | |
20 // TODO(ddorwin): Find a better place for ReadManifest. | 22 // TODO(ddorwin): Find a better place for ReadManifest. |
21 #include "components/component_updater/component_updater_service.h" | 23 #include "components/component_updater/component_updater_service.h" |
22 #include "components/update_client/component_unpacker.h" | 24 #include "components/update_client/component_unpacker.h" |
23 #include "components/update_client/utils.h" | 25 #include "components/update_client/utils.h" |
24 | 26 |
25 using update_client::CrxComponent; | 27 using update_client::CrxComponent; |
26 | 28 |
27 namespace component_updater { | 29 namespace component_updater { |
28 | 30 |
29 namespace { | 31 namespace { |
(...skipping 69 matching lines...) Loading... | |
99 manifest.GetStringASCII("version", &manifest_version); | 101 manifest.GetStringASCII("version", &manifest_version); |
100 base::Version version(manifest_version); | 102 base::Version version(manifest_version); |
101 | 103 |
102 VLOG(1) << "Install: version=" << version.GetString() | 104 VLOG(1) << "Install: version=" << version.GetString() |
103 << " current version=" << current_version_.GetString(); | 105 << " current version=" << current_version_.GetString(); |
104 | 106 |
105 if (!version.IsValid()) | 107 if (!version.IsValid()) |
106 return false; | 108 return false; |
107 if (current_version_.CompareTo(version) > 0) | 109 if (current_version_.CompareTo(version) > 0) |
108 return false; | 110 return false; |
109 base::FilePath install_path = | 111 base::FilePath install_path; |
110 installer_traits_->GetBaseDirectory().AppendASCII(version.GetString()); | 112 if (!PathService::Get(DIR_COMPONENT_USER, &install_path)) |
113 return false; | |
114 install_path = | |
115 install_path.AppendASCII(installer_traits_->GetASCIIDirectoryName()) | |
116 .AppendASCII(version.GetString()); | |
111 if (base::PathExists(install_path)) { | 117 if (base::PathExists(install_path)) { |
112 if (!base::DeleteFile(install_path, true)) | 118 if (!base::DeleteFile(install_path, true)) |
113 return false; | 119 return false; |
114 } | 120 } |
115 if (!InstallHelper(manifest, unpack_path, install_path)) { | 121 if (!InstallHelper(manifest, unpack_path, install_path)) { |
116 base::DeleteFile(install_path, true); | 122 base::DeleteFile(install_path, true); |
117 return false; | 123 return false; |
118 } | 124 } |
119 current_version_ = version; | 125 current_version_ = version; |
126 current_install_dir_ = install_path; | |
120 // TODO(ddorwin): Change parameter to std::unique_ptr<base::DictionaryValue> | 127 // TODO(ddorwin): Change parameter to std::unique_ptr<base::DictionaryValue> |
121 // so we can avoid this DeepCopy. | 128 // so we can avoid this DeepCopy. |
122 current_manifest_.reset(manifest.DeepCopy()); | 129 current_manifest_.reset(manifest.DeepCopy()); |
123 std::unique_ptr<base::DictionaryValue> manifest_copy( | 130 std::unique_ptr<base::DictionaryValue> manifest_copy( |
124 current_manifest_->DeepCopy()); | 131 current_manifest_->DeepCopy()); |
125 main_task_runner_->PostTask( | 132 main_task_runner_->PostTask( |
126 FROM_HERE, | 133 FROM_HERE, |
127 base::Bind(&DefaultComponentInstaller::ComponentReady, | 134 base::Bind(&DefaultComponentInstaller::ComponentReady, |
128 this, base::Passed(&manifest_copy))); | 135 this, base::Passed(&manifest_copy))); |
129 return true; | 136 return true; |
130 } | 137 } |
131 | 138 |
132 bool DefaultComponentInstaller::GetInstalledFile( | 139 bool DefaultComponentInstaller::GetInstalledFile( |
133 const std::string& file, | 140 const std::string& file, |
134 base::FilePath* installed_file) { | 141 base::FilePath* installed_file) { |
135 if (current_version_ == base::Version(kNullVersion)) | 142 if (current_version_ == base::Version(kNullVersion)) |
136 return false; // No component has been installed yet. | 143 return false; // No component has been installed yet. |
137 | 144 *installed_file = current_install_dir_.AppendASCII(file); |
138 *installed_file = installer_traits_->GetBaseDirectory() | |
139 .AppendASCII(current_version_.GetString()) | |
140 .AppendASCII(file); | |
141 return true; | 145 return true; |
142 } | 146 } |
143 | 147 |
144 bool DefaultComponentInstaller::Uninstall() { | 148 bool DefaultComponentInstaller::Uninstall() { |
145 DCHECK(thread_checker_.CalledOnValidThread()); | 149 DCHECK(thread_checker_.CalledOnValidThread()); |
146 task_runner_->PostTask( | 150 task_runner_->PostTask( |
147 FROM_HERE, | 151 FROM_HERE, |
148 base::Bind(&DefaultComponentInstaller::UninstallOnTaskRunner, this)); | 152 base::Bind(&DefaultComponentInstaller::UninstallOnTaskRunner, this)); |
149 return true; | 153 return true; |
150 } | 154 } |
151 | 155 |
152 void DefaultComponentInstaller::StartRegistration(ComponentUpdateService* cus) { | 156 void DefaultComponentInstaller::StartRegistration(ComponentUpdateService* cus) { |
153 DCHECK(task_runner_.get()); | 157 DCHECK(task_runner_.get()); |
154 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | 158 DCHECK(task_runner_->RunsTasksOnCurrentThread()); |
155 base::FilePath base_dir = installer_traits_->GetBaseDirectory(); | 159 |
160 base::Version latest_version(kNullVersion); | |
161 | |
162 // First check for a system-wide installation. | |
163 base::FilePath path; | |
164 if (PathService::Get(DIR_COMPONENT_SYSTEM, &path)) { | |
165 path = path.AppendASCII(installer_traits_->GetASCIIDirectoryName()); | |
166 if (base::PathExists(path)) { | |
167 std::unique_ptr<base::DictionaryValue> manifest = | |
168 update_client::ReadManifest(path); | |
169 if (manifest && installer_traits_->VerifyInstallation(*manifest, path)) { | |
170 std::string version_s; | |
xhwang
2016/05/02 17:47:00
nit: "Names should be descriptive; eschew abbrevia
waffles
2016/05/03 21:04:22
Done.
| |
171 if (manifest->GetStringASCII("version", &version_s)) { | |
172 base::Version version(version_s); | |
173 if (version.IsValid()) { | |
174 current_install_dir_ = path; | |
175 current_manifest_ = std::move(manifest); | |
176 current_version_ = version; | |
177 latest_version = version; | |
178 } | |
179 } | |
180 } | |
181 } | |
182 } | |
xhwang
2016/05/02 17:47:00
nit: It might be clearer to wrap this block into a
waffles
2016/05/03 21:04:22
Done.
| |
183 | |
184 // Then check for a higher-versioned user-wide installation. | |
185 base::FilePath latest_path; | |
186 std::unique_ptr<base::DictionaryValue> latest_manifest; | |
187 base::FilePath base_dir; | |
188 if (!PathService::Get(DIR_COMPONENT_USER, &base_dir)) | |
189 return; | |
190 base_dir = base_dir.AppendASCII(installer_traits_->GetASCIIDirectoryName()); | |
156 if (!base::PathExists(base_dir) && !base::CreateDirectory(base_dir)) { | 191 if (!base::PathExists(base_dir) && !base::CreateDirectory(base_dir)) { |
157 PLOG(ERROR) << "Could not create the base directory for " | 192 PLOG(ERROR) << "Could not create the base directory for " |
158 << installer_traits_->GetName() << " (" | 193 << installer_traits_->GetName() << " (" |
159 << base_dir.MaybeAsASCII() << ")."; | 194 << base_dir.MaybeAsASCII() << ")."; |
160 return; | 195 return; |
161 } | 196 } |
162 | |
163 base::FilePath latest_path; | |
164 base::Version latest_version(kNullVersion); | |
165 std::unique_ptr<base::DictionaryValue> latest_manifest; | |
166 | |
167 std::vector<base::FilePath> older_paths; | 197 std::vector<base::FilePath> older_paths; |
168 base::FileEnumerator file_enumerator( | 198 base::FileEnumerator file_enumerator( |
169 base_dir, false, base::FileEnumerator::DIRECTORIES); | 199 base_dir, false, base::FileEnumerator::DIRECTORIES); |
170 for (base::FilePath path = file_enumerator.Next(); | 200 for (base::FilePath path = file_enumerator.Next(); |
171 !path.value().empty(); | 201 !path.value().empty(); |
172 path = file_enumerator.Next()) { | 202 path = file_enumerator.Next()) { |
173 base::Version version(path.BaseName().MaybeAsASCII()); | 203 base::Version version(path.BaseName().MaybeAsASCII()); |
174 | 204 |
175 // Ignore folders that don't have valid version names. These folders are not | 205 // Ignore folders that don't have valid version names. These folders are not |
176 // managed by component installer so do not try to remove them. | 206 // managed by component installer so do not try to remove them. |
(...skipping 12 matching lines...) Loading... | |
189 if (!manifest || !installer_traits_->VerifyInstallation(*manifest, path)) { | 219 if (!manifest || !installer_traits_->VerifyInstallation(*manifest, path)) { |
190 PLOG(ERROR) << "Failed to read manifest or verify installation for " | 220 PLOG(ERROR) << "Failed to read manifest or verify installation for " |
191 << installer_traits_->GetName() << " (" << path.MaybeAsASCII() | 221 << installer_traits_->GetName() << " (" << path.MaybeAsASCII() |
192 << ")."; | 222 << ")."; |
193 older_paths.push_back(path); | 223 older_paths.push_back(path); |
194 continue; | 224 continue; |
195 } | 225 } |
196 | 226 |
197 // New valid |version| folder found! | 227 // New valid |version| folder found! |
198 | 228 |
199 if (latest_manifest) { | 229 if (!latest_path.empty()) |
200 DCHECK(!latest_path.empty()); | |
201 older_paths.push_back(latest_path); | 230 older_paths.push_back(latest_path); |
202 } | |
203 | 231 |
204 latest_path = path; | 232 latest_path = path; |
205 latest_version = version; | 233 latest_version = version; |
206 latest_manifest = std::move(manifest); | 234 latest_manifest = std::move(manifest); |
207 } | 235 } |
208 | 236 |
209 if (latest_manifest) { | 237 if (latest_manifest) { |
210 current_version_ = latest_version; | 238 current_version_ = latest_version; |
211 current_manifest_ = std::move(latest_manifest); | 239 current_manifest_ = std::move(latest_manifest); |
240 current_install_dir_ = latest_path; | |
212 // TODO(ddorwin): Remove these members and pass them directly to | 241 // TODO(ddorwin): Remove these members and pass them directly to |
213 // FinishRegistration(). | 242 // FinishRegistration(). |
214 base::ReadFileToString(latest_path.AppendASCII("manifest.fingerprint"), | 243 base::ReadFileToString(latest_path.AppendASCII("manifest.fingerprint"), |
215 ¤t_fingerprint_); | 244 ¤t_fingerprint_); |
216 } | 245 } |
217 | 246 |
218 // Remove older versions of the component. None should be in use during | 247 // Remove older versions of the component. None should be in use during |
219 // browser startup. | 248 // browser startup. |
220 for (const auto& older_path : older_paths) | 249 for (const auto& older_path : older_paths) |
221 base::DeleteFile(older_path, true); | 250 base::DeleteFile(older_path, true); |
222 } | 251 } |
223 | 252 |
224 void DefaultComponentInstaller::UninstallOnTaskRunner() { | 253 void DefaultComponentInstaller::UninstallOnTaskRunner() { |
225 DCHECK(task_runner_.get()); | 254 DCHECK(task_runner_.get()); |
226 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | 255 DCHECK(task_runner_->RunsTasksOnCurrentThread()); |
227 const base::FilePath base_dir = installer_traits_->GetBaseDirectory(); | |
228 | 256 |
229 base::FileEnumerator file_enumerator(base_dir, false, | 257 // Only try to delete any files that are in our user-level install path. |
258 base::FilePath userInstallPath; | |
259 if (!PathService::Get(DIR_COMPONENT_USER, &userInstallPath)) | |
260 return; | |
261 if (!userInstallPath.IsParent(current_install_dir_)) | |
262 return; | |
263 | |
264 base::FileEnumerator file_enumerator(current_install_dir_, false, | |
230 base::FileEnumerator::DIRECTORIES); | 265 base::FileEnumerator::DIRECTORIES); |
231 for (base::FilePath path = file_enumerator.Next(); !path.value().empty(); | 266 for (base::FilePath path = file_enumerator.Next(); !path.value().empty(); |
232 path = file_enumerator.Next()) { | 267 path = file_enumerator.Next()) { |
233 base::Version version(path.BaseName().MaybeAsASCII()); | 268 base::Version version(path.BaseName().MaybeAsASCII()); |
234 | 269 |
235 // Ignore folders that don't have valid version names. These folders are not | 270 // Ignore folders that don't have valid version names. These folders are not |
236 // managed by the component installer, so do not try to remove them. | 271 // managed by the component installer, so do not try to remove them. |
237 if (!version.IsValid()) | 272 if (!version.IsValid()) |
238 continue; | 273 continue; |
239 | 274 |
240 if (!base::DeleteFile(path, true)) | 275 if (!base::DeleteFile(path, true)) |
241 DLOG(ERROR) << "Couldn't delete " << path.value(); | 276 DLOG(ERROR) << "Couldn't delete " << path.value(); |
242 } | 277 } |
243 | 278 |
244 // Delete the base directory if it's empty now. | 279 // Delete the base directory if it's empty now. |
245 if (base::IsDirectoryEmpty(base_dir)) { | 280 if (base::IsDirectoryEmpty(current_install_dir_)) { |
246 if (base::DeleteFile(base_dir, false)) | 281 if (base::DeleteFile(current_install_dir_, false)) |
247 DLOG(ERROR) << "Couldn't delete " << base_dir.value(); | 282 DLOG(ERROR) << "Couldn't delete " << current_install_dir_.value(); |
248 } | 283 } |
249 } | 284 } |
250 | 285 |
251 base::FilePath DefaultComponentInstaller::GetInstallDirectory() { | |
252 return installer_traits_->GetBaseDirectory() | |
253 .AppendASCII(current_version_.GetString()); | |
254 } | |
255 | |
256 void DefaultComponentInstaller::FinishRegistration( | 286 void DefaultComponentInstaller::FinishRegistration( |
257 ComponentUpdateService* cus, | 287 ComponentUpdateService* cus, |
258 const base::Closure& callback) { | 288 const base::Closure& callback) { |
259 DCHECK(thread_checker_.CalledOnValidThread()); | 289 DCHECK(thread_checker_.CalledOnValidThread()); |
260 if (installer_traits_->CanAutoUpdate()) { | 290 if (installer_traits_->CanAutoUpdate()) { |
261 CrxComponent crx; | 291 CrxComponent crx; |
262 crx.name = installer_traits_->GetName(); | 292 crx.name = installer_traits_->GetName(); |
263 crx.requires_network_encryption = | 293 crx.requires_network_encryption = |
264 installer_traits_->RequiresNetworkEncryption(); | 294 installer_traits_->RequiresNetworkEncryption(); |
265 crx.installer = this; | 295 crx.installer = this; |
(...skipping 14 matching lines...) Loading... | |
280 return; | 310 return; |
281 | 311 |
282 std::unique_ptr<base::DictionaryValue> manifest_copy( | 312 std::unique_ptr<base::DictionaryValue> manifest_copy( |
283 current_manifest_->DeepCopy()); | 313 current_manifest_->DeepCopy()); |
284 ComponentReady(std::move(manifest_copy)); | 314 ComponentReady(std::move(manifest_copy)); |
285 } | 315 } |
286 | 316 |
287 void DefaultComponentInstaller::ComponentReady( | 317 void DefaultComponentInstaller::ComponentReady( |
288 std::unique_ptr<base::DictionaryValue> manifest) { | 318 std::unique_ptr<base::DictionaryValue> manifest) { |
289 VLOG(1) << "Component ready, version " << current_version_.GetString() | 319 VLOG(1) << "Component ready, version " << current_version_.GetString() |
290 << " in " << GetInstallDirectory().value(); | 320 << " in " << current_install_dir_.value(); |
291 installer_traits_->ComponentReady(current_version_, GetInstallDirectory(), | 321 installer_traits_->ComponentReady(current_version_, current_install_dir_, |
292 std::move(manifest)); | 322 std::move(manifest)); |
293 } | 323 } |
294 | 324 |
295 } // namespace component_updater | 325 } // namespace component_updater |
OLD | NEW |