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

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

Issue 10790144: Revert 148046 - Revert 147650 - Implement installation of the Chrome App Host. (Closed) Base URL: svn://svn.chromium.org/chrome/branches/1215/src/
Patch Set: 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/setup/uninstall.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
===================================================================
--- chrome/installer/setup/setup_main.cc (revision 148103)
+++ chrome/installer/setup/setup_main.cc (working copy)
@@ -148,8 +148,10 @@
void AddExistingMultiInstalls(const InstallationState& original_state,
InstallerState* installer_state) {
if (installer_state->is_multi_install()) {
- for (size_t i = 0; i < BrowserDistribution::kNumProductTypes; ++i) {
- BrowserDistribution::Type type = BrowserDistribution::kProductTypes[i];
+ for (size_t i = 0; i < BrowserDistribution::NUM_TYPES; ++i) {
+ BrowserDistribution::Type type =
+ static_cast<BrowserDistribution::Type>(i);
+
if (!installer_state->FindProduct(type)) {
const ProductState* state =
original_state.GetProductState(installer_state->system_install(),
@@ -333,18 +335,20 @@
#endif // defined(GOOGLE_CHROME_BUILD)
}
-// The supported multi-install modes are:
-// --multi-install --chrome --chrome-frame --ready-mode
+// If Chrome Frame is being installed by itself in multi-mode, non-ready-mode:
+// - If a non-multi Chrome Frame installation is present, fail.
+// If Chrome Frame is being installed by itself in multi-mode, ready-mode:
+// - If no Chrome installation is present, fail.
+// - If a Chrome installation is present, add it to the set of products to
+// install.
+// If Chrome Frame is being installed with Chrome in multi-mode, ready-mode:
// - If a non-multi Chrome Frame installation is present, Chrome Frame is
// removed from |installer_state|'s list of products (thereby preserving
// the existing SxS install).
// - If a multi Chrome Frame installation is present, its options are
// preserved (i.e., the --ready-mode command-line option is ignored).
-// --multi-install --chrome-frame
-// - If a non-multi Chrome Frame installation is present, fail.
-// - If --ready-mode and no Chrome installation is present, fail.
-// - If a Chrome installation is present, add it to the set of products to
-// install.
+// If any product is being installed in single-mode that already exists in
+// multi-mode, fail.
bool CheckMultiInstallConditions(const InstallationState& original_state,
InstallerState* installer_state,
installer::InstallStatus* status) {
@@ -356,13 +360,42 @@
if (installer_state->is_multi_install()) {
const Product* chrome =
installer_state->FindProduct(BrowserDistribution::CHROME_BROWSER);
+ const Product* app_host =
+ installer_state->FindProduct(BrowserDistribution::CHROME_APP_HOST);
+ const Product* binaries =
+ installer_state->FindProduct(BrowserDistribution::CHROME_BINARIES);
const Product* chrome_frame =
installer_state->FindProduct(BrowserDistribution::CHROME_FRAME);
const ProductState* cf_state =
original_state.GetProductState(system_level,
BrowserDistribution::CHROME_FRAME);
- if (chrome != NULL) {
- if (chrome_frame != NULL &&
+ const ProductState* chrome_state =
+ original_state.GetProductState(system_level,
+ BrowserDistribution::CHROME_BROWSER);
+
+ if (!binaries) {
+ if (app_host && !chrome && !chrome_frame && !cf_state && !chrome_state) {
+ DCHECK(!system_level);
+ // App Host may use Chrome/Chrome binaries at system-level.
+ if (original_state.GetProductState(
+ true, // system
+ BrowserDistribution::CHROME_BROWSER) ||
+ original_state.GetProductState(
+ true, // system
+ BrowserDistribution::CHROME_BINARIES)) {
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ // Every other scenario requires the binaries to be installed/updated
+ // simultaneous to the main product.
+ return false;
+ }
+ }
+
+ if (chrome) {
+ if (chrome_frame &&
chrome_frame->HasOption(installer::kOptionReadyMode)) {
// We're being asked to install Chrome with Chrome Frame in ready-mode.
// This is an optimistic operation: if a SxS install of Chrome Frame
@@ -384,56 +417,88 @@
VLOG(1) << "Performing initial install of Chrome Frame ready-mode.";
}
}
- } else if (chrome_frame != NULL) {
- // We're being asked to install or update Chrome Frame alone.
- const ProductState* chrome_state =
- original_state.GetProductState(system_level,
- BrowserDistribution::CHROME_BROWSER);
- if (chrome_state != NULL) {
- // 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)));
- multi_chrome->SetOption(installer::kOptionMultiInstall, true);
- chrome = installer_state->AddProduct(&multi_chrome);
- VLOG(1) << "Upgrading existing multi-install Chrome browser along with "
- << chrome_frame->distribution()->GetAppShortCutName();
- } else if (chrome_frame->HasOption(installer::kOptionReadyMode)) {
- // Chrome Frame with ready-mode is to be installed, yet Chrome is
- // neither installed nor being installed. Fail.
- LOG(ERROR) << "Cannot install Chrome Frame in ready mode without "
- "Chrome.";
- *status = installer::READY_MODE_REQUIRES_CHROME;
- installer_state->WriteInstallerResult(*status,
- IDS_INSTALL_READY_MODE_REQUIRES_CHROME_BASE, NULL);
- return false;
- }
+ } 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.
+ scoped_ptr<Product> multi_chrome(new Product(
+ BrowserDistribution::GetSpecificDistribution(
+ BrowserDistribution::CHROME_BROWSER)));
+ multi_chrome->SetOption(installer::kOptionMultiInstall, true);
+ chrome = installer_state->AddProduct(&multi_chrome);
+ VLOG(1) << "Upgrading existing Chrome browser in multi-install mode.";
+ } else if (chrome_frame &&
+ chrome_frame->HasOption(installer::kOptionReadyMode)) {
+ // Chrome Frame with ready-mode is to be installed, yet Chrome is
+ // neither installed nor being installed. Fail.
+ LOG(ERROR) << "Cannot install Chrome Frame in ready mode without Chrome.";
+ *status = installer::READY_MODE_REQUIRES_CHROME;
+ installer_state->WriteInstallerResult(
+ *status, IDS_INSTALL_READY_MODE_REQUIRES_CHROME_BASE, NULL);
+ return false;
}
// 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 != NULL &&
- cf_state != NULL && !cf_state->is_multi_install()) {
+ if (chrome_frame && cf_state && !cf_state->is_multi_install()) {
LOG(ERROR) << "Cannot migrate existing Chrome Frame installation to "
- "multi-install.";
+ << "multi-install.";
*status = installer::NON_MULTI_INSTALLATION_EXISTS;
installer_state->WriteInstallerResult(*status,
IDS_INSTALL_NON_MULTI_INSTALLATION_EXISTS_BASE, NULL);
return false;
}
- } else if (DCHECK_IS_ON()) {
+ } 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());
+ if (product_state != NULL) {
+ // Block downgrades from multi-install to single-install.
+ if (product_state->is_multi_install()) {
+ LOG(ERROR) << "Multi-install "
+ << products[0]->distribution()->GetAppShortCutName()
+ << " exists; aborting single install.";
+ *status = installer::MULTI_INSTALLATION_EXISTS;
+ installer_state->WriteInstallerResult(*status,
+ IDS_INSTALL_MULTI_INSTALLATION_EXISTS_BASE, NULL);
+ return false;
+ }
+ }
+
}
return true;
}
+bool CheckAppHostPreconditions(const InstallationState& original_state,
+ InstallerState* installer_state) {
+ if (!installer_state->FindProduct(BrowserDistribution::CHROME_APP_HOST))
+ return true;
+
+ if (!installer_state->is_multi_install()) {
+ VLOG(1) << "Application Host may only be installed in multi-install mode.";
+ return false;
+ }
+
+ if (installer_state->system_install()) {
+ VLOG(1) << "Application Host may only be installed at user-level.";
+ return false;
+ }
+
+ return true;
+}
+
// Checks for compatibility between the current state of the system and the
// desired operation. Also applies policy that mutates the desired operation;
// specifically, the |installer_state| object.
@@ -446,10 +511,12 @@
bool CheckPreInstallConditions(const InstallationState& original_state,
InstallerState* installer_state,
installer::InstallStatus* status) {
- // 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 (!CheckAppHostPreconditions(original_state, installer_state))
+ return false;
+ if (!CheckMultiInstallConditions(original_state, installer_state, status))
+ return false;
+
const Products& products = installer_state->products();
if (products.empty()) {
// We haven't been given any products on which to operate.
@@ -461,57 +528,47 @@
return false;
}
- if (!CheckMultiInstallConditions(original_state, installer_state, 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);
- bool is_first_install = true;
- const bool system_level = installer_state->system_install();
+ 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();
+ const ProductState* user_level_product_state =
+ original_state.GetProductState(false, browser_dist->GetType());
+ const ProductState* system_level_product_state =
+ original_state.GetProductState(true, browser_dist->GetType());
- for (size_t i = 0; i < products.size(); ++i) {
- const Product* product = products[i];
- BrowserDistribution* browser_dist = product->distribution();
+ // Allow upgrades to proceed so that out-of-date versions are not left
+ // around.
+ if (user_level_product_state)
+ continue;
- // Check for an existing installation of the product.
- const ProductState* product_state =
- original_state.GetProductState(system_level, browser_dist->GetType());
- if (product_state != NULL) {
- is_first_install = false;
- // Block downgrades from multi-install to single-install.
- if (!installer_state->is_multi_install() &&
- product_state->is_multi_install()) {
- LOG(ERROR) << "Multi-install " << browser_dist->GetAppShortCutName()
- << " exists; aborting single install.";
- *status = installer::MULTI_INSTALLATION_EXISTS;
- installer_state->WriteInstallerResult(*status,
- IDS_INSTALL_MULTI_INSTALLATION_EXISTS_BASE, NULL);
- return false;
- }
- }
+ // This is a new user-level install...
- // Check to avoid attempting to lay down a user-level installation on top
- // of a system-level one.
- const ProductState* other_state =
- original_state.GetProductState(!system_level, browser_dist->GetType());
- if (other_state != NULL && !system_level) {
- if (is_first_install) {
- // This is a user-level install and there is a system-level install of
- // the product.
+ if (system_level_product_state) {
+ // ... and the product already exists at system-level.
LOG(ERROR) << "Already installed version "
- << other_state->version().GetString()
+ << system_level_product_state->version().GetString()
<< " at system-level conflicts with this one at user-level.";
if (product->is_chrome()) {
// Instruct Google Update to launch the existing system-level Chrome.
// There should be no error dialog.
- FilePath chrome_exe(installer::GetChromeInstallPath(!system_level,
- browser_dist));
- if (chrome_exe.empty()) {
- // If we failed to construct install path. Give up.
+ FilePath install_path(installer::GetChromeInstallPath(true, // system
+ browser_dist));
+ if (install_path.empty()) {
+ // Give up if we failed to construct the install path.
*status = installer::OS_ERROR;
installer_state->WriteInstallerResult(*status,
- IDS_INSTALL_OS_ERROR_BASE, NULL);
+ IDS_INSTALL_OS_ERROR_BASE,
+ NULL);
} else {
*status = installer::EXISTING_VERSION_LAUNCHED;
- chrome_exe = chrome_exe.Append(installer::kChromeExe);
+ FilePath chrome_exe = install_path.Append(installer::kChromeExe);
CommandLine cmd(chrome_exe);
cmd.AppendSwitch(switches::kFirstRun);
installer_state->WriteInstallerResult(*status, 0, NULL);
@@ -519,34 +576,16 @@
base::LaunchProcess(cmd, base::LaunchOptions(), NULL);
}
} else {
- // Display an error message for Chrome Frame.
+ // Display an error message for other products.
*status = installer::SYSTEM_LEVEL_INSTALL_EXISTS;
- installer_state->WriteInstallerResult(*status,
- IDS_INSTALL_SYSTEM_LEVEL_EXISTS_BASE, NULL);
+ installer_state->WriteInstallerResult(
+ *status, IDS_INSTALL_SYSTEM_LEVEL_EXISTS_BASE, NULL);
}
return false;
}
- // This is an update, not a new install. Allow it to take place so that
- // out-of-date versions are not left around.
}
}
- // If no previous installation of Chrome, make sure installation directory
- // either does not exist or can be deleted (i.e. is not locked by some other
- // process).
- if (is_first_install) {
- if (file_util::PathExists(installer_state->target_path()) &&
- !file_util::Delete(installer_state->target_path(), true)) {
- LOG(ERROR) << "Installation directory "
- << installer_state->target_path().value()
- << " exists and can not be deleted.";
- *status = installer::INSTALL_DIR_IN_USE;
- int str_id = IDS_INSTALL_DIR_IN_USE_BASE;
- installer_state->WriteInstallerResult(*status, str_id, NULL);
- return false;
- }
- }
-
return true;
}
@@ -570,7 +609,7 @@
archive = cmd_line.GetSwitchValuePath(
installer::switches::kInstallArchive);
}
- VLOG(1) << "Archive found to install Chrome " << archive.value();
+
const Products& products = installer_state.products();
// Create a temp folder where we will unpack Chrome archive. If it fails,
@@ -586,13 +625,48 @@
VLOG(1) << "created path " << temp_path.path().value();
FilePath unpack_path(temp_path.path().Append(installer::kInstallSourceDir));
- if (UnPackArchive(archive, installer_state, temp_path.path(), unpack_path,
- archive_type)) {
- install_status = (*archive_type) == installer::INCREMENTAL_ARCHIVE_TYPE ?
- installer::APPLY_DIFF_PATCH_FAILED : installer::UNCOMPRESSION_FAILED;
- installer_state.WriteInstallerResult(install_status,
- IDS_INSTALL_UNCOMPRESSION_FAILED_BASE, NULL);
+
+ bool unpacked = false;
+
+ // We want to keep uncompressed archive (chrome.7z) that we get after
+ // uncompressing and binary patching. Get the location for this file.
+ FilePath archive_to_copy;
+ if (file_util::PathExists(archive)) {
+ VLOG(1) << "Archive found to install Chrome " << archive.value();
+ if (UnPackArchive(archive, installer_state, temp_path.path(), unpack_path,
+ archive_type)) {
+ install_status = (*archive_type) == installer::INCREMENTAL_ARCHIVE_TYPE ?
+ installer::APPLY_DIFF_PATCH_FAILED : installer::UNCOMPRESSION_FAILED;
+ installer_state.WriteInstallerResult(
+ install_status,
+ IDS_INSTALL_UNCOMPRESSION_FAILED_BASE,
+ NULL);
+ } else {
+ unpacked = true;
+ archive_to_copy = temp_path.path().Append(installer::kChromeArchive);
+ }
} else {
+ FilePath uncompressed_archive(cmd_line.GetProgram().DirName().Append(
+ installer::kChromeArchive));
+
+ if (file_util::PathExists(uncompressed_archive)) {
+ VLOG(1) << "Uncompressed archive found to install Chrome "
+ << uncompressed_archive.value();
+ *archive_type = installer::FULL_ARCHIVE_TYPE;
+ string16 unpacked_file;
+ if (LzmaUtil::UnPackArchive(uncompressed_archive.value(),
+ unpack_path.value(), &unpacked_file)) {
+ installer_state.WriteInstallerResult(
+ installer::UNCOMPRESSION_FAILED,
+ IDS_INSTALL_UNCOMPRESSION_FAILED_BASE,
+ NULL);
+ } else {
+ unpacked = true;
+ archive_to_copy = uncompressed_archive;
+ }
+ }
+ }
+ if (unpacked) {
VLOG(1) << "unpacked to " << unpack_path.value();
FilePath src_path(unpack_path.Append(installer::kInstallSourceChromeDir));
scoped_ptr<Version>
@@ -624,22 +698,28 @@
}
if (higher_products != 0) {
- COMPILE_ASSERT(BrowserDistribution::NUM_TYPES == 3,
+ COMPILE_ASSERT(BrowserDistribution::NUM_TYPES == 4,
add_support_for_new_products_here_);
const uint32 kBrowserBit = 1 << BrowserDistribution::CHROME_BROWSER;
const uint32 kGCFBit = 1 << BrowserDistribution::CHROME_FRAME;
+ const uint32 kAppHostBit = 1 << BrowserDistribution::CHROME_APP_HOST;
int message_id = 0;
proceed_with_installation = false;
install_status = installer::HIGHER_VERSION_EXISTS;
- if ((higher_products & kBrowserBit) != 0) {
- if ((higher_products & kGCFBit) != 0)
+ switch (higher_products) {
+ case kBrowserBit:
+ message_id = IDS_INSTALL_HIGHER_VERSION_BASE;
+ break;
+ case kGCFBit:
+ message_id = IDS_INSTALL_HIGHER_VERSION_CF_BASE;
+ break;
+ case kGCFBit | kBrowserBit:
message_id = IDS_INSTALL_HIGHER_VERSION_CB_CF_BASE;
- else
- message_id = IDS_INSTALL_HIGHER_VERSION_BASE;
- } else {
- DCHECK(higher_products == kGCFBit);
- message_id = IDS_INSTALL_HIGHER_VERSION_CF_BASE;
+ break;
+ default:
+ message_id = IDS_INSTALL_HIGHER_VERSION_APP_HOST_BASE;
+ break;
}
installer_state.WriteInstallerResult(install_status, message_id, NULL);
@@ -651,10 +731,6 @@
*installer_version, &install_status);
if (proceed_with_installation) {
- // We want to keep uncompressed archive (chrome.7z) that we get after
- // uncompressing and binary patching. Get the location for this file.
- FilePath archive_to_copy(
- temp_path.path().Append(installer::kChromeArchive));
FilePath prefs_source_path(cmd_line.GetSwitchValueNative(
installer::switches::kInstallerData));
install_status = installer::InstallOrUpdateProduct(original_state,
@@ -879,11 +955,20 @@
const InstallerState& installer_state,
const CommandLine& cmd_line) {
const Products& products = installer_state.products();
- // InstallerState::Initialize always puts Chrome first, and we rely on that
- // here for this reason: if Chrome is in-use, the user will be prompted to
- // confirm uninstallation. Upon cancel, we should not continue with the
- // other products.
- DCHECK(products.size() < 2 || products[0]->is_chrome());
+
+ if (installer_state.FindProduct(BrowserDistribution::CHROME_BROWSER)) {
+ // InstallerState::Initialize always puts Chrome first, and we rely on that
+ // here for this reason: if Chrome is in-use, the user will be prompted to
+ // confirm uninstallation. Upon cancel, we should not continue with the
+ // other products.
+ DCHECK(products[0]->is_chrome());
+ }
+ if (installer_state.FindProduct(BrowserDistribution::CHROME_BINARIES)) {
+ // Chrome Binaries should be last; if something else is cancelled, they
+ // should stay.
+ DCHECK(products[products.size() - 1]->is_chrome_binaries());
+ }
+
installer::InstallStatus install_status = installer::UNINSTALL_SUCCESSFUL;
installer::InstallStatus prod_status = installer::UNKNOWN_STATUS;
const bool force = cmd_line.HasSwitch(installer::switches::kForceUninstall);
« no previous file with comments | « chrome/installer/setup/install_worker.cc ('k') | chrome/installer/setup/uninstall.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698