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_) { | |
Sorin Jianu
2015/02/05 22:55:35
If Chrome is on the exit path, it is possible that
Bernhard Bauer
2015/02/05 23:57:35
No, SupervisedUserWhitelistService keeps track of
Sorin Jianu
2015/02/06 00:22:04
I think cleaning up on startup could be wise. I do
Bernhard Bauer
2015/02/06 16:05:05
OK. Something for a followup CL maybe?
| |
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 16 matching lines...) Expand all Loading... | |
70 return false; | 103 return false; |
71 if (!installer_traits_->OnCustomInstall(manifest, install_path)) | 104 if (!installer_traits_->OnCustomInstall(manifest, install_path)) |
72 return false; | 105 return false; |
73 if (!installer_traits_->VerifyInstallation(manifest, install_path)) | 106 if (!installer_traits_->VerifyInstallation(manifest, install_path)) |
74 return false; | 107 return false; |
75 return true; | 108 return true; |
76 } | 109 } |
77 | 110 |
78 bool DefaultComponentInstaller::Install(const base::DictionaryValue& manifest, | 111 bool DefaultComponentInstaller::Install(const base::DictionaryValue& manifest, |
79 const base::FilePath& unpack_path) { | 112 const base::FilePath& unpack_path) { |
113 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
114 | |
80 std::string manifest_version; | 115 std::string manifest_version; |
81 manifest.GetStringASCII("version", &manifest_version); | 116 manifest.GetStringASCII("version", &manifest_version); |
82 base::Version version(manifest_version.c_str()); | 117 base::Version version(manifest_version.c_str()); |
83 if (!version.IsValid()) | 118 if (!version.IsValid()) |
84 return false; | 119 return false; |
85 if (current_version_.CompareTo(version) > 0) | 120 if (current_version_.CompareTo(version) > 0) |
86 return false; | 121 return false; |
87 base::FilePath install_path = | 122 base::FilePath install_path = |
88 installer_traits_->GetBaseDirectory().AppendASCII(version.GetString()); | 123 installer_traits_->GetBaseDirectory().AppendASCII(version.GetString()); |
89 if (base::PathExists(install_path)) { | 124 if (base::PathExists(install_path)) { |
(...skipping 22 matching lines...) Expand all Loading... | |
112 base::FilePath* installed_file) { | 147 base::FilePath* installed_file) { |
113 if (current_version_.Equals(base::Version(kNullVersion))) | 148 if (current_version_.Equals(base::Version(kNullVersion))) |
114 return false; // No component has been installed yet. | 149 return false; // No component has been installed yet. |
115 | 150 |
116 *installed_file = installer_traits_->GetBaseDirectory() | 151 *installed_file = installer_traits_->GetBaseDirectory() |
117 .AppendASCII(current_version_.GetString()) | 152 .AppendASCII(current_version_.GetString()) |
118 .AppendASCII(file); | 153 .AppendASCII(file); |
119 return true; | 154 return true; |
120 } | 155 } |
121 | 156 |
157 void DefaultComponentInstaller::Unregister(ComponentUpdateService* cus) { | |
158 DCHECK(thread_checker_.CalledOnValidThread()); | |
159 | |
160 CrxComponent crx; | |
161 installer_traits_->GetHash(&crx.pk_hash); | |
162 ComponentUpdateService::Status status = | |
163 cus->UnregisterComponent(GetCrxComponentID(crx)); | |
164 DCHECK_EQ(ComponentUpdateService::kOk, status); | |
165 | |
166 // Wait with uninstallation until all references have been dropped. | |
167 should_uninstall_on_destruction_ = true; | |
Sorin Jianu
2015/02/05 22:55:35
Would it be possible to run the uninstall code her
Bernhard Bauer
2015/02/05 23:57:35
The problem with that is that when this method is
Sorin Jianu
2015/02/06 00:22:04
Right. I wonder if this would work. ComponentInsta
Bernhard Bauer
2015/02/06 16:05:05
Done.
| |
168 } | |
169 | |
122 void DefaultComponentInstaller::StartRegistration(ComponentUpdateService* cus) { | 170 void DefaultComponentInstaller::StartRegistration(ComponentUpdateService* cus) { |
123 DCHECK(task_runner_.get()); | 171 DCHECK(task_runner_.get()); |
124 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | 172 DCHECK(task_runner_->RunsTasksOnCurrentThread()); |
125 base::FilePath base_dir = installer_traits_->GetBaseDirectory(); | 173 base::FilePath base_dir = installer_traits_->GetBaseDirectory(); |
126 if (!base::PathExists(base_dir) && !base::CreateDirectory(base_dir)) { | 174 if (!base::PathExists(base_dir) && !base::CreateDirectory(base_dir)) { |
127 NOTREACHED() << "Could not create the base directory for " | 175 NOTREACHED() << "Could not create the base directory for " |
128 << installer_traits_->GetName() << " (" | 176 << installer_traits_->GetName() << " (" |
129 << base_dir.MaybeAsASCII() << ")."; | 177 << base_dir.MaybeAsASCII() << ")."; |
130 return; | 178 return; |
131 } | 179 } |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
228 ComponentReady(manifest_copy.Pass()); | 276 ComponentReady(manifest_copy.Pass()); |
229 } | 277 } |
230 | 278 |
231 void DefaultComponentInstaller::ComponentReady( | 279 void DefaultComponentInstaller::ComponentReady( |
232 scoped_ptr<base::DictionaryValue> manifest) { | 280 scoped_ptr<base::DictionaryValue> manifest) { |
233 installer_traits_->ComponentReady( | 281 installer_traits_->ComponentReady( |
234 current_version_, GetInstallDirectory(), manifest.Pass()); | 282 current_version_, GetInstallDirectory(), manifest.Pass()); |
235 } | 283 } |
236 | 284 |
237 } // namespace component_updater | 285 } // namespace component_updater |
OLD | NEW |