Chromium Code Reviews| Index: chrome/installer/util/google_update_util.cc |
| diff --git a/chrome/installer/util/google_update_util.cc b/chrome/installer/util/google_update_util.cc |
| new file mode 100755 |
| index 0000000000000000000000000000000000000000..4e009c936abcc30afe2729b3266831ce4c4bb2e6 |
| --- /dev/null |
| +++ b/chrome/installer/util/google_update_util.cc |
| @@ -0,0 +1,142 @@ |
| +// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "chrome/installer/util/google_update_util.h" |
| + |
| +#include "base/command_line.h" |
| +#include "base/file_path.h" |
| +#include "base/file_util.h" |
| +#include "base/logging.h" |
| +#include "base/process.h" |
| +#include "base/process_util.h" |
| +#include "base/string16.h" |
| +#include "base/time.h" |
| +#include "base/win/registry.h" |
| +#include "base/win/scoped_handle.h" |
| +#include "chrome/installer/launcher_support/chrome_launcher_support.h" |
| +#include "chrome/installer/util/google_update_constants.h" |
| +#include "chrome/installer/util/google_update_settings.h" |
| + |
| +using base::win::RegKey; |
| + |
| +namespace google_update { |
| + |
| +namespace { |
| + |
| +const int kGoogleUpdateTimeoutMs = 20 * 1000; |
| + |
| +// Returns true if and only if Google Update is present at the given level. |
|
erikwright (departed)
2012/09/21 19:10:06
if and only if -> iff
huangs
2012/09/21 19:45:17
Done.
|
| +bool IsGoogleUpdatePresent(bool system_install) { |
| + // Using the existence of version key in the registry to decide. |
| + return GoogleUpdateSettings::GetGoogleUpdateVersion(system_install).IsValid(); |
| +} |
| + |
| +// Returns GoogleUpdateSetup.exe's executable path at |system_level|, |
|
erikwright (departed)
2012/09/21 19:10:06
|system_level| -> the specified level
huangs
2012/09/21 19:45:17
Done.
|
| +// or an empty path if none is found. |
| +FilePath GetGoogleUpdateSetupExe(bool system_install) { |
| + const HKEY root_key = system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; |
| + RegKey update_key; |
| + |
| + if (update_key.Open(root_key, kRegPathGoogleUpdate, KEY_QUERY_VALUE) == |
| + ERROR_SUCCESS) { |
| + string16 path_str; |
| + string16 version_str; |
| + if ((update_key.ReadValue(kRegPathField, &path_str) == ERROR_SUCCESS) && |
| + (update_key.ReadValue(kRegGoogleUpdateVersion, &version_str) == |
| + ERROR_SUCCESS)) { |
| + return FilePath(path_str).DirName().Append(version_str). |
| + Append(kGoogleUpdateSetupExe); |
| + } |
| + } |
| + return FilePath(); |
| +} |
| + |
| +// Assign |cmd_string| as command line to install Google Update at user-level, |
|
erikwright (departed)
2012/09/21 19:10:06
"If Google Update is present at system-level, sets
huangs
2012/09/21 19:45:17
Done.
|
| +// if Google Update is present at system-level, else empty command line. |
| +// Returns true if and only if command line is successfully generated. |
| +bool GetUserLevelGoogleUpdateInstallCommandLine(string16* cmd_string) { |
| + cmd_string->clear(); |
| + CommandLine cmd(CommandLine::NO_PROGRAM); |
| + FilePath google_update_setup(GetGoogleUpdateSetupExe(true)); // system-level. |
| + if (google_update_setup.empty()) { |
|
erikwright (departed)
2012/09/21 19:10:06
if (!google_update_setup.empty()) {
...
}
retur
huangs
2012/09/21 19:45:17
Done.
|
| + return false; |
| + } else { |
| + cmd.SetProgram(google_update_setup); |
|
erikwright (departed)
2012/09/21 19:10:06
Declare cmd here, and use the constructor that tak
huangs
2012/09/21 19:45:17
Done.
|
| + // Appends parameter "/install runtime=true&needsadmin=false /silent" |
| + // Constants are found in code.google.com/p/omaha/common/const_cmd_line.h. |
| + cmd.AppendArg("/install"); |
| + // The "&" can be used in base::LaunchProcess() without quotation |
| + // (this is problematic only if run from command prompt). |
| + cmd.AppendArg("runtime=true&needsadmin=false"); |
| + cmd.AppendArg("/silent"); |
| + *cmd_string = cmd.GetCommandLineString(); |
| + return true; |
| + } |
| +} |
| + |
| +} // namespace |
| + |
| +bool EnsureUserLevelGoogleUpdatePresent() { |
| + LOG(INFO) << "Ensuring Google Update is present at user-level."; |
| + |
| + bool success = false; |
| + if (IsGoogleUpdatePresent(false)) { |
| + success = true; |
| + } else { |
| + string16 cmd_string; |
| + if (!GetUserLevelGoogleUpdateInstallCommandLine(&cmd_string)) { |
| + LOG(ERROR) << "Cannot find Google Update at system-level."; |
| + } else { |
| + // WaitForExitCode() will releases handle for us, so using ProcessHandle. |
|
erikwright (departed)
2012/09/21 19:10:06
Use a ScopedHandle and call Take() when passing it
huangs
2012/09/21 19:45:17
Done. Now we can extract into common code!
|
| + base::ProcessHandle process_handle; |
| + int exit_code = 0; |
| + LOG(INFO) << "Launching: " << cmd_string; |
| + if (!base::LaunchProcess(cmd_string, base::LaunchOptions(), |
| + &process_handle)) { |
| + PLOG(ERROR) << "Failed to launch (" << cmd_string << ")"; |
| + } else if (!base::WaitForExitCode(process_handle, &exit_code)) { |
| + // The process didn't finish in time, or GetExitCodeProcess failed. |
|
erikwright (departed)
2012/09/21 19:10:06
Remove "The process didn't finish in time, or "
Fi
huangs
2012/09/21 19:45:17
Moot, as this is moved to common code.
|
| + LOG(ERROR) <<"Command (" << cmd_string << ") is taking more than " |
| + << kGoogleUpdateTimeoutMs << " milliseconds to complete."; |
| + } else if (exit_code != 0) { |
| + LOG(ERROR) << "Command (" << cmd_string << ") exited with code " |
| + << exit_code; |
| + } else { |
| + success = true; |
| + } |
| + } |
| + } |
| + return success; |
| +} |
| + |
| +bool UninstallGoogleUpdate(bool system_install) { |
| + bool success = false; |
| + string16 cmd_string( |
| + GoogleUpdateSettings::GetUninstallCommandLine(system_install)); |
| + if (cmd_string.empty()) { |
| + success = true; // Nothing to; vacuous success. |
| + } else { |
| + // WaitForExitCodeWithTimeout() will not releases handle for us. |
|
erikwright (departed)
2012/09/21 19:10:06
Remove this comment.
huangs
2012/09/21 19:45:17
Done.
|
| + base::win::ScopedHandle process; |
| + int exit_code = 0; |
| + LOG(INFO) << "Launching: " << cmd_string; |
| + if (!base::LaunchProcess(cmd_string, base::LaunchOptions(), |
| + process.Receive())) { |
| + PLOG(ERROR) << "Failed to launch (" << cmd_string << ")"; |
| + } else if (!base::WaitForExitCodeWithTimeout(process, &exit_code, |
| + base::TimeDelta::FromMilliseconds(kGoogleUpdateTimeoutMs))) { |
| + // The process didn't finish in time, or GetExitCodeProcess failed. |
| + LOG(ERROR) <<"Command (" << cmd_string << ") is taking more than " |
| + << kGoogleUpdateTimeoutMs << " milliseconds to complete."; |
| + } else if (exit_code != 0) { |
| + LOG(ERROR) << "Command (" << cmd_string << ") exited with code " |
| + << exit_code; |
| + } else { |
| + success = true; |
| + } |
| + } |
| + return success; |
| +} |
| + |
| +} // namespace google_update |