0

Introduce OnIdle state for ActiveSessionAuthControllerImpl

This Cl is fixes the ShowAuthDialog crash when two requestsi happens,
and the first is just reached the kWaitForInit state and not the
kInitialized the check fails in ShowAuthDialog.

Bug: b:364647663
Change-Id: Ide4d4f6e8bf14d40a4ae48892c3c2e539f99ca30
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6370643
Reviewed-by: Elie Maamari <emaamari@google.com>
Commit-Queue: Istvan Nagy <iscsi@google.com>
Cr-Commit-Position: refs/heads/main@{#1437418}
This commit is contained in:
Istvan Nagy
2025-03-25 04:56:52 -07:00
committed by Chromium LUCI CQ
parent 960c871929
commit a5c054421b
2 changed files with 28 additions and 6 deletions

@ -111,6 +111,8 @@ const char* ReasonToString(AuthRequest::Reason reason) {
const char* ActiveSessionAuthStateToString(
ActiveSessionAuthControllerImpl::ActiveSessionAuthState state) {
switch (state) {
case ActiveSessionAuthControllerImpl::ActiveSessionAuthState::kOnIdle:
return "OnIdle";
case ActiveSessionAuthControllerImpl::ActiveSessionAuthState::kWaitForInit:
return "WaitForInit";
case ActiveSessionAuthControllerImpl::ActiveSessionAuthState::kInitialized:
@ -226,6 +228,11 @@ ActiveSessionAuthControllerImpl::TestApi::GetPinStatusMessage() const {
ActiveSessionAuthControllerImpl::ActiveSessionAuthControllerImpl() = default;
ActiveSessionAuthControllerImpl::~ActiveSessionAuthControllerImpl() = default;
bool ActiveSessionAuthControllerImpl::IsPreInitializedState() const {
return state_ == ActiveSessionAuthState::kOnIdle ||
state_ == ActiveSessionAuthState::kWaitForInit;
}
bool ActiveSessionAuthControllerImpl::IsSucceedState() const {
return state_ == ActiveSessionAuthState::kPasswordAuthSucceeded ||
state_ == ActiveSessionAuthState::kPinAuthSucceeded ||
@ -244,6 +251,14 @@ bool ActiveSessionAuthControllerImpl::ShowAuthDialog(
return false;
}
if (state_ == ActiveSessionAuthState::kWaitForInit) {
VLOG(1) << "A show request is already pending; waiting for initialization.";
return false;
}
// This state transition checking the current state is kOnIdle.
SetState(ActiveSessionAuthState::kWaitForInit);
CHECK(!auth_request_);
auth_request_ = std::move(auth_request);
@ -370,7 +385,7 @@ void ActiveSessionAuthControllerImpl::AuthFactorsAreReady(
void ActiveSessionAuthControllerImpl::OnFingerprintScan(
const FingerprintAuthScanResult scan_result) {
CHECK_NE(state_, ActiveSessionAuthState::kWaitForInit);
CHECK(!ActiveSessionAuthControllerImpl::IsPreInitializedState());
// Avoid unnecessary processing if we've already initiated close.
if (IsSucceedState() || state_ == ActiveSessionAuthState::kCloseRequested) {
return;
@ -449,7 +464,7 @@ void ActiveSessionAuthControllerImpl::StartClose() {
CHECK(user_context_);
CHECK(auth_request_);
CHECK(auth_performer_);
if (state_ != ActiveSessionAuthState::kWaitForInit) {
if (!IsPreInitializedState()) {
uma_recorder_.RecordClose();
}
contents_view_observer_.Reset();
@ -457,7 +472,7 @@ void ActiveSessionAuthControllerImpl::StartClose() {
contents_view_->RemoveObserver(this);
contents_view_ = nullptr;
} else {
CHECK_EQ(state_, ActiveSessionAuthState::kWaitForInit);
CHECK(IsPreInitializedState());
}
auth_session_broadcast_id_.clear();
@ -494,7 +509,7 @@ void ActiveSessionAuthControllerImpl::CompleteClose(
auth_request_.reset();
available_factors_.Clear();
SetState(ActiveSessionAuthState::kWaitForInit);
SetState(ActiveSessionAuthState::kOnIdle);
title_.clear();
description_.clear();
@ -581,6 +596,7 @@ void ActiveSessionAuthControllerImpl::OnAuthComplete(
void ActiveSessionAuthControllerImpl::OnClose() {
switch (state_) {
case ActiveSessionAuthState::kOnIdle:
case ActiveSessionAuthState::kWaitForInit:
NOTREACHED();
case ActiveSessionAuthState::kInitialized:
@ -606,7 +622,10 @@ void ActiveSessionAuthControllerImpl::SetState(ActiveSessionAuthState state) {
<< " state to : " << ActiveSessionAuthStateToString(state)
<< " state.";
switch (state) {
case ActiveSessionAuthState::kOnIdle:
break;
case ActiveSessionAuthState::kWaitForInit:
CHECK(state_ == ActiveSessionAuthState::kOnIdle);
break;
case ActiveSessionAuthState::kInitialized:
CHECK(state_ == ActiveSessionAuthState::kWaitForInit ||
@ -668,6 +687,7 @@ void ActiveSessionAuthControllerImpl::OnAuthFactorStatusUpdate(
}
return;
case ActiveSessionAuthState::kOnIdle:
case ActiveSessionAuthState::kWaitForInit:
return;

@ -120,7 +120,8 @@ class ASH_EXPORT ActiveSessionAuthControllerImpl
// Tracks the authentication flow for the active session.
enum class ActiveSessionAuthState {
kWaitForInit, // Initial state, awaiting session start.
kOnIdle, // Initial state, waiting for request.
kWaitForInit, // Waiting session start.
kInitialized, // Session started, ready for user input.
kPasswordAuthStarted, // User submitted password, awaiting verification.
kPasswordAuthSucceeded, // Successful password authentication.
@ -158,6 +159,7 @@ class ASH_EXPORT ActiveSessionAuthControllerImpl
// of the UI. Validates the transitions.
void SetState(ActiveSessionAuthState state);
bool IsPreInitializedState() const;
bool IsSucceedState() const;
// Internal methods for authentication.
@ -198,7 +200,7 @@ class ASH_EXPORT ActiveSessionAuthControllerImpl
std::unique_ptr<UserContext> user_context_;
AuthFactorSet available_factors_;
ActiveSessionAuthState state_ = ActiveSessionAuthState::kWaitForInit;
ActiveSessionAuthState state_ = ActiveSessionAuthState::kOnIdle;
std::unique_ptr<AuthRequest> auth_request_;