diff options
author | mirandac@chromium.org <mirandac@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-22 14:58:23 +0000 |
---|---|---|
committer | mirandac@chromium.org <mirandac@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-22 14:58:23 +0000 |
commit | f8b2ca3555497caedc341ec16f110e310c15562d (patch) | |
tree | e9d22ccd68a40201dc1bb9834efb7ed26ab49561 /chrome/browser | |
parent | d21a8a5fb4d3af19452149bdcf7f6855ba80a194 (diff) | |
download | chromium_src-f8b2ca3555497caedc341ec16f110e310c15562d.zip chromium_src-f8b2ca3555497caedc341ec16f110e310c15562d.tar.gz chromium_src-f8b2ca3555497caedc341ec16f110e310c15562d.tar.bz2 |
Add Windows desktop shortcut for multiple profiles.
BUG=87770
TEST=new unit tests added with this CL.
Review URL: http://codereview.chromium.org/8502033
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@111156 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r-- | chrome/browser/chrome_browser_main_win.cc | 13 | ||||
-rw-r--r-- | chrome/browser/first_run/first_run_win.cc | 2 | ||||
-rw-r--r-- | chrome/browser/profiles/profile_info_cache.cc | 73 | ||||
-rw-r--r-- | chrome/browser/profiles/profile_info_cache.h | 16 | ||||
-rw-r--r-- | chrome/browser/profiles/profile_info_cache_observer.h | 30 | ||||
-rw-r--r-- | chrome/browser/profiles/profile_manager.cc | 13 | ||||
-rw-r--r-- | chrome/browser/profiles/profile_manager.h | 26 | ||||
-rw-r--r-- | chrome/browser/profiles/profile_manager_unittest.cc | 6 | ||||
-rw-r--r-- | chrome/browser/profiles/profile_shortcut_manager_win.cc | 216 | ||||
-rw-r--r-- | chrome/browser/profiles/profile_shortcut_manager_win.h | 62 |
10 files changed, 436 insertions, 21 deletions
diff --git a/chrome/browser/chrome_browser_main_win.cc b/chrome/browser/chrome_browser_main_win.cc index 928315b..3965c1d 100644 --- a/chrome/browser/chrome_browser_main_win.cc +++ b/chrome/browser/chrome_browser_main_win.cc @@ -22,6 +22,8 @@ #include "chrome/browser/browser_util_win.h" #include "chrome/browser/first_run/first_run.h" #include "chrome/browser/metrics/metrics_service.h" +#include "chrome/browser/profiles/profile_info_cache.h" +#include "chrome/browser/profiles/profile_shortcut_manager_win.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/views/uninstall_view.h" #include "chrome/common/chrome_constants.h" @@ -141,11 +143,18 @@ int DoUninstallTasks(bool chrome_still_running) { // created by us and not by the installer so |alternate| is false. BrowserDistribution* dist = BrowserDistribution::GetDistribution(); if (!ShellUtil::RemoveChromeDesktopShortcut(dist, ShellUtil::CURRENT_USER, - false)) + false)) { VLOG(1) << "Failed to delete desktop shortcut."; + } + if (!ShellUtil::RemoveChromeDesktopShortcutsWithAppendedNames( + ProfileShortcutManagerWin::GenerateShortcutsFromProfiles( + ProfileInfoCache::GetProfileNames()))) { + VLOG(1) << "Failed to delete desktop profiles shortcuts."; + } if (!ShellUtil::RemoveChromeQuickLaunchShortcut(dist, - ShellUtil::CURRENT_USER)) + ShellUtil::CURRENT_USER)) { VLOG(1) << "Failed to delete quick launch shortcut."; + } } return ret; } diff --git a/chrome/browser/first_run/first_run_win.cc b/chrome/browser/first_run/first_run_win.cc index 6d343c9..9a0c675 100644 --- a/chrome/browser/first_run/first_run_win.cc +++ b/chrome/browser/first_run/first_run_win.cc @@ -108,6 +108,8 @@ bool CreateChromeDesktopShortcut() { dist, chrome_exe.value(), dist->GetAppDescription(), + L"", + L"", ShellUtil::CURRENT_USER, false, true); // create if doesn't exist. diff --git a/chrome/browser/profiles/profile_info_cache.cc b/chrome/browser/profiles/profile_info_cache.cc index c0966da..c3b20e0 100644 --- a/chrome/browser/profiles/profile_info_cache.cc +++ b/chrome/browser/profiles/profile_info_cache.cc @@ -12,6 +12,7 @@ #include "base/stringprintf.h" #include "base/utf_string_conversions.h" #include "base/values.h" +#include "chrome/browser/browser_process.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/prefs/scoped_user_pref_update.h" #include "chrome/common/chrome_notification_types.h" @@ -86,7 +87,7 @@ const int kDefaultNames[] = { IDS_DEFAULT_AVATAR_NAME_25 }; -} // namespace +} // namespace ProfileInfoCache::ProfileInfoCache(PrefService* prefs, const FilePath& user_data_dir) @@ -127,10 +128,22 @@ void ProfileInfoCache::AddProfileToCache(const FilePath& profile_path, sorted_keys_.insert(FindPositionForProfile(key, name), key); + FOR_EACH_OBSERVER(ProfileInfoCacheObserver, + observer_list_, + OnProfileAdded(name, UTF8ToUTF16(key))); + content::NotificationService::current()->Notify( - chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED, - content::NotificationService::AllSources(), - content::NotificationService::NoDetails()); + chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED, + content::NotificationService::AllSources(), + content::NotificationService::NoDetails()); +} + +void ProfileInfoCache::AddObserver(ProfileInfoCacheObserver* obs) { + observer_list_.AddObserver(obs); +} + +void ProfileInfoCache::RemoveObserver(ProfileInfoCacheObserver* obs) { + observer_list_.RemoveObserver(obs); } void ProfileInfoCache::DeleteProfileFromCache(const FilePath& profile_path) { @@ -138,13 +151,22 @@ void ProfileInfoCache::DeleteProfileFromCache(const FilePath& profile_path) { DictionaryValue* cache = update.Get(); std::string key = CacheKeyFromProfilePath(profile_path); + DictionaryValue* info = NULL; + cache->GetDictionary(key, &info); + string16 name; + info->GetString(kNameKey, &name); + + FOR_EACH_OBSERVER(ProfileInfoCacheObserver, + observer_list_, + OnProfileRemoved(name)); + cache->Remove(key, NULL); sorted_keys_.erase(std::find(sorted_keys_.begin(), sorted_keys_.end(), key)); content::NotificationService::current()->Notify( - chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED, - content::NotificationService::AllSources(), - content::NotificationService::NoDetails()); + chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED, + content::NotificationService::AllSources(), + content::NotificationService::NoDetails()); } size_t ProfileInfoCache::GetNumberOfProfiles() const { @@ -215,6 +237,8 @@ size_t ProfileInfoCache::GetAvatarIconIndexOfProfileAtIndex(size_t index) void ProfileInfoCache::SetNameOfProfileAtIndex(size_t index, const string16& name) { scoped_ptr<DictionaryValue> info(GetInfoForProfileAtIndex(index)->DeepCopy()); + string16 old_name; + info->GetString(kNameKey, &old_name); info->SetString(kNameKey, name); // This takes ownership of |info|. SetInfoForProfileAtIndex(index, info.release()); @@ -227,10 +251,14 @@ void ProfileInfoCache::SetNameOfProfileAtIndex(size_t index, sorted_keys_.erase(key_it); sorted_keys_.insert(FindPositionForProfile(key, name), key); + FOR_EACH_OBSERVER(ProfileInfoCacheObserver, + observer_list_, + OnProfileNameChanged(old_name, name)); + content::NotificationService::current()->Notify( - chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED, - content::NotificationService::AllSources(), - content::NotificationService::NoDetails()); + chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED, + content::NotificationService::AllSources(), + content::NotificationService::NoDetails()); } void ProfileInfoCache::SetUserNameOfProfileAtIndex(size_t index, @@ -395,9 +423,9 @@ void ProfileInfoCache::SetInfoForProfileAtIndex(size_t index, cache->Set(sorted_keys_[index], info); content::NotificationService::current()->Notify( - chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED, - content::NotificationService::AllSources(), - content::NotificationService::NoDetails()); + chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED, + content::NotificationService::AllSources(), + content::NotificationService::NoDetails()); } std::string ProfileInfoCache::CacheKeyFromProfilePath( @@ -423,6 +451,25 @@ std::vector<std::string>::iterator ProfileInfoCache::FindPositionForProfile( return sorted_keys_.end(); } +// static +std::vector<string16> ProfileInfoCache::GetProfileNames() { + std::vector<string16> names; + PrefService* local_state = g_browser_process->local_state(); + const DictionaryValue* cache = local_state->GetDictionary( + prefs::kProfileInfoCache); + string16 name; + for (base::DictionaryValue::key_iterator it = cache->begin_keys(); + it != cache->end_keys(); + ++it) { + base::DictionaryValue* info = NULL; + cache->GetDictionary(*it, &info); + info->GetString(kNameKey, &name); + names.push_back(name); + } + return names; +} + +// static void ProfileInfoCache::RegisterPrefs(PrefService* prefs) { prefs->RegisterDictionaryPref(prefs::kProfileInfoCache); } diff --git a/chrome/browser/profiles/profile_info_cache.h b/chrome/browser/profiles/profile_info_cache.h index 345503c..63e08ff 100644 --- a/chrome/browser/profiles/profile_info_cache.h +++ b/chrome/browser/profiles/profile_info_cache.h @@ -12,7 +12,9 @@ #include "base/basictypes.h" #include "base/compiler_specific.h" #include "base/file_path.h" +#include "base/observer_list.h" #include "base/string16.h" +#include "chrome/browser/profiles/profile_info_cache_observer.h" #include "chrome/browser/profiles/profile_info_interface.h" namespace gfx { @@ -25,7 +27,6 @@ class DictionaryValue; class PrefService; - // This class saves various information about profiles to local preferences. // This cache can be used to display a list of profiles without having to // actually load the profiles from disk. @@ -83,13 +84,22 @@ class ProfileInfoCache : public ProfileInfoInterface { static bool IsDefaultAvatarIconUrl(const std::string& icon_url, size_t *icon_index); + // Gets all names of profiles associated with this instance of Chrome. + // Because this method will be called during uninstall, before the creation + // of the ProfileManager, it reads directly from the local state preferences, + // rather than going through the ProfileInfoCache object. + static std::vector<string16> GetProfileNames(); + // Register cache related preferences in Local State. static void RegisterPrefs(PrefService* prefs); + void AddObserver(ProfileInfoCacheObserver* obs); + void RemoveObserver(ProfileInfoCacheObserver* obs); + private: const base::DictionaryValue* GetInfoForProfileAtIndex(size_t index) const; // Saves the profile info to a cache and takes ownership of |info|. - // Currently the only information that is cached is the profiles name, + // Currently the only information that is cached is the profile's name, // user name, and avatar icon. void SetInfoForProfileAtIndex(size_t index, base::DictionaryValue* info); std::string CacheKeyFromProfilePath(const FilePath& profile_path) const; @@ -110,6 +120,8 @@ class ProfileInfoCache : public ProfileInfoInterface { std::vector<std::string> sorted_keys_; FilePath user_data_dir_; + ObserverList<ProfileInfoCacheObserver> observer_list_; + DISALLOW_COPY_AND_ASSIGN(ProfileInfoCache); }; diff --git a/chrome/browser/profiles/profile_info_cache_observer.h b/chrome/browser/profiles/profile_info_cache_observer.h new file mode 100644 index 0000000..43beaef7 --- /dev/null +++ b/chrome/browser/profiles/profile_info_cache_observer.h @@ -0,0 +1,30 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_PROFILES_PROFILE_INFO_CACHE_OBSERVER_H_ +#define CHROME_BROWSER_PROFILES_PROFILE_INFO_CACHE_OBSERVER_H_ +#pragma once + +// This class provides an Observer interface to watch for changes to the +// ProfileInfoCache. +class ProfileInfoCacheObserver { + public: + virtual ~ProfileInfoCacheObserver() {} + + virtual void OnProfileAdded( + const string16& profile_name, + const string16& profile_base_dir) = 0; + virtual void OnProfileRemoved( + const string16& profile_name) = 0; + virtual void OnProfileNameChanged( + const string16& old_profile_name, + const string16& new_profile_name) = 0; + + protected: + ProfileInfoCacheObserver() {} + + DISALLOW_COPY_AND_ASSIGN(ProfileInfoCacheObserver); +}; + +#endif // CHROME_BROWSER_PROFILES_PROFILE_INFO_CACHE_OBSERVER_H_ diff --git a/chrome/browser/profiles/profile_manager.cc b/chrome/browser/profiles/profile_manager.cc index 26d38b6..6836041 100644 --- a/chrome/browser/profiles/profile_manager.cc +++ b/chrome/browser/profiles/profile_manager.cc @@ -213,6 +213,9 @@ ProfileManager::ProfileManager(const FilePath& user_data_dir) ProfileManager::~ProfileManager() { BrowserList::RemoveObserver(this); +#if defined(OS_WIN) + profile_info_cache_->RemoveObserver(profile_shortcut_manager_.get()); +#endif } FilePath ProfileManager::GetDefaultProfileDir( @@ -589,6 +592,10 @@ ProfileInfoCache& ProfileManager::GetProfileInfoCache() { if (!profile_info_cache_.get()) { profile_info_cache_.reset(new ProfileInfoCache( g_browser_process->local_state(), user_data_dir_)); +#if defined(OS_WIN) + profile_shortcut_manager_.reset(new ProfileShortcutManagerWin()); + profile_info_cache_->AddObserver(profile_shortcut_manager_.get()); +#endif } return *profile_info_cache_.get(); } @@ -699,3 +706,9 @@ void ProfileManager::RegisterTestingProfile(Profile* profile, if (add_to_cache) AddProfileToCache(profile); } + +#if defined(OS_WIN) +void ProfileManager::RemoveProfileShortcutManagerForTesting() { + profile_info_cache_->RemoveObserver(profile_shortcut_manager_.get()); +} +#endif diff --git a/chrome/browser/profiles/profile_manager.h b/chrome/browser/profiles/profile_manager.h index 12c5d99..b353b0a 100644 --- a/chrome/browser/profiles/profile_manager.h +++ b/chrome/browser/profiles/profile_manager.h @@ -24,13 +24,17 @@ #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" +#if defined(OS_WIN) +#include "chrome/browser/profiles/profile_shortcut_manager_win.h" +#endif + class NewProfileLauncher; class ProfileInfoCache; class ProfileManagerObserver { public: enum Status { - // So epic. + // Asynchronous Profile services were not created. STATUS_FAIL, // Profile created but before initializing extensions and promo resources. STATUS_CREATED, @@ -190,6 +194,11 @@ class ProfileManager : public base::NonThreadSafe, // for testing. If |addToCache|, add to ProfileInfoCache as well. void RegisterTestingProfile(Profile* profile, bool addToCache); +#if defined(OS_WIN) + // Remove the shortcut manager for testing. + void RemoveProfileShortcutManagerForTesting(); +#endif + const FilePath& user_data_dir() const { return user_data_dir_; } protected: @@ -243,7 +252,7 @@ class ProfileManager : public base::NonThreadSafe, const ProfileManager::ProfilePathAndName& pair1, const ProfileManager::ProfilePathAndName& pair2); - // Adds |profile| to the profile info cache if it's not already there. + // Adds |profile| to the profile info cache if it hasn't been added yet. void AddProfileToCache(Profile* profile); // For ChromeOS, determines if profile should be otr. @@ -270,13 +279,22 @@ class ProfileManager : public base::NonThreadSafe, bool will_import_; // Maps profile path to ProfileInfo (if profile has been created). Use - // RegisterProfile() to add into this map. + // RegisterProfile() to add into this map. This map owns all loaded profile + // objects in a running instance of Chrome. typedef std::map<FilePath, linked_ptr<ProfileInfo> > ProfilesInfoMap; ProfilesInfoMap profiles_info_; - // Object to cache various information about profiles. + // Object to cache various information about profiles. Contains information + // about every profile which has been created for this instance of Chrome, + // if it has not been explicitly deleted. scoped_ptr<ProfileInfoCache> profile_info_cache_; +#if defined(OS_WIN) + // Manages the creation, deletion, and renaming of Windows shortcuts by + // observing the ProfileInfoCache. + scoped_ptr<ProfileShortcutManagerWin> profile_shortcut_manager_; +#endif + DISALLOW_COPY_AND_ASSIGN(ProfileManager); }; diff --git a/chrome/browser/profiles/profile_manager_unittest.cc b/chrome/browser/profiles/profile_manager_unittest.cc index 0392b4d..4f91e70 100644 --- a/chrome/browser/profiles/profile_manager_unittest.cc +++ b/chrome/browser/profiles/profile_manager_unittest.cc @@ -66,6 +66,12 @@ class ProfileManagerTest : public testing::Test { // Create a new temporary directory, and store the path ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); profile_manager_.reset(new ProfileManagerWithoutInit(temp_dir_.path())); +#if defined(OS_WIN) + // Force the ProfileInfoCache to be created immediately, so we can + // remove the shortcut manager for testing. + profile_manager_->GetProfileInfoCache(); + profile_manager_->RemoveProfileShortcutManagerForTesting(); +#endif } virtual void TearDown() { diff --git a/chrome/browser/profiles/profile_shortcut_manager_win.cc b/chrome/browser/profiles/profile_shortcut_manager_win.cc new file mode 100644 index 0000000..8258ef5 --- /dev/null +++ b/chrome/browser/profiles/profile_shortcut_manager_win.cc @@ -0,0 +1,216 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// 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 "base/bind.h" +#include "base/file_path.h" +#include "base/file_util.h" +#include "base/path_service.h" +#include "base/stringprintf.h" +#include "base/utf_string_conversions.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/prefs/pref_service.h" +#include "chrome/browser/profiles/profile_info_cache.h" +#include "chrome/browser/profiles/profile_manager.h" +#include "chrome/common/chrome_constants.h" +#include "chrome/common/chrome_switches.h" +#include "chrome/common/pref_names.h" +#include "chrome/installer/util/browser_distribution.h" +#include "chrome/installer/util/shell_util.h" +#include "content/public/browser/browser_thread.h" +#include "grit/generated_resources.h" +#include "ui/base/l10n/l10n_util.h" + +using content::BrowserThread; + +namespace { + +// 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(string16 profile_base_dir) { + string16 profile_directory = base::StringPrintf(L"--%ls=\"%ls\"", + ASCIIToUTF16(switches::kProfileDirectory).c_str(), + profile_base_dir.c_str()); + return profile_directory; +} + +// 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(); +} + +} // namespace + +ProfileShortcutManagerWin::ProfileShortcutManagerWin() { +} + +ProfileShortcutManagerWin::~ProfileShortcutManagerWin() { +} + +void ProfileShortcutManagerWin::OnProfileAdded( + const string16& profile_name, + const string16& profile_base_dir) { + // 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) { + string16 profile_directory = + CreateProfileShortcutSwitch(profile_base_dir); + BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, + base::Bind(&CreateChromeDesktopShortcutForProfile, + profile_name, profile_directory, true)); + + // If this is the very first multi-user account created, change the + // original shortcut to launch with the First User profile. + PrefService* local_state = g_browser_process->local_state(); + if (local_state->GetInteger(prefs::kProfilesNumCreated) == 2) { + string16 default_name = l10n_util::GetStringUTF16( + IDS_DEFAULT_PROFILE_NAME); + string16 default_directory = + CreateProfileShortcutSwitch(UTF8ToUTF16(chrome::kInitialProfile)); + BrowserDistribution* dist = BrowserDistribution::GetDistribution(); + + string16 old_shortcut; + string16 new_shortcut; + if (ShellUtil::GetChromeShortcutName(dist, false, L"", &old_shortcut) && + ShellUtil::GetChromeShortcutName(dist, false, default_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)); + BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, + base::Bind(&UpdateChromeDesktopShortcutForProfile, + new_shortcut, default_directory)); + } + } + } else { // Only one profile, so create original shortcut. + BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, + base::Bind(&CreateChromeDesktopShortcutForProfile, + L"", L"", true)); + } +} + +void ProfileShortcutManagerWin::OnProfileRemoved( + const string16& profile_name) { + 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))); + } +} + +void ProfileShortcutManagerWin::OnProfileNameChanged( + const string16& old_profile_name, + const string16& new_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) + 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)); + } +} + +// static +std::vector<string16> ProfileShortcutManagerWin::GenerateShortcutsFromProfiles( + const std::vector<string16>& profile_names) { + 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); + } + return shortcuts; +} + +// static +void ProfileShortcutManagerWin::CreateChromeDesktopShortcutForProfile( + const string16& profile_name, + const string16& directory, + 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()); + ShellUtil::CreateChromeDesktopShortcut( + dist, + chrome_exe.value(), + description, + profile_name, + directory, + ShellUtil::CURRENT_USER, + false, // Use alternate text. + create); // Create if it doesn't already exist. +} + +// static +void ProfileShortcutManagerWin::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); + } +} + +// static +void ProfileShortcutManagerWin::UpdateChromeDesktopShortcutForProfile( + const string16& shortcut, + const string16& arguments) { + 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()); + ShellUtil::UpdateChromeShortcut( + dist, + chrome_exe.value(), + shortcut_path.value(), + arguments, + description, + false); +} diff --git a/chrome/browser/profiles/profile_shortcut_manager_win.h b/chrome/browser/profiles/profile_shortcut_manager_win.h new file mode 100644 index 0000000..938bcbe --- /dev/null +++ b/chrome/browser/profiles/profile_shortcut_manager_win.h @@ -0,0 +1,62 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_PROFILES_PROFILE_SHORTCUT_MANAGER_WIN_H_ +#define CHROME_BROWSER_PROFILES_PROFILE_SHORTCUT_MANAGER_WIN_H_ +#pragma once + +#include <vector> + +#include "base/callback.h" +#include "base/compiler_specific.h" +#include "base/string16.h" +#include "chrome/browser/profiles/profile_info_cache_observer.h" + +// This class observes the ProfileInfoCache, and makes corresponding changes +// to shortcuts on the user's desktop in Windows systems. +class ProfileShortcutManagerWin : public ProfileInfoCacheObserver { + public: + ProfileShortcutManagerWin(); + virtual ~ProfileShortcutManagerWin(); + + // ProfileInfoCacheObserver: + virtual void OnProfileAdded( + const string16& profile_name, + const string16& profile_base_dir) OVERRIDE; + virtual void OnProfileRemoved( + const string16& profile_name) OVERRIDE; + virtual void OnProfileNameChanged( + const string16& old_profile_name, + const string16& new_profile_name) OVERRIDE; + + // Takes a vector of profile names (for example: "Sparky") and generates a + // vector of shortcut link names (for example: "Chromium (Sparky).lnk"). + static std::vector<string16> GenerateShortcutsFromProfiles( + const std::vector<string16>& profile_names); + + private: + // Creates a desktop shortcut to open Chrome with the given profile name and + // directory. Iff |create|, create shortcut if it doesn't already exist. Must + // be called on the FILE thread. + static void CreateChromeDesktopShortcutForProfile( + const string16& profile_name, + const string16& directory, + bool create); + + // Renames an existing Chrome desktop profile shortcut. Must be called on the + // FILE thread. + static void RenameChromeDesktopShortcutForProfile( + const string16& old_profile_name, + const string16& new_profile_name); + + // Updates the arguments to a Chrome desktop shortcut for a profile. Must be + // called on the FILE thread. + static void UpdateChromeDesktopShortcutForProfile( + const string16& shortcut, + const string16& arguments); + + DISALLOW_COPY_AND_ASSIGN(ProfileShortcutManagerWin); +}; + +#endif // CHROME_BROWSER_PROFILES_PROFILE_SHORTCUT_MANAGER_WIN_H_ |