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

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

Issue 11419184: Add public accounts to UserManager (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Quickly fix comment in typo before anyone notices... Created 8 years 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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>
8
7 #include "ash/shell.h" 9 #include "ash/shell.h"
8 #include "base/bind.h" 10 #include "base/bind.h"
9 #include "base/chromeos/chromeos_version.h" 11 #include "base/chromeos/chromeos_version.h"
10 #include "base/command_line.h" 12 #include "base/command_line.h"
11 #include "base/compiler_specific.h" 13 #include "base/compiler_specific.h"
12 #include "base/file_path.h" 14 #include "base/file_path.h"
13 #include "base/file_util.h" 15 #include "base/file_util.h"
14 #include "base/logging.h" 16 #include "base/logging.h"
15 #include "base/rand_util.h" 17 #include "base/rand_util.h"
16 #include "base/utf_string_conversions.h" 18 #include "base/utf_string_conversions.h"
17 #include "base/values.h" 19 #include "base/values.h"
18 #include "chrome/browser/browser_process.h" 20 #include "chrome/browser/browser_process.h"
19 #include "chrome/browser/chromeos/cros/cert_library.h" 21 #include "chrome/browser/chromeos/cros/cert_library.h"
20 #include "chrome/browser/chromeos/cros/cros_library.h" 22 #include "chrome/browser/chromeos/cros/cros_library.h"
21 #include "chrome/browser/chromeos/input_method/input_method_manager.h" 23 #include "chrome/browser/chromeos/input_method/input_method_manager.h"
22 #include "chrome/browser/chromeos/login/login_display.h" 24 #include "chrome/browser/chromeos/login/login_display.h"
23 #include "chrome/browser/chromeos/login/remove_user_delegate.h" 25 #include "chrome/browser/chromeos/login/remove_user_delegate.h"
24 #include "chrome/browser/chromeos/login/user_image_manager_impl.h" 26 #include "chrome/browser/chromeos/login/user_image_manager_impl.h"
25 #include "chrome/browser/chromeos/login/wizard_controller.h" 27 #include "chrome/browser/chromeos/login/wizard_controller.h"
26 #include "chrome/browser/chromeos/settings/cros_settings.h"
27 #include "chrome/browser/policy/browser_policy_connector.h" 28 #include "chrome/browser/policy/browser_policy_connector.h"
28 #include "chrome/browser/prefs/pref_service.h" 29 #include "chrome/browser/prefs/pref_service.h"
29 #include "chrome/browser/prefs/scoped_user_pref_update.h" 30 #include "chrome/browser/prefs/scoped_user_pref_update.h"
30 #include "chrome/browser/profiles/profile_manager.h" 31 #include "chrome/browser/profiles/profile_manager.h"
31 #include "chrome/browser/sync/profile_sync_service.h" 32 #include "chrome/browser/sync/profile_sync_service.h"
32 #include "chrome/browser/sync/profile_sync_service_factory.h" 33 #include "chrome/browser/sync/profile_sync_service_factory.h"
33 #include "chrome/common/chrome_notification_types.h" 34 #include "chrome/common/chrome_notification_types.h"
34 #include "chrome/common/chrome_switches.h" 35 #include "chrome/common/chrome_switches.h"
35 #include "chrome/common/pref_names.h" 36 #include "chrome/common/pref_names.h"
36 #include "chromeos/cryptohome/async_method_caller.h" 37 #include "chromeos/cryptohome/async_method_caller.h"
37 #include "content/public/browser/browser_thread.h" 38 #include "content/public/browser/browser_thread.h"
38 #include "content/public/browser/notification_service.h" 39 #include "content/public/browser/notification_service.h"
39 #include "google_apis/gaia/google_service_auth_error.h" 40 #include "google_apis/gaia/google_service_auth_error.h"
40 41
41 using content::BrowserThread; 42 using content::BrowserThread;
42 43
43 namespace chromeos { 44 namespace chromeos {
44 45
45 namespace { 46 namespace {
46 47
47 // A vector pref of the users who have logged into the device. 48 // A vector pref of the regular users who have logged into this device.
48 const char kLoggedInUsers[] = "LoggedInUsers"; 49 const char kRegularUsers[] = "LoggedInUsers";
Ivan Korotkov 2012/11/28 21:40:53 I'm very concerned about splitting users into seve
Nikita (slow) 2012/11/29 12:00:50 I agree with Ivan. We should have single LoggedInU
Ivan Korotkov 2012/11/29 12:06:31 As discussed over chat, this CL actually adds supp
bartfab (slow) 2012/11/29 14:18:09 I renamed |LocalUsers| to |PublicAccounts|. I left
50
51 // A vector pref of the device-local users defined on this device.
52 const char kLocalUsers[] = "LocalUsers";
53
54 // A string pref that gets set when a device-local user is to be removed but is
55 // currently logged in, requiring the user's data to be removed after logout.
56 const char kUserPendingDataRemoval[] = "UserPendingDataRemoval";
49 57
50 // A dictionary that maps usernames to the displayed name. 58 // A dictionary that maps usernames to the displayed name.
51 const char kUserDisplayName[] = "UserDisplayName"; 59 const char kUserDisplayName[] = "UserDisplayName";
52 60
53 // A dictionary that maps usernames to the displayed (non-canonical) emails. 61 // A dictionary that maps usernames to the displayed (non-canonical) emails.
54 const char kUserDisplayEmail[] = "UserDisplayEmail"; 62 const char kUserDisplayEmail[] = "UserDisplayEmail";
55 63
56 // A dictionary that maps usernames to OAuth token presence flag. 64 // A dictionary that maps usernames to OAuth token presence flag.
57 const char kUserOAuthTokenStatus[] = "OAuthTokenStatus"; 65 const char kUserOAuthTokenStatus[] = "OAuthTokenStatus";
58 66
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 user_email, base::Bind(&OnRemoveUserComplete, user_email)); 102 user_email, base::Bind(&OnRemoveUserComplete, user_email));
95 103
96 if (delegate) 104 if (delegate)
97 delegate->OnUserRemoved(user_email); 105 delegate->OnUserRemoved(user_email);
98 } 106 }
99 107
100 } // namespace 108 } // namespace
101 109
102 // static 110 // static
103 void UserManager::RegisterPrefs(PrefService* local_state) { 111 void UserManager::RegisterPrefs(PrefService* local_state) {
104 local_state->RegisterListPref(kLoggedInUsers, PrefService::UNSYNCABLE_PREF); 112 local_state->RegisterListPref(kRegularUsers, PrefService::UNSYNCABLE_PREF);
113 local_state->RegisterListPref(kLocalUsers, PrefService::UNSYNCABLE_PREF);
114 local_state->RegisterStringPref(kUserPendingDataRemoval, "",
115 PrefService::UNSYNCABLE_PREF);
105 local_state->RegisterDictionaryPref(kUserOAuthTokenStatus, 116 local_state->RegisterDictionaryPref(kUserOAuthTokenStatus,
106 PrefService::UNSYNCABLE_PREF); 117 PrefService::UNSYNCABLE_PREF);
107 local_state->RegisterDictionaryPref(kUserDisplayName, 118 local_state->RegisterDictionaryPref(kUserDisplayName,
108 PrefService::UNSYNCABLE_PREF); 119 PrefService::UNSYNCABLE_PREF);
109 local_state->RegisterDictionaryPref(kUserDisplayEmail, 120 local_state->RegisterDictionaryPref(kUserDisplayEmail,
110 PrefService::UNSYNCABLE_PREF); 121 PrefService::UNSYNCABLE_PREF);
111 } 122 }
112 123
113 UserManagerImpl::UserManagerImpl() 124 UserManagerImpl::UserManagerImpl()
114 : logged_in_user_(NULL), 125 : cros_settings_(CrosSettings::Get()),
126 users_loaded_(false),
127 logged_in_user_(NULL),
115 session_started_(false), 128 session_started_(false),
116 is_current_user_owner_(false), 129 is_current_user_owner_(false),
117 is_current_user_new_(false), 130 is_current_user_new_(false),
118 is_current_user_ephemeral_(false), 131 is_current_user_ephemeral_(false),
119 ephemeral_users_enabled_(false), 132 ephemeral_users_enabled_(false),
120 observed_sync_service_(NULL), 133 observed_sync_service_(NULL),
121 user_image_manager_(new UserImageManagerImpl) { 134 user_image_manager_(new UserImageManagerImpl) {
122 // UserManager instance should be used only on UI thread. 135 // UserManager instance should be used only on UI thread.
123 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 136 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
124 registrar_.Add(this, chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED, 137 registrar_.Add(this, chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED,
125 content::NotificationService::AllSources()); 138 content::NotificationService::AllSources());
126 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_ADDED, 139 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_ADDED,
127 content::NotificationService::AllSources()); 140 content::NotificationService::AllSources());
128 RetrieveTrustedDevicePolicies(); 141 RetrieveTrustedDevicePolicies();
129 } 142 }
130 143
131 UserManagerImpl::~UserManagerImpl() { 144 UserManagerImpl::~UserManagerImpl() {
132 // Can't use STLDeleteElements because of the private destructor of User. 145 // Can't use STLDeleteElements because of the private destructor of User.
133 for (size_t i = 0; i < users_.size(); ++i) 146 for (size_t i = 0; i < users_.size(); ++i)
134 delete users_[i]; 147 delete users_[i];
135 users_.clear(); 148 users_.clear();
136 if (is_current_user_ephemeral_) 149 if (is_current_user_ephemeral_)
137 delete logged_in_user_; 150 delete logged_in_user_;
138 } 151 }
139 152
153 void UserManagerImpl::Shutdown() {
154 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
155 cros_settings_->RemoveSettingsObserver(kAccountsPrefDeviceLocalAccounts,
156 this);
157 }
158
140 UserImageManager* UserManagerImpl::GetUserImageManager() { 159 UserImageManager* UserManagerImpl::GetUserImageManager() {
141 return user_image_manager_.get(); 160 return user_image_manager_.get();
142 } 161 }
143 162
144 const UserList& UserManagerImpl::GetUsers() const { 163 const UserList& UserManagerImpl::GetUsers() const {
145 const_cast<UserManagerImpl*>(this)->EnsureUsersLoaded(); 164 EnsureUsersLoaded();
146 return users_; 165 return users_;
147 } 166 }
148 167
149 void UserManagerImpl::UserLoggedIn(const std::string& email, 168 void UserManagerImpl::UserLoggedIn(const std::string& email,
150 bool browser_restart) { 169 bool browser_restart) {
151 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 170 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
152 DCHECK(!IsUserLoggedIn()); 171 DCHECK(!IsUserLoggedIn());
153 172
154 if (email == kGuestUserEMail) { 173 if (email == kGuestUserEMail) {
155 GuestUserLoggedIn(); 174 GuestUserLoggedIn();
156 return; 175 return;
157 } 176 }
158 177
159 if (email == kRetailModeUserEMail) { 178 if (email == kRetailModeUserEMail) {
160 RetailModeUserLoggedIn(); 179 RetailModeUserLoggedIn();
161 return; 180 return;
162 } 181 }
163 182
164 if (IsEphemeralUser(email)) { 183 if (IsEphemeralUser(email)) {
Nikita (slow) 2012/11/29 12:00:50 Public accounts will be handled here, right? If t
bartfab (slow) 2012/11/29 14:18:09 Public accounts will be treated separately because
165 EphemeralUserLoggedIn(email); 184 EphemeralUserLoggedIn(email);
166 return; 185 return;
167 } 186 }
168 187
169 EnsureUsersLoaded(); 188 EnsureUsersLoaded();
170 189
171 // Clear the prefs view of the users. 190 // Remove the user from the user list.
172 PrefService* prefs = g_browser_process->local_state(); 191 logged_in_user_ = RemoveUserFromListInternal(email);
173 ListPrefUpdate prefs_users_update(prefs, kLoggedInUsers);
174 prefs_users_update->Clear();
175 192
176 // Make sure this user is first. 193 // Add the user to the front of the persistent user list.
177 prefs_users_update->Append(new base::StringValue(email)); 194 ListPrefUpdate prefs_users_update(g_browser_process->local_state(),
178 UserList::iterator logged_in_user = users_.end(); 195 kRegularUsers);
179 for (UserList::iterator it = users_.begin(); it != users_.end(); ++it) { 196 prefs_users_update->Insert(0, new base::StringValue(email));
180 std::string user_email = (*it)->email();
181 // Skip the most recent user.
182 if (email != user_email)
183 prefs_users_update->Append(new base::StringValue(user_email));
184 else
185 logged_in_user = it;
186 }
187 197
188 if (logged_in_user == users_.end()) { 198 // If the user was not found on the user list, create a new user.
199 if (!logged_in_user_) {
189 is_current_user_new_ = true; 200 is_current_user_new_ = true;
190 logged_in_user_ = User::CreateRegularUser(email); 201 logged_in_user_ = User::CreateRegularUser(email);
191 logged_in_user_->set_oauth_token_status(LoadUserOAuthStatus(email)); 202 logged_in_user_->set_oauth_token_status(LoadUserOAuthStatus(email));
192 } else {
193 logged_in_user_ = *logged_in_user;
194 users_.erase(logged_in_user);
195 }
196 // This user must be in the front of the user list.
197 users_.insert(users_.begin(), logged_in_user_);
198
199 if (is_current_user_new_) {
200 SaveUserDisplayName(logged_in_user_->email(), 203 SaveUserDisplayName(logged_in_user_->email(),
201 UTF8ToUTF16(logged_in_user_->GetAccountName(true))); 204 UTF8ToUTF16(logged_in_user_->GetAccountName(true)));
202 WallpaperManager::Get()->SetInitialUserWallpaper(email, true); 205 WallpaperManager::Get()->SetInitialUserWallpaper(email, true);
203 } 206 }
204 207
205 user_image_manager_->UserLoggedIn(email, is_current_user_new_); 208 user_image_manager_->UserLoggedIn(email, is_current_user_new_);
206 209
207 if (!browser_restart) { 210 if (!browser_restart) {
208 // For GAIA login flow, logged in user wallpaper may not be loaded. 211 // For GAIA login flow, logged in user wallpaper may not be loaded.
209 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded(); 212 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
210 } 213 }
211 214
Ivan Korotkov 2012/11/28 21:40:53 Why are you removing this bit?
Nikita (slow) 2012/11/29 12:00:50 To give more context: this call ensures that if si
bartfab (slow) 2012/11/29 14:18:09 I removed this at Julian's request. The local stat
Ivan Korotkov 2012/11/29 17:25:33 Right, but if browser crashes in the first few sec
bartfab (slow) 2012/11/29 18:56:17 Done.
212 // Make sure we persist new user data to Local State.
213 prefs->CommitPendingWrite();
214
215 NotifyOnLogin(); 215 NotifyOnLogin();
216 } 216 }
217 217
218 void UserManagerImpl::RetailModeUserLoggedIn() { 218 void UserManagerImpl::RetailModeUserLoggedIn() {
219 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 219 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
220 is_current_user_new_ = true; 220 is_current_user_new_ = true;
221 is_current_user_ephemeral_ = true; 221 is_current_user_ephemeral_ = true;
222 logged_in_user_ = User::CreateRetailModeUser(); 222 logged_in_user_ = User::CreateRetailModeUser();
223 user_image_manager_->UserLoggedIn(kRetailModeUserEMail, 223 user_image_manager_->UserLoggedIn(kRetailModeUserEMail,
224 /* user_is_new= */ true); 224 /* user_is_new= */ true);
(...skipping 20 matching lines...) Expand all
245 NotifyOnLogin(); 245 NotifyOnLogin();
246 } 246 }
247 247
248 void UserManagerImpl::SessionStarted() { 248 void UserManagerImpl::SessionStarted() {
249 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 249 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
250 session_started_ = true; 250 session_started_ = true;
251 content::NotificationService::current()->Notify( 251 content::NotificationService::current()->Notify(
252 chrome::NOTIFICATION_SESSION_STARTED, 252 chrome::NOTIFICATION_SESSION_STARTED,
253 content::NotificationService::AllSources(), 253 content::NotificationService::AllSources(),
254 content::NotificationService::NoDetails()); 254 content::NotificationService::NoDetails());
255 if (is_current_user_new_) {
256 // Make sure we persist new user data to Local State.
Ivan Korotkov 2012/11/28 21:40:53 And this one.
Nikita (slow) 2012/11/29 12:00:50 Same here: ensures that new user avatar is saved i
bartfab (slow) 2012/11/29 14:18:09 Same as above.
bartfab (slow) 2012/11/29 18:56:17 Done.
257 g_browser_process->local_state()->CommitPendingWrite();
258 }
259 } 255 }
260 256
261 void UserManagerImpl::RemoveUser(const std::string& email, 257 void UserManagerImpl::RemoveUser(const std::string& email,
262 RemoveUserDelegate* delegate) { 258 RemoveUserDelegate* delegate) {
263 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 259 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
264 260
265 if (!IsKnownUser(email)) 261 const User* user = FindUser(email);
262 if (!user || user->GetType() != User::USER_TYPE_REGULAR)
266 return; 263 return;
267 264
268 // Sanity check: we must not remove single user. This check may seem 265 // Sanity check: we must not remove single user. This check may seem
269 // redundant at a first sight because this single user must be an owner and 266 // redundant at a first sight because this single user must be an owner and
270 // we perform special check later in order not to remove an owner. However 267 // we perform special check later in order not to remove an owner. However
271 // due to non-instant nature of ownership assignment this later check may 268 // due to non-instant nature of ownership assignment this later check may
272 // sometimes fail. See http://crosbug.com/12723 269 // sometimes fail. See http://crosbug.com/12723
273 if (users_.size() < 2) 270 if (users_.size() < 2)
274 return; 271 return;
275 272
276 // Sanity check: do not allow the logged-in user to remove himself. 273 // Sanity check: do not allow the logged-in user to remove himself.
277 if (logged_in_user_ && logged_in_user_->email() == email) 274 if (logged_in_user_ && logged_in_user_->email() == email)
278 return; 275 return;
279 276
280 RemoveUserInternal(email, delegate); 277 RemoveUserInternal(email, delegate);
281 } 278 }
282 279
283 void UserManagerImpl::RemoveUserFromList(const std::string& email) { 280 void UserManagerImpl::RemoveUserFromList(const std::string& email) {
284 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 281 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
285 EnsureUsersLoaded(); 282 EnsureUsersLoaded();
286 RemoveUserFromListInternal(email); 283 RemoveNonCryptohomeData(email);
284 delete RemoveUserFromListInternal(email);
287 } 285 }
288 286
289 bool UserManagerImpl::IsKnownUser(const std::string& email) const { 287 bool UserManagerImpl::IsKnownUser(const std::string& email) const {
290 return FindUser(email) != NULL; 288 return FindUser(email) != NULL;
291 } 289 }
292 290
293 const User* UserManagerImpl::FindUser(const std::string& email) const { 291 const User* UserManagerImpl::FindUser(const std::string& email) const {
294 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 292 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
295 if (logged_in_user_ && logged_in_user_->email() == email) 293 if (logged_in_user_ && logged_in_user_->email() == email)
296 return logged_in_user_; 294 return logged_in_user_;
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 if (!profile->IsOffTheRecord() && 420 if (!profile->IsOffTheRecord() &&
423 profile == ProfileManager::GetDefaultProfile()) { 421 profile == ProfileManager::GetDefaultProfile()) {
424 DCHECK(NULL == observed_sync_service_); 422 DCHECK(NULL == observed_sync_service_);
425 observed_sync_service_ = 423 observed_sync_service_ =
426 ProfileSyncServiceFactory::GetForProfile(profile); 424 ProfileSyncServiceFactory::GetForProfile(profile);
427 if (observed_sync_service_) 425 if (observed_sync_service_)
428 observed_sync_service_->AddObserver(this); 426 observed_sync_service_->AddObserver(this);
429 } 427 }
430 } 428 }
431 break; 429 break;
430 case chrome::NOTIFICATION_SYSTEM_SETTING_CHANGED:
431 DCHECK_EQ(*content::Details<const std::string>(details).ptr(),
432 kAccountsPrefDeviceLocalAccounts);
433 RetrieveTrustedDevicePolicies();
434 break;
432 default: 435 default:
433 NOTREACHED(); 436 NOTREACHED();
434 } 437 }
435 } 438 }
436 439
437 void UserManagerImpl::OnStateChanged() { 440 void UserManagerImpl::OnStateChanged() {
438 DCHECK(IsUserLoggedIn() && !IsLoggedInAsGuest()); 441 DCHECK(IsLoggedInAsRegularUser());
439 GoogleServiceAuthError::State state = 442 GoogleServiceAuthError::State state =
440 observed_sync_service_->GetAuthError().state(); 443 observed_sync_service_->GetAuthError().state();
441 if (state != GoogleServiceAuthError::NONE && 444 if (state != GoogleServiceAuthError::NONE &&
442 state != GoogleServiceAuthError::CONNECTION_FAILED && 445 state != GoogleServiceAuthError::CONNECTION_FAILED &&
443 state != GoogleServiceAuthError::SERVICE_UNAVAILABLE && 446 state != GoogleServiceAuthError::SERVICE_UNAVAILABLE &&
444 state != GoogleServiceAuthError::REQUEST_CANCELED) { 447 state != GoogleServiceAuthError::REQUEST_CANCELED) {
445 // Invalidate OAuth token to force Gaia sign-in flow. This is needed 448 // Invalidate OAuth token to force Gaia sign-in flow. This is needed
446 // because sign-out/sign-in solution is suggested to the user. 449 // because sign-out/sign-in solution is suggested to the user.
447 // TODO(altimofeev): this code isn't needed after crosbug.com/25978 is 450 // TODO(altimofeev): this code isn't needed after crosbug.com/25978 is
448 // implemented. 451 // implemented.
(...skipping 28 matching lines...) Expand all
477 bool UserManagerImpl::CanCurrentUserLock() const { 480 bool UserManagerImpl::CanCurrentUserLock() const {
478 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 481 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
479 return IsUserLoggedIn() && logged_in_user_->can_lock(); 482 return IsUserLoggedIn() && logged_in_user_->can_lock();
480 } 483 }
481 484
482 bool UserManagerImpl::IsUserLoggedIn() const { 485 bool UserManagerImpl::IsUserLoggedIn() const {
483 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 486 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
484 return logged_in_user_; 487 return logged_in_user_;
485 } 488 }
486 489
490 bool UserManagerImpl::IsLoggedInAsRegularUser() const {
491 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
492 return IsUserLoggedIn() &&
493 logged_in_user_->GetType() == User::USER_TYPE_REGULAR;
494 }
495
487 bool UserManagerImpl::IsLoggedInAsDemoUser() const { 496 bool UserManagerImpl::IsLoggedInAsDemoUser() const {
488 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 497 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
489 return IsUserLoggedIn() && 498 return IsUserLoggedIn() &&
490 logged_in_user_->GetType() == User::USER_TYPE_RETAIL_MODE; 499 logged_in_user_->GetType() == User::USER_TYPE_RETAIL_MODE;
491 } 500 }
492 501
493 bool UserManagerImpl::IsLoggedInAsPublicAccount() const { 502 bool UserManagerImpl::IsLoggedInAsPublicAccount() const {
494 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 503 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
495 return IsUserLoggedIn() && 504 return IsUserLoggedIn() &&
496 logged_in_user_->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT; 505 logged_in_user_->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
544 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 553 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
545 observer_list_.RemoveObserver(obs); 554 observer_list_.RemoveObserver(obs);
546 } 555 }
547 556
548 void UserManagerImpl::NotifyLocalStateChanged() { 557 void UserManagerImpl::NotifyLocalStateChanged() {
549 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 558 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
550 FOR_EACH_OBSERVER(UserManager::Observer, observer_list_, 559 FOR_EACH_OBSERVER(UserManager::Observer, observer_list_,
551 LocalStateChanged(this)); 560 LocalStateChanged(this));
552 } 561 }
553 562
554 void UserManagerImpl::EnsureUsersLoaded() { 563 bool UserManagerImpl::ParseUserList(
Ivan Korotkov 2012/11/28 21:40:53 Since this is a utility method that has nothing to
bartfab (slow) 2012/11/29 14:18:09 Done.
564 const ListValue& users_list,
565 const std::set<std::string>& existing_users,
566 const std::string& logged_in_user,
567 std::vector<std::string>* users_vector,
568 std::set<std::string>* users_set) const {
569 users_vector->clear();
570 users_set->clear();
571 bool logged_in_user_on_list = false;
572 for (size_t i = 0; i < users_list.GetSize(); ++i) {
573 std::string email;
574 if (!users_list.GetString(i, &email) || email.empty()) {
575 LOG(ERROR) << "Corrupt entry in user list at index " << i << ".";
576 continue;
577 }
578 if (existing_users.find(email) != existing_users.end() ||
579 !users_set->insert(email).second) {
580 LOG(ERROR) << "Duplicate user: " << email;
581 continue;
582 }
583 if (email == logged_in_user) {
584 logged_in_user_on_list = true;
585 continue;
586 }
587 users_vector->push_back(email);
588 }
589 users_set->erase(logged_in_user);
590 return logged_in_user_on_list;
591 }
592
593 void UserManagerImpl::EnsureUsersLoaded() const {
555 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 594 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
556 if (!users_.empty())
557 return;
558 if (!g_browser_process) 595 if (!g_browser_process)
559 return; 596 return;
560 597
598 if (users_loaded_)
599 return;
600 users_loaded_ = true;
601
561 PrefService* local_state = g_browser_process->local_state(); 602 PrefService* local_state = g_browser_process->local_state();
562 const ListValue* prefs_users = 603 const ListValue* prefs_regular_users = local_state->GetList(kRegularUsers);
563 local_state->GetList(kLoggedInUsers); 604 const ListValue* prefs_local_users = local_state->GetList(kLocalUsers);
564 const DictionaryValue* prefs_display_names = 605 const DictionaryValue* prefs_display_names =
565 local_state->GetDictionary(kUserDisplayName); 606 local_state->GetDictionary(kUserDisplayName);
566 const DictionaryValue* prefs_display_emails = 607 const DictionaryValue* prefs_display_emails =
567 local_state->GetDictionary(kUserDisplayEmail); 608 local_state->GetDictionary(kUserDisplayEmail);
568 609
569 if (!prefs_users) 610 // Load regular users.
570 return; 611 std::vector<std::string> regular_users;
612 std::set<std::string> regular_users_set;
613 ParseUserList(*prefs_regular_users, std::set<std::string>(), "",
614 &regular_users, &regular_users_set);
615 for (std::vector<std::string>::const_iterator it = regular_users.begin();
616 it != regular_users.end(); ++it) {
617 User* user = User::CreateRegularUser(*it);
618 user->set_oauth_token_status(LoadUserOAuthStatus(*it));
619 users_.push_back(user);
571 620
572 for (ListValue::const_iterator it = prefs_users->begin(); 621 string16 display_name;
573 it != prefs_users->end(); ++it) { 622 if (prefs_display_names->GetStringWithoutPathExpansion(*it,
574 std::string email; 623 &display_name)) {
575 if ((*it)->GetAsString(&email)) { 624 user->set_display_name(display_name);
576 User* user = User::CreateRegularUser(email); 625 }
577 user->set_oauth_token_status(LoadUserOAuthStatus(email));
578 users_.push_back(user);
579 626
580 string16 display_name; 627 std::string display_email;
581 if (prefs_display_names && 628 if (prefs_display_emails->GetStringWithoutPathExpansion(*it,
582 prefs_display_names->GetStringWithoutPathExpansion( 629 &display_email)) {
583 email, &display_name)) { 630 user->set_display_email(display_email);
584 user->set_display_name(display_name); 631 }
585 } 632 }
586 633
587 std::string display_email; 634 // Load device-local users.
588 if (prefs_display_emails && 635 std::vector<std::string> local_users;
589 prefs_display_emails->GetStringWithoutPathExpansion( 636 std::set<std::string> local_users_set;
590 email, &display_email)) { 637 ParseUserList(*prefs_local_users,regular_users_set, "",
591 user->set_display_email(display_email); 638 &local_users, &local_users_set);
592 } 639 for (std::vector<std::string>::const_iterator it = local_users.begin();
593 } 640 it != local_users.end(); ++it) {
641 // Currently, all device-local users are public account users. This may
642 // change in the future.
643 users_.push_back(User::CreatePublicAccountUser(*it));
Ivan Korotkov 2012/11/28 21:40:53 Maybe CreateGaiaAccountUser? Public sounds somewha
bartfab (slow) 2012/11/29 14:18:09 As discussed offline, public accounts are non-GAIA
594 } 644 }
595 645
596 user_image_manager_->LoadUserImages(users_); 646 user_image_manager_->LoadUserImages(users_);
597 } 647 }
598 648
599 void UserManagerImpl::RetrieveTrustedDevicePolicies() { 649 void UserManagerImpl::RetrieveTrustedDevicePolicies() {
600 ephemeral_users_enabled_ = false; 650 ephemeral_users_enabled_ = false;
601 owner_email_ = ""; 651 owner_email_ = "";
602 652
603 CrosSettings* cros_settings = CrosSettings::Get();
604 // Schedule a callback if device policy has not yet been verified. 653 // Schedule a callback if device policy has not yet been verified.
605 if (CrosSettingsProvider::TRUSTED != cros_settings->PrepareTrustedValues( 654 if (CrosSettingsProvider::TRUSTED != cros_settings_->PrepareTrustedValues(
606 base::Bind(&UserManagerImpl::RetrieveTrustedDevicePolicies, 655 base::Bind(&UserManagerImpl::RetrieveTrustedDevicePolicies,
607 base::Unretained(this)))) { 656 base::Unretained(this)))) {
608 return; 657 return;
609 } 658 }
610 659
611 cros_settings->GetBoolean(kAccountsPrefEphemeralUsersEnabled, 660 cros_settings_->GetBoolean(kAccountsPrefEphemeralUsersEnabled,
612 &ephemeral_users_enabled_); 661 &ephemeral_users_enabled_);
613 cros_settings->GetString(kDeviceOwner, &owner_email_); 662 cros_settings_->GetString(kDeviceOwner, &owner_email_);
663 const base::ListValue* local_users;
664 cros_settings_->GetList(kAccountsPrefDeviceLocalAccounts, &local_users);
665
666 EnsureUsersLoaded();
667
668 bool changed = UpdateLocalUsers(*local_users);
614 669
615 // If ephemeral users are enabled and we are on the login screen, take this 670 // If ephemeral users are enabled and we are on the login screen, take this
616 // opportunity to clean up by removing all users except the owner. 671 // opportunity to clean up by removing all users except the owner.
617 if (ephemeral_users_enabled_ && !IsUserLoggedIn()) { 672 if (ephemeral_users_enabled_ && !IsUserLoggedIn()) {
618 scoped_ptr<base::ListValue> users( 673 scoped_ptr<base::ListValue> users(
619 g_browser_process->local_state()->GetList(kLoggedInUsers)->DeepCopy()); 674 g_browser_process->local_state()->GetList(kRegularUsers)->DeepCopy());
620 675
621 bool changed = false;
622 for (base::ListValue::const_iterator user = users->begin(); 676 for (base::ListValue::const_iterator user = users->begin();
623 user != users->end(); ++user) { 677 user != users->end(); ++user) {
624 std::string user_email; 678 std::string user_email;
625 (*user)->GetAsString(&user_email); 679 (*user)->GetAsString(&user_email);
626 if (user_email != owner_email_) { 680 if (user_email != owner_email_) {
627 RemoveUserFromListInternal(user_email); 681 RemoveNonCryptohomeData(user_email);
682 delete RemoveUserFromListInternal(user_email);
628 changed = true; 683 changed = true;
629 } 684 }
630 } 685 }
686 }
631 687
632 if (changed) { 688 if (changed) {
633 content::NotificationService::current()->Notify( 689 content::NotificationService::current()->Notify(
634 chrome::NOTIFICATION_POLICY_USER_LIST_CHANGED, 690 chrome::NOTIFICATION_POLICY_USER_LIST_CHANGED,
635 content::Source<UserManager>(this), 691 content::Source<UserManager>(this),
636 content::NotificationService::NoDetails()); 692 content::NotificationService::NoDetails());
637 }
638 } 693 }
694
695 cros_settings_->AddSettingsObserver(kAccountsPrefDeviceLocalAccounts,
696 this);
639 } 697 }
640 698
641 bool UserManagerImpl::AreEphemeralUsersEnabled() const { 699 bool UserManagerImpl::AreEphemeralUsersEnabled() const {
642 return ephemeral_users_enabled_ && 700 return ephemeral_users_enabled_ &&
643 (g_browser_process->browser_policy_connector()->IsEnterpriseManaged() || 701 (g_browser_process->browser_policy_connector()->IsEnterpriseManaged() ||
644 !owner_email_.empty()); 702 !owner_email_.empty());
645 } 703 }
646 704
647 const User* UserManagerImpl::FindUserInList(const std::string& email) const { 705 const User* UserManagerImpl::FindUserInList(const std::string& email) const {
648 const UserList& users = GetUsers(); 706 const UserList& users = GetUsers();
(...skipping 25 matching lines...) Expand all
674 732
675 SetCurrentUserIsOwner(is_owner); 733 SetCurrentUserIsOwner(is_owner);
676 } 734 }
677 735
678 void UserManagerImpl::CheckOwnership() { 736 void UserManagerImpl::CheckOwnership() {
679 DeviceSettingsService::Get()->GetOwnershipStatusAsync( 737 DeviceSettingsService::Get()->GetOwnershipStatusAsync(
680 base::Bind(&UserManagerImpl::UpdateOwnership, 738 base::Bind(&UserManagerImpl::UpdateOwnership,
681 base::Unretained(this))); 739 base::Unretained(this)));
682 } 740 }
683 741
684 void UserManagerImpl::RemoveUserFromListInternal(const std::string& email) { 742 void UserManagerImpl::RemoveNonCryptohomeData(const std::string& email) {
685 // Clear the prefs view of the users. 743 WallpaperManager::Get()->RemoveUserWallpaperInfo(email);
744 user_image_manager_->DeleteUserImage(email);
745
686 PrefService* prefs = g_browser_process->local_state(); 746 PrefService* prefs = g_browser_process->local_state();
687 ListPrefUpdate prefs_users_update(prefs, kLoggedInUsers);
688 prefs_users_update->Clear();
689
690 UserList::iterator user_to_remove = users_.end();
691 for (UserList::iterator it = users_.begin(); it != users_.end(); ++it) {
692 std::string user_email = (*it)->email();
693 // Skip user that we would like to delete.
694 if (email != user_email)
695 prefs_users_update->Append(new base::StringValue(user_email));
696 else
697 user_to_remove = it;
698 }
699
700 WallpaperManager::Get()->RemoveUserWallpaperInfo(email);
701
702 DictionaryPrefUpdate prefs_oauth_update(prefs, kUserOAuthTokenStatus); 747 DictionaryPrefUpdate prefs_oauth_update(prefs, kUserOAuthTokenStatus);
703 int oauth_status; 748 int oauth_status;
704 prefs_oauth_update->GetIntegerWithoutPathExpansion(email, &oauth_status); 749 prefs_oauth_update->GetIntegerWithoutPathExpansion(email, &oauth_status);
705 prefs_oauth_update->RemoveWithoutPathExpansion(email, NULL); 750 prefs_oauth_update->RemoveWithoutPathExpansion(email, NULL);
706 751
707 DictionaryPrefUpdate prefs_display_name_update(prefs, kUserDisplayName); 752 DictionaryPrefUpdate prefs_display_name_update(prefs, kUserDisplayName);
708 prefs_display_name_update->RemoveWithoutPathExpansion(email, NULL); 753 prefs_display_name_update->RemoveWithoutPathExpansion(email, NULL);
709 754
710 DictionaryPrefUpdate prefs_display_email_update(prefs, kUserDisplayEmail); 755 DictionaryPrefUpdate prefs_display_email_update(prefs, kUserDisplayEmail);
711 prefs_display_email_update->RemoveWithoutPathExpansion(email, NULL); 756 prefs_display_email_update->RemoveWithoutPathExpansion(email, NULL);
757 }
712 758
713 if (user_to_remove != users_.end()) { 759 User *UserManagerImpl::RemoveUserFromListInternal(const std::string& email) {
Ivan Korotkov 2012/11/28 21:40:53 This looks like it really is RemoveRegularUser...?
bartfab (slow) 2012/11/29 14:18:09 Done. Though note that the method will handle othe
714 delete *user_to_remove; 760 ListPrefUpdate prefs_users_update(g_browser_process->local_state(),
715 users_.erase(user_to_remove); 761 kRegularUsers);
762 prefs_users_update->Clear();
763 User* user = NULL;
764 for (UserList::iterator it = users_.begin(); it != users_.end(); ) {
765 const std::string user_email = (*it)->email();
766 if (user_email == email) {
767 user = *it;
768 it = users_.erase(it);
769 } else {
770 if ((*it)->GetType() == User::USER_TYPE_REGULAR)
771 prefs_users_update->Append(new base::StringValue(user_email));
772 ++it;
773 }
716 } 774 }
775 return user;
776 }
777
778 bool UserManagerImpl::UpdateLocalUsers(
779 const base::ListValue& local_users_list) {
780 PrefService* local_state = g_browser_process->local_state();
781
782 // Determine the currently logged-in user's email.
783 std::string logged_in_user;
Nikita (slow) 2012/11/29 16:42:50 Please rename to logged_in_user_email so that you
bartfab (slow) 2012/11/29 18:56:17 Done.
784 if (IsUserLoggedIn())
785 logged_in_user = GetLoggedInUser()->email();
786
787 // If there is a user whose data is pending removal and that user is not
788 // currently logged in, take this opportunity to remove the data.
789 std::string user_pending_data_removal =
790 local_state->GetString(kUserPendingDataRemoval);
791 if (!user_pending_data_removal.empty() &&
792 user_pending_data_removal != logged_in_user) {
793 RemoveNonCryptohomeData(user_pending_data_removal);
794 local_state->ClearPref(kUserPendingDataRemoval);
795 }
796
797 // Split the current user list into device-local users and regular users.
798 std::vector<std::string> old_local_users;
799 std::set<std::string> regular_users;
800 for (UserList::const_iterator it = users_.begin(); it != users_.end(); ++it) {
801 if ((*it)->is_device_local_account())
802 old_local_users.push_back((*it)->email());
803 else
804 regular_users.insert((*it)->email());
805 }
806
807 // Get the new list of device-local users from policy.
808 std::vector<std::string> new_local_users;
809 std::set<std::string> new_local_users_set;
810 std::string pending_remove;
811 if (!ParseUserList(local_users_list, regular_users, logged_in_user,
812 &new_local_users, &new_local_users_set) &&
813 IsUserLoggedIn()) {
814 User* user = GetLoggedInUser();
815 // If the currently logged-in user is a device-local user not found on the
816 // new list, mark that user's data as pending removal after logout.
817 if (user->is_device_local_account() && !user->is_builtin_account())
818 local_state->SetString(kUserPendingDataRemoval, logged_in_user);
819 }
820
821 // Persist the new list of device-local users in a pref.
822 ListPrefUpdate prefs_local_users_update(local_state, kLocalUsers);
823 scoped_ptr<base::ListValue> prefs_local_users(local_users_list.DeepCopy());
824 prefs_local_users_update->Swap(prefs_local_users.get());
825
826 // If the list of device-local users has not changed, return.
827 if (new_local_users.size() == old_local_users.size()) {
828 bool changed = false;
829 for (size_t i = 0; i < new_local_users.size(); ++i) {
830 if (new_local_users[i] != old_local_users[i]) {
831 changed = true;
832 break;
833 }
834 }
835 if (!changed)
836 return false;
837 }
838
839 // Remove the old device-local users from the user list.
840 for (UserList::iterator it = users_.begin(); it != users_.end(); ) {
841 if ((*it)->is_device_local_account()) {
842 delete *it;
843 it = users_.erase(it);
844 } else {
845 ++it;
846 }
847 }
848
849 // Add the new device-local users to the user list.
850 for (std::vector<std::string>::const_iterator it = new_local_users.begin();
851 it != new_local_users.end(); ++it) {
852 // Currently, all device-local users are public account users. This may
853 // change in the future.
854 users_.push_back(User::CreatePublicAccountUser(*it));
855 }
856
857 user_image_manager_->LoadUserImages(
858 UserList(users_.end() - new_local_users.size(), users_.end()));
859
860 return true;
717 } 861 }
718 862
719 } // namespace chromeos 863 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698