exit method
Attempts to leave kiosk mode.
Implementation
Future<DVKioskExitResult> exit(DVKioskExitRequest request) async {
// A build with no kiosk policy has no kiosk runtime: the call exists,
// reports, and changes nothing.
if (!policy.enabled) {
return const DVKioskExitResult(
granted: false,
message: 'This build declares no kiosk policy, so there is nothing to '
'exit.',
degradation: DVKioskDegradation.noPolicy,
);
}
if (isLockedOut) {
return const DVKioskExitResult(
granted: false,
message: 'Too many attempts. Try again later.',
degradation: DVKioskDegradation.lockedOut,
);
}
// The lockout has run out, so the next attempt starts clean.
if (_lockedUntil != null) {
_lockedUntil = null;
_failedAttempts = 0;
if (state.value == DVKioskState.locked) {
_enter(DVKioskState.active);
}
}
// The declared method is the only way out. Accepting a PIN against an
// adminAuth policy would make the declaration advisory.
final bool methodMatches = switch (policy.exitMethod) {
DVKioskExitMethod.pin ||
DVKioskExitMethod.gesturePin =>
request.method == DVKioskExitMethod.pin,
DVKioskExitMethod.adminAuth =>
request.method == DVKioskExitMethod.adminAuth,
DVKioskExitMethod.remote => request.method == DVKioskExitMethod.remote,
DVKioskExitMethod.hardwareCombo => false,
DVKioskExitMethod.none => false,
};
if (!methodMatches) {
return const DVKioskExitResult(
granted: false,
message: 'That is not how this kiosk is left.',
);
}
final bool ok = await _accepts(request);
if (ok) {
// Forgotten on success, or two wrong entries today and one tomorrow
// lock a kiosk out for no reason anyone can see.
_failedAttempts = 0;
_lockedUntil = null;
_enter(DVKioskState.staffMode);
return const DVKioskExitResult(granted: true, message: 'Staff mode.');
}
_failedAttempts++;
if (_failedAttempts >= policy.maxAttempts) {
_lockedUntil = _clock().add(policy.lockoutFor);
_enter(DVKioskState.locked);
return const DVKioskExitResult(
granted: false,
message: 'Too many attempts. Try again later.',
degradation: DVKioskDegradation.lockedOut,
);
}
// Never says what the right answer was, or how close this one came.
return const DVKioskExitResult(
granted: false,
message: 'That did not work.',
);
}