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/memory/ptr_util.h" |
| 11 #include "base/stl_util.h" |
10 #include "base/strings/utf_string_conversions.h" | 12 #include "base/strings/utf_string_conversions.h" |
11 #include "build/build_config.h" | 13 #include "build/build_config.h" |
| 14 #include "chrome/browser/browsing_data/browsing_data_remover_impl.h" |
| 15 #include "chrome/browser/lifetime/keep_alive_types.h" |
| 16 #include "chrome/browser/lifetime/scoped_keep_alive.h" |
12 #include "chrome/browser/password_manager/password_store_factory.h" | 17 #include "chrome/browser/password_manager/password_store_factory.h" |
13 #include "chrome/browser/profiles/profile_attributes_entry.h" | 18 #include "chrome/browser/profiles/profile_attributes_entry.h" |
14 #include "chrome/browser/profiles/profile_attributes_storage.h" | 19 #include "chrome/browser/profiles/profile_attributes_storage.h" |
15 #include "chrome/browser/profiles/profile_manager.h" | 20 #include "chrome/browser/profiles/profile_manager.h" |
16 #include "chrome/browser/profiles/profile_window.h" | 21 #include "chrome/browser/profiles/profile_window.h" |
17 #include "chrome/browser/profiles/profiles_state.h" | 22 #include "chrome/browser/profiles/profiles_state.h" |
18 #include "chrome/browser/ui/browser_finder.h" | 23 #include "chrome/browser/ui/browser_finder.h" |
19 #include "chrome/browser/ui/browser_list.h" | 24 #include "chrome/browser/ui/browser_list.h" |
20 #include "chrome/browser/ui/browser_window.h" | 25 #include "chrome/browser/ui/browser_window.h" |
21 #include "chrome/common/pref_names.h" | 26 #include "chrome/common/pref_names.h" |
(...skipping 30 matching lines...) Expand all Loading... |
52 void ProfileCreationComplete(Profile* profile, Profile::CreateStatus status) { | 57 void ProfileCreationComplete(Profile* profile, Profile::CreateStatus status) { |
53 ASSERT_NE(status, Profile::CREATE_STATUS_LOCAL_FAIL); | 58 ASSERT_NE(status, Profile::CREATE_STATUS_LOCAL_FAIL); |
54 ASSERT_NE(status, Profile::CREATE_STATUS_REMOTE_FAIL); | 59 ASSERT_NE(status, Profile::CREATE_STATUS_REMOTE_FAIL); |
55 // No browser should have been created for this profile yet. | 60 // No browser should have been created for this profile yet. |
56 EXPECT_EQ(chrome::GetBrowserCount(profile), 0U); | 61 EXPECT_EQ(chrome::GetBrowserCount(profile), 0U); |
57 EXPECT_EQ(chrome::GetTotalBrowserCount(), 1U); | 62 EXPECT_EQ(chrome::GetTotalBrowserCount(), 1U); |
58 if (status == Profile::CREATE_STATUS_INITIALIZED) | 63 if (status == Profile::CREATE_STATUS_INITIALIZED) |
59 base::MessageLoop::current()->QuitWhenIdle(); | 64 base::MessageLoop::current()->QuitWhenIdle(); |
60 } | 65 } |
61 | 66 |
| 67 // An observer returns back to test code after one or more profiles was deleted. |
| 68 // It has ScopedKeepAlive object to prevent browser shutdown started in case |
| 69 // browser become windowless. |
| 70 class MultipleProfileDeletionObserver |
| 71 : public BrowsingDataRemoverImpl::CompletionInhibitor { |
| 72 public: |
| 73 explicit MultipleProfileDeletionObserver(size_t expected_count) |
| 74 : expected_count_(expected_count), |
| 75 profiles_created_count_(0), |
| 76 profiles_data_removed_count_(0) { |
| 77 EXPECT_LT(0u, expected_count_); |
| 78 BrowsingDataRemoverImpl::set_completion_inhibitor_for_testing(this); |
| 79 } |
| 80 ~MultipleProfileDeletionObserver() { |
| 81 BrowsingDataRemoverImpl::set_completion_inhibitor_for_testing(nullptr); |
| 82 } |
| 83 ProfileManager::CreateCallback OnProfileCreatedClosure() { |
| 84 return base::Bind(&MultipleProfileDeletionObserver::OnProfileCreated, |
| 85 base::Unretained(this)); |
| 86 } |
| 87 void Wait() { |
| 88 keep_alive_ = base::MakeUnique<ScopedKeepAlive>( |
| 89 KeepAliveOrigin::PROFILE_HELPER, KeepAliveRestartOption::DISABLED); |
| 90 loop_.Run(); |
| 91 } |
| 92 |
| 93 private: |
| 94 void OnProfileCreated(Profile* profile, Profile::CreateStatus status) { |
| 95 EXPECT_EQ(Profile::CREATE_STATUS_INITIALIZED, status); |
| 96 ++profiles_created_count_; |
| 97 MaybeQuit(); |
| 98 } |
| 99 |
| 100 // TODO(bug 704601): remove it when bug is fixed. |
| 101 void OnBrowsingDataRemoverWouldComplete( |
| 102 BrowsingDataRemoverImpl* remover, |
| 103 const base::Closure& continue_to_completion) override { |
| 104 continue_to_completion.Run(); |
| 105 |
| 106 ++profiles_data_removed_count_; |
| 107 MaybeQuit(); |
| 108 } |
| 109 |
| 110 void MaybeQuit() { |
| 111 LOG(INFO) << profiles_created_count_ << " profiles created & " |
| 112 << profiles_data_removed_count_ << " profile data removed of " |
| 113 << expected_count_ << " expected."; |
| 114 if (profiles_created_count_ < expected_count_ || |
| 115 profiles_data_removed_count_ < expected_count_) |
| 116 return; |
| 117 |
| 118 EXPECT_EQ(expected_count_, profiles_created_count_); |
| 119 EXPECT_EQ(expected_count_, profiles_data_removed_count_); |
| 120 |
| 121 keep_alive_.reset(); |
| 122 loop_.Quit(); |
| 123 } |
| 124 |
| 125 base::RunLoop loop_; |
| 126 std::unique_ptr<ScopedKeepAlive> keep_alive_; |
| 127 size_t expected_count_; |
| 128 size_t profiles_created_count_; |
| 129 size_t profiles_data_removed_count_; |
| 130 }; |
| 131 |
62 void EphemeralProfileCreationComplete(Profile* profile, | 132 void EphemeralProfileCreationComplete(Profile* profile, |
63 Profile::CreateStatus status) { | 133 Profile::CreateStatus status) { |
64 if (status == Profile::CREATE_STATUS_INITIALIZED) | 134 if (status == Profile::CREATE_STATUS_INITIALIZED) |
65 profile->GetPrefs()->SetBoolean(prefs::kForceEphemeralProfiles, true); | 135 profile->GetPrefs()->SetBoolean(prefs::kForceEphemeralProfiles, true); |
66 ProfileCreationComplete(profile, status); | 136 ProfileCreationComplete(profile, status); |
67 } | 137 } |
68 | 138 |
69 class ProfileRemovalObserver : public ProfileAttributesStorage::Observer { | 139 class ProfileRemovalObserver : public ProfileAttributesStorage::Observer { |
70 public: | 140 public: |
71 ProfileRemovalObserver() { | 141 ProfileRemovalObserver() { |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 class ProfileManagerBrowserTest : public InProcessBrowserTest { | 215 class ProfileManagerBrowserTest : public InProcessBrowserTest { |
146 protected: | 216 protected: |
147 void SetUpCommandLine(base::CommandLine* command_line) override { | 217 void SetUpCommandLine(base::CommandLine* command_line) override { |
148 #if defined(OS_CHROMEOS) | 218 #if defined(OS_CHROMEOS) |
149 command_line->AppendSwitch( | 219 command_line->AppendSwitch( |
150 chromeos::switches::kIgnoreUserProfileMappingForTests); | 220 chromeos::switches::kIgnoreUserProfileMappingForTests); |
151 #endif | 221 #endif |
152 } | 222 } |
153 }; | 223 }; |
154 | 224 |
155 #if defined(OS_MACOSX) | 225 // Android does not support multi-profiles, and CrOS multi-profiles |
| 226 // implementation is too different for these tests. |
| 227 #if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) |
156 | 228 |
157 // Delete single profile and make sure a new one is created. | 229 // Delete single profile and make sure a new one is created. |
158 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, DeleteSingletonProfile) { | 230 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, DeleteSingletonProfile) { |
159 ProfileManager* profile_manager = g_browser_process->profile_manager(); | 231 ProfileManager* profile_manager = g_browser_process->profile_manager(); |
160 ProfileAttributesStorage& storage = | 232 ProfileAttributesStorage& storage = |
161 profile_manager->GetProfileAttributesStorage(); | 233 profile_manager->GetProfileAttributesStorage(); |
162 ProfileRemovalObserver observer; | 234 ProfileRemovalObserver observer; |
163 | 235 |
164 // We should start out with 1 profile. | 236 // We should start out with 1 profile. |
165 ASSERT_EQ(1u, storage.GetNumberOfProfiles()); | 237 ASSERT_EQ(1u, storage.GetNumberOfProfiles()); |
166 | 238 |
167 // Delete singleton profile. | 239 // Delete singleton profile. |
168 base::FilePath singleton_profile_path = | 240 base::FilePath singleton_profile_path = |
169 storage.GetAllProfilesAttributes().front()->GetPath(); | 241 storage.GetAllProfilesAttributes().front()->GetPath(); |
170 EXPECT_FALSE(singleton_profile_path.empty()); | 242 EXPECT_FALSE(singleton_profile_path.empty()); |
171 base::RunLoop run_loop; | 243 MultipleProfileDeletionObserver profile_deletion_observer(1u); |
172 profile_manager->ScheduleProfileForDeletion( | 244 profile_manager->ScheduleProfileForDeletion( |
173 singleton_profile_path, | 245 singleton_profile_path, |
174 base::Bind(&OnUnblockOnProfileCreation, &run_loop)); | 246 profile_deletion_observer.OnProfileCreatedClosure()); |
175 | 247 |
176 // Run the message loop until the profile is actually deleted (as indicated | 248 // Run the message loop until the profile is actually deleted (as indicated |
177 // by the callback above being called). | 249 // by the callback above being called). |
178 run_loop.Run(); | 250 profile_deletion_observer.Wait(); |
179 | 251 |
180 // Make sure a new profile was created automatically. | 252 // Make sure a new profile was created automatically. |
181 EXPECT_EQ(1u, storage.GetNumberOfProfiles()); | 253 EXPECT_EQ(1u, storage.GetNumberOfProfiles()); |
182 base::FilePath new_profile_path = | 254 base::FilePath new_profile_path = |
183 storage.GetAllProfilesAttributes().front()->GetPath(); | 255 storage.GetAllProfilesAttributes().front()->GetPath(); |
184 EXPECT_NE(new_profile_path.value(), singleton_profile_path.value()); | 256 EXPECT_NE(new_profile_path.value(), singleton_profile_path.value()); |
185 | 257 |
186 // Make sure that last used profile preference is set correctly. | 258 // Make sure that last used profile preference is set correctly. |
187 Profile* last_used = ProfileManager::GetLastUsedProfile(); | 259 Profile* last_used = ProfileManager::GetLastUsedProfile(); |
188 EXPECT_EQ(new_profile_path.value(), last_used->GetPath().value()); | 260 EXPECT_EQ(new_profile_path.value(), last_used->GetPath().value()); |
189 | 261 |
190 // Make sure the last used profile was set correctly before the notification | 262 // Make sure the last used profile was set correctly before the notification |
191 // was sent. | 263 // was sent. |
192 std::string last_used_profile_name = | 264 std::string last_used_profile_name = |
193 last_used->GetPath().BaseName().MaybeAsASCII(); | 265 last_used->GetPath().BaseName().MaybeAsASCII(); |
194 EXPECT_EQ(last_used_profile_name, observer.last_used_profile_name()); | 266 EXPECT_EQ(last_used_profile_name, observer.last_used_profile_name()); |
195 } | 267 } |
196 | 268 |
| 269 // Delete inactive profile in a multi profile setup and make sure current |
| 270 // browser is not affected. |
| 271 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, DeleteInactiveProfile) { |
| 272 ProfileManager* profile_manager = g_browser_process->profile_manager(); |
| 273 ProfileAttributesStorage& storage = |
| 274 profile_manager->GetProfileAttributesStorage(); |
| 275 base::FilePath current_profile_path = browser()->profile()->GetPath(); |
| 276 |
| 277 // Create an additional profile. |
| 278 base::FilePath new_path = profile_manager->GenerateNextProfileDirectoryPath(); |
| 279 base::RunLoop run_loop; |
| 280 profile_manager->CreateProfileAsync( |
| 281 new_path, base::Bind(&OnUnblockOnProfileCreation, &run_loop), |
| 282 base::string16(), std::string(), std::string()); |
| 283 run_loop.Run(); |
| 284 |
| 285 ASSERT_EQ(2u, storage.GetNumberOfProfiles()); |
| 286 |
| 287 // Delete inactive profile. |
| 288 MultipleProfileDeletionObserver profile_deletion_observer(1u); |
| 289 profile_manager->ScheduleProfileForDeletion( |
| 290 new_path, profile_deletion_observer.OnProfileCreatedClosure()); |
| 291 // Profile will not be created, call OnProfileCreatedClosure() directly to |
| 292 // fulfill |profile_deletion_observer| expectataion. |
| 293 profile_deletion_observer.OnProfileCreatedClosure().Run( |
| 294 browser()->profile(), Profile::CREATE_STATUS_INITIALIZED); |
| 295 profile_deletion_observer.Wait(); |
| 296 |
| 297 // Make sure there only preexisted profile left. |
| 298 EXPECT_EQ(1u, storage.GetNumberOfProfiles()); |
| 299 EXPECT_EQ(current_profile_path, |
| 300 storage.GetAllProfilesAttributes().front()->GetPath()); |
| 301 |
| 302 // Make sure that last used profile preference is set correctly. |
| 303 Profile* last_used = ProfileManager::GetLastUsedProfile(); |
| 304 EXPECT_EQ(current_profile_path, last_used->GetPath()); |
| 305 } |
| 306 |
| 307 // Delete current profile in a multi profile setup and make sure an existing one |
| 308 // is loaded. |
| 309 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, DeleteCurrentProfile) { |
| 310 ProfileManager* profile_manager = g_browser_process->profile_manager(); |
| 311 ProfileAttributesStorage& storage = |
| 312 profile_manager->GetProfileAttributesStorage(); |
| 313 |
| 314 // Create an additional profile. |
| 315 base::FilePath new_path = profile_manager->GenerateNextProfileDirectoryPath(); |
| 316 base::RunLoop run_loop; |
| 317 profile_manager->CreateProfileAsync( |
| 318 new_path, base::Bind(&OnUnblockOnProfileCreation, &run_loop), |
| 319 base::string16(), std::string(), std::string()); |
| 320 run_loop.Run(); |
| 321 |
| 322 ASSERT_EQ(2u, storage.GetNumberOfProfiles()); |
| 323 |
| 324 // Delete current profile. |
| 325 MultipleProfileDeletionObserver profile_deletion_observer(1u); |
| 326 profile_manager->ScheduleProfileForDeletion( |
| 327 browser()->profile()->GetPath(), |
| 328 profile_deletion_observer.OnProfileCreatedClosure()); |
| 329 profile_deletion_observer.Wait(); |
| 330 |
| 331 // Make sure a profile created earlier become the only profile. |
| 332 EXPECT_EQ(1u, storage.GetNumberOfProfiles()); |
| 333 EXPECT_EQ(new_path, storage.GetAllProfilesAttributes().front()->GetPath()); |
| 334 |
| 335 // Make sure that last used profile preference is set correctly. |
| 336 Profile* last_used = ProfileManager::GetLastUsedProfile(); |
| 337 EXPECT_EQ(new_path, last_used->GetPath()); |
| 338 } |
| 339 |
197 // Delete all profiles in a multi profile setup and make sure a new one is | 340 // Delete all profiles in a multi profile setup and make sure a new one is |
198 // created. | 341 // created. |
199 // Crashes/CHECKs. See crbug.com/104851 | 342 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, DeleteAllProfiles) { |
200 IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, DISABLED_DeleteAllProfiles) { | |
201 ProfileManager* profile_manager = g_browser_process->profile_manager(); | 343 ProfileManager* profile_manager = g_browser_process->profile_manager(); |
202 ProfileAttributesStorage& storage = | 344 ProfileAttributesStorage& storage = |
203 profile_manager->GetProfileAttributesStorage(); | 345 profile_manager->GetProfileAttributesStorage(); |
204 | 346 |
205 // Create an additional profile. | 347 // Create an additional profile. |
206 base::FilePath new_path = profile_manager->GenerateNextProfileDirectoryPath(); | 348 base::FilePath new_path = profile_manager->GenerateNextProfileDirectoryPath(); |
207 base::RunLoop run_loop; | 349 base::RunLoop run_loop; |
208 profile_manager->CreateProfileAsync( | 350 profile_manager->CreateProfileAsync( |
209 new_path, base::Bind(&OnUnblockOnProfileCreation, &run_loop), | 351 new_path, base::Bind(&OnUnblockOnProfileCreation, &run_loop), |
210 base::string16(), std::string(), std::string()); | 352 base::string16(), std::string(), std::string()); |
211 | 353 |
212 // Run the message loop to allow profile creation to take place; the loop is | 354 // Run the message loop to allow profile creation to take place; the loop is |
213 // terminated by OnUnblockOnProfileCreation when the profile is created. | 355 // terminated by OnUnblockOnProfileCreation when the profile is created. |
214 run_loop.Run(); | 356 run_loop.Run(); |
215 | 357 |
216 ASSERT_EQ(2u, storage.GetNumberOfProfiles()); | 358 ASSERT_EQ(2u, storage.GetNumberOfProfiles()); |
217 | 359 |
218 // Delete all profiles. | 360 // Delete all profiles. |
| 361 MultipleProfileDeletionObserver profile_deletion_observer(2u); |
219 std::vector<ProfileAttributesEntry*> entries = | 362 std::vector<ProfileAttributesEntry*> entries = |
220 storage.GetAllProfilesAttributes(); | 363 storage.GetAllProfilesAttributes(); |
221 std::vector<base::FilePath> old_profile_paths; | 364 std::vector<base::FilePath> old_profile_paths; |
222 for (ProfileAttributesEntry* entry : entries) { | 365 for (ProfileAttributesEntry* entry : entries) { |
223 base::FilePath profile_path = entry->GetPath(); | 366 base::FilePath profile_path = entry->GetPath(); |
224 EXPECT_FALSE(profile_path.empty()); | 367 EXPECT_FALSE(profile_path.empty()); |
225 profile_manager->ScheduleProfileForDeletion( | 368 profile_manager->ScheduleProfileForDeletion( |
226 profile_path, ProfileManager::CreateCallback()); | 369 profile_path, profile_deletion_observer.OnProfileCreatedClosure()); |
227 old_profile_paths.push_back(profile_path); | 370 old_profile_paths.push_back(profile_path); |
228 } | 371 } |
229 | 372 profile_deletion_observer.Wait(); |
230 // Spin things so deletion can take place. | |
231 content::RunAllPendingInMessageLoop(); | |
232 | 373 |
233 // Make sure a new profile was created automatically. | 374 // Make sure a new profile was created automatically. |
234 EXPECT_EQ(1u, storage.GetNumberOfProfiles()); | 375 EXPECT_EQ(1u, storage.GetNumberOfProfiles()); |
235 base::FilePath new_profile_path = | 376 base::FilePath new_profile_path = |
236 storage.GetAllProfilesAttributes().front()->GetPath(); | 377 storage.GetAllProfilesAttributes().front()->GetPath(); |
237 for (const base::FilePath& old_profile_path : old_profile_paths) | 378 for (const base::FilePath& old_profile_path : old_profile_paths) |
238 EXPECT_NE(old_profile_path, new_profile_path); | 379 EXPECT_NE(old_profile_path, new_profile_path); |
239 | 380 |
240 // Make sure that last used profile preference is set correctly. | 381 // Make sure that last used profile preference is set correctly. |
241 Profile* last_used = ProfileManager::GetLastUsedProfile(); | 382 Profile* last_used = ProfileManager::GetLastUsedProfile(); |
242 EXPECT_EQ(new_profile_path, last_used->GetPath()); | 383 EXPECT_EQ(new_profile_path, last_used->GetPath()); |
243 } | 384 } |
244 #endif // OS_MACOSX | 385 #endif // !defined(OS_ANDROID) && !defined(OS_CHROMEOS) |
245 | 386 |
246 #if defined(OS_CHROMEOS) | 387 #if defined(OS_CHROMEOS) |
247 | 388 |
248 class ProfileManagerCrOSBrowserTest : public ProfileManagerBrowserTest { | 389 class ProfileManagerCrOSBrowserTest : public ProfileManagerBrowserTest { |
249 protected: | 390 protected: |
250 void SetUpCommandLine(base::CommandLine* command_line) override { | 391 void SetUpCommandLine(base::CommandLine* command_line) override { |
251 // Use a user hash other than the default chrome::kTestUserProfileDir | 392 // Use a user hash other than the default chrome::kTestUserProfileDir |
252 // so that the prefix case is tested. | 393 // so that the prefix case is tested. |
253 command_line->AppendSwitchASCII(chromeos::switches::kLoginProfile, | 394 command_line->AppendSwitchASCII(chromeos::switches::kLoginProfile, |
254 "test-user-hash"); | 395 "test-user-hash"); |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
500 | 641 |
501 EXPECT_FALSE(profile->HasOffTheRecordProfile()); | 642 EXPECT_FALSE(profile->HasOffTheRecordProfile()); |
502 EXPECT_FALSE(profile_manager->IsValidProfile(incognito_profile)); | 643 EXPECT_FALSE(profile_manager->IsValidProfile(incognito_profile)); |
503 EXPECT_EQ(initial_profile_count, profile_manager->GetNumberOfProfiles()); | 644 EXPECT_EQ(initial_profile_count, profile_manager->GetNumberOfProfiles()); |
504 // After destroying the incognito profile incognito preferences should be | 645 // After destroying the incognito profile incognito preferences should be |
505 // cleared so the default save path should be taken from the main profile. | 646 // cleared so the default save path should be taken from the main profile. |
506 EXPECT_FALSE(profile->GetOffTheRecordPrefs() | 647 EXPECT_FALSE(profile->GetOffTheRecordPrefs() |
507 ->GetFilePath(prefs::kSaveFileDefaultDirectory) | 648 ->GetFilePath(prefs::kSaveFileDefaultDirectory) |
508 .empty()); | 649 .empty()); |
509 } | 650 } |
OLD | NEW |