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/chrome_switches.h"
19 #include "chrome/common/pref_names.h"
20 #include "chrome/test/base/in_process_browser_test.h"
21 #include "chrome/test/base/test_switches.h"
22 #include "chrome/test/base/testing_browser_process.h"
23 #include "chrome/test/base/ui_test_utils.h"
25 #if defined(OS_CHROMEOS)
26 #include "base/path_service.h"
27 #include "chrome/common/chrome_constants.h"
28 #include "chrome/common/chrome_paths.h"
29 #include "testing/gtest/include/gtest/gtest.h"
34 const profiles::ProfileSwitchingDoneCallback kOnProfileSwitchDoNothing;
36 // An observer that returns back to test code after a new profile is
38 void OnUnblockOnProfileCreation(Profile* profile,
39 Profile::CreateStatus status) {
40 if (status == Profile::CREATE_STATUS_INITIALIZED)
41 base::MessageLoop::current()->Quit();
44 void ProfileCreationComplete(Profile* profile, Profile::CreateStatus status) {
45 ASSERT_NE(status, Profile::CREATE_STATUS_LOCAL_FAIL);
46 ASSERT_NE(status, Profile::CREATE_STATUS_REMOTE_FAIL);
47 // No browser should have been created for this profile yet.
48 EXPECT_EQ(chrome::GetTotalBrowserCountForProfile(profile), 0U);
49 EXPECT_EQ(chrome::GetTotalBrowserCount(), 1U);
50 if (status == Profile::CREATE_STATUS_INITIALIZED)
51 base::MessageLoop::current()->Quit();
54 void EphemeralProfileCreationComplete(Profile* profile,
55 Profile::CreateStatus status) {
56 if (status == Profile::CREATE_STATUS_INITIALIZED)
57 profile->GetPrefs()->SetBoolean(prefs::kForceEphemeralProfiles, true);
58 ProfileCreationComplete(profile, status);
61 class ProfileRemovalObserver : public ProfileInfoCacheObserver {
63 ProfileRemovalObserver() {
64 g_browser_process->profile_manager()->GetProfileInfoCache().AddObserver(
68 virtual ~ProfileRemovalObserver() {
69 g_browser_process->profile_manager()->GetProfileInfoCache().RemoveObserver(
73 std::string last_used_profile_name() { return last_used_profile_name_; }
75 // ProfileInfoCacheObserver overrides:
76 virtual void OnProfileWillBeRemoved(
77 const base::FilePath& profile_path) OVERRIDE {
78 last_used_profile_name_ = g_browser_process->local_state()->GetString(
79 prefs::kProfileLastUsed);
83 std::string last_used_profile_name_;
85 DISALLOW_COPY_AND_ASSIGN(ProfileRemovalObserver);
90 // This file contains tests for the ProfileManager that require a heavyweight
91 // InProcessBrowserTest. These include tests involving profile deletion.
93 // TODO(jeremy): crbug.com/103355 - These tests should be enabled on all
95 class ProfileManagerBrowserTest : public InProcessBrowserTest {
98 #if defined(OS_MACOSX)
100 // Delete single profile and make sure a new one is created.
101 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, DeleteSingletonProfile) {
102 ProfileManager* profile_manager = g_browser_process->profile_manager();
103 ProfileInfoCache& cache = profile_manager->GetProfileInfoCache();
104 ProfileRemovalObserver observer;
106 // We should start out with 1 profile.
107 ASSERT_EQ(cache.GetNumberOfProfiles(), 1U);
109 // Delete singleton profile.
110 base::FilePath singleton_profile_path = cache.GetPathOfProfileAtIndex(0);
111 EXPECT_FALSE(singleton_profile_path.empty());
112 profile_manager->ScheduleProfileForDeletion(singleton_profile_path,
113 ProfileManager::CreateCallback());
115 // Spin things till profile is actually deleted.
116 content::RunAllPendingInMessageLoop();
118 // Make sure a new profile was created automatically.
119 EXPECT_EQ(cache.GetNumberOfProfiles(), 1U);
120 base::FilePath new_profile_path = cache.GetPathOfProfileAtIndex(0);
121 EXPECT_NE(new_profile_path, singleton_profile_path);
123 // Make sure that last used profile preference is set correctly.
124 Profile* last_used = ProfileManager::GetLastUsedProfile();
125 EXPECT_EQ(new_profile_path, last_used->GetPath());
127 // Make sure the last used profile was set correctly before the notification
129 std::string last_used_profile_name =
130 last_used->GetPath().BaseName().MaybeAsASCII();
131 EXPECT_EQ(last_used_profile_name, observer.last_used_profile_name());
134 // Delete all profiles in a multi profile setup and make sure a new one is
136 // Crashes/CHECKs. See crbug.com/104851
137 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, DISABLED_DeleteAllProfiles) {
138 ProfileManager* profile_manager = g_browser_process->profile_manager();
139 ProfileInfoCache& cache = profile_manager->GetProfileInfoCache();
141 // Create an additional profile.
142 base::FilePath new_path = profile_manager->GenerateNextProfileDirectoryPath();
143 profile_manager->CreateProfileAsync(new_path,
144 base::Bind(&OnUnblockOnProfileCreation),
145 base::string16(), base::string16(),
148 // Spin to allow profile creation to take place, loop is terminated
149 // by OnUnblockOnProfileCreation when the profile is created.
150 content::RunMessageLoop();
152 ASSERT_EQ(cache.GetNumberOfProfiles(), 2U);
154 // Delete all profiles.
155 base::FilePath profile_path1 = cache.GetPathOfProfileAtIndex(0);
156 base::FilePath profile_path2 = cache.GetPathOfProfileAtIndex(1);
157 EXPECT_FALSE(profile_path1.empty());
158 EXPECT_FALSE(profile_path2.empty());
159 profile_manager->ScheduleProfileForDeletion(profile_path1,
160 ProfileManager::CreateCallback());
161 profile_manager->ScheduleProfileForDeletion(profile_path2,
162 ProfileManager::CreateCallback());
164 // Spin things so deletion can take place.
165 content::RunAllPendingInMessageLoop();
167 // Make sure a new profile was created automatically.
168 EXPECT_EQ(cache.GetNumberOfProfiles(), 1U);
169 base::FilePath new_profile_path = cache.GetPathOfProfileAtIndex(0);
170 EXPECT_NE(new_profile_path, profile_path1);
171 EXPECT_NE(new_profile_path, profile_path2);
173 // Make sure that last used profile preference is set correctly.
174 Profile* last_used = ProfileManager::GetLastUsedProfile();
175 EXPECT_EQ(new_profile_path, last_used->GetPath());
179 #if defined(OS_CHROMEOS)
181 class ProfileManagerCrOSBrowserTest : public ProfileManagerBrowserTest,
182 public testing::WithParamInterface<bool> {
184 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
186 command_line->AppendSwitch(::switches::kMultiProfiles);
190 IN_PROC_BROWSER_TEST_P(ProfileManagerCrOSBrowserTest, GetLastUsedProfile) {
191 // Make sure that last used profile is correct.
192 Profile* last_used_profile = ProfileManager::GetLastUsedProfile();
193 EXPECT_TRUE(last_used_profile != NULL);
195 base::FilePath profile_path;
196 PathService::Get(chrome::DIR_USER_DATA, &profile_path);
198 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
199 if (command_line.HasSwitch(switches::kMultiProfiles)) {
200 profile_path = profile_path.Append(base::FilePath(
201 std::string(chrome::kProfileDirPrefix) + chrome::kTestUserProfileDir));
203 profile_path = profile_path.Append(
204 base::FilePath(chrome::kTestUserProfileDir));
206 EXPECT_EQ(profile_path.value(), last_used_profile->GetPath().value());
209 INSTANTIATE_TEST_CASE_P(ProfileManagerCrOSBrowserTestInstantiation,
210 ProfileManagerCrOSBrowserTest,
213 #endif // OS_CHROMEOS
215 // Times out (http://crbug.com/159002)
216 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest,
217 DISABLED_CreateProfileWithCallback) {
218 ProfileManager* profile_manager = g_browser_process->profile_manager();
220 ASSERT_EQ(profile_manager->GetNumberOfProfiles(), 1U);
221 EXPECT_EQ(chrome::GetTotalBrowserCount(), 1U);
223 // Create a profile, make sure callback is invoked before any callbacks are
224 // invoked (so they can do things like sign in the profile, etc).
225 ProfileManager::CreateMultiProfileAsync(
226 base::string16(), // name
227 base::string16(), // icon url
228 base::Bind(ProfileCreationComplete),
230 // Wait for profile to finish loading.
231 content::RunMessageLoop();
232 EXPECT_EQ(profile_manager->GetNumberOfProfiles(), 2U);
233 EXPECT_EQ(chrome::GetTotalBrowserCount(), 2U);
235 // Now close all browser windows.
236 std::vector<Profile*> profiles = profile_manager->GetLoadedProfiles();
237 for (std::vector<Profile*>::const_iterator it = profiles.begin();
238 it != profiles.end(); ++it) {
239 BrowserList::CloseAllBrowsersWithProfile(*it);
243 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest,
245 #if defined(OS_WIN) && defined(USE_ASH)
246 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
247 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
251 // If multiprofile mode is not enabled, you can't switch between profiles.
252 if (!profiles::IsMultipleProfilesEnabled())
255 ProfileManager* profile_manager = g_browser_process->profile_manager();
256 ProfileInfoCache& cache = profile_manager->GetProfileInfoCache();
257 base::FilePath path_profile1 = cache.GetPathOfProfileAtIndex(0);
259 ASSERT_EQ(profile_manager->GetNumberOfProfiles(), 1U);
260 EXPECT_EQ(chrome::GetTotalBrowserCount(), 1U);
262 // Create an additional profile.
263 base::FilePath path_profile2 =
264 profile_manager->GenerateNextProfileDirectoryPath();
265 profile_manager->CreateProfileAsync(path_profile2,
266 base::Bind(&OnUnblockOnProfileCreation),
267 base::string16(), base::string16(),
270 // Spin to allow profile creation to take place, loop is terminated
271 // by OnUnblockOnProfileCreation when the profile is created.
272 content::RunMessageLoop();
274 chrome::HostDesktopType desktop_type = chrome::GetActiveDesktop();
275 BrowserList* browser_list = BrowserList::GetInstance(desktop_type);
276 ASSERT_EQ(cache.GetNumberOfProfiles(), 2U);
277 EXPECT_EQ(1U, browser_list->size());
279 // Open a browser window for the first profile.
280 profiles::SwitchToProfile(path_profile1, desktop_type, false,
281 kOnProfileSwitchDoNothing,
282 ProfileMetrics::SWITCH_PROFILE_ICON);
283 EXPECT_EQ(chrome::GetTotalBrowserCount(), 1U);
284 EXPECT_EQ(1U, browser_list->size());
285 EXPECT_EQ(path_profile1, browser_list->get(0)->profile()->GetPath());
287 // Open a browser window for the second profile.
288 profiles::SwitchToProfile(path_profile2, desktop_type, false,
289 kOnProfileSwitchDoNothing,
290 ProfileMetrics::SWITCH_PROFILE_ICON);
291 EXPECT_EQ(chrome::GetTotalBrowserCount(), 2U);
292 EXPECT_EQ(2U, browser_list->size());
293 EXPECT_EQ(path_profile2, browser_list->get(1)->profile()->GetPath());
295 // Switch to the first profile without opening a new window.
296 profiles::SwitchToProfile(path_profile1, desktop_type, false,
297 kOnProfileSwitchDoNothing,
298 ProfileMetrics::SWITCH_PROFILE_ICON);
299 EXPECT_EQ(chrome::GetTotalBrowserCount(), 2U);
300 EXPECT_EQ(2U, browser_list->size());
302 EXPECT_EQ(path_profile1, browser_list->get(0)->profile()->GetPath());
303 EXPECT_EQ(path_profile2, browser_list->get(1)->profile()->GetPath());
306 // This test used to be flakily timing out on Windows: http://crbug.com/314905.
307 // If this happens again please make it a MAYBE_ test and reopen that bug.
308 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, EphemeralProfile) {
309 #if defined(OS_WIN) && defined(USE_ASH)
310 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
311 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
315 // If multiprofile mode is not enabled, you can't switch between profiles.
316 if (!profiles::IsMultipleProfilesEnabled())
319 ProfileManager* profile_manager = g_browser_process->profile_manager();
320 ProfileInfoCache& cache = profile_manager->GetProfileInfoCache();
321 base::FilePath path_profile1 = cache.GetPathOfProfileAtIndex(0);
323 ASSERT_EQ(1U, profile_manager->GetNumberOfProfiles());
324 EXPECT_EQ(1U, chrome::GetTotalBrowserCount());
326 // Create an ephemeral profile.
327 base::FilePath path_profile2 =
328 profile_manager->GenerateNextProfileDirectoryPath();
329 profile_manager->CreateProfileAsync(
331 base::Bind(&EphemeralProfileCreationComplete),
332 base::string16(), base::string16(), std::string());
334 // Spin to allow profile creation to take place.
335 content::RunMessageLoop();
337 chrome::HostDesktopType desktop_type = chrome::GetActiveDesktop();
338 BrowserList* browser_list = BrowserList::GetInstance(desktop_type);
339 ASSERT_EQ(2U, cache.GetNumberOfProfiles());
340 EXPECT_EQ(1U, browser_list->size());
342 // Open a browser window for the second profile.
343 profiles::SwitchToProfile(path_profile2, desktop_type, false,
344 kOnProfileSwitchDoNothing,
345 ProfileMetrics::SWITCH_PROFILE_ICON);
346 EXPECT_EQ(2U, chrome::GetTotalBrowserCount());
347 EXPECT_EQ(2U, browser_list->size());
348 EXPECT_EQ(path_profile2, browser_list->get(1)->profile()->GetPath());
350 // Create a second window for the ephemeral profile.
351 profiles::SwitchToProfile(path_profile2, desktop_type, true,
352 kOnProfileSwitchDoNothing,
353 ProfileMetrics::SWITCH_PROFILE_ICON);
354 EXPECT_EQ(3U, chrome::GetTotalBrowserCount());
355 EXPECT_EQ(3U, browser_list->size());
357 EXPECT_EQ(path_profile1, browser_list->get(0)->profile()->GetPath());
358 EXPECT_EQ(path_profile2, browser_list->get(1)->profile()->GetPath());
359 EXPECT_EQ(path_profile2, browser_list->get(2)->profile()->GetPath());
361 // Closing the first window of the ephemeral profile should not delete it.
362 browser_list->get(2)->window()->Close();
363 content::RunAllPendingInMessageLoop();
364 EXPECT_EQ(2U, browser_list->size());
365 ASSERT_EQ(2U, cache.GetNumberOfProfiles());
367 // The second should though.
368 browser_list->get(1)->window()->Close();
369 content::RunAllPendingInMessageLoop();
370 EXPECT_EQ(1U, browser_list->size());
371 ASSERT_EQ(1U, cache.GetNumberOfProfiles());