| 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/files/file_path.h" | 15 #include "base/files/file_path.h" |
| 16 #include "base/logging.h" | 16 #include "base/logging.h" |
| 17 #include "base/metrics/histogram.h" | 17 #include "base/metrics/histogram.h" |
| 18 #include "base/prefs/pref_registry_simple.h" | 18 #include "base/prefs/pref_registry_simple.h" |
| 19 #include "base/prefs/pref_service.h" | 19 #include "base/prefs/pref_service.h" |
| 20 #include "base/rand_util.h" | 20 #include "base/rand_util.h" |
| 21 #include "base/strings/string_util.h" | 21 #include "base/strings/string_util.h" |
| 22 #include "base/strings/stringprintf.h" | 22 #include "base/strings/stringprintf.h" |
| 23 #include "base/strings/utf_string_conversions.h" | 23 #include "base/strings/utf_string_conversions.h" |
| 24 #include "base/values.h" | 24 #include "base/values.h" |
| 25 #include "chrome/browser/app_mode/app_mode_utils.h" | 25 #include "chrome/browser/app_mode/app_mode_utils.h" |
| 26 #include "chrome/browser/browser_process.h" | 26 #include "chrome/browser/browser_process.h" |
| 27 #include "chrome/browser/chrome_notification_types.h" | 27 #include "chrome/browser/chrome_notification_types.h" |
| 28 #include "chrome/browser/chromeos/cros/cert_library.h" | 28 #include "chrome/browser/chromeos/cros/cert_library.h" |
| 29 #include "chrome/browser/chromeos/login/default_pinned_apps_field_trial.h" | 29 #include "chrome/browser/chromeos/login/default_pinned_apps_field_trial.h" |
| 30 #include "chrome/browser/chromeos/login/language_switch_menu.h" |
| 30 #include "chrome/browser/chromeos/login/login_display.h" | 31 #include "chrome/browser/chromeos/login/login_display.h" |
| 31 #include "chrome/browser/chromeos/login/login_utils.h" | 32 #include "chrome/browser/chromeos/login/login_utils.h" |
| 32 #include "chrome/browser/chromeos/login/remove_user_delegate.h" | 33 #include "chrome/browser/chromeos/login/remove_user_delegate.h" |
| 33 #include "chrome/browser/chromeos/login/user_image_manager_impl.h" | 34 #include "chrome/browser/chromeos/login/user_image_manager_impl.h" |
| 34 #include "chrome/browser/chromeos/login/wizard_controller.h" | 35 #include "chrome/browser/chromeos/login/wizard_controller.h" |
| 35 #include "chrome/browser/chromeos/policy/device_local_account.h" | 36 #include "chrome/browser/chromeos/policy/device_local_account.h" |
| 37 #include "chrome/browser/chromeos/profiles/profile_helper.h" |
| 36 #include "chrome/browser/chromeos/session_length_limiter.h" | 38 #include "chrome/browser/chromeos/session_length_limiter.h" |
| 37 #include "chrome/browser/chromeos/settings/cros_settings_names.h" | 39 #include "chrome/browser/chromeos/settings/cros_settings_names.h" |
| 38 #include "chrome/browser/managed_mode/managed_user_service.h" | 40 #include "chrome/browser/managed_mode/managed_user_service.h" |
| 39 #include "chrome/browser/policy/browser_policy_connector.h" | 41 #include "chrome/browser/policy/browser_policy_connector.h" |
| 40 #include "chrome/browser/prefs/scoped_user_pref_update.h" | 42 #include "chrome/browser/prefs/scoped_user_pref_update.h" |
| 43 #include "chrome/browser/profiles/profile.h" |
| 41 #include "chrome/browser/profiles/profile_manager.h" | 44 #include "chrome/browser/profiles/profile_manager.h" |
| 42 #include "chrome/browser/sync/profile_sync_service.h" | 45 #include "chrome/browser/sync/profile_sync_service.h" |
| 43 #include "chrome/browser/sync/profile_sync_service_factory.h" | 46 #include "chrome/browser/sync/profile_sync_service_factory.h" |
| 44 #include "chrome/common/chrome_switches.h" | 47 #include "chrome/common/chrome_switches.h" |
| 45 #include "chrome/common/pref_names.h" | 48 #include "chrome/common/pref_names.h" |
| 46 #include "chromeos/chromeos_switches.h" | 49 #include "chromeos/chromeos_switches.h" |
| 47 #include "chromeos/cryptohome/async_method_caller.h" | 50 #include "chromeos/cryptohome/async_method_caller.h" |
| 48 #include "chromeos/dbus/dbus_thread_manager.h" | 51 #include "chromeos/dbus/dbus_thread_manager.h" |
| 49 #include "chromeos/ime/input_method_manager.h" | 52 #include "chromeos/ime/input_method_manager.h" |
| 50 #include "chromeos/login/login_state.h" | 53 #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), | 227 merge_session_state_(MERGE_STATUS_NOT_STARTED), |
| 225 observed_sync_service_(NULL), | 228 observed_sync_service_(NULL), |
| 226 user_image_manager_(new UserImageManagerImpl), | 229 user_image_manager_(new UserImageManagerImpl), |
| 227 manager_creation_time_(base::TimeTicks::Now()) { | 230 manager_creation_time_(base::TimeTicks::Now()) { |
| 228 // UserManager instance should be used only on UI thread. | 231 // UserManager instance should be used only on UI thread. |
| 229 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 232 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 230 registrar_.Add(this, chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED, | 233 registrar_.Add(this, chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED, |
| 231 content::NotificationService::AllSources()); | 234 content::NotificationService::AllSources()); |
| 232 registrar_.Add(this, chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED, | 235 registrar_.Add(this, chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED, |
| 233 content::NotificationService::AllSources()); | 236 content::NotificationService::AllSources()); |
| 237 registrar_.Add(this, |
| 238 chrome::NOTIFICATION_PROFILE_CREATED, |
| 239 content::NotificationService::AllSources()); |
| 234 RetrieveTrustedDevicePolicies(); | 240 RetrieveTrustedDevicePolicies(); |
| 235 cros_settings_->AddSettingsObserver(kAccountsPrefDeviceLocalAccounts, | 241 cros_settings_->AddSettingsObserver(kAccountsPrefDeviceLocalAccounts, |
| 236 this); | 242 this); |
| 237 cros_settings_->AddSettingsObserver(kAccountsPrefSupervisedUsersEnabled, | 243 cros_settings_->AddSettingsObserver(kAccountsPrefSupervisedUsersEnabled, |
| 238 this); | 244 this); |
| 239 UpdateLoginState(); | 245 UpdateLoginState(); |
| 240 } | 246 } |
| 241 | 247 |
| 242 UserManagerImpl::~UserManagerImpl() { | 248 UserManagerImpl::~UserManagerImpl() { |
| 243 // Can't use STLDeleteElements because of the private destructor of User. | 249 // Can't use STLDeleteElements because of the private destructor of User. |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 287 if ((*it)->GetType() == User::USER_TYPE_REGULAR && !(*it)->is_logged_in()) | 293 if ((*it)->GetType() == User::USER_TYPE_REGULAR && !(*it)->is_logged_in()) |
| 288 result.push_back(*it); | 294 result.push_back(*it); |
| 289 } | 295 } |
| 290 return result; | 296 return result; |
| 291 } | 297 } |
| 292 | 298 |
| 293 const UserList& UserManagerImpl::GetLoggedInUsers() const { | 299 const UserList& UserManagerImpl::GetLoggedInUsers() const { |
| 294 return logged_in_users_; | 300 return logged_in_users_; |
| 295 } | 301 } |
| 296 | 302 |
| 303 const User* UserManagerImpl::GetPrimaryUser() const { |
| 304 return (logged_in_users_.size() == 0 ? active_user_ |
| 305 : logged_in_users_.front()); |
| 306 } |
| 307 |
| 297 const UserList& UserManagerImpl::GetLRULoggedInUsers() { | 308 const UserList& UserManagerImpl::GetLRULoggedInUsers() { |
| 298 // If there is no user logged in, we return the active user as the only one. | 309 // If there is no user logged in, we return the active user as the only one. |
| 299 if (lru_logged_in_users_.empty() && active_user_) { | 310 if (lru_logged_in_users_.empty() && active_user_) { |
| 300 temp_single_logged_in_users_.clear(); | 311 temp_single_logged_in_users_.clear(); |
| 301 temp_single_logged_in_users_.insert(temp_single_logged_in_users_.begin(), | 312 temp_single_logged_in_users_.insert(temp_single_logged_in_users_.begin(), |
| 302 active_user_); | 313 active_user_); |
| 303 return temp_single_logged_in_users_; | 314 return temp_single_logged_in_users_; |
| 304 } | 315 } |
| 305 return lru_logged_in_users_; | 316 return lru_logged_in_users_; |
| 306 } | 317 } |
| (...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 641 static_cast<User::OAuthTokenStatus>(oauth_token_status); | 652 static_cast<User::OAuthTokenStatus>(oauth_token_status); |
| 642 if (result == User::OAUTH2_TOKEN_STATUS_INVALID) | 653 if (result == User::OAUTH2_TOKEN_STATUS_INVALID) |
| 643 GetUserFlow(username)->HandleOAuthTokenStatusChange(result); | 654 GetUserFlow(username)->HandleOAuthTokenStatusChange(result); |
| 644 return result; | 655 return result; |
| 645 } | 656 } |
| 646 return User::OAUTH_TOKEN_STATUS_UNKNOWN; | 657 return User::OAUTH_TOKEN_STATUS_UNKNOWN; |
| 647 } | 658 } |
| 648 | 659 |
| 649 void UserManagerImpl::SaveUserDisplayName(const std::string& username, | 660 void UserManagerImpl::SaveUserDisplayName(const std::string& username, |
| 650 const string16& display_name) { | 661 const string16& display_name) { |
| 662 UpdateUserAccountDataImpl(username, display_name, NULL); |
| 663 } |
| 664 |
| 665 void UserManagerImpl::UpdateUserAccountData(const std::string& username, |
| 666 const string16& display_name, |
| 667 const std::string& locale) { |
| 668 UpdateUserAccountDataImpl(username, display_name, &locale); |
| 669 } |
| 670 |
| 671 void UserManagerImpl::UpdateUserAccountDataImpl(const std::string& username, |
| 672 const string16& display_name, |
| 673 const std::string* locale) { |
| 651 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 674 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 652 | 675 |
| 653 User* user = FindUserAndModify(username); | 676 User* user = FindUserAndModify(username); |
| 654 if (!user) | 677 if (!user) |
| 655 return; // Ignore if there is no such user. | 678 return; // Ignore if there is no such user. |
| 656 | 679 |
| 680 // locale is not NULL if User Account has been downloaded |
| 681 // (i.e. it is UpdateUserAccountData(), not SaveUserDisplayName() ) |
| 682 if (locale != NULL) { |
| 683 user->SetAccountLocale(*locale); |
| 684 RespectLocalePreference(GetProfileByUser(user), user); |
| 685 } |
| 686 |
| 687 if (display_name.empty()) |
| 688 return; |
| 689 |
| 657 user->set_display_name(display_name); | 690 user->set_display_name(display_name); |
| 658 | 691 |
| 659 // Do not update local store if data stored or cached outside the user's | 692 // Do not update local store if data stored or cached outside the user's |
| 660 // cryptohome is to be treated as ephemeral. | 693 // cryptohome is to be treated as ephemeral. |
| 661 if (IsUserNonCryptohomeDataEphemeral(username)) | 694 if (IsUserNonCryptohomeDataEphemeral(username)) |
| 662 return; | 695 return; |
| 663 | 696 |
| 664 PrefService* local_state = g_browser_process->local_state(); | 697 PrefService* local_state = g_browser_process->local_state(); |
| 665 | 698 |
| 666 DictionaryPrefUpdate display_name_update(local_state, kUserDisplayName); | 699 DictionaryPrefUpdate display_name_update(local_state, kUserDisplayName); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 715 username, | 748 username, |
| 716 new base::StringValue(display_email)); | 749 new base::StringValue(display_email)); |
| 717 } | 750 } |
| 718 | 751 |
| 719 std::string UserManagerImpl::GetUserDisplayEmail( | 752 std::string UserManagerImpl::GetUserDisplayEmail( |
| 720 const std::string& username) const { | 753 const std::string& username) const { |
| 721 const User* user = FindUser(username); | 754 const User* user = FindUser(username); |
| 722 return user ? user->display_email() : username; | 755 return user ? user->display_email() : username; |
| 723 } | 756 } |
| 724 | 757 |
| 758 // TODO(alemate): http://crbug.com/288941 : Respect preferred language list in |
| 759 // the Google user profile. |
| 760 void UserManagerImpl::RespectLocalePreference(Profile* profile, |
| 761 const User* user) const { |
| 762 if (g_browser_process == NULL) |
| 763 return; |
| 764 if ((user == NULL) || (user != GetPrimaryUser()) || |
| 765 (!user->is_profile_created())) |
| 766 return; |
| 767 |
| 768 if (profile != ProfileManager::GetDefaultProfile()) |
| 769 return; |
| 770 const PrefService* prefs = profile->GetPrefs(); |
| 771 if (prefs == NULL) |
| 772 return; |
| 773 |
| 774 std::string pref_locale = prefs->GetString(prefs::kApplicationLocale); |
| 775 if (pref_locale.empty()) |
| 776 pref_locale = prefs->GetString(prefs::kApplicationLocaleBackup); |
| 777 |
| 778 if (pref_locale.empty() && user->has_gaia_account()) { |
| 779 if (user->GetAccountLocale() == NULL) |
| 780 return; // wait until Account profile is loaded. |
| 781 pref_locale = *(user->GetAccountLocale()); |
| 782 } |
| 783 if (pref_locale.empty()) |
| 784 pref_locale = g_browser_process->GetApplicationLocale(); |
| 785 DCHECK(!pref_locale.empty()); |
| 786 profile->ChangeAppLocale(pref_locale, Profile::APP_LOCALE_CHANGED_VIA_LOGIN); |
| 787 // Here we don't enable keyboard layouts. Input methods are set up when |
| 788 // the user first logs in. Then the user may customize the input methods. |
| 789 // Hence changing input methods here, just because the user's UI language |
| 790 // is different from the login screen UI language, is not desirable. Note |
| 791 // that input method preferences are synced, so users can use their |
| 792 // farovite input methods as soon as the preferences are synced. |
| 793 chromeos::LanguageSwitchMenu::SwitchLanguage(pref_locale); |
| 794 } |
| 795 |
| 796 class UserHashMatcher { |
| 797 public: |
| 798 explicit UserHashMatcher(const std::string& h) : username_hash(h) {} |
| 799 bool operator()(const User* user) const { |
| 800 return user->username_hash() == username_hash; |
| 801 } |
| 802 |
| 803 private: |
| 804 const std::string& username_hash; |
| 805 }; |
| 806 |
| 807 // Returns NULL if user is not created |
| 808 User* UserManagerImpl::GetUserByProfile(Profile* profile) const { |
| 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 |
| 820 Profile* UserManagerImpl::GetProfileByUser(const User* user) const { |
| 821 if (CommandLine::ForCurrentProcess()->HasSwitch(::switches::kMultiProfiles)) |
| 822 return ProfileHelper::GetProfileByUserIdHash(user->username_hash()); |
| 823 return g_browser_process->profile_manager()->GetDefaultProfile(); |
| 824 } |
| 825 |
| 725 void UserManagerImpl::Observe(int type, | 826 void UserManagerImpl::Observe(int type, |
| 726 const content::NotificationSource& source, | 827 const content::NotificationSource& source, |
| 727 const content::NotificationDetails& details) { | 828 const content::NotificationDetails& details) { |
| 728 switch (type) { | 829 switch (type) { |
| 729 case chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED: | 830 case chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED: |
| 730 if (!device_local_account_policy_service_) { | 831 if (!device_local_account_policy_service_) { |
| 731 device_local_account_policy_service_ = | 832 device_local_account_policy_service_ = |
| 732 g_browser_process->browser_policy_connector()-> | 833 g_browser_process->browser_policy_connector()-> |
| 733 GetDeviceLocalAccountPolicyService(); | 834 GetDeviceLocalAccountPolicyService(); |
| 734 if (device_local_account_policy_service_) | 835 if (device_local_account_policy_service_) |
| (...skipping 16 matching lines...) Expand all Loading... |
| 751 HasSwitch(::switches::kMultiProfiles)) { | 852 HasSwitch(::switches::kMultiProfiles)) { |
| 752 DCHECK(NULL == observed_sync_service_); | 853 DCHECK(NULL == observed_sync_service_); |
| 753 observed_sync_service_ = | 854 observed_sync_service_ = |
| 754 ProfileSyncServiceFactory::GetForProfile(profile); | 855 ProfileSyncServiceFactory::GetForProfile(profile); |
| 755 if (observed_sync_service_) | 856 if (observed_sync_service_) |
| 756 observed_sync_service_->AddObserver(this); | 857 observed_sync_service_->AddObserver(this); |
| 757 } | 858 } |
| 758 } | 859 } |
| 759 } | 860 } |
| 760 break; | 861 break; |
| 862 case chrome::NOTIFICATION_PROFILE_CREATED: { |
| 863 Profile* profile = content::Source<Profile>(source).ptr(); |
| 864 User* user = GetUserByProfile(profile); |
| 865 if (user != NULL) { |
| 866 user->set_profile_is_created(); |
| 867 if (user == active_user_) |
| 868 RespectLocalePreference(profile, user); |
| 869 } |
| 870 break; |
| 871 } |
| 761 case chrome::NOTIFICATION_SYSTEM_SETTING_CHANGED: { | 872 case chrome::NOTIFICATION_SYSTEM_SETTING_CHANGED: { |
| 762 std::string changed_setting = | 873 std::string changed_setting = |
| 763 *content::Details<const std::string>(details).ptr(); | 874 *content::Details<const std::string>(details).ptr(); |
| 764 DCHECK(changed_setting == kAccountsPrefDeviceLocalAccounts || | 875 DCHECK(changed_setting == kAccountsPrefDeviceLocalAccounts || |
| 765 changed_setting == kAccountsPrefSupervisedUsersEnabled); | 876 changed_setting == kAccountsPrefSupervisedUsersEnabled); |
| 766 RetrieveTrustedDevicePolicies(); | 877 RetrieveTrustedDevicePolicies(); |
| 767 break; | 878 break; |
| 768 } | 879 } |
| 769 default: | 880 default: |
| 770 NOTREACHED(); | 881 NOTREACHED(); |
| (...skipping 1033 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1804 base::TimeTicks::Now() - manager_creation_time_; | 1915 base::TimeTicks::Now() - manager_creation_time_; |
| 1805 if (!last_email.empty() && email != last_email && | 1916 if (!last_email.empty() && email != last_email && |
| 1806 time_to_login.InSeconds() <= kLogoutToLoginDelayMaxSec) { | 1917 time_to_login.InSeconds() <= kLogoutToLoginDelayMaxSec) { |
| 1807 UMA_HISTOGRAM_CUSTOM_COUNTS("UserManager.LogoutToLoginDelay", | 1918 UMA_HISTOGRAM_CUSTOM_COUNTS("UserManager.LogoutToLoginDelay", |
| 1808 time_to_login.InSeconds(), 0, kLogoutToLoginDelayMaxSec, 50); | 1919 time_to_login.InSeconds(), 0, kLogoutToLoginDelayMaxSec, 50); |
| 1809 } | 1920 } |
| 1810 } | 1921 } |
| 1811 } | 1922 } |
| 1812 | 1923 |
| 1813 } // namespace chromeos | 1924 } // namespace chromeos |
| OLD | NEW |