Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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/chromeos/login/user_manager_impl.h" | 5 #include "chrome/browser/chromeos/login/user_manager_impl.h" |
| 6 | 6 |
| 7 #include <cstddef> | 7 #include <cstddef> |
| 8 #include <set> | 8 #include <set> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/bind_helpers.h" | 11 #include "base/bind_helpers.h" |
| 12 #include "base/chromeos/chromeos_version.h" | 12 #include "base/chromeos/chromeos_version.h" |
| 13 #include "base/command_line.h" | 13 #include "base/command_line.h" |
| 14 #include "base/compiler_specific.h" | 14 #include "base/compiler_specific.h" |
| 15 #include "base/debug/stack_trace.h" | |
| 15 #include "base/files/file_path.h" | 16 #include "base/files/file_path.h" |
| 16 #include "base/logging.h" | 17 #include "base/logging.h" |
| 17 #include "base/metrics/histogram.h" | 18 #include "base/metrics/histogram.h" |
| 18 #include "base/prefs/pref_registry_simple.h" | 19 #include "base/prefs/pref_registry_simple.h" |
| 19 #include "base/prefs/pref_service.h" | 20 #include "base/prefs/pref_service.h" |
| 20 #include "base/rand_util.h" | 21 #include "base/rand_util.h" |
| 21 #include "base/strings/string_util.h" | 22 #include "base/strings/string_util.h" |
| 22 #include "base/strings/stringprintf.h" | 23 #include "base/strings/stringprintf.h" |
| 23 #include "base/strings/utf_string_conversions.h" | 24 #include "base/strings/utf_string_conversions.h" |
| 24 #include "base/values.h" | 25 #include "base/values.h" |
| 25 #include "chrome/browser/app_mode/app_mode_utils.h" | 26 #include "chrome/browser/app_mode/app_mode_utils.h" |
| 26 #include "chrome/browser/browser_process.h" | 27 #include "chrome/browser/browser_process.h" |
| 27 #include "chrome/browser/chrome_notification_types.h" | 28 #include "chrome/browser/chrome_notification_types.h" |
| 28 #include "chrome/browser/chromeos/cros/cert_library.h" | 29 #include "chrome/browser/chromeos/cros/cert_library.h" |
| 29 #include "chrome/browser/chromeos/login/default_pinned_apps_field_trial.h" | 30 #include "chrome/browser/chromeos/login/default_pinned_apps_field_trial.h" |
| 31 #include "chrome/browser/chromeos/login/language_switch_menu.h" | |
| 30 #include "chrome/browser/chromeos/login/login_display.h" | 32 #include "chrome/browser/chromeos/login/login_display.h" |
| 31 #include "chrome/browser/chromeos/login/login_utils.h" | 33 #include "chrome/browser/chromeos/login/login_utils.h" |
| 32 #include "chrome/browser/chromeos/login/remove_user_delegate.h" | 34 #include "chrome/browser/chromeos/login/remove_user_delegate.h" |
| 33 #include "chrome/browser/chromeos/login/user_image_manager_impl.h" | 35 #include "chrome/browser/chromeos/login/user_image_manager_impl.h" |
| 34 #include "chrome/browser/chromeos/login/wizard_controller.h" | 36 #include "chrome/browser/chromeos/login/wizard_controller.h" |
| 35 #include "chrome/browser/chromeos/policy/device_local_account.h" | 37 #include "chrome/browser/chromeos/policy/device_local_account.h" |
| 38 #include "chrome/browser/chromeos/profiles/profile_helper.h" | |
| 36 #include "chrome/browser/chromeos/session_length_limiter.h" | 39 #include "chrome/browser/chromeos/session_length_limiter.h" |
| 37 #include "chrome/browser/chromeos/settings/cros_settings_names.h" | 40 #include "chrome/browser/chromeos/settings/cros_settings_names.h" |
| 38 #include "chrome/browser/managed_mode/managed_user_service.h" | 41 #include "chrome/browser/managed_mode/managed_user_service.h" |
| 39 #include "chrome/browser/policy/browser_policy_connector.h" | 42 #include "chrome/browser/policy/browser_policy_connector.h" |
| 40 #include "chrome/browser/prefs/scoped_user_pref_update.h" | 43 #include "chrome/browser/prefs/scoped_user_pref_update.h" |
| 44 #include "chrome/browser/profiles/profile.h" | |
| 41 #include "chrome/browser/profiles/profile_manager.h" | 45 #include "chrome/browser/profiles/profile_manager.h" |
| 42 #include "chrome/browser/sync/profile_sync_service.h" | 46 #include "chrome/browser/sync/profile_sync_service.h" |
| 43 #include "chrome/browser/sync/profile_sync_service_factory.h" | 47 #include "chrome/browser/sync/profile_sync_service_factory.h" |
| 44 #include "chrome/common/chrome_switches.h" | 48 #include "chrome/common/chrome_switches.h" |
| 45 #include "chrome/common/pref_names.h" | 49 #include "chrome/common/pref_names.h" |
| 46 #include "chromeos/chromeos_switches.h" | 50 #include "chromeos/chromeos_switches.h" |
| 47 #include "chromeos/cryptohome/async_method_caller.h" | 51 #include "chromeos/cryptohome/async_method_caller.h" |
| 48 #include "chromeos/dbus/dbus_thread_manager.h" | 52 #include "chromeos/dbus/dbus_thread_manager.h" |
| 49 #include "chromeos/ime/input_method_manager.h" | 53 #include "chromeos/ime/input_method_manager.h" |
| 50 #include "chromeos/login/login_state.h" | 54 #include "chromeos/login/login_state.h" |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 224 merge_session_state_(MERGE_STATUS_NOT_STARTED), | 228 merge_session_state_(MERGE_STATUS_NOT_STARTED), |
| 225 observed_sync_service_(NULL), | 229 observed_sync_service_(NULL), |
| 226 user_image_manager_(new UserImageManagerImpl), | 230 user_image_manager_(new UserImageManagerImpl), |
| 227 manager_creation_time_(base::TimeTicks::Now()) { | 231 manager_creation_time_(base::TimeTicks::Now()) { |
| 228 // UserManager instance should be used only on UI thread. | 232 // UserManager instance should be used only on UI thread. |
| 229 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 233 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 230 registrar_.Add(this, chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED, | 234 registrar_.Add(this, chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED, |
| 231 content::NotificationService::AllSources()); | 235 content::NotificationService::AllSources()); |
| 232 registrar_.Add(this, chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED, | 236 registrar_.Add(this, chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED, |
| 233 content::NotificationService::AllSources()); | 237 content::NotificationService::AllSources()); |
| 238 registrar_.Add(this, | |
| 239 chrome::NOTIFICATION_PROFILE_CREATED, | |
| 240 content::NotificationService::AllSources()); | |
| 234 RetrieveTrustedDevicePolicies(); | 241 RetrieveTrustedDevicePolicies(); |
| 235 cros_settings_->AddSettingsObserver(kAccountsPrefDeviceLocalAccounts, | 242 cros_settings_->AddSettingsObserver(kAccountsPrefDeviceLocalAccounts, |
| 236 this); | 243 this); |
| 237 cros_settings_->AddSettingsObserver(kAccountsPrefSupervisedUsersEnabled, | 244 cros_settings_->AddSettingsObserver(kAccountsPrefSupervisedUsersEnabled, |
| 238 this); | 245 this); |
| 239 UpdateLoginState(); | 246 UpdateLoginState(); |
| 240 } | 247 } |
| 241 | 248 |
| 242 UserManagerImpl::~UserManagerImpl() { | 249 UserManagerImpl::~UserManagerImpl() { |
| 243 // Can't use STLDeleteElements because of the private destructor of User. | 250 // Can't use STLDeleteElements because of the private destructor of User. |
| (...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 641 static_cast<User::OAuthTokenStatus>(oauth_token_status); | 648 static_cast<User::OAuthTokenStatus>(oauth_token_status); |
| 642 if (result == User::OAUTH2_TOKEN_STATUS_INVALID) | 649 if (result == User::OAUTH2_TOKEN_STATUS_INVALID) |
| 643 GetUserFlow(username)->HandleOAuthTokenStatusChange(result); | 650 GetUserFlow(username)->HandleOAuthTokenStatusChange(result); |
| 644 return result; | 651 return result; |
| 645 } | 652 } |
| 646 return User::OAUTH_TOKEN_STATUS_UNKNOWN; | 653 return User::OAUTH_TOKEN_STATUS_UNKNOWN; |
| 647 } | 654 } |
| 648 | 655 |
| 649 void UserManagerImpl::SaveUserDisplayName(const std::string& username, | 656 void UserManagerImpl::SaveUserDisplayName(const std::string& username, |
| 650 const string16& display_name) { | 657 const string16& display_name) { |
| 658 UpdateUserAccountDataImpl(username, display_name, NULL); | |
| 659 } | |
| 660 | |
| 661 void UserManagerImpl::UpdateUserAccountData(const std::string& username, | |
| 662 const string16& display_name, | |
| 663 const std::string& locale) { | |
| 664 UpdateUserAccountDataImpl(username, display_name, &locale); | |
| 665 } | |
| 666 | |
| 667 void UserManagerImpl::UpdateUserAccountDataImpl(const std::string& username, | |
| 668 const string16& display_name, | |
| 669 const std::string* locale) { | |
| 651 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 670 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 652 | 671 |
| 653 User* user = FindUserAndModify(username); | 672 User* user = FindUserAndModify(username); |
| 654 if (!user) | 673 if (!user) |
| 655 return; // Ignore if there is no such user. | 674 return; // Ignore if there is no such user. |
| 656 | 675 |
| 676 // locale is not NULL if User Account has been downloaded | |
| 677 // (i.e. it is UpdateUserAccountData(), not SaveUserDisplayName() ) | |
| 678 if (locale != NULL) { | |
| 679 user->SetAccountLocale(*locale); | |
| 680 RespectLocalePreference( | |
| 681 g_browser_process->profile_manager()->GetDefaultProfile(), user); | |
| 682 } | |
| 683 | |
| 684 if (display_name.empty()) | |
| 685 return; | |
| 686 | |
| 657 user->set_display_name(display_name); | 687 user->set_display_name(display_name); |
| 658 | 688 |
| 659 // Do not update local store if data stored or cached outside the user's | 689 // Do not update local store if data stored or cached outside the user's |
| 660 // cryptohome is to be treated as ephemeral. | 690 // cryptohome is to be treated as ephemeral. |
| 661 if (IsUserNonCryptohomeDataEphemeral(username)) | 691 if (IsUserNonCryptohomeDataEphemeral(username)) |
| 662 return; | 692 return; |
| 663 | 693 |
| 664 PrefService* local_state = g_browser_process->local_state(); | 694 PrefService* local_state = g_browser_process->local_state(); |
| 665 | 695 |
| 666 DictionaryPrefUpdate display_name_update(local_state, kUserDisplayName); | 696 DictionaryPrefUpdate display_name_update(local_state, kUserDisplayName); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 715 username, | 745 username, |
| 716 new base::StringValue(display_email)); | 746 new base::StringValue(display_email)); |
| 717 } | 747 } |
| 718 | 748 |
| 719 std::string UserManagerImpl::GetUserDisplayEmail( | 749 std::string UserManagerImpl::GetUserDisplayEmail( |
| 720 const std::string& username) const { | 750 const std::string& username) const { |
| 721 const User* user = FindUser(username); | 751 const User* user = FindUser(username); |
| 722 return user ? user->display_email() : username; | 752 return user ? user->display_email() : username; |
| 723 } | 753 } |
| 724 | 754 |
| 755 // TODO(alemate): Jungshik Shin: 2013/08/26 16:42:50 | |
|
Dmitry Polukhin
2013/09/06 20:30:05
Please file issue about and add here. TODO(alemate
Alexander Alekseev
2013/09/11 18:53:02
Done.
| |
| 756 // This does not take into account the preferred language list in the Google | |
| 757 // user profile. If a user's primary language is not supported by Chrome OS | |
| 758 // (let's say, "Foo") but one of languages in the fallback list in the user's | |
| 759 // Google profile (e.g. French) is supported by Chrome, we have to pick it up | |
| 760 // instead of falling back to the universal (hard-coded) fallback ('en-US'). | |
| 761 void UserManagerImpl::RespectLocalePreference(Profile* profile, | |
| 762 const User* user) const { | |
| 763 if (g_browser_process == NULL) | |
| 764 return; | |
| 765 if ((active_user_ == NULL) || (user != active_user_) || | |
| 766 !active_user_->is_profile_created()) | |
| 767 return; | |
| 768 | |
| 769 if (profile != ProfileManager::GetDefaultProfile()) | |
| 770 return; | |
| 771 const PrefService* prefs = profile->GetPrefs(); | |
| 772 if (prefs == NULL) | |
| 773 return; | |
| 774 | |
| 775 std::string pref_locale = prefs->GetString(prefs::kApplicationLocale); | |
| 776 if (pref_locale.empty()) | |
| 777 pref_locale = prefs->GetString(prefs::kApplicationLocaleBackup); | |
| 778 | |
| 779 if (pref_locale.empty() && user->has_account()) { | |
| 780 if (user->GetAccountLocale() == NULL) | |
| 781 return; // wait until Account profile is loaded. | |
| 782 pref_locale = *(user->GetAccountLocale()); | |
| 783 } | |
| 784 if (pref_locale.empty()) | |
| 785 pref_locale = g_browser_process->GetApplicationLocale(); | |
| 786 DCHECK(!pref_locale.empty()); | |
| 787 profile->ChangeAppLocale(pref_locale, Profile::APP_LOCALE_CHANGED_VIA_LOGIN); | |
| 788 // Here we don't enable keyboard layouts. Input methods are set up when | |
| 789 // the user first logs in. Then the user may customize the input methods. | |
| 790 // Hence changing input methods here, just because the user's UI language | |
| 791 // is different from the login screen UI language, is not desirable. Note | |
| 792 // that input method preferences are synced, so users can use their | |
| 793 // farovite input methods as soon as the preferences are synced. | |
| 794 chromeos::LanguageSwitchMenu::SwitchLanguage(pref_locale); | |
| 795 } | |
| 796 | |
| 797 class UserHashMatcher { | |
| 798 const std::string& username_hash; | |
|
Dmitry Polukhin
2013/09/06 20:30:05
Please make private members last.
Alexander Alekseev
2013/09/11 18:53:02
Done.
| |
| 799 | |
| 800 public: | |
| 801 explicit UserHashMatcher(const std::string& h) : username_hash(h) {} | |
| 802 bool operator()(const User* user) const { | |
| 803 return user->username_hash() == username_hash; | |
| 804 } | |
| 805 }; | |
| 806 | |
| 807 // Returns NULL if user is not created | |
| 808 User* UserManagerImpl::GetUserByProfile(Profile* profile) { | |
| 809 if (CommandLine::ForCurrentProcess()->HasSwitch(::switches::kMultiProfiles)) { | |
| 810 const std::string username_hash = | |
| 811 ProfileHelper::GetUserIdHashFromProfile(profile); | |
| 812 const UserList& users = GetUsers(); | |
| 813 const UserList::const_iterator pos = std::find_if( | |
| 814 users.begin(), users.end(), UserHashMatcher(username_hash)); | |
| 815 return (pos != users.end()) ? *pos : NULL; | |
| 816 } | |
| 817 return active_user_; | |
| 818 } | |
| 819 | |
| 725 void UserManagerImpl::Observe(int type, | 820 void UserManagerImpl::Observe(int type, |
| 726 const content::NotificationSource& source, | 821 const content::NotificationSource& source, |
| 727 const content::NotificationDetails& details) { | 822 const content::NotificationDetails& details) { |
| 728 switch (type) { | 823 switch (type) { |
| 729 case chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED: | 824 case chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED: |
| 730 if (!device_local_account_policy_service_) { | 825 if (!device_local_account_policy_service_) { |
| 731 device_local_account_policy_service_ = | 826 device_local_account_policy_service_ = |
| 732 g_browser_process->browser_policy_connector()-> | 827 g_browser_process->browser_policy_connector()-> |
| 733 GetDeviceLocalAccountPolicyService(); | 828 GetDeviceLocalAccountPolicyService(); |
| 734 if (device_local_account_policy_service_) | 829 if (device_local_account_policy_service_) |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 751 HasSwitch(::switches::kMultiProfiles)) { | 846 HasSwitch(::switches::kMultiProfiles)) { |
| 752 DCHECK(NULL == observed_sync_service_); | 847 DCHECK(NULL == observed_sync_service_); |
| 753 observed_sync_service_ = | 848 observed_sync_service_ = |
| 754 ProfileSyncServiceFactory::GetForProfile(profile); | 849 ProfileSyncServiceFactory::GetForProfile(profile); |
| 755 if (observed_sync_service_) | 850 if (observed_sync_service_) |
| 756 observed_sync_service_->AddObserver(this); | 851 observed_sync_service_->AddObserver(this); |
| 757 } | 852 } |
| 758 } | 853 } |
| 759 } | 854 } |
| 760 break; | 855 break; |
| 856 case chrome::NOTIFICATION_PROFILE_CREATED: { | |
| 857 Profile* profile = content::Source<Profile>(source).ptr(); | |
| 858 User* user = GetUserByProfile(profile); | |
| 859 if (user != NULL) { | |
| 860 user->set_profile_is_created(); | |
| 861 if (user == active_user_) | |
| 862 RespectLocalePreference(profile, user); | |
| 863 } | |
| 864 break; | |
| 865 } | |
| 761 case chrome::NOTIFICATION_SYSTEM_SETTING_CHANGED: { | 866 case chrome::NOTIFICATION_SYSTEM_SETTING_CHANGED: { |
| 762 std::string changed_setting = | 867 std::string changed_setting = |
| 763 *content::Details<const std::string>(details).ptr(); | 868 *content::Details<const std::string>(details).ptr(); |
| 764 DCHECK(changed_setting == kAccountsPrefDeviceLocalAccounts || | 869 DCHECK(changed_setting == kAccountsPrefDeviceLocalAccounts || |
| 765 changed_setting == kAccountsPrefSupervisedUsersEnabled); | 870 changed_setting == kAccountsPrefSupervisedUsersEnabled); |
| 766 RetrieveTrustedDevicePolicies(); | 871 RetrieveTrustedDevicePolicies(); |
| 767 break; | 872 break; |
| 768 } | 873 } |
| 769 default: | 874 default: |
| 770 NOTREACHED(); | 875 NOTREACHED(); |
| (...skipping 1033 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1804 base::TimeTicks::Now() - manager_creation_time_; | 1909 base::TimeTicks::Now() - manager_creation_time_; |
| 1805 if (!last_email.empty() && email != last_email && | 1910 if (!last_email.empty() && email != last_email && |
| 1806 time_to_login.InSeconds() <= kLogoutToLoginDelayMaxSec) { | 1911 time_to_login.InSeconds() <= kLogoutToLoginDelayMaxSec) { |
| 1807 UMA_HISTOGRAM_CUSTOM_COUNTS("UserManager.LogoutToLoginDelay", | 1912 UMA_HISTOGRAM_CUSTOM_COUNTS("UserManager.LogoutToLoginDelay", |
| 1808 time_to_login.InSeconds(), 0, kLogoutToLoginDelayMaxSec, 50); | 1913 time_to_login.InSeconds(), 0, kLogoutToLoginDelayMaxSec, 50); |
| 1809 } | 1914 } |
| 1810 } | 1915 } |
| 1811 } | 1916 } |
| 1812 | 1917 |
| 1813 } // namespace chromeos | 1918 } // namespace chromeos |
| OLD | NEW |