OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <stddef.h> | 5 #include <stddef.h> |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/macros.h" | 9 #include "base/macros.h" |
10 #include "base/stl_util.h" | |
10 #include "base/strings/utf_string_conversions.h" | 11 #include "base/strings/utf_string_conversions.h" |
11 #include "build/build_config.h" | 12 #include "build/build_config.h" |
13 #include "chrome/browser/lifetime/keep_alive_types.h" | |
14 #include "chrome/browser/lifetime/scoped_keep_alive.h" | |
12 #include "chrome/browser/password_manager/password_store_factory.h" | 15 #include "chrome/browser/password_manager/password_store_factory.h" |
13 #include "chrome/browser/profiles/profile_attributes_entry.h" | 16 #include "chrome/browser/profiles/profile_attributes_entry.h" |
14 #include "chrome/browser/profiles/profile_attributes_storage.h" | 17 #include "chrome/browser/profiles/profile_attributes_storage.h" |
15 #include "chrome/browser/profiles/profile_manager.h" | 18 #include "chrome/browser/profiles/profile_manager.h" |
16 #include "chrome/browser/profiles/profile_window.h" | 19 #include "chrome/browser/profiles/profile_window.h" |
17 #include "chrome/browser/profiles/profiles_state.h" | 20 #include "chrome/browser/profiles/profiles_state.h" |
18 #include "chrome/browser/ui/browser_finder.h" | 21 #include "chrome/browser/ui/browser_finder.h" |
19 #include "chrome/browser/ui/browser_list.h" | 22 #include "chrome/browser/ui/browser_list.h" |
20 #include "chrome/browser/ui/browser_window.h" | 23 #include "chrome/browser/ui/browser_window.h" |
21 #include "chrome/common/pref_names.h" | 24 #include "chrome/common/pref_names.h" |
(...skipping 30 matching lines...) Expand all Loading... | |
52 void ProfileCreationComplete(Profile* profile, Profile::CreateStatus status) { | 55 void ProfileCreationComplete(Profile* profile, Profile::CreateStatus status) { |
53 ASSERT_NE(status, Profile::CREATE_STATUS_LOCAL_FAIL); | 56 ASSERT_NE(status, Profile::CREATE_STATUS_LOCAL_FAIL); |
54 ASSERT_NE(status, Profile::CREATE_STATUS_REMOTE_FAIL); | 57 ASSERT_NE(status, Profile::CREATE_STATUS_REMOTE_FAIL); |
55 // No browser should have been created for this profile yet. | 58 // No browser should have been created for this profile yet. |
56 EXPECT_EQ(chrome::GetBrowserCount(profile), 0U); | 59 EXPECT_EQ(chrome::GetBrowserCount(profile), 0U); |
57 EXPECT_EQ(chrome::GetTotalBrowserCount(), 1U); | 60 EXPECT_EQ(chrome::GetTotalBrowserCount(), 1U); |
58 if (status == Profile::CREATE_STATUS_INITIALIZED) | 61 if (status == Profile::CREATE_STATUS_INITIALIZED) |
59 base::MessageLoop::current()->QuitWhenIdle(); | 62 base::MessageLoop::current()->QuitWhenIdle(); |
60 } | 63 } |
61 | 64 |
65 // An observer returns back to test code after one or more profiles was deleted. | |
66 // It has ScopedKeepAlive object to prevent browser shutdown started in case | |
67 // browser become windowless. | |
68 class MultipleProfileDeletionObserver { | |
69 public: | |
70 MultipleProfileDeletionObserver(size_t callbacks_calls_expected) | |
71 : callback_calls_left_(callbacks_calls_expected) { | |
72 EXPECT_LT(0u, callback_calls_left_); | |
73 } | |
74 ProfileManager::CreateCallback QuitAttemptClosure() { | |
75 return base::Bind(&MultipleProfileDeletionObserver::QuitAttempt, | |
76 base::Unretained(this)); | |
77 } | |
78 void Wait() { | |
79 keep_alive_.reset(new ScopedKeepAlive(KeepAliveOrigin::PROFILE_HELPER, | |
Bernhard Bauer
2017/03/16 16:31:52
Can you use base::MakeUnique<ScopedKeepAlive>() an
| |
80 KeepAliveRestartOption::DISABLED)); | |
81 loop_.Run(); | |
82 } | |
83 | |
84 private: | |
85 void QuitAttempt(Profile* profile, Profile::CreateStatus status) { | |
86 EXPECT_EQ(Profile::CREATE_STATUS_INITIALIZED, status); | |
87 if (--callback_calls_left_) | |
88 return; | |
89 keep_alive_.reset(nullptr); | |
90 loop_.Quit(); | |
91 } | |
92 | |
93 base::RunLoop loop_; | |
94 size_t callback_calls_left_; | |
95 std::unique_ptr<ScopedKeepAlive> keep_alive_; | |
96 }; | |
97 | |
62 void EphemeralProfileCreationComplete(Profile* profile, | 98 void EphemeralProfileCreationComplete(Profile* profile, |
63 Profile::CreateStatus status) { | 99 Profile::CreateStatus status) { |
64 if (status == Profile::CREATE_STATUS_INITIALIZED) | 100 if (status == Profile::CREATE_STATUS_INITIALIZED) |
65 profile->GetPrefs()->SetBoolean(prefs::kForceEphemeralProfiles, true); | 101 profile->GetPrefs()->SetBoolean(prefs::kForceEphemeralProfiles, true); |
66 ProfileCreationComplete(profile, status); | 102 ProfileCreationComplete(profile, status); |
67 } | 103 } |
68 | 104 |
69 class ProfileRemovalObserver : public ProfileAttributesStorage::Observer { | 105 class ProfileRemovalObserver : public ProfileAttributesStorage::Observer { |
70 public: | 106 public: |
71 ProfileRemovalObserver() { | 107 ProfileRemovalObserver() { |
72 g_browser_process->profile_manager()->GetProfileAttributesStorage(). | 108 g_browser_process->profile_manager()->GetProfileAttributesStorage(). |
73 AddObserver(this); | 109 AddObserver(this); |
74 } | 110 } |
75 | 111 |
76 ~ProfileRemovalObserver() override { | 112 ~ProfileRemovalObserver() override { |
77 g_browser_process->profile_manager()->GetProfileAttributesStorage(). | 113 g_browser_process->profile_manager()->GetProfileAttributesStorage(). |
78 RemoveObserver(this); | 114 RemoveObserver(this); |
79 } | 115 } |
80 | 116 |
81 std::string last_used_profile_name() { return last_used_profile_name_; } | 117 std::string last_used_profile_name() { return last_used_profile_name_; } |
82 | 118 |
119 void set_on_profile_removal_callback(base::Closure callback) { | |
Bernhard Bauer
2017/03/16 16:31:52
Nit: Pass the callback by const-ref.
| |
120 on_profile_removal_callback_ = callback; | |
121 } | |
122 | |
83 // ProfileAttributesStorage::Observer overrides: | 123 // ProfileAttributesStorage::Observer overrides: |
84 void OnProfileWillBeRemoved(const base::FilePath& profile_path) override { | 124 void OnProfileWillBeRemoved(const base::FilePath& profile_path) override { |
85 last_used_profile_name_ = g_browser_process->local_state()->GetString( | 125 last_used_profile_name_ = g_browser_process->local_state()->GetString( |
86 prefs::kProfileLastUsed); | 126 prefs::kProfileLastUsed); |
127 if (!on_profile_removal_callback_.is_null()) | |
128 on_profile_removal_callback_.Run(); | |
87 } | 129 } |
88 | 130 |
89 private: | 131 private: |
90 std::string last_used_profile_name_; | 132 std::string last_used_profile_name_; |
133 base::Closure on_profile_removal_callback_; | |
91 | 134 |
92 DISALLOW_COPY_AND_ASSIGN(ProfileRemovalObserver); | 135 DISALLOW_COPY_AND_ASSIGN(ProfileRemovalObserver); |
93 }; | 136 }; |
94 | 137 |
95 // The class serves to retrieve passwords from PasswordStore asynchronously. It | 138 // The class serves to retrieve passwords from PasswordStore asynchronously. It |
96 // used by ProfileManagerBrowserTest.DeletePasswords on some platforms. | 139 // used by ProfileManagerBrowserTest.DeletePasswords on some platforms. |
97 class PasswordStoreConsumerVerifier | 140 class PasswordStoreConsumerVerifier |
98 : public password_manager::PasswordStoreConsumer { | 141 : public password_manager::PasswordStoreConsumer { |
99 public: | 142 public: |
100 void OnGetPasswordStoreResults( | 143 void OnGetPasswordStoreResults( |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
145 class ProfileManagerBrowserTest : public InProcessBrowserTest { | 188 class ProfileManagerBrowserTest : public InProcessBrowserTest { |
146 protected: | 189 protected: |
147 void SetUpCommandLine(base::CommandLine* command_line) override { | 190 void SetUpCommandLine(base::CommandLine* command_line) override { |
148 #if defined(OS_CHROMEOS) | 191 #if defined(OS_CHROMEOS) |
149 command_line->AppendSwitch( | 192 command_line->AppendSwitch( |
150 chromeos::switches::kIgnoreUserProfileMappingForTests); | 193 chromeos::switches::kIgnoreUserProfileMappingForTests); |
151 #endif | 194 #endif |
152 } | 195 } |
153 }; | 196 }; |
154 | 197 |
155 #if defined(OS_MACOSX) | 198 #if !defined(OS_ANDROID) |
156 | 199 |
157 // Delete single profile and make sure a new one is created. | 200 // Delete single profile and make sure a new one is created. |
158 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, DeleteSingletonProfile) { | 201 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, DeleteSingletonProfile) { |
159 ProfileManager* profile_manager = g_browser_process->profile_manager(); | 202 ProfileManager* profile_manager = g_browser_process->profile_manager(); |
160 ProfileAttributesStorage& storage = | 203 ProfileAttributesStorage& storage = |
161 profile_manager->GetProfileAttributesStorage(); | 204 profile_manager->GetProfileAttributesStorage(); |
162 ProfileRemovalObserver observer; | 205 ProfileRemovalObserver observer; |
163 | 206 |
164 // We should start out with 1 profile. | 207 // We should start out with 1 profile. |
165 ASSERT_EQ(1u, storage.GetNumberOfProfiles()); | 208 ASSERT_EQ(1u, storage.GetNumberOfProfiles()); |
166 | 209 |
167 // Delete singleton profile. | 210 // Delete singleton profile. |
168 base::FilePath singleton_profile_path = | 211 base::FilePath singleton_profile_path = |
169 storage.GetAllProfilesAttributes().front()->GetPath(); | 212 storage.GetAllProfilesAttributes().front()->GetPath(); |
170 EXPECT_FALSE(singleton_profile_path.empty()); | 213 EXPECT_FALSE(singleton_profile_path.empty()); |
171 base::RunLoop run_loop; | 214 MultipleProfileDeletionObserver profile_deletion_observer(1u); |
172 profile_manager->ScheduleProfileForDeletion( | 215 profile_manager->ScheduleProfileForDeletion( |
173 singleton_profile_path, | 216 singleton_profile_path, profile_deletion_observer.QuitAttemptClosure()); |
174 base::Bind(&OnUnblockOnProfileCreation, &run_loop)); | |
175 | 217 |
176 // Run the message loop until the profile is actually deleted (as indicated | 218 // Run the message loop until the profile is actually deleted (as indicated |
177 // by the callback above being called). | 219 // by the callback above being called). |
178 run_loop.Run(); | 220 profile_deletion_observer.Wait(); |
179 | 221 |
180 // Make sure a new profile was created automatically. | 222 // Make sure a new profile was created automatically. |
181 EXPECT_EQ(1u, storage.GetNumberOfProfiles()); | 223 EXPECT_EQ(1u, storage.GetNumberOfProfiles()); |
182 base::FilePath new_profile_path = | 224 base::FilePath new_profile_path = |
183 storage.GetAllProfilesAttributes().front()->GetPath(); | 225 storage.GetAllProfilesAttributes().front()->GetPath(); |
184 EXPECT_NE(new_profile_path.value(), singleton_profile_path.value()); | 226 EXPECT_NE(new_profile_path.value(), singleton_profile_path.value()); |
185 | 227 |
186 // Make sure that last used profile preference is set correctly. | 228 // Make sure that last used profile preference is set correctly. |
187 Profile* last_used = ProfileManager::GetLastUsedProfile(); | 229 Profile* last_used = ProfileManager::GetLastUsedProfile(); |
188 EXPECT_EQ(new_profile_path.value(), last_used->GetPath().value()); | 230 EXPECT_EQ(new_profile_path.value(), last_used->GetPath().value()); |
189 | 231 |
190 // Make sure the last used profile was set correctly before the notification | 232 // Make sure the last used profile was set correctly before the notification |
191 // was sent. | 233 // was sent. |
192 std::string last_used_profile_name = | 234 std::string last_used_profile_name = |
193 last_used->GetPath().BaseName().MaybeAsASCII(); | 235 last_used->GetPath().BaseName().MaybeAsASCII(); |
194 EXPECT_EQ(last_used_profile_name, observer.last_used_profile_name()); | 236 EXPECT_EQ(last_used_profile_name, observer.last_used_profile_name()); |
195 } | 237 } |
196 | 238 |
239 // Delete inactive profile in a multi profile setup and make sure current | |
240 // browser is not affected. | |
241 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, DeleteInactiveProfile) { | |
242 ProfileManager* profile_manager = g_browser_process->profile_manager(); | |
243 ProfileAttributesStorage& storage = | |
244 profile_manager->GetProfileAttributesStorage(); | |
245 base::FilePath current_profile_path = browser()->profile()->GetPath(); | |
246 | |
247 // Create an additional profile. | |
248 base::FilePath new_path = profile_manager->GenerateNextProfileDirectoryPath(); | |
249 base::RunLoop run_loop; | |
250 profile_manager->CreateProfileAsync( | |
251 new_path, base::Bind(&OnUnblockOnProfileCreation, &run_loop), | |
252 base::string16(), std::string(), std::string()); | |
253 run_loop.Run(); | |
254 | |
255 ASSERT_EQ(2u, storage.GetNumberOfProfiles()); | |
256 | |
257 // Delete inactive profile. | |
258 base::RunLoop loop; | |
259 ProfileRemovalObserver observer; | |
260 observer.set_on_profile_removal_callback(loop.QuitClosure()); | |
261 profile_manager->ScheduleProfileForDeletion(new_path, | |
262 ProfileManager::CreateCallback()); | |
263 loop.Run(); | |
264 | |
265 // Make sure there only preexisted profile left. | |
266 EXPECT_EQ(1u, storage.GetNumberOfProfiles()); | |
267 EXPECT_EQ(current_profile_path, | |
268 storage.GetAllProfilesAttributes().front()->GetPath()); | |
269 | |
270 // Make sure that last used profile preference is set correctly. | |
271 Profile* last_used = ProfileManager::GetLastUsedProfile(); | |
272 EXPECT_EQ(current_profile_path, last_used->GetPath()); | |
273 } | |
274 | |
275 // Delete current profile in a multi profile setup and make sure an existing one | |
276 // is loaded. | |
277 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, DeleteCurrentProfile) { | |
278 ProfileManager* profile_manager = g_browser_process->profile_manager(); | |
279 ProfileAttributesStorage& storage = | |
280 profile_manager->GetProfileAttributesStorage(); | |
281 | |
282 // Create an additional profile. | |
283 base::FilePath new_path = profile_manager->GenerateNextProfileDirectoryPath(); | |
284 base::RunLoop run_loop; | |
285 profile_manager->CreateProfileAsync( | |
286 new_path, base::Bind(&OnUnblockOnProfileCreation, &run_loop), | |
287 base::string16(), std::string(), std::string()); | |
288 run_loop.Run(); | |
289 | |
290 ASSERT_EQ(2u, storage.GetNumberOfProfiles()); | |
291 | |
292 // Delete current profile. | |
293 MultipleProfileDeletionObserver profile_deletion_observer(1u); | |
294 profile_manager->ScheduleProfileForDeletion( | |
295 browser()->profile()->GetPath(), | |
296 profile_deletion_observer.QuitAttemptClosure()); | |
297 profile_deletion_observer.Wait(); | |
298 | |
299 // Make sure a profile created earlier become the only profile. | |
300 EXPECT_EQ(1u, storage.GetNumberOfProfiles()); | |
301 EXPECT_EQ(new_path, storage.GetAllProfilesAttributes().front()->GetPath()); | |
302 | |
303 // Make sure that last used profile preference is set correctly. | |
304 Profile* last_used = ProfileManager::GetLastUsedProfile(); | |
305 EXPECT_EQ(new_path, last_used->GetPath()); | |
306 } | |
307 | |
197 // Delete all profiles in a multi profile setup and make sure a new one is | 308 // Delete all profiles in a multi profile setup and make sure a new one is |
198 // created. | 309 // created. |
199 // Crashes/CHECKs. See crbug.com/104851 | 310 // Should be fixed: Crashes/CHECKs. See crbug.com/104851 |
Bernhard Bauer
2017/03/16 16:31:52
Does this test still crash? If so, we probably sho
| |
200 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, DISABLED_DeleteAllProfiles) { | 311 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, DeleteAllProfiles) { |
201 ProfileManager* profile_manager = g_browser_process->profile_manager(); | 312 ProfileManager* profile_manager = g_browser_process->profile_manager(); |
202 ProfileAttributesStorage& storage = | 313 ProfileAttributesStorage& storage = |
203 profile_manager->GetProfileAttributesStorage(); | 314 profile_manager->GetProfileAttributesStorage(); |
204 | 315 |
205 // Create an additional profile. | 316 // Create an additional profile. |
206 base::FilePath new_path = profile_manager->GenerateNextProfileDirectoryPath(); | 317 base::FilePath new_path = profile_manager->GenerateNextProfileDirectoryPath(); |
207 base::RunLoop run_loop; | 318 base::RunLoop run_loop; |
208 profile_manager->CreateProfileAsync( | 319 profile_manager->CreateProfileAsync( |
209 new_path, base::Bind(&OnUnblockOnProfileCreation, &run_loop), | 320 new_path, base::Bind(&OnUnblockOnProfileCreation, &run_loop), |
210 base::string16(), std::string(), std::string()); | 321 base::string16(), std::string(), std::string()); |
211 | 322 |
212 // Run the message loop to allow profile creation to take place; the loop is | 323 // Run the message loop to allow profile creation to take place; the loop is |
213 // terminated by OnUnblockOnProfileCreation when the profile is created. | 324 // terminated by OnUnblockOnProfileCreation when the profile is created. |
214 run_loop.Run(); | 325 run_loop.Run(); |
215 | 326 |
216 ASSERT_EQ(2u, storage.GetNumberOfProfiles()); | 327 ASSERT_EQ(2u, storage.GetNumberOfProfiles()); |
217 | 328 |
218 // Delete all profiles. | 329 // Delete all profiles. |
330 MultipleProfileDeletionObserver profile_deletion_observer(2u); | |
219 std::vector<ProfileAttributesEntry*> entries = | 331 std::vector<ProfileAttributesEntry*> entries = |
220 storage.GetAllProfilesAttributes(); | 332 storage.GetAllProfilesAttributes(); |
221 std::vector<base::FilePath> old_profile_paths; | 333 std::vector<base::FilePath> old_profile_paths; |
222 for (ProfileAttributesEntry* entry : entries) { | 334 for (ProfileAttributesEntry* entry : entries) { |
223 base::FilePath profile_path = entry->GetPath(); | 335 base::FilePath profile_path = entry->GetPath(); |
224 EXPECT_FALSE(profile_path.empty()); | 336 EXPECT_FALSE(profile_path.empty()); |
225 profile_manager->ScheduleProfileForDeletion( | 337 profile_manager->ScheduleProfileForDeletion( |
226 profile_path, ProfileManager::CreateCallback()); | 338 profile_path, profile_deletion_observer.QuitAttemptClosure()); |
227 old_profile_paths.push_back(profile_path); | 339 old_profile_paths.push_back(profile_path); |
228 } | 340 } |
229 | 341 profile_deletion_observer.Wait(); |
230 // Spin things so deletion can take place. | |
231 content::RunAllPendingInMessageLoop(); | |
232 | 342 |
233 // Make sure a new profile was created automatically. | 343 // Make sure a new profile was created automatically. |
234 EXPECT_EQ(1u, storage.GetNumberOfProfiles()); | 344 EXPECT_EQ(1u, storage.GetNumberOfProfiles()); |
235 base::FilePath new_profile_path = | 345 base::FilePath new_profile_path = |
236 storage.GetAllProfilesAttributes().front()->GetPath(); | 346 storage.GetAllProfilesAttributes().front()->GetPath(); |
237 for (const base::FilePath& old_profile_path : old_profile_paths) | 347 for (const base::FilePath& old_profile_path : old_profile_paths) |
238 EXPECT_NE(old_profile_path, new_profile_path); | 348 EXPECT_NE(old_profile_path, new_profile_path); |
239 | 349 |
240 // Make sure that last used profile preference is set correctly. | 350 // Make sure that last used profile preference is set correctly. |
241 Profile* last_used = ProfileManager::GetLastUsedProfile(); | 351 Profile* last_used = ProfileManager::GetLastUsedProfile(); |
242 EXPECT_EQ(new_profile_path, last_used->GetPath()); | 352 EXPECT_EQ(new_profile_path, last_used->GetPath()); |
243 } | 353 } |
244 #endif // OS_MACOSX | 354 #endif // !defined(OS_ANDROID) |
245 | 355 |
246 #if defined(OS_CHROMEOS) | 356 #if defined(OS_CHROMEOS) |
247 | 357 |
248 class ProfileManagerCrOSBrowserTest : public ProfileManagerBrowserTest { | 358 class ProfileManagerCrOSBrowserTest : public ProfileManagerBrowserTest { |
249 protected: | 359 protected: |
250 void SetUpCommandLine(base::CommandLine* command_line) override { | 360 void SetUpCommandLine(base::CommandLine* command_line) override { |
251 // Use a user hash other than the default chrome::kTestUserProfileDir | 361 // Use a user hash other than the default chrome::kTestUserProfileDir |
252 // so that the prefix case is tested. | 362 // so that the prefix case is tested. |
253 command_line->AppendSwitchASCII(chromeos::switches::kLoginProfile, | 363 command_line->AppendSwitchASCII(chromeos::switches::kLoginProfile, |
254 "test-user-hash"); | 364 "test-user-hash"); |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
500 | 610 |
501 EXPECT_FALSE(profile->HasOffTheRecordProfile()); | 611 EXPECT_FALSE(profile->HasOffTheRecordProfile()); |
502 EXPECT_FALSE(profile_manager->IsValidProfile(incognito_profile)); | 612 EXPECT_FALSE(profile_manager->IsValidProfile(incognito_profile)); |
503 EXPECT_EQ(initial_profile_count, profile_manager->GetNumberOfProfiles()); | 613 EXPECT_EQ(initial_profile_count, profile_manager->GetNumberOfProfiles()); |
504 // After destroying the incognito profile incognito preferences should be | 614 // After destroying the incognito profile incognito preferences should be |
505 // cleared so the default save path should be taken from the main profile. | 615 // cleared so the default save path should be taken from the main profile. |
506 EXPECT_FALSE(profile->GetOffTheRecordPrefs() | 616 EXPECT_FALSE(profile->GetOffTheRecordPrefs() |
507 ->GetFilePath(prefs::kSaveFileDefaultDirectory) | 617 ->GetFilePath(prefs::kSaveFileDefaultDirectory) |
508 .empty()); | 618 .empty()); |
509 } | 619 } |
OLD | NEW |