Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(926)

Side by Side Diff: chrome/browser/chromeos/login/user_manager_impl.cc

Issue 23095006: If user profile doesn't contain language setting, default to his Google account settings. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix Multi Profile support. Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698