diff options
author | tommi@chromium.org <tommi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-11 21:36:55 +0000 |
---|---|---|
committer | tommi@chromium.org <tommi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-11 21:36:55 +0000 |
commit | 933d320d6e4366547dc7abffb32fa2d06a1ae7d4 (patch) | |
tree | 0183066fe593c80c2c385a426606295f510f45e4 | |
parent | c742d957136361c4164e0e93ad78267e558339e8 (diff) | |
download | chromium_src-933d320d6e4366547dc7abffb32fa2d06a1ae7d4.zip chromium_src-933d320d6e4366547dc7abffb32fa2d06a1ae7d4.tar.gz chromium_src-933d320d6e4366547dc7abffb32fa2d06a1ae7d4.tar.bz2 |
Add multi install support to MasterPreferences and start using it in a few places.I'm also adding a constant for CEEE - I named it kCeee instead of kEnableCeee since it's also used in uninstalls.This change is just a beginning of being aware of having more than one product available in setup.
I added some todos and dcheck for myself to keep track of places that will need more significant changes when running multiple installs.
BUG=61609
TEST=All installations (chrome, chrome frame, ceee) should work as before with the exception that the CEEE switch is now --ceee and not --enable-ceee.
Review URL: http://codereview.chromium.org/4635006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@65855 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/installer/setup/install.cc | 105 | ||||
-rw-r--r-- | chrome/installer/setup/setup_main.cc | 45 | ||||
-rw-r--r-- | chrome/installer/util/browser_distribution.cc | 16 | ||||
-rw-r--r-- | chrome/installer/util/install_util.cc | 11 | ||||
-rw-r--r-- | chrome/installer/util/logging_installer.cc | 36 | ||||
-rw-r--r-- | chrome/installer/util/logging_installer.h | 9 | ||||
-rw-r--r-- | chrome/installer/util/master_preferences.cc | 62 | ||||
-rw-r--r-- | chrome/installer/util/master_preferences.h | 23 | ||||
-rw-r--r-- | chrome/installer/util/master_preferences_constants.cc | 5 | ||||
-rw-r--r-- | chrome/installer/util/master_preferences_constants.h | 11 | ||||
-rw-r--r-- | chrome/installer/util/master_preferences_unittest.cc | 95 | ||||
-rw-r--r-- | chrome/installer/util/util_constants.cc | 11 | ||||
-rw-r--r-- | chrome/installer/util/util_constants.h | 5 |
13 files changed, 328 insertions, 106 deletions
diff --git a/chrome/installer/setup/install.cc b/chrome/installer/setup/install.cc index adc7eb8..c1325f8 100644 --- a/chrome/installer/setup/install.cc +++ b/chrome/installer/setup/install.cc @@ -12,6 +12,7 @@ #include "base/logging.h" #include "base/path_service.h" #include "base/scoped_ptr.h" +#include "base/string_util.h" #include "base/win/registry.h" #include "chrome/installer/setup/setup_constants.h" #include "chrome/installer/util/browser_distribution.h" @@ -81,39 +82,43 @@ void AddInstallerCopyTasks(const std::wstring& exe_path, } } -void AppendUninstallCommandLineFlags(std::wstring* uninstall_cmd_line, - bool is_system) { - DCHECK(uninstall_cmd_line); - uninstall_cmd_line->append(L" --"); - uninstall_cmd_line->append(installer_util::switches::kUninstall); +// A little helper function to save on tons of WideToASCII call sites. +void AppendWideSwitch(CommandLine* cmd, const wchar_t* switch_name) { + cmd->AppendSwitch(WideToASCII(switch_name)); +} - if (InstallUtil::IsChromeFrameProcess()) { - uninstall_cmd_line->append(L" --"); - uninstall_cmd_line->append(installer_util::switches::kDeleteProfile); - uninstall_cmd_line->append(L" --"); - uninstall_cmd_line->append(installer_util::switches::kChromeFrame); +void AppendUninstallCommandLineFlags(CommandLine* uninstall_cmd, + bool is_system) { + DCHECK(uninstall_cmd); + AppendWideSwitch(uninstall_cmd, installer_util::switches::kUninstall); + + // TODO(tommi): In case of multiple installations, we need to create multiple + // uninstall entries, and not one magic one for all. + const installer_util::MasterPreferences& prefs = + InstallUtil::GetMasterPreferencesForCurrentProcess(); + DCHECK(!prefs.is_multi_install()); + + if (prefs.install_chrome_frame()) { + AppendWideSwitch(uninstall_cmd, installer_util::switches::kDeleteProfile); + AppendWideSwitch(uninstall_cmd, installer_util::switches::kChromeFrame); } if (InstallUtil::IsChromeSxSProcess()) { - uninstall_cmd_line->append(L" --"); - uninstall_cmd_line->append(installer_util::switches::kChromeSxS); + AppendWideSwitch(uninstall_cmd, installer_util::switches::kChromeSxS); } if (InstallUtil::IsMSIProcess(is_system)) { - uninstall_cmd_line->append(L" --"); - uninstall_cmd_line->append(installer_util::switches::kMsi); + AppendWideSwitch(uninstall_cmd, installer_util::switches::kMsi); } // Propagate the verbose logging switch to uninstalls too. const CommandLine& command_line = *CommandLine::ForCurrentProcess(); if (command_line.HasSwitch(installer_util::switches::kVerboseLogging)) { - uninstall_cmd_line->append(L" --"); - uninstall_cmd_line->append(installer_util::switches::kVerboseLogging); + AppendWideSwitch(uninstall_cmd, installer_util::switches::kVerboseLogging); } if (is_system) { - uninstall_cmd_line->append(L" --"); - uninstall_cmd_line->append(installer_util::switches::kSystemLevel); + AppendWideSwitch(uninstall_cmd, installer_util::switches::kSystemLevel); } } @@ -129,45 +134,49 @@ void AddUninstallShortcutWorkItems(HKEY reg_root, BrowserDistribution* dist = BrowserDistribution::GetDistribution(); const CommandLine& command_line = *CommandLine::ForCurrentProcess(); + // TODO(tommi): Support this for multi-install. We need to add work items + // for each product being installed. + const installer_util::MasterPreferences& prefs = + InstallUtil::GetMasterPreferencesForCurrentProcess(); + DCHECK(!prefs.is_multi_install()) << "TODO"; + // When we are installed via an MSI, we need to store our uninstall strings // in the Google Update client state key. We do this even for non-MSI // managed installs to avoid breaking the edge case whereby an MSI-managed // install is updated by a non-msi installer (which would confuse the MSI // machinery if these strings were not also updated). // Do not quote the command line for the MSI invocation. - std::wstring uninstall_cmd( - installer::GetInstallerPathUnderChrome(install_path, new_version)); - file_util::AppendToPath(&uninstall_cmd, - file_util::GetFilenameFromPath(exe_path)); - std::wstring uninstall_arguments; + FilePath installer_path(installer::GetInstallerPathUnderChrome(install_path, + new_version)); + installer_path = installer_path.Append( + file_util::GetFilenameFromPath(exe_path)); + + CommandLine uninstall_arguments(CommandLine::NO_PROGRAM); AppendUninstallCommandLineFlags(&uninstall_arguments, reg_root == HKEY_LOCAL_MACHINE); std::wstring update_state_key = dist->GetStateKey(); install_list->AddCreateRegKeyWorkItem(reg_root, update_state_key); install_list->AddSetRegValueWorkItem(reg_root, update_state_key, - installer_util::kUninstallStringField, uninstall_cmd, true); + installer_util::kUninstallStringField, installer_path.value(), true); install_list->AddSetRegValueWorkItem(reg_root, update_state_key, - installer_util::kUninstallArgumentsField, uninstall_arguments, true); + installer_util::kUninstallArgumentsField, + uninstall_arguments.command_line_string(), true); // MSI installations will manage their own uninstall shortcuts. if (!InstallUtil::IsMSIProcess(reg_root == HKEY_LOCAL_MACHINE)) { // We need to quote the command line for the Add/Remove Programs dialog. - std::wstring quoted_uninstall_cmd(L"\""); - quoted_uninstall_cmd += uninstall_cmd; - quoted_uninstall_cmd += L"\""; + CommandLine quoted_uninstall_cmd(installer_path); + DCHECK_EQ(quoted_uninstall_cmd.command_line_string()[0], '"'); + quoted_uninstall_cmd.AppendArguments(uninstall_arguments, false); - AppendUninstallCommandLineFlags("ed_uninstall_cmd, - reg_root == HKEY_LOCAL_MACHINE); std::wstring uninstall_reg = dist->GetUninstallRegPath(); install_list->AddCreateRegKeyWorkItem(reg_root, uninstall_reg); install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg, installer_util::kUninstallDisplayNameField, product_name, true); install_list->AddSetRegValueWorkItem(reg_root, - uninstall_reg, - installer_util::kUninstallStringField, - quoted_uninstall_cmd, - true); + uninstall_reg, installer_util::kUninstallStringField, + quoted_uninstall_cmd.command_line_string(), true); install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg, L"InstallLocation", @@ -340,14 +349,14 @@ bool CreateOrUpdateChromeShortcuts(const std::wstring& exe_path, file_util::AppendToPath(&setup_exe, file_util::GetFilenameFromPath(exe_path)); - std::wstring arguments; + CommandLine arguments(CommandLine::NO_PROGRAM); AppendUninstallCommandLineFlags(&arguments, system_install); VLOG(1) << "Creating/updating uninstall link at " << uninstall_link.value(); ret = ret && file_util::CreateShortcutLink(setup_exe.c_str(), uninstall_link.value().c_str(), NULL, - arguments.c_str(), + arguments.command_line_string().c_str(), NULL, setup_exe.c_str(), 0, @@ -394,6 +403,8 @@ bool DoPostInstallTasks(HKEY reg_root, std::wstring version_key = dist->GetVersionKey(); bool is_system_install = (reg_root == HKEY_LOCAL_MACHINE); + const installer_util::MasterPreferences& prefs = + InstallUtil::GetMasterPreferencesForCurrentProcess(); if (file_util::PathExists(FilePath::FromWStringHack(new_chrome_exe))) { // Looks like this was in use update. So make sure we update the 'opv' key @@ -419,7 +430,7 @@ bool DoPostInstallTasks(HKEY reg_root, if (is_system_install) rename_cmd = rename_cmd + L" --" + installer_util::switches::kSystemLevel; - if (InstallUtil::IsChromeFrameProcess()) { + if (prefs.install_chrome_frame()) { rename_cmd += L" --"; rename_cmd += installer_util::switches::kChromeFrame; } @@ -455,15 +466,16 @@ bool DoPostInstallTasks(HKEY reg_root, } } - if (InstallUtil::IsChromeFrameProcess()) { - // Chrome Frame instances of setup.exe should always have at least - // one DLL to register. Enforce that this is so. + if (prefs.install_chrome_frame()) { + // TODO(tommi): setup.exe should always have at least one DLL to + // register. Currently we rely on scan_server_dlls.py to populate + // the array for us, but we might as well use an explicit static + // array of required components. if (kNumDllsToRegister <= 0) { - NOTREACHED(); + NOTREACHED() << "no dlls to register"; return false; } - // Now we need to register any self registering components and unregister // any that were left from the old version that is being upgraded: if (!current_version.empty()) { std::wstring old_dll_path(install_path); @@ -606,8 +618,10 @@ installer_util::InstallStatus InstallNewVersion( KEY_READ); if (file_util::PathExists(FilePath::FromWStringHack(new_chrome_exe))) chrome_key.ReadValue(google_update::kRegOldVersionField, current_version); + if (current_version->empty()) chrome_key.ReadValue(google_update::kRegVersionField, current_version); + chrome_key.Close(); install_list->AddDeleteTreeWorkItem(new_chrome_exe, std::wstring()); @@ -757,9 +771,12 @@ installer_util::InstallStatus installer::InstallOrUpdateChrome( CopyPreferenceFileForFirstRun(system_install, prefs_path); bool value = false; - if (!prefs.GetBool( + // TODO(tommi): Currently this only creates shortcuts for Chrome, but + // for other products we might want to create shortcuts. + if (prefs.install_chrome() && + (!prefs.GetBool( installer_util::master_preferences::kDoNotCreateShortcuts, - &value) || !value) { + &value) || !value)) { bool create_all_shortcut = false; prefs.GetBool(installer_util::master_preferences::kCreateAllShortcuts, &create_all_shortcut); diff --git a/chrome/installer/setup/setup_main.cc b/chrome/installer/setup/setup_main.cc index 0898017..88b74d1 100644 --- a/chrome/installer/setup/setup_main.cc +++ b/chrome/installer/setup/setup_main.cc @@ -327,9 +327,13 @@ installer_util::InstallStatus InstallChrome(const CommandLine& cmd_line, } bool value = false; - prefs.GetBool( - installer_util::master_preferences::kDoNotRegisterForUpdateLaunch, - &value); + if (prefs.install_chrome()) { + prefs.GetBool( + installer_util::master_preferences::kDoNotRegisterForUpdateLaunch, + &value); + } else { + value = true; // Never register. + } bool write_chrome_launch_string = (!value) && (install_status != installer_util::IN_USE_UPDATED); @@ -338,12 +342,15 @@ installer_util::InstallStatus InstallChrome(const CommandLine& cmd_line, if (install_status == installer_util::FIRST_INSTALL_SUCCESS) { VLOG(1) << "First install successful."; - // We never want to launch Chrome in system level install mode. - bool do_not_launch_chrome = false; - prefs.GetBool(installer_util::master_preferences::kDoNotLaunchChrome, - &do_not_launch_chrome); - if (!system_level && !do_not_launch_chrome) - installer::LaunchChrome(system_level); + if (prefs.install_chrome()) { + // We never want to launch Chrome in system level install mode. + bool do_not_launch_chrome = false; + prefs.GetBool( + installer_util::master_preferences::kDoNotLaunchChrome, + &do_not_launch_chrome); + if (!system_level && !do_not_launch_chrome) + installer::LaunchChrome(system_level); + } } else if ((install_status == installer_util::NEW_VERSION_UPDATED) || (install_status == installer_util::IN_USE_UPDATED)) { installer_setup::RemoveLegacyRegistryKeys(); @@ -618,28 +625,12 @@ int WINAPI wWinMain(HINSTANCE instance, HINSTANCE prev_instance, // The exit manager is in charge of calling the dtors of singletons. base::AtExitManager exit_manager; CommandLine::Init(0, NULL); - CommandLine* mutable_command_line = CommandLine::ForCurrentProcess(); - - if (mutable_command_line->HasSwitch(installer_util::switches::kChromeFrame)) { - mutable_command_line->AppendSwitch( - WideToASCII(installer_util::switches::kDoNotCreateShortcuts)); - mutable_command_line->AppendSwitch( - WideToASCII(installer_util::switches::kDoNotLaunchChrome)); - mutable_command_line->AppendSwitch( - WideToASCII(installer_util::switches::kDoNotRegisterForUpdateLaunch)); - } - const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess(); - - installer::InitInstallerLogging(parsed_command_line); const installer_util::MasterPreferences& prefs = InstallUtil::GetMasterPreferencesForCurrentProcess(); - bool value = false; - if (prefs.GetBool(installer_util::master_preferences::kVerboseLogging, - &value) && value) { - logging::SetMinLogLevel(logging::LOG_INFO); - } + installer::InitInstallerLogging(prefs); + const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess(); VLOG(1) << "Command Line: " << parsed_command_line.command_line_string(); bool system_install = false; diff --git a/chrome/installer/util/browser_distribution.cc b/chrome/installer/util/browser_distribution.cc index baf7031..2bb6716 100644 --- a/chrome/installer/util/browser_distribution.cc +++ b/chrome/installer/util/browser_distribution.cc @@ -10,6 +10,8 @@ #include "chrome/installer/util/browser_distribution.h" #include "base/command_line.h" +#include "base/file_path.h" +#include "base/path_service.h" #include "base/lock.h" #include "base/win/registry.h" #include "chrome/common/chrome_switches.h" @@ -22,8 +24,20 @@ #include "installer_util_strings.h" +namespace { +// Returns true if currently running in npchrome_frame.dll +bool IsChromeFrameModule() { + FilePath module_path; + PathService::Get(base::FILE_MODULE, &module_path); + return FilePath::CompareEqualIgnoreCase(module_path.BaseName().value(), + installer_util::kChromeFrameDll); +} + +} // end namespace + BrowserDistribution* BrowserDistribution::GetDistribution() { - return GetDistribution(InstallUtil::IsChromeFrameProcess()); + return GetDistribution(InstallUtil::IsChromeFrameProcess() || + IsChromeFrameModule()); } BrowserDistribution* BrowserDistribution::GetDistribution(bool chrome_frame) { diff --git a/chrome/installer/util/install_util.cc b/chrome/installer/util/install_util.cc index d5fe07d..74b4e9f 100644 --- a/chrome/installer/util/install_util.cc +++ b/chrome/installer/util/install_util.cc @@ -138,17 +138,8 @@ bool InstallUtil::IsPerUserInstall(const wchar_t* const exe_path) { } bool InstallUtil::IsChromeFrameProcess() { - FilePath module_path; - PathService::Get(base::FILE_MODULE, &module_path); - std::wstring module_name(module_path.BaseName().value()); - const MasterPreferences& prefs = GetMasterPreferencesForCurrentProcess(); - bool is_cf = false; - prefs.GetBool(installer_util::master_preferences::kChromeFrame, &is_cf); - - // Also assume this to be a ChromeFrame process if we are running inside - // the Chrome Frame DLL. - return is_cf || module_name == installer_util::kChromeFrameDll; + return prefs.install_chrome_frame(); } bool InstallUtil::IsChromeSxSProcess() { diff --git a/chrome/installer/util/logging_installer.cc b/chrome/installer/util/logging_installer.cc index 9dfda73..33cf342 100644 --- a/chrome/installer/util/logging_installer.cc +++ b/chrome/installer/util/logging_installer.cc @@ -11,6 +11,9 @@ #include "base/logging.h" #include "base/path_service.h" #include "base/string_util.h" +#include "base/utf_string_conversions.h" +#include "chrome/installer/util/master_preferences.h" +#include "chrome/installer/util/master_preferences_constants.h" #include "chrome/installer/util/util_constants.h" namespace installer { @@ -19,24 +22,25 @@ namespace installer { // InitInstallerLogging() and the beginning of EndInstallerLogging(). bool installer_logging_ = false; -void InitInstallerLogging(const CommandLine& command_line) { +void InitInstallerLogging(const installer_util::MasterPreferences& prefs) { if (installer_logging_) return; - if (command_line.HasSwitch( - WideToASCII(installer_util::switches::kDisableLogging))) { + bool value = false; + if (prefs.GetBool(installer_util::master_preferences::kDisableLogging, + &value) && value) { installer_logging_ = true; return; } - logging::InitLogging(GetLogFilePath(command_line).value().c_str(), + logging::InitLogging(GetLogFilePath(prefs).value().c_str(), logging::LOG_ONLY_TO_FILE, logging::LOCK_LOG_FILE, logging::DELETE_OLD_LOG_FILE); - if (command_line.HasSwitch( - WideToASCII(installer_util::switches::kVerboseLogging))) { - logging::SetMinLogLevel(logging::LOG_INFO); + if (prefs.GetBool(installer_util::master_preferences::kVerboseLogging, + &value) && value) { + logging::SetMinLogLevel(logging::LOG_VERBOSE); } else { logging::SetMinLogLevel(logging::LOG_ERROR); } @@ -50,19 +54,15 @@ void EndInstallerLogging() { installer_logging_ = false; } -FilePath GetLogFilePath(const CommandLine& command_line) { - if (command_line.HasSwitch( - WideToASCII(installer_util::switches::kLogFile))) { - return command_line.GetSwitchValuePath( - WideToASCII(installer_util::switches::kLogFile)); +FilePath GetLogFilePath(const installer_util::MasterPreferences& prefs) { + std::string path; + prefs.GetString(installer_util::master_preferences::kLogFile, &path); + if (!path.empty()) { + return FilePath(UTF8ToWide(path)); } - std::wstring log_filename; - if (command_line.HasSwitch(installer_util::switches::kChromeFrame)) { - log_filename = L"chrome_frame_installer.log"; - } else { - log_filename = L"chrome_installer.log"; - } + std::wstring log_filename = prefs.install_chrome_frame() ? + L"chrome_frame_installer.log" : L"chrome_installer.log"; FilePath log_path; if (PathService::Get(base::DIR_TEMP, &log_path)) { diff --git a/chrome/installer/util/logging_installer.h b/chrome/installer/util/logging_installer.h index 922de72..56495b6 100644 --- a/chrome/installer/util/logging_installer.h +++ b/chrome/installer/util/logging_installer.h @@ -6,19 +6,22 @@ #define CHROME_INSTALLER_UTIL_LOGGING_INSTALLER_H_ #pragma once -class CommandLine; +namespace installer_util { + class MasterPreferences; +} + class FilePath; namespace installer { // Call to initialize logging for Chrome installer. -void InitInstallerLogging(const CommandLine& command_line); +void InitInstallerLogging(const installer_util::MasterPreferences& prefs); // Call when done using logging for Chrome installer. void EndInstallerLogging(); // Returns the full path of the log file. -FilePath GetLogFilePath(const CommandLine& command_line); +FilePath GetLogFilePath(const installer_util::MasterPreferences& prefs); } // namespace installer diff --git a/chrome/installer/util/master_preferences.cc b/chrome/installer/util/master_preferences.cc index 1602f6d..51b9192 100644 --- a/chrome/installer/util/master_preferences.cc +++ b/chrome/installer/util/master_preferences.cc @@ -75,7 +75,8 @@ DictionaryValue* ParseDistributionPreferences( namespace installer_util { MasterPreferences::MasterPreferences(const CommandLine& cmd_line) - : distribution_(NULL), preferences_read_from_file_(false) { + : distribution_(NULL), preferences_read_from_file_(false), ceee_(false), + chrome_(true), chrome_frame_(false), multi_install_(false) { #if defined(OS_WIN) if (cmd_line.HasSwitch(installer_util::switches::kInstallerData)) { FilePath prefs_path(cmd_line.GetSwitchValuePath( @@ -94,14 +95,22 @@ MasterPreferences::MasterPreferences(const CommandLine& cmd_line) const wchar_t* cmd_line_switch; const char* distribution_switch; } translate_switches[] = { + { installer_util::switches::kCeee, + installer_util::master_preferences::kCeee }, + { installer_util::switches::kChrome, + installer_util::master_preferences::kChrome }, { installer_util::switches::kChromeFrame, installer_util::master_preferences::kChromeFrame }, { installer_util::switches::kCreateAllShortcuts, installer_util::master_preferences::kCreateAllShortcuts }, + { installer_util::switches::kDisableLogging, + installer_util::master_preferences::kDisableLogging }, { installer_util::switches::kDoNotCreateShortcuts, installer_util::master_preferences::kDoNotCreateShortcuts }, { installer_util::switches::kMsi, installer_util::master_preferences::kMsi }, + { installer_util::switches::kMultiInstall, + installer_util::master_preferences::kMultiInstall }, { installer_util::switches::kDoNotRegisterForUpdateLaunch, installer_util::master_preferences::kDoNotRegisterForUpdateLaunch }, { installer_util::switches::kDoNotLaunchChrome, @@ -125,13 +134,25 @@ MasterPreferences::MasterPreferences(const CommandLine& cmd_line) } } + // See if the log file path was specified on the command line. + std::wstring str_value(cmd_line.GetSwitchValueNative( + WideToASCII(installer_util::switches::kLogFile))); + if (!str_value.empty()) { + name.resize(arraysize(kDistroDict) - 1); + name.append(".").append(installer_util::master_preferences::kLogFile); + master_dictionary_->SetString(name, str_value); + } + // Cache a pointer to the distribution dictionary. Ignore errors if any. master_dictionary_->GetDictionary(kDistroDict, &distribution_); + + InitializeProductFlags(); #endif } MasterPreferences::MasterPreferences(const FilePath& prefs_path) - : distribution_(NULL), preferences_read_from_file_(false) { + : distribution_(NULL), preferences_read_from_file_(false), ceee_(false), + chrome_(true), chrome_frame_(false), multi_install_(false) { master_dictionary_.reset(ParseDistributionPreferences(prefs_path)); if (!master_dictionary_.get()) { @@ -141,11 +162,48 @@ MasterPreferences::MasterPreferences(const FilePath& prefs_path) // Cache a pointer to the distribution dictionary. master_dictionary_->GetDictionary(kDistroDict, &distribution_); } + + InitializeProductFlags(); } MasterPreferences::~MasterPreferences() { } +void MasterPreferences::InitializeProductFlags() { + // Make sure we start out with the correct defaults. + multi_install_ = false; + chrome_frame_ = false; + ceee_ = false; + chrome_ = true; + + GetBool(installer_util::master_preferences::kMultiInstall, &multi_install_); + GetBool(installer_util::master_preferences::kChromeFrame, &chrome_frame_); + GetBool(installer_util::master_preferences::kCeee, &ceee_); + + // When multi-install is specified, the checks are pretty simple (in theory): + // In order to be installed/uninstalled, each product must have its switch + // present on the command line. + // Before multi-install was introduced however, we only supported installing + // two products, Chrome and Chrome Frame. For the time being we need to + // continue to support this mode where multi-install is not set. + // So, when multi-install is not set, we continue to support mutually + // exclusive installation of Chrome and Chrome Frame in addition to supporting + // installation of CEEE with Chrome Frame. + + // Regardless of multi install being present, CEEE always needs CF to + // be installed. + if (ceee_) + chrome_frame_ = true; + + if (multi_install_) { + if (!GetBool(installer_util::master_preferences::kChrome, &chrome_)) + chrome_ = false; + } else { + // If chrome-frame is on the command line however, we only install CF. + chrome_ = !chrome_frame_; + } +} + bool MasterPreferences::GetBool(const std::string& name, bool* value) const { bool ret = false; if (distribution_) diff --git a/chrome/installer/util/master_preferences.h b/chrome/installer/util/master_preferences.h index 15e1cb5..53c708e 100644 --- a/chrome/installer/util/master_preferences.h +++ b/chrome/installer/util/master_preferences.h @@ -149,10 +149,33 @@ class MasterPreferences { return preferences_read_from_file_; } + bool install_ceee() const { + return ceee_; + } + + bool install_chrome() const { + return chrome_; + } + + bool install_chrome_frame() const { + return chrome_frame_; + } + + bool is_multi_install() const { + return multi_install_; + } + + protected: + void InitializeProductFlags(); + protected: scoped_ptr<DictionaryValue> master_dictionary_; DictionaryValue* distribution_; bool preferences_read_from_file_; + bool ceee_; + bool chrome_; + bool chrome_frame_; + bool multi_install_; private: DISALLOW_COPY_AND_ASSIGN(MasterPreferences); diff --git a/chrome/installer/util/master_preferences_constants.cc b/chrome/installer/util/master_preferences_constants.cc index 3ac6b92..d3e013c 100644 --- a/chrome/installer/util/master_preferences_constants.cc +++ b/chrome/installer/util/master_preferences_constants.cc @@ -8,9 +8,12 @@ namespace installer_util { namespace master_preferences { const char kAltFirstRunBubble[] = "oem_bubble"; const char kAltShortcutText[] = "alternate_shortcut_text"; + const char kCeee[] = "ceee"; + const char kChrome[] = "chrome"; const char kChromeFrame[] = "chrome_frame"; const char kChromeShortcutIconIndex[] = "chrome_shortcut_icon_index"; const char kCreateAllShortcuts[] = "create_all_shortcuts"; + const char kDisableLogging[] = "disable_logging"; const char kDistroImportBookmarksPref[] = "import_bookmarks"; const char kDistroImportBookmarksFromFilePref[] = "import_bookmarks_from_file"; @@ -25,9 +28,11 @@ namespace master_preferences { const char kDoNotLaunchChrome[] = "do_not_launch_chrome"; const char kDoNotRegisterForUpdateLaunch[] = "do_not_register_for_update_launch"; + const char kLogFile[] = "log_file"; const char kMakeChromeDefault[] = "make_chrome_default"; const char kMakeChromeDefaultForUser[] = "make_chrome_default_for_user"; const char kMsi[] = "msi"; + const char kMultiInstall[] = "multi_install"; const char kRequireEula[] = "require_eula"; const char kSearchEngineExperimentPref[] = "search_engine_experiment"; const char kSearchEngineExperimentRandomizePref[] = diff --git a/chrome/installer/util/master_preferences_constants.h b/chrome/installer/util/master_preferences_constants.h index f6adedd..fbf6da4 100644 --- a/chrome/installer/util/master_preferences_constants.h +++ b/chrome/installer/util/master_preferences_constants.h @@ -20,12 +20,19 @@ namespace master_preferences { extern const char kAltShortcutText[]; // Boolean. Use alternate smaller first run info bubble. extern const char kAltFirstRunBubble[]; +// Boolean. CEEE features of Chrome Frame should be enabled as part of +// the install. Requires kChromeFrame to be specified as well. +extern const char kCeee[]; +// Boolean. This is to be a Chrome install. (When using MultiInstall) +extern const char kChrome[]; // Boolean. This is to be a Chrome Frame install. extern const char kChromeFrame[]; // Integer. Icon index from chrome.exe to use for shortcuts. extern const char kChromeShortcutIconIndex[]; // Boolean. Create Desktop and QuickLaunch shortcuts. Cmd line override present. extern const char kCreateAllShortcuts[]; +// Boolean pref that disables all logging. +extern const char kDisableLogging[]; // Boolean pref that triggers silent import of the default browser bookmarks. extern const char kDistroImportBookmarksPref[]; // String pref that triggers silent import of bookmarks from the html file at @@ -52,12 +59,16 @@ extern const char kDoNotLaunchChrome[]; // Boolean. Do not register with Google Update to have Chrome launched after // install. Cmd line override present. extern const char kDoNotRegisterForUpdateLaunch[]; +// String. Specifies the file path to write logging info to. +extern const char kLogFile[]; // Boolean. Register Chrome as default browser. Cmd line override present. extern const char kMakeChromeDefault[]; // Boolean. Register Chrome as default browser for the current user. extern const char kMakeChromeDefaultForUser[]; // Boolean. Expect to be run by an MSI installer. Cmd line override present. extern const char kMsi[]; +// Boolean. Support installing multiple products at once. +extern const char kMultiInstall[]; // Boolean. Show EULA dialog before install. extern const char kRequireEula[]; // Boolean. Use experimental search engine selection dialog. diff --git a/chrome/installer/util/master_preferences_unittest.cc b/chrome/installer/util/master_preferences_unittest.cc index d1650fc..fe53c29 100644 --- a/chrome/installer/util/master_preferences_unittest.cc +++ b/chrome/installer/util/master_preferences_unittest.cc @@ -7,10 +7,12 @@ #include "base/file_util.h" #include "base/path_service.h" #include "base/scoped_ptr.h" +#include "base/stringprintf.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/json_value_serializer.h" #include "chrome/installer/util/master_preferences.h" #include "chrome/installer/util/master_preferences_constants.h" +#include "chrome/installer/util/util_constants.h" #include "googleurl/src/gurl.h" #include "testing/gtest/include/gtest/gtest.h" @@ -299,3 +301,96 @@ TEST_F(MasterPreferencesTest, GetInstallPreferencesTest) { EXPECT_FALSE(prefs2.GetBool( installer_util::master_preferences::kVerboseLogging, &value)); } + +TEST_F(MasterPreferencesTest, TestDefaultInstallConfig) { + const std::wstring kChromeInstall(L"setup.exe"); + const std::wstring kCfInstall(StringPrintf(L"setup.exe --%ls", + installer_util::switches::kChromeFrame)); + const std::wstring kCeeeInstall(StringPrintf(L"setup.exe --%ls", + installer_util::switches::kCeee)); + + CommandLine chrome_install(CommandLine::FromString(kChromeInstall)); + CommandLine cf_install(CommandLine::FromString(kCfInstall)); + CommandLine ceee_install(CommandLine::FromString(kCeeeInstall)); + + installer_util::MasterPreferences pref_chrome(chrome_install); + installer_util::MasterPreferences pref_cf(cf_install); + installer_util::MasterPreferences pref_ceee(ceee_install); + + EXPECT_FALSE(pref_chrome.is_multi_install()); + EXPECT_TRUE(pref_chrome.install_chrome()); + EXPECT_FALSE(pref_chrome.install_ceee()); + EXPECT_FALSE(pref_chrome.install_chrome_frame()); + + EXPECT_FALSE(pref_cf.is_multi_install()); + EXPECT_FALSE(pref_cf.install_chrome()); + EXPECT_FALSE(pref_cf.install_ceee()); + EXPECT_TRUE(pref_cf.install_chrome_frame()); + + EXPECT_FALSE(pref_ceee.is_multi_install()); + EXPECT_FALSE(pref_ceee.install_chrome()); + EXPECT_TRUE(pref_ceee.install_ceee()); + EXPECT_TRUE(pref_ceee.install_chrome_frame()); +} + +TEST_F(MasterPreferencesTest, TestMultiInstallConfig) { + const std::wstring kChromeInstall(StringPrintf(L"setup.exe --%ls --%ls", + installer_util::switches::kMultiInstall, + installer_util::switches::kChrome)); + const std::wstring kCfInstall(StringPrintf(L"setup.exe --%ls --%ls", + installer_util::switches::kMultiInstall, + installer_util::switches::kChromeFrame)); + const std::wstring kCeeeInstall(StringPrintf(L"setup.exe --%ls --%ls", + installer_util::switches::kMultiInstall, + installer_util::switches::kCeee)); + const std::wstring kChromeCfInstall( + StringPrintf(L"setup.exe --%ls --%ls --%ls", + installer_util::switches::kMultiInstall, + installer_util::switches::kChrome, + installer_util::switches::kChromeFrame)); + const std::wstring kChromeCeeeCfInstall( + StringPrintf(L"setup.exe --%ls --%ls --%ls --%ls", + installer_util::switches::kMultiInstall, + installer_util::switches::kChrome, + installer_util::switches::kChromeFrame, + installer_util::switches::kCeee)); + + CommandLine chrome_install(CommandLine::FromString(kChromeInstall)); + CommandLine cf_install(CommandLine::FromString(kCfInstall)); + CommandLine ceee_install(CommandLine::FromString(kCeeeInstall)); + CommandLine chrome_cf_install(CommandLine::FromString(kChromeCfInstall)); + CommandLine chrome_cf_ceee_install( + CommandLine::FromString(kChromeCeeeCfInstall)); + + installer_util::MasterPreferences pref_chrome(chrome_install); + installer_util::MasterPreferences pref_cf(cf_install); + installer_util::MasterPreferences pref_ceee(ceee_install); + installer_util::MasterPreferences pref_chrome_cf(chrome_cf_install); + installer_util::MasterPreferences pref_all(chrome_cf_ceee_install); + + EXPECT_TRUE(pref_chrome.is_multi_install()); + EXPECT_TRUE(pref_chrome.install_chrome()); + EXPECT_FALSE(pref_chrome.install_ceee()); + EXPECT_FALSE(pref_chrome.install_chrome_frame()); + + EXPECT_TRUE(pref_cf.is_multi_install()); + EXPECT_FALSE(pref_cf.install_chrome()); + EXPECT_FALSE(pref_cf.install_ceee()); + EXPECT_TRUE(pref_cf.install_chrome_frame()); + + EXPECT_TRUE(pref_ceee.is_multi_install()); + EXPECT_FALSE(pref_ceee.install_chrome()); + EXPECT_TRUE(pref_ceee.install_ceee()); + EXPECT_TRUE(pref_ceee.install_chrome_frame()); + + EXPECT_TRUE(pref_chrome_cf.is_multi_install()); + EXPECT_TRUE(pref_chrome_cf.install_chrome()); + EXPECT_FALSE(pref_chrome_cf.install_ceee()); + EXPECT_TRUE(pref_chrome_cf.install_chrome_frame()); + + EXPECT_TRUE(pref_all.is_multi_install()); + EXPECT_TRUE(pref_all.install_chrome()); + EXPECT_TRUE(pref_all.install_ceee()); + EXPECT_TRUE(pref_all.install_chrome_frame()); +} + diff --git a/chrome/installer/util/util_constants.cc b/chrome/installer/util/util_constants.cc index 412dd50..2cb5ceb 100644 --- a/chrome/installer/util/util_constants.cc +++ b/chrome/installer/util/util_constants.cc @@ -8,6 +8,13 @@ namespace installer_util { namespace switches { +// Install CEEE. +const wchar_t kCeee[] = L"ceee"; + +// Install Chrome. +// Currently this is only required when used in combination with kMultiInstall. +const wchar_t kChrome[] = L"chrome"; + // Run the installer in Chrome Frame mode. const wchar_t kChromeFrame[] = L"chrome-frame"; @@ -65,6 +72,10 @@ const wchar_t kMakeChromeDefault[] = L"make-chrome-default"; // Tells installer to expect to be run as a subsidiary to an MSI. const wchar_t kMsi[] = L"msi"; +// Tells installer to install multiple products specified on the command line. +// (e.g. Chrome Frame, CEEE, Chrome) +const wchar_t kMultiInstall[] = L"multi-install"; + // Useful only when used with --update-setup-exe, otherwise ignored. It // specifies the full path where updated setup.exe will be stored. const char kNewSetupExe[] = "new-setup-exe"; diff --git a/chrome/installer/util/util_constants.h b/chrome/installer/util/util_constants.h index ed22874..eb6342e 100644 --- a/chrome/installer/util/util_constants.h +++ b/chrome/installer/util/util_constants.h @@ -45,12 +45,14 @@ enum InstallStatus { UNINSTALL_REQUIRES_REBOOT, // Uninstallation required a reboot. IN_USE_UPDATED, // Chrome successfully updated but old version running SAME_VERSION_REPAIR_FAILED, // Chrome repair failed as Chrome was running - REENTRY_SYS_UPDATE, // Setup has been re-lauched as the interactive user + REENTRY_SYS_UPDATE, // Setup has been re-launched as the interactive user SXS_OPTION_NOT_SUPPORTED // The chrome-sxs option provided does not work // with other command line options. }; namespace switches { +extern const wchar_t kCeee[]; +extern const wchar_t kChrome[]; extern const wchar_t kChromeFrame[]; extern const wchar_t kChromeSxS[]; extern const wchar_t kCreateAllShortcuts[]; @@ -67,6 +69,7 @@ extern const char kInstallerData[]; extern const wchar_t kLogFile[]; extern const wchar_t kMakeChromeDefault[]; extern const wchar_t kMsi[]; +extern const wchar_t kMultiInstall[]; extern const char kNewSetupExe[]; extern const char kRegisterChromeBrowser[]; extern const char kRegisterChromeBrowserSuffix[]; |