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