diff options
author | grt@chromium.org <grt@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-27 16:48:45 +0000 |
---|---|---|
committer | grt@chromium.org <grt@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-27 16:48:45 +0000 |
commit | 5d67720d49524b249eeb0892a61fcf179fde8dbf (patch) | |
tree | e2085749344892828c9cab18d26b4f458c7a2f38 /chrome | |
parent | e3d3a94984f6ce4d4fdaf0ce3dd3039d436188b5 (diff) | |
download | chromium_src-5d67720d49524b249eeb0892a61fcf179fde8dbf.zip chromium_src-5d67720d49524b249eeb0892a61fcf179fde8dbf.tar.gz chromium_src-5d67720d49524b249eeb0892a61fcf179fde8dbf.tar.bz2 |
Properly detect the current version when migrating single to multi. Previously, we were missing the current version, which could have led to:
- failing to set "opv" on in-use update
- failing to unregister Chrome Frame COM DLLs
- returning INSTALL_FAILED instead of SAME_VERSION_REPAIR_FAILED
- returning FIRST_INSTALL_SUCCESS instead of INSTALL_REPAIRED, IN_USE_UPDATED, or NEW_VERSION_UPDATED
- leaving behind old version directories
- failing to check for duplicates on same version repair
BUG=none
TEST=install single chrome. run mini_installer.exe with --multi-install --chrome to migrate to multi-install. make sure the installer result code is correct as above.
Review URL: http://codereview.chromium.org/6976049
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@87035 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/chrome_installer.gypi | 2 | ||||
-rw-r--r-- | chrome/installer/util/fake_installation_state.h | 59 | ||||
-rw-r--r-- | chrome/installer/util/fake_product_state.h | 36 | ||||
-rw-r--r-- | chrome/installer/util/installer_state.cc | 30 | ||||
-rw-r--r-- | chrome/installer/util/installer_state_unittest.cc | 26 |
5 files changed, 150 insertions, 3 deletions
diff --git a/chrome/chrome_installer.gypi b/chrome/chrome_installer.gypi index eb49522..814347ee 100644 --- a/chrome/chrome_installer.gypi +++ b/chrome/chrome_installer.gypi @@ -88,6 +88,8 @@ 'installer/util/delete_reg_value_work_item_unittest.cc', 'installer/util/delete_tree_work_item_unittest.cc', 'installer/util/duplicate_tree_detector_unittest.cc', + 'installer/util/fake_installation_state.h', + 'installer/util/fake_product_state.h', 'installer/util/google_chrome_distribution_unittest.cc', 'installer/util/google_update_settings_unittest.cc', 'installer/util/install_util_unittest.cc', diff --git a/chrome/installer/util/fake_installation_state.h b/chrome/installer/util/fake_installation_state.h new file mode 100644 index 0000000..fc91a42 --- /dev/null +++ b/chrome/installer/util/fake_installation_state.h @@ -0,0 +1,59 @@ +// Copyright (c) 2011 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. + +#ifndef CHROME_INSTALLER_UTIL_FAKE_INSTALLATION_STATE_H_ +#define CHROME_INSTALLER_UTIL_FAKE_INSTALLATION_STATE_H_ +#pragma once + +#include "base/file_path.h" +#include "base/version.h" +#include "chrome/installer/util/fake_product_state.h" +#include "chrome/installer/util/helper.h" +#include "chrome/installer/util/installation_state.h" +#include "chrome/installer/util/util_constants.h" + +namespace installer { + +// An InstallationState helper for use by unit tests. +class FakeInstallationState : public InstallationState { + public: + // Takes ownership of |version|. + void AddChrome(bool system_install, bool multi_install, Version* version) { + FakeProductState chrome_state; + chrome_state.set_version(version); + chrome_state.set_multi_install(multi_install); + FilePath setup_exe( + GetChromeInstallPath(system_install, + BrowserDistribution::GetSpecificDistribution( + BrowserDistribution::CHROME_BROWSER))); + setup_exe = setup_exe + .AppendASCII(version->GetString()) + .Append(kInstallerDir) + .Append(kSetupExe); + chrome_state.SetUninstallProgram(setup_exe); + chrome_state.AddUninstallSwitch(switches::kUninstall); + if (multi_install) { + chrome_state.AddUninstallSwitch(switches::kMultiInstall); + chrome_state.AddUninstallSwitch(switches::kChrome); + } + SetProductState(system_install, BrowserDistribution::CHROME_BROWSER, + chrome_state); + } + + void SetProductState(bool system_install, + BrowserDistribution::Type type, + const ProductState& product_state) { + ProductState& target = GetProducts(system_install)[IndexFromDistType(type)]; + target.CopyFrom(product_state); + } + + protected: + ProductState* GetProducts(bool system_install) { + return system_install ? system_products_ : user_products_; + } +}; + +} // namespace installer + +#endif // CHROME_INSTALLER_UTIL_FAKE_INSTALLATION_STATE_H_ diff --git a/chrome/installer/util/fake_product_state.h b/chrome/installer/util/fake_product_state.h new file mode 100644 index 0000000..03fa1a4 --- /dev/null +++ b/chrome/installer/util/fake_product_state.h @@ -0,0 +1,36 @@ +// Copyright (c) 2011 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. + +#ifndef CHROME_INSTALLER_UTIL_FAKE_PRODUCT_STATE_H_ +#define CHROME_INSTALLER_UTIL_FAKE_PRODUCT_STATE_H_ +#pragma once + +#include <string> +#include "chrome/installer/util/installation_state.h" + +namespace installer { + +// A ProductState helper for use by unit tests. +class FakeProductState : public ProductState { + public: + // Takes ownership of |version|. + void set_version(Version* version) { version_.reset(version); } + void set_multi_install(bool multi) { multi_install_ = multi; } + void set_brand(const std::wstring& brand) { brand_ = brand; } + void set_usagestats(DWORD usagestats) { + has_usagestats_ = true; + usagestats_ = usagestats; + } + void clear_usagestats() { has_usagestats_ = false; } + void SetUninstallProgram(const FilePath& setup_exe) { + uninstall_command_ = CommandLine(setup_exe); + } + void AddUninstallSwitch(const std::string& option) { + uninstall_command_.AppendSwitch(option); + } +}; + +} // namespace installer + +#endif // CHROME_INSTALLER_UTIL_FAKE_PRODUCT_STATE_H_ diff --git a/chrome/installer/util/installer_state.cc b/chrome/installer/util/installer_state.cc index ff8a6b7..42e8e10 100644 --- a/chrome/installer/util/installer_state.cc +++ b/chrome/installer/util/installer_state.cc @@ -364,9 +364,33 @@ Version* InstallerState::GetCurrentVersion( const InstallationState& machine_state) const { DCHECK(!products_.empty()); scoped_ptr<Version> current_version; - const BrowserDistribution::Type prod_type = (package_type_ == MULTI_PACKAGE) ? - BrowserDistribution::CHROME_BINARIES : - products_[0]->distribution()->GetType(); + // If we're doing a multi-install, the current version may be either an + // existing multi or an existing single product that is being migrated + // in place (i.e., Chrome). In the latter case, there is no existing + // CHROME_BINARIES installation so we need to search for the product. + BrowserDistribution::Type prod_type; + if (package_type_ == MULTI_PACKAGE) { + prod_type = BrowserDistribution::CHROME_BINARIES; + if (machine_state.GetProductState(level_ == SYSTEM_LEVEL, + prod_type) == NULL) { + // Search for a product on which we're operating that is installed in our + // target directory. + Products::const_iterator end = products().end(); + for (Products::const_iterator scan = products().begin(); scan != end; + ++scan) { + BrowserDistribution::Type product_type = + (*scan)->distribution()->GetType(); + const ProductState* state = + machine_state.GetProductState(level_ == SYSTEM_LEVEL, product_type); + if (state != NULL && target_path_.IsParent(state->GetSetupPath())) { + prod_type = product_type; + break; + } + } + } + } else { + prod_type = products_[0]->distribution()->GetType(); + } const ProductState* product_state = machine_state.GetProductState(level_ == SYSTEM_LEVEL, prod_type); diff --git a/chrome/installer/util/installer_state_unittest.cc b/chrome/installer/util/installer_state_unittest.cc index c35fac4..7edb9b8 100644 --- a/chrome/installer/util/installer_state_unittest.cc +++ b/chrome/installer/util/installer_state_unittest.cc @@ -17,6 +17,9 @@ #include "base/version.h" #include "base/win/registry.h" #include "base/win/scoped_handle.h" +#include "chrome/common/chrome_constants.h" +#include "chrome/installer/util/fake_installation_state.h" +#include "chrome/installer/util/fake_product_state.h" #include "chrome/installer/util/google_update_constants.h" #include "chrome/installer/util/helper.h" #include "chrome/installer/util/installation_state.h" @@ -431,3 +434,26 @@ TEST_F(InstallerStateTest, InstallerResult) { } TempRegKeyOverride::DeleteAllTempKeys(); } + +// Test GetCurrentVersion when migrating single Chrome to multi +TEST_F(InstallerStateTest, GetCurrentVersionMigrateChrome) { + using installer::FakeInstallationState; + + const bool system_install = false; + FakeInstallationState machine_state; + + // Pretend that this version of single-install Chrome is already installed. + machine_state.AddChrome(system_install, false, + Version::GetVersionFromString(chrome::kChromeVersion)); + + // Now we're invoked to install multi Chrome. + CommandLine cmd_line( + CommandLine::FromString(L"setup.exe --multi-install --chrome")); + MasterPreferences prefs(cmd_line); + InstallerState installer_state; + installer_state.Initialize(cmd_line, prefs, machine_state); + + // Is the Chrome version picked up? + scoped_ptr<Version> version(installer_state.GetCurrentVersion(machine_state)); + EXPECT_TRUE(version.get() != NULL); +} |