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..6cf155cc74113cd157ec3229716c4a1e988a4bdc |
| --- /dev/null |
| +++ b/chrome/installer/util/google_update_util.cc |
| @@ -0,0 +1,151 @@ |
| +// 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_util.h" |
| +#include "base/string16.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 installed at the given level. |
| +bool IsGoogleUpdateInstalled(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|, |
| +// 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)) { |
| + FilePath google_update_setup(FilePath(path_str).DirName(). |
| + Append(version_str). |
| + Append(kGoogleUpdateSetupExe)); |
| + if (file_util::PathExists(google_update_setup)) { |
|
grt (UTC plus 2)
2012/09/21 14:20:33
i suggest you don't bother with this check. it's
huangs
2012/09/21 18:48:43
Done.
|
| + return google_update_setup; |
| + } else { |
| + LOG(ERROR) << "Unexpectedly missing " << kGoogleUpdateSetupExe; |
|
erikwright (departed)
2012/09/21 14:08:49
log google_update_setup instead (so full path is i
huangs
2012/09/21 18:48:43
Moot, as check is removed.
|
| + } |
| + } |
| + } |
| + return FilePath(); |
| +} |
| + |
| +// Returns command line to install Google Update at user-level if Google Update |
| +// is already installed at system-level,or an empty command line if none found. |
| +// This is not in GoogleUpdateSettings because we build the command line, |
|
erikwright (departed)
2012/09/21 14:08:49
Remove "This is not ..."
huangs
2012/09/21 18:48:43
Done.
|
| +// instead of just reading it from the registry. |
| +CommandLine GetUserLevelGoogleUpdateInstallCommandLine() { |
| + CommandLine cmd(CommandLine::NO_PROGRAM); |
| + FilePath google_update_setup(GetGoogleUpdateSetupExe(true)); // system-level. |
| + if (!google_update_setup.empty()) { |
| + cmd.SetProgram(google_update_setup); |
| + // 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"); |
| + } |
| + return cmd; |
| +} |
| + |
| +bool ExecuteGoogleUpdateCommand(const string16& cmd_string, |
|
grt (UTC plus 2)
2012/09/21 14:20:33
please add a doc comment
huangs
2012/09/21 18:48:43
Moot: Routine inlined.
|
| + const string16& cmd_name, |
| + base::win::ScopedHandle* process) { |
| + bool success = false; |
| + if (cmd_string.empty()) { // Command not rendered. |
|
grt (UTC plus 2)
2012/09/21 14:20:33
remove this whole block and let an empty cmd_strin
huangs
2012/09/21 18:48:43
Moot: Routine inlined.
|
| + LOG(ERROR) << "Failed to find " << cmd_name; |
| + } else { |
| + LOG(INFO) << "Launching " << cmd_name << ": " << cmd_string; |
|
erikwright (departed)
2012/09/21 14:08:49
just log cmd_string instead of cmd_name here.
huangs
2012/09/21 18:48:43
Done.
|
| + success = base::LaunchProcess(cmd_string, base::LaunchOptions(), |
| + process->Receive()); |
| + if (!success) { |
| + PLOG(ERROR) << "Failed to launch " << cmd_name << " (" << cmd_string |
|
erikwright (departed)
2012/09/21 14:08:49
no need to include cmd_name.
|
| + << ")."; |
|
grt (UTC plus 2)
2012/09/21 14:20:33
remove the period at the end here since PLOG will
huangs
2012/09/21 18:48:43
Done.
|
| + } |
| + } |
| + return success; |
| +} |
| + |
| +bool WaitForGoogleUpdateCommand(const string16& cmd_string, |
| + const string16& cmd_name, |
| + const base::win::ScopedHandle& process) { |
|
erikwright (departed)
2012/09/21 14:08:49
Define |process| as a plain-old HANDLE. There is a
huangs
2012/09/21 18:48:43
Moot: Function inlined. Note extra complexity wit
|
| + bool success = false; |
| + int exit_code = 0; |
| + if (base::WaitForExitCodeWithTimeout( |
| + process, &exit_code, |
|
grt (UTC plus 2)
2012/09/21 14:20:33
please move these to the previous line to conserve
huangs
2012/09/21 18:48:43
Done.
|
| + base::TimeDelta::FromMilliseconds(kGoogleUpdateTimeoutMs))) { |
| + if (exit_code == 0) { |
| + LOG(INFO) << " normal exit."; |
|
grt (UTC plus 2)
2012/09/21 14:20:33
i should never have put this there, please remove
huangs
2012/09/21 18:48:43
Done.
|
| + success = true; |
| + } else { |
| + PLOG(ERROR) << cmd_name << " (" << cmd_string << ") exited with code " |
|
erikwright (departed)
2012/09/21 14:08:49
no need for cmd_name here.
grt (UTC plus 2)
2012/09/21 14:20:33
PLOG -> LOG
huangs
2012/09/21 18:48:43
Done.
huangs
2012/09/21 18:48:43
Done.
|
| + << exit_code << "."; |
| + } |
| + } else { |
| + // The process didn't finish in time, or GetExitCodeProcess failed. |
| + LOG(ERROR) << cmd_name << " (" << cmd_string |
|
erikwright (departed)
2012/09/21 14:08:49
no need for cmd_name here.
grt (UTC plus 2)
2012/09/21 14:20:33
it's not clear to me that the process taking longe
huangs
2012/09/21 18:48:43
Done.
huangs
2012/09/21 18:48:43
As discussed, will wait indefinitely. However, th
|
| + << ") is taking more than " << kGoogleUpdateTimeoutMs |
| + << " milliseconds to complete."; |
| + } |
| + return success; |
| +} |
| + |
| +} // namespace |
| + |
| +bool EnsureUserLevelGoogleUpdateInstalled() { |
| + LOG(INFO) << "Ensuring Google Update is installed at user level."; |
| + |
| + if (IsGoogleUpdateInstalled(false)) { |
| + LOG(INFO) << "Google Update is already installed."; |
|
grt (UTC plus 2)
2012/09/21 14:20:33
i don't think this is needed. the log files get p
huangs
2012/09/21 18:48:43
Done.
|
| + return true; |
| + } else { |
| + string16 cmd_name(L"Google Update installer"); |
|
erikwright (departed)
2012/09/21 14:08:49
There's no need to pass around cmd_name. For the p
huangs
2012/09/21 18:48:43
Done.
|
| + string16 install_cmd( |
| + GetUserLevelGoogleUpdateInstallCommandLine().GetCommandLineString()); |
| + base::win::ScopedHandle process; |
|
grt (UTC plus 2)
2012/09/21 14:20:33
i think this should check that the command string
huangs
2012/09/21 18:48:43
Added check for empty string upstream.
|
| + return ExecuteGoogleUpdateCommand(install_cmd, cmd_name, &process) && |
|
grt (UTC plus 2)
2012/09/21 14:20:33
please combine these two into one function that do
huangs
2012/09/21 18:48:43
Refactored another way!
|
| + WaitForGoogleUpdateCommand(install_cmd, cmd_name, process); |
| + } |
| +} |
| + |
| +bool UninstallGoogleUpdate(bool system_install) { |
| + string16 cmd_name(L"Google Update uninstaller"); |
| + string16 uninstall_cmd( |
| + GoogleUpdateSettings::GetUninstallCommandLine(system_install)); |
| + if (!uninstall_cmd.empty()) { |
| + base::win::ScopedHandle process; |
| + return ExecuteGoogleUpdateCommand(uninstall_cmd, cmd_name, &process) && |
| + WaitForGoogleUpdateCommand(uninstall_cmd, cmd_name, process); |
| + } |
| + return true; |
| +} |
| + |
| +} // namespace google_update |