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 |