OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 <set> | 5 #include <set> |
6 | 6 |
7 #include "chrome/browser/profiles/profile_manager.h" | 7 #include "chrome/browser/profiles/profile_manager.h" |
8 | 8 |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/file_path.h" | 10 #include "base/file_path.h" |
11 #include "base/file_util.h" | 11 #include "base/file_util.h" |
12 #include "base/metrics/field_trial.h" | 12 #include "base/metrics/field_trial.h" |
13 #include "base/metrics/histogram.h" | 13 #include "base/metrics/histogram.h" |
14 #include "base/stl_util.h" | |
15 #include "base/string_number_conversions.h" | 14 #include "base/string_number_conversions.h" |
16 #include "base/string_util.h" | 15 #include "base/string_util.h" |
17 #include "base/utf_string_conversions.h" | 16 #include "base/utf_string_conversions.h" |
18 #include "chrome/browser/browser_process.h" | 17 #include "chrome/browser/browser_process.h" |
19 #include "chrome/browser/extensions/default_apps_trial.h" | 18 #include "chrome/browser/extensions/default_apps_trial.h" |
20 #include "chrome/browser/extensions/extension_service.h" | 19 #include "chrome/browser/extensions/extension_service.h" |
21 #include "chrome/browser/prefs/pref_service.h" | 20 #include "chrome/browser/prefs/pref_service.h" |
22 #include "chrome/browser/prefs/scoped_user_pref_update.h" | 21 #include "chrome/browser/prefs/scoped_user_pref_update.h" |
23 #include "chrome/browser/profiles/profile_info_cache.h" | 22 #include "chrome/browser/profiles/profile_info_cache.h" |
24 #include "chrome/browser/sessions/session_service_factory.h" | 23 #include "chrome/browser/sessions/session_service_factory.h" |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 kDefaultAppsTrialName), | 134 kDefaultAppsTrialName), |
136 extension_count_); | 135 extension_count_); |
137 } | 136 } |
138 } | 137 } |
139 } | 138 } |
140 | 139 |
141 void QueueProfileDirectoryForDeletion(const FilePath& path) { | 140 void QueueProfileDirectoryForDeletion(const FilePath& path) { |
142 ProfilesToDelete().push_back(path); | 141 ProfilesToDelete().push_back(path); |
143 } | 142 } |
144 | 143 |
| 144 // Called upon completion of profile creation. This function takes care of |
| 145 // launching a new browser window and signing the user in to their Google |
| 146 // account. |
| 147 void OnOpenWindowForNewProfile(Profile* profile, |
| 148 Profile::CreateStatus status) { |
| 149 if (status == Profile::CREATE_STATUS_INITIALIZED) { |
| 150 ProfileManager::NewWindowWithProfile(profile, |
| 151 BrowserInit::IS_PROCESS_STARTUP, |
| 152 BrowserInit::IS_FIRST_RUN); |
| 153 } |
| 154 } |
| 155 |
145 } // namespace | 156 } // namespace |
146 | 157 |
147 bool ProfileManagerObserver::DeleteAfter() { | |
148 return false; | |
149 } | |
150 | |
151 // The NewProfileLauncher class is created when to wait for a multi-profile | |
152 // to be created asynchronously. Upon completion of profile creation, the | |
153 // NPL takes care of launching a new browser window and signing the user | |
154 // in to their Google account. | |
155 class NewProfileLauncher : public ProfileManagerObserver { | |
156 public: | |
157 virtual void OnProfileCreated(Profile* profile, Status status) { | |
158 if (status == STATUS_INITIALIZED) { | |
159 ProfileManager::NewWindowWithProfile(profile, | |
160 BrowserInit::IS_PROCESS_STARTUP, | |
161 BrowserInit::IS_FIRST_RUN); | |
162 } | |
163 } | |
164 | |
165 virtual bool DeleteAfter() OVERRIDE { return true; } | |
166 }; | |
167 | |
168 // static | 158 // static |
169 void ProfileManager::ShutdownSessionServices() { | 159 void ProfileManager::ShutdownSessionServices() { |
170 ProfileManager* pm = g_browser_process->profile_manager(); | 160 ProfileManager* pm = g_browser_process->profile_manager(); |
171 if (!pm) // Is NULL when running unit tests. | 161 if (!pm) // Is NULL when running unit tests. |
172 return; | 162 return; |
173 std::vector<Profile*> profiles(pm->GetLoadedProfiles()); | 163 std::vector<Profile*> profiles(pm->GetLoadedProfiles()); |
174 for (size_t i = 0; i < profiles.size(); ++i) | 164 for (size_t i = 0; i < profiles.size(); ++i) |
175 SessionServiceFactory::ShutdownForProfile(profiles[i]); | 165 SessionServiceFactory::ShutdownForProfile(profiles[i]); |
176 } | 166 } |
177 | 167 |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
325 | 315 |
326 profile = CreateProfileHelper(profile_dir); | 316 profile = CreateProfileHelper(profile_dir); |
327 DCHECK(profile); | 317 DCHECK(profile); |
328 if (profile) { | 318 if (profile) { |
329 bool result = AddProfile(profile); | 319 bool result = AddProfile(profile); |
330 DCHECK(result); | 320 DCHECK(result); |
331 } | 321 } |
332 return profile; | 322 return profile; |
333 } | 323 } |
334 | 324 |
335 void ProfileManager::CreateProfileAsync(const FilePath& user_data_dir, | 325 void ProfileManager::CreateProfileAsync(const FilePath& profile_path, |
336 ProfileManagerObserver* observer) { | 326 const CreateCallback& callback) { |
337 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 327 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
338 ProfilesInfoMap::iterator iter = profiles_info_.find(user_data_dir); | 328 ProfilesInfoMap::iterator iter = profiles_info_.find(profile_path); |
339 if (iter != profiles_info_.end()) { | 329 if (iter != profiles_info_.end()) { |
340 ProfileInfo* info = iter->second.get(); | 330 ProfileInfo* info = iter->second.get(); |
341 if (info->created) { | 331 if (info->created) { |
342 // Profile has already been created. Call observer immediately. | 332 // Profile has already been created. Run callback immediately. |
343 observer->OnProfileCreated( | 333 callback.Run(info->profile.get(), Profile::CREATE_STATUS_INITIALIZED); |
344 info->profile.get(), ProfileManagerObserver::STATUS_INITIALIZED); | |
345 if (observer->DeleteAfter()) | |
346 delete observer; | |
347 } else { | 334 } else { |
348 // Profile is being created. Add observer to list. | 335 // Profile is being created. Add callback to list. |
349 info->observers.push_back(observer); | 336 info->callbacks.push_back(callback); |
350 } | 337 } |
351 } else { | 338 } else { |
352 // Initiate asynchronous creation process. | 339 // Initiate asynchronous creation process. |
353 ProfileInfo* info = | 340 ProfileInfo* info = |
354 RegisterProfile(CreateProfileAsyncHelper(user_data_dir, this), | 341 RegisterProfile(CreateProfileAsyncHelper(profile_path, this), false); |
355 false); | 342 info->callbacks.push_back(callback); |
356 info->observers.push_back(observer); | |
357 } | 343 } |
358 } | 344 } |
359 | 345 |
360 // static | 346 // static |
361 void ProfileManager::CreateDefaultProfileAsync( | 347 void ProfileManager::CreateDefaultProfileAsync(const CreateCallback& callback) { |
362 ProfileManagerObserver* observer) { | |
363 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 348 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
364 ProfileManager* profile_manager = g_browser_process->profile_manager(); | 349 ProfileManager* profile_manager = g_browser_process->profile_manager(); |
365 | 350 |
366 FilePath default_profile_dir = profile_manager->user_data_dir_; | 351 FilePath default_profile_dir = profile_manager->user_data_dir_; |
367 // TODO(mirandac): current directory will not always be default in the future | 352 // TODO(mirandac): current directory will not always be default in the future |
368 default_profile_dir = default_profile_dir.Append( | 353 default_profile_dir = default_profile_dir.Append( |
369 profile_manager->GetInitialProfileDir()); | 354 profile_manager->GetInitialProfileDir()); |
370 | 355 |
371 profile_manager->CreateProfileAsync(default_profile_dir, | 356 profile_manager->CreateProfileAsync(default_profile_dir, callback); |
372 observer); | |
373 } | 357 } |
374 | 358 |
375 bool ProfileManager::AddProfile(Profile* profile) { | 359 bool ProfileManager::AddProfile(Profile* profile) { |
376 DCHECK(profile); | 360 DCHECK(profile); |
377 | 361 |
378 // Make sure that we're not loading a profile with the same ID as a profile | 362 // Make sure that we're not loading a profile with the same ID as a profile |
379 // that's already loaded. | 363 // that's already loaded. |
380 if (GetProfileByPath(profile->GetPath())) { | 364 if (GetProfileByPath(profile->GetPath())) { |
381 NOTREACHED() << "Attempted to add profile with the same path (" << | 365 NOTREACHED() << "Attempted to add profile with the same path (" << |
382 profile->GetPath().value() << | 366 profile->GetPath().value() << |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
496 return Profile::CreateProfileAsync(path, delegate); | 480 return Profile::CreateProfileAsync(path, delegate); |
497 } | 481 } |
498 | 482 |
499 void ProfileManager::OnProfileCreated(Profile* profile, bool success) { | 483 void ProfileManager::OnProfileCreated(Profile* profile, bool success) { |
500 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 484 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
501 | 485 |
502 ProfilesInfoMap::iterator iter = profiles_info_.find(profile->GetPath()); | 486 ProfilesInfoMap::iterator iter = profiles_info_.find(profile->GetPath()); |
503 DCHECK(iter != profiles_info_.end()); | 487 DCHECK(iter != profiles_info_.end()); |
504 ProfileInfo* info = iter->second.get(); | 488 ProfileInfo* info = iter->second.get(); |
505 | 489 |
506 std::vector<ProfileManagerObserver*> observers; | 490 std::vector<CreateCallback> callbacks; |
507 info->observers.swap(observers); | 491 info->callbacks.swap(callbacks); |
508 | 492 |
| 493 // Invoke CREATED callback for normal profiles. |
509 bool go_off_the_record = ShouldGoOffTheRecord(); | 494 bool go_off_the_record = ShouldGoOffTheRecord(); |
| 495 if (success && !go_off_the_record) |
| 496 RunCallbacks(callbacks, profile, Profile::CREATE_STATUS_CREATED); |
| 497 |
| 498 // Perform initialization. |
510 if (success) { | 499 if (success) { |
511 if (!go_off_the_record) { | |
512 for (size_t i = 0; i < observers.size(); ++i) { | |
513 observers[i]->OnProfileCreated( | |
514 profile, ProfileManagerObserver::STATUS_CREATED); | |
515 } | |
516 } | |
517 DoFinalInit(profile, go_off_the_record); | 500 DoFinalInit(profile, go_off_the_record); |
| 501 if (go_off_the_record) |
| 502 profile = profile->GetOffTheRecordProfile(); |
518 info->created = true; | 503 info->created = true; |
519 } else { | 504 } else { |
520 profile = NULL; | 505 profile = NULL; |
521 profiles_info_.erase(iter); | 506 profiles_info_.erase(iter); |
522 } | 507 } |
523 | 508 |
524 std::vector<ProfileManagerObserver*> observers_to_delete; | 509 // Invoke CREATED callback for incognito profiles. |
| 510 if (profile && go_off_the_record) |
| 511 RunCallbacks(callbacks, profile, Profile::CREATE_STATUS_CREATED); |
525 | 512 |
526 for (size_t i = 0; i < observers.size(); ++i) { | 513 // Invoke INITIALIZED or FAIL for all profiles. |
527 if (profile && go_off_the_record) { | 514 RunCallbacks(callbacks, profile, |
528 profile = profile->GetOffTheRecordProfile(); | 515 profile ? Profile::CREATE_STATUS_INITIALIZED : |
529 DCHECK(profile); | 516 Profile::CREATE_STATUS_FAIL); |
530 observers[i]->OnProfileCreated( | |
531 profile, ProfileManagerObserver::STATUS_CREATED); | |
532 } | |
533 observers[i]->OnProfileCreated( | |
534 profile, profile ? ProfileManagerObserver::STATUS_INITIALIZED : | |
535 ProfileManagerObserver::STATUS_FAIL); | |
536 if (observers[i]->DeleteAfter()) | |
537 observers_to_delete.push_back(observers[i]); | |
538 } | |
539 | |
540 STLDeleteElements(&observers_to_delete); | |
541 } | 517 } |
542 | 518 |
543 FilePath ProfileManager::GenerateNextProfileDirectoryPath() { | 519 FilePath ProfileManager::GenerateNextProfileDirectoryPath() { |
544 PrefService* local_state = g_browser_process->local_state(); | 520 PrefService* local_state = g_browser_process->local_state(); |
545 DCHECK(local_state); | 521 DCHECK(local_state); |
546 | 522 |
547 // Create the next profile in the next available directory slot. | 523 // Create the next profile in the next available directory slot. |
548 int next_directory = local_state->GetInteger(prefs::kProfilesNumCreated); | 524 int next_directory = local_state->GetInteger(prefs::kProfilesNumCreated); |
549 std::string profile_name = chrome::kMultiProfileDirPrefix; | 525 std::string profile_name = chrome::kMultiProfileDirPrefix; |
550 profile_name.append(base::IntToString(next_directory)); | 526 profile_name.append(base::IntToString(next_directory)); |
551 FilePath new_path = user_data_dir_; | 527 FilePath new_path = user_data_dir_; |
552 #if defined(OS_WIN) | 528 #if defined(OS_WIN) |
553 new_path = new_path.Append(ASCIIToUTF16(profile_name)); | 529 new_path = new_path.Append(ASCIIToUTF16(profile_name)); |
554 #else | 530 #else |
555 new_path = new_path.Append(profile_name); | 531 new_path = new_path.Append(profile_name); |
556 #endif | 532 #endif |
557 local_state->SetInteger(prefs::kProfilesNumCreated, ++next_directory); | 533 local_state->SetInteger(prefs::kProfilesNumCreated, ++next_directory); |
558 return new_path; | 534 return new_path; |
559 } | 535 } |
560 | 536 |
561 // static | 537 // static |
562 void ProfileManager::CreateMultiProfileAsync() { | 538 void ProfileManager::CreateMultiProfileAsync() { |
563 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 539 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
564 | 540 |
565 ProfileManager* profile_manager = g_browser_process->profile_manager(); | 541 ProfileManager* profile_manager = g_browser_process->profile_manager(); |
566 | 542 |
567 FilePath new_path = profile_manager->GenerateNextProfileDirectoryPath(); | 543 FilePath new_path = profile_manager->GenerateNextProfileDirectoryPath(); |
568 | 544 |
569 // The launcher is deleted by the manager when profile creation is finished. | 545 profile_manager->CreateProfileAsync(new_path, |
570 NewProfileLauncher* launcher = new NewProfileLauncher(); | 546 base::Bind(&OnOpenWindowForNewProfile)); |
571 profile_manager->CreateProfileAsync(new_path, launcher); | |
572 } | 547 } |
573 | 548 |
574 // static | 549 // static |
575 void ProfileManager::RegisterPrefs(PrefService* prefs) { | 550 void ProfileManager::RegisterPrefs(PrefService* prefs) { |
576 prefs->RegisterStringPref(prefs::kProfileLastUsed, ""); | 551 prefs->RegisterStringPref(prefs::kProfileLastUsed, ""); |
577 prefs->RegisterIntegerPref(prefs::kProfilesNumCreated, 1); | 552 prefs->RegisterIntegerPref(prefs::kProfilesNumCreated, 1); |
578 } | 553 } |
579 | 554 |
580 size_t ProfileManager::GetNumberOfProfiles() { | 555 size_t ProfileManager::GetNumberOfProfiles() { |
581 return GetProfileInfoCache().GetNumberOfProfiles(); | 556 return GetProfileInfoCache().GetNumberOfProfiles(); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
646 return go_off_the_record; | 621 return go_off_the_record; |
647 } | 622 } |
648 | 623 |
649 void ProfileManager::ScheduleProfileForDeletion(const FilePath& profile_dir) { | 624 void ProfileManager::ScheduleProfileForDeletion(const FilePath& profile_dir) { |
650 // If we're deleting the last profile, then create a new profile in its | 625 // If we're deleting the last profile, then create a new profile in its |
651 // place. | 626 // place. |
652 ProfileInfoCache& cache = GetProfileInfoCache(); | 627 ProfileInfoCache& cache = GetProfileInfoCache(); |
653 if (cache.GetNumberOfProfiles() == 1) { | 628 if (cache.GetNumberOfProfiles() == 1) { |
654 FilePath new_path = GenerateNextProfileDirectoryPath(); | 629 FilePath new_path = GenerateNextProfileDirectoryPath(); |
655 | 630 |
656 // The launcher is deleted by the manager when profile creation is finished. | 631 CreateProfileAsync(new_path, base::Bind(&OnOpenWindowForNewProfile)); |
657 NewProfileLauncher* launcher = new NewProfileLauncher(); | |
658 CreateProfileAsync(new_path, launcher); | |
659 } | 632 } |
660 | 633 |
661 // Update the last used profile pref before closing browser windows. This way | 634 // Update the last used profile pref before closing browser windows. This way |
662 // the correct last used profile is set for any notification observers. | 635 // the correct last used profile is set for any notification observers. |
663 PrefService* local_state = g_browser_process->local_state(); | 636 PrefService* local_state = g_browser_process->local_state(); |
664 std::string last_profile = local_state->GetString(prefs::kProfileLastUsed); | 637 std::string last_profile = local_state->GetString(prefs::kProfileLastUsed); |
665 if (profile_dir.BaseName().MaybeAsASCII() == last_profile) { | 638 if (profile_dir.BaseName().MaybeAsASCII() == last_profile) { |
666 for (size_t i = 0; i < cache.GetNumberOfProfiles(); ++i) { | 639 for (size_t i = 0; i < cache.GetNumberOfProfiles(); ++i) { |
667 FilePath cur_path = cache.GetPathOfProfileAtIndex(i); | 640 FilePath cur_path = cache.GetPathOfProfileAtIndex(i); |
668 if (cur_path != profile_dir) { | 641 if (cur_path != profile_dir) { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
719 RegisterProfile(profile, true); | 692 RegisterProfile(profile, true); |
720 if (add_to_cache) | 693 if (add_to_cache) |
721 AddProfileToCache(profile); | 694 AddProfileToCache(profile); |
722 } | 695 } |
723 | 696 |
724 #if defined(OS_WIN) | 697 #if defined(OS_WIN) |
725 void ProfileManager::RemoveProfileShortcutManagerForTesting() { | 698 void ProfileManager::RemoveProfileShortcutManagerForTesting() { |
726 profile_info_cache_->RemoveObserver(profile_shortcut_manager_.get()); | 699 profile_info_cache_->RemoveObserver(profile_shortcut_manager_.get()); |
727 } | 700 } |
728 #endif | 701 #endif |
| 702 |
| 703 void ProfileManager::RunCallbacks(const std::vector<CreateCallback>& callbacks, |
| 704 Profile* profile, |
| 705 Profile::CreateStatus status) { |
| 706 for (size_t i = 0; i < callbacks.size(); ++i) |
| 707 callbacks[i].Run(profile, status); |
| 708 } |
OLD | NEW |