Commit 181f6701 authored by Yicheng Li's avatar Yicheng Li Committed by Commit Bot

ash: Request fingerprint check from in-session auth dialog

In-session auth dialog may involve multiple fingerprint retries. The
contents view needs to display corresponding prompts and animations
upon a fingerprint mismatch. Start fingerprint auth with a callback
from the contents view so that the view can act according to the
fingerprint scan result.

This change also handles fingerprint retry.

Bug: b:156258540, b:144861739
Change-Id: I7a3c29c706e4fe6c3bb0bd3f8dfb9bd1d07d3180
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2369368
Commit-Queue: Yicheng Li <yichengli@chromium.org>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#801198}
parent cd283b08
......@@ -136,6 +136,16 @@ AuthDialogContentsView::AuthDialogContentsView(uint32_t auth_methods)
InitPasswordView();
}
void AuthDialogContentsView::AddedToWidget() {
if (auth_methods_ & kAuthFingerprint) {
// Inject a callback from the contents view so that we can show retry
// prompt.
InSessionAuthDialogController::Get()->AuthenticateUserWithFingerprint(
base::BindOnce(&AuthDialogContentsView::OnFingerprintAuthComplete,
weak_factory_.GetWeakPtr()));
}
}
AuthDialogContentsView::~AuthDialogContentsView() = default;
void AuthDialogContentsView::AddTitleView() {
......@@ -261,11 +271,28 @@ views::LabelButton* AuthDialogContentsView::AddButton(const std::string& text,
void AuthDialogContentsView::OnAuthSubmit(const base::string16& password) {
InSessionAuthDialogController::Get()->AuthenticateUserWithPasswordOrPin(
base::UTF16ToUTF8(password),
base::BindOnce(&AuthDialogContentsView::OnAuthComplete,
base::BindOnce(&AuthDialogContentsView::OnPasswordOrPinAuthComplete,
weak_factory_.GetWeakPtr()));
}
// TODO(b/156258540): Clear password/PIN if auth failed and retry is allowed.
void AuthDialogContentsView::OnAuthComplete(base::Optional<bool> success) {}
void AuthDialogContentsView::OnPasswordOrPinAuthComplete(
base::Optional<bool> success) {}
void AuthDialogContentsView::OnFingerprintAuthComplete(
bool success,
FingerprintState fingerprint_state) {
if (!success) {
if (fingerprint_state == FingerprintState::AVAILABLE_DEFAULT) {
// TODO(b/156258540): Show animation and prompt in fingerprint_view_.
InSessionAuthDialogController::Get()->AuthenticateUserWithFingerprint(
base::BindOnce(&AuthDialogContentsView::OnFingerprintAuthComplete,
weak_factory_.GetWeakPtr()));
} else {
fingerprint_view_->SetVisible(false);
}
}
// TODO(b/156258540): Show success animation before the dialog closes.
}
} // namespace ash
......@@ -7,6 +7,7 @@
#include <string>
#include "ash/public/cpp/login_types.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/view.h"
......@@ -47,6 +48,9 @@ class AuthDialogContentsView : public views::View,
private:
class FingerprintView;
// views::View:
void AddedToWidget() override;
// Add a view for dialog title.
void AddTitleView();
......@@ -76,8 +80,12 @@ class AuthDialogContentsView : public views::View,
// Called when the user submits password or PIN.
void OnAuthSubmit(const base::string16& password);
// Called when authentication of the user completes.
void OnAuthComplete(base::Optional<bool> success);
// Called when password/PIN authentication of the user completes.
void OnPasswordOrPinAuthComplete(base::Optional<bool> success);
// Called when fingerprint authentication completes.
void OnFingerprintAuthComplete(bool success,
FingerprintState fingerprint_state);
// Debug container which holds the entire debug UI.
views::View* container_ = nullptr;
......
......@@ -101,6 +101,15 @@ void InSessionAuthDialogControllerImpl::AuthenticateUserWithPasswordOrPin(
weak_factory_.GetWeakPtr(), std::move(callback)));
}
void InSessionAuthDialogControllerImpl::AuthenticateUserWithFingerprint(
base::OnceCallback<void(bool, FingerprintState)> views_callback) {
DCHECK(client_);
client_->AuthenticateUserWithFingerprint(base::BindOnce(
&InSessionAuthDialogControllerImpl::OnFingerprintAuthComplete,
weak_factory_.GetWeakPtr(), std::move(views_callback)));
}
void InSessionAuthDialogControllerImpl::OnAuthenticateComplete(
OnAuthenticateCallback callback,
bool success) {
......@@ -111,6 +120,22 @@ void InSessionAuthDialogControllerImpl::OnAuthenticateComplete(
std::move(finish_callback_).Run(success);
}
void InSessionAuthDialogControllerImpl::OnFingerprintAuthComplete(
base::OnceCallback<void(bool, FingerprintState)> views_callback,
bool success,
FingerprintState fingerprint_state) {
// If success is false and retry is allowed, the view will start another
// fingerprint check.
std::move(views_callback).Run(success, fingerprint_state);
if (success) {
DestroyAuthenticationDialog();
if (finish_callback_)
std::move(finish_callback_).Run(success);
return;
}
}
void InSessionAuthDialogControllerImpl::Cancel() {
DestroyAuthenticationDialog();
if (finish_callback_)
......
......@@ -36,6 +36,8 @@ class InSessionAuthDialogControllerImpl : public InSessionAuthDialogController {
void AuthenticateUserWithPasswordOrPin(
const std::string& password,
OnAuthenticateCallback callback) override;
void AuthenticateUserWithFingerprint(
base::OnceCallback<void(bool, FingerprintState)> callback) override;
void Cancel() override;
private:
......@@ -48,6 +50,11 @@ class InSessionAuthDialogControllerImpl : public InSessionAuthDialogController {
// Callback to execute when auth on ChromeOS side completes.
void OnAuthenticateComplete(OnAuthenticateCallback callback, bool success);
void OnFingerprintAuthComplete(
base::OnceCallback<void(bool, FingerprintState)> views_callback,
bool success,
FingerprintState fingerprint_state);
InSessionAuthDialogClient* client_ = nullptr;
// Callback to provide result of the entire authentication flow to
......
......@@ -45,6 +45,11 @@ class MockInSessionAuthDialogClient : public InSessionAuthDialogClient {
(const AccountId& account_id,
base::OnceCallback<void(bool)> callback),
(override));
MOCK_METHOD(void,
AuthenticateUserWithFingerprint,
(base::OnceCallback<void(bool, FingerprintState)> callback),
(override));
};
} // namespace ash
......
......@@ -8,6 +8,7 @@
#include <string>
#include "ash/public/cpp/ash_public_export.h"
#include "ash/public/cpp/login_types.h"
#include "base/callback_forward.h"
#include "components/account_id/account_id.h"
......@@ -42,6 +43,9 @@ class ASH_PUBLIC_EXPORT InSessionAuthDialogClient {
const AccountId& account_id,
base::OnceCallback<void(bool)> callback) = 0;
virtual void AuthenticateUserWithFingerprint(
base::OnceCallback<void(bool, FingerprintState)> callback) = 0;
protected:
virtual ~InSessionAuthDialogClient() = default;
};
......
......@@ -41,6 +41,10 @@ class ASH_PUBLIC_EXPORT InSessionAuthDialogController {
const std::string& password,
OnAuthenticateCallback callback) = 0;
// Requests ChromeOS to report fingerprint scan result through |callback|.
virtual void AuthenticateUserWithFingerprint(
base::OnceCallback<void(bool, FingerprintState)> callback) = 0;
// Cancels all operations and destroys the dialog.
virtual void Cancel() = 0;
......
......@@ -8,6 +8,7 @@
#include "ash/public/cpp/in_session_auth_dialog_controller.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/logging.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/chromeos/login/quick_unlock/fingerprint_storage.h"
......@@ -169,6 +170,41 @@ void InSessionAuthDialogClient::OnPasswordAuthSuccess(
quick_unlock_storage->MarkStrongAuth();
}
void InSessionAuthDialogClient::AuthenticateUserWithFingerprint(
base::OnceCallback<void(bool, ash::FingerprintState)> callback) {
const user_manager::User* const user =
user_manager::UserManager::Get()->GetActiveUser();
DCHECK(user);
UserContext user_context(*user);
DCHECK(extended_authenticator_);
extended_authenticator_->AuthenticateWithFingerprint(
user_context,
base::BindOnce(&InSessionAuthDialogClient::OnFingerprintAuthDone,
weak_factory_.GetWeakPtr(),
base::Passed(std::move(callback))));
}
void InSessionAuthDialogClient::OnFingerprintAuthDone(
base::OnceCallback<void(bool, ash::FingerprintState)> callback,
cryptohome::CryptohomeErrorCode error) {
switch (error) {
case cryptohome::CRYPTOHOME_ERROR_NOT_SET:
std::move(callback).Run(true, ash::FingerprintState::AVAILABLE_DEFAULT);
break;
case cryptohome::CRYPTOHOME_ERROR_FINGERPRINT_RETRY_REQUIRED:
std::move(callback).Run(false, ash::FingerprintState::AVAILABLE_DEFAULT);
break;
case cryptohome::CRYPTOHOME_ERROR_FINGERPRINT_DENIED:
std::move(callback).Run(false,
ash::FingerprintState::DISABLED_FROM_ATTEMPTS);
break;
default:
// Internal error.
std::move(callback).Run(false, ash::FingerprintState::UNAVAILABLE);
}
}
// AuthStatusConsumer:
void InSessionAuthDialogClient::OnAuthFailure(
const chromeos::AuthFailure& error) {
......
......@@ -44,6 +44,8 @@ class InSessionAuthDialogClient : public ash::InSessionAuthDialogClient,
void CheckPinAuthAvailability(
const AccountId& account_id,
base::OnceCallback<void(bool)> callback) override;
void AuthenticateUserWithFingerprint(
base::OnceCallback<void(bool, ash::FingerprintState)> callback) override;
// AuthStatusConsumer:
void OnAuthFailure(const chromeos::AuthFailure& error) override;
......@@ -56,7 +58,9 @@ class InSessionAuthDialogClient : public ash::InSessionAuthDialogClient,
}
private:
// State associated with a pending authentication attempt.
// State associated with a pending authentication attempt. Only for Password
// and PIN, not for fingerprint, since the fingerprint path needs to surface
// retry status.
struct AuthState {
explicit AuthState(base::OnceCallback<void(bool)> callback);
~AuthState();
......@@ -76,6 +80,10 @@ class InSessionAuthDialogClient : public ash::InSessionAuthDialogClient,
void OnPasswordAuthSuccess(const chromeos::UserContext& user_context);
void OnFingerprintAuthDone(
base::OnceCallback<void(bool, ash::FingerprintState)> callback,
cryptohome::CryptohomeErrorCode error);
// Used to authenticate the user to unlock supervised users.
scoped_refptr<chromeos::ExtendedAuthenticator> extended_authenticator_;
......
......@@ -45,6 +45,9 @@ class FakeInSessionAuthDialogController
void AuthenticateUserWithPasswordOrPin(
const std::string& password,
OnAuthenticateCallback callback) override {}
void AuthenticateUserWithFingerprint(
base::OnceCallback<void(bool, ash::FingerprintState)> callback) override {
}
void Cancel() override {}
};
......
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