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

Side by Side Diff: components/component_updater/default_component_installer.cc

Issue 1937683002: Implement support in DefaultComponentInstaller for picking up bundled (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: comments through #35 Created 4 years, 7 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
« no previous file with comments | « components/component_updater/default_component_installer.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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...) Expand 10 before | Expand all | Expand 10 after
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 = install_path.Append(installer_traits_->GetRelativeInstallDir())
115 .AppendASCII(version.GetString());
111 if (base::PathExists(install_path)) { 116 if (base::PathExists(install_path)) {
112 if (!base::DeleteFile(install_path, true)) 117 if (!base::DeleteFile(install_path, true))
113 return false; 118 return false;
114 } 119 }
115 if (!InstallHelper(manifest, unpack_path, install_path)) { 120 if (!InstallHelper(manifest, unpack_path, install_path)) {
116 base::DeleteFile(install_path, true); 121 base::DeleteFile(install_path, true);
117 return false; 122 return false;
118 } 123 }
119 current_version_ = version; 124 current_version_ = version;
125 current_install_dir_ = install_path;
120 // TODO(ddorwin): Change parameter to std::unique_ptr<base::DictionaryValue> 126 // TODO(ddorwin): Change parameter to std::unique_ptr<base::DictionaryValue>
121 // so we can avoid this DeepCopy. 127 // so we can avoid this DeepCopy.
122 current_manifest_.reset(manifest.DeepCopy()); 128 current_manifest_.reset(manifest.DeepCopy());
123 std::unique_ptr<base::DictionaryValue> manifest_copy( 129 std::unique_ptr<base::DictionaryValue> manifest_copy(
124 current_manifest_->DeepCopy()); 130 current_manifest_->DeepCopy());
125 main_task_runner_->PostTask( 131 main_task_runner_->PostTask(
126 FROM_HERE, 132 FROM_HERE,
127 base::Bind(&DefaultComponentInstaller::ComponentReady, 133 base::Bind(&DefaultComponentInstaller::ComponentReady,
128 this, base::Passed(&manifest_copy))); 134 this, base::Passed(&manifest_copy)));
129 return true; 135 return true;
130 } 136 }
131 137
132 bool DefaultComponentInstaller::GetInstalledFile( 138 bool DefaultComponentInstaller::GetInstalledFile(
133 const std::string& file, 139 const std::string& file,
134 base::FilePath* installed_file) { 140 base::FilePath* installed_file) {
135 if (current_version_ == base::Version(kNullVersion)) 141 if (current_version_ == base::Version(kNullVersion))
136 return false; // No component has been installed yet. 142 return false; // No component has been installed yet.
137 143 *installed_file = current_install_dir_.AppendASCII(file);
138 *installed_file = installer_traits_->GetBaseDirectory()
139 .AppendASCII(current_version_.GetString())
140 .AppendASCII(file);
141 return true; 144 return true;
142 } 145 }
143 146
144 bool DefaultComponentInstaller::Uninstall() { 147 bool DefaultComponentInstaller::Uninstall() {
145 DCHECK(thread_checker_.CalledOnValidThread()); 148 DCHECK(thread_checker_.CalledOnValidThread());
146 task_runner_->PostTask( 149 task_runner_->PostTask(
147 FROM_HERE, 150 FROM_HERE,
148 base::Bind(&DefaultComponentInstaller::UninstallOnTaskRunner, this)); 151 base::Bind(&DefaultComponentInstaller::UninstallOnTaskRunner, this));
149 return true; 152 return true;
150 } 153 }
151 154
155 bool DefaultComponentInstaller::FindPreinstallation() {
156 base::FilePath path;
157 if (!PathService::Get(DIR_COMPONENT_PREINSTALLED, &path))
158 return false;
159 path = path.Append(installer_traits_->GetRelativeInstallDir());
160 if (!base::PathExists(path))
161 return false;
162 std::unique_ptr<base::DictionaryValue> manifest =
163 update_client::ReadManifest(path);
164 if (!manifest || !installer_traits_->VerifyInstallation(*manifest, path))
165 return false;
166 std::string version_lexical;
167 if (!manifest->GetStringASCII("version", &version_lexical))
168 return false;
169 const base::Version version(version_lexical);
170 if (!version.IsValid())
171 return false;
172 current_install_dir_ = path;
173 current_manifest_ = std::move(manifest);
174 current_version_ = version;
175 return true;
176 }
177
152 void DefaultComponentInstaller::StartRegistration(ComponentUpdateService* cus) { 178 void DefaultComponentInstaller::StartRegistration(ComponentUpdateService* cus) {
153 DCHECK(task_runner_.get()); 179 DCHECK(task_runner_.get());
154 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 180 DCHECK(task_runner_->RunsTasksOnCurrentThread());
155 base::FilePath base_dir = installer_traits_->GetBaseDirectory(); 181
182 base::Version latest_version(kNullVersion);
183
184 // First check for an installation set up alongside Chrome itself.
185 if (FindPreinstallation())
186 latest_version = current_version_;
187
188 // Then check for a higher-versioned user-wide installation.
189 base::FilePath latest_path;
190 std::unique_ptr<base::DictionaryValue> latest_manifest;
191 base::FilePath base_dir;
192 if (!PathService::Get(DIR_COMPONENT_USER, &base_dir))
193 return;
194 base_dir = base_dir.Append(installer_traits_->GetRelativeInstallDir());
156 if (!base::PathExists(base_dir) && !base::CreateDirectory(base_dir)) { 195 if (!base::PathExists(base_dir) && !base::CreateDirectory(base_dir)) {
157 PLOG(ERROR) << "Could not create the base directory for " 196 PLOG(ERROR) << "Could not create the base directory for "
158 << installer_traits_->GetName() << " (" 197 << installer_traits_->GetName() << " ("
159 << base_dir.MaybeAsASCII() << ")."; 198 << base_dir.MaybeAsASCII() << ").";
160 return; 199 return;
161 } 200 }
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; 201 std::vector<base::FilePath> older_paths;
168 base::FileEnumerator file_enumerator( 202 base::FileEnumerator file_enumerator(
169 base_dir, false, base::FileEnumerator::DIRECTORIES); 203 base_dir, false, base::FileEnumerator::DIRECTORIES);
170 for (base::FilePath path = file_enumerator.Next(); 204 for (base::FilePath path = file_enumerator.Next();
171 !path.value().empty(); 205 !path.value().empty();
172 path = file_enumerator.Next()) { 206 path = file_enumerator.Next()) {
173 base::Version version(path.BaseName().MaybeAsASCII()); 207 base::Version version(path.BaseName().MaybeAsASCII());
174 208
175 // Ignore folders that don't have valid version names. These folders are not 209 // 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. 210 // managed by component installer so do not try to remove them.
(...skipping 12 matching lines...) Expand all
189 if (!manifest || !installer_traits_->VerifyInstallation(*manifest, path)) { 223 if (!manifest || !installer_traits_->VerifyInstallation(*manifest, path)) {
190 PLOG(ERROR) << "Failed to read manifest or verify installation for " 224 PLOG(ERROR) << "Failed to read manifest or verify installation for "
191 << installer_traits_->GetName() << " (" << path.MaybeAsASCII() 225 << installer_traits_->GetName() << " (" << path.MaybeAsASCII()
192 << ")."; 226 << ").";
193 older_paths.push_back(path); 227 older_paths.push_back(path);
194 continue; 228 continue;
195 } 229 }
196 230
197 // New valid |version| folder found! 231 // New valid |version| folder found!
198 232
199 if (latest_manifest) { 233 if (!latest_path.empty())
200 DCHECK(!latest_path.empty());
201 older_paths.push_back(latest_path); 234 older_paths.push_back(latest_path);
202 }
203 235
204 latest_path = path; 236 latest_path = path;
205 latest_version = version; 237 latest_version = version;
206 latest_manifest = std::move(manifest); 238 latest_manifest = std::move(manifest);
207 } 239 }
208 240
209 if (latest_manifest) { 241 if (latest_manifest) {
210 current_version_ = latest_version; 242 current_version_ = latest_version;
211 current_manifest_ = std::move(latest_manifest); 243 current_manifest_ = std::move(latest_manifest);
244 current_install_dir_ = latest_path;
212 // TODO(ddorwin): Remove these members and pass them directly to 245 // TODO(ddorwin): Remove these members and pass them directly to
213 // FinishRegistration(). 246 // FinishRegistration().
214 base::ReadFileToString(latest_path.AppendASCII("manifest.fingerprint"), 247 base::ReadFileToString(latest_path.AppendASCII("manifest.fingerprint"),
215 &current_fingerprint_); 248 &current_fingerprint_);
216 } 249 }
217 250
218 // Remove older versions of the component. None should be in use during 251 // Remove older versions of the component. None should be in use during
219 // browser startup. 252 // browser startup.
220 for (const auto& older_path : older_paths) 253 for (const auto& older_path : older_paths)
221 base::DeleteFile(older_path, true); 254 base::DeleteFile(older_path, true);
222 } 255 }
223 256
224 void DefaultComponentInstaller::UninstallOnTaskRunner() { 257 void DefaultComponentInstaller::UninstallOnTaskRunner() {
225 DCHECK(task_runner_.get()); 258 DCHECK(task_runner_.get());
226 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 259 DCHECK(task_runner_->RunsTasksOnCurrentThread());
227 const base::FilePath base_dir = installer_traits_->GetBaseDirectory();
228 260
261 // Only try to delete any files that are in our user-level install path.
262 base::FilePath userInstallPath;
263 if (!PathService::Get(DIR_COMPONENT_USER, &userInstallPath))
264 return;
265 if (!userInstallPath.IsParent(current_install_dir_))
266 return;
267
268 const base::FilePath base_dir = current_install_dir_.DirName();
229 base::FileEnumerator file_enumerator(base_dir, false, 269 base::FileEnumerator file_enumerator(base_dir, false,
230 base::FileEnumerator::DIRECTORIES); 270 base::FileEnumerator::DIRECTORIES);
231 for (base::FilePath path = file_enumerator.Next(); !path.value().empty(); 271 for (base::FilePath path = file_enumerator.Next(); !path.value().empty();
232 path = file_enumerator.Next()) { 272 path = file_enumerator.Next()) {
233 base::Version version(path.BaseName().MaybeAsASCII()); 273 base::Version version(path.BaseName().MaybeAsASCII());
234 274
235 // Ignore folders that don't have valid version names. These folders are not 275 // 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. 276 // managed by the component installer, so do not try to remove them.
237 if (!version.IsValid()) 277 if (!version.IsValid())
238 continue; 278 continue;
239 279
240 if (!base::DeleteFile(path, true)) 280 if (!base::DeleteFile(path, true))
241 DLOG(ERROR) << "Couldn't delete " << path.value(); 281 DLOG(ERROR) << "Couldn't delete " << path.value();
242 } 282 }
243 283
244 // Delete the base directory if it's empty now. 284 // Delete the base directory if it's empty now.
245 if (base::IsDirectoryEmpty(base_dir)) { 285 if (base::IsDirectoryEmpty(base_dir)) {
246 if (base::DeleteFile(base_dir, false)) 286 if (base::DeleteFile(base_dir, false))
247 DLOG(ERROR) << "Couldn't delete " << base_dir.value(); 287 DLOG(ERROR) << "Couldn't delete " << base_dir.value();
248 } 288 }
249 } 289 }
250 290
251 base::FilePath DefaultComponentInstaller::GetInstallDirectory() {
252 return installer_traits_->GetBaseDirectory()
253 .AppendASCII(current_version_.GetString());
254 }
255
256 void DefaultComponentInstaller::FinishRegistration( 291 void DefaultComponentInstaller::FinishRegistration(
257 ComponentUpdateService* cus, 292 ComponentUpdateService* cus,
258 const base::Closure& callback) { 293 const base::Closure& callback) {
259 DCHECK(thread_checker_.CalledOnValidThread()); 294 DCHECK(thread_checker_.CalledOnValidThread());
260 if (installer_traits_->CanAutoUpdate()) { 295 if (installer_traits_->CanAutoUpdate()) {
261 CrxComponent crx; 296 CrxComponent crx;
262 crx.name = installer_traits_->GetName(); 297 crx.name = installer_traits_->GetName();
263 crx.requires_network_encryption = 298 crx.requires_network_encryption =
264 installer_traits_->RequiresNetworkEncryption(); 299 installer_traits_->RequiresNetworkEncryption();
265 crx.installer = this; 300 crx.installer = this;
(...skipping 14 matching lines...) Expand all
280 return; 315 return;
281 316
282 std::unique_ptr<base::DictionaryValue> manifest_copy( 317 std::unique_ptr<base::DictionaryValue> manifest_copy(
283 current_manifest_->DeepCopy()); 318 current_manifest_->DeepCopy());
284 ComponentReady(std::move(manifest_copy)); 319 ComponentReady(std::move(manifest_copy));
285 } 320 }
286 321
287 void DefaultComponentInstaller::ComponentReady( 322 void DefaultComponentInstaller::ComponentReady(
288 std::unique_ptr<base::DictionaryValue> manifest) { 323 std::unique_ptr<base::DictionaryValue> manifest) {
289 VLOG(1) << "Component ready, version " << current_version_.GetString() 324 VLOG(1) << "Component ready, version " << current_version_.GetString()
290 << " in " << GetInstallDirectory().value(); 325 << " in " << current_install_dir_.value();
291 installer_traits_->ComponentReady(current_version_, GetInstallDirectory(), 326 installer_traits_->ComponentReady(current_version_, current_install_dir_,
292 std::move(manifest)); 327 std::move(manifest));
293 } 328 }
294 329
295 } // namespace component_updater 330 } // namespace component_updater
OLDNEW
« no previous file with comments | « components/component_updater/default_component_installer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698