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

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

Issue 2015413002: Enable the PIN keyboard on the lockscreen. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@lkgr
Patch Set: Created 4 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/lock/screen_locker.h" 5 #include "chrome/browser/chromeos/login/lock/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/audio/sounds.h" 11 #include "ash/audio/sounds.h"
12 #include "ash/desktop_background/desktop_background_controller.h" 12 #include "ash/desktop_background/desktop_background_controller.h"
13 #include "ash/shell.h" 13 #include "ash/shell.h"
14 #include "ash/wm/common/window_state.h" 14 #include "ash/wm/common/window_state.h"
15 #include "ash/wm/common/wm_event.h" 15 #include "ash/wm/common/wm_event.h"
16 #include "ash/wm/lock_state_controller.h" 16 #include "ash/wm/lock_state_controller.h"
17 #include "ash/wm/window_state_aura.h" 17 #include "ash/wm/window_state_aura.h"
18 #include "ash/wm/window_util.h" 18 #include "ash/wm/window_util.h"
19 #include "base/bind.h" 19 #include "base/bind.h"
20 #include "base/command_line.h" 20 #include "base/command_line.h"
21 #include "base/lazy_instance.h" 21 #include "base/lazy_instance.h"
22 #include "base/macros.h" 22 #include "base/macros.h"
23 #include "base/memory/weak_ptr.h" 23 #include "base/memory/weak_ptr.h"
24 #include "base/message_loop/message_loop.h" 24 #include "base/message_loop/message_loop.h"
25 #include "base/metrics/histogram.h" 25 #include "base/metrics/histogram.h"
26 #include "base/strings/string_number_conversions.h" 26 #include "base/strings/string_number_conversions.h"
27 #include "base/strings/string_util.h" 27 #include "base/strings/string_util.h"
28 #include "chrome/browser/chrome_notification_types.h" 28 #include "chrome/browser/chrome_notification_types.h"
29 #include "chrome/browser/chromeos/login/lock/webui_screen_locker.h" 29 #include "chrome/browser/chromeos/login/lock/webui_screen_locker.h"
30 #include "chrome/browser/chromeos/login/quick_unlock/pin_storage.h"
31 #include "chrome/browser/chromeos/login/quick_unlock/pin_storage_factory.h"
30 #include "chrome/browser/chromeos/login/session/user_session_manager.h" 32 #include "chrome/browser/chromeos/login/session/user_session_manager.h"
31 #include "chrome/browser/chromeos/login/supervised/supervised_user_authenticatio n.h" 33 #include "chrome/browser/chromeos/login/supervised/supervised_user_authenticatio n.h"
32 #include "chrome/browser/chromeos/login/ui/user_adding_screen.h" 34 #include "chrome/browser/chromeos/login/ui/user_adding_screen.h"
33 #include "chrome/browser/chromeos/login/users/chrome_user_manager.h" 35 #include "chrome/browser/chromeos/login/users/chrome_user_manager.h"
34 #include "chrome/browser/chromeos/login/users/supervised_user_manager.h" 36 #include "chrome/browser/chromeos/login/users/supervised_user_manager.h"
35 #include "chrome/browser/lifetime/application_lifetime.h" 37 #include "chrome/browser/lifetime/application_lifetime.h"
36 #include "chrome/browser/signin/easy_unlock_service.h" 38 #include "chrome/browser/signin/easy_unlock_service.h"
37 #include "chrome/browser/signin/signin_manager_factory.h" 39 #include "chrome/browser/signin/signin_manager_factory.h"
38 #include "chrome/browser/ui/webui/chromeos/login/screenlock_icon_provider.h" 40 #include "chrome/browser/ui/webui/chromeos/login/screenlock_icon_provider.h"
39 #include "chrome/browser/ui/webui/chromeos/login/screenlock_icon_source.h" 41 #include "chrome/browser/ui/webui/chromeos/login/screenlock_icon_source.h"
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 ScreenLocker::HandleLockScreenRequest(); 114 ScreenLocker::HandleLockScreenRequest();
113 } 115 }
114 116
115 private: 117 private:
116 bool session_started_; 118 bool session_started_;
117 content::NotificationRegistrar registrar_; 119 content::NotificationRegistrar registrar_;
118 120
119 DISALLOW_COPY_AND_ASSIGN(ScreenLockObserver); 121 DISALLOW_COPY_AND_ASSIGN(ScreenLockObserver);
120 }; 122 };
121 123
124 bool IsLikelyPIN(const std::string& input) {
125 // Check if |input| looks like a number; the actual numeric value doesn't
126 // matter.
127 int num;
128 return base::StringToInt(input, &num);
129 }
130
122 ScreenLockObserver* g_screen_lock_observer = NULL; 131 ScreenLockObserver* g_screen_lock_observer = NULL;
123 132
124 } // namespace 133 } // namespace
125 134
126 // static 135 // static
127 ScreenLocker* ScreenLocker::screen_locker_ = NULL; 136 ScreenLocker* ScreenLocker::screen_locker_ = NULL;
128 137
129 ////////////////////////////////////////////////////////////////////////////// 138 //////////////////////////////////////////////////////////////////////////////
130 // ScreenLocker, public: 139 // ScreenLocker, public:
131 140
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 } 217 }
209 218
210 const user_manager::User* user = 219 const user_manager::User* user =
211 user_manager::UserManager::Get()->FindUser(user_context.GetAccountId()); 220 user_manager::UserManager::Get()->FindUser(user_context.GetAccountId());
212 if (user) { 221 if (user) {
213 if (!user->is_active()) { 222 if (!user->is_active()) {
214 saved_ime_state_ = NULL; 223 saved_ime_state_ = NULL;
215 user_manager::UserManager::Get()->SwitchActiveUser( 224 user_manager::UserManager::Get()->SwitchActiveUser(
216 user_context.GetAccountId()); 225 user_context.GetAccountId());
217 } 226 }
227
228 // Reset the number of PIN attempts available to the user. We always do this
229 // because:
230 // 1. If the user signed in with a PIN, that means they should be able to
231 // continue signing in with a PIN.
232 // 2. If the user signed in with cryptohome keys, then the PIN timeout is
233 // going to be reset as well, so it is safe to reset the unlock attempt
234 // count.
235 PinStorage* pin_storage = PinStorageFactory::GetForUser(user);
236 if (pin_storage) {
237 pin_storage->ResetUnlockAttemptCount();
238 } else {
239 NOTREACHED() << "PinStorage not available for user";
240 }
241
218 UserSessionManager::GetInstance()->UpdateEasyUnlockKeys(user_context); 242 UserSessionManager::GetInstance()->UpdateEasyUnlockKeys(user_context);
219 } else { 243 } else {
220 NOTREACHED() << "Logged in user not found."; 244 NOTREACHED() << "Logged in user not found.";
221 } 245 }
222 246
223 authentication_capture_.reset(new AuthenticationParametersCapture()); 247 authentication_capture_.reset(new AuthenticationParametersCapture());
224 authentication_capture_->user_context = user_context; 248 authentication_capture_->user_context = user_context;
225 249
226 // Add guard for case when something get broken in call chain to unlock 250 // Add guard for case when something get broken in call chain to unlock
227 // for sure. 251 // for sure.
228 base::MessageLoop::current()->PostDelayedTask( 252 base::MessageLoop::current()->PostDelayedTask(
229 FROM_HERE, 253 FROM_HERE,
230 base::Bind(&ScreenLocker::UnlockOnLoginSuccess, 254 base::Bind(&ScreenLocker::UnlockOnLoginSuccess,
231 weak_factory_.GetWeakPtr()), 255 weak_factory_.GetWeakPtr()),
232 base::TimeDelta::FromMilliseconds(kUnlockGuardTimeoutMs)); 256 base::TimeDelta::FromMilliseconds(kUnlockGuardTimeoutMs));
233 delegate_->AnimateAuthenticationSuccess(); 257 delegate_->AnimateAuthenticationSuccess();
234 } 258 }
235 259
260 void ScreenLocker::OnPasswordAuthSuccess(const UserContext& user_context) {
261 // The user has signed in using their password, so reset the PIN timeout.
262 PinStorage* pin_storage =
263 PinStorageFactory::GetForAccountId(user_context.GetAccountId());
264
265 if (pin_storage) {
266 pin_storage->MarkStrongAuth();
267 } else {
268 NOTREACHED() << "Missing PinStorage for account";
269 }
270 }
271
236 void ScreenLocker::UnlockOnLoginSuccess() { 272 void ScreenLocker::UnlockOnLoginSuccess() {
237 DCHECK(base::MessageLoopForUI::IsCurrent()); 273 DCHECK(base::MessageLoopForUI::IsCurrent());
238 if (!authentication_capture_.get()) { 274 if (!authentication_capture_.get()) {
239 LOG(WARNING) << "Call to UnlockOnLoginSuccess without previous " << 275 LOG(WARNING) << "Call to UnlockOnLoginSuccess without previous " <<
240 "authentication success."; 276 "authentication success.";
241 return; 277 return;
242 } 278 }
243 279
244 if (auth_status_consumer_) { 280 if (auth_status_consumer_) {
245 auth_status_consumer_->OnAuthSuccess(authentication_capture_->user_context); 281 auth_status_consumer_->OnAuthSuccess(authentication_capture_->user_context);
246 } 282 }
247 authentication_capture_.reset(); 283 authentication_capture_.reset();
248 weak_factory_.InvalidateWeakPtrs(); 284 weak_factory_.InvalidateWeakPtrs();
249 285
250 VLOG(1) << "Hiding the lock screen."; 286 VLOG(1) << "Hiding the lock screen.";
251 chromeos::ScreenLocker::Hide(); 287 chromeos::ScreenLocker::Hide();
252 } 288 }
253 289
254 void ScreenLocker::Authenticate(const UserContext& user_context) { 290 void ScreenLocker::Authenticate(const UserContext& user_context) {
255 LOG_ASSERT(IsUserLoggedIn(user_context.GetAccountId().GetUserEmail())) 291 LOG_ASSERT(IsUserLoggedIn(user_context.GetAccountId()))
256 << "Invalid user trying to unlock."; 292 << "Invalid user trying to unlock.";
257 293
258 authentication_start_time_ = base::Time::Now(); 294 authentication_start_time_ = base::Time::Now();
259 delegate_->SetInputEnabled(false); 295 delegate_->SetInputEnabled(false);
260 delegate_->OnAuthenticate(); 296 delegate_->OnAuthenticate();
261 297
262 // Special case: supervised users. Use special authenticator. 298 const user_manager::User* user = FindUnlockUser(user_context.GetAccountId());
263 if (const user_manager::User* user = 299 if (user) {
264 FindUnlockUser(user_context.GetAccountId().GetUserEmail())) { 300 // Check to see if the user submitted a PIN and it is valid.
301 std::string pin = user_context.GetKey()->GetSecret();
achuithb 2016/06/02 23:34:45 const
jdufault 2016/06/03 23:39:49 Done.
302 if (IsLikelyPIN(pin)) {
achuithb 2016/06/02 23:34:45 Not sure if this deserves a separate function - it
jdufault 2016/06/03 23:39:49 Done. Yea, it's iffy. Inlining introduces an extra
303 chromeos::PinStorage* pin_storage =
304 chromeos::PinStorageFactory::GetForUser(user);
305 if (!pin_storage) {
306 NOTREACHED() << "Missing PinStorage when trying to authenticate PIN";
achuithb 2016/06/02 23:34:45 Is this logging important? Why not if (pin_storag
jdufault 2016/06/03 23:39:49 Done.
307 } else if (pin_storage->TryAuthenticatePin(pin)) {
308 OnAuthSuccess(user_context);
309 return;
310 }
311 }
312
313 // Special case: supervised users. Use special authenticator.
265 if (user->GetType() == user_manager::USER_TYPE_SUPERVISED) { 314 if (user->GetType() == user_manager::USER_TYPE_SUPERVISED) {
266 UserContext updated_context = ChromeUserManager::Get() 315 UserContext updated_context = ChromeUserManager::Get()
267 ->GetSupervisedUserManager() 316 ->GetSupervisedUserManager()
268 ->GetAuthentication() 317 ->GetAuthentication()
269 ->TransformKey(user_context); 318 ->TransformKey(user_context);
270 // TODO(antrim) : replace empty closure with explicit method.
271 // http://crbug.com/351268
272 BrowserThread::PostTask( 319 BrowserThread::PostTask(
273 BrowserThread::UI, 320 BrowserThread::UI, FROM_HERE,
274 FROM_HERE,
275 base::Bind(&ExtendedAuthenticator::AuthenticateToCheck, 321 base::Bind(&ExtendedAuthenticator::AuthenticateToCheck,
276 extended_authenticator_.get(), 322 extended_authenticator_.get(), updated_context,
277 updated_context, 323 base::Bind(&ScreenLocker::OnPasswordAuthSuccess,
278 base::Closure())); 324 base::Unretained(this), user_context)));
achuithb 2016/06/02 23:34:45 Why base::Unretained? Also, should this be updated
jdufault 2016/06/03 23:39:49 Done on updated_context.
279 return; 325 return;
280 } 326 }
281 } 327 }
282 328
283 BrowserThread::PostTask( 329 BrowserThread::PostTask(
284 BrowserThread::UI, FROM_HERE, 330 BrowserThread::UI, FROM_HERE,
285 base::Bind(&ExtendedAuthenticator::AuthenticateToCheck, 331 base::Bind(&ExtendedAuthenticator::AuthenticateToCheck,
286 extended_authenticator_.get(), 332 extended_authenticator_.get(), user_context,
287 user_context, 333 base::Bind(&ScreenLocker::OnPasswordAuthSuccess,
288 base::Closure())); 334 base::Unretained(this), user_context)));
achuithb 2016/06/02 23:34:45 base::Unretained?
jdufault 2016/06/03 23:39:49 I've converted this to use a weak_ptr, but I belie
achuithb 2016/06/04 00:32:00 If you feel strongly that base::Unretained is the
jdufault 2016/06/08 18:40:50 sg; the current CL is using the weak_ptr approach.
289 } 335 }
290 336
291 const user_manager::User* ScreenLocker::FindUnlockUser( 337 const user_manager::User* ScreenLocker::FindUnlockUser(
292 const std::string& user_id) { 338 const AccountId& account_id) {
293 const user_manager::User* unlock_user = NULL; 339 for (const user_manager::User* user : users_) {
294 for (user_manager::UserList::const_iterator it = users_.begin(); 340 if (user->GetAccountId() == account_id)
295 it != users_.end(); 341 return user;
296 ++it) {
297 if ((*it)->email() == user_id) {
298 unlock_user = *it;
299 break;
300 }
301 } 342 }
302 return unlock_user; 343 return nullptr;
303 } 344 }
304 345
305 void ScreenLocker::ClearErrors() { 346 void ScreenLocker::ClearErrors() {
306 delegate_->ClearErrors(); 347 delegate_->ClearErrors();
307 } 348 }
308 349
309 void ScreenLocker::Signout() { 350 void ScreenLocker::Signout() {
310 delegate_->ClearErrors(); 351 delegate_->ClearErrors();
311 content::RecordAction(UserMetricsAction("ScreenLocker_Signout")); 352 content::RecordAction(UserMetricsAction("ScreenLocker_Signout"));
312 // We expect that this call will not wait for any user input. 353 // We expect that this call will not wait for any user input.
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
496 537
497 input_method::InputMethodManager::Get() 538 input_method::InputMethodManager::Get()
498 ->GetActiveIMEState() 539 ->GetActiveIMEState()
499 ->EnableLockScreenLayouts(); 540 ->EnableLockScreenLayouts();
500 } 541 }
501 542
502 content::WebUI* ScreenLocker::GetAssociatedWebUI() { 543 content::WebUI* ScreenLocker::GetAssociatedWebUI() {
503 return delegate_->GetAssociatedWebUI(); 544 return delegate_->GetAssociatedWebUI();
504 } 545 }
505 546
506 bool ScreenLocker::IsUserLoggedIn(const std::string& username) { 547 bool ScreenLocker::IsUserLoggedIn(const AccountId& account_id) {
achuithb 2016/06/02 23:34:45 is it painful to make this function const?
jdufault 2016/06/03 23:39:49 Done.
507 for (user_manager::UserList::const_iterator it = users_.begin(); 548 for (user_manager::User* user : users_) {
508 it != users_.end(); 549 if (user->GetAccountId() == account_id)
509 ++it) {
510 if ((*it)->email() == username)
511 return true; 550 return true;
512 } 551 }
513 return false; 552 return false;
514 } 553 }
515 554
516 } // namespace chromeos 555 } // namespace chromeos
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/login/lock/screen_locker.h ('k') | chrome/browser/chromeos/login/quick_unlock/pin_storage_factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698