| 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 "chrome/browser/profiles/profile_manager.h" | 5 #include "chrome/browser/profiles/profile_manager.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 183 return; | 183 return; |
| 184 } | 184 } |
| 185 if (!is_mounted) | 185 if (!is_mounted) |
| 186 LOG(ERROR) << "Cryptohome is not mounted."; | 186 LOG(ERROR) << "Cryptohome is not mounted."; |
| 187 } | 187 } |
| 188 | 188 |
| 189 #endif | 189 #endif |
| 190 | 190 |
| 191 } // namespace | 191 } // namespace |
| 192 | 192 |
| 193 ProfileManager::ProfileManager(const base::FilePath& user_data_dir) |
| 194 : user_data_dir_(user_data_dir), |
| 195 logged_in_(false), |
| 196 #if !defined(OS_ANDROID) && !defined(OS_IOS) |
| 197 browser_list_observer_(this), |
| 198 #endif |
| 199 closing_all_browsers_(false) { |
| 200 #if defined(OS_CHROMEOS) |
| 201 registrar_.Add( |
| 202 this, |
| 203 chrome::NOTIFICATION_LOGIN_USER_CHANGED, |
| 204 content::NotificationService::AllSources()); |
| 205 #endif |
| 206 registrar_.Add( |
| 207 this, |
| 208 chrome::NOTIFICATION_BROWSER_OPENED, |
| 209 content::NotificationService::AllSources()); |
| 210 registrar_.Add( |
| 211 this, |
| 212 chrome::NOTIFICATION_BROWSER_CLOSED, |
| 213 content::NotificationService::AllSources()); |
| 214 registrar_.Add( |
| 215 this, |
| 216 chrome::NOTIFICATION_CLOSE_ALL_BROWSERS_REQUEST, |
| 217 content::NotificationService::AllSources()); |
| 218 registrar_.Add( |
| 219 this, |
| 220 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, |
| 221 content::NotificationService::AllSources()); |
| 222 registrar_.Add( |
| 223 this, |
| 224 chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED, |
| 225 content::NotificationService::AllSources()); |
| 226 |
| 227 if (ProfileShortcutManager::IsFeatureEnabled() && !user_data_dir_.empty()) |
| 228 profile_shortcut_manager_.reset(ProfileShortcutManager::Create( |
| 229 this)); |
| 230 } |
| 231 |
| 232 ProfileManager::~ProfileManager() { |
| 233 } |
| 234 |
| 193 #if defined(ENABLE_SESSION_SERVICE) | 235 #if defined(ENABLE_SESSION_SERVICE) |
| 194 // static | 236 // static |
| 195 void ProfileManager::ShutdownSessionServices() { | 237 void ProfileManager::ShutdownSessionServices() { |
| 196 ProfileManager* pm = g_browser_process->profile_manager(); | 238 ProfileManager* pm = g_browser_process->profile_manager(); |
| 197 if (!pm) // Is NULL when running unit tests. | 239 if (!pm) // Is NULL when running unit tests. |
| 198 return; | 240 return; |
| 199 std::vector<Profile*> profiles(pm->GetLoadedProfiles()); | 241 std::vector<Profile*> profiles(pm->GetLoadedProfiles()); |
| 200 for (size_t i = 0; i < profiles.size(); ++i) | 242 for (size_t i = 0; i < profiles.size(); ++i) |
| 201 SessionServiceFactory::ShutdownForProfile(profiles[i]); | 243 SessionServiceFactory::ShutdownForProfile(profiles[i]); |
| 202 } | 244 } |
| 203 #endif | 245 #endif |
| 204 | 246 |
| 205 // static | 247 // static |
| 206 void ProfileManager::NukeDeletedProfilesFromDisk() { | 248 void ProfileManager::NukeDeletedProfilesFromDisk() { |
| 207 for (std::vector<base::FilePath>::iterator it = | 249 for (std::vector<base::FilePath>::iterator it = |
| 208 ProfilesToDelete().begin(); | 250 ProfilesToDelete().begin(); |
| 209 it != ProfilesToDelete().end(); | 251 it != ProfilesToDelete().end(); |
| 210 ++it) { | 252 ++it) { |
| 211 NukeProfileFromDisk(*it); | 253 NukeProfileFromDisk(*it); |
| 212 } | 254 } |
| 213 ProfilesToDelete().clear(); | 255 ProfilesToDelete().clear(); |
| 214 } | 256 } |
| 215 | 257 |
| 216 // static | 258 // static |
| 217 // TODO(skuhne): Remove this method once all clients are migrated. | |
| 218 Profile* ProfileManager::GetDefaultProfile() { | |
| 219 ProfileManager* profile_manager = g_browser_process->profile_manager(); | |
| 220 return profile_manager->GetActiveUserOrOffTheRecordProfileFromPath( | |
| 221 profile_manager->user_data_dir_); | |
| 222 } | |
| 223 | |
| 224 // static | |
| 225 Profile* ProfileManager::GetLastUsedProfile() { | 259 Profile* ProfileManager::GetLastUsedProfile() { |
| 226 ProfileManager* profile_manager = g_browser_process->profile_manager(); | 260 ProfileManager* profile_manager = g_browser_process->profile_manager(); |
| 227 return profile_manager->GetLastUsedProfile(profile_manager->user_data_dir_); | 261 return profile_manager->GetLastUsedProfile(profile_manager->user_data_dir_); |
| 228 } | 262 } |
| 229 | 263 |
| 230 // static | 264 // static |
| 231 Profile* ProfileManager::GetLastUsedProfileAllowedByPolicy() { | 265 Profile* ProfileManager::GetLastUsedProfileAllowedByPolicy() { |
| 232 Profile* profile = GetLastUsedProfile(); | 266 Profile* profile = GetLastUsedProfile(); |
| 233 if (IncognitoModePrefs::GetAvailability(profile->GetPrefs()) == | 267 if (IncognitoModePrefs::GetAvailability(profile->GetPrefs()) == |
| 234 IncognitoModePrefs::FORCED) { | 268 IncognitoModePrefs::FORCED) { |
| 235 return profile->GetOffTheRecordProfile(); | 269 return profile->GetOffTheRecordProfile(); |
| 236 } | 270 } |
| 237 return profile; | 271 return profile; |
| 238 } | 272 } |
| 239 | 273 |
| 240 // static | 274 // static |
| 241 std::vector<Profile*> ProfileManager::GetLastOpenedProfiles() { | 275 std::vector<Profile*> ProfileManager::GetLastOpenedProfiles() { |
| 242 ProfileManager* profile_manager = g_browser_process->profile_manager(); | 276 ProfileManager* profile_manager = g_browser_process->profile_manager(); |
| 243 return profile_manager->GetLastOpenedProfiles( | 277 return profile_manager->GetLastOpenedProfiles( |
| 244 profile_manager->user_data_dir_); | 278 profile_manager->user_data_dir_); |
| 245 } | 279 } |
| 246 | 280 |
| 247 ProfileManager::ProfileManager(const base::FilePath& user_data_dir) | 281 // static |
| 248 : user_data_dir_(user_data_dir), | 282 Profile* ProfileManager::GetPrimaryUserProfile() { |
| 249 logged_in_(false), | 283 ProfileManager* profile_manager = g_browser_process->profile_manager(); |
| 250 | 284 #if defined(OS_CHROMEOS) |
| 251 #if !defined(OS_ANDROID) && !defined(OS_IOS) | 285 if (!profile_manager->IsLoggedIn() || !chromeos::UserManager::IsInitialized()) |
| 252 browser_list_observer_(this), | 286 return profile_manager->GetActiveUserOrOffTheRecordProfileFromPath( |
| 287 profile_manager->user_data_dir()); |
| 288 chromeos::UserManager* manager = chromeos::UserManager::Get(); |
| 289 // Note: The user manager will take care of guest profiles. |
| 290 return manager->GetProfileByUser(manager->GetPrimaryUser()); |
| 291 #else |
| 292 return profile_manager->GetActiveUserOrOffTheRecordProfileFromPath( |
| 293 profile_manager->user_data_dir()); |
| 253 #endif | 294 #endif |
| 254 closing_all_browsers_(false) { | |
| 255 #if defined(OS_CHROMEOS) | |
| 256 registrar_.Add( | |
| 257 this, | |
| 258 chrome::NOTIFICATION_LOGIN_USER_CHANGED, | |
| 259 content::NotificationService::AllSources()); | |
| 260 #endif | |
| 261 registrar_.Add( | |
| 262 this, | |
| 263 chrome::NOTIFICATION_BROWSER_OPENED, | |
| 264 content::NotificationService::AllSources()); | |
| 265 registrar_.Add( | |
| 266 this, | |
| 267 chrome::NOTIFICATION_BROWSER_CLOSED, | |
| 268 content::NotificationService::AllSources()); | |
| 269 registrar_.Add( | |
| 270 this, | |
| 271 chrome::NOTIFICATION_CLOSE_ALL_BROWSERS_REQUEST, | |
| 272 content::NotificationService::AllSources()); | |
| 273 registrar_.Add( | |
| 274 this, | |
| 275 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED, | |
| 276 content::NotificationService::AllSources()); | |
| 277 registrar_.Add( | |
| 278 this, | |
| 279 chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED, | |
| 280 content::NotificationService::AllSources()); | |
| 281 | |
| 282 if (ProfileShortcutManager::IsFeatureEnabled() && !user_data_dir_.empty()) | |
| 283 profile_shortcut_manager_.reset(ProfileShortcutManager::Create( | |
| 284 this)); | |
| 285 } | 295 } |
| 286 | 296 |
| 287 ProfileManager::~ProfileManager() { | 297 // static |
| 298 Profile* ProfileManager::GetActiveUserProfile() { |
| 299 ProfileManager* profile_manager = g_browser_process->profile_manager(); |
| 300 #if defined(OS_CHROMEOS) |
| 301 if (!chromeos::UserManager::IsMultipleProfilesAllowed() || |
| 302 !profile_manager->IsLoggedIn() || |
| 303 !chromeos::UserManager::IsInitialized()) |
| 304 return profile_manager->GetActiveUserOrOffTheRecordProfileFromPath( |
| 305 profile_manager->user_data_dir()); |
| 306 chromeos::UserManager* manager = chromeos::UserManager::Get(); |
| 307 // Note: The user manager will take care of guest profiles. |
| 308 return manager->GetProfileByUser(manager->GetActiveUser()); |
| 309 #else |
| 310 return profile_manager->GetActiveUserOrOffTheRecordProfileFromPath( |
| 311 profile_manager->user_data_dir()); |
| 312 #endif |
| 313 } |
| 314 |
| 315 Profile* ProfileManager::GetProfile(const base::FilePath& profile_dir) { |
| 316 TRACE_EVENT0("browser", "ProfileManager::GetProfile") |
| 317 // If the profile is already loaded (e.g., chrome.exe launched twice), just |
| 318 // return it. |
| 319 Profile* profile = GetProfileByPath(profile_dir); |
| 320 if (NULL != profile) |
| 321 return profile; |
| 322 |
| 323 profile = CreateProfileHelper(profile_dir); |
| 324 DCHECK(profile); |
| 325 if (profile) { |
| 326 bool result = AddProfile(profile); |
| 327 DCHECK(result); |
| 328 } |
| 329 return profile; |
| 330 } |
| 331 |
| 332 size_t ProfileManager::GetNumberOfProfiles() { |
| 333 return GetProfileInfoCache().GetNumberOfProfiles(); |
| 334 } |
| 335 |
| 336 void ProfileManager::CreateProfileAsync( |
| 337 const base::FilePath& profile_path, |
| 338 const CreateCallback& callback, |
| 339 const base::string16& name, |
| 340 const base::string16& icon_url, |
| 341 const std::string& managed_user_id) { |
| 342 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 343 |
| 344 // Make sure that this profile is not pending deletion. |
| 345 if (IsProfileMarkedForDeletion(profile_path)) { |
| 346 if (!callback.is_null()) |
| 347 callback.Run(NULL, Profile::CREATE_STATUS_LOCAL_FAIL); |
| 348 return; |
| 349 } |
| 350 |
| 351 // Create the profile if needed and collect its ProfileInfo. |
| 352 ProfilesInfoMap::iterator iter = profiles_info_.find(profile_path); |
| 353 ProfileInfo* info = NULL; |
| 354 |
| 355 if (iter != profiles_info_.end()) { |
| 356 info = iter->second.get(); |
| 357 } else { |
| 358 // Initiate asynchronous creation process. |
| 359 info = RegisterProfile(CreateProfileAsyncHelper(profile_path, this), false); |
| 360 ProfileInfoCache& cache = GetProfileInfoCache(); |
| 361 // Get the icon index from the user's icon url |
| 362 size_t icon_index; |
| 363 std::string icon_url_std = UTF16ToASCII(icon_url); |
| 364 if (cache.IsDefaultAvatarIconUrl(icon_url_std, &icon_index)) { |
| 365 // add profile to cache with user selected name and avatar |
| 366 cache.AddProfileToCache(profile_path, name, base::string16(), icon_index, |
| 367 managed_user_id); |
| 368 } |
| 369 |
| 370 if (!managed_user_id.empty()) { |
| 371 content::RecordAction( |
| 372 UserMetricsAction("ManagedMode_LocallyManagedUserCreated")); |
| 373 } |
| 374 |
| 375 ProfileMetrics::UpdateReportedProfilesStatistics(this); |
| 376 } |
| 377 |
| 378 // Call or enqueue the callback. |
| 379 if (!callback.is_null()) { |
| 380 if (iter != profiles_info_.end() && info->created) { |
| 381 Profile* profile = info->profile.get(); |
| 382 // If this was the guest profile, apply settings. |
| 383 if (profile->GetPath() == ProfileManager::GetGuestProfilePath()) |
| 384 SetGuestProfilePrefs(profile); |
| 385 // Profile has already been created. Run callback immediately. |
| 386 callback.Run(profile, Profile::CREATE_STATUS_INITIALIZED); |
| 387 } else { |
| 388 // Profile is either already in the process of being created, or new. |
| 389 // Add callback to the list. |
| 390 info->callbacks.push_back(callback); |
| 391 } |
| 392 } |
| 393 } |
| 394 |
| 395 bool ProfileManager::IsValidProfile(Profile* profile) { |
| 396 for (ProfilesInfoMap::iterator iter = profiles_info_.begin(); |
| 397 iter != profiles_info_.end(); ++iter) { |
| 398 if (iter->second->created) { |
| 399 Profile* candidate = iter->second->profile.get(); |
| 400 if (candidate == profile || |
| 401 (candidate->HasOffTheRecordProfile() && |
| 402 candidate->GetOffTheRecordProfile() == profile)) { |
| 403 return true; |
| 404 } |
| 405 } |
| 406 } |
| 407 return false; |
| 288 } | 408 } |
| 289 | 409 |
| 290 base::FilePath ProfileManager::GetInitialProfileDir() { | 410 base::FilePath ProfileManager::GetInitialProfileDir() { |
| 291 base::FilePath relative_profile_dir; | 411 base::FilePath relative_profile_dir; |
| 292 #if defined(OS_CHROMEOS) | 412 #if defined(OS_CHROMEOS) |
| 293 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); | 413 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); |
| 294 if (logged_in_) { | 414 if (logged_in_) { |
| 295 base::FilePath profile_dir; | 415 base::FilePath profile_dir; |
| 296 // If the user has logged in, pick up the new profile. | 416 // If the user has logged in, pick up the new profile. |
| 297 if (command_line.HasSwitch(chromeos::switches::kLoginProfile)) { | 417 if (command_line.HasSwitch(chromeos::switches::kLoginProfile)) { |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 390 if (!(*it)->GetAsString(&profile) || profile.empty()) { | 510 if (!(*it)->GetAsString(&profile) || profile.empty()) { |
| 391 LOG(WARNING) << "Invalid entry in " << prefs::kProfilesLastActive; | 511 LOG(WARNING) << "Invalid entry in " << prefs::kProfilesLastActive; |
| 392 continue; | 512 continue; |
| 393 } | 513 } |
| 394 to_return.push_back(GetProfile(user_data_dir.AppendASCII(profile))); | 514 to_return.push_back(GetProfile(user_data_dir.AppendASCII(profile))); |
| 395 } | 515 } |
| 396 } | 516 } |
| 397 return to_return; | 517 return to_return; |
| 398 } | 518 } |
| 399 | 519 |
| 400 Profile* ProfileManager::GetPrimaryUserProfile() { | |
| 401 #if defined(OS_CHROMEOS) | |
| 402 ProfileManager* profile_manager = g_browser_process->profile_manager(); | |
| 403 if (!profile_manager->IsLoggedIn() || !chromeos::UserManager::IsInitialized()) | |
| 404 return GetDefaultProfile(); | |
| 405 chromeos::UserManager* manager = chromeos::UserManager::Get(); | |
| 406 // Note: The user manager will take care of guest profiles. | |
| 407 return manager->GetProfileByUser(manager->GetPrimaryUser()); | |
| 408 #else | |
| 409 return GetDefaultProfile(); | |
| 410 #endif | |
| 411 } | |
| 412 | |
| 413 Profile* ProfileManager::GetActiveUserProfile() { | |
| 414 #if defined(OS_CHROMEOS) | |
| 415 ProfileManager* profile_manager = g_browser_process->profile_manager(); | |
| 416 if (!chromeos::UserManager::IsMultipleProfilesAllowed() || | |
| 417 !profile_manager->IsLoggedIn() || | |
| 418 !chromeos::UserManager::IsInitialized()) | |
| 419 return GetDefaultProfile(); | |
| 420 chromeos::UserManager* manager = chromeos::UserManager::Get(); | |
| 421 // Note: The user manager will take care of guest profiles. | |
| 422 return manager->GetProfileByUser(manager->GetActiveUser()); | |
| 423 #else | |
| 424 return GetDefaultProfile(); | |
| 425 #endif | |
| 426 } | |
| 427 | |
| 428 bool ProfileManager::IsValidProfile(Profile* profile) { | |
| 429 for (ProfilesInfoMap::iterator iter = profiles_info_.begin(); | |
| 430 iter != profiles_info_.end(); ++iter) { | |
| 431 if (iter->second->created) { | |
| 432 Profile* candidate = iter->second->profile.get(); | |
| 433 if (candidate == profile || | |
| 434 (candidate->HasOffTheRecordProfile() && | |
| 435 candidate->GetOffTheRecordProfile() == profile)) { | |
| 436 return true; | |
| 437 } | |
| 438 } | |
| 439 } | |
| 440 return false; | |
| 441 } | |
| 442 | |
| 443 std::vector<Profile*> ProfileManager::GetLoadedProfiles() const { | 520 std::vector<Profile*> ProfileManager::GetLoadedProfiles() const { |
| 444 std::vector<Profile*> profiles; | 521 std::vector<Profile*> profiles; |
| 445 for (ProfilesInfoMap::const_iterator iter = profiles_info_.begin(); | 522 for (ProfilesInfoMap::const_iterator iter = profiles_info_.begin(); |
| 446 iter != profiles_info_.end(); ++iter) { | 523 iter != profiles_info_.end(); ++iter) { |
| 447 if (iter->second->created) | 524 if (iter->second->created) |
| 448 profiles.push_back(iter->second->profile.get()); | 525 profiles.push_back(iter->second->profile.get()); |
| 449 } | 526 } |
| 450 return profiles; | 527 return profiles; |
| 451 } | 528 } |
| 452 | 529 |
| 453 Profile* ProfileManager::GetProfile(const base::FilePath& profile_dir) { | |
| 454 TRACE_EVENT0("browser", "ProfileManager::GetProfile") | |
| 455 // If the profile is already loaded (e.g., chrome.exe launched twice), just | |
| 456 // return it. | |
| 457 Profile* profile = GetProfileByPath(profile_dir); | |
| 458 if (NULL != profile) | |
| 459 return profile; | |
| 460 | |
| 461 profile = CreateProfileHelper(profile_dir); | |
| 462 DCHECK(profile); | |
| 463 if (profile) { | |
| 464 bool result = AddProfile(profile); | |
| 465 DCHECK(result); | |
| 466 } | |
| 467 return profile; | |
| 468 } | |
| 469 | |
| 470 void ProfileManager::CreateProfileAsync( | |
| 471 const base::FilePath& profile_path, | |
| 472 const CreateCallback& callback, | |
| 473 const base::string16& name, | |
| 474 const base::string16& icon_url, | |
| 475 const std::string& managed_user_id) { | |
| 476 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 477 | |
| 478 // Make sure that this profile is not pending deletion. | |
| 479 if (IsProfileMarkedForDeletion(profile_path)) { | |
| 480 if (!callback.is_null()) | |
| 481 callback.Run(NULL, Profile::CREATE_STATUS_LOCAL_FAIL); | |
| 482 return; | |
| 483 } | |
| 484 | |
| 485 // Create the profile if needed and collect its ProfileInfo. | |
| 486 ProfilesInfoMap::iterator iter = profiles_info_.find(profile_path); | |
| 487 ProfileInfo* info = NULL; | |
| 488 | |
| 489 if (iter != profiles_info_.end()) { | |
| 490 info = iter->second.get(); | |
| 491 } else { | |
| 492 // Initiate asynchronous creation process. | |
| 493 info = RegisterProfile(CreateProfileAsyncHelper(profile_path, this), false); | |
| 494 ProfileInfoCache& cache = GetProfileInfoCache(); | |
| 495 // Get the icon index from the user's icon url | |
| 496 size_t icon_index; | |
| 497 std::string icon_url_std = UTF16ToASCII(icon_url); | |
| 498 if (cache.IsDefaultAvatarIconUrl(icon_url_std, &icon_index)) { | |
| 499 // add profile to cache with user selected name and avatar | |
| 500 cache.AddProfileToCache(profile_path, name, base::string16(), icon_index, | |
| 501 managed_user_id); | |
| 502 } | |
| 503 | |
| 504 if (!managed_user_id.empty()) { | |
| 505 content::RecordAction( | |
| 506 UserMetricsAction("ManagedMode_LocallyManagedUserCreated")); | |
| 507 } | |
| 508 | |
| 509 ProfileMetrics::UpdateReportedProfilesStatistics(this); | |
| 510 } | |
| 511 | |
| 512 // Call or enqueue the callback. | |
| 513 if (!callback.is_null()) { | |
| 514 if (iter != profiles_info_.end() && info->created) { | |
| 515 Profile* profile = info->profile.get(); | |
| 516 // If this was the guest profile, apply settings. | |
| 517 if (profile->GetPath() == ProfileManager::GetGuestProfilePath()) | |
| 518 SetGuestProfilePrefs(profile); | |
| 519 // Profile has already been created. Run callback immediately. | |
| 520 callback.Run(profile, Profile::CREATE_STATUS_INITIALIZED); | |
| 521 } else { | |
| 522 // Profile is either already in the process of being created, or new. | |
| 523 // Add callback to the list. | |
| 524 info->callbacks.push_back(callback); | |
| 525 } | |
| 526 } | |
| 527 } | |
| 528 | |
| 529 Profile* ProfileManager::GetActiveUserOrOffTheRecordProfileFromPath( | |
| 530 const base::FilePath& user_data_dir) { | |
| 531 #if defined(OS_CHROMEOS) | |
| 532 base::FilePath default_profile_dir(user_data_dir); | |
| 533 if (!logged_in_) { | |
| 534 default_profile_dir = profiles::GetDefaultProfileDir(user_data_dir); | |
| 535 Profile* profile = GetProfile(default_profile_dir); | |
| 536 // For cros, return the OTR profile so we never accidentally keep | |
| 537 // user data in an unencrypted profile. But doing this makes | |
| 538 // many of the browser and ui tests fail. We do return the OTR profile | |
| 539 // if the login-profile switch is passed so that we can test this. | |
| 540 if (ShouldGoOffTheRecord(profile)) | |
| 541 return profile->GetOffTheRecordProfile(); | |
| 542 DCHECK(!chromeos::UserManager::Get()->IsLoggedInAsGuest()); | |
| 543 return profile; | |
| 544 } | |
| 545 | |
| 546 default_profile_dir = default_profile_dir.Append(GetInitialProfileDir()); | |
| 547 ProfileInfo* profile_info = GetProfileInfoByPath(default_profile_dir); | |
| 548 // Fallback to default off-the-record profile, if user profile has not fully | |
| 549 // loaded yet. | |
| 550 if (profile_info && !profile_info->created) | |
| 551 default_profile_dir = profiles::GetDefaultProfileDir(user_data_dir); | |
| 552 | |
| 553 Profile* profile = GetProfile(default_profile_dir); | |
| 554 // Some unit tests didn't initialize the UserManager. | |
| 555 if (chromeos::UserManager::IsInitialized() && | |
| 556 chromeos::UserManager::Get()->IsLoggedInAsGuest()) | |
| 557 return profile->GetOffTheRecordProfile(); | |
| 558 return profile; | |
| 559 #else | |
| 560 base::FilePath default_profile_dir(user_data_dir); | |
| 561 default_profile_dir = default_profile_dir.Append(GetInitialProfileDir()); | |
| 562 return GetProfile(default_profile_dir); | |
| 563 #endif | |
| 564 } | |
| 565 | |
| 566 bool ProfileManager::AddProfile(Profile* profile) { | |
| 567 DCHECK(profile); | |
| 568 | |
| 569 // Make sure that we're not loading a profile with the same ID as a profile | |
| 570 // that's already loaded. | |
| 571 if (GetProfileByPath(profile->GetPath())) { | |
| 572 NOTREACHED() << "Attempted to add profile with the same path (" << | |
| 573 profile->GetPath().value() << | |
| 574 ") as an already-loaded profile."; | |
| 575 return false; | |
| 576 } | |
| 577 | |
| 578 RegisterProfile(profile, true); | |
| 579 InitProfileUserPrefs(profile); | |
| 580 DoFinalInit(profile, ShouldGoOffTheRecord(profile)); | |
| 581 return true; | |
| 582 } | |
| 583 | |
| 584 ProfileManager::ProfileInfo* ProfileManager::RegisterProfile( | |
| 585 Profile* profile, | |
| 586 bool created) { | |
| 587 ProfileInfo* info = new ProfileInfo(profile, created); | |
| 588 profiles_info_.insert( | |
| 589 std::make_pair(profile->GetPath(), linked_ptr<ProfileInfo>(info))); | |
| 590 return info; | |
| 591 } | |
| 592 | |
| 593 ProfileManager::ProfileInfo* ProfileManager::GetProfileInfoByPath( | |
| 594 const base::FilePath& path) const { | |
| 595 ProfilesInfoMap::const_iterator iter = profiles_info_.find(path); | |
| 596 return (iter == profiles_info_.end()) ? NULL : iter->second.get(); | |
| 597 } | |
| 598 | |
| 599 Profile* ProfileManager::GetProfileByPath(const base::FilePath& path) const { | 530 Profile* ProfileManager::GetProfileByPath(const base::FilePath& path) const { |
| 600 ProfileInfo* profile_info = GetProfileInfoByPath(path); | 531 ProfileInfo* profile_info = GetProfileInfoByPath(path); |
| 601 return profile_info ? profile_info->profile.get() : NULL; | 532 return profile_info ? profile_info->profile.get() : NULL; |
| 602 } | 533 } |
| 603 | 534 |
| 535 // static |
| 536 base::FilePath ProfileManager::CreateMultiProfileAsync( |
| 537 const base::string16& name, |
| 538 const base::string16& icon_url, |
| 539 const CreateCallback& callback, |
| 540 const std::string& managed_user_id) { |
| 541 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 542 |
| 543 ProfileManager* profile_manager = g_browser_process->profile_manager(); |
| 544 |
| 545 base::FilePath new_path = profile_manager->GenerateNextProfileDirectoryPath(); |
| 546 |
| 547 profile_manager->CreateProfileAsync(new_path, |
| 548 callback, |
| 549 name, |
| 550 icon_url, |
| 551 managed_user_id); |
| 552 return new_path; |
| 553 } |
| 554 |
| 555 // static |
| 556 base::FilePath ProfileManager::GetGuestProfilePath() { |
| 557 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 558 |
| 559 ProfileManager* profile_manager = g_browser_process->profile_manager(); |
| 560 |
| 561 base::FilePath guest_path = profile_manager->user_data_dir(); |
| 562 return guest_path.Append(chrome::kGuestProfileDir); |
| 563 } |
| 564 |
| 565 base::FilePath ProfileManager::GenerateNextProfileDirectoryPath() { |
| 566 PrefService* local_state = g_browser_process->local_state(); |
| 567 DCHECK(local_state); |
| 568 |
| 569 DCHECK(profiles::IsMultipleProfilesEnabled()); |
| 570 |
| 571 // Create the next profile in the next available directory slot. |
| 572 int next_directory = local_state->GetInteger(prefs::kProfilesNumCreated); |
| 573 std::string profile_name = chrome::kMultiProfileDirPrefix; |
| 574 profile_name.append(base::IntToString(next_directory)); |
| 575 base::FilePath new_path = user_data_dir_; |
| 576 #if defined(OS_WIN) |
| 577 new_path = new_path.Append(base::ASCIIToUTF16(profile_name)); |
| 578 #else |
| 579 new_path = new_path.Append(profile_name); |
| 580 #endif |
| 581 local_state->SetInteger(prefs::kProfilesNumCreated, ++next_directory); |
| 582 return new_path; |
| 583 } |
| 584 |
| 585 ProfileInfoCache& ProfileManager::GetProfileInfoCache() { |
| 586 if (!profile_info_cache_) { |
| 587 profile_info_cache_.reset(new ProfileInfoCache( |
| 588 g_browser_process->local_state(), user_data_dir_)); |
| 589 } |
| 590 return *profile_info_cache_.get(); |
| 591 } |
| 592 |
| 593 ProfileShortcutManager* ProfileManager::profile_shortcut_manager() { |
| 594 return profile_shortcut_manager_.get(); |
| 595 } |
| 596 |
| 597 void ProfileManager::ScheduleProfileForDeletion( |
| 598 const base::FilePath& profile_dir, |
| 599 const CreateCallback& callback) { |
| 600 DCHECK(profiles::IsMultipleProfilesEnabled()); |
| 601 PrefService* local_state = g_browser_process->local_state(); |
| 602 ProfileInfoCache& cache = GetProfileInfoCache(); |
| 603 |
| 604 if (profile_dir.BaseName().MaybeAsASCII() == |
| 605 local_state->GetString(prefs::kProfileLastUsed)) { |
| 606 // Update the last used profile pref before closing browser windows. This |
| 607 // way the correct last used profile is set for any notification observers. |
| 608 base::FilePath last_non_managed_profile_path; |
| 609 for (size_t i = 0; i < cache.GetNumberOfProfiles(); ++i) { |
| 610 base::FilePath cur_path = cache.GetPathOfProfileAtIndex(i); |
| 611 // Make sure that this profile is not pending deletion. |
| 612 if (cur_path != profile_dir && !cache.ProfileIsManagedAtIndex(i) && |
| 613 !IsProfileMarkedForDeletion(cur_path)) { |
| 614 last_non_managed_profile_path = cur_path; |
| 615 break; |
| 616 } |
| 617 } |
| 618 |
| 619 // If we're deleting the last (non-managed) profile, then create a new |
| 620 // profile in its place. |
| 621 const std::string last_non_managed_profile = |
| 622 last_non_managed_profile_path.BaseName().MaybeAsASCII(); |
| 623 if (last_non_managed_profile.empty()) { |
| 624 base::FilePath new_path = GenerateNextProfileDirectoryPath(); |
| 625 // Make sure the last used profile path is pointing at it. This way the |
| 626 // correct last used profile is set for any notification observers. |
| 627 local_state->SetString(prefs::kProfileLastUsed, |
| 628 new_path.BaseName().MaybeAsASCII()); |
| 629 CreateProfileAsync(new_path, |
| 630 callback, |
| 631 base::string16(), |
| 632 base::string16(), |
| 633 std::string()); |
| 634 } else { |
| 635 // On the Mac, the browser process is not killed when all browser windows |
| 636 // are closed, so just in case we are deleting the active profile, and no |
| 637 // other profile has been loaded, we must pre-load a next one. |
| 638 #if defined(OS_MACOSX) |
| 639 CreateProfileAsync(last_non_managed_profile_path, |
| 640 base::Bind(&ProfileManager::OnNewActiveProfileLoaded, |
| 641 base::Unretained(this), |
| 642 profile_dir, |
| 643 last_non_managed_profile_path, |
| 644 callback), |
| 645 base::string16(), |
| 646 base::string16(), |
| 647 std::string()); |
| 648 return; |
| 649 #else |
| 650 // For OS_MACOSX the pref is updated in the callback to make sure that |
| 651 // it isn't used before the profile is actually loaded. |
| 652 local_state->SetString(prefs::kProfileLastUsed, last_non_managed_profile); |
| 653 #endif |
| 654 } |
| 655 } |
| 656 FinishDeletingProfile(profile_dir); |
| 657 } |
| 658 |
| 659 // static |
| 660 void ProfileManager::CleanUpStaleProfiles( |
| 661 const std::vector<base::FilePath>& profile_paths) { |
| 662 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 663 |
| 664 for (std::vector<base::FilePath>::const_iterator it = profile_paths.begin(); |
| 665 it != profile_paths.end(); ++it) { |
| 666 NukeProfileFromDisk(*it); |
| 667 } |
| 668 } |
| 669 |
| 670 void ProfileManager::AutoloadProfiles() { |
| 671 // If running in the background is disabled for the browser, do not autoload |
| 672 // any profiles. |
| 673 PrefService* local_state = g_browser_process->local_state(); |
| 674 if (!local_state->HasPrefPath(prefs::kBackgroundModeEnabled) || |
| 675 !local_state->GetBoolean(prefs::kBackgroundModeEnabled)) { |
| 676 return; |
| 677 } |
| 678 |
| 679 ProfileInfoCache& cache = GetProfileInfoCache(); |
| 680 size_t number_of_profiles = cache.GetNumberOfProfiles(); |
| 681 for (size_t p = 0; p < number_of_profiles; ++p) { |
| 682 if (cache.GetBackgroundStatusOfProfileAtIndex(p)) { |
| 683 // If status is true, that profile is running background apps. By calling |
| 684 // GetProfile, we automatically cause the profile to be loaded which will |
| 685 // register it with the BackgroundModeManager. |
| 686 GetProfile(cache.GetPathOfProfileAtIndex(p)); |
| 687 } |
| 688 } |
| 689 } |
| 690 |
| 691 void ProfileManager::InitProfileUserPrefs(Profile* profile) { |
| 692 ProfileInfoCache& cache = GetProfileInfoCache(); |
| 693 |
| 694 if (profile->GetPath().DirName() != cache.GetUserDataDir()) |
| 695 return; |
| 696 |
| 697 size_t avatar_index; |
| 698 std::string profile_name; |
| 699 std::string managed_user_id; |
| 700 if (profile->IsGuestSession()) { |
| 701 profile_name = l10n_util::GetStringUTF8(IDS_PROFILES_GUEST_PROFILE_NAME); |
| 702 avatar_index = 0; |
| 703 } else { |
| 704 size_t profile_cache_index = |
| 705 cache.GetIndexOfProfileWithPath(profile->GetPath()); |
| 706 // If the cache has an entry for this profile, use the cache data. |
| 707 if (profile_cache_index != std::string::npos) { |
| 708 avatar_index = |
| 709 cache.GetAvatarIconIndexOfProfileAtIndex(profile_cache_index); |
| 710 profile_name = |
| 711 base::UTF16ToUTF8(cache.GetNameOfProfileAtIndex(profile_cache_index)); |
| 712 managed_user_id = |
| 713 cache.GetManagedUserIdOfProfileAtIndex(profile_cache_index); |
| 714 } else if (profile->GetPath() == |
| 715 profiles::GetDefaultProfileDir(cache.GetUserDataDir())) { |
| 716 avatar_index = 0; |
| 717 profile_name = l10n_util::GetStringUTF8(IDS_DEFAULT_PROFILE_NAME); |
| 718 } else { |
| 719 avatar_index = cache.ChooseAvatarIconIndexForNewProfile(); |
| 720 profile_name = |
| 721 base::UTF16ToUTF8(cache.ChooseNameForNewProfile(avatar_index)); |
| 722 } |
| 723 } |
| 724 |
| 725 if (!profile->GetPrefs()->HasPrefPath(prefs::kProfileAvatarIndex)) |
| 726 profile->GetPrefs()->SetInteger(prefs::kProfileAvatarIndex, avatar_index); |
| 727 |
| 728 if (!profile->GetPrefs()->HasPrefPath(prefs::kProfileName)) |
| 729 profile->GetPrefs()->SetString(prefs::kProfileName, profile_name); |
| 730 |
| 731 CommandLine* command_line = CommandLine::ForCurrentProcess(); |
| 732 bool force_managed_user_id = |
| 733 command_line->HasSwitch(switches::kManagedUserId); |
| 734 if (force_managed_user_id) { |
| 735 managed_user_id = |
| 736 command_line->GetSwitchValueASCII(switches::kManagedUserId); |
| 737 } |
| 738 if (force_managed_user_id || |
| 739 !profile->GetPrefs()->HasPrefPath(prefs::kManagedUserId)) { |
| 740 profile->GetPrefs()->SetString(prefs::kManagedUserId, managed_user_id); |
| 741 } |
| 742 } |
| 743 |
| 744 void ProfileManager::RegisterTestingProfile(Profile* profile, |
| 745 bool add_to_cache, |
| 746 bool start_deferred_task_runners) { |
| 747 RegisterProfile(profile, true); |
| 748 if (add_to_cache) { |
| 749 InitProfileUserPrefs(profile); |
| 750 AddProfileToCache(profile); |
| 751 } |
| 752 if (start_deferred_task_runners) { |
| 753 StartupTaskRunnerServiceFactory::GetForProfile(profile)-> |
| 754 StartDeferredTaskRunners(); |
| 755 } |
| 756 } |
| 757 |
| 604 void ProfileManager::Observe( | 758 void ProfileManager::Observe( |
| 605 int type, | 759 int type, |
| 606 const content::NotificationSource& source, | 760 const content::NotificationSource& source, |
| 607 const content::NotificationDetails& details) { | 761 const content::NotificationDetails& details) { |
| 608 #if defined(OS_CHROMEOS) | 762 #if defined(OS_CHROMEOS) |
| 609 if (type == chrome::NOTIFICATION_LOGIN_USER_CHANGED) { | 763 if (type == chrome::NOTIFICATION_LOGIN_USER_CHANGED) { |
| 610 logged_in_ = true; | 764 logged_in_ = true; |
| 611 | 765 |
| 612 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); | 766 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); |
| 613 if (!command_line.HasSwitch(switches::kTestType)) { | 767 if (!command_line.HasSwitch(switches::kTestType)) { |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 704 // Some profiles might become ephemeral after they are created. | 858 // Some profiles might become ephemeral after they are created. |
| 705 if (!(*it)->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles) && | 859 if (!(*it)->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles) && |
| 706 profile_paths.find(profile_path) == profile_paths.end()) { | 860 profile_paths.find(profile_path) == profile_paths.end()) { |
| 707 profile_paths.insert(profile_path); | 861 profile_paths.insert(profile_path); |
| 708 profile_list->Append(new base::StringValue(profile_path)); | 862 profile_list->Append(new base::StringValue(profile_path)); |
| 709 } | 863 } |
| 710 } | 864 } |
| 711 } | 865 } |
| 712 } | 866 } |
| 713 | 867 |
| 714 #if !defined(OS_ANDROID) && !defined(OS_IOS) | 868 void ProfileManager::OnProfileCreated(Profile* profile, |
| 715 ProfileManager::BrowserListObserver::BrowserListObserver( | 869 bool success, |
| 716 ProfileManager* manager) | 870 bool is_new_profile) { |
| 717 : profile_manager_(manager) { | 871 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 718 BrowserList::AddObserver(this); | |
| 719 } | |
| 720 | 872 |
| 721 ProfileManager::BrowserListObserver::~BrowserListObserver() { | 873 ProfilesInfoMap::iterator iter = profiles_info_.find(profile->GetPath()); |
| 722 BrowserList::RemoveObserver(this); | 874 DCHECK(iter != profiles_info_.end()); |
| 723 } | 875 ProfileInfo* info = iter->second.get(); |
| 724 | 876 |
| 725 void ProfileManager::BrowserListObserver::OnBrowserAdded( | 877 std::vector<CreateCallback> callbacks; |
| 726 Browser* browser) {} | 878 info->callbacks.swap(callbacks); |
| 727 | 879 |
| 728 void ProfileManager::BrowserListObserver::OnBrowserRemoved( | 880 // Invoke CREATED callback for normal profiles. |
| 729 Browser* browser) { | 881 bool go_off_the_record = ShouldGoOffTheRecord(profile); |
| 730 Profile* profile = browser->profile(); | 882 if (success && !go_off_the_record) |
| 731 for (chrome::BrowserIterator it; !it.done(); it.Next()) { | 883 RunCallbacks(callbacks, profile, Profile::CREATE_STATUS_CREATED); |
| 732 if (it->profile()->GetOriginalProfile() == profile->GetOriginalProfile()) | 884 |
| 733 // Not the last window for this profile. | 885 // Perform initialization. |
| 734 return; | 886 if (success) { |
| 887 DoFinalInit(profile, go_off_the_record); |
| 888 if (go_off_the_record) |
| 889 profile = profile->GetOffTheRecordProfile(); |
| 890 info->created = true; |
| 891 } else { |
| 892 profile = NULL; |
| 893 profiles_info_.erase(iter); |
| 735 } | 894 } |
| 736 | 895 |
| 737 // If the last browser of a profile that is scheduled for deletion is closed | 896 if (profile) { |
| 738 // do that now. | 897 // If this was the guest profile, finish setting its incognito status. |
| 739 base::FilePath path = profile->GetPath(); | 898 if (profile->GetPath() == ProfileManager::GetGuestProfilePath()) |
| 740 if (profile->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles) && | 899 SetGuestProfilePrefs(profile); |
| 741 !IsProfileMarkedForDeletion(path)) { | 900 |
| 742 g_browser_process->profile_manager()->ScheduleProfileForDeletion( | 901 // Invoke CREATED callback for incognito profiles. |
| 743 path, ProfileManager::CreateCallback()); | 902 if (go_off_the_record) |
| 903 RunCallbacks(callbacks, profile, Profile::CREATE_STATUS_CREATED); |
| 744 } | 904 } |
| 905 |
| 906 // Invoke INITIALIZED or FAIL for all profiles. |
| 907 RunCallbacks(callbacks, profile, |
| 908 profile ? Profile::CREATE_STATUS_INITIALIZED : |
| 909 Profile::CREATE_STATUS_LOCAL_FAIL); |
| 745 } | 910 } |
| 746 | 911 |
| 747 void ProfileManager::BrowserListObserver::OnBrowserSetLastActive( | |
| 748 Browser* browser) { | |
| 749 // If all browsers are being closed (e.g. the user is in the process of | |
| 750 // shutting down), this event will be fired after each browser is | |
| 751 // closed. This does not represent a user intention to change the active | |
| 752 // browser so is not handled here. | |
| 753 if (profile_manager_->closing_all_browsers_) | |
| 754 return; | |
| 755 | |
| 756 Profile* last_active = browser->profile(); | |
| 757 | |
| 758 // Don't remember ephemeral profiles as last because they are not going to | |
| 759 // persist after restart. | |
| 760 if (last_active->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles)) | |
| 761 return; | |
| 762 | |
| 763 PrefService* local_state = g_browser_process->local_state(); | |
| 764 DCHECK(local_state); | |
| 765 // Only keep track of profiles that we are managing; tests may create others. | |
| 766 if (profile_manager_->profiles_info_.find( | |
| 767 last_active->GetPath()) != profile_manager_->profiles_info_.end()) { | |
| 768 local_state->SetString(prefs::kProfileLastUsed, | |
| 769 last_active->GetPath().BaseName().MaybeAsASCII()); | |
| 770 } | |
| 771 } | |
| 772 #endif // !defined(OS_ANDROID) && !defined(OS_IOS) | |
| 773 | |
| 774 void ProfileManager::DoFinalInit(Profile* profile, bool go_off_the_record) { | 912 void ProfileManager::DoFinalInit(Profile* profile, bool go_off_the_record) { |
| 775 DoFinalInitForServices(profile, go_off_the_record); | 913 DoFinalInitForServices(profile, go_off_the_record); |
| 776 AddProfileToCache(profile); | 914 AddProfileToCache(profile); |
| 777 DoFinalInitLogging(profile); | 915 DoFinalInitLogging(profile); |
| 778 | 916 |
| 779 ProfileMetrics::LogNumberOfProfiles(this); | 917 ProfileMetrics::LogNumberOfProfiles(this); |
| 780 content::NotificationService::current()->Notify( | 918 content::NotificationService::current()->Notify( |
| 781 chrome::NOTIFICATION_PROFILE_ADDED, | 919 chrome::NOTIFICATION_PROFILE_ADDED, |
| 782 content::Source<Profile>(profile), | 920 content::Source<Profile>(profile), |
| 783 content::NotificationService::NoDetails()); | 921 content::NotificationService::NoDetails()); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 829 return Profile::CreateProfile(path, NULL, Profile::CREATE_MODE_SYNCHRONOUS); | 967 return Profile::CreateProfile(path, NULL, Profile::CREATE_MODE_SYNCHRONOUS); |
| 830 } | 968 } |
| 831 | 969 |
| 832 Profile* ProfileManager::CreateProfileAsyncHelper(const base::FilePath& path, | 970 Profile* ProfileManager::CreateProfileAsyncHelper(const base::FilePath& path, |
| 833 Delegate* delegate) { | 971 Delegate* delegate) { |
| 834 return Profile::CreateProfile(path, | 972 return Profile::CreateProfile(path, |
| 835 delegate, | 973 delegate, |
| 836 Profile::CREATE_MODE_ASYNCHRONOUS); | 974 Profile::CREATE_MODE_ASYNCHRONOUS); |
| 837 } | 975 } |
| 838 | 976 |
| 839 void ProfileManager::OnProfileCreated(Profile* profile, | 977 Profile* ProfileManager::GetActiveUserOrOffTheRecordProfileFromPath( |
| 840 bool success, | 978 const base::FilePath& user_data_dir) { |
| 841 bool is_new_profile) { | 979 #if defined(OS_CHROMEOS) |
| 842 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 980 base::FilePath default_profile_dir(user_data_dir); |
| 843 | 981 if (!logged_in_) { |
| 844 ProfilesInfoMap::iterator iter = profiles_info_.find(profile->GetPath()); | 982 default_profile_dir = profiles::GetDefaultProfileDir(user_data_dir); |
| 845 DCHECK(iter != profiles_info_.end()); | 983 Profile* profile = GetProfile(default_profile_dir); |
| 846 ProfileInfo* info = iter->second.get(); | 984 // For cros, return the OTR profile so we never accidentally keep |
| 847 | 985 // user data in an unencrypted profile. But doing this makes |
| 848 std::vector<CreateCallback> callbacks; | 986 // many of the browser and ui tests fail. We do return the OTR profile |
| 849 info->callbacks.swap(callbacks); | 987 // if the login-profile switch is passed so that we can test this. |
| 850 | 988 if (ShouldGoOffTheRecord(profile)) |
| 851 // Invoke CREATED callback for normal profiles. | 989 return profile->GetOffTheRecordProfile(); |
| 852 bool go_off_the_record = ShouldGoOffTheRecord(profile); | 990 DCHECK(!chromeos::UserManager::Get()->IsLoggedInAsGuest()); |
| 853 if (success && !go_off_the_record) | 991 return profile; |
| 854 RunCallbacks(callbacks, profile, Profile::CREATE_STATUS_CREATED); | |
| 855 | |
| 856 // Perform initialization. | |
| 857 if (success) { | |
| 858 DoFinalInit(profile, go_off_the_record); | |
| 859 if (go_off_the_record) | |
| 860 profile = profile->GetOffTheRecordProfile(); | |
| 861 info->created = true; | |
| 862 } else { | |
| 863 profile = NULL; | |
| 864 profiles_info_.erase(iter); | |
| 865 } | 992 } |
| 866 | 993 |
| 867 if (profile) { | 994 default_profile_dir = default_profile_dir.Append(GetInitialProfileDir()); |
| 868 // If this was the guest profile, finish setting its incognito status. | 995 ProfileInfo* profile_info = GetProfileInfoByPath(default_profile_dir); |
| 869 if (profile->GetPath() == ProfileManager::GetGuestProfilePath()) | 996 // Fallback to default off-the-record profile, if user profile has not fully |
| 870 SetGuestProfilePrefs(profile); | 997 // loaded yet. |
| 998 if (profile_info && !profile_info->created) |
| 999 default_profile_dir = profiles::GetDefaultProfileDir(user_data_dir); |
| 871 | 1000 |
| 872 // Invoke CREATED callback for incognito profiles. | 1001 Profile* profile = GetProfile(default_profile_dir); |
| 873 if (go_off_the_record) | 1002 // Some unit tests didn't initialize the UserManager. |
| 874 RunCallbacks(callbacks, profile, Profile::CREATE_STATUS_CREATED); | 1003 if (chromeos::UserManager::IsInitialized() && |
| 1004 chromeos::UserManager::Get()->IsLoggedInAsGuest()) |
| 1005 return profile->GetOffTheRecordProfile(); |
| 1006 return profile; |
| 1007 #else |
| 1008 base::FilePath default_profile_dir(user_data_dir); |
| 1009 default_profile_dir = default_profile_dir.Append(GetInitialProfileDir()); |
| 1010 return GetProfile(default_profile_dir); |
| 1011 #endif |
| 1012 } |
| 1013 |
| 1014 bool ProfileManager::AddProfile(Profile* profile) { |
| 1015 DCHECK(profile); |
| 1016 |
| 1017 // Make sure that we're not loading a profile with the same ID as a profile |
| 1018 // that's already loaded. |
| 1019 if (GetProfileByPath(profile->GetPath())) { |
| 1020 NOTREACHED() << "Attempted to add profile with the same path (" << |
| 1021 profile->GetPath().value() << |
| 1022 ") as an already-loaded profile."; |
| 1023 return false; |
| 875 } | 1024 } |
| 876 | 1025 |
| 877 // Invoke INITIALIZED or FAIL for all profiles. | 1026 RegisterProfile(profile, true); |
| 878 RunCallbacks(callbacks, profile, | 1027 InitProfileUserPrefs(profile); |
| 879 profile ? Profile::CREATE_STATUS_INITIALIZED : | 1028 DoFinalInit(profile, ShouldGoOffTheRecord(profile)); |
| 880 Profile::CREATE_STATUS_LOCAL_FAIL); | 1029 return true; |
| 881 } | 1030 } |
| 882 | 1031 |
| 883 base::FilePath ProfileManager::GenerateNextProfileDirectoryPath() { | 1032 void ProfileManager::FinishDeletingProfile(const base::FilePath& profile_dir) { |
| 884 PrefService* local_state = g_browser_process->local_state(); | 1033 ProfileInfoCache& cache = GetProfileInfoCache(); |
| 885 DCHECK(local_state); | 1034 // TODO(sail): Due to bug 88586 we don't delete the profile instance. Once we |
| 1035 // start deleting the profile instance we need to close background apps too. |
| 1036 Profile* profile = GetProfileByPath(profile_dir); |
| 886 | 1037 |
| 887 DCHECK(profiles::IsMultipleProfilesEnabled()); | 1038 if (profile) { |
| 1039 BrowserList::CloseAllBrowsersWithProfile(profile); |
| 888 | 1040 |
| 889 // Create the next profile in the next available directory slot. | 1041 // Disable sync for doomed profile. |
| 890 int next_directory = local_state->GetInteger(prefs::kProfilesNumCreated); | 1042 if (ProfileSyncServiceFactory::GetInstance()->HasProfileSyncService( |
| 891 std::string profile_name = chrome::kMultiProfileDirPrefix; | 1043 profile)) { |
| 892 profile_name.append(base::IntToString(next_directory)); | 1044 ProfileSyncServiceFactory::GetInstance()->GetForProfile( |
| 893 base::FilePath new_path = user_data_dir_; | 1045 profile)->DisableForUser(); |
| 894 #if defined(OS_WIN) | 1046 } |
| 895 new_path = new_path.Append(base::ASCIIToUTF16(profile_name)); | 1047 } |
| 896 #else | 1048 |
| 897 new_path = new_path.Append(profile_name); | 1049 QueueProfileDirectoryForDeletion(profile_dir); |
| 898 #endif | 1050 cache.DeleteProfileFromCache(profile_dir); |
| 899 local_state->SetInteger(prefs::kProfilesNumCreated, ++next_directory); | 1051 ProfileMetrics::UpdateReportedProfilesStatistics(this); |
| 900 return new_path; | |
| 901 } | 1052 } |
| 902 | 1053 |
| 903 // static | 1054 ProfileManager::ProfileInfo* ProfileManager::RegisterProfile( |
| 904 base::FilePath ProfileManager::CreateMultiProfileAsync( | 1055 Profile* profile, |
| 905 const base::string16& name, | 1056 bool created) { |
| 906 const base::string16& icon_url, | 1057 ProfileInfo* info = new ProfileInfo(profile, created); |
| 907 const CreateCallback& callback, | 1058 profiles_info_.insert( |
| 908 const std::string& managed_user_id) { | 1059 std::make_pair(profile->GetPath(), linked_ptr<ProfileInfo>(info))); |
| 909 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1060 return info; |
| 910 | |
| 911 ProfileManager* profile_manager = g_browser_process->profile_manager(); | |
| 912 | |
| 913 base::FilePath new_path = profile_manager->GenerateNextProfileDirectoryPath(); | |
| 914 | |
| 915 profile_manager->CreateProfileAsync(new_path, | |
| 916 callback, | |
| 917 name, | |
| 918 icon_url, | |
| 919 managed_user_id); | |
| 920 return new_path; | |
| 921 } | 1061 } |
| 922 | 1062 |
| 923 // static | 1063 ProfileManager::ProfileInfo* ProfileManager::GetProfileInfoByPath( |
| 924 base::FilePath ProfileManager::GetGuestProfilePath() { | 1064 const base::FilePath& path) const { |
| 925 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1065 ProfilesInfoMap::const_iterator iter = profiles_info_.find(path); |
| 926 | 1066 return (iter == profiles_info_.end()) ? NULL : iter->second.get(); |
| 927 ProfileManager* profile_manager = g_browser_process->profile_manager(); | |
| 928 | |
| 929 base::FilePath guest_path = profile_manager->user_data_dir(); | |
| 930 return guest_path.Append(chrome::kGuestProfileDir); | |
| 931 } | |
| 932 | |
| 933 size_t ProfileManager::GetNumberOfProfiles() { | |
| 934 return GetProfileInfoCache().GetNumberOfProfiles(); | |
| 935 } | |
| 936 | |
| 937 bool ProfileManager::CompareProfilePathAndName( | |
| 938 const ProfileManager::ProfilePathAndName& pair1, | |
| 939 const ProfileManager::ProfilePathAndName& pair2) { | |
| 940 int name_compare = pair1.second.compare(pair2.second); | |
| 941 if (name_compare < 0) { | |
| 942 return true; | |
| 943 } else if (name_compare > 0) { | |
| 944 return false; | |
| 945 } else { | |
| 946 return pair1.first < pair2.first; | |
| 947 } | |
| 948 } | |
| 949 | |
| 950 ProfileInfoCache& ProfileManager::GetProfileInfoCache() { | |
| 951 if (!profile_info_cache_) { | |
| 952 profile_info_cache_.reset(new ProfileInfoCache( | |
| 953 g_browser_process->local_state(), user_data_dir_)); | |
| 954 } | |
| 955 return *profile_info_cache_.get(); | |
| 956 } | |
| 957 | |
| 958 ProfileShortcutManager* ProfileManager::profile_shortcut_manager() { | |
| 959 return profile_shortcut_manager_.get(); | |
| 960 } | 1067 } |
| 961 | 1068 |
| 962 void ProfileManager::AddProfileToCache(Profile* profile) { | 1069 void ProfileManager::AddProfileToCache(Profile* profile) { |
| 963 if (profile->IsGuestSession()) | 1070 if (profile->IsGuestSession()) |
| 964 return; | 1071 return; |
| 965 ProfileInfoCache& cache = GetProfileInfoCache(); | 1072 ProfileInfoCache& cache = GetProfileInfoCache(); |
| 966 if (profile->GetPath().DirName() != cache.GetUserDataDir()) | 1073 if (profile->GetPath().DirName() != cache.GetUserDataDir()) |
| 967 return; | 1074 return; |
| 968 | 1075 |
| 969 if (cache.GetIndexOfProfileWithPath(profile->GetPath()) != std::string::npos) | 1076 if (cache.GetIndexOfProfileWithPath(profile->GetPath()) != std::string::npos) |
| (...skipping 18 matching lines...) Expand all Loading... |
| 988 username, | 1095 username, |
| 989 icon_index, | 1096 icon_index, |
| 990 managed_user_id); | 1097 managed_user_id); |
| 991 | 1098 |
| 992 if (profile->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles)) { | 1099 if (profile->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles)) { |
| 993 cache.SetProfileIsEphemeralAtIndex( | 1100 cache.SetProfileIsEphemeralAtIndex( |
| 994 cache.GetIndexOfProfileWithPath(profile->GetPath()), true); | 1101 cache.GetIndexOfProfileWithPath(profile->GetPath()), true); |
| 995 } | 1102 } |
| 996 } | 1103 } |
| 997 | 1104 |
| 998 void ProfileManager::InitProfileUserPrefs(Profile* profile) { | |
| 999 ProfileInfoCache& cache = GetProfileInfoCache(); | |
| 1000 | |
| 1001 if (profile->GetPath().DirName() != cache.GetUserDataDir()) | |
| 1002 return; | |
| 1003 | |
| 1004 size_t avatar_index; | |
| 1005 std::string profile_name; | |
| 1006 std::string managed_user_id; | |
| 1007 if (profile->IsGuestSession()) { | |
| 1008 profile_name = l10n_util::GetStringUTF8(IDS_PROFILES_GUEST_PROFILE_NAME); | |
| 1009 avatar_index = 0; | |
| 1010 } else { | |
| 1011 size_t profile_cache_index = | |
| 1012 cache.GetIndexOfProfileWithPath(profile->GetPath()); | |
| 1013 // If the cache has an entry for this profile, use the cache data. | |
| 1014 if (profile_cache_index != std::string::npos) { | |
| 1015 avatar_index = | |
| 1016 cache.GetAvatarIconIndexOfProfileAtIndex(profile_cache_index); | |
| 1017 profile_name = | |
| 1018 base::UTF16ToUTF8(cache.GetNameOfProfileAtIndex(profile_cache_index)); | |
| 1019 managed_user_id = | |
| 1020 cache.GetManagedUserIdOfProfileAtIndex(profile_cache_index); | |
| 1021 } else if (profile->GetPath() == | |
| 1022 profiles::GetDefaultProfileDir(cache.GetUserDataDir())) { | |
| 1023 avatar_index = 0; | |
| 1024 profile_name = l10n_util::GetStringUTF8(IDS_DEFAULT_PROFILE_NAME); | |
| 1025 } else { | |
| 1026 avatar_index = cache.ChooseAvatarIconIndexForNewProfile(); | |
| 1027 profile_name = | |
| 1028 base::UTF16ToUTF8(cache.ChooseNameForNewProfile(avatar_index)); | |
| 1029 } | |
| 1030 } | |
| 1031 | |
| 1032 if (!profile->GetPrefs()->HasPrefPath(prefs::kProfileAvatarIndex)) | |
| 1033 profile->GetPrefs()->SetInteger(prefs::kProfileAvatarIndex, avatar_index); | |
| 1034 | |
| 1035 if (!profile->GetPrefs()->HasPrefPath(prefs::kProfileName)) | |
| 1036 profile->GetPrefs()->SetString(prefs::kProfileName, profile_name); | |
| 1037 | |
| 1038 CommandLine* command_line = CommandLine::ForCurrentProcess(); | |
| 1039 bool force_managed_user_id = | |
| 1040 command_line->HasSwitch(switches::kManagedUserId); | |
| 1041 if (force_managed_user_id) { | |
| 1042 managed_user_id = | |
| 1043 command_line->GetSwitchValueASCII(switches::kManagedUserId); | |
| 1044 } | |
| 1045 if (force_managed_user_id || | |
| 1046 !profile->GetPrefs()->HasPrefPath(prefs::kManagedUserId)) { | |
| 1047 profile->GetPrefs()->SetString(prefs::kManagedUserId, managed_user_id); | |
| 1048 } | |
| 1049 } | |
| 1050 | |
| 1051 void ProfileManager::SetGuestProfilePrefs(Profile* profile) { | 1105 void ProfileManager::SetGuestProfilePrefs(Profile* profile) { |
| 1052 IncognitoModePrefs::SetAvailability(profile->GetPrefs(), | 1106 IncognitoModePrefs::SetAvailability(profile->GetPrefs(), |
| 1053 IncognitoModePrefs::FORCED); | 1107 IncognitoModePrefs::FORCED); |
| 1054 profile->GetPrefs()->SetBoolean(prefs::kShowBookmarkBar, false); | 1108 profile->GetPrefs()->SetBoolean(prefs::kShowBookmarkBar, false); |
| 1055 } | 1109 } |
| 1056 | 1110 |
| 1057 bool ProfileManager::ShouldGoOffTheRecord(Profile* profile) { | 1111 bool ProfileManager::ShouldGoOffTheRecord(Profile* profile) { |
| 1058 bool go_off_the_record = false; | 1112 bool go_off_the_record = false; |
| 1059 #if defined(OS_CHROMEOS) | 1113 #if defined(OS_CHROMEOS) |
| 1060 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); | 1114 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); |
| 1061 if (command_line.HasSwitch(chromeos::switches::kGuestSession) || | 1115 if (command_line.HasSwitch(chromeos::switches::kGuestSession) || |
| 1062 (profile->GetPath().BaseName().value() == chrome::kInitialProfile && | 1116 (profile->GetPath().BaseName().value() == chrome::kInitialProfile && |
| 1063 (!command_line.HasSwitch(switches::kTestType) || | 1117 (!command_line.HasSwitch(switches::kTestType) || |
| 1064 command_line.HasSwitch(chromeos::switches::kLoginProfile)))) { | 1118 command_line.HasSwitch(chromeos::switches::kLoginProfile)))) { |
| 1065 go_off_the_record = true; | 1119 go_off_the_record = true; |
| 1066 } | 1120 } |
| 1067 #endif | 1121 #endif |
| 1068 return go_off_the_record; | 1122 return go_off_the_record; |
| 1069 } | 1123 } |
| 1070 | 1124 |
| 1071 void ProfileManager::ScheduleProfileForDeletion( | 1125 void ProfileManager::RunCallbacks(const std::vector<CreateCallback>& callbacks, |
| 1072 const base::FilePath& profile_dir, | 1126 Profile* profile, |
| 1073 const CreateCallback& callback) { | 1127 Profile::CreateStatus status) { |
| 1074 DCHECK(profiles::IsMultipleProfilesEnabled()); | 1128 for (size_t i = 0; i < callbacks.size(); ++i) |
| 1075 PrefService* local_state = g_browser_process->local_state(); | 1129 callbacks[i].Run(profile, status); |
| 1076 ProfileInfoCache& cache = GetProfileInfoCache(); | |
| 1077 | |
| 1078 if (profile_dir.BaseName().MaybeAsASCII() == | |
| 1079 local_state->GetString(prefs::kProfileLastUsed)) { | |
| 1080 // Update the last used profile pref before closing browser windows. This | |
| 1081 // way the correct last used profile is set for any notification observers. | |
| 1082 base::FilePath last_non_managed_profile_path; | |
| 1083 for (size_t i = 0; i < cache.GetNumberOfProfiles(); ++i) { | |
| 1084 base::FilePath cur_path = cache.GetPathOfProfileAtIndex(i); | |
| 1085 // Make sure that this profile is not pending deletion. | |
| 1086 if (cur_path != profile_dir && !cache.ProfileIsManagedAtIndex(i) && | |
| 1087 !IsProfileMarkedForDeletion(cur_path)) { | |
| 1088 last_non_managed_profile_path = cur_path; | |
| 1089 break; | |
| 1090 } | |
| 1091 } | |
| 1092 | |
| 1093 // If we're deleting the last (non-managed) profile, then create a new | |
| 1094 // profile in its place. | |
| 1095 const std::string last_non_managed_profile = | |
| 1096 last_non_managed_profile_path.BaseName().MaybeAsASCII(); | |
| 1097 if (last_non_managed_profile.empty()) { | |
| 1098 base::FilePath new_path = GenerateNextProfileDirectoryPath(); | |
| 1099 // Make sure the last used profile path is pointing at it. This way the | |
| 1100 // correct last used profile is set for any notification observers. | |
| 1101 local_state->SetString(prefs::kProfileLastUsed, | |
| 1102 new_path.BaseName().MaybeAsASCII()); | |
| 1103 CreateProfileAsync(new_path, | |
| 1104 callback, | |
| 1105 base::string16(), | |
| 1106 base::string16(), | |
| 1107 std::string()); | |
| 1108 } else { | |
| 1109 // On the Mac, the browser process is not killed when all browser windows | |
| 1110 // are closed, so just in case we are deleting the active profile, and no | |
| 1111 // other profile has been loaded, we must pre-load a next one. | |
| 1112 #if defined(OS_MACOSX) | |
| 1113 CreateProfileAsync(last_non_managed_profile_path, | |
| 1114 base::Bind(&ProfileManager::OnNewActiveProfileLoaded, | |
| 1115 base::Unretained(this), | |
| 1116 profile_dir, | |
| 1117 last_non_managed_profile_path, | |
| 1118 callback), | |
| 1119 base::string16(), | |
| 1120 base::string16(), | |
| 1121 std::string()); | |
| 1122 return; | |
| 1123 #else | |
| 1124 // For OS_MACOSX the pref is updated in the callback to make sure that | |
| 1125 // it isn't used before the profile is actually loaded. | |
| 1126 local_state->SetString(prefs::kProfileLastUsed, last_non_managed_profile); | |
| 1127 #endif | |
| 1128 } | |
| 1129 } | |
| 1130 FinishDeletingProfile(profile_dir); | |
| 1131 } | 1130 } |
| 1132 | 1131 |
| 1133 // static | 1132 ProfileManager::ProfileInfo::ProfileInfo( |
| 1134 void ProfileManager::CleanUpStaleProfiles( | 1133 Profile* profile, |
| 1135 const std::vector<base::FilePath>& profile_paths) { | 1134 bool created) |
| 1136 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 1135 : profile(profile), |
| 1136 created(created) { |
| 1137 } |
| 1137 | 1138 |
| 1138 for (std::vector<base::FilePath>::const_iterator it = profile_paths.begin(); | 1139 ProfileManager::ProfileInfo::~ProfileInfo() { |
| 1139 it != profile_paths.end(); ++it) { | 1140 ProfileDestroyer::DestroyProfileWhenAppropriate(profile.release()); |
| 1140 NukeProfileFromDisk(*it); | 1141 } |
| 1142 |
| 1143 #if !defined(OS_ANDROID) && !defined(OS_IOS) |
| 1144 ProfileManager::BrowserListObserver::BrowserListObserver( |
| 1145 ProfileManager* manager) |
| 1146 : profile_manager_(manager) { |
| 1147 BrowserList::AddObserver(this); |
| 1148 } |
| 1149 |
| 1150 ProfileManager::BrowserListObserver::~BrowserListObserver() { |
| 1151 BrowserList::RemoveObserver(this); |
| 1152 } |
| 1153 |
| 1154 void ProfileManager::BrowserListObserver::OnBrowserAdded( |
| 1155 Browser* browser) {} |
| 1156 |
| 1157 void ProfileManager::BrowserListObserver::OnBrowserRemoved( |
| 1158 Browser* browser) { |
| 1159 Profile* profile = browser->profile(); |
| 1160 for (chrome::BrowserIterator it; !it.done(); it.Next()) { |
| 1161 if (it->profile()->GetOriginalProfile() == profile->GetOriginalProfile()) |
| 1162 // Not the last window for this profile. |
| 1163 return; |
| 1164 } |
| 1165 |
| 1166 // If the last browser of a profile that is scheduled for deletion is closed |
| 1167 // do that now. |
| 1168 base::FilePath path = profile->GetPath(); |
| 1169 if (profile->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles) && |
| 1170 !IsProfileMarkedForDeletion(path)) { |
| 1171 g_browser_process->profile_manager()->ScheduleProfileForDeletion( |
| 1172 path, ProfileManager::CreateCallback()); |
| 1141 } | 1173 } |
| 1142 } | 1174 } |
| 1143 | 1175 |
| 1176 void ProfileManager::BrowserListObserver::OnBrowserSetLastActive( |
| 1177 Browser* browser) { |
| 1178 // If all browsers are being closed (e.g. the user is in the process of |
| 1179 // shutting down), this event will be fired after each browser is |
| 1180 // closed. This does not represent a user intention to change the active |
| 1181 // browser so is not handled here. |
| 1182 if (profile_manager_->closing_all_browsers_) |
| 1183 return; |
| 1184 |
| 1185 Profile* last_active = browser->profile(); |
| 1186 |
| 1187 // Don't remember ephemeral profiles as last because they are not going to |
| 1188 // persist after restart. |
| 1189 if (last_active->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles)) |
| 1190 return; |
| 1191 |
| 1192 PrefService* local_state = g_browser_process->local_state(); |
| 1193 DCHECK(local_state); |
| 1194 // Only keep track of profiles that we are managing; tests may create others. |
| 1195 if (profile_manager_->profiles_info_.find( |
| 1196 last_active->GetPath()) != profile_manager_->profiles_info_.end()) { |
| 1197 local_state->SetString(prefs::kProfileLastUsed, |
| 1198 last_active->GetPath().BaseName().MaybeAsASCII()); |
| 1199 } |
| 1200 } |
| 1201 #endif // !defined(OS_ANDROID) && !defined(OS_IOS) |
| 1202 |
| 1203 #if defined(OS_MACOSX) |
| 1144 void ProfileManager::OnNewActiveProfileLoaded( | 1204 void ProfileManager::OnNewActiveProfileLoaded( |
| 1145 const base::FilePath& profile_to_delete_path, | 1205 const base::FilePath& profile_to_delete_path, |
| 1146 const base::FilePath& last_non_managed_profile_path, | 1206 const base::FilePath& last_non_managed_profile_path, |
| 1147 const CreateCallback& original_callback, | 1207 const CreateCallback& original_callback, |
| 1148 Profile* loaded_profile, | 1208 Profile* loaded_profile, |
| 1149 Profile::CreateStatus status) { | 1209 Profile::CreateStatus status) { |
| 1150 DCHECK(status != Profile::CREATE_STATUS_LOCAL_FAIL && | 1210 DCHECK(status != Profile::CREATE_STATUS_LOCAL_FAIL && |
| 1151 status != Profile::CREATE_STATUS_REMOTE_FAIL); | 1211 status != Profile::CREATE_STATUS_REMOTE_FAIL); |
| 1152 | 1212 |
| 1153 // Only run the code if the profile initialization has finished completely. | 1213 // Only run the code if the profile initialization has finished completely. |
| 1154 if (status == Profile::CREATE_STATUS_INITIALIZED) { | 1214 if (status == Profile::CREATE_STATUS_INITIALIZED) { |
| 1155 if (IsProfileMarkedForDeletion(last_non_managed_profile_path)) { | 1215 if (IsProfileMarkedForDeletion(last_non_managed_profile_path)) { |
| 1156 // If the profile we tried to load as the next active profile has been | 1216 // If the profile we tried to load as the next active profile has been |
| 1157 // deleted, then retry deleting this profile to redo the logic to load | 1217 // deleted, then retry deleting this profile to redo the logic to load |
| 1158 // the next available profile. | 1218 // the next available profile. |
| 1159 ScheduleProfileForDeletion(profile_to_delete_path, original_callback); | 1219 ScheduleProfileForDeletion(profile_to_delete_path, original_callback); |
| 1160 } else { | 1220 } else { |
| 1161 // Update the local state as promised in the ScheduleProfileForDeletion. | 1221 // Update the local state as promised in the ScheduleProfileForDeletion. |
| 1162 g_browser_process->local_state()->SetString( | 1222 g_browser_process->local_state()->SetString( |
| 1163 prefs::kProfileLastUsed, | 1223 prefs::kProfileLastUsed, |
| 1164 last_non_managed_profile_path.BaseName().MaybeAsASCII()); | 1224 last_non_managed_profile_path.BaseName().MaybeAsASCII()); |
| 1165 FinishDeletingProfile(profile_to_delete_path); | 1225 FinishDeletingProfile(profile_to_delete_path); |
| 1166 } | 1226 } |
| 1167 } | 1227 } |
| 1168 } | 1228 } |
| 1169 | 1229 #endif |
| 1170 void ProfileManager::FinishDeletingProfile(const base::FilePath& profile_dir) { | |
| 1171 ProfileInfoCache& cache = GetProfileInfoCache(); | |
| 1172 // TODO(sail): Due to bug 88586 we don't delete the profile instance. Once we | |
| 1173 // start deleting the profile instance we need to close background apps too. | |
| 1174 Profile* profile = GetProfileByPath(profile_dir); | |
| 1175 | |
| 1176 if (profile) { | |
| 1177 BrowserList::CloseAllBrowsersWithProfile(profile); | |
| 1178 | |
| 1179 // Disable sync for doomed profile. | |
| 1180 if (ProfileSyncServiceFactory::GetInstance()->HasProfileSyncService( | |
| 1181 profile)) { | |
| 1182 ProfileSyncServiceFactory::GetInstance()->GetForProfile( | |
| 1183 profile)->DisableForUser(); | |
| 1184 } | |
| 1185 } | |
| 1186 | |
| 1187 QueueProfileDirectoryForDeletion(profile_dir); | |
| 1188 cache.DeleteProfileFromCache(profile_dir); | |
| 1189 ProfileMetrics::UpdateReportedProfilesStatistics(this); | |
| 1190 } | |
| 1191 | |
| 1192 void ProfileManager::AutoloadProfiles() { | |
| 1193 // If running in the background is disabled for the browser, do not autoload | |
| 1194 // any profiles. | |
| 1195 PrefService* local_state = g_browser_process->local_state(); | |
| 1196 if (!local_state->HasPrefPath(prefs::kBackgroundModeEnabled) || | |
| 1197 !local_state->GetBoolean(prefs::kBackgroundModeEnabled)) { | |
| 1198 return; | |
| 1199 } | |
| 1200 | |
| 1201 ProfileInfoCache& cache = GetProfileInfoCache(); | |
| 1202 size_t number_of_profiles = cache.GetNumberOfProfiles(); | |
| 1203 for (size_t p = 0; p < number_of_profiles; ++p) { | |
| 1204 if (cache.GetBackgroundStatusOfProfileAtIndex(p)) { | |
| 1205 // If status is true, that profile is running background apps. By calling | |
| 1206 // GetProfile, we automatically cause the profile to be loaded which will | |
| 1207 // register it with the BackgroundModeManager. | |
| 1208 GetProfile(cache.GetPathOfProfileAtIndex(p)); | |
| 1209 } | |
| 1210 } | |
| 1211 } | |
| 1212 | 1230 |
| 1213 ProfileManagerWithoutInit::ProfileManagerWithoutInit( | 1231 ProfileManagerWithoutInit::ProfileManagerWithoutInit( |
| 1214 const base::FilePath& user_data_dir) : ProfileManager(user_data_dir) { | 1232 const base::FilePath& user_data_dir) : ProfileManager(user_data_dir) { |
| 1215 } | 1233 } |
| 1216 | |
| 1217 void ProfileManager::RegisterTestingProfile(Profile* profile, | |
| 1218 bool add_to_cache, | |
| 1219 bool start_deferred_task_runners) { | |
| 1220 RegisterProfile(profile, true); | |
| 1221 if (add_to_cache) { | |
| 1222 InitProfileUserPrefs(profile); | |
| 1223 AddProfileToCache(profile); | |
| 1224 } | |
| 1225 if (start_deferred_task_runners) { | |
| 1226 StartupTaskRunnerServiceFactory::GetForProfile(profile)-> | |
| 1227 StartDeferredTaskRunners(); | |
| 1228 } | |
| 1229 } | |
| 1230 | |
| 1231 void ProfileManager::RunCallbacks(const std::vector<CreateCallback>& callbacks, | |
| 1232 Profile* profile, | |
| 1233 Profile::CreateStatus status) { | |
| 1234 for (size_t i = 0; i < callbacks.size(); ++i) | |
| 1235 callbacks[i].Run(profile, status); | |
| 1236 } | |
| 1237 | |
| 1238 ProfileManager::ProfileInfo::ProfileInfo( | |
| 1239 Profile* profile, | |
| 1240 bool created) | |
| 1241 : profile(profile), | |
| 1242 created(created) { | |
| 1243 } | |
| 1244 | |
| 1245 ProfileManager::ProfileInfo::~ProfileInfo() { | |
| 1246 ProfileDestroyer::DestroyProfileWhenAppropriate(profile.release()); | |
| 1247 } | |
| OLD | NEW |