summaryrefslogtreecommitdiffstats
path: root/chrome/installer/setup/uninstall.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/installer/setup/uninstall.cc')
-rw-r--r--chrome/installer/setup/uninstall.cc138
1 files changed, 113 insertions, 25 deletions
diff --git a/chrome/installer/setup/uninstall.cc b/chrome/installer/setup/uninstall.cc
index a84b49f..ead0795 100644
--- a/chrome/installer/setup/uninstall.cc
+++ b/chrome/installer/setup/uninstall.cc
@@ -70,6 +70,41 @@ void DeleteInstallTempDir(const FilePath& target_path) {
}
}
+// Iterates over the list of distribution types in |dist_types|, and
+// adds to |update_list| the work item to update the corresponding "ap"
+// registry value specified in |channel_info|.
+void AddChannelValueUpdateWorkItems(
+ const installer::InstallationState& original_state,
+ const installer::InstallerState& installer_state,
+ const installer::ChannelInfo& channel_info,
+ const std::vector<BrowserDistribution::Type>& dist_types,
+ WorkItemList* update_list) {
+ const bool system_level = installer_state.system_install();
+ const HKEY reg_root = installer_state.root_key();
+ for (size_t i = 0; i < dist_types.size(); ++i) {
+ BrowserDistribution::Type dist_type = dist_types[i];
+ const installer::ProductState* product_state =
+ original_state.GetProductState(system_level, dist_type);
+ // Only modify other products if they're installed and multi.
+ if (product_state != NULL &&
+ product_state->is_multi_install() &&
+ !product_state->channel().Equals(channel_info)) {
+ BrowserDistribution* other_dist =
+ BrowserDistribution::GetSpecificDistribution(dist_type);
+ update_list->AddSetRegValueWorkItem(reg_root, other_dist->GetStateKey(),
+ google_update::kRegApField, channel_info.value(), true);
+ } else {
+ LOG_IF(ERROR,
+ product_state != NULL && product_state->is_multi_install())
+ << "Channel value for "
+ << BrowserDistribution::GetSpecificDistribution(
+ dist_type)->GetAppShortCutName()
+ << " is somehow already set to the desired new value of "
+ << channel_info.value();
+ }
+ }
+}
+
// Makes appropriate changes to the Google Update "ap" value in the registry.
// Specifically, removes the flags associated with this product ("-chrome" or
// "-chromeframe[-readymode]") from the "ap" values for all other
@@ -81,7 +116,6 @@ void ProcessGoogleUpdateItems(
DCHECK(installer_state.is_multi_install());
const bool system_level = installer_state.system_install();
BrowserDistribution* distribution = product.distribution();
- const HKEY reg_root = installer_state.root_key();
const installer::ProductState* product_state =
original_state.GetProductState(system_level, distribution->GetType());
DCHECK(product_state != NULL);
@@ -95,34 +129,16 @@ void ProcessGoogleUpdateItems(
if (modified) {
scoped_ptr<WorkItemList>
update_list(WorkItem::CreateNoRollbackWorkItemList());
-
+ std::vector<BrowserDistribution::Type> dist_types;
for (size_t i = 0; i < BrowserDistribution::NUM_TYPES; ++i) {
BrowserDistribution::Type other_dist_type =
static_cast<BrowserDistribution::Type>(i);
- if (distribution->GetType() == other_dist_type)
- continue;
-
- product_state =
- original_state.GetProductState(system_level, other_dist_type);
- // Only modify other products if they're installed and multi.
- if (product_state != NULL &&
- product_state->is_multi_install() &&
- !product_state->channel().Equals(channel_info)) {
- BrowserDistribution* other_dist =
- BrowserDistribution::GetSpecificDistribution(other_dist_type);
- update_list->AddSetRegValueWorkItem(reg_root, other_dist->GetStateKey(),
- google_update::kRegApField, channel_info.value(), true);
- } else {
- LOG_IF(ERROR,
- product_state != NULL && product_state->is_multi_install())
- << "Channel value for "
- << BrowserDistribution::GetSpecificDistribution(
- other_dist_type)->GetAppShortCutName()
- << " is somehow already set to the desired new value of "
- << channel_info.value();
- }
+ if (distribution->GetType() != other_dist_type)
+ dist_types.push_back(other_dist_type);
}
-
+ AddChannelValueUpdateWorkItems(original_state, installer_state,
+ channel_info, dist_types,
+ update_list.get());
bool success = update_list->Do();
LOG_IF(ERROR, !success) << "Failed updating channel values.";
}
@@ -1254,4 +1270,76 @@ InstallStatus UninstallProduct(const InstallationState& original_state,
return ret;
}
+// Eventually App Launcher will be the only way to run V2 apps, and this flow
+// will become obsolete. That's why we concentrate all the changes here,
+// to reduce polluting common code, and to simplify future removal.
+void DemoteAppLauncherToAppHost(
+ const InstallationState& original_state,
+ const InstallerState& installer_state) {
+ VLOG(1) << "Demoting App Launcher to App Host.";
+ InstallStatus ret = installer::UNKNOWN_STATUS;
+ // App Host can only be present if Chrome is present (unlike App Launcher).
+ DCHECK(original_state.GetProductState(false,
+ BrowserDistribution::CHROME_BROWSER) ||
+ original_state.GetProductState(true,
+ BrowserDistribution::CHROME_BROWSER));
+ const ProductState* app_host_state = original_state.GetProductState(
+ installer_state.system_install(), BrowserDistribution::CHROME_APP_HOST);
+ if (!app_host_state || !app_host_state->uninstall_command().HasSwitch(
+ switches::kChromeAppLauncher)) {
+ NOTREACHED();
+ return;
+ }
+
+ BrowserDistribution* app_host_dist =
+ BrowserDistribution::GetSpecificDistribution(
+ BrowserDistribution::CHROME_APP_HOST);
+ Product app_host_product(app_host_dist);
+ app_host_product.InitializeFromUninstallCommand(
+ app_host_state->uninstall_command());
+ app_host_product.SetOption(installer::kOptionAppHostIsLauncher, false);
+
+ scoped_ptr<WorkItemList>
+ work_item_list(WorkItem::CreateNoRollbackWorkItemList());
+
+ // Update the App Host uninstall string in Google Update Client.
+ // This is extracted from AddUninstallShortcutWorkItems().
+ HKEY reg_root = installer_state.root_key();
+ string16 update_state_key(app_host_dist->GetStateKey());
+ CommandLine uninstall_arguments(CommandLine::NO_PROGRAM);
+ AppendUninstallCommandLineFlags(
+ installer_state, app_host_product, &uninstall_arguments);
+ work_item_list->AddSetRegValueWorkItem(reg_root, update_state_key,
+ installer::kUninstallArgumentsField,
+ uninstall_arguments.GetCommandLineString(), true);
+
+ // Change the "ap" keys in Google Update registry.
+ // This is extracted from ProcessGoogleUpdateItems().
+ installer::ChannelInfo channel_info;
+ channel_info.set_value(app_host_state->channel().value());
+ bool modified_app_launcher = channel_info.SetAppLauncher(false);
+ bool modified_app_host = channel_info.SetAppHost(true);
+ DCHECK(modified_app_host && modified_app_launcher);
+ std::vector<BrowserDistribution::Type> dist_types;
+ for (size_t i = 0; i < BrowserDistribution::NUM_TYPES; ++i) {
+ dist_types.push_back(static_cast<BrowserDistribution::Type>(i));
+ }
+ AddChannelValueUpdateWorkItems(original_state, installer_state, channel_info,
+ dist_types, work_item_list.get());
+
+ // Remove Control Panel uninstall link.
+ work_item_list->AddDeleteRegKeyWorkItem(
+ reg_root, app_host_dist->GetUninstallRegPath());
+
+ // Execute task list.
+ if (!work_item_list->Do())
+ LOG(ERROR) << "Failed to demote App Launcher to App Host.";
+
+ // Delete shortcuts.
+ FilePath app_host_exe(installer::GetChromeInstallPath(
+ installer_state.system_install(), app_host_dist)
+ .Append(kChromeAppHostExe));
+ DeleteShortcuts(installer_state, app_host_product, app_host_exe.value());
+}
+
} // namespace installer