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

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

Issue 16278003: Made possible to lock and unlock with several logged in users. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 7 years, 6 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) 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/screen_locker.h" 5 #include "chrome/browser/chromeos/login/screen_locker.h"
6 6
7 #include <string> 7 #include <string>
8 #include <vector> 8 #include <vector>
9 9
10 #include "ash/ash_switches.h" 10 #include "ash/ash_switches.h"
11 #include "ash/desktop_background/desktop_background_controller.h" 11 #include "ash/desktop_background/desktop_background_controller.h"
12 #include "ash/shell.h" 12 #include "ash/shell.h"
13 #include "ash/wm/session_state_controller.h" 13 #include "ash/wm/session_state_controller.h"
14 #include "base/bind.h" 14 #include "base/bind.h"
15 #include "base/command_line.h" 15 #include "base/command_line.h"
16 #include "base/lazy_instance.h" 16 #include "base/lazy_instance.h"
17 #include "base/memory/weak_ptr.h" 17 #include "base/memory/weak_ptr.h"
18 #include "base/message_loop.h" 18 #include "base/message_loop.h"
19 #include "base/metrics/histogram.h" 19 #include "base/metrics/histogram.h"
20 #include "base/string_util.h" 20 #include "base/string_util.h"
21 #include "base/timer.h" 21 #include "base/timer.h"
22 #include "base/utf_string_conversions.h"
23 #include "chrome/browser/chromeos/login/authenticator.h" 22 #include "chrome/browser/chromeos/login/authenticator.h"
24 #include "chrome/browser/chromeos/login/login_performer.h" 23 #include "chrome/browser/chromeos/login/login_performer.h"
25 #include "chrome/browser/chromeos/login/login_utils.h" 24 #include "chrome/browser/chromeos/login/login_utils.h"
26 #include "chrome/browser/chromeos/login/user_adding_screen.h" 25 #include "chrome/browser/chromeos/login/user_adding_screen.h"
27 #include "chrome/browser/chromeos/login/user_manager.h" 26 #include "chrome/browser/chromeos/login/user_manager.h"
28 #include "chrome/browser/chromeos/login/webui_screen_locker.h" 27 #include "chrome/browser/chromeos/login/webui_screen_locker.h"
29 #include "chrome/browser/lifetime/application_lifetime.h" 28 #include "chrome/browser/lifetime/application_lifetime.h"
30 #include "chrome/browser/profiles/profile.h" 29 #include "chrome/browser/profiles/profile.h"
31 #include "chrome/browser/profiles/profile_manager.h" 30 #include "chrome/browser/profiles/profile_manager.h"
32 #include "chrome/browser/signin/signin_manager.h" 31 #include "chrome/browser/signin/signin_manager.h"
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 } // namespace 144 } // namespace
146 145
147 namespace chromeos { 146 namespace chromeos {
148 147
149 // static 148 // static
150 ScreenLocker* ScreenLocker::screen_locker_ = NULL; 149 ScreenLocker* ScreenLocker::screen_locker_ = NULL;
151 150
152 ////////////////////////////////////////////////////////////////////////////// 151 //////////////////////////////////////////////////////////////////////////////
153 // ScreenLocker, public: 152 // ScreenLocker, public:
154 153
155 ScreenLocker::ScreenLocker(const User& user) 154 ScreenLocker::ScreenLocker(const UserList& users)
156 : user_(user), 155 : users_(users),
157 // TODO(oshima): support auto login mode (this is not implemented yet)
158 // http://crosbug.com/1881
159 unlock_on_input_(user_.email().empty()),
160 locked_(false), 156 locked_(false),
161 start_time_(base::Time::Now()), 157 start_time_(base::Time::Now()),
162 login_status_consumer_(NULL), 158 login_status_consumer_(NULL),
163 incorrect_passwords_count_(0), 159 incorrect_passwords_count_(0),
164 weak_factory_(this) { 160 weak_factory_(this) {
165 DCHECK(!screen_locker_); 161 DCHECK(!screen_locker_);
166 screen_locker_ = this; 162 screen_locker_ = this;
167 } 163 }
168 164
169 void ScreenLocker::Init() { 165 void ScreenLocker::Init() {
170 authenticator_ = LoginUtils::Get()->CreateAuthenticator(this); 166 authenticator_ = LoginUtils::Get()->CreateAuthenticator(this);
171 delegate_.reset(new WebUIScreenLocker(this)); 167 delegate_.reset(new WebUIScreenLocker(this));
172 delegate_->LockScreen(unlock_on_input_); 168 delegate_->LockScreen();
173 } 169 }
174 170
175 void ScreenLocker::OnLoginFailure(const LoginFailure& error) { 171 void ScreenLocker::OnLoginFailure(const LoginFailure& error) {
176 content::RecordAction(UserMetricsAction("ScreenLocker_OnLoginFailure")); 172 content::RecordAction(UserMetricsAction("ScreenLocker_OnLoginFailure"));
177 if (authentication_start_time_.is_null()) { 173 if (authentication_start_time_.is_null()) {
178 LOG(ERROR) << "Start time is not set at authentication failure"; 174 LOG(ERROR) << "Start time is not set at authentication failure";
179 } else { 175 } else {
180 base::TimeDelta delta = base::Time::Now() - authentication_start_time_; 176 base::TimeDelta delta = base::Time::Now() - authentication_start_time_;
181 VLOG(1) << "Authentication failure: " << delta.InSecondsF() << " second(s)"; 177 VLOG(1) << "Authentication failure: " << delta.InSecondsF() << " second(s)";
182 UMA_HISTOGRAM_TIMES("ScreenLocker.AuthenticationFailureTime", delta); 178 UMA_HISTOGRAM_TIMES("ScreenLocker.AuthenticationFailureTime", delta);
(...skipping 19 matching lines...) Expand all
202 incorrect_passwords_count_ = 0; 198 incorrect_passwords_count_ = 0;
203 if (authentication_start_time_.is_null()) { 199 if (authentication_start_time_.is_null()) {
204 if (!user_context.username.empty()) 200 if (!user_context.username.empty())
205 LOG(ERROR) << "Start time is not set at authentication success"; 201 LOG(ERROR) << "Start time is not set at authentication success";
206 } else { 202 } else {
207 base::TimeDelta delta = base::Time::Now() - authentication_start_time_; 203 base::TimeDelta delta = base::Time::Now() - authentication_start_time_;
208 VLOG(1) << "Authentication success: " << delta.InSecondsF() << " second(s)"; 204 VLOG(1) << "Authentication success: " << delta.InSecondsF() << " second(s)";
209 UMA_HISTOGRAM_TIMES("ScreenLocker.AuthenticationSuccessTime", delta); 205 UMA_HISTOGRAM_TIMES("ScreenLocker.AuthenticationSuccessTime", delta);
210 } 206 }
211 207
212 Profile* profile = ProfileManager::GetDefaultProfile(); 208 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kMultiProfiles)) {
213 if (profile && !user_context.password.empty()) { 209 // TODO(dzhioev): It seems like this branch never executed and should be
214 // We have a non-empty password, so notify listeners (such as the sync 210 // removed before multi-profile enabling.
215 // engine). 211 Profile* profile = ProfileManager::GetDefaultProfile();
216 SigninManagerBase* signin = SigninManagerFactory::GetForProfile(profile); 212 if (profile && !user_context.password.empty()) {
217 DCHECK(signin); 213 // We have a non-empty password, so notify listeners (such as the sync
218 GoogleServiceSigninSuccessDetails details( 214 // engine).
219 signin->GetAuthenticatedUsername(), 215 SigninManagerBase* signin = SigninManagerFactory::GetForProfile(profile);
220 user_context.password); 216 DCHECK(signin);
221 content::NotificationService::current()->Notify( 217 GoogleServiceSigninSuccessDetails details(
222 chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL, 218 signin->GetAuthenticatedUsername(),
223 content::Source<Profile>(profile), 219 user_context.password);
224 content::Details<const GoogleServiceSigninSuccessDetails>(&details)); 220 content::NotificationService::current()->Notify(
221 chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL,
222 content::Source<Profile>(profile),
223 content::Details<const GoogleServiceSigninSuccessDetails>(&details));
224 }
225 }
226
227 if (const User* user = UserManager::Get()->FindUser(user_context.username)) {
228 if (!user->is_active())
229 UserManager::Get()->SwitchActiveUser(user_context.username);
230 } else {
231 NOTREACHED() << "Logged in user not found.";
225 } 232 }
226 233
227 authentication_capture_.reset(new AuthenticationParametersCapture()); 234 authentication_capture_.reset(new AuthenticationParametersCapture());
228 authentication_capture_->username = user_context.username; 235 authentication_capture_->username = user_context.username;
229 authentication_capture_->pending_requests = pending_requests; 236 authentication_capture_->pending_requests = pending_requests;
230 authentication_capture_->using_oauth = using_oauth; 237 authentication_capture_->using_oauth = using_oauth;
231 238
232 CommandLine* command_line = CommandLine::ForCurrentProcess(); 239 CommandLine* command_line = CommandLine::ForCurrentProcess();
233 if (command_line->HasSwitch(ash::switches::kAshDisableNewLockAnimations)) { 240 if (command_line->HasSwitch(ash::switches::kAshDisableNewLockAnimations)) {
234 UnlockOnLoginSuccess(); 241 UnlockOnLoginSuccess();
(...skipping 25 matching lines...) Expand all
260 UserContext(authentication_capture_->username, 267 UserContext(authentication_capture_->username,
261 std::string(), // password 268 std::string(), // password
262 std::string()), // auth_code 269 std::string()), // auth_code
263 authentication_capture_->pending_requests, 270 authentication_capture_->pending_requests,
264 authentication_capture_->using_oauth); 271 authentication_capture_->using_oauth);
265 } 272 }
266 authentication_capture_.reset(); 273 authentication_capture_.reset();
267 weak_factory_.InvalidateWeakPtrs(); 274 weak_factory_.InvalidateWeakPtrs();
268 } 275 }
269 276
270 void ScreenLocker::Authenticate(const string16& password) { 277 void ScreenLocker::Authenticate(const UserContext& user_context) {
278 LOG_ASSERT(IsUserLoggedIn(user_context.username))
279 << "Invalid user trying to unlock.";
271 authentication_start_time_ = base::Time::Now(); 280 authentication_start_time_ = base::Time::Now();
272 delegate_->SetInputEnabled(false); 281 delegate_->SetInputEnabled(false);
273 delegate_->OnAuthenticate(); 282 delegate_->OnAuthenticate();
274 283
275 // If LoginPerformer instance exists, 284 BrowserThread::PostTask(
276 // initial online login phase is still active. 285 BrowserThread::UI, FROM_HERE,
277 if (LoginPerformer::default_performer()) { 286 base::Bind(&Authenticator::AuthenticateToUnlock,
278 DVLOG(1) << "Delegating authentication to LoginPerformer."; 287 authenticator_.get(),
279 LoginPerformer::default_performer()->PerformLogin( 288 user_context));
280 UserContext(user_.email(), 289 }
281 UTF16ToUTF8(password), 290
282 std::string()), // auth_code 291 void ScreenLocker::AuthenticateByPassword(const std::string& password) {
283 LoginPerformer::AUTH_MODE_INTERNAL); 292 LOG_ASSERT(users_.size() == 1);
284 } else { 293 Authenticate(UserContext(users_[0]->email(), password, ""));
285 BrowserThread::PostTask(
286 BrowserThread::UI, FROM_HERE,
287 base::Bind(&Authenticator::AuthenticateToUnlock, authenticator_.get(),
288 UserContext(user_.email(),
289 UTF16ToUTF8(password),
290 std::string()))); // auth_code
291 }
292 } 294 }
293 295
294 void ScreenLocker::ClearErrors() { 296 void ScreenLocker::ClearErrors() {
295 delegate_->ClearErrors(); 297 delegate_->ClearErrors();
296 } 298 }
297 299
298 void ScreenLocker::EnableInput() { 300 void ScreenLocker::EnableInput() {
299 delegate_->SetInputEnabled(true); 301 delegate_->SetInputEnabled(true);
300 } 302 }
301 303
(...skipping 21 matching lines...) Expand all
323 } 325 }
324 326
325 // static 327 // static
326 void ScreenLocker::Show() { 328 void ScreenLocker::Show() {
327 content::RecordAction(UserMetricsAction("ScreenLocker_Show")); 329 content::RecordAction(UserMetricsAction("ScreenLocker_Show"));
328 DCHECK(base::MessageLoop::current()->type() == base::MessageLoop::TYPE_UI); 330 DCHECK(base::MessageLoop::current()->type() == base::MessageLoop::TYPE_UI);
329 331
330 // Check whether the currently logged in user is a guest account and if so, 332 // Check whether the currently logged in user is a guest account and if so,
331 // refuse to lock the screen (crosbug.com/23764). 333 // refuse to lock the screen (crosbug.com/23764).
332 // For a demo user, we should never show the lock screen (crosbug.com/27647). 334 // For a demo user, we should never show the lock screen (crosbug.com/27647).
333 // TODO(flackr): We can allow lock screen for guest accounts when
334 // unlock_on_input is supported by the WebUI screen locker.
335 if (UserManager::Get()->IsLoggedInAsGuest() || 335 if (UserManager::Get()->IsLoggedInAsGuest() ||
336 UserManager::Get()->IsLoggedInAsDemoUser()) { 336 UserManager::Get()->IsLoggedInAsDemoUser()) {
337 VLOG(1) << "Refusing to lock screen for guest/demo account"; 337 VLOG(1) << "Refusing to lock screen for guest/demo account";
338 return; 338 return;
339 } 339 }
340 340
341 // Exit fullscreen. 341 // Exit fullscreen.
342 Browser* browser = chrome::FindLastActiveWithHostDesktopType( 342 Browser* browser = chrome::FindLastActiveWithHostDesktopType(
343 chrome::HOST_DESKTOP_TYPE_ASH); 343 chrome::HOST_DESKTOP_TYPE_ASH);
344 // browser can be NULL if we receive a lock request before the first browser 344 // browser can be NULL if we receive a lock request before the first browser
345 // window is shown. 345 // window is shown.
346 if (browser && browser->window()->IsFullscreen()) { 346 if (browser && browser->window()->IsFullscreen()) {
347 chrome::ToggleFullscreenMode(browser); 347 chrome::ToggleFullscreenMode(browser);
348 } 348 }
349 349
350 if (!screen_locker_) { 350 if (!screen_locker_) {
351 ScreenLocker* locker = 351 ScreenLocker* locker =
352 new ScreenLocker(*UserManager::Get()->GetLoggedInUser()); 352 new ScreenLocker(UserManager::Get()->GetLRULoggedInUsers());
353 VLOG(1) << "Created ScreenLocker " << locker; 353 VLOG(1) << "Created ScreenLocker " << locker;
354 locker->Init(); 354 locker->Init();
355 } else { 355 } else {
356 VLOG(1) << "ScreenLocker " << screen_locker_ << " already exists; " 356 VLOG(1) << "ScreenLocker " << screen_locker_ << " already exists; "
357 << " calling session manager's HandleLockScreenShown D-Bus method"; 357 << " calling session manager's HandleLockScreenShown D-Bus method";
358 DBusThreadManager::Get()->GetSessionManagerClient()-> 358 DBusThreadManager::Get()->GetSessionManagerClient()->
359 NotifyLockScreenShown(); 359 NotifyLockScreenShown();
360 } 360 }
361 } 361 }
362 362
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
441 content::Source<ScreenLocker>(this), 441 content::Source<ScreenLocker>(this),
442 content::Details<bool>(&state)); 442 content::Details<bool>(&state));
443 VLOG(1) << "Calling session manager's HandleLockScreenShown D-Bus method"; 443 VLOG(1) << "Calling session manager's HandleLockScreenShown D-Bus method";
444 DBusThreadManager::Get()->GetSessionManagerClient()->NotifyLockScreenShown(); 444 DBusThreadManager::Get()->GetSessionManagerClient()->NotifyLockScreenShown();
445 } 445 }
446 446
447 content::WebUI* ScreenLocker::GetAssociatedWebUI() { 447 content::WebUI* ScreenLocker::GetAssociatedWebUI() {
448 return delegate_->GetAssociatedWebUI(); 448 return delegate_->GetAssociatedWebUI();
449 } 449 }
450 450
451 bool ScreenLocker::IsUserLoggedIn(const std::string& username) {
452 for (UserList::const_iterator it = users_.begin(); it != users_.end(); ++it) {
453 if ((*it)->email() == username)
454 return true;
455 }
456 return false;
457 }
458
451 } // namespace chromeos 459 } // namespace chromeos
460
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/login/screen_locker.h ('k') | chrome/browser/chromeos/login/screen_locker_delegate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698