summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorgrt@chromium.org <grt@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-27 16:48:45 +0000
committergrt@chromium.org <grt@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-27 16:48:45 +0000
commit5d67720d49524b249eeb0892a61fcf179fde8dbf (patch)
treee2085749344892828c9cab18d26b4f458c7a2f38 /chrome
parente3d3a94984f6ce4d4fdaf0ce3dd3039d436188b5 (diff)
downloadchromium_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.gypi2
-rw-r--r--chrome/installer/util/fake_installation_state.h59
-rw-r--r--chrome/installer/util/fake_product_state.h36
-rw-r--r--chrome/installer/util/installer_state.cc30
-rw-r--r--chrome/installer/util/installer_state_unittest.cc26
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);
+}