Skip to content

Fix PIN unlock unusable after cancelling biometric prompt (#151)#166

Open
MiMoHo wants to merge 1 commit into
hegocre:mainfrom
MiMoHo:fix/app-lock-pin-feedback
Open

Fix PIN unlock unusable after cancelling biometric prompt (#151)#166
MiMoHo wants to merge 1 commit into
hegocre:mainfrom
MiMoHo:fix/app-lock-pin-feedback

Conversation

@MiMoHo

@MiMoHo MiMoHo commented Jul 4, 2026

Copy link
Copy Markdown

Summary

Fixes #151. When both PIN and biometric app lock are enabled, cancelling the biometric prompt drops the user onto the PIN keypad — but the passcode was only ever verified as it was typed, with no submit button and no feedback. Because a wrong digit was never rejected, the user could "type in numbers endlessly" and a correct PIN was effectively unreachable once a wrong digit had been entered.

Changes

  • NCPAppLock.kt — when the typed passcode reaches the length of the stored passcode and is still incorrect, the screen now shows the existing "Incorrect code" error and clears the input, instead of silently accepting further digits. The stored passcode length is loaded asynchronously and the check only runs once it is known, so a correct PIN of any length still unlocks on the last digit as before.
  • AppLockHelper.kt
    • checkPasscode() no longer falls back to the hardcoded "0000" when the stored passcode cannot be read; it returns false instead, so the lock can never be opened with a default code.
    • Added a small pure helper shouldRejectPasscodeAttempt(input, length) that encapsulates the "is this a completed, wrong attempt" decision so it can be unit-tested without the Android runtime.
  • Dialogs.ktInputPasscodeDialog now filters input with all { it.isDigit() } instead of toIntOrNull() != null. The old check rejected passcodes longer than 9–10 digits because they overflowed Int parsing, even though the field allows up to 16 digits.

Testing

  • Added JVM unit tests (AppLockHelperTest) covering empty / incomplete / full-length-wrong / over-length / unreadable-passcode / long-passcode cases. All green.
  • Manually verified on an Android 15 emulator (the issue's repro): enable PIN + fingerprint → lock → cancel the fingerprint prompt → the PIN keypad now rejects a wrong code with "Incorrect code" and unlocks with the correct one. Also verified the physical-keyboard input path and the setup dialog still accept a normal PIN.
  • ./gradlew testDebugUnitTest passes; lintDebug shows only pre-existing findings (unchanged by this diff).

Note

This contribution was made using AI (Claude). All generated code was proofread and validated by the committer.

The app lock passcode screen has no submit button and verifies the code on
every keystroke, but a wrong code was never rejected. After cancelling the
biometric prompt and falling back to the PIN keypad, the user could type
digits endlessly with no feedback and no way to submit, so a correct PIN was
effectively unreachable.

- NCPAppLock: once the entered code reaches the stored passcode length and is
  still wrong, show the existing "Incorrect code" error and clear the input.
- AppLockHelper: checkPasscode no longer accepts the hardcoded "0000" fallback
  when the stored passcode is unreadable; added a pure, unit-tested helper
  shouldRejectPasscodeAttempt.
- Dialogs: InputPasscodeDialog now validates with all { isDigit() } instead of
  toIntOrNull(), which silently rejected passcodes longer than ~9 digits even
  though the field allows up to 16.

Adds unit tests for the passcode attempt evaluation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PIN unlock no longer works when biometric unlock is activated

1 participant