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

Unified Diff: chrome/installer/util/google_update_util.cc

Issue 10957016: Ensuring Google Update at user-level is installed alongside App Host, for the quick-enable App Host… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Removing time-out, and wait for Google Update to install; moving flag to InstallerState; adding to … Created 8 years, 3 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 side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698