Chromium Code Reviews| Index: chrome/installer/setup/install.cc |
| =================================================================== |
| --- chrome/installer/setup/install.cc (revision 71802) |
| +++ chrome/installer/setup/install.cc (working copy) |
| @@ -16,13 +16,9 @@ |
| #include "base/scoped_ptr.h" |
| #include "base/string_util.h" |
| #include "base/utf_string_conversions.h" |
| -#include "base/win/registry.h" |
| #include "chrome/installer/setup/setup_constants.h" |
| #include "chrome/installer/setup/install_worker.h" |
| #include "chrome/installer/util/browser_distribution.h" |
| -#include "chrome/installer/util/channel_info.h" |
| -#include "chrome/installer/util/chrome_frame_distribution.h" |
| -#include "chrome/installer/util/conditional_work_item_list.h" |
| #include "chrome/installer/util/create_reg_key_work_item.h" |
| #include "chrome/installer/util/delete_after_reboot_helper.h" |
| #include "chrome/installer/util/google_update_constants.h" |
| @@ -32,8 +28,6 @@ |
| #include "chrome/installer/util/installer_state.h" |
| #include "chrome/installer/util/master_preferences.h" |
| #include "chrome/installer/util/master_preferences_constants.h" |
| -#include "chrome/installer/util/package.h" |
| -#include "chrome/installer/util/package_properties.h" |
| #include "chrome/installer/util/product.h" |
| #include "chrome/installer/util/set_reg_value_work_item.h" |
| #include "chrome/installer/util/shell_util.h" |
| @@ -44,15 +38,9 @@ |
| #include "installer_util_strings.h" // NOLINT |
| #include "registered_dlls.h" // NOLINT |
| -using base::win::RegKey; |
| -using installer::ChannelInfo; |
| using installer::InstallerState; |
| using installer::InstallationState; |
| -using installer::MasterPreferences; |
| -using installer::Products; |
| using installer::Product; |
| -using installer::Package; |
| -using installer::PackageProperties; |
| namespace { |
| @@ -69,14 +57,14 @@ |
| LOG(ERROR) << "Could not add Chrome to media player inclusion list."; |
| } |
| -void AddInstallerCopyTasks(const FilePath& setup_path, |
| +void AddInstallerCopyTasks(const InstallerState& installer_state, |
| + const FilePath& setup_path, |
| const FilePath& archive_path, |
| const FilePath& temp_path, |
| const Version& new_version, |
| - WorkItemList* install_list, |
| - const Package& package) { |
| + WorkItemList* install_list) { |
| DCHECK(install_list); |
| - FilePath installer_dir(package.GetInstallerDirectory(new_version)); |
| + FilePath installer_dir(installer_state.GetInstallerDirectory(new_version)); |
| install_list->AddCreateDirWorkItem(installer_dir); |
| FilePath exe_dst(installer_dir.Append(setup_path.BaseName())); |
| @@ -84,7 +72,7 @@ |
| install_list->AddCopyTreeWorkItem(setup_path.value(), exe_dst.value(), |
| temp_path.value(), WorkItem::ALWAYS); |
| - if (package.system_level()) { |
| + if (installer_state.system_install()) { |
| install_list->AddCopyTreeWorkItem(archive_path.value(), archive_dst.value(), |
| temp_path.value(), WorkItem::ALWAYS); |
| } else { |
| @@ -93,139 +81,12 @@ |
| } |
| } |
| -// Adds work items that make registry adjustments for Google Update. When a |
| -// product is installed (including overinstall), Google Update will write the |
| -// channel ("ap") value into either Chrome or Chrome Frame's ClientState key. |
| -// In the multi-install case, this value is used as the basis upon which the |
| -// package's channel value is built (by adding the ordered list of installed |
| -// products and their options). |
| -void AddGoogleUpdateWorkItems(const InstallationState& original_state, |
| - const InstallerState& installer_state, |
| - const Package& package, |
| - WorkItemList* install_list) { |
| - // Is a multi-install product being installed or over-installed? |
| - if (installer_state.operation() != InstallerState::MULTI_INSTALL) |
| - return; |
| - |
| - const HKEY reg_root = package.system_level() ? HKEY_LOCAL_MACHINE : |
| - HKEY_CURRENT_USER; |
| - const std::wstring key_path = installer_state.state_key(); |
| - ChannelInfo channel_info; |
| - |
| - // Update the "ap" value for the product being installed/updated. |
| - // It is completely acceptable for there to be no "ap" value or even no |
| - // ClientState key. Note that we check the registry rather than |
| - // original_state since on a fresh install the "ap" value will be present |
| - // sans "pv" value. |
| - channel_info.Initialize(RegKey(reg_root, key_path.c_str(), KEY_QUERY_VALUE)); |
| - |
| - // This is a multi-install product. |
| - bool modified = channel_info.SetMultiInstall(true); |
| - |
| - // Add the appropriate modifiers for all products and their options. |
| - Products::const_iterator scan = package.products().begin(); |
| - const Products::const_iterator end = package.products().end(); |
| - for (; scan != end; ++scan) { |
| - modified |= scan->get()->distribution()->SetChannelFlags(true, |
| - &channel_info); |
| - } |
| - |
| - // Write the results if needed. |
| - if (modified) { |
| - install_list->AddSetRegValueWorkItem(reg_root, key_path, |
| - google_update::kRegApField, |
| - channel_info.value(), true); |
| - } |
| - |
| - // Synchronize the other products and the package with this one. |
| - std::wstring other_key; |
| - std::vector<std::wstring> keys; |
| - |
| - keys.reserve(package.products().size()); |
| - other_key = package.properties()->GetStateKey(); |
| - if (other_key != key_path) |
| - keys.push_back(other_key); |
| - scan = package.products().begin(); |
| - for (; scan != end; ++scan) { |
| - other_key = scan->get()->distribution()->GetStateKey(); |
| - if (other_key != key_path) |
| - keys.push_back(other_key); |
| - } |
| - |
| - RegKey key; |
| - ChannelInfo other_info; |
| - std::vector<std::wstring>::const_iterator kscan = keys.begin(); |
| - std::vector<std::wstring>::const_iterator kend = keys.end(); |
| - for (; kscan != kend; ++kscan) { |
| - // Handle the case where the ClientState key doesn't exist by creating it. |
| - // This takes care of the multi-installer's package key, which is not |
| - // created by Google Update for us. |
| - if (key.Open(reg_root, kscan->c_str(), KEY_QUERY_VALUE) != ERROR_SUCCESS || |
| - !other_info.Initialize(key)) { |
| - other_info.set_value(std::wstring()); |
| - } |
| - if (!other_info.Equals(channel_info)) { |
| - if (!key.Valid()) |
| - install_list->AddCreateRegKeyWorkItem(reg_root, *kscan); |
| - install_list->AddSetRegValueWorkItem(reg_root, *kscan, |
| - google_update::kRegApField, |
| - channel_info.value(), true); |
| - } |
| - } |
| - // TODO(grt): check for other keys/values we should put in the package's |
| - // ClientState and/or Clients key. |
| -} |
| - |
| -// This is called when an MSI installation is run. It may be that a user is |
| -// attempting to install the MSI on top of a non-MSI managed installation. |
| -// If so, try and remove any existing uninstallation shortcuts, as we want the |
| -// uninstall to be managed entirely by the MSI machinery (accessible via the |
| -// Add/Remove programs dialog). |
| -void AddDeleteUninstallShortcutsForMSIWorkItems(const Product& product, |
| - WorkItemList* work_item_list) { |
| - DCHECK(product.IsMsi()) << "This must only be called for MSI installations!"; |
| - |
| - // First attempt to delete the old installation's ARP dialog entry. |
| - HKEY reg_root = product.system_level() ? HKEY_LOCAL_MACHINE : |
| - HKEY_CURRENT_USER; |
| - base::win::RegKey root_key(reg_root, L"", KEY_ALL_ACCESS); |
| - std::wstring uninstall_reg(product.distribution()->GetUninstallRegPath()); |
| - |
| - WorkItem* delete_reg_key = work_item_list->AddDeleteRegKeyWorkItem( |
| - reg_root, uninstall_reg); |
| - delete_reg_key->set_ignore_failure(true); |
| - |
| - // Then attempt to delete the old installation's start menu shortcut. |
| - FilePath uninstall_link; |
| - if (product.system_level()) { |
| - PathService::Get(base::DIR_COMMON_START_MENU, &uninstall_link); |
| - } else { |
| - PathService::Get(base::DIR_START_MENU, &uninstall_link); |
| - } |
| - |
| - if (uninstall_link.empty()) { |
| - LOG(ERROR) << "Failed to get location for shortcut."; |
| - } else { |
| - uninstall_link = uninstall_link.Append( |
| - product.distribution()->GetAppShortCutName()); |
| - uninstall_link = uninstall_link.Append( |
| - product.distribution()->GetUninstallLinkName() + L".lnk"); |
| - VLOG(1) << "Deleting old uninstall shortcut (if present): " |
| - << uninstall_link.value(); |
| - WorkItem* delete_link = work_item_list->AddDeleteTreeWorkItem( |
| - uninstall_link); |
| - delete_link->set_ignore_failure(true); |
| - delete_link->set_log_message( |
| - "Failed to delete old uninstall shortcut."); |
| - } |
| -} |
| - |
| // Copy master preferences file provided to installer, in the same folder |
| // as chrome.exe so Chrome first run can find it. This function will be called |
| // only on the first install of Chrome. |
| -void CopyPreferenceFileForFirstRun(const Package& package, |
| +void CopyPreferenceFileForFirstRun(const InstallerState& installer_state, |
| const FilePath& prefs_source_path) { |
| - FilePath prefs_dest_path(package.path().AppendASCII( |
| + FilePath prefs_dest_path(installer_state.target_path().AppendASCII( |
| installer::kDefaultMasterPrefs)); |
| if (!file_util::CopyFile(prefs_source_path, prefs_dest_path)) { |
| VLOG(1) << "Failed to copy master preferences from:" |
| @@ -247,7 +108,8 @@ |
| // |
| // If the shortcuts do not exist, the function does not recreate them during |
| // update. |
| -bool CreateOrUpdateChromeShortcuts(const FilePath& setup_path, |
| +bool CreateOrUpdateChromeShortcuts(const InstallerState& installer_state, |
| + const FilePath& setup_path, |
| const Version& new_version, |
| installer::InstallStatus install_status, |
| const Product& product, |
| @@ -257,7 +119,7 @@ |
| DCHECK(product.is_chrome()); |
| FilePath shortcut_path; |
| - int dir_enum = product.system_level() ? |
| + int dir_enum = installer_state.system_install() ? |
| base::DIR_COMMON_START_MENU : base::DIR_START_MENU; |
| if (!PathService::Get(dir_enum, &shortcut_path)) { |
| LOG(ERROR) << "Failed to get location for shortcut."; |
| @@ -283,7 +145,7 @@ |
| chrome_link = chrome_link.Append(product_name + L".lnk"); |
| // Chrome link target |
| FilePath chrome_exe( |
| - product.package().path().Append(installer::kChromeExe)); |
| + installer_state.target_path().Append(installer::kChromeExe)); |
| if ((install_status == installer::FIRST_INSTALL_SUCCESS) || |
| (install_status == installer::INSTALL_REPAIRED)) { |
| @@ -309,7 +171,7 @@ |
| // installations are, for the time being, managed only through the |
| // Add/Remove Programs dialog. |
| // TODO(robertshield): We could add a shortcut to msiexec /X {GUID} here. |
| - if (ret && !product.IsMsi()) { |
| + if (ret && !installer_state.msi()) { |
| FilePath uninstall_link(shortcut_path); // Uninstall Chrome link |
| uninstall_link = uninstall_link.Append( |
| browser_dist->GetUninstallLinkName() + L".lnk"); |
| @@ -319,12 +181,11 @@ |
| if (!file_util::PathExists(shortcut_path)) |
| file_util::CreateDirectory(shortcut_path); |
| - FilePath setup_exe( |
| - product.package().GetInstallerDirectory(new_version) |
| - .Append(setup_path.BaseName())); |
| + FilePath setup_exe(installer_state.GetInstallerDirectory(new_version) |
| + .Append(setup_path.BaseName())); |
| CommandLine arguments(CommandLine::NO_PROGRAM); |
| - AppendUninstallCommandLineFlags(&arguments, product); |
| + AppendUninstallCommandLineFlags(installer_state, product, &arguments); |
| VLOG(1) << "Creating/updating uninstall link at " |
| << uninstall_link.value(); |
| ret = file_util::CreateShortcutLink(setup_exe.value().c_str(), |
| @@ -342,7 +203,7 @@ |
| // is specified we want to create them, otherwise we update them only if |
| // they exist. |
| if (ret) { |
| - if (product.system_level()) { |
| + if (installer_state.system_install()) { |
| ret = ShellUtil::CreateChromeDesktopShortcut(product.distribution(), |
| chrome_exe.value(), product_desc, ShellUtil::SYSTEM_LEVEL, |
| alt_shortcut, create_all_shortcut); |
| @@ -367,8 +228,8 @@ |
| return ret; |
| } |
| - |
| -void RegisterChromeOnMachine(const Product& product, |
| +void RegisterChromeOnMachine(const InstallerState& installer_state, |
| + const Product& product, |
| bool make_chrome_default) { |
| DCHECK(product.is_chrome()); |
| @@ -380,11 +241,11 @@ |
| // Is --make-chrome-default option is given we make Chrome default browser |
| // otherwise we only register it on the machine as a valid browser. |
| FilePath chrome_exe( |
| - product.package().path().Append(installer::kChromeExe)); |
| + installer_state.target_path().Append(installer::kChromeExe)); |
| VLOG(1) << "Registering Chrome as browser: " << chrome_exe.value(); |
| if (make_chrome_default) { |
| int level = ShellUtil::CURRENT_USER; |
| - if (product.system_level()) |
| + if (installer_state.system_install()) |
| level = level | ShellUtil::SYSTEM_LEVEL; |
| ShellUtil::MakeChromeDefault(product.distribution(), level, |
| chrome_exe.value(), true); |
| @@ -417,33 +278,29 @@ |
| installer::InstallStatus InstallNewVersion( |
| const InstallationState& original_state, |
| const InstallerState& installer_state, |
| - bool multi_install, |
| const FilePath& setup_path, |
| const FilePath& archive_path, |
| const FilePath& src_path, |
| const FilePath& temp_dir, |
| const Version& new_version, |
| - scoped_ptr<Version>* current_version, |
| - const Package& package) { |
| + scoped_ptr<Version>* current_version) { |
| DCHECK(current_version); |
| - current_version->reset(package.GetCurrentVersion()); |
| + current_version->reset(installer_state.GetCurrentVersion(original_state)); |
| scoped_ptr<WorkItemList> install_list(WorkItem::CreateWorkItemList()); |
| AddInstallWorkItems(original_state, |
| installer_state, |
| - multi_install, |
| setup_path, |
| archive_path, |
| src_path, |
| temp_dir, |
| new_version, |
| current_version, |
| - package, |
| install_list.get()); |
| FilePath new_chrome_exe( |
| - package.path().Append(installer::kChromeNewExe)); |
| + installer_state.target_path().Append(installer::kChromeNewExe)); |
| if (!install_list->Do()) { |
| installer::InstallStatus result = |
| @@ -488,61 +345,60 @@ |
| namespace installer { |
| -installer::InstallStatus InstallOrUpdateProduct( |
| +InstallStatus InstallOrUpdateProduct( |
| const InstallationState& original_state, |
| const InstallerState& installer_state, |
| const FilePath& setup_path, const FilePath& archive_path, |
| const FilePath& install_temp_path, const FilePath& prefs_path, |
| - const installer::MasterPreferences& prefs, const Version& new_version, |
| - const Package& install) { |
| + const MasterPreferences& prefs, const Version& new_version) { |
|
robertshield
2011/01/20 22:06:06
could we put each of these parameters on a separat
grt (UTC plus 2)
2011/01/21 05:27:51
Done.
|
| FilePath src_path(install_temp_path); |
| src_path = src_path.Append(kInstallSourceDir).Append(kInstallSourceChromeDir); |
| // TODO(robertshield): Removing the pending on-reboot moves should be done |
| // elsewhere. |
| - const Products& products = install.products(); |
| + const Products& products = installer_state.products(); |
| DCHECK(products.size()); |
| - if (FindProduct(products, BrowserDistribution::CHROME_FRAME)) { |
| + if (installer_state.FindProduct(BrowserDistribution::CHROME_FRAME)) { |
| // Make sure that we don't end up deleting installed files on next reboot. |
| - if (!RemoveFromMovesPendingReboot(install.path().value().c_str())) { |
| + if (!RemoveFromMovesPendingReboot( |
| + installer_state.target_path().value().c_str())) { |
| LOG(ERROR) << "Error accessing pending moves value."; |
| } |
| } |
| scoped_ptr<Version> existing_version; |
| - installer::InstallStatus result = InstallNewVersion(original_state, |
| - installer_state, prefs.is_multi_install(), setup_path, archive_path, |
| - src_path, install_temp_path, new_version, &existing_version, install); |
| + InstallStatus result = InstallNewVersion(original_state, installer_state, |
| + setup_path, archive_path, src_path, install_temp_path, new_version, |
| + &existing_version); |
| // TODO(robertshield): Everything below this line should instead be captured |
| // by WorkItems. |
| if (!InstallUtil::GetInstallReturnCode(result)) { |
| - if (result == installer::FIRST_INSTALL_SUCCESS && !prefs_path.empty()) |
| - CopyPreferenceFileForFirstRun(install, prefs_path); |
| + if (result == FIRST_INSTALL_SUCCESS && !prefs_path.empty()) |
| + CopyPreferenceFileForFirstRun(installer_state, prefs_path); |
| bool do_not_create_shortcuts = false; |
| - prefs.GetBool(installer::master_preferences::kDoNotCreateShortcuts, |
| + prefs.GetBool(master_preferences::kDoNotCreateShortcuts, |
| &do_not_create_shortcuts); |
| // Currently this only creates shortcuts for Chrome, but for other products |
| // we might want to create shortcuts. |
| const Product* chrome_install = |
| - FindProduct(install.products(), BrowserDistribution::CHROME_BROWSER); |
| + installer_state.FindProduct(BrowserDistribution::CHROME_BROWSER); |
| if (chrome_install && !do_not_create_shortcuts) { |
| bool create_all_shortcut = false; |
| - prefs.GetBool(installer::master_preferences::kCreateAllShortcuts, |
| + prefs.GetBool(master_preferences::kCreateAllShortcuts, |
| &create_all_shortcut); |
| bool alt_shortcut = false; |
| - prefs.GetBool(installer::master_preferences::kAltShortcutText, |
| - &alt_shortcut); |
| - if (!CreateOrUpdateChromeShortcuts(setup_path, new_version, result, |
| - *chrome_install, create_all_shortcut, |
| - alt_shortcut)) { |
| + prefs.GetBool(master_preferences::kAltShortcutText, &alt_shortcut); |
| + if (!CreateOrUpdateChromeShortcuts(installer_state, setup_path, |
| + new_version, result, *chrome_install, |
| + create_all_shortcut, alt_shortcut)) { |
| PLOG(WARNING) << "Failed to create/update start menu shortcut."; |
| } |
| bool make_chrome_default = false; |
| - prefs.GetBool(installer::master_preferences::kMakeChromeDefault, |
| + prefs.GetBool(master_preferences::kMakeChromeDefault, |
| &make_chrome_default); |
| // If this is not the user's first Chrome install, but they have chosen |
| @@ -550,18 +406,17 @@ |
| // force it here because the master_preferences file will not get copied |
| // into the build. |
| bool force_chrome_default_for_user = false; |
| - if (result == installer::NEW_VERSION_UPDATED || |
| - result == installer::INSTALL_REPAIRED) { |
| - prefs.GetBool( |
| - installer::master_preferences::kMakeChromeDefaultForUser, |
| - &force_chrome_default_for_user); |
| + if (result == NEW_VERSION_UPDATED || |
| + result == INSTALL_REPAIRED) { |
| + prefs.GetBool(master_preferences::kMakeChromeDefaultForUser, |
| + &force_chrome_default_for_user); |
| } |
| - RegisterChromeOnMachine(*chrome_install, |
| + RegisterChromeOnMachine(installer_state, *chrome_install, |
| make_chrome_default || force_chrome_default_for_user); |
| } |
| - install.RemoveOldVersionDirectories(existing_version.get() ? |
| + installer_state.RemoveOldVersionDirectories(existing_version.get() ? |
| *existing_version.get() : new_version); |
| } |