diff options
author | tommi@chromium.org <tommi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-12-29 19:20:18 +0000 |
---|---|---|
committer | tommi@chromium.org <tommi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-12-29 19:20:18 +0000 |
commit | 57618d827ba3d4d618b78518f538c4c613bbd906 (patch) | |
tree | 1d3a2608076bdfacadd1f0c13836e3d7be350e28 /chrome/installer | |
parent | 253274b4e2ffeea590480f461c6a0bdbfa5e4369 (diff) | |
download | chromium_src-57618d827ba3d4d618b78518f538c4c613bbd906.zip chromium_src-57618d827ba3d4d618b78518f538c4c613bbd906.tar.gz chromium_src-57618d827ba3d4d618b78518f538c4c613bbd906.tar.bz2 |
Do machine inspection on install.
When installing Chrome [x]or Chrome Frame in multi mode, check if the other product (CF xor Chrome) is installed.
If it is, also include it in the installation as we need to update both products in sync.
For Chrome Frame, I also added checks to see if CEEE is already enabled or if the user has already opted into GCF.
If CEEE has been enabled, we implicitly include it when the install is run even though ceee is not on the command line.
If ready-mode is set on the command line but Chrome Frame is already installed without it, we won't enable ready mode.
TEST=Try installing Chrome Frame in multi mode. Then install a more recent version of Chrome in multi mode. Both product should be updated. Secondly, for Chrome Frame, install it first and then try to run the installer again, but with ready-mode ont the command line. Chrome Frame should not be switched to ready mode.
BUG=61609
Review URL: http://codereview.chromium.org/6091008
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@70268 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/installer')
-rw-r--r-- | chrome/installer/setup/install.cc | 22 | ||||
-rw-r--r-- | chrome/installer/setup/setup_main.cc | 31 | ||||
-rw-r--r-- | chrome/installer/util/chrome_frame_distribution.cc | 31 | ||||
-rw-r--r-- | chrome/installer/util/helper.cc | 40 | ||||
-rw-r--r-- | chrome/installer/util/helper.h | 9 |
5 files changed, 113 insertions, 20 deletions
diff --git a/chrome/installer/setup/install.cc b/chrome/installer/setup/install.cc index 61f0b2c..d1d74d6 100644 --- a/chrome/installer/setup/install.cc +++ b/chrome/installer/setup/install.cc @@ -289,10 +289,7 @@ bool CreateOrUpdateChromeShortcuts(const FilePath& setup_path, bool create_all_shortcut, bool alt_shortcut) { // TODO(tommi): Change this function to use WorkItemList. -#ifndef NDEBUG - const MasterPreferences& prefs = MasterPreferences::ForCurrentProcess(); - DCHECK(prefs.install_chrome()); -#endif + DCHECK(product.is_chrome()); FilePath shortcut_path; int dir_enum = product.system_level() ? @@ -938,10 +935,16 @@ void AddChromeFrameWorkItems(bool install, return; } - const MasterPreferences& prefs = MasterPreferences::ForCurrentProcess(); - bool ready_mode = false; - prefs.GetBool(installer::master_preferences::kChromeFrameReadyMode, - &ready_mode); + // TODO(tommi): This assumes we know exactly how ShouldCreateUninstallEntry + // is implemented. Since there is logic in ChromeFrameDistribution for how + // to determine when this is enabled, this is how we have to figure out if + // this feature is enabled right now, but it's a hack and we need a cleaner + // way to figure this out. + // Note that we cannot just check the master preferences for + // kChromeFrameReadyMode, since there are other things that need to be correct + // in the environment in order to enable this feature. + bool ready_mode = !product.distribution()->ShouldCreateUninstallEntry(); + HKEY root = product.package().system_level() ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; bool update_chrome_uninstall_command = false; @@ -996,6 +999,7 @@ void AddChromeFrameWorkItems(bool install, // Chrome is not a part of this installation run, so we have to explicitly // check if Chrome is installed, and if so, update its uninstallation // command lines. + const MasterPreferences& prefs = MasterPreferences::ForCurrentProcess(); BrowserDistribution* chrome_dist = BrowserDistribution::GetSpecificDistribution( BrowserDistribution::CHROME_BROWSER, prefs); @@ -1017,6 +1021,8 @@ InstallStatus ChromeFrameReadyModeOptIn(const CommandLine& cmd_line) { prefs.GetBool(master_preferences::kSystemLevel, &system_install); BrowserDistribution* cf = BrowserDistribution::GetSpecificDistribution( BrowserDistribution::CHROME_FRAME, prefs); + DCHECK(cf->ShouldCreateUninstallEntry()) + << "Opting into CF should create an uninstall entry"; BrowserDistribution* chrome = BrowserDistribution::GetSpecificDistribution( BrowserDistribution::CHROME_BROWSER, prefs); diff --git a/chrome/installer/setup/setup_main.cc b/chrome/installer/setup/setup_main.cc index a3db00d..2db0977 100644 --- a/chrome/installer/setup/setup_main.cc +++ b/chrome/installer/setup/setup_main.cc @@ -704,13 +704,40 @@ bool PopulateInstallations(const MasterPreferences& prefs, ProductPackageMapping* installations) { DCHECK(installations); bool success = true; - if (prefs.install_chrome()) { + + bool implicit_chrome_install = false; + bool implicit_gcf_install = false; + + if (prefs.is_multi_install()) { + // See what products are already installed in multi mode. + // When we do multi installs, we must upgrade all installations + // in sync since they share the binaries. + struct CheckInstall { + bool* installed; + BrowserDistribution::Type type; + } product_checks[] = { + {&implicit_chrome_install, BrowserDistribution::CHROME_BROWSER}, + {&implicit_gcf_install, BrowserDistribution::CHROME_FRAME}, + }; + + for (size_t i = 0; i < arraysize(product_checks); ++i) { + BrowserDistribution* dist = BrowserDistribution::GetSpecificDistribution( + product_checks[i].type, prefs); + *product_checks[i].installed = installer::IsInstalledAsMulti( + installations->system_level(), dist); + LOG_IF(INFO, *product_checks[i].installed) + << "Product already installed and must be included: " + << dist->GetApplicationName(); + } + } + + if (prefs.install_chrome() || implicit_chrome_install) { VLOG(1) << "Install distribution: Chrome"; success = installations->AddDistribution( BrowserDistribution::CHROME_BROWSER, prefs); } - if (success && prefs.install_chrome_frame()) { + if (success && (prefs.install_chrome_frame() || implicit_gcf_install)) { VLOG(1) << "Install distribution: Chrome Frame"; success = installations->AddDistribution( BrowserDistribution::CHROME_FRAME, prefs); diff --git a/chrome/installer/util/chrome_frame_distribution.cc b/chrome/installer/util/chrome_frame_distribution.cc index c02e643..9d643c4 100644 --- a/chrome/installer/util/chrome_frame_distribution.cc +++ b/chrome/installer/util/chrome_frame_distribution.cc @@ -14,6 +14,7 @@ #include "base/string_util.h" #include "chrome/installer/util/google_update_constants.h" #include "chrome/installer/util/google_update_settings.h" +#include "chrome/installer/util/helper.h" #include "chrome/installer/util/install_util.h" #include "chrome/installer/util/l10n_string_util.h" #include "chrome/installer/util/master_preferences.h" @@ -32,6 +33,36 @@ ChromeFrameDistribution::ChromeFrameDistribution( type_ = BrowserDistribution::CHROME_FRAME; prefs.GetBool(installer::master_preferences::kChromeFrameReadyMode, &ready_mode_); + + bool system_install = false; + prefs.GetBool(installer::master_preferences::kSystemLevel, &system_install); + + // See if Chrome Frame is already installed. If so, we must make sure that + // the ceee and ready mode flags match. + CommandLine uninstall(CommandLine::NO_PROGRAM); + if (installer::GetUninstallSwitches(system_install, this, &uninstall)) { + if (!ceee_ && uninstall.HasSwitch(installer::switches::kCeee)) { + LOG(INFO) << "CEEE is not specified on the command line but CEEE is " + "already installed. Implicitly enabling CEEE."; + ceee_ = true; + } + + // If the user has already opted in to CF, we shouldn't set the ready-mode + // flag. If we don't do this, we might have two entries in the Add/Remove + // Programs list that can uninstall GCF. Also, we can only enable + // ready-mode if Chrome is also being installed. Without it, there's no way + // to uninstall Chrome Frame. + if (ready_mode_) { + if (!uninstall.HasSwitch(installer::switches::kChromeFrameReadyMode)) { + LOG(INFO) << "Ready mode was specified on the command line but GCF " + "is already fully installed. Ignoring command line."; + ready_mode_ = false; + } else if (!prefs.install_chrome()) { + LOG(WARNING) << "Cannot enable ready mode without installing Chrome."; + ready_mode_ = false; + } + } + } } std::wstring ChromeFrameDistribution::GetAppGuid() { diff --git a/chrome/installer/util/helper.cc b/chrome/installer/util/helper.cc index c1b9d42..aa6a264 100644 --- a/chrome/installer/util/helper.cc +++ b/chrome/installer/util/helper.cc @@ -41,18 +41,38 @@ namespace installer { bool IsInstalledAsMulti(bool system_install, BrowserDistribution* dist) { bool installed_as_multi = false; - HKEY root = system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; - RegKey key(root, dist->GetStateKey().c_str(), KEY_READ); - if (key.Valid()) { - std::wstring args; - key.ReadValue(installer::kUninstallArgumentsField, &args); - if (!args.empty()) { - args.insert(0, L"fake.exe "); - CommandLine cmd(CommandLine::FromString(args)); - installed_as_multi = cmd.HasSwitch(installer::switches::kMultiInstall); + CommandLine cmd(CommandLine::NO_PROGRAM); + if (GetUninstallSwitches(system_install, dist, &cmd)) + installed_as_multi = cmd.HasSwitch(installer::switches::kMultiInstall); + return installed_as_multi; +} + +bool GetUninstallSwitches(bool system_install, BrowserDistribution* dist, + CommandLine* cmd_line_switches) { + scoped_ptr<Version> installed(InstallUtil::GetChromeVersion(dist, + system_install)); + if (installed.get()) { + HKEY root = system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; + RegKey key(root, dist->GetStateKey().c_str(), KEY_READ); + if (key.Valid()) { + std::wstring args; + key.ReadValue(installer::kUninstallArgumentsField, &args); + if (!args.empty()) { + args.insert(0, L"foo.exe "); + *cmd_line_switches = CommandLine::FromString(args); + } else { + LOG(ERROR) << "No uninstallation arguments for " + << dist->GetApplicationName(); + installed.reset(); + } + } else { + LOG(ERROR) << "Product looks to be installed but we can't access the " + "state key: " << dist->GetApplicationName(); + installed.reset(); } } - return installed_as_multi; + + return installed.get() != NULL; } FilePath GetChromeInstallPath(bool system_install, BrowserDistribution* dist) { diff --git a/chrome/installer/util/helper.h b/chrome/installer/util/helper.h index 3845806..e5f19ae 100644 --- a/chrome/installer/util/helper.h +++ b/chrome/installer/util/helper.h @@ -9,6 +9,7 @@ #pragma once class BrowserDistribution; +class CommandLine; class FilePath; namespace installer { @@ -16,6 +17,14 @@ namespace installer { // Checks if a distribution is currently installed as part of a multi-install. bool IsInstalledAsMulti(bool system_install, BrowserDistribution* dist); +// Retrieves the command line switches for uninstalling the distribution. +// Note that the returned CommandLine object does not include a "program". +// Only the switches should be used. +// Returns true if the product is installed and the uninstall switches +// were successfully retrieved, otherwise false. +bool GetUninstallSwitches(bool system_install, BrowserDistribution* dist, + CommandLine* cmd_line_switches); + // This function returns the install path for Chrome depending on whether its // system wide install or user specific install. // system_install: if true, the function returns system wide location |