summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/browser_main.cc6
-rw-r--r--chrome/browser/prefs/browser_prefs.cc2
-rw-r--r--chrome/browser/profiles/profile.cc5
-rw-r--r--chrome/browser/profiles/profile.h4
-rw-r--r--chrome/browser/profiles/profile_impl.cc10
-rw-r--r--chrome/browser/profiles/profile_impl.h1
-rw-r--r--chrome/browser/profiles/profile_manager.cc106
-rw-r--r--chrome/browser/profiles/profile_manager.h38
-rw-r--r--chrome/browser/profiles/profile_manager_unittest.cc25
-rw-r--r--chrome/browser/sync/profile_sync_service.h1
-rw-r--r--chrome/browser/ui/browser.cc10
-rw-r--r--chrome/browser/ui/browser.h6
-rw-r--r--chrome/browser/ui/views/profile_menu_model.cc15
-rw-r--r--chrome/browser/ui/views/profile_menu_model.h4
-rw-r--r--chrome/common/chrome_constants.cc1
-rw-r--r--chrome/common/chrome_constants.h1
-rw-r--r--chrome/common/pref_names.cc10
-rw-r--r--chrome/common/pref_names.h4
-rw-r--r--chrome/test/testing_profile.cc4
-rw-r--r--chrome/test/testing_profile.h1
20 files changed, 245 insertions, 9 deletions
diff --git a/chrome/browser/browser_main.cc b/chrome/browser/browser_main.cc
index a4fd01e..ef17b57 100644
--- a/chrome/browser/browser_main.cc
+++ b/chrome/browser/browser_main.cc
@@ -806,8 +806,10 @@ MetricsService* InitializeMetrics(const CommandLine& parsed_command_line,
// should not continue.
Profile* CreateProfile(const MainFunctionParams& parameters,
const FilePath& user_data_dir) {
- Profile* profile = g_browser_process->profile_manager()->GetDefaultProfile(
- user_data_dir);
+ const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
+ Profile* profile = browser_command_line.HasSwitch(switches::kMultiProfiles) ?
+ g_browser_process->profile_manager()->GetLastUsedProfile(user_data_dir) :
+ g_browser_process->profile_manager()->GetDefaultProfile(user_data_dir);
if (profile)
return profile;
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc
index 2dd4dcb..2df2b2e4 100644
--- a/chrome/browser/prefs/browser_prefs.cc
+++ b/chrome/browser/prefs/browser_prefs.cc
@@ -38,6 +38,7 @@
#include "chrome/browser/prefs/session_startup_pref.h"
#include "chrome/browser/printing/print_job_manager.h"
#include "chrome/browser/profiles/profile_impl.h"
+#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/renderer_host/web_cache_manager.h"
#include "chrome/browser/safe_browsing/safe_browsing_service.h"
#include "chrome/browser/search_engines/template_url_model.h"
@@ -109,6 +110,7 @@ void RegisterLocalState(PrefService* local_state) {
NotificationUIManager::RegisterPrefs(local_state);
PrefProxyConfigService::RegisterPrefs(local_state);
policy::CloudPolicySubsystem::RegisterPrefs(local_state);
+ ProfileManager::RegisterPrefs(local_state);
#if defined(OS_CHROMEOS)
chromeos::AudioMixerAlsa::RegisterPrefs(local_state);
chromeos::UserManager::RegisterPrefs(local_state);
diff --git a/chrome/browser/profiles/profile.cc b/chrome/browser/profiles/profile.cc
index 0b0f2e1..e7ff3f3 100644
--- a/chrome/browser/profiles/profile.cc
+++ b/chrome/browser/profiles/profile.cc
@@ -210,6 +210,11 @@ class OffTheRecordProfileImpl : public Profile,
return reinterpret_cast<ProfileId>(this);
}
+ virtual std::string GetProfileName() {
+ // Incognito profile should not return the profile name.
+ return std::string();
+ }
+
virtual FilePath GetPath() { return profile_->GetPath(); }
virtual bool IsOffTheRecord() {
diff --git a/chrome/browser/profiles/profile.h b/chrome/browser/profiles/profile.h
index bbc6658..a3b2a6e 100644
--- a/chrome/browser/profiles/profile.h
+++ b/chrome/browser/profiles/profile.h
@@ -165,6 +165,10 @@ class Profile {
// NOTIFY_DEFAULT_REQUEST_CONTEXT_AVAILABLE.
static net::URLRequestContextGetter* GetDefaultRequestContext();
+ // Returns the name associated with this profile. This name is displayed in
+ // the browser frame.
+ virtual std::string GetProfileName() = 0;
+
// Returns a unique Id that can be used to identify this profile at runtime.
// This Id is not persistent and will not survive a restart of the browser.
virtual ProfileId GetRuntimeId() = 0;
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc
index 92e7630..8cd12c6 100644
--- a/chrome/browser/profiles/profile_impl.cc
+++ b/chrome/browser/profiles/profile_impl.cc
@@ -246,7 +246,7 @@ Profile* Profile::CreateProfile(const FilePath& path) {
Profile* Profile::CreateProfileAsync(const FilePath&path,
Profile::Delegate* delegate) {
DCHECK(delegate);
- // This is safe while all file opeartions are done on the FILE thread.
+ // This is safe while all file operations are done on the FILE thread.
BrowserThread::PostTask(BrowserThread::FILE,
FROM_HERE,
NewRunnableFunction(&file_util::CreateDirectory,
@@ -311,6 +311,7 @@ void ProfileImpl::DoFinalInit() {
pref_change_registrar_.Add(prefs::kEnableSpellCheck, this);
pref_change_registrar_.Add(prefs::kEnableAutoSpellCorrect, this);
pref_change_registrar_.Add(prefs::kClearSiteDataOnExit, this);
+ pref_change_registrar_.Add(prefs::kGoogleServicesUsername, this);
// It would be nice to use PathService for fetching this directory, but
// the cache directory depends on the profile directory, which isn't available
@@ -661,6 +662,10 @@ ProfileImpl::~ProfileImpl() {
MarkAsCleanShutdown();
}
+std::string ProfileImpl::GetProfileName() {
+ return GetPrefs()->GetString(prefs::kGoogleServicesUsername);
+}
+
ProfileId ProfileImpl::GetRuntimeId() {
return reinterpret_cast<ProfileId>(this);
}
@@ -1346,6 +1351,9 @@ void ProfileImpl::Observe(NotificationType type,
appcache_service_->SetClearLocalStateOnExit(
clear_local_state_on_exit_);
}
+ } else if (*pref_name_in == prefs::kGoogleServicesUsername) {
+ ProfileManager* profile_manager = g_browser_process->profile_manager();
+ profile_manager->RegisterProfileName(this);
}
} else if (NotificationType::BOOKMARK_MODEL_LOADED == type) {
GetProfileSyncService(); // Causes lazy-load if sync is enabled.
diff --git a/chrome/browser/profiles/profile_impl.h b/chrome/browser/profiles/profile_impl.h
index 0119610..00e30fe 100644
--- a/chrome/browser/profiles/profile_impl.h
+++ b/chrome/browser/profiles/profile_impl.h
@@ -44,6 +44,7 @@ class ProfileImpl : public Profile,
static void RegisterUserPrefs(PrefService* prefs);
// Profile implementation.
+ virtual std::string GetProfileName();
virtual ProfileId GetRuntimeId();
virtual FilePath GetPath();
virtual bool IsOffTheRecord();
diff --git a/chrome/browser/profiles/profile_manager.cc b/chrome/browser/profiles/profile_manager.cc
index 94af544..7011e8e 100644
--- a/chrome/browser/profiles/profile_manager.cc
+++ b/chrome/browser/profiles/profile_manager.cc
@@ -7,16 +7,22 @@
#include "chrome/browser/profiles/profile_manager.h"
#include "base/command_line.h"
+#include "base/file_path.h"
#include "base/file_util.h"
#include "base/path_service.h"
+#include "base/string_number_conversions.h"
#include "base/string_util.h"
+#include "base/utf_string_conversions.h"
#include "chrome/browser/browser_process.h"
-#include "chrome/browser/ui/browser_list.h"
+#include "chrome/browser/prefs/pref_service.h"
+#include "chrome/browser/prefs/scoped_user_pref_update.h"
+#include "chrome/browser/sync/profile_sync_service.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/logging_chrome.h"
+#include "chrome/common/pref_names.h"
#include "content/browser/browser_thread.h"
#include "content/common/notification_service.h"
#include "content/common/notification_type.h"
@@ -63,6 +69,23 @@ void ResumeRequestContext(
} // namespace
+// The NewProfileLauncher class is created when to wait for a multi-profile
+// to be created asynchronously. Upon completion of profile creation, the
+// NPL takes care of launching a new browser window and signing the user
+// in to their Google account.
+class NewProfileLauncher : public ProfileManager::Observer {
+ public:
+ virtual void OnProfileCreated(Profile* profile) {
+ Browser::NewWindowWithProfile(profile);
+ ProfileSyncService* service = profile->GetProfileSyncService();
+ DCHECK(service);
+ service->ShowLoginDialog(NULL);
+ ProfileSyncService::SyncEvent(ProfileSyncService::START_FROM_PROFILE_MENU);
+ }
+
+ virtual bool DeleteAfterCreation() OVERRIDE { return true; }
+};
+
// static
void ProfileManager::ShutdownSessionServices() {
ProfileManager* pm = g_browser_process->profile_manager();
@@ -83,6 +106,7 @@ Profile* ProfileManager::GetDefaultProfile() {
ProfileManager::ProfileManager() : logged_in_(false) {
ui::SystemMonitor::Get()->AddObserver(this);
+ BrowserList::AddObserver(this);
#if defined(OS_CHROMEOS)
registrar_.Add(
this,
@@ -95,6 +119,7 @@ ProfileManager::~ProfileManager() {
ui::SystemMonitor* system_monitor = ui::SystemMonitor::Get();
if (system_monitor)
system_monitor->RemoveObserver(this);
+ BrowserList::RemoveObserver(this);
}
FilePath ProfileManager::GetDefaultProfileDir(
@@ -130,11 +155,38 @@ FilePath ProfileManager::GetCurrentProfileDir() {
return relative_profile_dir;
}
#endif
+ // TODO(mirandac): should not automatically be default profile.
relative_profile_dir =
relative_profile_dir.AppendASCII(chrome::kNotSignedInProfile);
return relative_profile_dir;
}
+Profile* ProfileManager::GetLastUsedProfile(const FilePath& user_data_dir) {
+ FilePath last_used_profile_dir(user_data_dir);
+ std::string last_profile_used;
+ PrefService* local_state = g_browser_process->local_state();
+ DCHECK(local_state);
+
+ if (local_state->HasPrefPath(prefs::kProfileLastUsed))
+ last_profile_used = local_state->GetString(prefs::kProfileLastUsed);
+ last_used_profile_dir = last_profile_used.empty() ?
+ last_used_profile_dir.AppendASCII(chrome::kNotSignedInProfile) :
+ last_used_profile_dir.AppendASCII(last_profile_used);
+ return GetProfile(last_used_profile_dir);
+}
+
+void ProfileManager::RegisterProfileName(Profile* profile) {
+ std::string profile_name = profile->GetProfileName();
+ std::string dir_base = profile->GetPath().BaseName().MaybeAsASCII();
+ DictionaryPrefUpdate update(g_browser_process->local_state(),
+ prefs::kProfileDirectoryMap);
+ DictionaryValue* path_map = update.Get();
+ // We don't check for duplicates because we should be able to overwrite
+ // path->name mappings here, if the user syncs a local account to a
+ // different Google account.
+ path_map->SetString(dir_base, profile_name);
+}
+
Profile* ProfileManager::GetDefaultProfile(const FilePath& user_data_dir) {
FilePath default_profile_dir(user_data_dir);
default_profile_dir = default_profile_dir.Append(GetCurrentProfileDir());
@@ -250,6 +302,7 @@ void ProfileManager::CreateDefaultProfileAsync(Observer* observer) {
FilePath default_profile_dir;
PathService::Get(chrome::DIR_USER_DATA, &default_profile_dir);
+ // TODO(mirandac): current directory will not always be default in the future
default_profile_dir = default_profile_dir.Append(
profile_manager->GetCurrentProfileDir());
@@ -352,6 +405,18 @@ void ProfileManager::Observe(
#endif
}
+void ProfileManager::OnBrowserAdded(const Browser* browser) {}
+
+void ProfileManager::OnBrowserRemoved(const Browser* browser) {}
+
+void ProfileManager::OnBrowserSetLastActive(const Browser* browser) {
+ Profile* last_active = browser->GetProfile();
+ PrefService* local_state = g_browser_process->local_state();
+ DCHECK(local_state);
+ local_state->SetString(prefs::kProfileLastUsed,
+ last_active->GetPath().BaseName().MaybeAsASCII());
+}
+
void ProfileManager::DoFinalInit(Profile* profile) {
const CommandLine& command_line = *CommandLine::ForCurrentProcess();
bool init_extensions = true;
@@ -394,7 +459,46 @@ void ProfileManager::OnProfileCreated(Profile* profile, bool success) {
profiles_info_.erase(iter);
}
+ std::vector<Observer*> observers_to_delete;
+
for (size_t i = 0; i < observers.size(); ++i) {
observers[i]->OnProfileCreated(profile);
+ if (observers[i]->DeleteAfterCreation())
+ observers_to_delete.push_back(observers[i]);
}
+
+ observers_to_delete.clear();
+}
+
+// static
+void ProfileManager::CreateMultiProfileAsync() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ // Create the next profile in the next available directory slot.
+ PrefService* local_state = g_browser_process->local_state();
+ DCHECK(local_state);
+
+ int next_directory = local_state->GetInteger(prefs::kProfilesNumCreated);
+ std::string profile_name = chrome::kMultiProfileDirPrefix;
+ profile_name.append(base::IntToString(next_directory));
+ FilePath new_path;
+ PathService::Get(chrome::DIR_USER_DATA, &new_path);
+#if defined(OS_WIN)
+ new_path = new_path.Append(ASCIIToUTF16(profile_name));
+#else
+ new_path = new_path.Append(profile_name);
+#endif
+ local_state->SetInteger(prefs::kProfilesNumCreated, ++next_directory);
+
+ ProfileManager* profile_manager = g_browser_process->profile_manager();
+ // The launcher is deleted by the manager when profile creation is finished.
+ NewProfileLauncher* launcher = new NewProfileLauncher();
+ profile_manager->CreateProfileAsync(new_path, launcher);
+}
+
+// static
+void ProfileManager::RegisterPrefs(PrefService* prefs) {
+ prefs->RegisterStringPref(prefs::kProfileLastUsed, "");
+ prefs->RegisterDictionaryPref(prefs::kProfileDirectoryMap);
+ prefs->RegisterIntegerPref(prefs::kProfilesNumCreated, 1);
}
diff --git a/chrome/browser/profiles/profile_manager.h b/chrome/browser/profiles/profile_manager.h
index 9af8f2b..98190b11 100644
--- a/chrome/browser/profiles/profile_manager.h
+++ b/chrome/browser/profiles/profile_manager.h
@@ -8,6 +8,7 @@
#define CHROME_BROWSER_PROFILES_PROFILE_MANAGER_H_
#pragma once
+#include <list>
#include <vector>
#include "base/basictypes.h"
@@ -18,22 +19,29 @@
#include "base/message_loop.h"
#include "base/threading/non_thread_safe.h"
#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/browser_list.h"
#include "content/common/notification_observer.h"
#include "content/common/notification_registrar.h"
#include "ui/base/system_monitor/system_monitor.h"
class FilePath;
+class NewProfileLauncher;
class ProfileManager : public base::NonThreadSafe,
public ui::SystemMonitor::PowerObserver,
+ public BrowserList::Observer,
public NotificationObserver,
public Profile::Delegate {
public:
class Observer {
public:
- // This method is called when profile is ready. If profile creation has been
- // failed, method is called with |profile| equals to NULL.
+ // This method is called when profile is ready. If profile creation has
+ // failed, method is called with |profile| equal to NULL.
virtual void OnProfileCreated(Profile* profile) = 0;
+
+ // If true, delete the observer after the profile has been created. Default
+ // is false.
+ virtual bool DeleteAfterCreation() { return false; }
};
ProfileManager();
@@ -78,6 +86,13 @@ class ProfileManager : public base::NonThreadSafe,
// stored, relative to the user data directory currently in use..
FilePath GetCurrentProfileDir();
+ // Get the Profile last used with this Chrome build. If no signed profile has
+ // been stored in Local State, hand back the Default profile.
+ Profile* GetLastUsedProfile(const FilePath& user_data_dir);
+
+ // Register the mapping of a directory to a profile name in Local State.
+ void RegisterProfileName(Profile* profile);
+
// Returns created profiles. Note, profiles order is NOT guaranteed to be
// related with the creation order.
std::vector<Profile*> GetLoadedProfiles() const;
@@ -91,6 +106,11 @@ class ProfileManager : public base::NonThreadSafe,
const NotificationSource& source,
const NotificationDetails& details);
+ // BrowserList::Observer implementation.
+ virtual void OnBrowserAdded(const Browser* browser);
+ virtual void OnBrowserRemoved(const Browser* browser);
+ virtual void OnBrowserSetLastActive(const Browser* browser);
+
// ------------------ static utility functions -------------------
// Returns the path to the default profile directory, based on the given
@@ -108,6 +128,20 @@ class ProfileManager : public base::NonThreadSafe,
// Profile::Delegate implementation:
virtual void OnProfileCreated(Profile* profile, bool success);
+ // Add or remove a profile launcher to/from the list of launchers waiting for
+ // new profiles to be created from the multi-profile menu.
+ void AddProfileLauncher(NewProfileLauncher* profile_launcher);
+ void RemoveProfileLauncher(NewProfileLauncher* profile_launcher);
+
+ // Creates a new profile in the next available multiprofile directory.
+ // Directories are named "profile_1", "profile_2", etc., in sequence of
+ // creation. (Because directories can be removed, however, it may be the case
+ // that at some point the list of numbered profiles is not continuous.)
+ static void CreateMultiProfileAsync();
+
+ // Register multi-profile related preferences in Local State.
+ static void RegisterPrefs(PrefService* prefs);
+
protected:
// Does final initial actions.
virtual void DoFinalInit(Profile* profile);
diff --git a/chrome/browser/profiles/profile_manager_unittest.cc b/chrome/browser/profiles/profile_manager_unittest.cc
index 4a4a4b8..97fffcf 100644
--- a/chrome/browser/profiles/profile_manager_unittest.cc
+++ b/chrome/browser/profiles/profile_manager_unittest.cc
@@ -8,12 +8,14 @@
#include "base/memory/scoped_temp_dir.h"
#include "base/message_loop.h"
#include "base/path_service.h"
+#include "base/values.h"
#include "chrome/browser/prefs/browser_prefs.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
+#include "chrome/common/pref_names.h"
#include "chrome/test/testing_browser_process_test.h"
#include "chrome/test/testing_pref_service.h"
#include "content/browser/browser_thread.h"
@@ -119,6 +121,29 @@ TEST_F(ProfileManagerTest, LoggedInProfileDir) {
#endif
+TEST_F(ProfileManagerTest, RegisterProfileName) {
+ // Create a test profile.
+ FilePath dest_path1 = temp_dir_.path();
+ std::string dir_base("New Profile 1");
+ dest_path1 = dest_path1.Append(FILE_PATH_LITERAL("New Profile 1"));
+ Profile* profile1;
+ profile1 = profile_manager_->GetProfile(dest_path1);
+ ASSERT_TRUE(profile1);
+
+ // Simulate registration of the profile name (normally triggered by the
+ // change of the kGoogleServicesUsername preference):
+ std::string testname("testname");
+ profile1->GetPrefs()->SetString(prefs::kGoogleServicesUsername, testname);
+ profile_manager_->RegisterProfileName(profile1);
+
+ // Profile name should be associated with the directory in Local State.
+ std::string stored_profile_name;
+ const DictionaryValue* path_map = static_cast<const DictionaryValue*>(
+ local_state_.Get()->GetUserPref(prefs::kProfileDirectoryMap));
+ path_map->GetString(dir_base, &stored_profile_name);
+ ASSERT_STREQ(testname.c_str(), stored_profile_name.c_str());
+}
+
TEST_F(ProfileManagerTest, CreateAndUseTwoProfiles) {
FilePath dest_path1 = temp_dir_.path();
dest_path1 = dest_path1.Append(FILE_PATH_LITERAL("New Profile 1"));
diff --git a/chrome/browser/sync/profile_sync_service.h b/chrome/browser/sync/profile_sync_service.h
index 7b0d905..05aa410 100644
--- a/chrome/browser/sync/profile_sync_service.h
+++ b/chrome/browser/sync/profile_sync_service.h
@@ -112,6 +112,7 @@ class ProfileSyncService : public browser_sync::SyncFrontend,
START_FROM_WRENCH = 2, // Sync was started from the Wrench menu.
START_FROM_OPTIONS = 3, // Sync was started from Wrench->Options.
START_FROM_BOOKMARK_MANAGER = 4, // Sync was started from Bookmark manager.
+ START_FROM_PROFILE_MENU = 5, // Sync was started from multiprofile menu.
// Events regarding cancellation of the signon process of sync.
CANCEL_FROM_SIGNON_WITHOUT_AUTH = 10, // Cancelled before submitting
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc
index 20bea8e..a1257a5 100644
--- a/chrome/browser/ui/browser.cc
+++ b/chrome/browser/ui/browser.cc
@@ -752,6 +752,16 @@ void Browser::OpenExtensionsWindow(Profile* profile) {
browser->window()->Show();
}
+// static
+void Browser::NewWindowWithProfile(Profile* profile) {
+ UserMetrics::RecordAction(UserMetricsAction("NewWindow"), profile);
+ SessionService* session_service =
+ profile->GetOriginalProfile()->GetSessionService();
+ if (!session_service ||
+ !session_service->RestoreIfNecessary(std::vector<GURL>())) {
+ Browser::OpenEmptyWindow(profile->GetOriginalProfile());
+ }
+}
///////////////////////////////////////////////////////////////////////////////
// Browser, State Storage and Retrieval for UI:
diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h
index 5155909..6288a2e 100644
--- a/chrome/browser/ui/browser.h
+++ b/chrome/browser/ui/browser.h
@@ -292,6 +292,12 @@ class Browser : public TabHandlerDelegate,
// extensions which may run with no windows open.
static void OpenExtensionsWindow(Profile* profile);
+ // Opens a new window with the given profile. This starts the session_service
+ // for the new profile as well; it is the static equivalent of the instance
+ // method Browser::NewWindow(), used for the creation of a Window from the
+ // multi-profile dropdown menu.
+ static void NewWindowWithProfile(Profile* profile);
+
// State Storage and Retrieval for UI ///////////////////////////////////////
// Save and restore the window position.
diff --git a/chrome/browser/ui/views/profile_menu_model.cc b/chrome/browser/ui/views/profile_menu_model.cc
index da2021a..8c29c3a 100644
--- a/chrome/browser/ui/views/profile_menu_model.cc
+++ b/chrome/browser/ui/views/profile_menu_model.cc
@@ -4,6 +4,8 @@
#include "chrome/browser/ui/views/profile_menu_model.h"
+#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/sync/profile_sync_service.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/models/accelerator.h"
@@ -14,7 +16,7 @@ namespace views {
ProfileMenuModel::ProfileMenuModel()
: ALLOW_THIS_IN_INITIALIZER_LIST(ui::SimpleMenuModel(this)) {
- AddItem(0, l10n_util::GetStringUTF16(
+ AddItem(COMMAND_CREATE_NEW_PROFILE, l10n_util::GetStringUTF16(
IDS_PROFILES_CREATE_NEW_PROFILE_OPTION));
menu_.reset(new views::Menu2(this));
}
@@ -31,7 +33,7 @@ bool ProfileMenuModel::IsCommandIdChecked(int command_id) const {
}
bool ProfileMenuModel::IsCommandIdEnabled(int command_id) const {
- return false;
+ return true;
}
bool ProfileMenuModel::GetAcceleratorForCommandId(int command_id,
@@ -40,7 +42,14 @@ bool ProfileMenuModel::GetAcceleratorForCommandId(int command_id,
}
void ProfileMenuModel::ExecuteCommand(int command_id) {
- NOTIMPLEMENTED();
+ switch (command_id) {
+ case COMMAND_CREATE_NEW_PROFILE:
+ ProfileManager::CreateMultiProfileAsync();
+ break;
+ default:
+ NOTIMPLEMENTED();
+ break;
+ }
}
} // namespace views
diff --git a/chrome/browser/ui/views/profile_menu_model.h b/chrome/browser/ui/views/profile_menu_model.h
index 9f2bc74..7ee2203 100644
--- a/chrome/browser/ui/views/profile_menu_model.h
+++ b/chrome/browser/ui/views/profile_menu_model.h
@@ -38,6 +38,10 @@ class ProfileMenuModel : public ui::SimpleMenuModel,
virtual void ExecuteCommand(int command_id);
private:
+ enum {
+ COMMAND_CREATE_NEW_PROFILE,
+ };
+
scoped_ptr<views::Menu2> menu_;
DISALLOW_COPY_AND_ASSIGN(ProfileMenuModel);
diff --git a/chrome/common/chrome_constants.cc b/chrome/common/chrome_constants.cc
index 465a1efe6..6cd9514 100644
--- a/chrome/common/chrome_constants.cc
+++ b/chrome/common/chrome_constants.cc
@@ -70,6 +70,7 @@ const wchar_t kMessageWindowClass[] = L"Chrome_MessageWindow";
const wchar_t kCrashReportLog[] = L"Reported Crashes.txt";
const wchar_t kTestingInterfaceDLL[] = L"testing_interface.dll";
const char kNotSignedInProfile[] = "Default";
+const char kMultiProfileDirPrefix[] = "profile_";
const wchar_t kBrowserResourcesDll[] = L"chrome.dll";
const FilePath::CharType kExtensionFileExtension[] = FPL(".crx");
const FilePath::CharType kExtensionKeyFileExtension[] = FPL(".pem");
diff --git a/chrome/common/chrome_constants.h b/chrome/common/chrome_constants.h
index 4cc992d..e6d8fbe 100644
--- a/chrome/common/chrome_constants.h
+++ b/chrome/common/chrome_constants.h
@@ -31,6 +31,7 @@ extern const wchar_t kMessageWindowClass[];
extern const wchar_t kCrashReportLog[];
extern const wchar_t kTestingInterfaceDLL[];
extern const char kNotSignedInProfile[];
+extern const char kMultiProfileDirPrefix[];
extern const char kStatsFilename[];
extern const wchar_t kBrowserResourcesDll[];
extern const wchar_t kNaClAppName[];
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index f1869af..4c4fbcc 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -704,6 +704,16 @@ const char kEnableReferrers[] = "enable_referrers";
// *************** LOCAL STATE ***************
// These are attached to the machine/installation
+// Directory of the last profile used.
+const char kProfileLastUsed[] = "profile.last_used";
+
+// Maps profile data directories to login names.
+const char kProfileDirectoryMap[] = "profile.directory_map";
+
+// Total number of profiles created for this Chrome build. Used to tag profile
+// directories.
+const char kProfilesNumCreated[] = "profile.profiles_created";
+
// Prefs for SSLConfigServicePref.
const char kCertRevocationCheckingEnabled[] = "ssl.rev_checking.enabled";
const char kSSL3Enabled[] = "ssl.ssl3.enabled";
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index 53da7bb..b1f62e3 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -258,6 +258,10 @@ extern const char kMetricsReportingEnabled[];
extern const char kMetricsInitialLogs[];
extern const char kMetricsOngoingLogs[];
+extern const char kProfileLastUsed[];
+extern const char kProfileDirectoryMap[];
+extern const char kProfilesNumCreated[];
+
extern const char kProfileMetrics[];
extern const char kProfilePrefix[];
diff --git a/chrome/test/testing_profile.cc b/chrome/test/testing_profile.cc
index 560c603..dbfa6c4 100644
--- a/chrome/test/testing_profile.cc
+++ b/chrome/test/testing_profile.cc
@@ -379,6 +379,10 @@ TestingPrefService* TestingProfile::GetTestingPrefService() {
return testing_prefs_;
}
+std::string TestingProfile::GetProfileName() {
+ return std::string("testing_profile");
+}
+
ProfileId TestingProfile::GetRuntimeId() {
return reinterpret_cast<ProfileId>(this);
}
diff --git a/chrome/test/testing_profile.h b/chrome/test/testing_profile.h
index 1543b35..c82e5e3 100644
--- a/chrome/test/testing_profile.h
+++ b/chrome/test/testing_profile.h
@@ -134,6 +134,7 @@ class TestingProfile : public Profile {
TestingPrefService* GetTestingPrefService();
+ virtual std::string GetProfileName();
virtual ProfileId GetRuntimeId();
virtual FilePath GetPath();