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 "base/bind.h" | 5 #include "base/bind.h" |
6 #include "base/bind_helpers.h" | 6 #include "base/bind_helpers.h" |
7 #include "base/files/file_enumerator.h" | 7 #include "base/files/file_enumerator.h" |
8 #include "base/files/file_path.h" | 8 #include "base/files/file_path.h" |
9 #include "base/files/file_util.h" | 9 #include "base/files/file_util.h" |
10 #include "base/location.h" | 10 #include "base/location.h" |
11 #include "base/message_loop/message_loop_proxy.h" | 11 #include "base/message_loop/message_loop_proxy.h" |
12 #include "base/sequenced_task_runner.h" | 12 #include "base/sequenced_task_runner.h" |
13 #include "base/single_thread_task_runner.h" | 13 #include "base/single_thread_task_runner.h" |
14 #include "base/values.h" | 14 #include "base/values.h" |
15 #include "base/version.h" | 15 #include "base/version.h" |
16 // TODO(ddorwin): Find a better place for ReadManifest. | 16 // TODO(ddorwin): Find a better place for ReadManifest. |
17 #include "components/component_updater/component_updater_service.h" | 17 #include "components/component_updater/component_updater_service.h" |
18 #include "components/component_updater/default_component_installer.h" | 18 #include "components/component_updater/default_component_installer.h" |
19 #include "components/update_client/component_unpacker.h" | 19 #include "components/update_client/component_unpacker.h" |
20 #include "components/update_client/update_client.h" | 20 #include "components/update_client/utils.h" |
21 | 21 |
22 using update_client::CrxComponent; | 22 using update_client::CrxComponent; |
23 | 23 |
24 namespace component_updater { | 24 namespace component_updater { |
25 | 25 |
26 namespace { | 26 namespace { |
| 27 |
27 // Version "0" corresponds to no installed version. By the server's conventions, | 28 // Version "0" corresponds to no installed version. By the server's conventions, |
28 // we represent it as a dotted quad. | 29 // we represent it as a dotted quad. |
29 const char kNullVersion[] = "0.0.0.0"; | 30 const char kNullVersion[] = "0.0.0.0"; |
| 31 |
| 32 void UninstallOnTaskRunner(const base::FilePath& base_dir) { |
| 33 std::vector<base::FilePath> paths; |
| 34 base::FileEnumerator file_enumerator( |
| 35 base_dir, false, base::FileEnumerator::DIRECTORIES); |
| 36 for (base::FilePath path = file_enumerator.Next(); |
| 37 !path.value().empty(); |
| 38 path = file_enumerator.Next()) { |
| 39 base::Version version(path.BaseName().MaybeAsASCII()); |
| 40 |
| 41 // Ignore folders that don't have valid version names. These folders are not |
| 42 // managed by the component installer, so do not try to remove them. |
| 43 if (!version.IsValid()) |
| 44 continue; |
| 45 |
| 46 if (!base::DeleteFile(path, true)) |
| 47 DLOG(ERROR) << "Couldn't delete " << path.value(); |
| 48 } |
| 49 |
| 50 // Delete the base directory if it's empty now. |
| 51 if (base::IsDirectoryEmpty(base_dir)) { |
| 52 if (base::DeleteFile(base_dir, false)) |
| 53 DLOG(ERROR) << "Couldn't delete " << base_dir.value(); |
| 54 } |
| 55 } |
| 56 |
30 } // namespace | 57 } // namespace |
31 | 58 |
32 ComponentInstallerTraits::~ComponentInstallerTraits() { | 59 ComponentInstallerTraits::~ComponentInstallerTraits() { |
33 } | 60 } |
34 | 61 |
35 DefaultComponentInstaller::DefaultComponentInstaller( | 62 DefaultComponentInstaller::DefaultComponentInstaller( |
36 scoped_ptr<ComponentInstallerTraits> installer_traits) | 63 scoped_ptr<ComponentInstallerTraits> installer_traits) |
37 : current_version_(kNullVersion), | 64 : current_version_(kNullVersion), |
| 65 should_uninstall_on_destruction_(false), |
38 main_task_runner_(base::MessageLoopProxy::current()) { | 66 main_task_runner_(base::MessageLoopProxy::current()) { |
39 installer_traits_ = installer_traits.Pass(); | 67 installer_traits_ = installer_traits.Pass(); |
40 } | 68 } |
41 | 69 |
42 DefaultComponentInstaller::~DefaultComponentInstaller() { | 70 DefaultComponentInstaller::~DefaultComponentInstaller() { |
43 DCHECK(thread_checker_.CalledOnValidThread()); | 71 DCHECK(thread_checker_.CalledOnValidThread()); |
| 72 if (should_uninstall_on_destruction_) { |
| 73 task_runner_->PostTask(FROM_HERE, |
| 74 base::Bind(&UninstallOnTaskRunner, |
| 75 installer_traits_->GetBaseDirectory())); |
| 76 } |
44 } | 77 } |
45 | 78 |
46 void DefaultComponentInstaller::Register(ComponentUpdateService* cus) { | 79 void DefaultComponentInstaller::Register(ComponentUpdateService* cus) { |
47 DCHECK(thread_checker_.CalledOnValidThread()); | 80 DCHECK(thread_checker_.CalledOnValidThread()); |
48 task_runner_ = cus->GetSequencedTaskRunner(); | 81 task_runner_ = cus->GetSequencedTaskRunner(); |
49 | 82 |
50 if (!installer_traits_) { | 83 if (!installer_traits_) { |
51 NOTREACHED() << "A DefaultComponentInstaller has been created but " | 84 NOTREACHED() << "A DefaultComponentInstaller has been created but " |
52 << "has no installer traits."; | 85 << "has no installer traits."; |
53 return; | 86 return; |
(...skipping 17 matching lines...) Expand all Loading... |
71 return false; | 104 return false; |
72 if (!installer_traits_->OnCustomInstall(manifest, install_path)) | 105 if (!installer_traits_->OnCustomInstall(manifest, install_path)) |
73 return false; | 106 return false; |
74 if (!installer_traits_->VerifyInstallation(manifest, install_path)) | 107 if (!installer_traits_->VerifyInstallation(manifest, install_path)) |
75 return false; | 108 return false; |
76 return true; | 109 return true; |
77 } | 110 } |
78 | 111 |
79 bool DefaultComponentInstaller::Install(const base::DictionaryValue& manifest, | 112 bool DefaultComponentInstaller::Install(const base::DictionaryValue& manifest, |
80 const base::FilePath& unpack_path) { | 113 const base::FilePath& unpack_path) { |
| 114 DCHECK(task_runner_->RunsTasksOnCurrentThread()); |
| 115 |
81 std::string manifest_version; | 116 std::string manifest_version; |
82 manifest.GetStringASCII("version", &manifest_version); | 117 manifest.GetStringASCII("version", &manifest_version); |
83 base::Version version(manifest_version.c_str()); | 118 base::Version version(manifest_version.c_str()); |
84 if (!version.IsValid()) | 119 if (!version.IsValid()) |
85 return false; | 120 return false; |
86 if (current_version_.CompareTo(version) > 0) | 121 if (current_version_.CompareTo(version) > 0) |
87 return false; | 122 return false; |
88 base::FilePath install_path = | 123 base::FilePath install_path = |
89 installer_traits_->GetBaseDirectory().AppendASCII(version.GetString()); | 124 installer_traits_->GetBaseDirectory().AppendASCII(version.GetString()); |
90 if (base::PathExists(install_path)) { | 125 if (base::PathExists(install_path)) { |
(...skipping 25 matching lines...) Expand all Loading... |
116 base::FilePath* installed_file) { | 151 base::FilePath* installed_file) { |
117 if (current_version_.Equals(base::Version(kNullVersion))) | 152 if (current_version_.Equals(base::Version(kNullVersion))) |
118 return false; // No component has been installed yet. | 153 return false; // No component has been installed yet. |
119 | 154 |
120 *installed_file = installer_traits_->GetBaseDirectory() | 155 *installed_file = installer_traits_->GetBaseDirectory() |
121 .AppendASCII(current_version_.GetString()) | 156 .AppendASCII(current_version_.GetString()) |
122 .AppendASCII(file); | 157 .AppendASCII(file); |
123 return true; | 158 return true; |
124 } | 159 } |
125 | 160 |
| 161 void DefaultComponentInstaller::Unregister(ComponentUpdateService* cus) { |
| 162 DCHECK(thread_checker_.CalledOnValidThread()); |
| 163 |
| 164 CrxComponent crx; |
| 165 installer_traits_->GetHash(&crx.pk_hash); |
| 166 ComponentUpdateService::Status status = |
| 167 cus->UnregisterComponent(GetCrxComponentID(crx)); |
| 168 DCHECK_EQ(ComponentUpdateService::kOk, status); |
| 169 |
| 170 // Wait with uninstallation until all references have been dropped. |
| 171 should_uninstall_on_destruction_ = true; |
| 172 } |
| 173 |
126 void DefaultComponentInstaller::StartRegistration(ComponentUpdateService* cus) { | 174 void DefaultComponentInstaller::StartRegistration(ComponentUpdateService* cus) { |
127 DCHECK(task_runner_.get()); | 175 DCHECK(task_runner_.get()); |
128 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | 176 DCHECK(task_runner_->RunsTasksOnCurrentThread()); |
129 base::FilePath base_dir = installer_traits_->GetBaseDirectory(); | 177 base::FilePath base_dir = installer_traits_->GetBaseDirectory(); |
130 if (!base::PathExists(base_dir) && !base::CreateDirectory(base_dir)) { | 178 if (!base::PathExists(base_dir) && !base::CreateDirectory(base_dir)) { |
131 NOTREACHED() << "Could not create the base directory for " | 179 NOTREACHED() << "Could not create the base directory for " |
132 << installer_traits_->GetName() << " (" | 180 << installer_traits_->GetName() << " (" |
133 << base_dir.MaybeAsASCII() << ")."; | 181 << base_dir.MaybeAsASCII() << ")."; |
134 return; | 182 return; |
135 } | 183 } |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
228 if (!current_manifest_) | 276 if (!current_manifest_) |
229 return; | 277 return; |
230 | 278 |
231 scoped_ptr<base::DictionaryValue> manifest_copy( | 279 scoped_ptr<base::DictionaryValue> manifest_copy( |
232 current_manifest_->DeepCopy()); | 280 current_manifest_->DeepCopy()); |
233 installer_traits_->ComponentReady( | 281 installer_traits_->ComponentReady( |
234 current_version_, GetInstallDirectory(), manifest_copy.Pass()); | 282 current_version_, GetInstallDirectory(), manifest_copy.Pass()); |
235 } | 283 } |
236 | 284 |
237 } // namespace component_updater | 285 } // namespace component_updater |
OLD | NEW |