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 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. Call observer 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(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, |
372 observer); | 357 callback); |
Robert Sesek
2011/12/07 16:36:13
nit: Does this fit on one line now?
sail
2011/12/07 17:18:13
Done.
| |
373 } | 358 } |
374 | 359 |
375 bool ProfileManager::AddProfile(Profile* profile) { | 360 bool ProfileManager::AddProfile(Profile* profile) { |
376 DCHECK(profile); | 361 DCHECK(profile); |
377 | 362 |
378 // Make sure that we're not loading a profile with the same ID as a profile | 363 // Make sure that we're not loading a profile with the same ID as a profile |
379 // that's already loaded. | 364 // that's already loaded. |
380 if (GetProfileByPath(profile->GetPath())) { | 365 if (GetProfileByPath(profile->GetPath())) { |
381 NOTREACHED() << "Attempted to add profile with the same path (" << | 366 NOTREACHED() << "Attempted to add profile with the same path (" << |
382 profile->GetPath().value() << | 367 profile->GetPath().value() << |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
496 return Profile::CreateProfileAsync(path, delegate); | 481 return Profile::CreateProfileAsync(path, delegate); |
497 } | 482 } |
498 | 483 |
499 void ProfileManager::OnProfileCreated(Profile* profile, bool success) { | 484 void ProfileManager::OnProfileCreated(Profile* profile, bool success) { |
500 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 485 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
501 | 486 |
502 ProfilesInfoMap::iterator iter = profiles_info_.find(profile->GetPath()); | 487 ProfilesInfoMap::iterator iter = profiles_info_.find(profile->GetPath()); |
503 DCHECK(iter != profiles_info_.end()); | 488 DCHECK(iter != profiles_info_.end()); |
504 ProfileInfo* info = iter->second.get(); | 489 ProfileInfo* info = iter->second.get(); |
505 | 490 |
506 std::vector<ProfileManagerObserver*> observers; | 491 std::vector<CreateCallback> callbacks; |
507 info->observers.swap(observers); | 492 info->callbacks.swap(callbacks); |
508 | 493 |
494 // Invoke CREATED callback for normal profiles. | |
509 bool go_off_the_record = ShouldGoOffTheRecord(); | 495 bool go_off_the_record = ShouldGoOffTheRecord(); |
496 if (success & !go_off_the_record) { | |
Robert Sesek
2011/12/07 16:36:13
&&
sail
2011/12/07 17:18:13
Done.
| |
497 for (size_t i = 0; i < callbacks.size(); ++i) | |
498 callbacks[i].Run(profile, Profile::CREATE_STATUS_CREATED); | |
499 } | |
500 | |
510 if (success) { | 501 if (success) { |
Robert Sesek
2011/12/07 16:36:13
I think this if-block structure is less clear than
sail
2011/12/07 17:18:13
I found the original code very confusing which is
| |
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); | 502 DoFinalInit(profile, go_off_the_record); |
503 if (go_off_the_record) | |
504 profile = profile->GetOffTheRecordProfile(); | |
518 info->created = true; | 505 info->created = true; |
519 } else { | 506 } else { |
520 profile = NULL; | 507 profile = NULL; |
521 profiles_info_.erase(iter); | 508 profiles_info_.erase(iter); |
522 } | 509 } |
523 | 510 |
524 std::vector<ProfileManagerObserver*> observers_to_delete; | 511 // Invoke CREATED callback for incognito profiles. |
525 | 512 if (profile && go_off_the_record) { |
526 for (size_t i = 0; i < observers.size(); ++i) { | 513 for (size_t i = 0; i < callbacks.size(); ++i) |
527 if (profile && go_off_the_record) { | 514 callbacks[i].Run(profile, Profile::CREATE_STATUS_CREATED); |
Robert Sesek
2011/12/07 16:36:13
What's the point of the CREATED status? It seems l
sail
2011/12/07 17:18:13
It looks like CREATED was added for the ChromeOS c
| |
528 profile = profile->GetOffTheRecordProfile(); | |
529 DCHECK(profile); | |
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 } | 515 } |
539 | 516 |
540 STLDeleteElements(&observers_to_delete); | 517 // Invoke INITIALIZED or FAIL for all profiles. |
518 for (size_t i = 0; i < callbacks.size(); ++i) { | |
519 callbacks[i].Run(profile, profile ? Profile::CREATE_STATUS_INITIALIZED : | |
520 Profile::CREATE_STATUS_FAIL); | |
521 } | |
541 } | 522 } |
542 | 523 |
543 FilePath ProfileManager::GenerateNextProfileDirectoryPath() { | 524 FilePath ProfileManager::GenerateNextProfileDirectoryPath() { |
544 PrefService* local_state = g_browser_process->local_state(); | 525 PrefService* local_state = g_browser_process->local_state(); |
545 DCHECK(local_state); | 526 DCHECK(local_state); |
546 | 527 |
547 // Create the next profile in the next available directory slot. | 528 // Create the next profile in the next available directory slot. |
548 int next_directory = local_state->GetInteger(prefs::kProfilesNumCreated); | 529 int next_directory = local_state->GetInteger(prefs::kProfilesNumCreated); |
549 std::string profile_name = chrome::kMultiProfileDirPrefix; | 530 std::string profile_name = chrome::kMultiProfileDirPrefix; |
550 profile_name.append(base::IntToString(next_directory)); | 531 profile_name.append(base::IntToString(next_directory)); |
551 FilePath new_path = user_data_dir_; | 532 FilePath new_path = user_data_dir_; |
552 #if defined(OS_WIN) | 533 #if defined(OS_WIN) |
553 new_path = new_path.Append(ASCIIToUTF16(profile_name)); | 534 new_path = new_path.Append(ASCIIToUTF16(profile_name)); |
554 #else | 535 #else |
555 new_path = new_path.Append(profile_name); | 536 new_path = new_path.Append(profile_name); |
556 #endif | 537 #endif |
557 local_state->SetInteger(prefs::kProfilesNumCreated, ++next_directory); | 538 local_state->SetInteger(prefs::kProfilesNumCreated, ++next_directory); |
558 return new_path; | 539 return new_path; |
559 } | 540 } |
560 | 541 |
561 // static | 542 // static |
562 void ProfileManager::CreateMultiProfileAsync() { | 543 void ProfileManager::CreateMultiProfileAsync() { |
563 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 544 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
564 | 545 |
565 ProfileManager* profile_manager = g_browser_process->profile_manager(); | 546 ProfileManager* profile_manager = g_browser_process->profile_manager(); |
566 | 547 |
567 FilePath new_path = profile_manager->GenerateNextProfileDirectoryPath(); | 548 FilePath new_path = profile_manager->GenerateNextProfileDirectoryPath(); |
568 | 549 |
569 // The launcher is deleted by the manager when profile creation is finished. | 550 profile_manager->CreateProfileAsync(new_path, |
570 NewProfileLauncher* launcher = new NewProfileLauncher(); | 551 base::Bind(&OnOpenWindowForNewProfile)); |
571 profile_manager->CreateProfileAsync(new_path, launcher); | |
572 } | 552 } |
573 | 553 |
574 // static | 554 // static |
575 void ProfileManager::RegisterPrefs(PrefService* prefs) { | 555 void ProfileManager::RegisterPrefs(PrefService* prefs) { |
576 prefs->RegisterStringPref(prefs::kProfileLastUsed, ""); | 556 prefs->RegisterStringPref(prefs::kProfileLastUsed, ""); |
577 prefs->RegisterIntegerPref(prefs::kProfilesNumCreated, 1); | 557 prefs->RegisterIntegerPref(prefs::kProfilesNumCreated, 1); |
578 } | 558 } |
579 | 559 |
580 size_t ProfileManager::GetNumberOfProfiles() { | 560 size_t ProfileManager::GetNumberOfProfiles() { |
581 return GetProfileInfoCache().GetNumberOfProfiles(); | 561 return GetProfileInfoCache().GetNumberOfProfiles(); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
646 return go_off_the_record; | 626 return go_off_the_record; |
647 } | 627 } |
648 | 628 |
649 void ProfileManager::ScheduleProfileForDeletion(const FilePath& profile_dir) { | 629 void ProfileManager::ScheduleProfileForDeletion(const FilePath& profile_dir) { |
650 // If we're deleting the last profile, then create a new profile in its | 630 // If we're deleting the last profile, then create a new profile in its |
651 // place. | 631 // place. |
652 ProfileInfoCache& cache = GetProfileInfoCache(); | 632 ProfileInfoCache& cache = GetProfileInfoCache(); |
653 if (cache.GetNumberOfProfiles() == 1) { | 633 if (cache.GetNumberOfProfiles() == 1) { |
654 FilePath new_path = GenerateNextProfileDirectoryPath(); | 634 FilePath new_path = GenerateNextProfileDirectoryPath(); |
655 | 635 |
656 // The launcher is deleted by the manager when profile creation is finished. | 636 CreateProfileAsync(new_path, base::Bind(&OnOpenWindowForNewProfile)); |
657 NewProfileLauncher* launcher = new NewProfileLauncher(); | |
658 CreateProfileAsync(new_path, launcher); | |
659 } | 637 } |
660 | 638 |
661 // Update the last used profile pref before closing browser windows. This way | 639 // Update the last used profile pref before closing browser windows. This way |
662 // the correct last used profile is set for any notification observers. | 640 // the correct last used profile is set for any notification observers. |
663 PrefService* local_state = g_browser_process->local_state(); | 641 PrefService* local_state = g_browser_process->local_state(); |
664 std::string last_profile = local_state->GetString(prefs::kProfileLastUsed); | 642 std::string last_profile = local_state->GetString(prefs::kProfileLastUsed); |
665 if (profile_dir.BaseName().MaybeAsASCII() == last_profile) { | 643 if (profile_dir.BaseName().MaybeAsASCII() == last_profile) { |
666 for (size_t i = 0; i < cache.GetNumberOfProfiles(); ++i) { | 644 for (size_t i = 0; i < cache.GetNumberOfProfiles(); ++i) { |
667 FilePath cur_path = cache.GetPathOfProfileAtIndex(i); | 645 FilePath cur_path = cache.GetPathOfProfileAtIndex(i); |
668 if (cur_path != profile_dir) { | 646 if (cur_path != profile_dir) { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
719 RegisterProfile(profile, true); | 697 RegisterProfile(profile, true); |
720 if (add_to_cache) | 698 if (add_to_cache) |
721 AddProfileToCache(profile); | 699 AddProfileToCache(profile); |
722 } | 700 } |
723 | 701 |
724 #if defined(OS_WIN) | 702 #if defined(OS_WIN) |
725 void ProfileManager::RemoveProfileShortcutManagerForTesting() { | 703 void ProfileManager::RemoveProfileShortcutManagerForTesting() { |
726 profile_info_cache_->RemoveObserver(profile_shortcut_manager_.get()); | 704 profile_info_cache_->RemoveObserver(profile_shortcut_manager_.get()); |
727 } | 705 } |
728 #endif | 706 #endif |
OLD | NEW |