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

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

Issue 11411314: Add public accounts to UserManager (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressed reasons for the original revert. 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 #include <set>
9 #include <vector>
10
7 #include "ash/shell.h" 11 #include "ash/shell.h"
8 #include "base/bind.h" 12 #include "base/bind.h"
9 #include "base/chromeos/chromeos_version.h" 13 #include "base/chromeos/chromeos_version.h"
10 #include "base/command_line.h" 14 #include "base/command_line.h"
11 #include "base/compiler_specific.h" 15 #include "base/compiler_specific.h"
12 #include "base/file_path.h" 16 #include "base/file_path.h"
13 #include "base/file_util.h" 17 #include "base/file_util.h"
14 #include "base/logging.h" 18 #include "base/logging.h"
15 #include "base/rand_util.h" 19 #include "base/rand_util.h"
16 #include "base/utf_string_conversions.h" 20 #include "base/utf_string_conversions.h"
17 #include "base/values.h" 21 #include "base/values.h"
18 #include "chrome/browser/browser_process.h" 22 #include "chrome/browser/browser_process.h"
19 #include "chrome/browser/chromeos/cros/cert_library.h" 23 #include "chrome/browser/chromeos/cros/cert_library.h"
20 #include "chrome/browser/chromeos/cros/cros_library.h" 24 #include "chrome/browser/chromeos/cros/cros_library.h"
21 #include "chrome/browser/chromeos/input_method/input_method_manager.h" 25 #include "chrome/browser/chromeos/input_method/input_method_manager.h"
22 #include "chrome/browser/chromeos/login/login_display.h" 26 #include "chrome/browser/chromeos/login/login_display.h"
23 #include "chrome/browser/chromeos/login/remove_user_delegate.h" 27 #include "chrome/browser/chromeos/login/remove_user_delegate.h"
24 #include "chrome/browser/chromeos/login/user_image_manager_impl.h" 28 #include "chrome/browser/chromeos/login/user_image_manager_impl.h"
25 #include "chrome/browser/chromeos/login/wizard_controller.h" 29 #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" 30 #include "chrome/browser/policy/browser_policy_connector.h"
28 #include "chrome/browser/prefs/pref_service.h" 31 #include "chrome/browser/prefs/pref_service.h"
29 #include "chrome/browser/prefs/scoped_user_pref_update.h" 32 #include "chrome/browser/prefs/scoped_user_pref_update.h"
30 #include "chrome/browser/profiles/profile_manager.h" 33 #include "chrome/browser/profiles/profile_manager.h"
31 #include "chrome/browser/sync/profile_sync_service.h" 34 #include "chrome/browser/sync/profile_sync_service.h"
32 #include "chrome/browser/sync/profile_sync_service_factory.h" 35 #include "chrome/browser/sync/profile_sync_service_factory.h"
33 #include "chrome/common/chrome_notification_types.h" 36 #include "chrome/common/chrome_notification_types.h"
34 #include "chrome/common/chrome_switches.h" 37 #include "chrome/common/chrome_switches.h"
35 #include "chrome/common/pref_names.h" 38 #include "chrome/common/pref_names.h"
36 #include "chromeos/cryptohome/async_method_caller.h" 39 #include "chromeos/cryptohome/async_method_caller.h"
37 #include "content/public/browser/browser_thread.h" 40 #include "content/public/browser/browser_thread.h"
38 #include "content/public/browser/notification_service.h" 41 #include "content/public/browser/notification_service.h"
39 #include "google_apis/gaia/google_service_auth_error.h" 42 #include "google_apis/gaia/google_service_auth_error.h"
40 43
41 using content::BrowserThread; 44 using content::BrowserThread;
42 45
43 namespace chromeos { 46 namespace chromeos {
44 47
45 namespace { 48 namespace {
46 49
47 // A vector pref of the users who have logged into the device. 50 // A vector pref of the the regular users known on this device, arranged in LRU
48 const char kLoggedInUsers[] = "LoggedInUsers"; 51 // order.
52 const char kRegularUsers[] = "LoggedInUsers";
53
54 // A vector pref of the public accounts defined on this device.
55 const char kPublicAccounts[] = "PublicAccounts";
56
57 // A string pref that gets set when a public account is removed but a user is
58 // currently logged into that account, requiring the account's data to be
59 // removed after logout.
60 const char kPublicAccountPendingDataRemoval[] =
61 "PublicAccountPendingDataRemoval";
49 62
50 // A dictionary that maps usernames to the displayed name. 63 // A dictionary that maps usernames to the displayed name.
51 const char kUserDisplayName[] = "UserDisplayName"; 64 const char kUserDisplayName[] = "UserDisplayName";
52 65
53 // A dictionary that maps usernames to the displayed (non-canonical) emails. 66 // A dictionary that maps usernames to the displayed (non-canonical) emails.
54 const char kUserDisplayEmail[] = "UserDisplayEmail"; 67 const char kUserDisplayEmail[] = "UserDisplayEmail";
55 68
56 // A dictionary that maps usernames to OAuth token presence flag. 69 // A dictionary that maps usernames to OAuth token presence flag.
57 const char kUserOAuthTokenStatus[] = "OAuthTokenStatus"; 70 const char kUserOAuthTokenStatus[] = "OAuthTokenStatus";
58 71
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 delegate->OnBeforeUserRemoved(user_email); 103 delegate->OnBeforeUserRemoved(user_email);
91 104
92 chromeos::UserManager::Get()->RemoveUserFromList(user_email); 105 chromeos::UserManager::Get()->RemoveUserFromList(user_email);
93 cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove( 106 cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove(
94 user_email, base::Bind(&OnRemoveUserComplete, user_email)); 107 user_email, base::Bind(&OnRemoveUserComplete, user_email));
95 108
96 if (delegate) 109 if (delegate)
97 delegate->OnUserRemoved(user_email); 110 delegate->OnUserRemoved(user_email);
98 } 111 }
99 112
113 // Helper function that copies users from |users_list| to |users_vector| and
114 // |users_set|. Duplicates and users already present in |existing_users| are
115 // skipped. The |logged_in_user| is also skipped and the return value
116 // indicates whether that user was found in |users_list|.
117 bool ParseUserList(const ListValue& users_list,
118 const std::set<std::string>& existing_users,
119 const std::string& logged_in_user,
120 std::vector<std::string>* users_vector,
121 std::set<std::string>* users_set) {
122 users_vector->clear();
123 users_set->clear();
124 bool logged_in_user_on_list = false;
125 for (size_t i = 0; i < users_list.GetSize(); ++i) {
126 std::string email;
127 if (!users_list.GetString(i, &email) || email.empty()) {
128 LOG(ERROR) << "Corrupt entry in user list at index " << i << ".";
129 continue;
130 }
131 if (existing_users.find(email) != existing_users.end() ||
132 !users_set->insert(email).second) {
133 LOG(ERROR) << "Duplicate user: " << email;
134 continue;
135 }
136 if (email == logged_in_user) {
137 logged_in_user_on_list = true;
138 continue;
139 }
140 users_vector->push_back(email);
141 }
142 users_set->erase(logged_in_user);
143 return logged_in_user_on_list;
144 }
145
100 } // namespace 146 } // namespace
101 147
102 // static 148 // static
103 void UserManager::RegisterPrefs(PrefService* local_state) { 149 void UserManager::RegisterPrefs(PrefService* local_state) {
104 local_state->RegisterListPref(kLoggedInUsers, PrefService::UNSYNCABLE_PREF); 150 local_state->RegisterListPref(kRegularUsers, PrefService::UNSYNCABLE_PREF);
151 local_state->RegisterListPref(kPublicAccounts, PrefService::UNSYNCABLE_PREF);
152 local_state->RegisterStringPref(kPublicAccountPendingDataRemoval, "",
153 PrefService::UNSYNCABLE_PREF);
105 local_state->RegisterDictionaryPref(kUserOAuthTokenStatus, 154 local_state->RegisterDictionaryPref(kUserOAuthTokenStatus,
106 PrefService::UNSYNCABLE_PREF); 155 PrefService::UNSYNCABLE_PREF);
107 local_state->RegisterDictionaryPref(kUserDisplayName, 156 local_state->RegisterDictionaryPref(kUserDisplayName,
108 PrefService::UNSYNCABLE_PREF); 157 PrefService::UNSYNCABLE_PREF);
109 local_state->RegisterDictionaryPref(kUserDisplayEmail, 158 local_state->RegisterDictionaryPref(kUserDisplayEmail,
110 PrefService::UNSYNCABLE_PREF); 159 PrefService::UNSYNCABLE_PREF);
111 } 160 }
112 161
113 UserManagerImpl::UserManagerImpl() 162 UserManagerImpl::UserManagerImpl()
114 : logged_in_user_(NULL), 163 : cros_settings_(CrosSettings::Get()),
164 users_loaded_(false),
165 logged_in_user_(NULL),
115 session_started_(false), 166 session_started_(false),
116 is_current_user_owner_(false), 167 is_current_user_owner_(false),
117 is_current_user_new_(false), 168 is_current_user_new_(false),
118 is_current_user_ephemeral_(false), 169 is_current_user_ephemeral_(false),
119 ephemeral_users_enabled_(false), 170 ephemeral_users_enabled_(false),
120 observed_sync_service_(NULL), 171 observed_sync_service_(NULL),
121 user_image_manager_(new UserImageManagerImpl) { 172 user_image_manager_(new UserImageManagerImpl) {
122 // UserManager instance should be used only on UI thread. 173 // UserManager instance should be used only on UI thread.
123 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 174 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
124 registrar_.Add(this, chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED, 175 registrar_.Add(this, chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED,
125 content::NotificationService::AllSources()); 176 content::NotificationService::AllSources());
126 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_ADDED, 177 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_ADDED,
127 content::NotificationService::AllSources()); 178 content::NotificationService::AllSources());
128 RetrieveTrustedDevicePolicies(); 179 RetrieveTrustedDevicePolicies();
129 } 180 }
130 181
131 UserManagerImpl::~UserManagerImpl() { 182 UserManagerImpl::~UserManagerImpl() {
132 // Can't use STLDeleteElements because of the private destructor of User. 183 // Can't use STLDeleteElements because of the private destructor of User.
133 for (size_t i = 0; i < users_.size(); ++i) 184 for (UserList::iterator it = users_.begin(); it != users_.end();
134 delete users_[i]; 185 it = users_.erase(it)) {
135 users_.clear(); 186 if (logged_in_user_ == *it)
136 if (is_current_user_ephemeral_) 187 logged_in_user_ = NULL;
bartfab (slow) 2012/12/03 10:39:21 This makes things more robust: The |logged_in_user
Ivan Korotkov 2012/12/03 11:04:45 Hmm, so it looks like now |logged_in_user| can poi
bartfab (slow) 2012/12/03 11:34:12 The description in user_manager_impl.h is still ac
137 delete logged_in_user_; 188 delete *it;
189 }
190 delete logged_in_user_;
191 }
192
193 void UserManagerImpl::Shutdown() {
194 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
195 cros_settings_->RemoveSettingsObserver(kAccountsPrefDeviceLocalAccounts,
196 this);
138 } 197 }
139 198
140 UserImageManager* UserManagerImpl::GetUserImageManager() { 199 UserImageManager* UserManagerImpl::GetUserImageManager() {
141 return user_image_manager_.get(); 200 return user_image_manager_.get();
142 } 201 }
143 202
144 const UserList& UserManagerImpl::GetUsers() const { 203 const UserList& UserManagerImpl::GetUsers() const {
145 const_cast<UserManagerImpl*>(this)->EnsureUsersLoaded(); 204 const_cast<UserManagerImpl*>(this)->EnsureUsersLoaded();
146 return users_; 205 return users_;
147 } 206 }
(...skipping 13 matching lines...) Expand all
161 return; 220 return;
162 } 221 }
163 222
164 if (IsEphemeralUser(email)) { 223 if (IsEphemeralUser(email)) {
165 EphemeralUserLoggedIn(email); 224 EphemeralUserLoggedIn(email);
166 return; 225 return;
167 } 226 }
168 227
169 EnsureUsersLoaded(); 228 EnsureUsersLoaded();
170 229
171 // Clear the prefs view of the users. 230 // Remove the user from the user list.
172 PrefService* prefs = g_browser_process->local_state(); 231 logged_in_user_ = RemoveRegularUserFromList(email);
bartfab (slow) 2012/12/03 10:39:21 This caused a memory leak because my reading of th
173 ListPrefUpdate prefs_users_update(prefs, kLoggedInUsers);
174 prefs_users_update->Clear();
175 232
176 // Make sure this user is first. 233 // If the user was not found on the user list, create a new user.
177 prefs_users_update->Append(new base::StringValue(email)); 234 if (!logged_in_user_) {
178 UserList::iterator logged_in_user = users_.end();
179 for (UserList::iterator it = users_.begin(); it != users_.end(); ++it) {
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
188 if (logged_in_user == users_.end()) {
189 is_current_user_new_ = true; 235 is_current_user_new_ = true;
190 logged_in_user_ = User::CreateRegularUser(email); 236 logged_in_user_ = User::CreateRegularUser(email);
191 logged_in_user_->set_oauth_token_status(LoadUserOAuthStatus(email)); 237 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(), 238 SaveUserDisplayName(logged_in_user_->email(),
201 UTF8ToUTF16(logged_in_user_->GetAccountName(true))); 239 UTF8ToUTF16(logged_in_user_->GetAccountName(true)));
202 WallpaperManager::Get()->SetInitialUserWallpaper(email, true); 240 WallpaperManager::Get()->SetInitialUserWallpaper(email, true);
203 } 241 }
204 242
243 // Add the user to the front of the user list.
244 ListPrefUpdate prefs_users_update(g_browser_process->local_state(),
245 kRegularUsers);
246 prefs_users_update->Insert(0, new base::StringValue(email));
247 users_.insert(users_.begin(), logged_in_user_);
248
205 user_image_manager_->UserLoggedIn(email, is_current_user_new_); 249 user_image_manager_->UserLoggedIn(email, is_current_user_new_);
206 250
207 if (!browser_restart) { 251 if (!browser_restart) {
208 // For GAIA login flow, logged in user wallpaper may not be loaded. 252 // For GAIA login flow, logged in user wallpaper may not be loaded.
209 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded(); 253 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
210 } 254 }
211 255
212 // Make sure we persist new user data to Local State. 256 // Make sure that new data is persisted to Local State.
213 prefs->CommitPendingWrite(); 257 g_browser_process->local_state()->CommitPendingWrite();
214 258
215 NotifyOnLogin(); 259 NotifyOnLogin();
216 } 260 }
217 261
218 void UserManagerImpl::RetailModeUserLoggedIn() { 262 void UserManagerImpl::RetailModeUserLoggedIn() {
219 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 263 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
220 is_current_user_new_ = true; 264 is_current_user_new_ = true;
221 is_current_user_ephemeral_ = true; 265 is_current_user_ephemeral_ = true;
222 logged_in_user_ = User::CreateRetailModeUser(); 266 logged_in_user_ = User::CreateRetailModeUser();
223 user_image_manager_->UserLoggedIn(kRetailModeUserEMail, 267 user_image_manager_->UserLoggedIn(kRetailModeUserEMail,
(...skipping 22 matching lines...) Expand all
246 } 290 }
247 291
248 void UserManagerImpl::SessionStarted() { 292 void UserManagerImpl::SessionStarted() {
249 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 293 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
250 session_started_ = true; 294 session_started_ = true;
251 content::NotificationService::current()->Notify( 295 content::NotificationService::current()->Notify(
252 chrome::NOTIFICATION_SESSION_STARTED, 296 chrome::NOTIFICATION_SESSION_STARTED,
253 content::NotificationService::AllSources(), 297 content::NotificationService::AllSources(),
254 content::NotificationService::NoDetails()); 298 content::NotificationService::NoDetails());
255 if (is_current_user_new_) { 299 if (is_current_user_new_) {
256 // Make sure we persist new user data to Local State. 300 // Make sure that the new user's data is persisted to Local State.
257 g_browser_process->local_state()->CommitPendingWrite(); 301 g_browser_process->local_state()->CommitPendingWrite();
258 } 302 }
259 } 303 }
260 304
261 void UserManagerImpl::RemoveUser(const std::string& email, 305 void UserManagerImpl::RemoveUser(const std::string& email,
262 RemoveUserDelegate* delegate) { 306 RemoveUserDelegate* delegate) {
263 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 307 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
264 308
265 if (!IsKnownUser(email)) 309 const User* user = FindUser(email);
310 if (!user || user->GetType() != User::USER_TYPE_REGULAR)
266 return; 311 return;
267 312
268 // Sanity check: we must not remove single user. This check may seem 313 // 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 314 // 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 315 // 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 316 // due to non-instant nature of ownership assignment this later check may
272 // sometimes fail. See http://crosbug.com/12723 317 // sometimes fail. See http://crosbug.com/12723
273 if (users_.size() < 2) 318 if (users_.size() < 2)
274 return; 319 return;
275 320
276 // Sanity check: do not allow the logged-in user to remove himself. 321 // Sanity check: do not allow the logged-in user to remove himself.
277 if (logged_in_user_ && logged_in_user_->email() == email) 322 if (logged_in_user_ && logged_in_user_->email() == email)
278 return; 323 return;
279 324
280 RemoveUserInternal(email, delegate); 325 RemoveUserInternal(email, delegate);
281 } 326 }
282 327
283 void UserManagerImpl::RemoveUserFromList(const std::string& email) { 328 void UserManagerImpl::RemoveUserFromList(const std::string& email) {
284 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 329 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
285 EnsureUsersLoaded(); 330 EnsureUsersLoaded();
286 RemoveUserFromListInternal(email); 331 RemoveNonCryptohomeData(email);
332 delete RemoveRegularUserFromList(email);
333 // Make sure that new data is persisted to Local State.
334 g_browser_process->local_state()->CommitPendingWrite();
287 } 335 }
288 336
289 bool UserManagerImpl::IsKnownUser(const std::string& email) const { 337 bool UserManagerImpl::IsKnownUser(const std::string& email) const {
290 return FindUser(email) != NULL; 338 return FindUser(email) != NULL;
291 } 339 }
292 340
293 const User* UserManagerImpl::FindUser(const std::string& email) const { 341 const User* UserManagerImpl::FindUser(const std::string& email) const {
294 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 342 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
295 if (logged_in_user_ && logged_in_user_->email() == email) 343 if (logged_in_user_ && logged_in_user_->email() == email)
296 return logged_in_user_; 344 return logged_in_user_;
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 if (!profile->IsOffTheRecord() && 470 if (!profile->IsOffTheRecord() &&
423 profile == ProfileManager::GetDefaultProfile()) { 471 profile == ProfileManager::GetDefaultProfile()) {
424 DCHECK(NULL == observed_sync_service_); 472 DCHECK(NULL == observed_sync_service_);
425 observed_sync_service_ = 473 observed_sync_service_ =
426 ProfileSyncServiceFactory::GetForProfile(profile); 474 ProfileSyncServiceFactory::GetForProfile(profile);
427 if (observed_sync_service_) 475 if (observed_sync_service_)
428 observed_sync_service_->AddObserver(this); 476 observed_sync_service_->AddObserver(this);
429 } 477 }
430 } 478 }
431 break; 479 break;
480 case chrome::NOTIFICATION_SYSTEM_SETTING_CHANGED:
481 DCHECK_EQ(*content::Details<const std::string>(details).ptr(),
482 kAccountsPrefDeviceLocalAccounts);
483 RetrieveTrustedDevicePolicies();
484 break;
432 default: 485 default:
433 NOTREACHED(); 486 NOTREACHED();
434 } 487 }
435 } 488 }
436 489
437 void UserManagerImpl::OnStateChanged() { 490 void UserManagerImpl::OnStateChanged() {
438 DCHECK(IsUserLoggedIn() && !IsLoggedInAsGuest()); 491 DCHECK(IsLoggedInAsRegularUser());
439 GoogleServiceAuthError::State state = 492 GoogleServiceAuthError::State state =
440 observed_sync_service_->GetAuthError().state(); 493 observed_sync_service_->GetAuthError().state();
441 if (state != GoogleServiceAuthError::NONE && 494 if (state != GoogleServiceAuthError::NONE &&
442 state != GoogleServiceAuthError::CONNECTION_FAILED && 495 state != GoogleServiceAuthError::CONNECTION_FAILED &&
443 state != GoogleServiceAuthError::SERVICE_UNAVAILABLE && 496 state != GoogleServiceAuthError::SERVICE_UNAVAILABLE &&
444 state != GoogleServiceAuthError::REQUEST_CANCELED) { 497 state != GoogleServiceAuthError::REQUEST_CANCELED) {
445 // Invalidate OAuth token to force Gaia sign-in flow. This is needed 498 // Invalidate OAuth token to force Gaia sign-in flow. This is needed
446 // because sign-out/sign-in solution is suggested to the user. 499 // because sign-out/sign-in solution is suggested to the user.
447 // TODO(altimofeev): this code isn't needed after crosbug.com/25978 is 500 // TODO(altimofeev): this code isn't needed after crosbug.com/25978 is
448 // implemented. 501 // implemented.
(...skipping 28 matching lines...) Expand all
477 bool UserManagerImpl::CanCurrentUserLock() const { 530 bool UserManagerImpl::CanCurrentUserLock() const {
478 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 531 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
479 return IsUserLoggedIn() && logged_in_user_->can_lock(); 532 return IsUserLoggedIn() && logged_in_user_->can_lock();
480 } 533 }
481 534
482 bool UserManagerImpl::IsUserLoggedIn() const { 535 bool UserManagerImpl::IsUserLoggedIn() const {
483 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 536 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
484 return logged_in_user_; 537 return logged_in_user_;
485 } 538 }
486 539
540 bool UserManagerImpl::IsLoggedInAsRegularUser() const {
541 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
542 return IsUserLoggedIn() &&
543 logged_in_user_->GetType() == User::USER_TYPE_REGULAR;
544 }
545
487 bool UserManagerImpl::IsLoggedInAsDemoUser() const { 546 bool UserManagerImpl::IsLoggedInAsDemoUser() const {
488 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 547 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
489 return IsUserLoggedIn() && 548 return IsUserLoggedIn() &&
490 logged_in_user_->GetType() == User::USER_TYPE_RETAIL_MODE; 549 logged_in_user_->GetType() == User::USER_TYPE_RETAIL_MODE;
491 } 550 }
492 551
493 bool UserManagerImpl::IsLoggedInAsPublicAccount() const { 552 bool UserManagerImpl::IsLoggedInAsPublicAccount() const {
494 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 553 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
495 return IsUserLoggedIn() && 554 return IsUserLoggedIn() &&
496 logged_in_user_->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT; 555 logged_in_user_->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
546 } 605 }
547 606
548 void UserManagerImpl::NotifyLocalStateChanged() { 607 void UserManagerImpl::NotifyLocalStateChanged() {
549 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 608 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
550 FOR_EACH_OBSERVER(UserManager::Observer, observer_list_, 609 FOR_EACH_OBSERVER(UserManager::Observer, observer_list_,
551 LocalStateChanged(this)); 610 LocalStateChanged(this));
552 } 611 }
553 612
554 void UserManagerImpl::EnsureUsersLoaded() { 613 void UserManagerImpl::EnsureUsersLoaded() {
555 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 614 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
556 if (!users_.empty())
557 return;
558 if (!g_browser_process) 615 if (!g_browser_process)
559 return; 616 return;
560 617
618 if (users_loaded_)
619 return;
620 users_loaded_ = true;
621
561 PrefService* local_state = g_browser_process->local_state(); 622 PrefService* local_state = g_browser_process->local_state();
562 const ListValue* prefs_users = 623 const ListValue* prefs_regular_users = local_state->GetList(kRegularUsers);
563 local_state->GetList(kLoggedInUsers); 624 const ListValue* prefs_public_accounts =
625 local_state->GetList(kPublicAccounts);
564 const DictionaryValue* prefs_display_names = 626 const DictionaryValue* prefs_display_names =
565 local_state->GetDictionary(kUserDisplayName); 627 local_state->GetDictionary(kUserDisplayName);
566 const DictionaryValue* prefs_display_emails = 628 const DictionaryValue* prefs_display_emails =
567 local_state->GetDictionary(kUserDisplayEmail); 629 local_state->GetDictionary(kUserDisplayEmail);
568 630
569 if (!prefs_users) 631 // Load regular users.
570 return; 632 std::vector<std::string> regular_users;
633 std::set<std::string> regular_users_set;
634 ParseUserList(*prefs_regular_users, std::set<std::string>(), "",
635 &regular_users, &regular_users_set);
636 for (std::vector<std::string>::const_iterator it = regular_users.begin();
637 it != regular_users.end(); ++it) {
638 User* user = User::CreateRegularUser(*it);
639 user->set_oauth_token_status(LoadUserOAuthStatus(*it));
640 users_.push_back(user);
571 641
572 for (ListValue::const_iterator it = prefs_users->begin(); 642 string16 display_name;
573 it != prefs_users->end(); ++it) { 643 if (prefs_display_names->GetStringWithoutPathExpansion(*it,
574 std::string email; 644 &display_name)) {
575 if ((*it)->GetAsString(&email)) { 645 user->set_display_name(display_name);
576 User* user = User::CreateRegularUser(email); 646 }
577 user->set_oauth_token_status(LoadUserOAuthStatus(email));
578 users_.push_back(user);
579 647
580 string16 display_name; 648 std::string display_email;
581 if (prefs_display_names && 649 if (prefs_display_emails->GetStringWithoutPathExpansion(*it,
582 prefs_display_names->GetStringWithoutPathExpansion( 650 &display_email)) {
583 email, &display_name)) { 651 user->set_display_email(display_email);
584 user->set_display_name(display_name); 652 }
585 } 653 }
586 654
587 std::string display_email; 655 // Load public accounts.
588 if (prefs_display_emails && 656 std::vector<std::string> public_accounts;
589 prefs_display_emails->GetStringWithoutPathExpansion( 657 std::set<std::string> public_accounts_set;
590 email, &display_email)) { 658 ParseUserList(*prefs_public_accounts, regular_users_set, "",
591 user->set_display_email(display_email); 659 &public_accounts, &public_accounts_set);
592 } 660 for (std::vector<std::string>::const_iterator it = public_accounts.begin();
593 } 661 it != public_accounts.end(); ++it) {
662 users_.push_back(User::CreatePublicAccountUser(*it));
594 } 663 }
595 664
596 user_image_manager_->LoadUserImages(users_); 665 user_image_manager_->LoadUserImages(users_);
597 } 666 }
598 667
599 void UserManagerImpl::RetrieveTrustedDevicePolicies() { 668 void UserManagerImpl::RetrieveTrustedDevicePolicies() {
600 ephemeral_users_enabled_ = false; 669 ephemeral_users_enabled_ = false;
601 owner_email_ = ""; 670 owner_email_ = "";
602 671
603 CrosSettings* cros_settings = CrosSettings::Get();
604 // Schedule a callback if device policy has not yet been verified. 672 // Schedule a callback if device policy has not yet been verified.
605 if (CrosSettingsProvider::TRUSTED != cros_settings->PrepareTrustedValues( 673 if (CrosSettingsProvider::TRUSTED != cros_settings_->PrepareTrustedValues(
606 base::Bind(&UserManagerImpl::RetrieveTrustedDevicePolicies, 674 base::Bind(&UserManagerImpl::RetrieveTrustedDevicePolicies,
607 base::Unretained(this)))) { 675 base::Unretained(this)))) {
608 return; 676 return;
609 } 677 }
610 678
611 cros_settings->GetBoolean(kAccountsPrefEphemeralUsersEnabled, 679 cros_settings_->GetBoolean(kAccountsPrefEphemeralUsersEnabled,
612 &ephemeral_users_enabled_); 680 &ephemeral_users_enabled_);
613 cros_settings->GetString(kDeviceOwner, &owner_email_); 681 cros_settings_->GetString(kDeviceOwner, &owner_email_);
682 const base::ListValue* public_accounts;
683 cros_settings_->GetList(kAccountsPrefDeviceLocalAccounts, &public_accounts);
684
685 EnsureUsersLoaded();
686
687 bool changed = UpdateAndCleanUpPublicAccounts(*public_accounts);
614 688
615 // If ephemeral users are enabled and we are on the login screen, take this 689 // 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. 690 // opportunity to clean up by removing all regular users except the owner.
617 if (ephemeral_users_enabled_ && !IsUserLoggedIn()) { 691 if (ephemeral_users_enabled_ && !IsUserLoggedIn()) {
618 scoped_ptr<base::ListValue> users( 692 ListPrefUpdate prefs_users_update(g_browser_process->local_state(),
619 g_browser_process->local_state()->GetList(kLoggedInUsers)->DeepCopy()); 693 kRegularUsers);
620 694 prefs_users_update->Clear();
621 bool changed = false; 695 for (UserList::iterator it = users_.begin(); it != users_.end(); ) {
622 for (base::ListValue::const_iterator user = users->begin(); 696 const std::string user_email = (*it)->email();
623 user != users->end(); ++user) { 697 if ((*it)->GetType() == User::USER_TYPE_REGULAR &&
624 std::string user_email; 698 user_email != owner_email_) {
625 (*user)->GetAsString(&user_email); 699 RemoveNonCryptohomeData(user_email);
626 if (user_email != owner_email_) { 700 delete *it;
627 RemoveUserFromListInternal(user_email); 701 it = users_.erase(it);
628 changed = true; 702 changed = true;
703 } else {
704 prefs_users_update->Append(new base::StringValue(user_email));
705 ++it;
629 } 706 }
630 } 707 }
708 }
631 709
632 if (changed) { 710 if (changed) {
633 content::NotificationService::current()->Notify( 711 content::NotificationService::current()->Notify(
634 chrome::NOTIFICATION_POLICY_USER_LIST_CHANGED, 712 chrome::NOTIFICATION_POLICY_USER_LIST_CHANGED,
635 content::Source<UserManager>(this), 713 content::Source<UserManager>(this),
636 content::NotificationService::NoDetails()); 714 content::NotificationService::NoDetails());
637 }
638 } 715 }
716
717 cros_settings_->AddSettingsObserver(kAccountsPrefDeviceLocalAccounts,
718 this);
639 } 719 }
640 720
641 bool UserManagerImpl::AreEphemeralUsersEnabled() const { 721 bool UserManagerImpl::AreEphemeralUsersEnabled() const {
642 return ephemeral_users_enabled_ && 722 return ephemeral_users_enabled_ &&
643 (g_browser_process->browser_policy_connector()->IsEnterpriseManaged() || 723 (g_browser_process->browser_policy_connector()->IsEnterpriseManaged() ||
644 !owner_email_.empty()); 724 !owner_email_.empty());
645 } 725 }
646 726
647 const User* UserManagerImpl::FindUserInList(const std::string& email) const { 727 const User* UserManagerImpl::FindUserInList(const std::string& email) const {
648 const UserList& users = GetUsers(); 728 const UserList& users = GetUsers();
(...skipping 25 matching lines...) Expand all
674 754
675 SetCurrentUserIsOwner(is_owner); 755 SetCurrentUserIsOwner(is_owner);
676 } 756 }
677 757
678 void UserManagerImpl::CheckOwnership() { 758 void UserManagerImpl::CheckOwnership() {
679 DeviceSettingsService::Get()->GetOwnershipStatusAsync( 759 DeviceSettingsService::Get()->GetOwnershipStatusAsync(
680 base::Bind(&UserManagerImpl::UpdateOwnership, 760 base::Bind(&UserManagerImpl::UpdateOwnership,
681 base::Unretained(this))); 761 base::Unretained(this)));
682 } 762 }
683 763
684 void UserManagerImpl::RemoveUserFromListInternal(const std::string& email) { 764 void UserManagerImpl::RemoveNonCryptohomeData(const std::string& email) {
685 // Clear the prefs view of the users. 765 WallpaperManager::Get()->RemoveUserWallpaperInfo(email);
766 user_image_manager_->DeleteUserImage(email);
767
686 PrefService* prefs = g_browser_process->local_state(); 768 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); 769 DictionaryPrefUpdate prefs_oauth_update(prefs, kUserOAuthTokenStatus);
703 int oauth_status; 770 int oauth_status;
704 prefs_oauth_update->GetIntegerWithoutPathExpansion(email, &oauth_status); 771 prefs_oauth_update->GetIntegerWithoutPathExpansion(email, &oauth_status);
705 prefs_oauth_update->RemoveWithoutPathExpansion(email, NULL); 772 prefs_oauth_update->RemoveWithoutPathExpansion(email, NULL);
706 773
707 DictionaryPrefUpdate prefs_display_name_update(prefs, kUserDisplayName); 774 DictionaryPrefUpdate prefs_display_name_update(prefs, kUserDisplayName);
708 prefs_display_name_update->RemoveWithoutPathExpansion(email, NULL); 775 prefs_display_name_update->RemoveWithoutPathExpansion(email, NULL);
709 776
710 DictionaryPrefUpdate prefs_display_email_update(prefs, kUserDisplayEmail); 777 DictionaryPrefUpdate prefs_display_email_update(prefs, kUserDisplayEmail);
711 prefs_display_email_update->RemoveWithoutPathExpansion(email, NULL); 778 prefs_display_email_update->RemoveWithoutPathExpansion(email, NULL);
779 }
712 780
713 if (user_to_remove != users_.end()) { 781 User *UserManagerImpl::RemoveRegularUserFromList(const std::string& email) {
714 delete *user_to_remove; 782 ListPrefUpdate prefs_users_update(g_browser_process->local_state(),
715 users_.erase(user_to_remove); 783 kRegularUsers);
784 prefs_users_update->Clear();
785 User* user = NULL;
786 for (UserList::iterator it = users_.begin(); it != users_.end(); ) {
787 const std::string user_email = (*it)->email();
788 if (user_email == email) {
789 user = *it;
790 it = users_.erase(it);
791 } else {
792 if ((*it)->GetType() == User::USER_TYPE_REGULAR)
793 prefs_users_update->Append(new base::StringValue(user_email));
794 ++it;
795 }
716 } 796 }
797 return user;
798 }
799
800 bool UserManagerImpl::UpdateAndCleanUpPublicAccounts(
801 const base::ListValue& public_accounts) {
802 PrefService* local_state = g_browser_process->local_state();
803
804 // Determine the currently logged-in user's email.
805 std::string logged_in_user_email;
806 if (IsUserLoggedIn())
807 logged_in_user_email = GetLoggedInUser()->email();
808
809 // If there is a public account whose data is pending removal and the user is
810 // not currently logged in with that account, take this opportunity to remove
811 // the data.
812 std::string public_account_pending_data_removal =
813 local_state->GetString(kPublicAccountPendingDataRemoval);
814 if (!public_account_pending_data_removal.empty() &&
815 public_account_pending_data_removal != logged_in_user_email) {
816 RemoveNonCryptohomeData(public_account_pending_data_removal);
817 local_state->ClearPref(kPublicAccountPendingDataRemoval);
818 }
819
820 // Split the current user list public accounts and regular users.
821 std::vector<std::string> old_public_accounts;
822 std::set<std::string> regular_users;
823 for (UserList::const_iterator it = users_.begin(); it != users_.end(); ++it) {
824 if ((*it)->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT)
825 old_public_accounts.push_back((*it)->email());
826 else
827 regular_users.insert((*it)->email());
828 }
829
830 // Get the new list of public accounts from policy.
831 std::vector<std::string> new_public_accounts;
832 std::set<std::string> new_public_accounts_set;
833 if (!ParseUserList(public_accounts, regular_users, logged_in_user_email,
834 &new_public_accounts, &new_public_accounts_set) &&
835 IsUserLoggedIn()) {
836 User* user = GetLoggedInUser();
837 // If the user is currently logged into a public account that has been
838 // removed from the list, mark the account's data as pending removal after
839 // logout.
840 if (user->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT) {
841 local_state->SetString(kPublicAccountPendingDataRemoval,
842 logged_in_user_email);
843 }
844 }
845
846 // Persist the new list of public accounts in a pref.
847 ListPrefUpdate prefs_public_accounts_update(local_state, kPublicAccounts);
848 scoped_ptr<base::ListValue> prefs_public_accounts(public_accounts.DeepCopy());
849 prefs_public_accounts_update->Swap(prefs_public_accounts.get());
850
851 // If the list of public accounts has not changed, return.
852 if (new_public_accounts.size() == old_public_accounts.size()) {
853 bool changed = false;
854 for (size_t i = 0; i < new_public_accounts.size(); ++i) {
855 if (new_public_accounts[i] != old_public_accounts[i]) {
856 changed = true;
857 break;
858 }
859 }
860 if (!changed)
861 return false;
862 }
863
864 // Remove the old public accounts from the user list.
865 for (UserList::iterator it = users_.begin(); it != users_.end(); ) {
866 if ((*it)->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT) {
867 delete *it;
868 it = users_.erase(it);
869 } else {
870 ++it;
871 }
872 }
873
874 // Add the new public accounts to the front of the user list.
875 for (std::vector<std::string>::const_reverse_iterator
876 it = new_public_accounts.rbegin();
877 it != new_public_accounts.rend(); ++it) {
878 users_.insert(users_.begin(), User::CreatePublicAccountUser(*it));
879 }
880
881 user_image_manager_->LoadUserImages(
882 UserList(users_.begin(), users_.begin() + new_public_accounts.size()));
883
884 return true;
717 } 885 }
718 886
719 } // namespace chromeos 887 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698