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

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

Issue 10665002: Implement installation of the Chrome App Host. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: A basic working app host installer/uninstaller. 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
Index: chrome/installer/setup/uninstall.cc
diff --git a/chrome/installer/setup/uninstall.cc b/chrome/installer/setup/uninstall.cc
index 5f7578b0608f00f4b84a3810fe879259f849538d..1c18b97c468f79c3c6d260342de94393d36ebd93 100644
--- a/chrome/installer/setup/uninstall.cc
+++ b/chrome/installer/setup/uninstall.cc
@@ -49,6 +49,23 @@ using installer::MasterPreferences;
namespace {
+// Avoid leaving behind a Temp dir. If one exists, ask SelfCleaningTempDir to
+// clean it up for us. This may involve scheduling it for deletion after
+// reboot. Don't report that a reboot is required in this case, however.
+// TODO(erikwright): Shouldn't this still lead to
+// ScheduleParentAndGrandparentForDeletion?
tommi (sloooow) - chröme 2012/07/12 08:11:31 if so, file a bug for tracking?
erikwright (departed) 2012/07/16 20:13:11 I don't know the answer. I'll ask Greg OOB.
+void DeleteInstallTempDir(const FilePath& target_path) {
+ FilePath temp_path(target_path.DirName().Append(installer::kInstallTempDir));
+ if (file_util::DirectoryExists(temp_path)) {
+ installer::SelfCleaningTempDir temp_dir;
+ if (!temp_dir.Initialize(target_path.DirName(),
+ installer::kInstallTempDir) ||
+ !temp_dir.Delete()) {
+ LOG(ERROR) << "Failed to delete temp dir " << temp_path.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
@@ -72,16 +89,17 @@ void ProcessGoogleUpdateItems(
// Apply the new channel value to all other products and to the multi package.
if (modified) {
- BrowserDistribution::Type other_dist_types[] = {
- (distribution->GetType() == BrowserDistribution::CHROME_BROWSER) ?
- BrowserDistribution::CHROME_FRAME :
- BrowserDistribution::CHROME_BROWSER,
- BrowserDistribution::CHROME_BINARIES
- };
+ std::vector<BrowserDistribution::Type> other_dist_types;
+ for (size_t i = 0; i < BrowserDistribution::kNumProductTypes; ++i) {
+ if (distribution->GetType() != BrowserDistribution::kProductTypes[i])
+ other_dist_types.push_back(BrowserDistribution::kProductTypes[i]);
+ }
+
scoped_ptr<WorkItemList>
update_list(WorkItem::CreateNoRollbackWorkItemList());
- for (int i = 0; i < arraysize(other_dist_types); ++i) {
+ for (size_t i = 0; i < other_dist_types.size(); ++i) {
+ // TODO(erikwright): Who updates the ap value for the binaries?
BrowserDistribution::Type other_dist_type = other_dist_types[i];
product_state =
original_state.GetProductState(system_level, other_dist_type);
@@ -396,44 +414,80 @@ bool MoveSetupOutOfInstallFolder(const InstallerState& installer_state,
return ret;
}
-DeleteResult DeleteFilesAndFolders(const InstallerState& installer_state,
- const Version& installed_version) {
+DeleteResult DeleteAppHostFilesAndFolders(const InstallerState& installer_state,
+ const Version& installed_version) {
const FilePath& target_path = installer_state.target_path();
if (target_path.empty()) {
- LOG(ERROR) << "DeleteFilesAndFolders: no installation destination path.";
+ LOG(ERROR) << "DeleteAppHostFilesAndFolders: no installation destination "
+ << "path.";
return DELETE_FAILED; // Nothing else we can do to uninstall, so we return.
}
+ DeleteInstallTempDir(target_path);
+
DeleteResult result = DELETE_SUCCEEDED;
- // Avoid leaving behind a Temp dir. If one exists, ask SelfCleaningTempDir to
- // clean it up for us. This may involve scheduling it for deletion after
- // reboot. Don't report that a reboot is required in this case, however.
- FilePath temp_path(target_path.DirName().Append(kInstallTempDir));
- if (file_util::DirectoryExists(temp_path)) {
- installer::SelfCleaningTempDir temp_dir;
- if (!temp_dir.Initialize(target_path.DirName(), kInstallTempDir) ||
- !temp_dir.Delete()) {
- LOG(ERROR) << "Failed to delete temp dir " << temp_path.value();
- }
+ FilePath app_host_exe(target_path.Append(installer::kChromeAppHostExe));
+ if (!file_util::Delete(app_host_exe, false)) {
+ result = DELETE_FAILED;
+ LOG(ERROR) << "Failed to delete path: " << app_host_exe.value();
+ } else {
+ DeleteEmptyParentDir(target_path);
}
- VLOG(1) << "Deleting install path " << target_path.value();
- if (!file_util::Delete(target_path, true)) {
- LOG(ERROR) << "Failed to delete folder (1st try): " << target_path.value();
- if (installer_state.FindProduct(BrowserDistribution::CHROME_FRAME)) {
- // We don't try killing Chrome processes for Chrome Frame builds since
- // that is unlikely to help. Instead, schedule files for deletion and
- // return a value that will trigger a reboot prompt.
- ScheduleDirectoryForDeletion(target_path.value().c_str());
- result = DELETE_REQUIRES_REBOOT;
- } else {
- // Try closing any running chrome processes and deleting files once again.
- CloseAllChromeProcesses();
- if (!file_util::Delete(target_path, true)) {
- LOG(ERROR) << "Failed to delete folder (2nd try): "
- << target_path.value();
- result = DELETE_FAILED;
+ return result;
+}
+
+DeleteResult DeleteChromeFilesAndFolders(const InstallerState& installer_state,
+ const Version& installed_version) {
+ const FilePath& target_path = installer_state.target_path();
+ if (target_path.empty()) {
+ LOG(ERROR) << "DeleteChromeFilesAndFolders: no installation destination "
+ << "path.";
+ return DELETE_FAILED; // Nothing else we can do to uninstall, so we return.
+ }
+
+ DeleteInstallTempDir(target_path);
+
+ DeleteResult result = DELETE_SUCCEEDED;
+
+ using file_util::FileEnumerator;
+ FileEnumerator file_enumerator(
+ target_path,
+ false,
+ static_cast<FileEnumerator::FileType>(FileEnumerator::FILES |
+ FileEnumerator::DIRECTORIES));
+ while (true) {
+ FilePath to_delete(file_enumerator.Next());
+ if (to_delete.empty())
+ break;
+ if (to_delete.BaseName().value() == installer::kChromeAppHostExe)
+ continue;
+
+ VLOG(1) << "Deleting install path " << target_path.value();
+ if (!file_util::Delete(to_delete, true)) {
+ LOG(ERROR) << "Failed to delete path (1st try): " << to_delete.value();
+ if (installer_state.FindProduct(BrowserDistribution::CHROME_FRAME)) {
+ // We don't try killing Chrome processes for Chrome Frame builds since
+ // that is unlikely to help. Instead, schedule files for deletion and
+ // return a value that will trigger a reboot prompt.
+ FileEnumerator::FindInfo find_info;
+ file_enumerator.GetFindInfo(&find_info);
+ if (FileEnumerator::IsDirectory(find_info))
+ ScheduleDirectoryForDeletion(to_delete.value().c_str());
+ else
+ ScheduleFileSystemEntityForDeletion(to_delete.value().c_str());
+ result = DELETE_REQUIRES_REBOOT;
+ } else {
+ // Try closing any running Chrome processes and deleting files once
+ // again.
+ CloseAllChromeProcesses();
+ if (!file_util::Delete(to_delete, true)) {
+ LOG(ERROR) << "Failed to delete path (2nd try): "
+ << to_delete.value();
+ result = DELETE_FAILED;
+ break;
+ }
}
}
}
@@ -497,7 +551,7 @@ bool ShouldDeleteProfile(const InstallerState& installer_state,
// UI to prompt otherwise and the profile stores no useful data anyway)
// unless they are managed by MSI. MSI uninstalls will explicitly include
// the --delete-profile flag to distinguish them from MSI upgrades.
- if (!product.is_chrome() && !installer_state.is_msi()) {
+ if (product.is_chrome_frame() && !installer_state.is_msi()) {
should_delete = true;
} else {
should_delete =
@@ -840,7 +894,7 @@ InstallStatus UninstallProduct(const InstallationState& original_state,
ProcessDelegateExecuteWorkItems(installer_state, product);
- if (!is_chrome) {
+ if (product.is_chrome_frame()) {
ProcessChromeFrameWorkItems(original_state, installer_state, setup_path,
product);
}
@@ -888,7 +942,7 @@ InstallStatus UninstallProduct(const InstallationState& original_state,
unreg_work_item_list->Do();
}
- if (!is_chrome)
+ if (product.is_chrome_frame())
ProcessIELowRightsPolicyWorkItems(installer_state);
}
@@ -908,41 +962,25 @@ InstallStatus UninstallProduct(const InstallationState& original_state,
ret = installer::UNINSTALL_SUCCESSFUL;
// When deleting files, we must make sure that we're either a "single"
- // (aka non-multi) installation or, in the case of multi, that no other
- // "multi" products share the binaries we are about to delete.
+ // (aka non-multi) installation or we are the Chrome Binaries.
- bool can_delete_files = true;
- if (installer_state.is_multi_install()) {
- ProductState prod_state;
- for (size_t i = 0; i < BrowserDistribution::kNumProductTypes; ++i) {
- if (prod_state.Initialize(installer_state.system_install(),
- BrowserDistribution::kProductTypes[i]) &&
- prod_state.is_multi_install()) {
- can_delete_files = false;
- break;
- }
- }
- LOG(INFO) << (can_delete_files ? "Shared binaries will be deleted." :
- "Shared binaries still in use.");
- if (can_delete_files) {
- BrowserDistribution* multi_dist =
- installer_state.multi_package_binaries_distribution();
- InstallUtil::DeleteRegistryKey(reg_root, multi_dist->GetVersionKey());
- }
- }
-
- FilePath backup_state_file(BackupLocalStateFile(
- GetLocalStateFolder(product)));
+ FilePath backup_state_file(
+ BackupLocalStateFile(GetLocalStateFolder(product)));
DeleteResult delete_result = DELETE_SUCCEEDED;
- if (can_delete_files) {
+
+ if (product.is_chrome_app_host()) {
+ DeleteAppHostFilesAndFolders(installer_state, product_state->version());
+ } else if (!installer_state.is_multi_install() ||
+ product.is_chrome_binaries()) {
+
// In order to be able to remove the folder in which we're running, we
// need to move setup.exe out of the install folder.
// TODO(tommi): What if the temp folder is on a different volume?
MoveSetupOutOfInstallFolder(installer_state, setup_path,
product_state->version());
- delete_result = DeleteFilesAndFolders(installer_state,
- product_state->version());
+ delete_result = DeleteChromeFilesAndFolders(installer_state,
+ product_state->version());
}
if (delete_profile)
@@ -955,7 +993,7 @@ InstallStatus UninstallProduct(const InstallationState& original_state,
}
if (!force_uninstall) {
- VLOG(1) << "Uninstallation complete. Launching Uninstall survey.";
+ VLOG(1) << "Uninstallation complete. Launching post-uninstall operations.";
browser_dist->DoPostUninstallOperations(product_state->version(),
backup_state_file, distribution_data);
}

Powered by Google App Engine
This is Rietveld 408576698