Commit dfdb8997 authored by Sarah Hu's avatar Sarah Hu Committed by Commit Bot

cros: Hide fingerprint view in the lock screen when user is forced to

use password/PIN to unlock.

Bug: 879297
Change-Id: Ia4518584977f24af1b7f7f2a849d1dc598e5fc95
Reviewed-on: https://chromium-review.googlesource.com/1211804Reviewed-by: default avatarJacob Dufault <jdufault@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Commit-Queue: Xiaoyin Hu <xiaoyinh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#594490}
parent c38fa0f4
...@@ -1294,7 +1294,9 @@ void LockContentsView::LayoutAuth(LoginBigUserView* to_update, ...@@ -1294,7 +1294,9 @@ void LockContentsView::LayoutAuth(LoginBigUserView* to_update,
if (state->enable_tap_auth) if (state->enable_tap_auth)
to_update_auth |= LoginAuthUserView::AUTH_TAP; to_update_auth |= LoginAuthUserView::AUTH_TAP;
if (state->fingerprint_state != if (state->fingerprint_state !=
mojom::FingerprintUnlockState::UNAVAILABLE) { mojom::FingerprintUnlockState::UNAVAILABLE &&
state->fingerprint_state !=
mojom::FingerprintUnlockState::AUTH_DISABLED_FROM_TIMEOUT) {
to_update_auth |= LoginAuthUserView::AUTH_FINGERPRINT; to_update_auth |= LoginAuthUserView::AUTH_FINGERPRINT;
} }
......
...@@ -335,6 +335,8 @@ class LockDebugView::DebugDataDispatcherTransformer ...@@ -335,6 +335,8 @@ class LockDebugView::DebugDataDispatcherTransformer
case mojom::FingerprintUnlockState::AUTH_FAILED: case mojom::FingerprintUnlockState::AUTH_FAILED:
return mojom::FingerprintUnlockState::AUTH_DISABLED; return mojom::FingerprintUnlockState::AUTH_DISABLED;
case mojom::FingerprintUnlockState::AUTH_DISABLED: case mojom::FingerprintUnlockState::AUTH_DISABLED:
return mojom::FingerprintUnlockState::AUTH_DISABLED_FROM_TIMEOUT;
case mojom::FingerprintUnlockState::AUTH_DISABLED_FROM_TIMEOUT:
return mojom::FingerprintUnlockState::UNAVAILABLE; return mojom::FingerprintUnlockState::UNAVAILABLE;
} }
}; };
......
...@@ -96,8 +96,8 @@ constexpr int kDisabledAuthMessageRoundedCornerRadiusDp = 8; ...@@ -96,8 +96,8 @@ constexpr int kDisabledAuthMessageRoundedCornerRadiusDp = 8;
constexpr int kNonEmptyWidthDp = 1; constexpr int kNonEmptyWidthDp = 1;
// Returns an observer that will hide |view| when it fires. The observer will // Returns an observer that will hide |view| when it fires. The observer will
// delete itself after firing. Make sure to call |observer->SetReady()| after // delete itself after firing (by returning true). Make sure to call
// attaching it. // |observer->SetActive()| after attaching it.
ui::CallbackLayerAnimationObserver* BuildObserverToHideView(views::View* view) { ui::CallbackLayerAnimationObserver* BuildObserverToHideView(views::View* view) {
return new ui::CallbackLayerAnimationObserver(base::Bind( return new ui::CallbackLayerAnimationObserver(base::Bind(
[](views::View* view, [](views::View* view,
...@@ -187,6 +187,7 @@ class LoginAuthUserView::FingerprintView : public views::View { ...@@ -187,6 +187,7 @@ class LoginAuthUserView::FingerprintView : public views::View {
case mojom::FingerprintUnlockState::UNAVAILABLE: case mojom::FingerprintUnlockState::UNAVAILABLE:
case mojom::FingerprintUnlockState::AVAILABLE: case mojom::FingerprintUnlockState::AVAILABLE:
case mojom::FingerprintUnlockState::AUTH_SUCCESS: case mojom::FingerprintUnlockState::AUTH_SUCCESS:
case mojom::FingerprintUnlockState::AUTH_DISABLED_FROM_TIMEOUT:
icon_->SetImage(gfx::CreateVectorIcon( icon_->SetImage(gfx::CreateVectorIcon(
kLockScreenFingerprintIcon, kFingerprintIconSizeDp, SK_ColorWHITE)); kLockScreenFingerprintIcon, kFingerprintIconSizeDp, SK_ColorWHITE));
return; return;
...@@ -210,6 +211,7 @@ class LoginAuthUserView::FingerprintView : public views::View { ...@@ -210,6 +211,7 @@ class LoginAuthUserView::FingerprintView : public views::View {
case mojom::FingerprintUnlockState::UNAVAILABLE: case mojom::FingerprintUnlockState::UNAVAILABLE:
case mojom::FingerprintUnlockState::AVAILABLE: case mojom::FingerprintUnlockState::AVAILABLE:
case mojom::FingerprintUnlockState::AUTH_SUCCESS: case mojom::FingerprintUnlockState::AUTH_SUCCESS:
case mojom::FingerprintUnlockState::AUTH_DISABLED_FROM_TIMEOUT:
return IDS_ASH_LOGIN_FINGERPRINT_UNLOCK_MESSAGE; return IDS_ASH_LOGIN_FINGERPRINT_UNLOCK_MESSAGE;
case mojom::FingerprintUnlockState::AUTH_FAILED: case mojom::FingerprintUnlockState::AUTH_FAILED:
return IDS_ASH_LOGIN_FINGERPRINT_UNLOCK_FAILED_MESSAGE; return IDS_ASH_LOGIN_FINGERPRINT_UNLOCK_FAILED_MESSAGE;
...@@ -226,7 +228,9 @@ class LoginAuthUserView::FingerprintView : public views::View { ...@@ -226,7 +228,9 @@ class LoginAuthUserView::FingerprintView : public views::View {
return; return;
state_ = state; state_ = state;
SetVisible(state != mojom::FingerprintUnlockState::UNAVAILABLE); SetVisible(state != mojom::FingerprintUnlockState::UNAVAILABLE &&
state !=
mojom::FingerprintUnlockState::AUTH_DISABLED_FROM_TIMEOUT);
SetIcon(state); SetIcon(state);
SetText(state); SetText(state);
...@@ -590,6 +594,17 @@ void LoginAuthUserView::SetEasyUnlockIcon( ...@@ -590,6 +594,17 @@ void LoginAuthUserView::SetEasyUnlockIcon(
} }
void LoginAuthUserView::CaptureStateForAnimationPreLayout() { void LoginAuthUserView::CaptureStateForAnimationPreLayout() {
auto stop_animation = [](views::View* view) {
if (view->layer()->GetAnimator()->is_animating())
view->layer()->GetAnimator()->StopAnimating();
};
// Stop any running animation scheduled in ApplyAnimationPostLayout.
stop_animation(this);
stop_animation(password_view_);
stop_animation(pin_view_);
stop_animation(fingerprint_view_);
DCHECK(!cached_animation_state_); DCHECK(!cached_animation_state_);
cached_animation_state_ = std::make_unique<AnimationState>(this); cached_animation_state_ = std::make_unique<AnimationState>(this);
} }
...@@ -597,11 +612,6 @@ void LoginAuthUserView::CaptureStateForAnimationPreLayout() { ...@@ -597,11 +612,6 @@ void LoginAuthUserView::CaptureStateForAnimationPreLayout() {
void LoginAuthUserView::ApplyAnimationPostLayout() { void LoginAuthUserView::ApplyAnimationPostLayout() {
DCHECK(cached_animation_state_); DCHECK(cached_animation_state_);
// Cancel any running animations.
pin_view_->layer()->GetAnimator()->AbortAllAnimations();
password_view_->layer()->GetAnimator()->AbortAllAnimations();
layer()->GetAnimator()->AbortAllAnimations();
bool has_password = (auth_methods() & AUTH_PASSWORD) != 0; bool has_password = (auth_methods() & AUTH_PASSWORD) != 0;
bool has_pin = (auth_methods() & AUTH_PIN) != 0; bool has_pin = (auth_methods() & AUTH_PIN) != 0;
bool has_fingerprint = (auth_methods() & AUTH_FINGERPRINT) != 0; bool has_fingerprint = (auth_methods() & AUTH_FINGERPRINT) != 0;
...@@ -700,7 +710,7 @@ void LoginAuthUserView::ApplyAnimationPostLayout() { ...@@ -700,7 +710,7 @@ void LoginAuthUserView::ApplyAnimationPostLayout() {
{ {
ui::ScopedLayerAnimationSettings settings( ui::ScopedLayerAnimationSettings settings(
password_view_->layer()->GetAnimator()); fingerprint_view_->layer()->GetAnimator());
settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds( settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(
login_constants::kChangeUserAnimationDurationMs)); login_constants::kChangeUserAnimationDurationMs));
settings.SetTweenType(gfx::Tween::Type::FAST_OUT_SLOW_IN); settings.SetTweenType(gfx::Tween::Type::FAST_OUT_SLOW_IN);
......
...@@ -54,6 +54,10 @@ enum FingerprintUnlockState { ...@@ -54,6 +54,10 @@ enum FingerprintUnlockState {
// recognized. There have been too many unlock attempts and fingerprint // recognized. There have been too many unlock attempts and fingerprint
// is now disabled. // is now disabled.
AUTH_DISABLED, AUTH_DISABLED,
// Fingerprint unlock is disabled because user is forced to use an
// authentication method that authenticates via cryptohome.
// I.e., password, cryptohome-based PIN, easy unlock.
AUTH_DISABLED_FROM_TIMEOUT,
}; };
// Information about the custom icon in the user pod. // Information about the custom icon in the user pod.
......
...@@ -395,6 +395,15 @@ void ScreenLocker::Authenticate(const UserContext& user_context, ...@@ -395,6 +395,15 @@ void ScreenLocker::Authenticate(const UserContext& user_context,
void ScreenLocker::OnPinAttemptDone(const UserContext& user_context, void ScreenLocker::OnPinAttemptDone(const UserContext& user_context,
bool success) { bool success) {
if (success) { if (success) {
// Mark strong auth if this is cryptohome based pin.
if (quick_unlock::PinBackend::GetInstance()->ShouldUseCryptohome(
user_context.GetAccountId())) {
quick_unlock::QuickUnlockStorage* quick_unlock_storage =
quick_unlock::QuickUnlockFactory::GetForAccountId(
user_context.GetAccountId());
if (quick_unlock_storage)
quick_unlock_storage->MarkStrongAuth();
}
OnAuthSuccess(user_context); OnAuthSuccess(user_context);
} else { } else {
// PIN authentication has failed; try submitting as a normal password. // PIN authentication has failed; try submitting as a normal password.
...@@ -672,6 +681,10 @@ void ScreenLocker::ScreenLockReady() { ...@@ -672,6 +681,10 @@ void ScreenLocker::ScreenLockReady() {
} else { } else {
VLOG(1) << "Fingerprint is not available on lock screen"; VLOG(1) << "Fingerprint is not available on lock screen";
} }
UpdateFingerprintState(
"ScreenLockReady",
user_manager::UserManager::Get()->GetPrimaryUser()->GetAccountId());
} }
bool ScreenLocker::IsUserLoggedIn(const AccountId& account_id) const { bool ScreenLocker::IsUserLoggedIn(const AccountId& account_id) const {
...@@ -756,4 +769,46 @@ void ScreenLocker::OnFingerprintAuthFailure(const user_manager::User& user) { ...@@ -756,4 +769,46 @@ void ScreenLocker::OnFingerprintAuthFailure(const user_manager::User& user) {
} }
} }
void ScreenLocker::UpdateFingerprintState(const std::string& source,
const AccountId& account_id) {
VLOG(1) << "Updating fingerprint state (source=" << source << ")";
update_fingerprint_state_timer_.Stop();
quick_unlock::QuickUnlockStorage* quick_unlock_storage =
quick_unlock::QuickUnlockFactory::GetForAccountId(account_id);
// If strong auth is required, disable fingerprint.
if (quick_unlock_storage && !quick_unlock_storage->HasStrongAuth() &&
quick_unlock_storage->fingerprint_storage()->IsFingerprintAvailable()) {
VLOG(1) << "Require strong auth to make fingerprint unlock available.";
delegate_->SetFingerprintState(account_id, FingerprintState::kTimeout);
// Prefs based pin will be unavailable when strong auth is required.
quick_unlock::PinBackend::GetInstance()->CanAuthenticate(
account_id, base::BindOnce(&ScreenLocker::OnPinCanAuthenticate,
weak_factory_.GetWeakPtr(), account_id));
return;
}
// If fingerprint is available, call this function again when strong auth
// will expire.
if (quick_unlock_storage &&
quick_unlock_storage->IsFingerprintAuthenticationAvailable()) {
const base::TimeDelta next_strong_auth =
quick_unlock_storage->TimeUntilNextStrongAuth();
VLOG(1) << "Scheduling next fingerprint state update in "
<< next_strong_auth;
update_fingerprint_state_timer_.Start(
FROM_HERE, next_strong_auth,
base::BindOnce(&ScreenLocker::UpdateFingerprintState,
base::Unretained(this),
"update_fingerprint_state_timer_", account_id));
}
}
void ScreenLocker::OnPinCanAuthenticate(const AccountId& account_id,
bool can_authenticate) {
LoginScreenClient::Get()->login_screen()->SetPinEnabledForUser(
account_id, can_authenticate);
}
} // namespace chromeos } // namespace chromeos
...@@ -55,6 +55,7 @@ class ScreenLocker : public AuthStatusConsumer, ...@@ -55,6 +55,7 @@ class ScreenLocker : public AuthStatusConsumer,
kSignin, kSignin,
kFailed, kFailed,
kRemoved, kRemoved,
kTimeout,
}; };
// Delegate used to send internal state changes back to the UI. // Delegate used to send internal state changes back to the UI.
...@@ -242,6 +243,11 @@ class ScreenLocker : public AuthStatusConsumer, ...@@ -242,6 +243,11 @@ class ScreenLocker : public AuthStatusConsumer,
// check has completed. // check has completed.
void ContinueAuthenticate(const UserContext& user_context); void ContinueAuthenticate(const UserContext& user_context);
void UpdateFingerprintState(const std::string& source,
const AccountId& account_id);
void OnPinCanAuthenticate(const AccountId& account_id, bool can_authenticate);
// WebUIScreenLocker instance in use. // WebUIScreenLocker instance in use.
std::unique_ptr<WebUIScreenLocker> web_ui_; std::unique_ptr<WebUIScreenLocker> web_ui_;
...@@ -300,6 +306,10 @@ class ScreenLocker : public AuthStatusConsumer, ...@@ -300,6 +306,10 @@ class ScreenLocker : public AuthStatusConsumer,
// ViewsScreenLocker instance in use. // ViewsScreenLocker instance in use.
std::unique_ptr<ViewsScreenLocker> views_screen_locker_; std::unique_ptr<ViewsScreenLocker> views_screen_locker_;
// Password is required every 24 hours in order to use fingerprint unlock.
// This is used to update fingerprint state when password is required.
base::OneShotTimer update_fingerprint_state_timer_;
base::WeakPtrFactory<ScreenLocker> weak_factory_; base::WeakPtrFactory<ScreenLocker> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(ScreenLocker); DISALLOW_COPY_AND_ASSIGN(ScreenLocker);
......
...@@ -52,6 +52,8 @@ ash::mojom::FingerprintUnlockState ConvertFromFingerprintState( ...@@ -52,6 +52,8 @@ ash::mojom::FingerprintUnlockState ConvertFromFingerprintState(
return ash::mojom::FingerprintUnlockState::AUTH_FAILED; return ash::mojom::FingerprintUnlockState::AUTH_FAILED;
case ScreenLocker::FingerprintState::kRemoved: case ScreenLocker::FingerprintState::kRemoved:
return ash::mojom::FingerprintUnlockState::AUTH_DISABLED; return ash::mojom::FingerprintUnlockState::AUTH_DISABLED;
case ScreenLocker::FingerprintState::kTimeout:
return ash::mojom::FingerprintUnlockState::AUTH_DISABLED_FROM_TIMEOUT;
} }
} }
......
...@@ -22,7 +22,7 @@ FingerprintStorage::FingerprintStorage(PrefService* pref_service) ...@@ -22,7 +22,7 @@ FingerprintStorage::FingerprintStorage(PrefService* pref_service)
FingerprintStorage::~FingerprintStorage() {} FingerprintStorage::~FingerprintStorage() {}
bool FingerprintStorage::IsFingerprintAuthenticationAvailable() const { bool FingerprintStorage::IsFingerprintAvailable() const {
return !ExceededUnlockAttempts() && IsFingerprintEnabled() && HasRecord(); return !ExceededUnlockAttempts() && IsFingerprintEnabled() && HasRecord();
} }
......
...@@ -28,6 +28,10 @@ class FingerprintStorage { ...@@ -28,6 +28,10 @@ class FingerprintStorage {
explicit FingerprintStorage(PrefService* pref_service); explicit FingerprintStorage(PrefService* pref_service);
~FingerprintStorage(); ~FingerprintStorage();
// Returns true if fingerprint unlock is currently available.
// This does not check if strong auth is available.
bool IsFingerprintAvailable() const;
// Returns true if the user has fingerprint record registered. // Returns true if the user has fingerprint record registered.
bool HasRecord() const; bool HasRecord() const;
...@@ -46,9 +50,6 @@ class FingerprintStorage { ...@@ -46,9 +50,6 @@ class FingerprintStorage {
friend class chromeos::FingerprintStorageTestApi; friend class chromeos::FingerprintStorageTestApi;
friend class QuickUnlockStorage; friend class QuickUnlockStorage;
// Returns true if fingerprint unlock is currently available.
bool IsFingerprintAuthenticationAvailable() const;
PrefService* pref_service_; PrefService* pref_service_;
// Number of fingerprint unlock attempt. // Number of fingerprint unlock attempt.
int unlock_attempt_count_ = 0; int unlock_attempt_count_ = 0;
......
...@@ -46,8 +46,8 @@ class FingerprintStorageTestApi { ...@@ -46,8 +46,8 @@ class FingerprintStorageTestApi {
quick_unlock::FingerprintStorage* fingerprint_storage) quick_unlock::FingerprintStorage* fingerprint_storage)
: fingerprint_storage_(fingerprint_storage) {} : fingerprint_storage_(fingerprint_storage) {}
bool IsFingerprintAuthenticationAvailable() const { bool IsFingerprintAvailable() const {
return fingerprint_storage_->IsFingerprintAuthenticationAvailable(); return fingerprint_storage_->IsFingerprintAvailable();
} }
private: private:
...@@ -90,14 +90,14 @@ TEST_F(FingerprintStorageUnitTest, AuthenticationUnAvailable) { ...@@ -90,14 +90,14 @@ TEST_F(FingerprintStorageUnitTest, AuthenticationUnAvailable) {
EXPECT_TRUE(fingerprint_storage->HasRecord()); EXPECT_TRUE(fingerprint_storage->HasRecord());
EXPECT_EQ(0, fingerprint_storage->unlock_attempt_count()); EXPECT_EQ(0, fingerprint_storage->unlock_attempt_count());
EXPECT_TRUE(test_api.IsFingerprintAuthenticationAvailable()); EXPECT_TRUE(test_api.IsFingerprintAvailable());
// No fingerprint records registered makes fingerprint authentication // No fingerprint records registered makes fingerprint authentication
// unavailable. // unavailable.
SetRecords(0); SetRecords(0);
EXPECT_FALSE(test_api.IsFingerprintAuthenticationAvailable()); EXPECT_FALSE(test_api.IsFingerprintAvailable());
SetRecords(1); SetRecords(1);
EXPECT_TRUE(test_api.IsFingerprintAuthenticationAvailable()); EXPECT_TRUE(test_api.IsFingerprintAvailable());
// Too many authentication attempts make fingerprint authentication // Too many authentication attempts make fingerprint authentication
// unavailable. // unavailable.
...@@ -105,9 +105,9 @@ TEST_F(FingerprintStorageUnitTest, AuthenticationUnAvailable) { ...@@ -105,9 +105,9 @@ TEST_F(FingerprintStorageUnitTest, AuthenticationUnAvailable) {
++i) { ++i) {
fingerprint_storage->AddUnlockAttempt(); fingerprint_storage->AddUnlockAttempt();
} }
EXPECT_FALSE(test_api.IsFingerprintAuthenticationAvailable()); EXPECT_FALSE(test_api.IsFingerprintAvailable());
fingerprint_storage->ResetUnlockAttemptCount(); fingerprint_storage->ResetUnlockAttemptCount();
EXPECT_TRUE(test_api.IsFingerprintAuthenticationAvailable()); EXPECT_TRUE(test_api.IsFingerprintAvailable());
} }
} // namespace chromeos } // namespace chromeos
...@@ -258,6 +258,17 @@ void PinBackend::TryAuthenticate(const AccountId& account_id, ...@@ -258,6 +258,17 @@ void PinBackend::TryAuthenticate(const AccountId& account_id,
} }
} }
bool PinBackend::ShouldUseCryptohome(const AccountId& account_id) {
if (!cryptohome_backend_)
return false;
// Even if cryptohome is supported, the user may have registered a PIN with
// the prefs backend from a previous version. If that's the case, we should
// talk to the prefs backend instead of the cryptohome backend.
QuickUnlockStorage* storage = GetPrefsBackend(account_id);
return !storage || !storage->pin_storage_prefs()->IsPinSet();
}
void PinBackend::OnIsCryptohomeBackendSupported(bool is_supported) { void PinBackend::OnIsCryptohomeBackendSupported(bool is_supported) {
if (is_supported) if (is_supported)
cryptohome_backend_ = std::make_unique<PinStorageCryptohome>(); cryptohome_backend_ = std::make_unique<PinStorageCryptohome>();
...@@ -276,16 +287,5 @@ void PinBackend::OnPinMigrationAttemptComplete(Profile* profile, bool success) { ...@@ -276,16 +287,5 @@ void PinBackend::OnPinMigrationAttemptComplete(Profile* profile, bool success) {
scoped_keep_alive_.reset(); scoped_keep_alive_.reset();
} }
bool PinBackend::ShouldUseCryptohome(const AccountId& account_id) {
if (!cryptohome_backend_)
return false;
// Even if cryptohome is supported, the user may have registered a PIN with
// the prefs backend from a previous version. If that's the case, we should
// talk to the prefs backend instead of the cryptohome backend.
QuickUnlockStorage* storage = GetPrefsBackend(account_id);
return !storage || !storage->pin_storage_prefs()->IsPinSet();
}
} // namespace quick_unlock } // namespace quick_unlock
} // namespace chromeos } // namespace chromeos
...@@ -72,6 +72,11 @@ class PinBackend { ...@@ -72,6 +72,11 @@ class PinBackend {
const Key& key, const Key& key,
BoolCallback result); BoolCallback result);
// Returns true if the cryptohome backend should be used. Sometimes the prefs
// backend should be used even when cryptohome is available, ie, when there is
// an non-migrated PIN key.
bool ShouldUseCryptohome(const AccountId& account_id);
// Resets any cached state for testing purposes. // Resets any cached state for testing purposes.
static void ResetForTesting(); static void ResetForTesting();
...@@ -83,11 +88,6 @@ class PinBackend { ...@@ -83,11 +88,6 @@ class PinBackend {
// should be cleared from prefs. // should be cleared from prefs.
void OnPinMigrationAttemptComplete(Profile* profile, bool success); void OnPinMigrationAttemptComplete(Profile* profile, bool success);
// Returns true if the cryptohome backend should be used. Sometimes the prefs
// backend should be used even when cryptohome is available, ie, when there is
// an non-migrated PIN key.
bool ShouldUseCryptohome(const AccountId& account_id);
// True if still trying to determine which backend should be used. // True if still trying to determine which backend should be used.
bool resolving_backend_ = true; bool resolving_backend_ = true;
// Determining if the device supports cryptohome-based keys requires an async // Determining if the device supports cryptohome-based keys requires an async
......
...@@ -14,6 +14,17 @@ ...@@ -14,6 +14,17 @@
namespace chromeos { namespace chromeos {
namespace quick_unlock { namespace quick_unlock {
namespace {
base::TimeDelta GetStrongAuthTimeout(PrefService* pref_service) {
PasswordConfirmationFrequency strong_auth_interval =
static_cast<PasswordConfirmationFrequency>(
pref_service->GetInteger(prefs::kQuickUnlockTimeout));
return PasswordConfirmationFrequencyToTimeDelta(strong_auth_interval);
}
} // namespace
QuickUnlockStorage::QuickUnlockStorage(PrefService* pref_service) QuickUnlockStorage::QuickUnlockStorage(PrefService* pref_service)
: pref_service_(pref_service) { : pref_service_(pref_service) {
fingerprint_storage_ = std::make_unique<FingerprintStorage>(pref_service); fingerprint_storage_ = std::make_unique<FingerprintStorage>(pref_service);
...@@ -31,15 +42,7 @@ void QuickUnlockStorage::MarkStrongAuth() { ...@@ -31,15 +42,7 @@ void QuickUnlockStorage::MarkStrongAuth() {
bool QuickUnlockStorage::HasStrongAuth() const { bool QuickUnlockStorage::HasStrongAuth() const {
if (last_strong_auth_.is_null()) if (last_strong_auth_.is_null())
return false; return false;
return TimeSinceLastStrongAuth() < GetStrongAuthTimeout(pref_service_);
// PIN and fingerprint share the same timeout policy.
PasswordConfirmationFrequency strong_auth_interval =
static_cast<PasswordConfirmationFrequency>(
pref_service_->GetInteger(prefs::kQuickUnlockTimeout));
base::TimeDelta strong_auth_timeout =
PasswordConfirmationFrequencyToTimeDelta(strong_auth_interval);
return TimeSinceLastStrongAuth() < strong_auth_timeout;
} }
base::TimeDelta QuickUnlockStorage::TimeSinceLastStrongAuth() const { base::TimeDelta QuickUnlockStorage::TimeSinceLastStrongAuth() const {
...@@ -47,9 +50,13 @@ base::TimeDelta QuickUnlockStorage::TimeSinceLastStrongAuth() const { ...@@ -47,9 +50,13 @@ base::TimeDelta QuickUnlockStorage::TimeSinceLastStrongAuth() const {
return base::TimeTicks::Now() - last_strong_auth_; return base::TimeTicks::Now() - last_strong_auth_;
} }
base::TimeDelta QuickUnlockStorage::TimeUntilNextStrongAuth() const {
DCHECK(!last_strong_auth_.is_null());
return GetStrongAuthTimeout(pref_service_) - TimeSinceLastStrongAuth();
}
bool QuickUnlockStorage::IsFingerprintAuthenticationAvailable() const { bool QuickUnlockStorage::IsFingerprintAuthenticationAvailable() const {
return HasStrongAuth() && return HasStrongAuth() && fingerprint_storage_->IsFingerprintAvailable();
fingerprint_storage_->IsFingerprintAuthenticationAvailable();
} }
bool QuickUnlockStorage::IsPinAuthenticationAvailable() const { bool QuickUnlockStorage::IsPinAuthenticationAvailable() const {
......
...@@ -44,7 +44,12 @@ class QuickUnlockStorage : public KeyedService { ...@@ -44,7 +44,12 @@ class QuickUnlockStorage : public KeyedService {
// called if HasStrongAuth returns false. // called if HasStrongAuth returns false.
base::TimeDelta TimeSinceLastStrongAuth() const; base::TimeDelta TimeSinceLastStrongAuth() const;
// Returns the time until next strong authentication required. This should
// not be called if HasStrongAuth returns false.
base::TimeDelta TimeUntilNextStrongAuth() const;
// Returns true if fingerprint unlock is currently available. // Returns true if fingerprint unlock is currently available.
// This checks whether there's fingerprint setup, as well as HasStrongAuth.
bool IsFingerprintAuthenticationAvailable() const; bool IsFingerprintAuthenticationAvailable() const;
// Returns true if PIN unlock is currently available. // Returns true if PIN unlock is currently available.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment