1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
6 #include "base/command_line.h"
7 #include "base/prefs/pref_service.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/browser/profiles/profile_info_cache.h"
10 #include "chrome/browser/profiles/profile_info_cache_observer.h"
11 #include "chrome/browser/profiles/profile_manager.h"
12 #include "chrome/browser/profiles/profile_window.h"
13 #include "chrome/browser/profiles/profiles_state.h"
14 #include "chrome/browser/ui/browser_finder.h"
15 #include "chrome/browser/ui/browser_list.h"
16 #include "chrome/browser/ui/browser_window.h"
17 #include "chrome/browser/ui/host_desktop.h"
18 #include "chrome/common/pref_names.h"
19 #include "chrome/test/base/in_process_browser_test.h"
20 #include "chrome/test/base/test_switches.h"
21 #include "chrome/test/base/testing_browser_process.h"
22 #include "chrome/test/base/ui_test_utils.h"
26 const profiles::ProfileSwitchingDoneCallback kOnProfileSwitchDoNothing;
28 // An observer that returns back to test code after a new profile is
30 void OnUnblockOnProfileCreation(Profile* profile,
31 Profile::CreateStatus status) {
32 if (status == Profile::CREATE_STATUS_INITIALIZED)
33 base::MessageLoop::current()->Quit();
36 void ProfileCreationComplete(Profile* profile, Profile::CreateStatus status) {
37 ASSERT_NE(status, Profile::CREATE_STATUS_LOCAL_FAIL);
38 ASSERT_NE(status, Profile::CREATE_STATUS_REMOTE_FAIL);
39 // No browser should have been created for this profile yet.
40 EXPECT_EQ(chrome::GetTotalBrowserCountForProfile(profile), 0U);
41 EXPECT_EQ(chrome::GetTotalBrowserCount(), 1U);
42 if (status == Profile::CREATE_STATUS_INITIALIZED)
43 base::MessageLoop::current()->Quit();
46 void EphemeralProfileCreationComplete(Profile* profile,
47 Profile::CreateStatus status) {
48 if (status == Profile::CREATE_STATUS_INITIALIZED)
49 profile->GetPrefs()->SetBoolean(prefs::kForceEphemeralProfiles, true);
50 ProfileCreationComplete(profile, status);
53 class ProfileRemovalObserver : public ProfileInfoCacheObserver {
55 ProfileRemovalObserver() {
56 g_browser_process->profile_manager()->GetProfileInfoCache().AddObserver(
60 virtual ~ProfileRemovalObserver() {
61 g_browser_process->profile_manager()->GetProfileInfoCache().RemoveObserver(
65 std::string last_used_profile_name() { return last_used_profile_name_; }
67 // ProfileInfoCacheObserver overrides:
68 virtual void OnProfileWillBeRemoved(
69 const base::FilePath& profile_path) OVERRIDE {
70 last_used_profile_name_ = g_browser_process->local_state()->GetString(
71 prefs::kProfileLastUsed);
75 std::string last_used_profile_name_;
77 DISALLOW_COPY_AND_ASSIGN(ProfileRemovalObserver);
82 // This file contains tests for the ProfileManager that require a heavyweight
83 // InProcessBrowserTest. These include tests involving profile deletion.
85 // TODO(jeremy): crbug.com/103355 - These tests should be enabled on all
87 class ProfileManagerBrowserTest : public InProcessBrowserTest {
90 #if defined(OS_MACOSX)
92 // Delete single profile and make sure a new one is created.
93 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, DeleteSingletonProfile) {
94 ProfileManager* profile_manager = g_browser_process->profile_manager();
95 ProfileInfoCache& cache = profile_manager->GetProfileInfoCache();
96 ProfileRemovalObserver observer;
98 // We should start out with 1 profile.
99 ASSERT_EQ(cache.GetNumberOfProfiles(), 1U);
101 // Delete singleton profile.
102 base::FilePath singleton_profile_path = cache.GetPathOfProfileAtIndex(0);
103 EXPECT_FALSE(singleton_profile_path.empty());
104 profile_manager->ScheduleProfileForDeletion(singleton_profile_path,
105 ProfileManager::CreateCallback());
107 // Spin things till profile is actually deleted.
108 content::RunAllPendingInMessageLoop();
110 // Make sure a new profile was created automatically.
111 EXPECT_EQ(cache.GetNumberOfProfiles(), 1U);
112 base::FilePath new_profile_path = cache.GetPathOfProfileAtIndex(0);
113 EXPECT_NE(new_profile_path, singleton_profile_path);
115 // Make sure that last used profile preference is set correctly.
116 Profile* last_used = ProfileManager::GetLastUsedProfile();
117 EXPECT_EQ(new_profile_path, last_used->GetPath());
119 // Make sure the last used profile was set correctly before the notification
121 std::string last_used_profile_name =
122 last_used->GetPath().BaseName().MaybeAsASCII();
123 EXPECT_EQ(last_used_profile_name, observer.last_used_profile_name());
126 // Delete all profiles in a multi profile setup and make sure a new one is
128 // Crashes/CHECKs. See crbug.com/104851
129 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, DISABLED_DeleteAllProfiles) {
130 ProfileManager* profile_manager = g_browser_process->profile_manager();
131 ProfileInfoCache& cache = profile_manager->GetProfileInfoCache();
133 // Create an additional profile.
134 base::FilePath new_path = profile_manager->GenerateNextProfileDirectoryPath();
135 profile_manager->CreateProfileAsync(new_path,
136 base::Bind(&OnUnblockOnProfileCreation),
137 string16(), string16(), std::string());
139 // Spin to allow profile creation to take place, loop is terminated
140 // by OnUnblockOnProfileCreation when the profile is created.
141 content::RunMessageLoop();
143 ASSERT_EQ(cache.GetNumberOfProfiles(), 2U);
145 // Delete all profiles.
146 base::FilePath profile_path1 = cache.GetPathOfProfileAtIndex(0);
147 base::FilePath profile_path2 = cache.GetPathOfProfileAtIndex(1);
148 EXPECT_FALSE(profile_path1.empty());
149 EXPECT_FALSE(profile_path2.empty());
150 profile_manager->ScheduleProfileForDeletion(profile_path1,
151 ProfileManager::CreateCallback());
152 profile_manager->ScheduleProfileForDeletion(profile_path2,
153 ProfileManager::CreateCallback());
155 // Spin things so deletion can take place.
156 content::RunAllPendingInMessageLoop();
158 // Make sure a new profile was created automatically.
159 EXPECT_EQ(cache.GetNumberOfProfiles(), 1U);
160 base::FilePath new_profile_path = cache.GetPathOfProfileAtIndex(0);
161 EXPECT_NE(new_profile_path, profile_path1);
162 EXPECT_NE(new_profile_path, profile_path2);
164 // Make sure that last used profile preference is set correctly.
165 Profile* last_used = ProfileManager::GetLastUsedProfile();
166 EXPECT_EQ(new_profile_path, last_used->GetPath());
170 // Times out (http://crbug.com/159002)
171 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest,
172 DISABLED_CreateProfileWithCallback) {
173 ProfileManager* profile_manager = g_browser_process->profile_manager();
175 ASSERT_EQ(profile_manager->GetNumberOfProfiles(), 1U);
176 EXPECT_EQ(chrome::GetTotalBrowserCount(), 1U);
178 // Create a profile, make sure callback is invoked before any callbacks are
179 // invoked (so they can do things like sign in the profile, etc).
180 ProfileManager::CreateMultiProfileAsync(
182 string16(), // icon url
183 base::Bind(ProfileCreationComplete),
185 // Wait for profile to finish loading.
186 content::RunMessageLoop();
187 EXPECT_EQ(profile_manager->GetNumberOfProfiles(), 2U);
188 EXPECT_EQ(chrome::GetTotalBrowserCount(), 2U);
190 // Now close all browser windows.
191 std::vector<Profile*> profiles = profile_manager->GetLoadedProfiles();
192 for (std::vector<Profile*>::const_iterator it = profiles.begin();
193 it != profiles.end(); ++it) {
194 BrowserList::CloseAllBrowsersWithProfile(*it);
198 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest,
200 #if defined(OS_WIN) && defined(USE_ASH)
201 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
202 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
206 // If multiprofile mode is not enabled, you can't switch between profiles.
207 if (!profiles::IsMultipleProfilesEnabled())
210 ProfileManager* profile_manager = g_browser_process->profile_manager();
211 ProfileInfoCache& cache = profile_manager->GetProfileInfoCache();
212 base::FilePath path_profile1 = cache.GetPathOfProfileAtIndex(0);
214 ASSERT_EQ(profile_manager->GetNumberOfProfiles(), 1U);
215 EXPECT_EQ(chrome::GetTotalBrowserCount(), 1U);
217 // Create an additional profile.
218 base::FilePath path_profile2 =
219 profile_manager->GenerateNextProfileDirectoryPath();
220 profile_manager->CreateProfileAsync(path_profile2,
221 base::Bind(&OnUnblockOnProfileCreation),
222 string16(), string16(), std::string());
224 // Spin to allow profile creation to take place, loop is terminated
225 // by OnUnblockOnProfileCreation when the profile is created.
226 content::RunMessageLoop();
228 chrome::HostDesktopType desktop_type = chrome::GetActiveDesktop();
229 BrowserList* browser_list = BrowserList::GetInstance(desktop_type);
230 ASSERT_EQ(cache.GetNumberOfProfiles(), 2U);
231 EXPECT_EQ(1U, browser_list->size());
233 // Open a browser window for the first profile.
234 profiles::SwitchToProfile(path_profile1, desktop_type, false,
235 kOnProfileSwitchDoNothing);
236 EXPECT_EQ(chrome::GetTotalBrowserCount(), 1U);
237 EXPECT_EQ(1U, browser_list->size());
238 EXPECT_EQ(path_profile1, browser_list->get(0)->profile()->GetPath());
240 // Open a browser window for the second profile.
241 profiles::SwitchToProfile(path_profile2, desktop_type, false,
242 kOnProfileSwitchDoNothing);
243 EXPECT_EQ(chrome::GetTotalBrowserCount(), 2U);
244 EXPECT_EQ(2U, browser_list->size());
245 EXPECT_EQ(path_profile2, browser_list->get(1)->profile()->GetPath());
247 // Switch to the first profile without opening a new window.
248 profiles::SwitchToProfile(path_profile1, desktop_type, false,
249 kOnProfileSwitchDoNothing);
250 EXPECT_EQ(chrome::GetTotalBrowserCount(), 2U);
251 EXPECT_EQ(2U, browser_list->size());
253 EXPECT_EQ(path_profile1, browser_list->get(0)->profile()->GetPath());
254 EXPECT_EQ(path_profile2, browser_list->get(1)->profile()->GetPath());
257 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, EphemeralProfile) {
258 #if defined(OS_WIN) && defined(USE_ASH)
259 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
260 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
264 // If multiprofile mode is not enabled, you can't switch between profiles.
265 if (!profiles::IsMultipleProfilesEnabled())
268 ProfileManager* profile_manager = g_browser_process->profile_manager();
269 ProfileInfoCache& cache = profile_manager->GetProfileInfoCache();
270 base::FilePath path_profile1 = cache.GetPathOfProfileAtIndex(0);
272 ASSERT_EQ(1U, profile_manager->GetNumberOfProfiles());
273 EXPECT_EQ(1U, chrome::GetTotalBrowserCount());
275 // Create an ephemeral profile.
276 base::FilePath path_profile2 =
277 profile_manager->GenerateNextProfileDirectoryPath();
278 profile_manager->CreateProfileAsync(
280 base::Bind(&EphemeralProfileCreationComplete),
281 string16(), string16(), std::string());
283 // Spin to allow profile creation to take place.
284 content::RunMessageLoop();
286 chrome::HostDesktopType desktop_type = chrome::GetActiveDesktop();
287 BrowserList* browser_list = BrowserList::GetInstance(desktop_type);
288 ASSERT_EQ(2U, cache.GetNumberOfProfiles());
289 EXPECT_EQ(1U, browser_list->size());
291 // Open a browser window for the second profile.
292 profiles::SwitchToProfile(path_profile2, desktop_type, false,
293 kOnProfileSwitchDoNothing);
294 EXPECT_EQ(2U, chrome::GetTotalBrowserCount());
295 EXPECT_EQ(2U, browser_list->size());
296 EXPECT_EQ(path_profile2, browser_list->get(1)->profile()->GetPath());
298 // Create a second window for the ephemeral profile.
299 profiles::SwitchToProfile(path_profile2, desktop_type, true,
300 kOnProfileSwitchDoNothing);
301 EXPECT_EQ(3U, chrome::GetTotalBrowserCount());
302 EXPECT_EQ(3U, browser_list->size());
304 EXPECT_EQ(path_profile1, browser_list->get(0)->profile()->GetPath());
305 EXPECT_EQ(path_profile2, browser_list->get(1)->profile()->GetPath());
306 EXPECT_EQ(path_profile2, browser_list->get(2)->profile()->GetPath());
308 // Closing the first window of the ephemeral profile should not delete it.
309 browser_list->get(2)->window()->Close();
310 content::RunAllPendingInMessageLoop();
311 EXPECT_EQ(2U, browser_list->size());
312 ASSERT_EQ(2U, cache.GetNumberOfProfiles());
314 // The second should though.
315 browser_list->get(1)->window()->Close();
316 content::RunAllPendingInMessageLoop();
317 content::RunAllPendingInMessageLoop();
318 EXPECT_EQ(1U, browser_list->size());
319 ASSERT_EQ(1U, cache.GetNumberOfProfiles());
321 // Closing the last window should not reduce the number of profiles.
322 browser_list->get(0)->window()->Close();
323 content::RunAllPendingInMessageLoop();
324 EXPECT_EQ(0U, browser_list->size());
325 ASSERT_EQ(1U, cache.GetNumberOfProfiles());