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 "apps/app_lifetime_monitor.h"
8 #include "apps/app_lifetime_monitor_factory.h"
10 #include "base/command_line.h"
11 #include "base/guid.h"
12 #include "base/logging.h"
13 #include "base/metrics/histogram_macros.h"
14 #include "base/prefs/pref_registry_simple.h"
15 #include "base/prefs/pref_service.h"
16 #include "base/prefs/scoped_user_pref_update.h"
17 #include "base/thread_task_runner_handle.h"
18 #include "base/time/time.h"
19 #include "base/values.h"
20 #include "chrome/browser/browser_process.h"
21 #include "chrome/browser/profiles/profile.h"
22 #include "chrome/browser/signin/easy_unlock_app_manager.h"
23 #include "chrome/browser/signin/easy_unlock_service_factory.h"
24 #include "chrome/browser/signin/easy_unlock_service_observer.h"
25 #include "chrome/browser/signin/screenlock_bridge.h"
26 #include "chrome/common/chrome_switches.h"
27 #include "chrome/common/extensions/extension_constants.h"
28 #include "chrome/common/pref_names.h"
29 #include "components/pref_registry/pref_registry_syncable.h"
30 #include "components/proximity_auth/switches.h"
31 #include "components/user_manager/user.h"
32 #include "device/bluetooth/bluetooth_adapter.h"
33 #include "device/bluetooth/bluetooth_adapter_factory.h"
35 #if defined(OS_CHROMEOS)
36 #include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_key_manager.h"
37 #include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_tpm_key_manager.h"
38 #include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_tpm_key_manager_factory.h"
39 #include "chrome/browser/chromeos/login/session/user_session_manager.h"
40 #include "chrome/browser/chromeos/profiles/profile_helper.h"
41 #include "chromeos/dbus/dbus_thread_manager.h"
42 #include "chromeos/dbus/power_manager_client.h"
43 #include "components/user_manager/user_manager.h"
47 #include "base/win/windows_version.h"
55 BT_LOW_ENERGY_CAPABLE
,
59 PrefService
* GetLocalState() {
60 return g_browser_process
? g_browser_process
->local_state() : NULL
;
65 EasyUnlockService::UserSettings::UserSettings()
66 : require_close_proximity(false) {
69 EasyUnlockService::UserSettings::~UserSettings() {
73 EasyUnlockService
* EasyUnlockService::Get(Profile
* profile
) {
74 return EasyUnlockServiceFactory::GetForProfile(profile
);
78 EasyUnlockService
* EasyUnlockService::GetForUser(
79 const user_manager::User
& user
) {
80 #if defined(OS_CHROMEOS)
81 Profile
* profile
= chromeos::ProfileHelper::Get()->GetProfileByUser(&user
);
84 return EasyUnlockService::Get(profile
);
91 bool EasyUnlockService::IsSignInEnabled() {
92 return !base::CommandLine::ForCurrentProcess()->HasSwitch(
93 proximity_auth::switches::kDisableEasyUnlock
);
96 class EasyUnlockService::BluetoothDetector
97 : public device::BluetoothAdapter::Observer
,
98 public apps::AppLifetimeMonitor::Observer
{
100 explicit BluetoothDetector(EasyUnlockService
* service
)
102 weak_ptr_factory_(this) {
103 apps::AppLifetimeMonitorFactory::GetForProfile(service_
->profile())
107 ~BluetoothDetector() override
{
109 adapter_
->RemoveObserver(this);
110 apps::AppLifetimeMonitorFactory::GetForProfile(service_
->profile())
111 ->RemoveObserver(this);
115 if (!device::BluetoothAdapterFactory::IsBluetoothAdapterAvailable())
118 device::BluetoothAdapterFactory::GetAdapter(
119 base::Bind(&BluetoothDetector::OnAdapterInitialized
,
120 weak_ptr_factory_
.GetWeakPtr()));
123 bool IsPresent() const { return adapter_
.get() && adapter_
->IsPresent(); }
125 // device::BluetoothAdapter::Observer:
126 void AdapterPresentChanged(device::BluetoothAdapter
* adapter
,
127 bool present
) override
{
128 service_
->OnBluetoothAdapterPresentChanged();
131 device::BluetoothAdapter
* getAdapter() {
132 return adapter_
.get();
136 void OnAdapterInitialized(scoped_refptr
<device::BluetoothAdapter
> adapter
) {
138 adapter_
->AddObserver(this);
139 service_
->OnBluetoothAdapterPresentChanged();
141 // TODO(tengs): At the moment, there is no way for Bluetooth discoverability
142 // to be turned on except through the Easy Unlock setup. If we step on any
143 // toes in the future then we need to revisit this guard.
144 if (adapter_
->IsDiscoverable())
145 TurnOffBluetoothDiscoverability();
147 #if !defined(OS_CHROMEOS)
148 // Bluetooth detection causes serious performance degradations on Mac
149 // and possibly other platforms as well: http://crbug.com/467316
150 // Since this feature is currently only offered for ChromeOS we just
151 // turn it off on other platforms once the inforamtion about the
152 // adapter has been gathered and reported.
153 // TODO(bcwhite,xiyuan): Revisit when non-chromeos platforms are supported.
154 adapter_
->RemoveObserver(this);
156 #endif // !defined(OS_CHROMEOS)
159 // apps::AppLifetimeMonitor::Observer:
160 void OnAppDeactivated(Profile
* profile
, const std::string
& app_id
) override
{
161 // TODO(tengs): Refactor the lifetime management to EasyUnlockAppManager.
162 if (app_id
== extension_misc::kEasyUnlockAppId
)
163 TurnOffBluetoothDiscoverability();
166 void OnAppStop(Profile
* profile
, const std::string
& app_id
) override
{
167 // TODO(tengs): Refactor the lifetime management to EasyUnlockAppManager.
168 if (app_id
== extension_misc::kEasyUnlockAppId
)
169 TurnOffBluetoothDiscoverability();
172 void TurnOffBluetoothDiscoverability() {
174 adapter_
->SetDiscoverable(
175 false, base::Bind(&base::DoNothing
), base::Bind(&base::DoNothing
));
179 // Owner of this class and should out-live this class.
180 EasyUnlockService
* service_
;
181 scoped_refptr
<device::BluetoothAdapter
> adapter_
;
182 base::WeakPtrFactory
<BluetoothDetector
> weak_ptr_factory_
;
184 DISALLOW_COPY_AND_ASSIGN(BluetoothDetector
);
187 #if defined(OS_CHROMEOS)
188 class EasyUnlockService::PowerMonitor
189 : public chromeos::PowerManagerClient::Observer
{
191 explicit PowerMonitor(EasyUnlockService
* service
)
194 weak_ptr_factory_(this) {
195 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->
199 ~PowerMonitor() override
{
200 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->
201 RemoveObserver(this);
204 // Called when the remote device has been authenticated to record the time
205 // delta from waking up. No time will be recorded if the start-up time has
206 // already been recorded or if the system never went to sleep previously.
207 void RecordStartUpTime() {
208 if (wake_up_time_
.is_null())
210 UMA_HISTOGRAM_MEDIUM_TIMES(
211 "EasyUnlock.StartupTimeFromSuspend",
212 base::Time::Now() - wake_up_time_
);
213 wake_up_time_
= base::Time();
216 bool waking_up() const { return waking_up_
; }
219 // chromeos::PowerManagerClient::Observer:
220 void SuspendImminent() override
{ service_
->PrepareForSuspend(); }
222 void SuspendDone(const base::TimeDelta
& sleep_duration
) override
{
224 wake_up_time_
= base::Time::Now();
225 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
227 base::Bind(&PowerMonitor::ResetWakingUp
,
228 weak_ptr_factory_
.GetWeakPtr()),
229 base::TimeDelta::FromSeconds(5));
230 service_
->OnSuspendDone();
231 service_
->UpdateAppState();
232 // Note that |this| may get deleted after |UpdateAppState| is called.
235 void ResetWakingUp() {
237 service_
->UpdateAppState();
240 EasyUnlockService
* service_
;
242 base::Time wake_up_time_
;
243 base::WeakPtrFactory
<PowerMonitor
> weak_ptr_factory_
;
245 DISALLOW_COPY_AND_ASSIGN(PowerMonitor
);
249 EasyUnlockService::EasyUnlockService(Profile
* profile
)
251 bluetooth_detector_(new BluetoothDetector(this)),
253 tpm_key_checked_(false),
254 weak_ptr_factory_(this) {
257 EasyUnlockService::~EasyUnlockService() {
261 void EasyUnlockService::RegisterProfilePrefs(
262 user_prefs::PrefRegistrySyncable
* registry
) {
263 registry
->RegisterBooleanPref(
264 prefs::kEasyUnlockAllowed
,
266 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
267 registry
->RegisterBooleanPref(
268 prefs::kEasyUnlockEnabled
,
270 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
271 registry
->RegisterDictionaryPref(
272 prefs::kEasyUnlockPairing
,
273 new base::DictionaryValue(),
274 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF
);
275 registry
->RegisterBooleanPref(
276 prefs::kEasyUnlockProximityRequired
,
278 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF
);
282 void EasyUnlockService::RegisterPrefs(PrefRegistrySimple
* registry
) {
283 registry
->RegisterStringPref(prefs::kEasyUnlockDeviceId
, std::string());
284 registry
->RegisterDictionaryPref(prefs::kEasyUnlockHardlockState
);
285 registry
->RegisterDictionaryPref(prefs::kEasyUnlockLocalStateUserPrefs
);
286 #if defined(OS_CHROMEOS)
287 EasyUnlockTpmKeyManager::RegisterLocalStatePrefs(registry
);
292 void EasyUnlockService::ResetLocalStateForUser(const std::string
& user_id
) {
293 DCHECK(!user_id
.empty());
295 PrefService
* local_state
= GetLocalState();
299 DictionaryPrefUpdate
update(local_state
, prefs::kEasyUnlockHardlockState
);
300 update
->RemoveWithoutPathExpansion(user_id
, NULL
);
302 #if defined(OS_CHROMEOS)
303 EasyUnlockTpmKeyManager::ResetLocalStateForUser(user_id
);
308 EasyUnlockService::UserSettings
EasyUnlockService::GetUserSettings(
309 const std::string
& user_id
) {
310 DCHECK(!user_id
.empty());
311 UserSettings user_settings
;
313 PrefService
* local_state
= GetLocalState();
315 return user_settings
;
317 const base::DictionaryValue
* all_user_prefs_dict
=
318 local_state
->GetDictionary(prefs::kEasyUnlockLocalStateUserPrefs
);
319 if (!all_user_prefs_dict
)
320 return user_settings
;
322 const base::DictionaryValue
* user_prefs_dict
;
323 if (!all_user_prefs_dict
->GetDictionaryWithoutPathExpansion(user_id
,
325 return user_settings
;
327 user_prefs_dict
->GetBooleanWithoutPathExpansion(
328 prefs::kEasyUnlockProximityRequired
,
329 &user_settings
.require_close_proximity
);
331 return user_settings
;
335 std::string
EasyUnlockService::GetDeviceId() {
336 PrefService
* local_state
= GetLocalState();
338 return std::string();
340 std::string device_id
= local_state
->GetString(prefs::kEasyUnlockDeviceId
);
341 if (device_id
.empty()) {
342 device_id
= base::GenerateGUID();
343 local_state
->SetString(prefs::kEasyUnlockDeviceId
, device_id
);
348 void EasyUnlockService::Initialize(
349 scoped_ptr
<EasyUnlockAppManager
> app_manager
) {
350 app_manager_
= app_manager
.Pass();
351 app_manager_
->EnsureReady(
352 base::Bind(&EasyUnlockService::InitializeOnAppManagerReady
,
353 weak_ptr_factory_
.GetWeakPtr()));
356 bool EasyUnlockService::IsAllowed() const {
360 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
361 proximity_auth::switches::kDisableEasyUnlock
)) {
365 if (!IsAllowedInternal())
368 #if defined(OS_CHROMEOS)
369 if (!bluetooth_detector_
->IsPresent())
374 // TODO(xiyuan): Revisit when non-chromeos platforms are supported.
379 bool EasyUnlockService::IsEnabled() const {
380 // The feature is enabled iff there are any paired devices.
381 const base::ListValue
* devices
= GetRemoteDevices();
382 return devices
&& !devices
->empty();
385 void EasyUnlockService::OpenSetupApp() {
386 app_manager_
->LaunchSetup();
389 void EasyUnlockService::SetHardlockState(
390 EasyUnlockScreenlockStateHandler::HardlockState state
) {
391 const std::string user_id
= GetUserEmail();
395 if (state
== GetHardlockState())
398 SetHardlockStateForUser(user_id
, state
);
401 EasyUnlockScreenlockStateHandler::HardlockState
402 EasyUnlockService::GetHardlockState() const {
403 EasyUnlockScreenlockStateHandler::HardlockState state
;
404 if (GetPersistedHardlockState(&state
))
407 return EasyUnlockScreenlockStateHandler::NO_HARDLOCK
;
410 bool EasyUnlockService::GetPersistedHardlockState(
411 EasyUnlockScreenlockStateHandler::HardlockState
* state
) const {
412 std::string user_id
= GetUserEmail();
416 PrefService
* local_state
= GetLocalState();
420 const base::DictionaryValue
* dict
=
421 local_state
->GetDictionary(prefs::kEasyUnlockHardlockState
);
423 if (dict
&& dict
->GetIntegerWithoutPathExpansion(user_id
, &state_int
)) {
425 static_cast<EasyUnlockScreenlockStateHandler::HardlockState
>(state_int
);
432 void EasyUnlockService::ShowInitialUserState() {
433 if (!GetScreenlockStateHandler())
436 EasyUnlockScreenlockStateHandler::HardlockState state
;
437 bool has_persisted_state
= GetPersistedHardlockState(&state
);
438 if (!has_persisted_state
)
441 if (state
== EasyUnlockScreenlockStateHandler::NO_HARDLOCK
) {
442 // Show connecting icon early when there is a persisted non hardlock state.
443 UpdateScreenlockState(
444 EasyUnlockScreenlockStateHandler::STATE_BLUETOOTH_CONNECTING
);
446 screenlock_state_handler_
->MaybeShowHardlockUI();
450 EasyUnlockScreenlockStateHandler
*
451 EasyUnlockService::GetScreenlockStateHandler() {
454 if (!screenlock_state_handler_
) {
455 screenlock_state_handler_
.reset(new EasyUnlockScreenlockStateHandler(
458 ScreenlockBridge::Get()));
460 return screenlock_state_handler_
.get();
463 bool EasyUnlockService::UpdateScreenlockState(
464 EasyUnlockScreenlockStateHandler::State state
) {
465 EasyUnlockScreenlockStateHandler
* handler
= GetScreenlockStateHandler();
469 handler
->ChangeState(state
);
471 if (state
== EasyUnlockScreenlockStateHandler::STATE_AUTHENTICATED
) {
472 #if defined(OS_CHROMEOS)
474 power_monitor_
->RecordStartUpTime();
476 } else if (auth_attempt_
.get()) {
477 // Clean up existing auth attempt if we can no longer authenticate the
479 auth_attempt_
.reset();
481 if (!handler
->InStateValidOnRemoteAuthFailure())
482 HandleAuthFailure(GetUserEmail());
486 EasyUnlockServiceObserver
, observers_
, OnScreenlockStateChanged(state
));
490 EasyUnlockScreenlockStateHandler::State
491 EasyUnlockService::GetScreenlockState() {
492 EasyUnlockScreenlockStateHandler
* handler
= GetScreenlockStateHandler();
494 return EasyUnlockScreenlockStateHandler::STATE_INACTIVE
;
496 return handler
->state();
499 void EasyUnlockService::AttemptAuth(const std::string
& user_id
) {
500 AttemptAuth(user_id
, AttemptAuthCallback());
503 void EasyUnlockService::AttemptAuth(const std::string
& user_id
,
504 const AttemptAuthCallback
& callback
) {
505 CHECK_EQ(GetUserEmail(), user_id
);
507 auth_attempt_
.reset(new EasyUnlockAuthAttempt(
508 app_manager_
.get(), user_id
,
509 GetType() == TYPE_REGULAR
? EasyUnlockAuthAttempt::TYPE_UNLOCK
510 : EasyUnlockAuthAttempt::TYPE_SIGNIN
,
512 if (!auth_attempt_
->Start())
513 auth_attempt_
.reset();
516 void EasyUnlockService::FinalizeUnlock(bool success
) {
517 if (!auth_attempt_
.get())
520 this->OnWillFinalizeUnlock(success
);
521 auth_attempt_
->FinalizeUnlock(GetUserEmail(), success
);
522 auth_attempt_
.reset();
523 // TODO(isherman): If observing screen unlock events, is there a race
524 // condition in terms of reading the service's state vs. the app setting the
527 // Make sure that the lock screen is updated on failure.
529 RecordEasyUnlockScreenUnlockEvent(EASY_UNLOCK_FAILURE
);
530 HandleAuthFailure(GetUserEmail());
534 void EasyUnlockService::FinalizeSignin(const std::string
& key
) {
535 if (!auth_attempt_
.get())
537 std::string wrapped_secret
= GetWrappedSecret();
538 if (!wrapped_secret
.empty())
539 auth_attempt_
->FinalizeSignin(GetUserEmail(), wrapped_secret
, key
);
540 auth_attempt_
.reset();
542 // Processing empty key is equivalent to auth cancellation. In this case the
543 // signin request will not actually be processed by login stack, so the lock
544 // screen state should be set from here.
546 HandleAuthFailure(GetUserEmail());
549 void EasyUnlockService::HandleAuthFailure(const std::string
& user_id
) {
550 if (user_id
!= GetUserEmail())
553 if (!screenlock_state_handler_
.get())
556 screenlock_state_handler_
->SetHardlockState(
557 EasyUnlockScreenlockStateHandler::LOGIN_FAILED
);
560 void EasyUnlockService::CheckCryptohomeKeysAndMaybeHardlock() {
561 #if defined(OS_CHROMEOS)
562 std::string user_id
= GetUserEmail();
566 const base::ListValue
* device_list
= GetRemoteDevices();
567 std::set
<std::string
> paired_devices
;
569 chromeos::EasyUnlockDeviceKeyDataList parsed_paired
;
570 chromeos::EasyUnlockKeyManager::RemoteDeviceListToDeviceDataList(
571 *device_list
, &parsed_paired
);
572 for (const auto& device_key_data
: parsed_paired
)
573 paired_devices
.insert(device_key_data
.psk
);
575 if (paired_devices
.empty()) {
576 SetHardlockState(EasyUnlockScreenlockStateHandler::NO_PAIRING
);
580 // No need to compare if a change is already recorded.
581 if (GetHardlockState() == EasyUnlockScreenlockStateHandler::PAIRING_CHANGED
||
582 GetHardlockState() == EasyUnlockScreenlockStateHandler::PAIRING_ADDED
) {
586 chromeos::EasyUnlockKeyManager
* key_manager
=
587 chromeos::UserSessionManager::GetInstance()->GetEasyUnlockKeyManager();
590 key_manager
->GetDeviceDataList(
591 chromeos::UserContext(user_id
),
592 base::Bind(&EasyUnlockService::OnCryptohomeKeysFetchedForChecking
,
593 weak_ptr_factory_
.GetWeakPtr(),
599 void EasyUnlockService::SetTrialRun() {
600 DCHECK_EQ(GetType(), TYPE_REGULAR
);
602 EasyUnlockScreenlockStateHandler
* handler
= GetScreenlockStateHandler();
604 handler
->SetTrialRun();
607 void EasyUnlockService::RecordClickOnLockIcon() {
608 if (screenlock_state_handler_
)
609 screenlock_state_handler_
->RecordClickOnLockIcon();
612 void EasyUnlockService::AddObserver(EasyUnlockServiceObserver
* observer
) {
613 observers_
.AddObserver(observer
);
616 void EasyUnlockService::RemoveObserver(EasyUnlockServiceObserver
* observer
) {
617 observers_
.RemoveObserver(observer
);
620 void EasyUnlockService::Shutdown() {
627 ResetScreenlockState();
628 bluetooth_detector_
.reset();
629 #if defined(OS_CHROMEOS)
630 power_monitor_
.reset();
633 weak_ptr_factory_
.InvalidateWeakPtrs();
636 void EasyUnlockService::ReloadAppAndLockScreen() {
637 // Make sure lock screen state set by the extension gets reset.
638 ResetScreenlockState();
639 app_manager_
->ReloadApp();
643 void EasyUnlockService::UpdateAppState() {
645 EnsureTpmKeyPresentIfNeeded();
646 app_manager_
->LoadApp();
649 #if defined(OS_CHROMEOS)
651 power_monitor_
.reset(new PowerMonitor(this));
654 bool bluetooth_waking_up
= false;
655 #if defined(OS_CHROMEOS)
656 // If the service is not allowed due to bluetooth not being detected just
657 // after system suspend is done, give bluetooth more time to be detected
658 // before disabling the app (and resetting screenlock state).
659 bluetooth_waking_up
=
660 power_monitor_
.get() && power_monitor_
->waking_up() &&
661 !bluetooth_detector_
->IsPresent();
664 if (!bluetooth_waking_up
) {
665 app_manager_
->DisableAppIfLoaded();
666 ResetScreenlockState();
667 #if defined(OS_CHROMEOS)
668 power_monitor_
.reset();
674 void EasyUnlockService::DisableAppWithoutResettingScreenlockState() {
675 app_manager_
->DisableAppIfLoaded();
678 void EasyUnlockService::NotifyUserUpdated() {
679 std::string user_id
= GetUserEmail();
683 // Notify the easy unlock app that the user info changed.
684 bool logged_in
= GetType() == TYPE_REGULAR
;
685 bool data_ready
= logged_in
|| GetRemoteDevices() != NULL
;
686 app_manager_
->SendUserUpdatedEvent(user_id
, logged_in
, data_ready
);
689 void EasyUnlockService::NotifyTurnOffOperationStatusChanged() {
691 EasyUnlockServiceObserver
, observers_
, OnTurnOffOperationStatusChanged());
694 void EasyUnlockService::ResetScreenlockState() {
695 screenlock_state_handler_
.reset();
696 auth_attempt_
.reset();
699 void EasyUnlockService::SetScreenlockHardlockedState(
700 EasyUnlockScreenlockStateHandler::HardlockState state
) {
701 if (screenlock_state_handler_
)
702 screenlock_state_handler_
->SetHardlockState(state
);
703 if (state
!= EasyUnlockScreenlockStateHandler::NO_HARDLOCK
)
704 auth_attempt_
.reset();
707 void EasyUnlockService::InitializeOnAppManagerReady() {
708 CHECK(app_manager_
.get());
710 InitializeInternal();
711 bluetooth_detector_
->Initialize();
714 void EasyUnlockService::OnBluetoothAdapterPresentChanged() {
717 // Whether we've already passed Bluetooth availability information to UMA.
718 // This is static because there may be multiple instances and we want to
719 // report this system-level stat only once per run of Chrome.
720 static bool bluetooth_adapter_has_been_reported
= false;
722 if (!bluetooth_adapter_has_been_reported
) {
723 bluetooth_adapter_has_been_reported
= true;
724 int bttype
= BT_NO_ADAPTER
;
725 if (bluetooth_detector_
->IsPresent()) {
726 bttype
= BT_LOW_ENERGY_CAPABLE
;
728 if (base::win::GetVersion() < base::win::VERSION_WIN8
) {
733 UMA_HISTOGRAM_ENUMERATION(
734 "EasyUnlock.BluetoothAvailability", bttype
, BT_MAX_TYPE
);
738 void EasyUnlockService::SetHardlockStateForUser(
739 const std::string
& user_id
,
740 EasyUnlockScreenlockStateHandler::HardlockState state
) {
741 DCHECK(!user_id
.empty());
743 PrefService
* local_state
= GetLocalState();
747 DictionaryPrefUpdate
update(local_state
, prefs::kEasyUnlockHardlockState
);
748 update
->SetIntegerWithoutPathExpansion(user_id
, static_cast<int>(state
));
750 if (GetUserEmail() == user_id
)
751 SetScreenlockHardlockedState(state
);
754 EasyUnlockAuthEvent
EasyUnlockService::GetPasswordAuthEvent() const {
757 if (GetHardlockState() != EasyUnlockScreenlockStateHandler::NO_HARDLOCK
) {
758 switch (GetHardlockState()) {
759 case EasyUnlockScreenlockStateHandler::NO_HARDLOCK
:
761 return EASY_UNLOCK_AUTH_EVENT_COUNT
;
762 case EasyUnlockScreenlockStateHandler::NO_PAIRING
:
763 return PASSWORD_ENTRY_NO_PAIRING
;
764 case EasyUnlockScreenlockStateHandler::USER_HARDLOCK
:
765 return PASSWORD_ENTRY_USER_HARDLOCK
;
766 case EasyUnlockScreenlockStateHandler::PAIRING_CHANGED
:
767 return PASSWORD_ENTRY_PAIRING_CHANGED
;
768 case EasyUnlockScreenlockStateHandler::LOGIN_FAILED
:
769 return PASSWORD_ENTRY_LOGIN_FAILED
;
770 case EasyUnlockScreenlockStateHandler::PAIRING_ADDED
:
771 return PASSWORD_ENTRY_PAIRING_ADDED
;
773 } else if (!screenlock_state_handler()) {
774 return PASSWORD_ENTRY_NO_SCREENLOCK_STATE_HANDLER
;
776 switch (screenlock_state_handler()->state()) {
777 case EasyUnlockScreenlockStateHandler::STATE_INACTIVE
:
778 return PASSWORD_ENTRY_SERVICE_NOT_ACTIVE
;
779 case EasyUnlockScreenlockStateHandler::STATE_NO_BLUETOOTH
:
780 return PASSWORD_ENTRY_NO_BLUETOOTH
;
781 case EasyUnlockScreenlockStateHandler::STATE_BLUETOOTH_CONNECTING
:
782 return PASSWORD_ENTRY_BLUETOOTH_CONNECTING
;
783 case EasyUnlockScreenlockStateHandler::STATE_NO_PHONE
:
784 return PASSWORD_ENTRY_NO_PHONE
;
785 case EasyUnlockScreenlockStateHandler::STATE_PHONE_NOT_AUTHENTICATED
:
786 return PASSWORD_ENTRY_PHONE_NOT_AUTHENTICATED
;
787 case EasyUnlockScreenlockStateHandler::STATE_PHONE_LOCKED
:
788 return PASSWORD_ENTRY_PHONE_LOCKED
;
789 case EasyUnlockScreenlockStateHandler::STATE_PHONE_UNLOCKABLE
:
790 return PASSWORD_ENTRY_PHONE_NOT_LOCKABLE
;
791 case EasyUnlockScreenlockStateHandler::STATE_PHONE_UNSUPPORTED
:
792 return PASSWORD_ENTRY_PHONE_UNSUPPORTED
;
793 case EasyUnlockScreenlockStateHandler::STATE_RSSI_TOO_LOW
:
794 return PASSWORD_ENTRY_RSSI_TOO_LOW
;
795 case EasyUnlockScreenlockStateHandler::STATE_TX_POWER_TOO_HIGH
:
796 return PASSWORD_ENTRY_TX_POWER_TOO_HIGH
;
797 case EasyUnlockScreenlockStateHandler::
798 STATE_PHONE_LOCKED_AND_TX_POWER_TOO_HIGH
:
799 return PASSWORD_ENTRY_PHONE_LOCKED_AND_TX_POWER_TOO_HIGH
;
800 case EasyUnlockScreenlockStateHandler::STATE_AUTHENTICATED
:
801 return PASSWORD_ENTRY_WITH_AUTHENTICATED_PHONE
;
806 return EASY_UNLOCK_AUTH_EVENT_COUNT
;
809 #if defined(OS_CHROMEOS)
810 void EasyUnlockService::OnCryptohomeKeysFetchedForChecking(
811 const std::string
& user_id
,
812 const std::set
<std::string
> paired_devices
,
814 const chromeos::EasyUnlockDeviceKeyDataList
& key_data_list
) {
815 DCHECK(!user_id
.empty() && !paired_devices
.empty());
818 SetHardlockStateForUser(user_id
,
819 EasyUnlockScreenlockStateHandler::NO_PAIRING
);
823 std::set
<std::string
> devices_in_cryptohome
;
824 for (const auto& device_key_data
: key_data_list
)
825 devices_in_cryptohome
.insert(device_key_data
.psk
);
827 if (paired_devices
!= devices_in_cryptohome
||
828 GetHardlockState() == EasyUnlockScreenlockStateHandler::NO_PAIRING
) {
829 SetHardlockStateForUser(
831 devices_in_cryptohome
.empty()
832 ? EasyUnlockScreenlockStateHandler::PAIRING_ADDED
833 : EasyUnlockScreenlockStateHandler::PAIRING_CHANGED
);
838 void EasyUnlockService::PrepareForSuspend() {
839 app_manager_
->DisableAppIfLoaded();
840 if (screenlock_state_handler_
&& screenlock_state_handler_
->IsActive()) {
841 UpdateScreenlockState(
842 EasyUnlockScreenlockStateHandler::STATE_BLUETOOTH_CONNECTING
);
846 void EasyUnlockService::EnsureTpmKeyPresentIfNeeded() {
847 if (tpm_key_checked_
|| GetType() != TYPE_REGULAR
|| GetUserEmail().empty())
850 #if defined(OS_CHROMEOS)
851 // If this is called before the session is started, the chances are Chrome
852 // is restarting in order to apply user flags. Don't check TPM keys in this
854 if (!user_manager::UserManager::Get() ||
855 !user_manager::UserManager::Get()->IsSessionStarted())
858 // TODO(tbarzic): Set check_private_key only if previous sign-in attempt
860 EasyUnlockTpmKeyManagerFactory::GetInstance()->Get(profile_
)
861 ->PrepareTpmKey(true /* check_private_key */,
863 #endif // defined(OS_CHROMEOS)
865 tpm_key_checked_
= true;