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

Side by Side Diff: chrome/browser/component_updater/recovery_component_installer.cc

Issue 321473003: Elevated install of recovery component (component update part) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 5 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "chrome/browser/component_updater/recovery_component_installer.h" 5 #include "chrome/browser/component_updater/recovery_component_installer.h"
6 6
7 #include <string> 7 #include <string>
8 #include <vector>
8 9
9 #include "base/base_paths.h" 10 #include "base/base_paths.h"
10 #include "base/bind.h" 11 #include "base/bind.h"
11 #include "base/command_line.h" 12 #include "base/command_line.h"
12 #include "base/compiler_specific.h" 13 #include "base/compiler_specific.h"
13 #include "base/file_util.h" 14 #include "base/file_util.h"
14 #include "base/files/file_path.h" 15 #include "base/files/file_path.h"
15 #include "base/logging.h" 16 #include "base/logging.h"
17 #include "base/memory/singleton.h"
16 #include "base/path_service.h" 18 #include "base/path_service.h"
17 #include "base/prefs/pref_registry_simple.h" 19 #include "base/prefs/pref_registry_simple.h"
18 #include "base/prefs/pref_service.h" 20 #include "base/prefs/pref_service.h"
21 #include "base/process/kill.h"
19 #include "base/process/launch.h" 22 #include "base/process/launch.h"
20 #include "base/strings/string_util.h" 23 #include "base/strings/string_util.h"
24 #include "base/strings/utf_string_conversions.h"
25 #include "base/synchronization/waitable_event.h"
21 #include "base/values.h" 26 #include "base/values.h"
27 #include "chrome/browser/component_updater/component_unpacker.h"
22 #include "chrome/browser/component_updater/component_updater_service.h" 28 #include "chrome/browser/component_updater/component_updater_service.h"
29 #include "chrome/common/chrome_paths.h"
30 #include "chrome/common/chrome_switches.h"
31 #include "chrome/common/chrome_version_info.h"
32 #include "chrome/common/pref_names.h"
23 #include "components/component_updater/component_updater_paths.h" 33 #include "components/component_updater/component_updater_paths.h"
24 #include "components/component_updater/pref_names.h" 34 #include "components/component_updater/pref_names.h"
25 #include "content/public/browser/browser_thread.h" 35 #include "content/public/browser/browser_thread.h"
26 36
27 using content::BrowserThread; 37 using content::BrowserThread;
28 38
29 namespace component_updater { 39 namespace component_updater {
30 40
31 namespace { 41 namespace {
32 42
33 // CRX hash. The extension id is: npdjjkjlcidkjlamlmmdelcjbcpdjocm. 43 // CRX hash. The extension id is: npdjjkjlcidkjlamlmmdelcjbcpdjocm.
34 const uint8 kSha2Hash[] = {0xdf, 0x39, 0x9a, 0x9b, 0x28, 0x3a, 0x9b, 0x0c, 44 const uint8 kSha2Hash[] = {0xdf, 0x39, 0x9a, 0x9b, 0x28, 0x3a, 0x9b, 0x0c,
35 0xbc, 0xc3, 0x4b, 0x29, 0x12, 0xf3, 0x9e, 0x2c, 45 0xbc, 0xc3, 0x4b, 0x29, 0x12, 0xf3, 0x9e, 0x2c,
36 0x19, 0x7a, 0x71, 0x4b, 0x0a, 0x7c, 0x80, 0x1c, 46 0x19, 0x7a, 0x71, 0x4b, 0x0a, 0x7c, 0x80, 0x1c,
37 0xf6, 0x29, 0x7c, 0x0a, 0x5f, 0xea, 0x67, 0xb7}; 47 0xf6, 0x29, 0x7c, 0x0a, 0x5f, 0xea, 0x67, 0xb7};
38 48
39 // File name of the recovery binary on different platforms. 49 // File name of the recovery binary on different platforms.
40 const base::FilePath::CharType kRecoveryFileName[] = 50 const base::FilePath::CharType kRecoveryFileName[] =
41 #if defined(OS_WIN) 51 #if defined(OS_WIN)
42 FILE_PATH_LITERAL("ChromeRecovery.exe"); 52 FILE_PATH_LITERAL("ChromeRecovery.exe");
43 #else // OS_LINUX, OS_MACOSX, etc. 53 #else // OS_LINUX, OS_MACOSX, etc.
44 FILE_PATH_LITERAL("ChromeRecovery"); 54 FILE_PATH_LITERAL("ChromeRecovery");
45 #endif 55 #endif
46 56
47 const char kRecoveryManifestName[] = "ChromeRecovery"; 57 const char kRecoveryManifestName[] = "ChromeRecovery";
48 58
59 // This is a contract between ChromeRecovery and this installer for the
60 // meaning of ChromeRecovery process exit code.
61 enum ChromeRecvoeryExitCode {
62 EXIT_CODE_RECOVERY_SUCCEEDED = 0,
63 EXIT_CODE_RECOVERY_SKIPPED = 1,
64 EXIT_CODE_ELEVATION_NEEDED = 2,
65 };
66
67 // Place where CRX and other installer files will be saved for elevated install.
68 base::FilePath GetInstallerBackupPath(const std::string& version) {
69 base::FilePath path;
70 if (PathService::Get(DIR_RECOVERY_BASE, &path)) {
71 path = path.Append(FILE_PATH_LITERAL("backup"));
72 path = path.AppendASCII(version);
73 }
74 return path;
75 }
76
77 // Returns a secure location that only elevated process can write.
78 // The elevated installer stores files there to make sure files will not be
79 // tampered by unauthorized process in the installation process.
80 base::FilePath GetSecureRecoveryPath(const std::string& version) {
81 base::FilePath path;
82 if (PathService::Get(DIR_SECURE_RECOVERY_BASE, &path)) {
83 path = path.AppendASCII(version);
84 }
85 return path;
86 }
87
49 } // namespace 88 } // namespace
50 89
90 // Recovery component installer tries to recover chrome with current process
91 // privilege first. If that fails, it then tries elevated install, if
92 // applicable applicable. The workflow of the elevated recovery is:
93 // 1) In the default recovery install, the recovery process returns an exit
94 // code that indicates elevation is needed. When that happens, the unpacker
95 // saves CRX to the backup path and then a preference flag will be set.
96 // 2) UpgradeDetector detects the flag, gets elevation permission from user.
97 // 3) ElevatedInstallLauncher starts an elevated process for recovery.
98 // 4) ElevatedRecoveryInstaller runs in the newly created elevated process,
99 // move the backed-up CRX to a secure location, verifies signature and
100 // unpacks CRX to a secure folder.
101 // 5) RecoveryComponentInstaller tries to do recovery again with elevated
102 // privilege.
51 class RecoveryComponentInstaller : public ComponentInstaller { 103 class RecoveryComponentInstaller : public ComponentInstaller {
52 public: 104 public:
53 explicit RecoveryComponentInstaller(const Version& version, 105 RecoveryComponentInstaller(
54 PrefService* prefs); 106 const Version& version, PrefService* prefs, bool elevated_install);
55 107
56 virtual ~RecoveryComponentInstaller() {} 108 virtual ~RecoveryComponentInstaller() {}
57 109
58 virtual void OnUpdateError(int error) OVERRIDE; 110 virtual void OnUpdateError(int error) OVERRIDE;
59 111
60 virtual bool Install(const base::DictionaryValue& manifest, 112 virtual bool Install(const base::DictionaryValue& manifest,
61 const base::FilePath& unpack_path) OVERRIDE; 113 const base::FilePath& unpack_path) OVERRIDE;
62 114
115 virtual base::FilePath GetBackupPath() const OVERRIDE;
116
117 virtual void InstallExternally() OVERRIDE;
118
63 virtual bool GetInstalledFile(const std::string& file, 119 virtual bool GetInstalledFile(const std::string& file,
64 base::FilePath* installed_file) OVERRIDE; 120 base::FilePath* installed_file) OVERRIDE;
65 121
66 private: 122 private:
123 bool IsElevatedInstallNeeded() const;
124
67 Version current_version_; 125 Version current_version_;
68 PrefService* prefs_; 126 PrefService* prefs_;
127 bool elevated_install_;
128 int installer_exit_code_;
129 };
130
131 // Creates an elevated process for recovery.
132 class ElevatedInstallLauncher {
133 public:
134 static ElevatedInstallLauncher* GetInstance();
135 void Launch(PrefService* prefs, bool elevation_allowed,
136 const base::Closure& callback);
137
138 private:
139 friend struct DefaultSingletonTraits<ElevatedInstallLauncher>;
140
141 ElevatedInstallLauncher();
142
143 static void RunInstaller(
144 PrefService* prefs, const std::string& version, bool elevation_allowed);
145
146 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_;
147
148 DISALLOW_COPY_AND_ASSIGN(ElevatedInstallLauncher);
149 };
150
151 class ElevatedRecoveryInstaller {
152 public:
153 static ElevatedRecoveryInstaller* GetInstance();
154 void Install(const std::string& version);
155 void WaitForInstallToComplete();
156
157 private:
158 friend struct DefaultSingletonTraits<ElevatedRecoveryInstaller>;
159
160 ElevatedRecoveryInstaller();
161
162 bool PrepareInstall(const std::string& version_str);
163 void DoInstall(const std::string& version_str);
164 void DoneInstall(ComponentUnpacker::Error error, int extended_error);
165 void PostInstallCleanup();
166
167 Version version_;
168 scoped_refptr<ComponentUnpacker> unpacker_;
169 scoped_ptr<RecoveryComponentInstaller> rc_installer_;
170 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_;
171 base::WaitableEvent install_complete_event_;
172
173 DISALLOW_COPY_AND_ASSIGN(ElevatedRecoveryInstaller);
69 }; 174 };
70 175
71 void RecoveryRegisterHelper(ComponentUpdateService* cus, PrefService* prefs) { 176 void RecoveryRegisterHelper(ComponentUpdateService* cus, PrefService* prefs) {
72 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 177 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
73 Version version(prefs->GetString(prefs::kRecoveryComponentVersion)); 178 Version version(prefs->GetString(prefs::kRecoveryComponentVersion));
74 if (!version.IsValid()) { 179 if (!version.IsValid()) {
75 NOTREACHED(); 180 NOTREACHED();
76 return; 181 return;
77 } 182 }
78 183
79 CrxComponent recovery; 184 CrxComponent recovery;
80 recovery.name = "recovery"; 185 recovery.name = "recovery";
81 recovery.installer = new RecoveryComponentInstaller(version, prefs); 186 recovery.installer = new RecoveryComponentInstaller(version, prefs, false);
82 recovery.version = version; 187 recovery.version = version;
83 recovery.pk_hash.assign(kSha2Hash, &kSha2Hash[sizeof(kSha2Hash)]); 188 recovery.pk_hash.assign(kSha2Hash, &kSha2Hash[sizeof(kSha2Hash)]);
84 if (cus->RegisterComponent(recovery) != ComponentUpdateService::kOk) { 189 if (cus->RegisterComponent(recovery) != ComponentUpdateService::kOk) {
85 NOTREACHED() << "Recovery component registration failed."; 190 NOTREACHED() << "Recovery component registration failed.";
86 } 191 }
87 } 192 }
88 193
89 void RecoveryUpdateVersionHelper(const Version& version, PrefService* prefs) { 194 void RecoveryUpdateVersionHelper(const Version& version, PrefService* prefs) {
90 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 195 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
91 prefs->SetString(prefs::kRecoveryComponentVersion, version.GetString()); 196 prefs->SetString(prefs::kRecoveryComponentVersion, version.GetString());
92 } 197 }
93 198
94 RecoveryComponentInstaller::RecoveryComponentInstaller(const Version& version, 199 void RecoveryUpdateElevationHelper(bool needs_elevation, PrefService* prefs) {
95 PrefService* prefs) 200 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
96 : current_version_(version), prefs_(prefs) { 201 prefs->SetBoolean(prefs::kRecoveryComponentNeedsElevation, needs_elevation);
202 }
203
204 RecoveryComponentInstaller::RecoveryComponentInstaller(
205 const Version& version, PrefService* prefs, bool elevated_install)
206 : current_version_(version),
207 prefs_(prefs),
208 elevated_install_(elevated_install),
209 installer_exit_code_(0) {
97 DCHECK(version.IsValid()); 210 DCHECK(version.IsValid());
98 } 211 }
99 212
100 void RecoveryComponentInstaller::OnUpdateError(int error) { 213 void RecoveryComponentInstaller::OnUpdateError(int error) {
101 NOTREACHED() << "Recovery component update error: " << error; 214 NOTREACHED() << "Recovery component update error: " << error;
102 } 215 }
103 216
104 bool RecoveryComponentInstaller::Install(const base::DictionaryValue& manifest, 217 bool RecoveryComponentInstaller::Install(const base::DictionaryValue& manifest,
105 const base::FilePath& unpack_path) { 218 const base::FilePath& unpack_path) {
106 std::string name; 219 std::string name;
107 manifest.GetStringASCII("name", &name); 220 manifest.GetStringASCII("name", &name);
108 if (name != kRecoveryManifestName) 221 if (name != kRecoveryManifestName)
109 return false; 222 return false;
110 std::string proposed_version; 223 std::string proposed_version;
111 manifest.GetStringASCII("version", &proposed_version); 224 manifest.GetStringASCII("version", &proposed_version);
112 Version version(proposed_version.c_str()); 225 Version version(proposed_version.c_str());
113 if (!version.IsValid()) 226 if (!version.IsValid())
114 return false; 227 return false;
115 if (current_version_.CompareTo(version) >= 0) 228 if (current_version_.CompareTo(version) >= 0)
116 return false; 229 return false;
117 230
118 // Passed the basic tests. Copy the installation to a permanent directory.
119 base::FilePath path; 231 base::FilePath path;
120 if (!PathService::Get(DIR_RECOVERY_BASE, &path)) 232 if (elevated_install_) {
121 return false; 233 // For elevated install, |unpack_path| should be a secure path that is
122 path = path.AppendASCII(version.GetString()); 234 // accessible by elevated user only and should be available thoughout the
123 if (base::PathExists(path) && !base::DeleteFile(path, true)) 235 // installation process.
124 return false; 236 path = unpack_path;
125 if (!base::Move(unpack_path, path)) { 237 } else {
126 DVLOG(1) << "Recovery component move failed."; 238 // Passed the basic tests. Copy the installation to a permanent directory.
127 return false; 239 if (!PathService::Get(DIR_RECOVERY_BASE, &path))
240 return false;
241 path = path.AppendASCII(version.GetString());
242 if (base::PathExists(path) && !base::DeleteFile(path, true))
243 return false;
244 if (!base::Move(unpack_path, path)) {
245 DVLOG(1) << "Recovery component move failed.";
246 return false;
247 }
128 } 248 }
129 249
130 base::FilePath main_file = path.Append(kRecoveryFileName); 250 base::FilePath main_file = path.Append(kRecoveryFileName);
131 if (!base::PathExists(main_file)) 251 if (!base::PathExists(main_file))
132 return false; 252 return false;
133 // Run the recovery component. 253 // Run the recovery component.
134 CommandLine cmdline(main_file); 254 CommandLine cmdline(main_file);
135 std::string arguments; 255 std::string arguments;
136 if (manifest.GetStringASCII("x-recovery-args", &arguments)) 256 if (manifest.GetStringASCII("x-recovery-args", &arguments))
137 cmdline.AppendArg(arguments); 257 cmdline.AppendArg(arguments);
138 std::string add_version; 258 std::string add_version;
139 if (manifest.GetStringASCII("x-recovery-add-version", &add_version)) { 259 if (manifest.GetStringASCII("x-recovery-add-version", &add_version)) {
140 if (add_version == "yes") 260 if (add_version == "yes")
141 cmdline.AppendSwitchASCII("version", current_version_.GetString()); 261 cmdline.AppendSwitchASCII("version", current_version_.GetString());
142 } 262 }
143 current_version_ = version; 263 current_version_ = version;
144 if (prefs_) { 264 if (prefs_) {
145 BrowserThread::PostTask( 265 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
146 BrowserThread::UI,
147 FROM_HERE,
148 base::Bind(&RecoveryUpdateVersionHelper, version, prefs_)); 266 base::Bind(&RecoveryUpdateVersionHelper, version, prefs_));
149 } 267 }
150 return base::LaunchProcess(cmdline, base::LaunchOptions(), NULL); 268
269 base::ProcessHandle process_handle;
270 base::LaunchOptions option;
271 if (elevated_install_) {
272 #if defined(OS_WIN)
273 if (!base::LaunchElevatedProcess(cmdline, option, &process_handle))
274 return false;
275 #else
276 // At this moment, elevated install is supported on Windows platform only.
277 return false;
278 #endif
279 } else if (!base::LaunchProcess(cmdline, option, &process_handle)) {
280 return false;
281 }
282
283 installer_exit_code_ = 0;
284 const base::TimeDelta kMaxWaitTime = base::TimeDelta::FromSeconds(300);
285 if (!base::WaitForExitCodeWithTimeout(process_handle,
286 &installer_exit_code_,
287 kMaxWaitTime)) {
288 // Ensure that the process terminates.
289 base::KillProcess(process_handle, -1, true);
290 return false;
291 }
292
293 return true;
294 }
295
296 bool RecoveryComponentInstaller::IsElevatedInstallNeeded() const {
297 return prefs_ && !elevated_install_ &&
298 installer_exit_code_ == EXIT_CODE_ELEVATION_NEEDED;
299 }
300
301 base::FilePath RecoveryComponentInstaller::GetBackupPath() const {
302 if (!IsElevatedInstallNeeded())
303 return base::FilePath();
304
305 return GetInstallerBackupPath(current_version_.GetString());
306 }
307
308 void RecoveryComponentInstaller::InstallExternally() {
309 // Set a flag in the preference so UpgradeDetector can detect and notify user
310 // about the elevation request. If user permits, elevated install will be
311 // triggered by the UI.
312 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
313 base::Bind(&RecoveryUpdateElevationHelper, true, prefs_));
151 } 314 }
152 315
153 bool RecoveryComponentInstaller::GetInstalledFile( 316 bool RecoveryComponentInstaller::GetInstalledFile(
154 const std::string& file, 317 const std::string& file,
155 base::FilePath* installed_file) { 318 base::FilePath* installed_file) {
156 return false; 319 return false;
157 } 320 }
158 321
322 ElevatedInstallLauncher::ElevatedInstallLauncher() {
323 blocking_task_runner_ = BrowserThread::GetBlockingPool()->
324 GetSequencedTaskRunnerWithShutdownBehavior(
325 BrowserThread::GetBlockingPool()->GetSequenceToken(),
326 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
327 }
328
329 ElevatedInstallLauncher* ElevatedInstallLauncher::GetInstance() {
330 return Singleton<ElevatedInstallLauncher>::get();
331 }
332
333 void ElevatedInstallLauncher::Launch(PrefService* prefs,
334 bool elevation_allowed,
335 const base::Closure& callback) {
336 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
337
338 // Reset the flag regardless of the install result. If later we want to
339 // retry failed install, we should postpone setting this flag until
340 // install completes.
341 BrowserThread::PostTaskAndReply(BrowserThread::UI, FROM_HERE,
342 base::Bind(&RecoveryUpdateElevationHelper, false, prefs),
343 callback);
344
345 blocking_task_runner_->PostTask(FROM_HERE,
346 base::Bind(&ElevatedInstallLauncher::RunInstaller,
347 prefs, prefs->GetString(prefs::kRecoveryComponentVersion),
348 elevation_allowed));
349 }
350
351 void ElevatedInstallLauncher::RunInstaller(PrefService* prefs,
352 const std::string& version,
353 bool elevation_allowed) {
354 if (!elevation_allowed) {
355 base::DeleteFile(GetInstallerBackupPath(version), true);
356 return;
357 }
358
359 base::FilePath chrome_exe;
360 if (!PathService::Get(base::FILE_EXE, &chrome_exe))
361 return;
362
363 CommandLine cmdline(chrome_exe);
364 cmdline.AppendSwitchASCII(switches::kInstallRecoveryComponent, version);
365 #if defined(OS_WIN)
366 base::LaunchOptions option;
367 option.start_hidden = true;
368 base::LaunchElevatedProcess(cmdline, option, NULL);
369 #else
370 // Currently elevated install is supported only on Windows platform.
371 return;
372 #endif
373 }
374
375 ElevatedRecoveryInstaller* ElevatedRecoveryInstaller::GetInstance() {
376 return Singleton<ElevatedRecoveryInstaller>::get();
377 }
378
379 ElevatedRecoveryInstaller::ElevatedRecoveryInstaller()
380 : install_complete_event_(false, false) {
381 blocking_task_runner_ = BrowserThread::GetBlockingPool()->
382 GetSequencedTaskRunnerWithShutdownBehavior(
383 BrowserThread::GetBlockingPool()->GetSequenceToken(),
384 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
385 }
386
387 void ElevatedRecoveryInstaller::Install(const std::string& version) {
388 blocking_task_runner_->PostTask(FROM_HERE,
389 base::Bind(&ElevatedRecoveryInstaller::DoInstall,
390 base::Unretained(this),
391 version));
392 }
393
394 bool ElevatedRecoveryInstaller::PrepareInstall(const std::string& version_str) {
395 Version version(version_str);
396 if (!version.IsValid())
397 return false;
398
399 // Move CRX and related files to a secure location
400 base::FilePath secure_path;
401 secure_path = GetSecureRecoveryPath(version_str);
402 if (secure_path.empty())
403 return false;
404 if (base::PathExists(secure_path) && !base::DeleteFile(secure_path, true))
405 return false;
406 if (!base::Move(GetInstallerBackupPath(version_str), secure_path)) {
407 DVLOG(1) << "Failed to move recovery component CRX to secure location.";
408 return false;
409 }
410 return true;
411 }
412
413 void ElevatedRecoveryInstaller::DoInstall(const std::string& version_str) {
414 if (!PrepareInstall(version_str)) {
415 NOTREACHED();
416 return;
417 }
418
419 version_ = Version(version_str);
420 rc_installer_.reset(new RecoveryComponentInstaller(version_, NULL, true));
421
422 std::vector<uint8> pk_hash;
423 pk_hash.assign(kSha2Hash, &kSha2Hash[sizeof(kSha2Hash)]);
424
425 base::FilePath path(GetSecureRecoveryPath(version_.GetString()));
426 unpacker_ = ComponentUnpacker::CreateFromBackup(
427 path, pk_hash, rc_installer_.get(),
428 blocking_task_runner_);
429
430 if (unpacker_.get()) {
431 unpacker_->set_unpack_base_dir(path);
432 unpacker_->Unpack(base::Bind(&ElevatedRecoveryInstaller::DoneInstall,
433 base::Unretained(this)));
434 } else {
435 // Unpacker creation failed, skip installation and go directly to cleanup.
436 PostInstallCleanup();
437 }
438 }
439
440 void ElevatedRecoveryInstaller::DoneInstall(ComponentUnpacker::Error error,
441 int extended_error) {
442 PostInstallCleanup();
443 }
444
445 void ElevatedRecoveryInstaller::PostInstallCleanup() {
446 base::FilePath secure_path;
447 secure_path = GetSecureRecoveryPath(version_.GetString());
448 if (!secure_path.empty() && base::PathExists(secure_path)) {
449 base::DeleteFile(secure_path, true);
450 }
451
452 unpacker_ = NULL;
453 rc_installer_.reset();
454 version_ = Version();
455 install_complete_event_.Signal();
456 }
457
458 void ElevatedRecoveryInstaller::WaitForInstallToComplete() {
459 install_complete_event_.Wait();
460 }
461
159 void RegisterRecoveryComponent(ComponentUpdateService* cus, 462 void RegisterRecoveryComponent(ComponentUpdateService* cus,
160 PrefService* prefs) { 463 PrefService* prefs) {
161 #if !defined(OS_CHROMEOS) 464 #if !defined(OS_CHROMEOS)
162 // We delay execute the registration because we are not required in 465 // We delay execute the registration because we are not required in
163 // the critical path during browser startup. 466 // the critical path during browser startup.
164 BrowserThread::PostDelayedTask( 467 BrowserThread::PostDelayedTask(
165 BrowserThread::UI, 468 BrowserThread::UI,
166 FROM_HERE, 469 FROM_HERE,
167 base::Bind(&RecoveryRegisterHelper, cus, prefs), 470 base::Bind(&RecoveryRegisterHelper, cus, prefs),
168 base::TimeDelta::FromSeconds(6)); 471 base::TimeDelta::FromSeconds(6));
169 #endif 472 #endif
170 } 473 }
171 474
172 void RegisterPrefsForRecoveryComponent(PrefRegistrySimple* registry) { 475 void RegisterPrefsForRecoveryComponent(PrefRegistrySimple* registry) {
173 registry->RegisterStringPref(prefs::kRecoveryComponentVersion, "0.0.0.0"); 476 registry->RegisterStringPref(prefs::kRecoveryComponentVersion, "0.0.0.0");
477 registry->RegisterBooleanPref(prefs::kRecoveryComponentNeedsElevation, false);
478 }
479
480 void StartElevatedRecoveryProcess(
481 PrefService* prefs, bool elevation_allowed, const base::Closure& callback) {
482 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
483 ElevatedInstallLauncher::GetInstance()->Launch(
484 prefs, elevation_allowed, callback);
485 }
486
487 void InstallRecoveryComponentElevated(const std::string& version) {
488 ElevatedRecoveryInstaller::GetInstance()->Install(version);
489
490 // Return from this function cause the process to exit. So wait to make sure
491 // recovery install completes before return.
492 ElevatedRecoveryInstaller::GetInstance()->WaitForInstallToComplete();
174 } 493 }
175 494
176 } // namespace component_updater 495 } // namespace component_updater
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698