Files
fksar/docs/thijooree/02-lock-screen.md
T
2026-06-13 21:30:12 +05:00

3.2 KiB
Raw Blame History

Lock Screen

LockActivity is shown whenever the app is locked — on cold start (when credentials exist), after the autolock timer fires, or when the user taps the lock icon in the toolbar.


Authentication Methods

The app attempts authentication in priority order:

  1. Biometrics — if enrolled and enabled, BiometricPrompt is presented automatically on open
  2. PIN — numeric keypad
  3. PatternPatternView grid

The user can switch between biometric and PIN/pattern manually.


Biometric Authentication

Uses Android BiometricPrompt with BIOMETRIC_WEAK (fingerprint or face depending on device). A successful biometric result sets app.isUnlocked = true and calls MainActivity to route to HomeActivity.

On biometric failure or cancellation the screen falls back to PIN/pattern entry.


PIN Entry

  • A custom on-screen numeric keypad (09 + backspace + confirm)
  • The entered digits are shown as filled/unfilled circles (no digit echo)
  • Confirm fires verification immediately when the correct number of digits is entered

Pattern Entry

  • The same PatternView widget used in onboarding, in verify-only mode
  • The drawn pattern is hashed and compared against the stored derived key

Verification

The entered PIN or pattern is run through PBKDF2-HMAC-SHA256 with the stored salt and compared to the stored hash. On match:

  1. app.isUnlocked = true
  2. LockActivity finishes
  3. MainActivity routes to HomeActivity

On mismatch the attempt counter increments and an error shake animation plays.


Brute-Force Protection

Constants live in LockActivity.kt:44-45: MAX_ATTEMPTS = 5, LOCKOUT_MS = 30_000L.

Threshold Behaviour
14 wrong attempts Error label shows remaining attempts
5 wrong attempts 30-second lockout; further entries are rejected by checkAndShowLockout() until LOCKOUT_MS has elapsed since the last fail
After 30 s Lockout expires (purely time-based, via last_fail_time) — the counter itself does not reset until a successful unlock

The fail counter resets to zero only inside resetFailures() (LockActivity.kt:313-315), which is called from the success paths of biometric, PIN, and pattern entry. A user who repeatedly fails will hit the 30-second wait again on the very first failure after each lockout window expires.

The attempt counter and last-fail timestamp live in a dedicated lock_attempts SharedPreferences file (LockActivity.kt:41) — plain (not encrypted), which is a known limitation documented in the security audit. The app does not wipe credentials after repeated failures.


app.isUnlocked Guard

app.isUnlocked is an in-memory flag that is false on every process start. Even if an attacker bypasses LockActivity via adb, HomeActivity checks this flag and re-fires LockActivity on resume if it is false. This prevents cold-start bypass.


Screenshot Protection

FLAG_SECURE is set on LockActivity's window, preventing screenshots and screen recording. This is always on for the lock screen regardless of the user's global screenshots setting.


 


← Onboarding     Next → Login