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

Unified Diff: chrome/installer/setup/setup_main.cc

Issue 10806086: Fix multi-install update regression. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: addressed review comments Created 8 years, 5 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
« no previous file with comments | « chrome/installer/setup/install_worker.cc ('k') | chrome/installer/util/chrome_binaries_operations.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/installer/setup/setup_main.cc
diff --git a/chrome/installer/setup/setup_main.cc b/chrome/installer/setup/setup_main.cc
index eb59d175a630b57a8153b5bbdcb399353f9375f4..95490b029e6811753a12c4a130e0a8a913acd3f5 100644
--- a/chrome/installer/setup/setup_main.cc
+++ b/chrome/installer/setup/setup_main.cc
@@ -217,27 +217,13 @@ installer::InstallStatus RenameChromeExecutables(
install_list->AddDeleteTreeWorkItem(chrome_old_exe, temp_path.path())
->set_ignore_failure(true);
- // Collect the set of distributions we need to update, which is the
- // multi-install binaries (if this is a multi-install operation) and all
- // products we're operating on.
- BrowserDistribution* dists[BrowserDistribution::NUM_TYPES];
- int num_dists = 0;
- // First, add the multi-install binaries, if relevant.
- if (installer_state->is_multi_install())
- dists[num_dists++] = installer_state->multi_package_binaries_distribution();
- // Next, add all products we're operating on. std::transform can handily do
- // this for us, but this is discouraged as being too tricky.
- const Products& products = installer_state->products();
- for (Products::size_type i = 0; i < products.size(); ++i) {
- dists[num_dists++] = products[i]->distribution();
- }
-
// Add work items to delete the "opv", "cpv", and "cmd" values from all
- // distributions.
+ // products we're operating on (which including the multi-install binaries).
+ const Products& products = installer_state->products();
HKEY reg_root = installer_state->root_key();
string16 version_key;
- for (int i = 0; i < num_dists; ++i) {
- version_key = dists[i]->GetVersionKey();
+ for (size_t i = 0; i < products.size(); ++i) {
+ version_key = products[i]->distribution()->GetVersionKey();
install_list->AddDeleteRegValueWorkItem(
reg_root, version_key, google_update::kRegOldVersionField);
install_list->AddDeleteRegValueWorkItem(
@@ -383,14 +369,23 @@ bool CheckMultiInstallConditions(const InstallationState& original_state,
original_state.GetProductState(
true, // system
BrowserDistribution::CHROME_BINARIES)) {
+ VLOG(1) << "Installing/updating Application Host without binaries.";
return true;
} else {
+ // Somehow the binaries were present when the quick-enable app host
+ // command was run, but now they appear to be missing.
+ // TODO(erikwright): should the binaries be implicitly added?
+ LOG(ERROR) << "Cannot install Application Host without binaries.";
+ *status = installer::APP_HOST_REQUIRES_BINARIES;
+ installer_state->WriteInstallerResult(*status, 0, NULL);
return false;
}
} else {
// Every other scenario requires the binaries to be installed/updated
- // simultaneous to the main product.
- return false;
+ // along with the main product. This will only be hit if
+ // --multi-install is given with no products. See
+ // CheckPreInstallConditions for handling of this case.
+ return true;
}
}
@@ -417,10 +412,10 @@ bool CheckMultiInstallConditions(const InstallationState& original_state,
VLOG(1) << "Performing initial install of Chrome Frame ready-mode.";
}
}
- } else if (chrome_state != NULL) {
- // Chrome Frame is being installed in multi-install mode, and Chrome is
- // already present. Add Chrome to the set of products (making it
- // multi-install in the process) so that it is updated, too.
+ } else if (chrome_state) {
+ // A product other than Chrome is being installed in multi-install mode,
+ // and Chrome is already present. Add Chrome to the set of products
+ // (making it multi-install in the process) so that it is updated, too.
scoped_ptr<Product> multi_chrome(new Product(
BrowserDistribution::GetSpecificDistribution(
BrowserDistribution::CHROME_BROWSER)));
@@ -440,8 +435,6 @@ bool CheckMultiInstallConditions(const InstallationState& original_state,
// Fail if we're installing Chrome Frame when a single-install of it is
// already installed.
- // TODO(grt): Add support for migration of Chrome Frame from single- to
- // multi-install.
if (chrome_frame && cf_state && !cf_state->is_multi_install()) {
LOG(ERROR) << "Cannot migrate existing Chrome Frame installation to "
<< "multi-install.";
@@ -453,13 +446,6 @@ bool CheckMultiInstallConditions(const InstallationState& original_state,
} else {
// This is a non-multi installation.
- // It isn't possible to stuff two products into a single-install
- // InstallerState. Abort the process here in debug builds just in case
- // someone finds a way.
- DCHECK_EQ(1U, products.size());
- if (products.size() != 1)
- return false;
-
// Check for an existing installation of the product.
const ProductState* product_state = original_state.GetProductState(
system_level, products[0]->distribution()->GetType());
@@ -475,25 +461,36 @@ bool CheckMultiInstallConditions(const InstallationState& original_state,
return false;
}
}
-
}
return true;
}
+// Checks app host pre-install conditions, specifically that this is a
+// user-level multi-install. When the pre-install conditions are not
+// satisfied, the result is written to the registry (via WriteInstallerResult),
+// |status| is set appropriately, and false is returned.
bool CheckAppHostPreconditions(const InstallationState& original_state,
- InstallerState* installer_state) {
- if (!installer_state->FindProduct(BrowserDistribution::CHROME_APP_HOST))
- return true;
+ InstallerState* installer_state,
+ installer::InstallStatus* status) {
+ if (installer_state->FindProduct(BrowserDistribution::CHROME_APP_HOST)) {
- if (!installer_state->is_multi_install()) {
- VLOG(1) << "Application Host may only be installed in multi-install mode.";
- return false;
- }
+ if (!installer_state->is_multi_install()) {
+ LOG(DFATAL) << "Application Host requires multi install";
+ *status = installer::APP_HOST_REQUIRES_MULTI_INSTALL;
+ // No message string since there is nothing a user can do.
+ installer_state->WriteInstallerResult(*status, 0, NULL);
+ return false;
+ }
+
+ if (installer_state->system_install()) {
+ LOG(DFATAL) << "Application Host may only be installed at user-level.";
+ *status = installer::APP_HOST_REQUIRES_USER_LEVEL;
+ // No message string since there is nothing a user can do.
+ installer_state->WriteInstallerResult(*status, 0, NULL);
+ return false;
+ }
- if (installer_state->system_install()) {
- VLOG(1) << "Application Host may only be installed at user-level.";
- return false;
}
return true;
@@ -511,11 +508,19 @@ bool CheckAppHostPreconditions(const InstallationState& original_state,
bool CheckPreInstallConditions(const InstallationState& original_state,
InstallerState* installer_state,
installer::InstallStatus* status) {
- if (!CheckAppHostPreconditions(original_state, installer_state))
+ if (!CheckAppHostPreconditions(original_state, installer_state, status)) {
+ DCHECK_NE(*status, installer::UNKNOWN_STATUS);
return false;
+ }
+
+ // See what products are already installed in multi mode. When we do multi
+ // installs, we must upgrade all installations since they share the binaries.
+ AddExistingMultiInstalls(original_state, installer_state);
- if (!CheckMultiInstallConditions(original_state, installer_state, status))
+ if (!CheckMultiInstallConditions(original_state, installer_state, status)) {
+ DCHECK_NE(*status, installer::UNKNOWN_STATUS);
return false;
+ }
const Products& products = installer_state->products();
if (products.empty()) {
@@ -528,16 +533,18 @@ bool CheckPreInstallConditions(const InstallationState& original_state,
return false;
}
- // See what products are already installed in multi mode. When we do multi
- // installs, we must upgrade all installations since they share the binaries.
- AddExistingMultiInstalls(original_state, installer_state);
-
if (!installer_state->system_install()) {
// This is a user-level installation. Make sure that we are not installing
// on top of an existing system-level installation.
for (size_t i = 0; i < products.size(); ++i) {
const Product* product = products[i];
BrowserDistribution* browser_dist = product->distribution();
+
+ // Skip over the binaries, as it's okay for them to be at both levels
+ // for different products.
+ if (browser_dist->GetType() == BrowserDistribution::CHROME_BINARIES)
+ continue;
+
const ProductState* user_level_product_state =
original_state.GetProductState(false, browser_dist->GetType());
const ProductState* system_level_product_state =
@@ -873,6 +880,9 @@ installer::InstallStatus InstallProducts(
VLOG(1) << "Installing to " << installer_state->target_path().value();
install_status = InstallProductsHelper(
original_state, cmd_line, prefs, *installer_state, &archive_type);
+ } else {
+ // CheckPreInstallConditions must set the status on failure.
+ DCHECK_NE(install_status, installer::UNKNOWN_STATUS);
}
const Products& products = installer_state->products();
@@ -882,10 +892,6 @@ installer::InstallStatus InstallProducts(
product->distribution()->UpdateInstallStatus(
system_install, archive_type, install_status);
}
- if (installer_state->is_multi_install()) {
- installer_state->multi_package_binaries_distribution()->UpdateInstallStatus(
- system_install, archive_type, install_status);
- }
installer_state->UpdateStage(installer::NO_STAGE);
return install_status;
@@ -1464,7 +1470,13 @@ int WINAPI wWinMain(HINSTANCE instance, HINSTANCE prev_instance,
} else if (is_uninstall) {
// Only show the message box if Chrome Frame was the only product being
// uninstalled.
- if (installer_state.products().size() == 1U) {
+ const Products& products = installer_state.products();
+ int num_products = 0;
+ for (size_t i = 0; i < products.size(); ++i) {
+ if (!products[i]->is_chrome_binaries())
+ ++num_products;
+ }
+ if (num_products == 1U) {
::MessageBoxW(NULL,
installer::GetLocalizedString(
IDS_UNINSTALL_COMPLETE_BASE).c_str(),
« no previous file with comments | « chrome/installer/setup/install_worker.cc ('k') | chrome/installer/util/chrome_binaries_operations.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698