Commit 75708f29 authored by Yicheng Li's avatar Yicheng Li Committed by Commit Bot

ash: Start/end fingerprint auth session in in-session auth dialog

If fingerprint auth is supported, the in-session auth dialog needs
to explicitly start fingerprint auth session (so that biometrics
daemon can get prepared for the upcoming fingerprint scans), and
explicitly end fingerprint auth session when no more retries are
expected.

Bug: b:156258540, b:144861739
Change-Id: I7534594a696bd42f6f29fdc85fe8548b5cf8caae
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2369336
Commit-Queue: Yicheng Li <yichengli@chromium.org>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#801153}
parent d2321e75
...@@ -42,6 +42,8 @@ class AuthDialogContentsView : public views::View, ...@@ -42,6 +42,8 @@ class AuthDialogContentsView : public views::View,
// views::ButtonListener: // views::ButtonListener:
void ButtonPressed(views::Button* sender, const ui::Event& event) override; void ButtonPressed(views::Button* sender, const ui::Event& event) override;
uint32_t auth_methods() const { return auth_methods_; }
private: private:
class FingerprintView; class FingerprintView;
......
...@@ -57,11 +57,11 @@ std::unique_ptr<views::Widget> CreateAuthDialogWidget(aura::Window* parent) { ...@@ -57,11 +57,11 @@ std::unique_ptr<views::Widget> CreateAuthDialogWidget(aura::Window* parent) {
InSessionAuthDialog::InSessionAuthDialog(uint32_t auth_methods) { InSessionAuthDialog::InSessionAuthDialog(uint32_t auth_methods) {
widget_ = CreateAuthDialogWidget(nullptr); widget_ = CreateAuthDialogWidget(nullptr);
auto* contents_view = widget_->SetContentsView( contents_view_ = widget_->SetContentsView(
std::make_unique<AuthDialogContentsView>(auth_methods)); std::make_unique<AuthDialogContentsView>(auth_methods));
gfx::Rect bound = widget_->GetWindowBoundsInScreen(); gfx::Rect bound = widget_->GetWindowBoundsInScreen();
// Calculate initial height based on which child views are shown. // Calculate initial height based on which child views are shown.
bound.set_height(contents_view->GetPreferredSize().height()); bound.set_height(contents_view_->GetPreferredSize().height());
widget_->SetBounds(bound); widget_->SetBounds(bound);
widget_->Show(); widget_->Show();
...@@ -69,4 +69,9 @@ InSessionAuthDialog::InSessionAuthDialog(uint32_t auth_methods) { ...@@ -69,4 +69,9 @@ InSessionAuthDialog::InSessionAuthDialog(uint32_t auth_methods) {
InSessionAuthDialog::~InSessionAuthDialog() = default; InSessionAuthDialog::~InSessionAuthDialog() = default;
uint32_t InSessionAuthDialog::GetAuthMethods() const {
DCHECK(contents_view_);
return contents_view_->auth_methods();
}
} // namespace ash } // namespace ash
...@@ -15,6 +15,8 @@ class Widget; ...@@ -15,6 +15,8 @@ class Widget;
namespace ash { namespace ash {
class AuthDialogContentsView;
// InSessionAuthDialog gets instantiated on every request to show // InSessionAuthDialog gets instantiated on every request to show
// an authentication dialog, and gets destroyed when the request is // an authentication dialog, and gets destroyed when the request is
// completed. // completed.
...@@ -29,10 +31,16 @@ class InSessionAuthDialog { ...@@ -29,10 +31,16 @@ class InSessionAuthDialog {
bool is_shown() const { return !!widget_; } bool is_shown() const { return !!widget_; }
uint32_t GetAuthMethods() const;
private: private:
// The dialog widget. Owned by this class so that we can close the widget // The dialog widget. Owned by this class so that we can close the widget
// when auth completes. // when auth completes.
std::unique_ptr<views::Widget> widget_; std::unique_ptr<views::Widget> widget_;
// Pointer to the contents view. Used to query and update the set of available
// auth methods.
AuthDialogContentsView* contents_view_ = nullptr;
}; };
} // namespace ash } // namespace ash
......
...@@ -38,7 +38,27 @@ void InSessionAuthDialogControllerImpl::ShowAuthenticationDialog( ...@@ -38,7 +38,27 @@ void InSessionAuthDialogControllerImpl::ShowAuthenticationDialog(
// Password should always be available. // Password should always be available.
uint32_t auth_methods = AuthDialogContentsView::kAuthPassword; uint32_t auth_methods = AuthDialogContentsView::kAuthPassword;
if (client_->IsFingerprintAuthAvailable(account_id)) if (client_->IsFingerprintAuthAvailable(account_id)) {
client_->StartFingerprintAuthSession(
account_id,
base::BindOnce(
&InSessionAuthDialogControllerImpl::OnStartFingerprintAuthSession,
weak_factory_.GetWeakPtr(), account_id, auth_methods));
// OnStartFingerprintAuthSession checks PIN availability.
return;
}
client_->CheckPinAuthAvailability(
account_id,
base::BindOnce(&InSessionAuthDialogControllerImpl::OnPinCanAuthenticate,
weak_factory_.GetWeakPtr(), auth_methods));
}
void InSessionAuthDialogControllerImpl::OnStartFingerprintAuthSession(
AccountId account_id,
uint32_t auth_methods,
bool success) {
if (success)
auth_methods |= AuthDialogContentsView::kAuthFingerprint; auth_methods |= AuthDialogContentsView::kAuthFingerprint;
client_->CheckPinAuthAvailability( client_->CheckPinAuthAvailability(
...@@ -57,6 +77,13 @@ void InSessionAuthDialogControllerImpl::OnPinCanAuthenticate( ...@@ -57,6 +77,13 @@ void InSessionAuthDialogControllerImpl::OnPinCanAuthenticate(
} }
void InSessionAuthDialogControllerImpl::DestroyAuthenticationDialog() { void InSessionAuthDialogControllerImpl::DestroyAuthenticationDialog() {
DCHECK(client_);
if (!dialog_)
return;
if (dialog_->GetAuthMethods() & AuthDialogContentsView::kAuthFingerprint)
client_->EndFingerprintAuthSession();
dialog_.reset(); dialog_.reset();
} }
......
...@@ -40,6 +40,9 @@ class InSessionAuthDialogControllerImpl : public InSessionAuthDialogController { ...@@ -40,6 +40,9 @@ class InSessionAuthDialogControllerImpl : public InSessionAuthDialogController {
private: private:
bool IsFingerprintAvailable(const AccountId& account_id); bool IsFingerprintAvailable(const AccountId& account_id);
void OnStartFingerprintAuthSession(AccountId account_id,
uint32_t auth_methods,
bool success);
void OnPinCanAuthenticate(uint32_t auth_methods, bool pin_auth_available); void OnPinCanAuthenticate(uint32_t auth_methods, bool pin_auth_available);
// Callback to execute when auth on ChromeOS side completes. // Callback to execute when auth on ChromeOS side completes.
......
...@@ -32,6 +32,14 @@ class MockInSessionAuthDialogClient : public InSessionAuthDialogClient { ...@@ -32,6 +32,14 @@ class MockInSessionAuthDialogClient : public InSessionAuthDialogClient {
(const AccountId& account_id), (const AccountId& account_id),
(override)); (override));
MOCK_METHOD(void,
StartFingerprintAuthSession,
(const AccountId& account_id,
base::OnceCallback<void(bool)> callback),
(override));
MOCK_METHOD(void, EndFingerprintAuthSession, (), (override));
MOCK_METHOD(void, MOCK_METHOD(void,
CheckPinAuthAvailability, CheckPinAuthAvailability,
(const AccountId& account_id, (const AccountId& account_id,
......
...@@ -29,6 +29,14 @@ class ASH_PUBLIC_EXPORT InSessionAuthDialogClient { ...@@ -29,6 +29,14 @@ class ASH_PUBLIC_EXPORT InSessionAuthDialogClient {
// Check whether fingerprint auth is available for |account_id|. // Check whether fingerprint auth is available for |account_id|.
virtual bool IsFingerprintAuthAvailable(const AccountId& account_id) = 0; virtual bool IsFingerprintAuthAvailable(const AccountId& account_id) = 0;
// Switch biometrics daemon to auth mode.
virtual void StartFingerprintAuthSession(
const AccountId& account_id,
base::OnceCallback<void(bool)> callback) = 0;
// Switch biometrics daemon to normal mode. Used when closing the dialog.
virtual void EndFingerprintAuthSession() = 0;
// Check whether PIN auth is available for |account_id|. // Check whether PIN auth is available for |account_id|.
virtual void CheckPinAuthAvailability( virtual void CheckPinAuthAvailability(
const AccountId& account_id, const AccountId& account_id,
......
...@@ -60,6 +60,26 @@ bool InSessionAuthDialogClient::IsFingerprintAuthAvailable( ...@@ -60,6 +60,26 @@ bool InSessionAuthDialogClient::IsFingerprintAuthAvailable(
quick_unlock_storage->fingerprint_storage()->IsFingerprintAvailable(); quick_unlock_storage->fingerprint_storage()->IsFingerprintAvailable();
} }
ExtendedAuthenticator* InSessionAuthDialogClient::GetExtendedAuthenticator() {
// Lazily allocate |extended_authenticator_| so that tests can inject a fake.
if (!extended_authenticator_)
extended_authenticator_ = ExtendedAuthenticator::Create(this);
return extended_authenticator_.get();
}
void InSessionAuthDialogClient::StartFingerprintAuthSession(
const AccountId& account_id,
base::OnceCallback<void(bool)> callback) {
GetExtendedAuthenticator()->StartFingerprintAuthSession(account_id,
std::move(callback));
}
void InSessionAuthDialogClient::EndFingerprintAuthSession() {
DCHECK(extended_authenticator_);
extended_authenticator_->EndFingerprintAuthSession();
}
void InSessionAuthDialogClient::CheckPinAuthAvailability( void InSessionAuthDialogClient::CheckPinAuthAvailability(
const AccountId& account_id, const AccountId& account_id,
base::OnceCallback<void(bool)> callback) { base::OnceCallback<void(bool)> callback) {
...@@ -90,10 +110,6 @@ void InSessionAuthDialogClient::AuthenticateUserWithPasswordOrPin( ...@@ -90,10 +110,6 @@ void InSessionAuthDialogClient::AuthenticateUserWithPasswordOrPin(
<< user_context.GetUserType(); << user_context.GetUserType();
} }
// Lazily allocate |extended_authenticator_| so that tests can inject a fake.
if (!extended_authenticator_)
extended_authenticator_ = ExtendedAuthenticator::Create(this);
DCHECK(!pending_auth_state_); DCHECK(!pending_auth_state_);
pending_auth_state_.emplace(std::move(callback)); pending_auth_state_.emplace(std::move(callback));
...@@ -139,7 +155,7 @@ void InSessionAuthDialogClient::AuthenticateWithPassword( ...@@ -139,7 +155,7 @@ void InSessionAuthDialogClient::AuthenticateWithPassword(
FROM_HERE, FROM_HERE,
base::BindOnce( base::BindOnce(
&ExtendedAuthenticator::AuthenticateToCheck, &ExtendedAuthenticator::AuthenticateToCheck,
extended_authenticator_.get(), user_context, GetExtendedAuthenticator(), user_context,
base::Bind(&InSessionAuthDialogClient::OnPasswordAuthSuccess, base::Bind(&InSessionAuthDialogClient::OnPasswordAuthSuccess,
weak_factory_.GetWeakPtr(), user_context))); weak_factory_.GetWeakPtr(), user_context)));
} }
......
...@@ -37,6 +37,10 @@ class InSessionAuthDialogClient : public ash::InSessionAuthDialogClient, ...@@ -37,6 +37,10 @@ class InSessionAuthDialogClient : public ash::InSessionAuthDialogClient,
bool authenticated_by_pin, bool authenticated_by_pin,
AuthenticateCallback callback) override; AuthenticateCallback callback) override;
bool IsFingerprintAuthAvailable(const AccountId& account_id) override; bool IsFingerprintAuthAvailable(const AccountId& account_id) override;
void StartFingerprintAuthSession(
const AccountId& account_id,
base::OnceCallback<void(bool)> callback) override;
void EndFingerprintAuthSession() override;
void CheckPinAuthAvailability( void CheckPinAuthAvailability(
const AccountId& account_id, const AccountId& account_id,
base::OnceCallback<void(bool)> callback) override; base::OnceCallback<void(bool)> callback) override;
...@@ -61,6 +65,10 @@ class InSessionAuthDialogClient : public ash::InSessionAuthDialogClient, ...@@ -61,6 +65,10 @@ class InSessionAuthDialogClient : public ash::InSessionAuthDialogClient,
base::OnceCallback<void(bool)> callback; base::OnceCallback<void(bool)> callback;
}; };
// Returns a pointer to the ExtendedAuthenticator instance if there is one.
// Otherwise creates one.
chromeos::ExtendedAuthenticator* GetExtendedAuthenticator();
void AuthenticateWithPassword(const chromeos::UserContext& user_context); void AuthenticateWithPassword(const chromeos::UserContext& user_context);
void OnPinAttemptDone(const chromeos::UserContext& user_context, void OnPinAttemptDone(const chromeos::UserContext& user_context,
......
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