summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/chrome_browser_main_win.cc13
-rw-r--r--chrome/browser/first_run/first_run_win.cc2
-rw-r--r--chrome/browser/profiles/profile_info_cache.cc73
-rw-r--r--chrome/browser/profiles/profile_info_cache.h16
-rw-r--r--chrome/browser/profiles/profile_info_cache_observer.h30
-rw-r--r--chrome/browser/profiles/profile_manager.cc13
-rw-r--r--chrome/browser/profiles/profile_manager.h26
-rw-r--r--chrome/browser/profiles/profile_manager_unittest.cc6
-rw-r--r--chrome/browser/profiles/profile_shortcut_manager_win.cc216
-rw-r--r--chrome/browser/profiles/profile_shortcut_manager_win.h62
-rw-r--r--chrome/chrome_browser.gypi3
-rw-r--r--chrome/installer/setup/install.cc8
-rw-r--r--chrome/installer/util/browser_distribution_unittest.cc15
-rw-r--r--chrome/installer/util/shell_util.cc62
-rw-r--r--chrome/installer/util/shell_util.h53
-rw-r--r--chrome/installer/util/shell_util_unittest.cc86
16 files changed, 622 insertions, 62 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_
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 9b01954..2f01db7 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -1965,6 +1965,7 @@
'browser/profiles/profile_impl_io_data.h',
'browser/profiles/profile_info_cache.cc',
'browser/profiles/profile_info_cache.h',
+ 'browser/profiles/profile_info_cache_observer.h',
'browser/profiles/profile_info_interface.h',
'browser/profiles/profile_io_data.cc',
'browser/profiles/profile_io_data.h',
@@ -1974,6 +1975,8 @@
'browser/profiles/profile_manager.h',
'browser/profiles/profile_metrics.cc',
'browser/profiles/profile_metrics.h',
+ 'browser/profiles/profile_shortcut_manager_win.cc',
+ 'browser/profiles/profile_shortcut_manager_win.h',
'browser/protector/base_setting_change.cc',
'browser/protector/base_setting_change.h',
'browser/protector/default_search_provider_change.cc',
diff --git a/chrome/installer/setup/install.cc b/chrome/installer/setup/install.cc
index d817c48..36c24ca 100644
--- a/chrome/installer/setup/install.cc
+++ b/chrome/installer/setup/install.cc
@@ -131,12 +131,12 @@ bool CreateOrUpdateChromeShortcuts(const InstallerState& installer_state,
VLOG(1) << "Creating shortcut to " << chrome_exe.value() << " at "
<< chrome_link.value();
ret = ShellUtil::UpdateChromeShortcut(browser_dist, chrome_exe.value(),
- chrome_link.value(), product_desc, true);
+ chrome_link.value(), L"", product_desc, true);
} else if (file_util::PathExists(chrome_link)) {
VLOG(1) << "Updating shortcut at " << chrome_link.value()
<< " to point to " << chrome_exe.value();
ret = ShellUtil::UpdateChromeShortcut(browser_dist, chrome_exe.value(),
- chrome_link.value(), product_desc, false);
+ chrome_link.value(), L"", product_desc, false);
} else {
VLOG(1)
<< "not first or repaired install, link file doesn't exist. status: "
@@ -181,7 +181,7 @@ bool CreateOrUpdateChromeShortcuts(const InstallerState& installer_state,
if (ret) {
if (installer_state.system_install()) {
ret = ShellUtil::CreateChromeDesktopShortcut(product.distribution(),
- chrome_exe.value(), product_desc, ShellUtil::SYSTEM_LEVEL,
+ chrome_exe.value(), product_desc, L"", L"", ShellUtil::SYSTEM_LEVEL,
alt_shortcut, create_all_shortcut);
if (ret) {
ret = ShellUtil::CreateChromeQuickLaunchShortcut(
@@ -191,7 +191,7 @@ bool CreateOrUpdateChromeShortcuts(const InstallerState& installer_state,
}
} else {
ret = ShellUtil::CreateChromeDesktopShortcut(product.distribution(),
- chrome_exe.value(), product_desc, ShellUtil::CURRENT_USER,
+ chrome_exe.value(), product_desc, L"", L"", ShellUtil::CURRENT_USER,
alt_shortcut, create_all_shortcut);
if (ret) {
ret = ShellUtil::CreateChromeQuickLaunchShortcut(
diff --git a/chrome/installer/util/browser_distribution_unittest.cc b/chrome/installer/util/browser_distribution_unittest.cc
index 942f62c..6a09443 100644
--- a/chrome/installer/util/browser_distribution_unittest.cc
+++ b/chrome/installer/util/browser_distribution_unittest.cc
@@ -43,10 +43,21 @@ TEST(BrowserDistributionTest, StringsTest) {
TEST(BrowserDistributionTest, AlternateAndNormalShortcutName) {
std::wstring normal_name;
std::wstring alternate_name;
+ std::wstring appended_name_one;
+ std::wstring appended_name_two;
BrowserDistribution* dist = BrowserDistribution::GetDistribution();
- EXPECT_TRUE(ShellUtil::GetChromeShortcutName(dist, &normal_name, false));
- EXPECT_TRUE(ShellUtil::GetChromeShortcutName(dist, &alternate_name, true));
+ EXPECT_TRUE(ShellUtil::GetChromeShortcutName(dist, false, L"",
+ &normal_name));
+ EXPECT_TRUE(ShellUtil::GetChromeShortcutName(dist, true, L"",
+ &alternate_name));
+ EXPECT_TRUE(ShellUtil::GetChromeShortcutName(dist, true, L"Sparky",
+ &appended_name_one));
+ EXPECT_TRUE(ShellUtil::GetChromeShortcutName(dist, true, L"Sparkles",
+ &appended_name_two));
EXPECT_NE(normal_name, alternate_name);
+ EXPECT_NE(appended_name_one, appended_name_two);
EXPECT_FALSE(normal_name.empty());
EXPECT_FALSE(alternate_name.empty());
+ EXPECT_FALSE(appended_name_one.empty());
+ EXPECT_FALSE(appended_name_two.empty());
}
diff --git a/chrome/installer/util/shell_util.cc b/chrome/installer/util/shell_util.cc
index 3b56f82..ab6622d 100644
--- a/chrome/installer/util/shell_util.cc
+++ b/chrome/installer/util/shell_util.cc
@@ -545,11 +545,14 @@ bool ShellUtil::AdminNeededForRegistryCleanup(BrowserDistribution* dist,
bool ShellUtil::CreateChromeDesktopShortcut(BrowserDistribution* dist,
const std::wstring& chrome_exe,
const std::wstring& description,
+ const std::wstring& appended_name,
+ const std::wstring& arguments,
ShellChange shell_change,
bool alternate,
bool create_new) {
std::wstring shortcut_name;
- if (!ShellUtil::GetChromeShortcutName(dist, &shortcut_name, alternate))
+ if (!ShellUtil::GetChromeShortcutName(dist, alternate, appended_name,
+ &shortcut_name))
return false;
bool ret = false;
@@ -565,18 +568,24 @@ bool ShellUtil::CreateChromeDesktopShortcut(BrowserDistribution* dist,
// nothing in it, so let's continue.
if (ShellUtil::GetDesktopPath(false, &shortcut_path)) {
shortcut = shortcut_path.Append(shortcut_name);
- ret = ShellUtil::UpdateChromeShortcut(dist, chrome_exe,
+ ret = ShellUtil::UpdateChromeShortcut(dist,
+ chrome_exe,
shortcut.value(),
- description, create_new);
+ arguments,
+ description,
+ create_new);
}
}
} else if (shell_change == ShellUtil::SYSTEM_LEVEL) {
FilePath shortcut_path;
if (ShellUtil::GetDesktopPath(true, &shortcut_path)) {
FilePath shortcut = shortcut_path.Append(shortcut_name);
- ret = ShellUtil::UpdateChromeShortcut(dist, chrome_exe,
+ ret = ShellUtil::UpdateChromeShortcut(dist,
+ chrome_exe,
shortcut.value(),
- description, create_new);
+ arguments,
+ description,
+ create_new);
}
} else {
NOTREACHED();
@@ -589,7 +598,7 @@ bool ShellUtil::CreateChromeQuickLaunchShortcut(BrowserDistribution* dist,
int shell_change,
bool create_new) {
std::wstring shortcut_name;
- if (!ShellUtil::GetChromeShortcutName(dist, &shortcut_name, false))
+ if (!ShellUtil::GetChromeShortcutName(dist, false, L"", &shortcut_name))
return false;
bool ret = true;
@@ -599,7 +608,7 @@ bool ShellUtil::CreateChromeQuickLaunchShortcut(BrowserDistribution* dist,
if (ShellUtil::GetQuickLaunchPath(false, &user_ql_path)) {
file_util::AppendToPath(&user_ql_path, shortcut_name);
ret = ShellUtil::UpdateChromeShortcut(dist, chrome_exe, user_ql_path,
- L"", create_new);
+ L"", L"", create_new);
} else {
ret = false;
}
@@ -612,7 +621,7 @@ bool ShellUtil::CreateChromeQuickLaunchShortcut(BrowserDistribution* dist,
if (ShellUtil::GetQuickLaunchPath(true, &default_ql_path)) {
file_util::AppendToPath(&default_ql_path, shortcut_name);
ret = ShellUtil::UpdateChromeShortcut(dist, chrome_exe, default_ql_path,
- L"", create_new) && ret;
+ L"", L"", create_new) && ret;
} else {
ret = false;
}
@@ -634,9 +643,16 @@ std::wstring ShellUtil::GetChromeShellOpenCmd(const std::wstring& chrome_exe) {
}
bool ShellUtil::GetChromeShortcutName(BrowserDistribution* dist,
- std::wstring* shortcut, bool alternate) {
+ bool alternate,
+ const std::wstring& appended_name,
+ std::wstring* shortcut) {
shortcut->assign(alternate ? dist->GetAlternateApplicationName() :
dist->GetAppShortCutName());
+ if (!appended_name.empty()) {
+ shortcut->append(L" (");
+ shortcut->append(appended_name);
+ shortcut->append(L")");
+ }
shortcut->append(L".lnk");
return true;
}
@@ -954,7 +970,8 @@ bool ShellUtil::RegisterChromeForProtocol(BrowserDistribution* dist,
bool ShellUtil::RemoveChromeDesktopShortcut(BrowserDistribution* dist,
int shell_change, bool alternate) {
std::wstring shortcut_name;
- if (!ShellUtil::GetChromeShortcutName(dist, &shortcut_name, alternate))
+ if (!ShellUtil::GetChromeShortcutName(dist, alternate, L"",
+ &shortcut_name))
return false;
bool ret = true;
@@ -980,10 +997,28 @@ bool ShellUtil::RemoveChromeDesktopShortcut(BrowserDistribution* dist,
return ret;
}
+bool ShellUtil::RemoveChromeDesktopShortcutsWithAppendedNames(
+ const std::vector<std::wstring>& appended_names) {
+ FilePath shortcut_path;
+ bool ret = true;
+ if (ShellUtil::GetDesktopPath(false, &shortcut_path)) {
+ for (std::vector<std::wstring>::const_iterator it =
+ appended_names.begin();
+ it != appended_names.end();
+ ++it) {
+ FilePath delete_shortcut = shortcut_path.Append(*it);
+ ret = ret && file_util::Delete(delete_shortcut, false);
+ }
+ } else {
+ ret = false;
+ }
+ return ret;
+}
+
bool ShellUtil::RemoveChromeQuickLaunchShortcut(BrowserDistribution* dist,
int shell_change) {
std::wstring shortcut_name;
- if (!ShellUtil::GetChromeShortcutName(dist, &shortcut_name, false))
+ if (!ShellUtil::GetChromeShortcutName(dist, false, L"", &shortcut_name))
return false;
bool ret = true;
@@ -1015,6 +1050,7 @@ bool ShellUtil::RemoveChromeQuickLaunchShortcut(BrowserDistribution* dist,
bool ShellUtil::UpdateChromeShortcut(BrowserDistribution* dist,
const std::wstring& chrome_exe,
const std::wstring& shortcut,
+ const std::wstring& arguments,
const std::wstring& description,
bool create_new) {
std::wstring chrome_path = FilePath(chrome_exe).DirName().value();
@@ -1030,7 +1066,7 @@ bool ShellUtil::UpdateChromeShortcut(BrowserDistribution* dist,
chrome_exe.c_str(), // target
shortcut.c_str(), // shortcut
chrome_path.c_str(), // working dir
- NULL, // arguments
+ arguments.c_str(), // arguments
description.c_str(), // description
chrome_exe.c_str(), // icon file
icon_index, // icon index
@@ -1040,7 +1076,7 @@ bool ShellUtil::UpdateChromeShortcut(BrowserDistribution* dist,
chrome_exe.c_str(), // target
shortcut.c_str(), // shortcut
chrome_path.c_str(), // working dir
- NULL, // arguments
+ arguments.c_str(), // arguments
description.c_str(), // description
chrome_exe.c_str(), // icon file
icon_index, // icon index
diff --git a/chrome/installer/util/shell_util.h b/chrome/installer/util/shell_util.h
index fcb0fb8..9b0524a 100644
--- a/chrome/installer/util/shell_util.h
+++ b/chrome/installer/util/shell_util.h
@@ -20,6 +20,10 @@
class BrowserDistribution;
class FilePath;
+namespace base {
+class DictionaryValue;
+}
+
// This is a utility class that provides common shell integration methods
// that can be used by installer as well as Chrome.
class ShellUtil {
@@ -87,18 +91,26 @@ class ShellUtil {
static bool AdminNeededForRegistryCleanup(BrowserDistribution* dist,
const std::wstring& suffix);
- // Create Chrome shortcut on Desktop
- // If shell_change is CURRENT_USER, the shortcut is created in the
- // Desktop folder of current user's profile.
- // If shell_change is SYSTEM_LEVEL, the shortcut is created in the
- // Desktop folder of "All Users" profile.
- // If alternate is true, an alternate text for the shortcut is used.
- // create_new: If false, will only update the shortcut. If true, the function
- // will create a new shortcut if it doesn't exist already.
+ // Creates Chrome shortcut on the Desktop.
+ // |dist| gives the type of browser distribution currently in use.
+ // |chrome_exe| provides the target path information.
+ // |description| provides the shortcut's "comment" property.
+ // |appended_name| provides a string to be appended to the distribution name,
+ // and can be the empty string.
+ // |arguments| gives a set of arguments to be passed to the executable.
+ // If |shell_change| is CURRENT_USER, the shortcut is created in the
+ // Desktop folder of current user's profile.
+ // If |shell_change| is SYSTEM_LEVEL, the shortcut is created in the
+ // Desktop folder of the "All Users" profile.
+ // If |alternate| is true, an alternate text for the shortcut is used.
+ // If |create_new| is false, an existing shortcut will be updated, but if
+ // no shortcut exists, it will not be created.
// Returns true iff the method causes a shortcut to be created / updated.
static bool CreateChromeDesktopShortcut(BrowserDistribution* dist,
const std::wstring& chrome_exe,
const std::wstring& description,
+ const std::wstring& appended_name,
+ const std::wstring& arguments,
ShellChange shell_change,
bool alternate,
bool create_new);
@@ -129,11 +141,14 @@ class ShellUtil {
// chrome_exe: the full path to chrome.exe
static std::wstring GetChromeShellOpenCmd(const std::wstring& chrome_exe);
- // Returns the localized name of Chrome shortcut. If |alternate| is true
- // it returns a second localized text that is better suited for certain
- // scenarios.
+ // Returns the localized name of Chrome shortcut in |shortcut|. If
+ // |appended_name| is not empty, it is included in the shortcut name. If
+ // |alternate| is true, a second localized text that is better suited for
+ // certain scenarios is used.
static bool GetChromeShortcutName(BrowserDistribution* dist,
- std::wstring* shortcut, bool alternate);
+ bool alternate,
+ const std::wstring& appended_name,
+ std::wstring* shortcut);
// Gets the desktop path for the current user or all users (if system_level
// is true) and returns it in 'path' argument. Return true if successful,
@@ -250,7 +265,14 @@ class ShellUtil {
// If alternate is true, the shortcut with the alternate name is removed. See
// CreateChromeDesktopShortcut() for more information.
static bool RemoveChromeDesktopShortcut(BrowserDistribution* dist,
- int shell_change, bool alternate);
+ int shell_change,
+ bool alternate);
+
+ // Removes a set of existing Chrome desktop shortcuts. |appended_names| is a
+ // list of shortcut file names as obtained from
+ // ShellUtil::GetChromeShortcutName.
+ static bool RemoveChromeDesktopShortcutsWithAppendedNames(
+ const std::vector<std::wstring>& appended_names);
// Remove Chrome shortcut from Quick Launch Bar.
// If shell_change is CURRENT_USER, the shortcut is removed from
@@ -261,13 +283,14 @@ class ShellUtil {
int shell_change);
// Updates shortcut (or creates a new shortcut) at destination given by
- // shortcut to a target given by chrome_exe. The arguments is left NULL
- // for the target and icon is set as icon at index 0 from exe.
+ // shortcut to a target given by chrome_exe. The arguments are given by
+ // |arguments| for the target and icon is set as icon at index 0 from exe.
// If create_new is set to true, the function will create a new shortcut if
// if doesn't exist.
static bool UpdateChromeShortcut(BrowserDistribution* dist,
const std::wstring& chrome_exe,
const std::wstring& shortcut,
+ const std::wstring& arguments,
const std::wstring& description,
bool create_new);
diff --git a/chrome/installer/util/shell_util_unittest.cc b/chrome/installer/util/shell_util_unittest.cc
index f6d3dd1..625010e 100644
--- a/chrome/installer/util/shell_util_unittest.cc
+++ b/chrome/installer/util/shell_util_unittest.cc
@@ -109,9 +109,12 @@ TEST_F(ShellUtilTest, UpdateChromeShortcutTest) {
FilePath shortcut_path = temp_dir_.path().AppendASCII("shortcut.lnk");
const std::wstring description(L"dummy description");
- EXPECT_TRUE(ShellUtil::UpdateChromeShortcut(dist, exe_path.value(),
+ EXPECT_TRUE(ShellUtil::UpdateChromeShortcut(dist,
+ exe_path.value(),
shortcut_path.value(),
- description, true));
+ L"",
+ description,
+ true));
EXPECT_TRUE(VerifyChromeShortcut(exe_path.value(),
shortcut_path.value(),
description, 0));
@@ -130,9 +133,12 @@ TEST_F(ShellUtilTest, UpdateChromeShortcutTest) {
"}";
file.close();
ASSERT_TRUE(file_util::Delete(shortcut_path, false));
- EXPECT_TRUE(ShellUtil::UpdateChromeShortcut(dist, exe_path.value(),
+ EXPECT_TRUE(ShellUtil::UpdateChromeShortcut(dist,
+ exe_path.value(),
shortcut_path.value(),
- description, true));
+ L"",
+ description,
+ true));
EXPECT_TRUE(VerifyChromeShortcut(exe_path.value(),
shortcut_path.value(),
description, 1));
@@ -140,9 +146,12 @@ TEST_F(ShellUtilTest, UpdateChromeShortcutTest) {
// Now change only description to update shortcut and make sure icon index
// doesn't change.
const std::wstring description2(L"dummy description 2");
- EXPECT_TRUE(ShellUtil::UpdateChromeShortcut(dist, exe_path.value(),
+ EXPECT_TRUE(ShellUtil::UpdateChromeShortcut(dist,
+ exe_path.value(),
shortcut_path.value(),
- description2, false));
+ L"",
+ description2,
+ false));
EXPECT_TRUE(VerifyChromeShortcut(exe_path.value(),
shortcut_path.value(),
description2, 1));
@@ -173,15 +182,34 @@ TEST_F(ShellUtilTest, CreateChromeDesktopShortcutTest) {
EXPECT_TRUE(ShellUtil::GetDesktopPath(true, &system_desktop_path));
std::wstring shortcut_name;
- EXPECT_TRUE(ShellUtil::GetChromeShortcutName(dist, &shortcut_name, false));
+ EXPECT_TRUE(ShellUtil::GetChromeShortcutName(dist, false, L"",
+ &shortcut_name));
+
+ std::wstring default_profile_shortcut_name;
+ const std::wstring default_profile_user_name = L"Minsk";
+ EXPECT_TRUE(ShellUtil::GetChromeShortcutName(dist, false,
+ default_profile_user_name,
+ &default_profile_shortcut_name));
+
+ std::wstring second_profile_shortcut_name;
+ const std::wstring second_profile_user_name = L"Pinsk";
+ EXPECT_TRUE(ShellUtil::GetChromeShortcutName(dist, false,
+ second_profile_user_name,
+ &second_profile_shortcut_name));
FilePath user_shortcut_path = user_desktop_path.Append(shortcut_name);
FilePath system_shortcut_path = system_desktop_path.Append(shortcut_name);
+ FilePath default_profile_shortcut_path = user_desktop_path.Append(
+ default_profile_shortcut_name);
+ FilePath second_profile_shortcut_path = user_desktop_path.Append(
+ second_profile_shortcut_name);
// Test simple creation of a user-level shortcut.
EXPECT_TRUE(ShellUtil::CreateChromeDesktopShortcut(dist,
exe_path.value(),
description,
+ L"",
+ L"",
ShellUtil::CURRENT_USER,
false,
true));
@@ -197,6 +225,8 @@ TEST_F(ShellUtilTest, CreateChromeDesktopShortcutTest) {
EXPECT_TRUE(ShellUtil::CreateChromeDesktopShortcut(dist,
exe_path.value(),
description,
+ L"",
+ L"",
ShellUtil::SYSTEM_LEVEL,
false,
true));
@@ -213,12 +243,16 @@ TEST_F(ShellUtilTest, CreateChromeDesktopShortcutTest) {
EXPECT_TRUE(ShellUtil::CreateChromeDesktopShortcut(dist,
exe_path.value(),
description,
+ L"",
+ L"",
ShellUtil::SYSTEM_LEVEL,
false,
true));
EXPECT_FALSE(ShellUtil::CreateChromeDesktopShortcut(dist,
exe_path.value(),
description,
+ L"",
+ L"",
ShellUtil::CURRENT_USER,
false,
true));
@@ -236,12 +270,16 @@ TEST_F(ShellUtilTest, CreateChromeDesktopShortcutTest) {
EXPECT_TRUE(ShellUtil::CreateChromeDesktopShortcut(dist,
exe_path.value(),
description,
+ L"",
+ L"",
ShellUtil::CURRENT_USER,
false,
true));
EXPECT_TRUE(ShellUtil::CreateChromeDesktopShortcut(dist,
exe_path.value(),
description,
+ L"",
+ L"",
ShellUtil::SYSTEM_LEVEL,
false,
true));
@@ -259,4 +297,38 @@ TEST_F(ShellUtilTest, CreateChromeDesktopShortcutTest) {
EXPECT_TRUE(ShellUtil::RemoveChromeDesktopShortcut(dist,
ShellUtil::SYSTEM_LEVEL,
false));
+
+ // Test creation of two profile-specific shortcuts (these are always
+ // user-level).
+ EXPECT_TRUE(ShellUtil::CreateChromeDesktopShortcut(
+ dist,
+ exe_path.value(),
+ description,
+ default_profile_user_name,
+ L"--profile-directory=\"Default\"",
+ ShellUtil::CURRENT_USER,
+ false,
+ true));
+ EXPECT_TRUE(VerifyChromeShortcut(exe_path.value(),
+ default_profile_shortcut_path.value(),
+ description,
+ 0));
+ EXPECT_TRUE(ShellUtil::CreateChromeDesktopShortcut(
+ dist,
+ exe_path.value(),
+ description,
+ second_profile_user_name,
+ L"--profile-directory=\"Profile 1\"",
+ ShellUtil::CURRENT_USER,
+ false,
+ true));
+ EXPECT_TRUE(VerifyChromeShortcut(exe_path.value(),
+ second_profile_shortcut_path.value(),
+ description,
+ 0));
+ std::vector<string16> profile_names;
+ profile_names.push_back(default_profile_shortcut_name);
+ profile_names.push_back(second_profile_shortcut_name);
+ EXPECT_TRUE(ShellUtil::RemoveChromeDesktopShortcutsWithAppendedNames(
+ profile_names));
}