From f80bda00955c8455397408abc67dce4d75c90aa1 Mon Sep 17 00:00:00 2001 From: "mgiuca@chromium.org" Date: Tue, 2 Jul 2013 10:30:31 +0000 Subject: Windows: Deleting a profile deletes all app shortcuts associated with it. This will search all locations where app shortcuts reside and delete any that open Chrome with the profile being deleted. Mac and Linux have empty stubs, to be completed in a follow-up CL. BUG=236353 Review URL: https://chromiumcodereview.appspot.com/16139004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@209658 0039d316-1c4b-4281-b951-d872f2087c98 --- chrome/browser/web_applications/web_app.h | 4 ++ chrome/browser/web_applications/web_app_android.cc | 2 + chrome/browser/web_applications/web_app_linux.cc | 4 ++ chrome/browser/web_applications/web_app_mac.mm | 4 ++ chrome/browser/web_applications/web_app_win.cc | 83 ++++++++++++++++------ 5 files changed, 76 insertions(+), 21 deletions(-) (limited to 'chrome/browser/web_applications') diff --git a/chrome/browser/web_applications/web_app.h b/chrome/browser/web_applications/web_app.h index af24aef..7436663 100644 --- a/chrome/browser/web_applications/web_app.h +++ b/chrome/browser/web_applications/web_app.h @@ -131,6 +131,10 @@ void UpdatePlatformShortcuts( const string16& old_app_title, const ShellIntegration::ShortcutInfo& shortcut_info); +// Delete all the shortcuts for an entire profile. +// This is executed on the FILE thread. +void DeleteAllShortcutsForProfile(const base::FilePath& profile_path); + // Sanitizes |name| and returns a version of it that is safe to use as an // on-disk file name . base::FilePath GetSanitizedFileName(const string16& name); diff --git a/chrome/browser/web_applications/web_app_android.cc b/chrome/browser/web_applications/web_app_android.cc index ece27a1..61c9445 100644 --- a/chrome/browser/web_applications/web_app_android.cc +++ b/chrome/browser/web_applications/web_app_android.cc @@ -23,5 +23,7 @@ void UpdatePlatformShortcuts( const string16& old_app_title, const ShellIntegration::ShortcutInfo& shortcut_info) {} +void DeleteAllShortcutsForProfile(const base::FilePath& profile_path) {} + } // namespace internals } // namespace web_app diff --git a/chrome/browser/web_applications/web_app_linux.cc b/chrome/browser/web_applications/web_app_linux.cc index f3139ba..a602918 100644 --- a/chrome/browser/web_applications/web_app_linux.cc +++ b/chrome/browser/web_applications/web_app_linux.cc @@ -53,6 +53,10 @@ void UpdatePlatformShortcuts( CreatePlatformShortcuts(web_app_path, shortcut_info, creation_locations); } +void DeleteAllShortcutsForProfile(const base::FilePath& profile_path) { + // TODO(mgiuca): Implement this on Linux. +} + } // namespace internals } // namespace web_app diff --git a/chrome/browser/web_applications/web_app_mac.mm b/chrome/browser/web_applications/web_app_mac.mm index 8a004eb..2717f9c 100644 --- a/chrome/browser/web_applications/web_app_mac.mm +++ b/chrome/browser/web_applications/web_app_mac.mm @@ -624,6 +624,10 @@ void UpdatePlatformShortcuts( shortcut_creator.UpdateShortcuts(); } +void DeleteAllShortcutsForProfile(const base::FilePath& profile_path) { + // TODO(mgiuca): Implement this on Mac. +} + } // namespace internals } // namespace web_app diff --git a/chrome/browser/web_applications/web_app_win.cc b/chrome/browser/web_applications/web_app_win.cc index e174eb8..de5355a 100644 --- a/chrome/browser/web_applications/web_app_win.cc +++ b/chrome/browser/web_applications/web_app_win.cc @@ -8,6 +8,7 @@ #include "base/command_line.h" #include "base/file_util.h" +#include "base/files/file_enumerator.h" #include "base/logging.h" #include "base/md5.h" #include "base/path_service.h" @@ -92,41 +93,63 @@ bool ShouldUpdateIcon(const base::FilePath& icon_file, sizeof(base::MD5Digest)) != 0; } -bool ShortcutIsForProfile(const base::FilePath& shortcut_file_name, - const base::FilePath& profile_path) { +// Returns true if |shortcut_file_name| matches profile |profile_path|, and has +// an --app-id flag. +bool IsAppShortcutForProfile(const base::FilePath& shortcut_file_name, + const base::FilePath& profile_path) { string16 cmd_line_string; if (base::win::ResolveShortcut(shortcut_file_name, NULL, &cmd_line_string)) { cmd_line_string = L"program " + cmd_line_string; CommandLine shortcut_cmd_line = CommandLine::FromString(cmd_line_string); return shortcut_cmd_line.HasSwitch(switches::kProfileDirectory) && shortcut_cmd_line.GetSwitchValuePath(switches::kProfileDirectory) == - profile_path.BaseName(); + profile_path.BaseName() && + shortcut_cmd_line.HasSwitch(switches::kAppId); } return false; } -std::vector MatchingShortcutsForProfileAndExtension( +// Finds shortcuts in |shortcut_path| that match profile for |profile_path| and +// extension with title |shortcut_name|. +// If |shortcut_name| is empty, finds all shortcuts matching |profile_path|. +std::vector FindAppShortcutsByProfileAndTitle( const base::FilePath& shortcut_path, const base::FilePath& profile_path, const string16& shortcut_name) { std::vector shortcut_paths; - base::FilePath base_path = shortcut_path. - Append(web_app::internals::GetSanitizedFileName(shortcut_name)). - AddExtension(FILE_PATH_LITERAL(".lnk")); - - const int fileNamesToCheck = 10; - for (int i = 0; i < fileNamesToCheck; ++i) { - base::FilePath shortcut_file = base_path; - if (i) { - shortcut_file = shortcut_file.InsertBeforeExtensionASCII( - base::StringPrintf(" (%d)", i)); + + if (shortcut_name.empty()) { + // Find all shortcuts for this profile. + base::FileEnumerator files(shortcut_path, false, + base::FileEnumerator::FILES, + FILE_PATH_LITERAL("*.lnk")); + base::FilePath shortcut_file = files.Next(); + while (!shortcut_file.empty()) { + if (IsAppShortcutForProfile(shortcut_file, profile_path)) + shortcut_paths.push_back(shortcut_file); + shortcut_file = files.Next(); } - if (file_util::PathExists(shortcut_file) && - ShortcutIsForProfile(shortcut_file, profile_path)) { - shortcut_paths.push_back(shortcut_file); + } else { + // Find all shortcuts matching |shortcut_name|. + base::FilePath base_path = shortcut_path. + Append(web_app::internals::GetSanitizedFileName(shortcut_name)). + AddExtension(FILE_PATH_LITERAL(".lnk")); + + const int fileNamesToCheck = 10; + for (int i = 0; i < fileNamesToCheck; ++i) { + base::FilePath shortcut_file = base_path; + if (i > 0) { + shortcut_file = shortcut_file.InsertBeforeExtensionASCII( + base::StringPrintf(" (%d)", i)); + } + if (file_util::PathExists(shortcut_file) && + IsAppShortcutForProfile(shortcut_file, profile_path)) { + shortcut_paths.push_back(shortcut_file); + } } } + return shortcut_paths; } @@ -229,6 +252,9 @@ bool CreateShortcutsInPaths( // in the profile with |profile_path|. // |was_pinned_to_taskbar| will be set to true if there was previously a // shortcut pinned to the taskbar for this app; false otherwise. +// If |web_app_path| is empty, this will not delete shortcuts from the web app +// directory. If |title| is empty, all shortcuts for this profile will be +// deleted. // |shortcut_paths| will be populated with a list of directories where shortcuts // for this app were found (and deleted). This will delete duplicate shortcuts, // but only return each path once, even if it contained multiple deleted @@ -253,16 +279,18 @@ void GetShortcutLocationsAndDeleteShortcuts( web_app::GetAppShortcutsSubdirName(); std::vector all_paths = web_app::internals::GetShortcutPaths( all_shortcut_locations); - if (base::win::GetVersion() >= base::win::VERSION_WIN7) + if (base::win::GetVersion() >= base::win::VERSION_WIN7 && + !web_app_path.empty()) { all_paths.push_back(web_app_path); + } if (was_pinned_to_taskbar) { // Determine if there is a link to this app in the TaskBar pin directory. base::FilePath taskbar_pin_path; if (PathService::Get(base::DIR_TASKBAR_PINS, &taskbar_pin_path)) { std::vector taskbar_pin_files = - MatchingShortcutsForProfileAndExtension(taskbar_pin_path, - profile_path, title); + FindAppShortcutsByProfileAndTitle(taskbar_pin_path, profile_path, + title); *was_pinned_to_taskbar = !taskbar_pin_files.empty(); } else { *was_pinned_to_taskbar = false; @@ -272,7 +300,7 @@ void GetShortcutLocationsAndDeleteShortcuts( for (std::vector::const_iterator i = all_paths.begin(); i != all_paths.end(); ++i) { std::vector shortcut_files = - MatchingShortcutsForProfileAndExtension(*i, profile_path, title); + FindAppShortcutsByProfileAndTitle(*i, profile_path, title); if (shortcut_paths && !shortcut_files.empty()) { shortcut_paths->push_back(*i); } @@ -423,6 +451,19 @@ void DeletePlatformShortcuts( } } +void DeleteAllShortcutsForProfile(const base::FilePath& profile_path) { + GetShortcutLocationsAndDeleteShortcuts(base::FilePath(), profile_path, L"", + NULL, NULL); + + // If there are no more shortcuts in the Chrome Apps subdirectory, remove it. + base::FilePath chrome_apps_dir; + if (PathService::Get(base::DIR_START_MENU, &chrome_apps_dir)) { + chrome_apps_dir = chrome_apps_dir.Append(GetAppShortcutsSubdirName()); + if (file_util::IsDirectoryEmpty(chrome_apps_dir)) + base::Delete(chrome_apps_dir, false); + } +} + std::vector GetShortcutPaths( const ShellIntegration::ShortcutLocations& creation_locations) { // Shortcut paths under which to create shortcuts. -- cgit v1.1