ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / chrome / browser / signin / easy_unlock_service.cc
bloba70603804decb19104df90895c716cd811bb2642
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
3 // found in the LICENSE file.
5 #include "chrome/browser/signin/easy_unlock_service.h"
7 #include "base/bind.h"
8 #include "base/command_line.h"
9 #include "base/guid.h"
10 #include "base/logging.h"
11 #include "base/metrics/histogram_macros.h"
12 #include "base/prefs/pref_registry_simple.h"
13 #include "base/prefs/pref_service.h"
14 #include "base/prefs/scoped_user_pref_update.h"
15 #include "base/thread_task_runner_handle.h"
16 #include "base/time/time.h"
17 #include "base/values.h"
18 #include "chrome/browser/browser_process.h"
19 #include "chrome/browser/profiles/profile.h"
20 #include "chrome/browser/signin/easy_unlock_app_manager.h"
21 #include "chrome/browser/signin/easy_unlock_auth_attempt.h"
22 #include "chrome/browser/signin/easy_unlock_service_factory.h"
23 #include "chrome/browser/signin/easy_unlock_service_observer.h"
24 #include "chrome/browser/signin/screenlock_bridge.h"
25 #include "chrome/common/chrome_switches.h"
26 #include "chrome/common/pref_names.h"
27 #include "components/pref_registry/pref_registry_syncable.h"
28 #include "components/proximity_auth/switches.h"
29 #include "components/user_manager/user.h"
30 #include "device/bluetooth/bluetooth_adapter.h"
31 #include "device/bluetooth/bluetooth_adapter_factory.h"
33 #if defined(OS_CHROMEOS)
34 #include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_key_manager.h"
35 #include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_tpm_key_manager.h"
36 #include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_tpm_key_manager_factory.h"
37 #include "chrome/browser/chromeos/login/session/user_session_manager.h"
38 #include "chrome/browser/chromeos/profiles/profile_helper.h"
39 #include "chromeos/dbus/dbus_thread_manager.h"
40 #include "chromeos/dbus/power_manager_client.h"
41 #include "components/user_manager/user_manager.h"
42 #endif
44 namespace {
46 PrefService* GetLocalState() {
47 return g_browser_process ? g_browser_process->local_state() : NULL;
50 } // namespace
52 EasyUnlockService::UserSettings::UserSettings()
53 : require_close_proximity(false) {
56 EasyUnlockService::UserSettings::~UserSettings() {
59 // static
60 EasyUnlockService* EasyUnlockService::Get(Profile* profile) {
61 return EasyUnlockServiceFactory::GetForProfile(profile);
64 // static
65 EasyUnlockService* EasyUnlockService::GetForUser(
66 const user_manager::User& user) {
67 #if defined(OS_CHROMEOS)
68 Profile* profile = chromeos::ProfileHelper::Get()->GetProfileByUser(&user);
69 if (!profile)
70 return NULL;
71 return EasyUnlockService::Get(profile);
72 #else
73 return NULL;
74 #endif
77 // static
78 bool EasyUnlockService::IsSignInEnabled() {
79 return !base::CommandLine::ForCurrentProcess()->HasSwitch(
80 proximity_auth::switches::kDisableEasyUnlock);
83 class EasyUnlockService::BluetoothDetector
84 : public device::BluetoothAdapter::Observer {
85 public:
86 explicit BluetoothDetector(EasyUnlockService* service)
87 : service_(service),
88 weak_ptr_factory_(this) {
91 ~BluetoothDetector() override {
92 if (adapter_.get())
93 adapter_->RemoveObserver(this);
96 void Initialize() {
97 if (!device::BluetoothAdapterFactory::IsBluetoothAdapterAvailable())
98 return;
100 device::BluetoothAdapterFactory::GetAdapter(
101 base::Bind(&BluetoothDetector::OnAdapterInitialized,
102 weak_ptr_factory_.GetWeakPtr()));
105 bool IsPresent() const { return adapter_.get() && adapter_->IsPresent(); }
107 // device::BluetoothAdapter::Observer:
108 void AdapterPresentChanged(device::BluetoothAdapter* adapter,
109 bool present) override {
110 service_->OnBluetoothAdapterPresentChanged();
113 private:
114 void OnAdapterInitialized(scoped_refptr<device::BluetoothAdapter> adapter) {
115 adapter_ = adapter;
116 adapter_->AddObserver(this);
117 service_->OnBluetoothAdapterPresentChanged();
120 // Owner of this class and should out-live this class.
121 EasyUnlockService* service_;
122 scoped_refptr<device::BluetoothAdapter> adapter_;
123 base::WeakPtrFactory<BluetoothDetector> weak_ptr_factory_;
125 DISALLOW_COPY_AND_ASSIGN(BluetoothDetector);
128 #if defined(OS_CHROMEOS)
129 class EasyUnlockService::PowerMonitor
130 : public chromeos::PowerManagerClient::Observer {
131 public:
132 explicit PowerMonitor(EasyUnlockService* service)
133 : service_(service),
134 waking_up_(false),
135 weak_ptr_factory_(this) {
136 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->
137 AddObserver(this);
140 ~PowerMonitor() override {
141 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->
142 RemoveObserver(this);
145 // Called when the remote device has been authenticated to record the time
146 // delta from waking up. No time will be recorded if the start-up time has
147 // already been recorded or if the system never went to sleep previously.
148 void RecordStartUpTime() {
149 if (wake_up_time_.is_null())
150 return;
151 UMA_HISTOGRAM_MEDIUM_TIMES(
152 "EasyUnlock.StartupTimeFromSuspend",
153 base::Time::Now() - wake_up_time_);
154 wake_up_time_ = base::Time();
157 bool waking_up() const { return waking_up_; }
159 private:
160 // chromeos::PowerManagerClient::Observer:
161 void SuspendImminent() override { service_->PrepareForSuspend(); }
163 void SuspendDone(const base::TimeDelta& sleep_duration) override {
164 waking_up_ = true;
165 wake_up_time_ = base::Time::Now();
166 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
167 FROM_HERE,
168 base::Bind(&PowerMonitor::ResetWakingUp,
169 weak_ptr_factory_.GetWeakPtr()),
170 base::TimeDelta::FromSeconds(5));
171 service_->UpdateAppState();
172 // Note that |this| may get deleted after |UpdateAppState| is called.
175 void ResetWakingUp() {
176 waking_up_ = false;
177 service_->UpdateAppState();
180 EasyUnlockService* service_;
181 bool waking_up_;
182 base::Time wake_up_time_;
183 base::WeakPtrFactory<PowerMonitor> weak_ptr_factory_;
185 DISALLOW_COPY_AND_ASSIGN(PowerMonitor);
187 #endif
189 EasyUnlockService::EasyUnlockService(Profile* profile)
190 : profile_(profile),
191 bluetooth_detector_(new BluetoothDetector(this)),
192 shut_down_(false),
193 tpm_key_checked_(false),
194 weak_ptr_factory_(this) {
197 EasyUnlockService::~EasyUnlockService() {
200 // static
201 void EasyUnlockService::RegisterProfilePrefs(
202 user_prefs::PrefRegistrySyncable* registry) {
203 registry->RegisterBooleanPref(
204 prefs::kEasyUnlockAllowed,
205 true,
206 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
207 registry->RegisterBooleanPref(
208 prefs::kEasyUnlockEnabled,
209 false,
210 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
211 registry->RegisterDictionaryPref(
212 prefs::kEasyUnlockPairing,
213 new base::DictionaryValue(),
214 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
215 registry->RegisterBooleanPref(
216 prefs::kEasyUnlockProximityRequired,
217 false,
218 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
221 // static
222 void EasyUnlockService::RegisterPrefs(PrefRegistrySimple* registry) {
223 registry->RegisterStringPref(prefs::kEasyUnlockDeviceId, std::string());
224 registry->RegisterDictionaryPref(prefs::kEasyUnlockHardlockState);
225 registry->RegisterDictionaryPref(prefs::kEasyUnlockLocalStateUserPrefs);
226 #if defined(OS_CHROMEOS)
227 EasyUnlockTpmKeyManager::RegisterLocalStatePrefs(registry);
228 #endif
231 // static
232 void EasyUnlockService::ResetLocalStateForUser(const std::string& user_id) {
233 DCHECK(!user_id.empty());
235 PrefService* local_state = GetLocalState();
236 if (!local_state)
237 return;
239 DictionaryPrefUpdate update(local_state, prefs::kEasyUnlockHardlockState);
240 update->RemoveWithoutPathExpansion(user_id, NULL);
242 #if defined(OS_CHROMEOS)
243 EasyUnlockTpmKeyManager::ResetLocalStateForUser(user_id);
244 #endif
247 // static
248 EasyUnlockService::UserSettings EasyUnlockService::GetUserSettings(
249 const std::string& user_id) {
250 DCHECK(!user_id.empty());
251 UserSettings user_settings;
253 PrefService* local_state = GetLocalState();
254 if (!local_state)
255 return user_settings;
257 const base::DictionaryValue* all_user_prefs_dict =
258 local_state->GetDictionary(prefs::kEasyUnlockLocalStateUserPrefs);
259 if (!all_user_prefs_dict)
260 return user_settings;
262 const base::DictionaryValue* user_prefs_dict;
263 if (!all_user_prefs_dict->GetDictionaryWithoutPathExpansion(user_id,
264 &user_prefs_dict))
265 return user_settings;
267 user_prefs_dict->GetBooleanWithoutPathExpansion(
268 prefs::kEasyUnlockProximityRequired,
269 &user_settings.require_close_proximity);
271 return user_settings;
274 // static
275 std::string EasyUnlockService::GetDeviceId() {
276 PrefService* local_state = GetLocalState();
277 if (!local_state)
278 return std::string();
280 std::string device_id = local_state->GetString(prefs::kEasyUnlockDeviceId);
281 if (device_id.empty()) {
282 device_id = base::GenerateGUID();
283 local_state->SetString(prefs::kEasyUnlockDeviceId, device_id);
285 return device_id;
288 void EasyUnlockService::Initialize(
289 scoped_ptr<EasyUnlockAppManager> app_manager) {
290 app_manager_ = app_manager.Pass();
291 app_manager_->EnsureReady(
292 base::Bind(&EasyUnlockService::InitializeOnAppManagerReady,
293 weak_ptr_factory_.GetWeakPtr()));
296 bool EasyUnlockService::IsAllowed() const {
297 if (shut_down_)
298 return false;
300 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
301 proximity_auth::switches::kDisableEasyUnlock)) {
302 return false;
305 if (!IsAllowedInternal())
306 return false;
308 #if defined(OS_CHROMEOS)
309 if (!bluetooth_detector_->IsPresent())
310 return false;
312 return true;
313 #else
314 // TODO(xiyuan): Revisit when non-chromeos platforms are supported.
315 return false;
316 #endif
319 bool EasyUnlockService::IsEnabled() const {
320 // The feature is enabled iff there are any paired devices.
321 const base::ListValue* devices = GetRemoteDevices();
322 return devices && !devices->empty();
325 void EasyUnlockService::OpenSetupApp() {
326 app_manager_->LaunchSetup();
329 void EasyUnlockService::SetHardlockState(
330 EasyUnlockScreenlockStateHandler::HardlockState state) {
331 const std::string user_id = GetUserEmail();
332 if (user_id.empty())
333 return;
335 SetHardlockStateForUser(user_id, state);
338 EasyUnlockScreenlockStateHandler::HardlockState
339 EasyUnlockService::GetHardlockState() const {
340 EasyUnlockScreenlockStateHandler::HardlockState state;
341 if (GetPersistedHardlockState(&state))
342 return state;
344 return EasyUnlockScreenlockStateHandler::NO_HARDLOCK;
347 bool EasyUnlockService::GetPersistedHardlockState(
348 EasyUnlockScreenlockStateHandler::HardlockState* state) const {
349 std::string user_id = GetUserEmail();
350 if (user_id.empty())
351 return false;
353 PrefService* local_state = GetLocalState();
354 if (!local_state)
355 return false;
357 const base::DictionaryValue* dict =
358 local_state->GetDictionary(prefs::kEasyUnlockHardlockState);
359 int state_int;
360 if (dict && dict->GetIntegerWithoutPathExpansion(user_id, &state_int)) {
361 *state =
362 static_cast<EasyUnlockScreenlockStateHandler::HardlockState>(state_int);
363 return true;
366 return false;
369 void EasyUnlockService::ShowInitialUserState() {
370 if (!GetScreenlockStateHandler())
371 return;
373 EasyUnlockScreenlockStateHandler::HardlockState state;
374 bool has_persisted_state = GetPersistedHardlockState(&state);
375 if (!has_persisted_state)
376 return;
378 if (state == EasyUnlockScreenlockStateHandler::NO_HARDLOCK) {
379 // Show connecting icon early when there is a persisted non hardlock state.
380 UpdateScreenlockState(
381 EasyUnlockScreenlockStateHandler::STATE_BLUETOOTH_CONNECTING);
382 } else {
383 screenlock_state_handler_->MaybeShowHardlockUI();
387 EasyUnlockScreenlockStateHandler*
388 EasyUnlockService::GetScreenlockStateHandler() {
389 if (!IsAllowed())
390 return NULL;
391 if (!screenlock_state_handler_) {
392 screenlock_state_handler_.reset(new EasyUnlockScreenlockStateHandler(
393 GetUserEmail(),
394 GetHardlockState(),
395 ScreenlockBridge::Get()));
397 return screenlock_state_handler_.get();
400 bool EasyUnlockService::UpdateScreenlockState(
401 EasyUnlockScreenlockStateHandler::State state) {
402 EasyUnlockScreenlockStateHandler* handler = GetScreenlockStateHandler();
403 if (!handler)
404 return false;
406 handler->ChangeState(state);
408 if (state == EasyUnlockScreenlockStateHandler::STATE_AUTHENTICATED) {
409 #if defined(OS_CHROMEOS)
410 if (power_monitor_)
411 power_monitor_->RecordStartUpTime();
412 #endif
413 } else if (auth_attempt_.get()) {
414 // Clean up existing auth attempt if we can no longer authenticate the
415 // remote device.
416 auth_attempt_.reset();
418 if (!handler->InStateValidOnRemoteAuthFailure())
419 HandleAuthFailure(GetUserEmail());
421 return true;
424 void EasyUnlockService::AttemptAuth(const std::string& user_id) {
425 CHECK_EQ(GetUserEmail(), user_id);
427 auth_attempt_.reset(new EasyUnlockAuthAttempt(
428 app_manager_.get(), user_id, GetType() == TYPE_REGULAR
429 ? EasyUnlockAuthAttempt::TYPE_UNLOCK
430 : EasyUnlockAuthAttempt::TYPE_SIGNIN));
431 if (!auth_attempt_->Start())
432 auth_attempt_.reset();
435 void EasyUnlockService::FinalizeUnlock(bool success) {
436 if (!auth_attempt_.get())
437 return;
439 this->OnWillFinalizeUnlock(success);
440 auth_attempt_->FinalizeUnlock(GetUserEmail(), success);
441 auth_attempt_.reset();
442 // TODO(isherman): If observing screen unlock events, is there a race
443 // condition in terms of reading the service's state vs. the app setting the
444 // state?
446 // Make sure that the lock screen is updated on failure.
447 if (!success) {
448 RecordEasyUnlockScreenUnlockEvent(EASY_UNLOCK_FAILURE);
449 HandleAuthFailure(GetUserEmail());
453 void EasyUnlockService::FinalizeSignin(const std::string& key) {
454 if (!auth_attempt_.get())
455 return;
456 std::string wrapped_secret = GetWrappedSecret();
457 if (!wrapped_secret.empty())
458 auth_attempt_->FinalizeSignin(GetUserEmail(), wrapped_secret, key);
459 auth_attempt_.reset();
461 // Processing empty key is equivalent to auth cancellation. In this case the
462 // signin request will not actually be processed by login stack, so the lock
463 // screen state should be set from here.
464 if (key.empty())
465 HandleAuthFailure(GetUserEmail());
468 void EasyUnlockService::HandleAuthFailure(const std::string& user_id) {
469 if (user_id != GetUserEmail())
470 return;
472 if (!screenlock_state_handler_.get())
473 return;
475 screenlock_state_handler_->SetHardlockState(
476 EasyUnlockScreenlockStateHandler::LOGIN_FAILED);
479 void EasyUnlockService::CheckCryptohomeKeysAndMaybeHardlock() {
480 #if defined(OS_CHROMEOS)
481 std::string user_id = GetUserEmail();
482 if (user_id.empty())
483 return;
485 const base::ListValue* device_list = GetRemoteDevices();
486 std::set<std::string> paired_devices;
487 if (device_list) {
488 chromeos::EasyUnlockDeviceKeyDataList parsed_paired;
489 chromeos::EasyUnlockKeyManager::RemoteDeviceListToDeviceDataList(
490 *device_list, &parsed_paired);
491 for (const auto& device_key_data : parsed_paired)
492 paired_devices.insert(device_key_data.psk);
494 if (paired_devices.empty()) {
495 SetHardlockState(EasyUnlockScreenlockStateHandler::NO_PAIRING);
496 return;
499 // No need to compare if a change is already recorded.
500 if (GetHardlockState() == EasyUnlockScreenlockStateHandler::PAIRING_CHANGED ||
501 GetHardlockState() == EasyUnlockScreenlockStateHandler::PAIRING_ADDED) {
502 return;
505 chromeos::EasyUnlockKeyManager* key_manager =
506 chromeos::UserSessionManager::GetInstance()->GetEasyUnlockKeyManager();
507 DCHECK(key_manager);
509 key_manager->GetDeviceDataList(
510 chromeos::UserContext(user_id),
511 base::Bind(&EasyUnlockService::OnCryptohomeKeysFetchedForChecking,
512 weak_ptr_factory_.GetWeakPtr(),
513 user_id,
514 paired_devices));
515 #endif
518 void EasyUnlockService::SetTrialRun() {
519 DCHECK_EQ(GetType(), TYPE_REGULAR);
521 EasyUnlockScreenlockStateHandler* handler = GetScreenlockStateHandler();
522 if (handler)
523 handler->SetTrialRun();
526 void EasyUnlockService::RecordClickOnLockIcon() {
527 if (screenlock_state_handler_)
528 screenlock_state_handler_->RecordClickOnLockIcon();
531 void EasyUnlockService::AddObserver(EasyUnlockServiceObserver* observer) {
532 observers_.AddObserver(observer);
535 void EasyUnlockService::RemoveObserver(EasyUnlockServiceObserver* observer) {
536 observers_.RemoveObserver(observer);
539 void EasyUnlockService::Shutdown() {
540 if (shut_down_)
541 return;
542 shut_down_ = true;
544 ShutdownInternal();
546 ResetScreenlockState();
547 bluetooth_detector_.reset();
548 #if defined(OS_CHROMEOS)
549 power_monitor_.reset();
550 #endif
552 weak_ptr_factory_.InvalidateWeakPtrs();
555 void EasyUnlockService::ReloadAppAndLockScreen() {
556 // Make sure lock screen state set by the extension gets reset.
557 ResetScreenlockState();
558 app_manager_->ReloadApp();
559 NotifyUserUpdated();
562 void EasyUnlockService::UpdateAppState() {
563 if (IsAllowed()) {
564 EnsureTpmKeyPresentIfNeeded();
565 app_manager_->LoadApp();
566 NotifyUserUpdated();
568 #if defined(OS_CHROMEOS)
569 if (!power_monitor_)
570 power_monitor_.reset(new PowerMonitor(this));
571 #endif
572 } else {
573 bool bluetooth_waking_up = false;
574 #if defined(OS_CHROMEOS)
575 // If the service is not allowed due to bluetooth not being detected just
576 // after system suspend is done, give bluetooth more time to be detected
577 // before disabling the app (and resetting screenlock state).
578 bluetooth_waking_up =
579 power_monitor_.get() && power_monitor_->waking_up() &&
580 !bluetooth_detector_->IsPresent();
581 #endif
583 if (!bluetooth_waking_up) {
584 app_manager_->DisableAppIfLoaded();
585 ResetScreenlockState();
586 #if defined(OS_CHROMEOS)
587 power_monitor_.reset();
588 #endif
593 void EasyUnlockService::DisableAppWithoutResettingScreenlockState() {
594 app_manager_->DisableAppIfLoaded();
597 void EasyUnlockService::NotifyUserUpdated() {
598 std::string user_id = GetUserEmail();
599 if (user_id.empty())
600 return;
602 // Notify the easy unlock app that the user info changed.
603 bool logged_in = GetType() == TYPE_REGULAR;
604 bool data_ready = logged_in || GetRemoteDevices() != NULL;
605 app_manager_->SendUserUpdatedEvent(user_id, logged_in, data_ready);
608 void EasyUnlockService::NotifyTurnOffOperationStatusChanged() {
609 FOR_EACH_OBSERVER(
610 EasyUnlockServiceObserver, observers_, OnTurnOffOperationStatusChanged());
613 void EasyUnlockService::ResetScreenlockState() {
614 screenlock_state_handler_.reset();
615 auth_attempt_.reset();
618 void EasyUnlockService::SetScreenlockHardlockedState(
619 EasyUnlockScreenlockStateHandler::HardlockState state) {
620 if (screenlock_state_handler_)
621 screenlock_state_handler_->SetHardlockState(state);
622 if (state != EasyUnlockScreenlockStateHandler::NO_HARDLOCK)
623 auth_attempt_.reset();
626 void EasyUnlockService::InitializeOnAppManagerReady() {
627 CHECK(app_manager_.get());
629 InitializeInternal();
631 #if defined(OS_CHROMEOS)
632 // Only start Bluetooth detection for ChromeOS since the feature is
633 // only offered on ChromeOS. Enabling this on non-ChromeOS platforms
634 // previously introduced a performance regression: http://crbug.com/404482
635 // Make sure not to reintroduce a performance regression if re-enabling on
636 // additional platforms.
637 // TODO(xiyuan): Revisit when non-chromeos platforms are supported.
638 bluetooth_detector_->Initialize();
639 #endif // defined(OS_CHROMEOS)
642 void EasyUnlockService::OnBluetoothAdapterPresentChanged() {
643 UpdateAppState();
646 void EasyUnlockService::SetHardlockStateForUser(
647 const std::string& user_id,
648 EasyUnlockScreenlockStateHandler::HardlockState state) {
649 DCHECK(!user_id.empty());
651 PrefService* local_state = GetLocalState();
652 if (!local_state)
653 return;
655 DictionaryPrefUpdate update(local_state, prefs::kEasyUnlockHardlockState);
656 update->SetIntegerWithoutPathExpansion(user_id, static_cast<int>(state));
658 if (GetUserEmail() == user_id)
659 SetScreenlockHardlockedState(state);
662 EasyUnlockAuthEvent EasyUnlockService::GetPasswordAuthEvent() const {
663 DCHECK(IsEnabled());
665 if (GetHardlockState() != EasyUnlockScreenlockStateHandler::NO_HARDLOCK) {
666 switch (GetHardlockState()) {
667 case EasyUnlockScreenlockStateHandler::NO_HARDLOCK:
668 NOTREACHED();
669 return EASY_UNLOCK_AUTH_EVENT_COUNT;
670 case EasyUnlockScreenlockStateHandler::NO_PAIRING:
671 return PASSWORD_ENTRY_NO_PAIRING;
672 case EasyUnlockScreenlockStateHandler::USER_HARDLOCK:
673 return PASSWORD_ENTRY_USER_HARDLOCK;
674 case EasyUnlockScreenlockStateHandler::PAIRING_CHANGED:
675 return PASSWORD_ENTRY_PAIRING_CHANGED;
676 case EasyUnlockScreenlockStateHandler::LOGIN_FAILED:
677 return PASSWORD_ENTRY_LOGIN_FAILED;
678 case EasyUnlockScreenlockStateHandler::PAIRING_ADDED:
679 return PASSWORD_ENTRY_PAIRING_ADDED;
681 } else if (!screenlock_state_handler()) {
682 return PASSWORD_ENTRY_NO_SCREENLOCK_STATE_HANDLER;
683 } else {
684 switch (screenlock_state_handler()->state()) {
685 case EasyUnlockScreenlockStateHandler::STATE_INACTIVE:
686 return PASSWORD_ENTRY_SERVICE_NOT_ACTIVE;
687 case EasyUnlockScreenlockStateHandler::STATE_NO_BLUETOOTH:
688 return PASSWORD_ENTRY_NO_BLUETOOTH;
689 case EasyUnlockScreenlockStateHandler::STATE_BLUETOOTH_CONNECTING:
690 return PASSWORD_ENTRY_BLUETOOTH_CONNECTING;
691 case EasyUnlockScreenlockStateHandler::STATE_NO_PHONE:
692 return PASSWORD_ENTRY_NO_PHONE;
693 case EasyUnlockScreenlockStateHandler::STATE_PHONE_NOT_AUTHENTICATED:
694 return PASSWORD_ENTRY_PHONE_NOT_AUTHENTICATED;
695 case EasyUnlockScreenlockStateHandler::STATE_PHONE_LOCKED:
696 return PASSWORD_ENTRY_PHONE_LOCKED;
697 case EasyUnlockScreenlockStateHandler::STATE_PHONE_UNLOCKABLE:
698 return PASSWORD_ENTRY_PHONE_NOT_LOCKABLE;
699 case EasyUnlockScreenlockStateHandler::STATE_PHONE_UNSUPPORTED:
700 return PASSWORD_ENTRY_PHONE_UNSUPPORTED;
701 case EasyUnlockScreenlockStateHandler::STATE_RSSI_TOO_LOW:
702 return PASSWORD_ENTRY_RSSI_TOO_LOW;
703 case EasyUnlockScreenlockStateHandler::STATE_TX_POWER_TOO_HIGH:
704 return PASSWORD_ENTRY_TX_POWER_TOO_HIGH;
705 case EasyUnlockScreenlockStateHandler::
706 STATE_PHONE_LOCKED_AND_TX_POWER_TOO_HIGH:
707 return PASSWORD_ENTRY_PHONE_LOCKED_AND_TX_POWER_TOO_HIGH;
708 case EasyUnlockScreenlockStateHandler::STATE_AUTHENTICATED:
709 return PASSWORD_ENTRY_WITH_AUTHENTICATED_PHONE;
713 NOTREACHED();
714 return EASY_UNLOCK_AUTH_EVENT_COUNT;
717 #if defined(OS_CHROMEOS)
718 void EasyUnlockService::OnCryptohomeKeysFetchedForChecking(
719 const std::string& user_id,
720 const std::set<std::string> paired_devices,
721 bool success,
722 const chromeos::EasyUnlockDeviceKeyDataList& key_data_list) {
723 DCHECK(!user_id.empty() && !paired_devices.empty());
725 if (!success) {
726 SetHardlockStateForUser(user_id,
727 EasyUnlockScreenlockStateHandler::NO_PAIRING);
728 return;
731 std::set<std::string> devices_in_cryptohome;
732 for (const auto& device_key_data : key_data_list)
733 devices_in_cryptohome.insert(device_key_data.psk);
735 if (paired_devices != devices_in_cryptohome ||
736 GetHardlockState() == EasyUnlockScreenlockStateHandler::NO_PAIRING) {
737 SetHardlockStateForUser(
738 user_id,
739 devices_in_cryptohome.empty()
740 ? EasyUnlockScreenlockStateHandler::PAIRING_ADDED
741 : EasyUnlockScreenlockStateHandler::PAIRING_CHANGED);
744 #endif
746 void EasyUnlockService::PrepareForSuspend() {
747 app_manager_->DisableAppIfLoaded();
748 if (screenlock_state_handler_ && screenlock_state_handler_->IsActive()) {
749 UpdateScreenlockState(
750 EasyUnlockScreenlockStateHandler::STATE_BLUETOOTH_CONNECTING);
754 void EasyUnlockService::EnsureTpmKeyPresentIfNeeded() {
755 if (tpm_key_checked_ || GetType() != TYPE_REGULAR || GetUserEmail().empty())
756 return;
758 #if defined(OS_CHROMEOS)
759 // If this is called before the session is started, the chances are Chrome
760 // is restarting in order to apply user flags. Don't check TPM keys in this
761 // case.
762 if (!user_manager::UserManager::Get() ||
763 !user_manager::UserManager::Get()->IsSessionStarted())
764 return;
766 // TODO(tbarzic): Set check_private_key only if previous sign-in attempt
767 // failed.
768 EasyUnlockTpmKeyManagerFactory::GetInstance()->Get(profile_)
769 ->PrepareTpmKey(true /* check_private_key */,
770 base::Closure());
771 #endif // defined(OS_CHROMEOS)
773 tpm_key_checked_ = true;