Chromium Code Reviews| Index: chrome/browser/profiles/profile_shortcut_manager_win.cc |
| =================================================================== |
| --- chrome/browser/profiles/profile_shortcut_manager_win.cc (revision 150342) |
| +++ chrome/browser/profiles/profile_shortcut_manager_win.cc (working copy) |
| @@ -2,10 +2,12 @@ |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| -#include "chrome/browser/profiles/profile_shortcut_manager_win.h" |
| +#include "chrome/browser/profiles/profile_shortcut_manager.h" |
| +#include <map> |
| + |
| #include "base/bind.h" |
| -#include "base/file_path.h" |
| +#include "base/command_line.h" |
| #include "base/file_util.h" |
| #include "base/path_service.h" |
| #include "base/stringprintf.h" |
| @@ -29,7 +31,6 @@ |
| #include "ui/base/l10n/l10n_util.h" |
| #include "ui/base/resource/resource_bundle.h" |
| #include "ui/gfx/icon_util.h" |
| -#include "ui/gfx/image/image.h" |
| using content::BrowserThread; |
| @@ -40,22 +41,6 @@ |
| const int kProfileAvatarShortcutBadgeHeight = 28; |
| const int kShortcutIconSize = 48; |
| -// Creates the argument to pass to the Windows executable that launches Chrome |
| -// with the profile in |profile_base_dir|. |
| -// For example: --profile-directory="Profile 2" |
| -string16 CreateProfileShortcutSwitch(const string16& profile_base_dir) { |
| - return base::StringPrintf(L"--%ls=\"%ls\"", |
| - ASCIIToUTF16(switches::kProfileDirectory).c_str(), |
| - profile_base_dir.c_str()); |
| -} |
| - |
| -// Wrap a ShellUtil function that returns a bool so it can be posted in a |
| -// task to the FILE thread. |
| -void CallShellUtilBoolFunction( |
| - const base::Callback<bool(void)>& bool_function) { |
| - bool_function.Run(); |
| -} |
| - |
| // Creates a desktop shortcut icon file (.ico) on the disk for a given profile, |
| // badging the browser distribution icon with the profile avatar. |
| // |profile_base_dir| is the base directory (and key) of the profile. Returns |
| @@ -73,7 +58,7 @@ |
| if (!app_icon_bitmap.get()) |
| return FilePath(); |
| - // TODO(stevet): Share this chunk of code with |
| + // TODO(hallielaine): Share this chunk of code with |
| // avatar_menu_button::DrawTaskBarDecoration. |
| const SkBitmap* source_bitmap = NULL; |
| SkBitmap squarer_bitmap; |
| @@ -117,315 +102,123 @@ |
| return icon_path; |
| } |
| -// Creates a desktop shortcut to open Chrome with the given profile name and |
| -// base directory. Iff |create|, create shortcut if it doesn't already exist. |
| -// Must be called on the FILE thread. |
| -void CreateChromeDesktopShortcutForProfile( |
| - const string16& profile_name, |
| - const string16& profile_base_dir, |
| - const FilePath& profile_path, |
| - const gfx::Image* avatar_image, |
| - bool create) { |
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| - FilePath chrome_exe; |
| - if (!PathService::Get(base::FILE_EXE, &chrome_exe)) |
| - return; |
| - BrowserDistribution* dist = BrowserDistribution::GetDistribution(); |
| - string16 description; |
| - if (!dist) |
| - return; |
| - else |
| - description = WideToUTF16(dist->GetAppDescription()); |
| - const string16& directory = CreateProfileShortcutSwitch(profile_base_dir); |
| - FilePath icon_path = avatar_image ? |
| - CreateChromeDesktopShortcutIconForProfile(profile_path, *avatar_image) : |
| - FilePath(); |
| - |
| - ShellUtil::CreateChromeDesktopShortcut( |
| - dist, |
| - chrome_exe.value(), |
| - description, |
| - profile_name, |
| - directory, |
| - icon_path.empty() ? chrome_exe.value() : icon_path.value(), |
| - icon_path.empty() ? dist->GetIconIndex() : 0, |
| - ShellUtil::CURRENT_USER, |
| - create ? ShellUtil::SHORTCUT_CREATE_ALWAYS : |
| - ShellUtil::SHORTCUT_NO_OPTIONS); |
| +string16 CreateProfileShortcutFlags(const FilePath& profile_path) { |
| + return base::StringPrintf(L"--%ls=\"%ls\"", |
| + ASCIIToUTF16(switches::kProfileDirectory).c_str(), |
| + profile_path.BaseName().value().c_str()); |
| } |
| -// Renames an existing Chrome desktop profile shortcut. Must be called on the |
| -// FILE thread. |
| -void RenameChromeDesktopShortcutForProfile( |
| - const string16& old_shortcut, |
| - const string16& new_shortcut) { |
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| - FilePath shortcut_path; |
| - if (ShellUtil::GetDesktopPath(false, // User's directory instead of system. |
| - &shortcut_path)) { |
| - FilePath old_profile = shortcut_path.Append(old_shortcut); |
| - FilePath new_profile = shortcut_path.Append(new_shortcut); |
| - file_util::Move(old_profile, new_profile); |
| - } |
| +// Wrap a ShellUtil function that returns a bool so it can be posted in a |
| +// task to the FILE thread. |
| +void CallShellUtilBoolFunction( |
| + const base::Callback<bool(void)>& bool_function) { |
| + bool_function.Run(); |
| } |
| -// Updates the arguments to a Chrome desktop shortcut for a profile. Must be |
| -// called on the FILE thread. |
| -void UpdateChromeDesktopShortcutForProfile( |
| - const string16& shortcut, |
| - const string16& arguments, |
| - const FilePath& profile_path, |
| - const gfx::Image* avatar_image) { |
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| - FilePath shortcut_path; |
| - if (!ShellUtil::GetDesktopPath(false, &shortcut_path)) |
| - return; |
| - |
| - shortcut_path = shortcut_path.Append(shortcut); |
| - FilePath chrome_exe; |
| - if (!PathService::Get(base::FILE_EXE, &chrome_exe)) |
| - return; |
| - BrowserDistribution* dist = BrowserDistribution::GetDistribution(); |
| - string16 description; |
| - if (!dist) |
| - return; |
| - else |
| - description = WideToUTF16(dist->GetAppDescription()); |
| - FilePath icon_path = avatar_image ? |
| - CreateChromeDesktopShortcutIconForProfile(profile_path, *avatar_image) : |
| - FilePath(); |
| - |
| - ShellUtil::UpdateChromeShortcut( |
| - dist, |
| - chrome_exe.value(), |
| - shortcut_path.value(), |
| - arguments, |
| - description, |
| - icon_path.empty() ? chrome_exe.value() : icon_path.value(), |
| - icon_path.empty() ? dist->GetIconIndex() : 0, |
| - ShellUtil::SHORTCUT_NO_OPTIONS); |
| -} |
| - |
| -void DeleteAutoLaunchValueForProfile( |
| - const FilePath& profile_path) { |
| - if (auto_launch_util::AutoStartRequested(profile_path.BaseName().value(), |
| - true, // Window requested. |
| - FilePath())) { |
| - auto_launch_util::DisableForegroundStartAtLogin( |
| - profile_path.BaseName().value()); |
| - } |
| -} |
| - |
| } // namespace |
| -ProfileShortcutManagerWin::ProfileShortcutManagerWin() { |
| -} |
| +class ProfileShortcutManagerWin : public ProfileShortcutManager { |
| + public: |
| + ProfileShortcutManagerWin(); |
| + ~ProfileShortcutManagerWin(); |
| -ProfileShortcutManagerWin::~ProfileShortcutManagerWin() { |
| -} |
| + virtual void CreateChromeDesktopShortcut( |
| + const FilePath& profile_path, const string16& profile_name, |
| + const gfx::Image& avatar_image) OVERRIDE; |
| + virtual void DeleteChromeDesktopShortcut(const FilePath& profile_path) |
| + OVERRIDE; |
| -void ProfileShortcutManagerWin::AddProfileShortcut( |
| - const FilePath& profile_path) { |
| - ProfileInfoCache& cache = |
| - g_browser_process->profile_manager()->GetProfileInfoCache(); |
| - size_t index = cache.GetIndexOfProfileWithPath(profile_path); |
| - if (index == std::string::npos) |
| - return; |
| + private: |
| + struct ProfileShortcutInfo { |
| + string16 flags; |
| + string16 profile_name; |
| + gfx::Image avatar_image; |
| - // Launch task to add shortcut to desktop on Windows. If this is the very |
| - // first profile created, don't add the user name to the shortcut. |
| - // TODO(mirandac): respect master_preferences choice to create no shortcuts |
| - // (see http://crbug.com/104463) |
| - if (g_browser_process->profile_manager()->GetNumberOfProfiles() > 1) { |
| - { |
| - // We make a copy of the Image to ensure that the underlying image data is |
| - // AddRef'd, in case the original copy gets deleted. |
| - gfx::Image* avatar_copy = |
| - new gfx::Image(cache.GetAvatarIconOfProfileAtIndex(index)); |
| - string16 profile_name = cache.GetNameOfProfileAtIndex(index); |
| - string16 profile_base_dir = profile_path.BaseName().value(); |
| - BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
| - base::Bind(&CreateChromeDesktopShortcutForProfile, |
| - profile_name, profile_base_dir, profile_path, |
| - base::Owned(avatar_copy), true)); |
| - } |
| + ProfileShortcutInfo() : flags(string16()), profile_name(string16()), |
|
sail
2012/08/14 21:34:57
I don't think you need these empty constructors
Halli
2012/08/14 22:19:47
I get the following error without the default cons
|
| + avatar_image(gfx::Image()) { |
| + } |
| - // If this is the second existing multi-user account created, change the |
| - // original shortcut use the first profile's details (name, badge, |
| - // argument). |
| - if (cache.GetNumberOfProfiles() == 2) { |
| - // Get the index of the first profile, based on the index of the second |
| - // profile. It's either 0 or 1, whichever the second profile isn't. |
| - size_t first_index = 0; |
| - if (cache.GetIndexOfProfileWithPath(profile_path) == 0) |
| - first_index = 1; |
| - string16 first_name = cache.GetNameOfProfileAtIndex(first_index); |
| - BrowserDistribution* dist = BrowserDistribution::GetDistribution(); |
| + ProfileShortcutInfo( |
| + string16 p_flags, string16 p_profile_name, gfx::Image p_avatar_image) |
|
sail
2012/08/14 21:34:57
this would be easier to read if the arguments were
Halli
2012/08/14 22:19:47
Done.
|
| + : flags(p_flags), profile_name(p_profile_name), |
| + avatar_image(p_avatar_image) { |
| + } |
| + }; |
| - string16 old_shortcut; |
| - string16 new_shortcut; |
| - if (ShellUtil::GetChromeShortcutName(dist, false, L"", &old_shortcut) && |
| - ShellUtil::GetChromeShortcutName(dist, false, first_name, |
| - &new_shortcut)) { |
| - // Update doesn't allow changing the target, so rename first. |
| - BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
| - base::Bind(&RenameChromeDesktopShortcutForProfile, |
| - old_shortcut, new_shortcut)); |
| + // TODO(hallielaine): Repopulate this map on chrome session startup |
| + typedef std::map<FilePath, ProfileShortcutInfo> ProfileShortcutsMap; |
| + ProfileShortcutsMap profile_shortcuts_; |
| +}; |
| - // Fetch the avatar for the first profile and make a copy of the Image |
| - // to ensure that the underlying image data is AddRef'd, in case the |
| - // original copy is deleted. |
| - gfx::Image& first_avatar = |
| - ResourceBundle::GetSharedInstance().GetNativeImageNamed( |
| - ProfileInfoCache::GetDefaultAvatarIconResourceIDAtIndex( |
| - cache.GetAvatarIconIndexOfProfileAtIndex(first_index))); |
| - gfx::Image* first_avatar_copy = new gfx::Image(first_avatar); |
| - FilePath first_path = cache.GetPathOfProfileAtIndex(first_index); |
| - |
| - BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
| - base::Bind(&UpdateChromeDesktopShortcutForProfile, |
| - new_shortcut, |
| - CreateProfileShortcutSwitch(UTF8ToUTF16( |
| - first_path.BaseName().MaybeAsASCII())), |
| - first_path, |
| - base::Owned(first_avatar_copy))); |
| - } |
| - } |
| - } else { // Only one profile, so create original shortcut, with no avatar. |
| - BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
| - base::Bind(&CreateChromeDesktopShortcutForProfile, |
| - string16(), string16(), FilePath(), |
| - static_cast<gfx::Image*>(NULL), true)); |
| +// static |
| +bool ProfileShortcutManager::IsFeatureEnabled() { |
| + if (CommandLine::ForCurrentProcess()->HasSwitch( |
| + switches::kProfileDesktopShortcuts)) { |
| + return true; |
| } |
| + return false; |
| } |
| -void ProfileShortcutManagerWin::OnProfileAdded( |
| - const FilePath& profile_path) { |
| +// static |
| +ProfileShortcutManager* ProfileShortcutManager::Create() { |
| + return new ProfileShortcutManagerWin(); |
| } |
| -void ProfileShortcutManagerWin::OnProfileWillBeRemoved( |
| - const FilePath& profile_path) { |
| - ProfileInfoCache& cache = |
| - g_browser_process->profile_manager()->GetProfileInfoCache(); |
| - size_t index = cache.GetIndexOfProfileWithPath(profile_path); |
| - if (index == std::string::npos) |
| - return; |
| - string16 profile_name = cache.GetNameOfProfileAtIndex(index); |
| - BrowserDistribution* dist = BrowserDistribution::GetDistribution(); |
| - string16 shortcut; |
| - if (ShellUtil::GetChromeShortcutName(dist, false, profile_name, &shortcut)) { |
| - std::vector<string16> shortcuts(1, shortcut); |
| - BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
| - base::Bind(&CallShellUtilBoolFunction, |
| - base::Bind( |
| - &ShellUtil::RemoveChromeDesktopShortcutsWithAppendedNames, |
| - shortcuts))); |
| - } |
| +ProfileShortcutManagerWin::ProfileShortcutManagerWin() { |
| } |
| -void ProfileShortcutManagerWin::OnProfileWasRemoved( |
| - const FilePath& profile_path, |
| - const string16& profile_name) { |
| - BrowserThread::PostTask( |
| - BrowserThread::FILE, FROM_HERE, |
| - base::Bind(&DeleteAutoLaunchValueForProfile, profile_path)); |
| - |
| - // If there is one profile left, we want to remove the badge and name from it. |
| - ProfileInfoCache& cache = |
| - g_browser_process->profile_manager()->GetProfileInfoCache(); |
| - if (cache.GetNumberOfProfiles() != 1) |
| - return; |
| - |
| - FilePath last_profile_path = cache.GetPathOfProfileAtIndex(0); |
| - string16 old_shortcut; |
| - string16 new_shortcut; |
| - BrowserDistribution* dist = BrowserDistribution::GetDistribution(); |
| - if (ShellUtil::GetChromeShortcutName( |
| - dist, false, cache.GetNameOfProfileAtIndex(0), &old_shortcut) && |
| - ShellUtil::GetChromeShortcutName( |
| - dist, false, L"", &new_shortcut)) { |
| - BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
| - base::Bind(&RenameChromeDesktopShortcutForProfile, |
| - old_shortcut, |
| - new_shortcut)); |
| - BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
| - base::Bind(&UpdateChromeDesktopShortcutForProfile, |
| - new_shortcut, |
| - CreateProfileShortcutSwitch(UTF8ToUTF16( |
| - last_profile_path.BaseName().MaybeAsASCII())), |
| - last_profile_path, |
| - static_cast<gfx::Image*>(NULL))); |
| - } |
| +ProfileShortcutManagerWin::~ProfileShortcutManagerWin() { |
| } |
| -void ProfileShortcutManagerWin::OnProfileNameChanged( |
| - const FilePath& profile_path, |
| - const string16& old_profile_name) { |
| - // Launch task to change name of desktop shortcut on Windows. |
| - // TODO(mirandac): respect master_preferences choice to create no shortcuts |
| - // (see http://crbug.com/104463) |
| - ProfileInfoCache& cache = |
| - g_browser_process->profile_manager()->GetProfileInfoCache(); |
| - size_t index = cache.GetIndexOfProfileWithPath(profile_path); |
| - if (index == std::string::npos) |
| +void ProfileShortcutManagerWin::CreateChromeDesktopShortcut( |
| + const FilePath& profile_path, const string16& profile_name, |
| + const gfx::Image& avatar_image) { |
| + FilePath shortcut_icon = CreateChromeDesktopShortcutIconForProfile( |
| + profile_path, avatar_image); |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| + FilePath chrome_exe; |
| + if (!PathService::Get(base::FILE_EXE, &chrome_exe)) |
| return; |
| - string16 new_profile_name = cache.GetNameOfProfileAtIndex(index); |
| - |
| - string16 old_shortcut; |
| - string16 new_shortcut; |
| BrowserDistribution* dist = BrowserDistribution::GetDistribution(); |
| - if (ShellUtil::GetChromeShortcutName( |
| - dist, false, old_profile_name, &old_shortcut) && |
| - ShellUtil::GetChromeShortcutName( |
| - dist, false, new_profile_name, &new_shortcut)) { |
| - BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
| - base::Bind(&RenameChromeDesktopShortcutForProfile, |
| - old_shortcut, |
| - new_shortcut)); |
| - } |
| -} |
| - |
| -void ProfileShortcutManagerWin::OnProfileAvatarChanged( |
| - const FilePath& profile_path) { |
| - ProfileInfoCache& cache = |
| - g_browser_process->profile_manager()->GetProfileInfoCache(); |
| - size_t index = cache.GetIndexOfProfileWithPath(profile_path); |
| - if (index == std::string::npos) |
| + string16 description; |
| + if (!dist) |
| return; |
| - string16 profile_name = cache.GetNameOfProfileAtIndex(index); |
| - string16 profile_base_dir = |
| - UTF8ToUTF16(profile_path.BaseName().MaybeAsASCII()); |
| - const gfx::Image& avatar_image = cache.GetAvatarIconOfProfileAtIndex(index); |
| + description = WideToUTF16(dist->GetAppDescription()); |
| - // Launch task to change the icon of the desktop shortcut on windows. |
| - string16 new_shortcut; |
| - BrowserDistribution* dist = BrowserDistribution::GetDistribution(); |
| - if (ShellUtil::GetChromeShortcutName(dist, false, profile_name, |
| - &new_shortcut)) { |
| - // We make a copy of the Image to ensure that the underlying image data is |
| - // AddRef'd, in case the original copy gets deleted. |
| - gfx::Image* avatar_copy = new gfx::Image(avatar_image); |
| - BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
| - base::Bind(&UpdateChromeDesktopShortcutForProfile, |
| - new_shortcut, |
| - CreateProfileShortcutSwitch(profile_base_dir), |
| - profile_path, |
| - base::Owned(avatar_copy))); |
| + // Add the profile to the map if it doesn't exist already |
| + if (!profile_shortcuts_.count(profile_path)) { |
| + string16 flags = CreateProfileShortcutFlags(profile_path); |
| + profile_shortcuts_.insert(std::make_pair(profile_path, |
| + ProfileShortcutInfo(flags, profile_name, |
| + avatar_image))); |
|
sail
2012/08/14 21:34:57
indent by 4 more
Halli
2012/08/14 22:19:47
Done.
|
| } |
| + |
| + ShellUtil::CreateChromeDesktopShortcut( |
| + dist, |
| + chrome_exe.value(), |
| + description, |
| + profile_shortcuts_[profile_path].profile_name, |
| + profile_shortcuts_[profile_path].flags, |
| + shortcut_icon.empty() ? chrome_exe.value() : shortcut_icon.value(), |
| + shortcut_icon.empty() ? dist->GetIconIndex() : 0, |
| + ShellUtil::CURRENT_USER, |
| + ShellUtil::SHORTCUT_CREATE_ALWAYS); |
| } |
| -// static |
| -std::vector<string16> ProfileShortcutManagerWin::GenerateShortcutsFromProfiles( |
| - const std::vector<string16>& profile_names) { |
| +void ProfileShortcutManagerWin::DeleteChromeDesktopShortcut( |
| + const FilePath& profile_path) { |
| BrowserDistribution* dist = BrowserDistribution::GetDistribution(); |
| - std::vector<string16> shortcuts; |
| - shortcuts.reserve(profile_names.size()); |
| - for (std::vector<string16>::const_iterator it = profile_names.begin(); |
| - it != profile_names.end(); |
| - ++it) { |
| - string16 shortcut; |
| - if (ShellUtil::GetChromeShortcutName(dist, false, *it, &shortcut)) |
| - shortcuts.push_back(shortcut); |
| + string16 shortcut; |
| + // If we can find the shortcut, delete it |
| + if (ShellUtil::GetChromeShortcutName(dist, false, |
| + profile_shortcuts_[profile_path].profile_name, &shortcut)) { |
| + std::vector<string16> appended_names(1, shortcut); |
| + BrowserThread::PostTask( |
| + BrowserThread::FILE, FROM_HERE, |
| + base::Bind(&CallShellUtilBoolFunction, base::Bind( |
| + &ShellUtil::RemoveChromeDesktopShortcutsWithAppendedNames, |
|
sail
2012/08/14 21:34:57
need to indent by 4 more, next line as well
Halli
2012/08/14 22:19:47
Done.
|
| + appended_names))); |
| + profile_shortcuts_.erase(profile_path); |
| } |
| - return shortcuts; |
| } |
| + |