Files
IronStorage/docs/android/adaptive-shell.md
T
hugo d22d71eb5e
Android ARM verification / rust (push) Failing after 47m11s
Android ARM verification / android (push) Failing after 8s
Dependency security audit / rustsec (push) Successful in 25s
Implement adaptive Android shell and safe navigation (#102)
2026-10-09 20:33:31 +02:00

73 lines
4.8 KiB
Markdown

# Adaptive Android shell
The single `MainActivity` is a `FragmentActivity` (a `ComponentActivity` subclass)
so AndroidX BiometricPrompt can retain its OS authentication fragment. Compose,
Hilt ViewModels, lifecycle-aware StateFlow collection, and Navigation 3 1.2.0
present the Rust-owned Home, Passwords, Search, TOTP, and Preferences pages.
The shell uses actual available window width: bottom navigation below 600 dp,
and a scrollable navigation rail at larger widths. Passwords retains Material 3
Adaptive list/detail panes and the library's fold/hinge-aware directives. Live
window changes recompute both layouts without replacing native handles or
repository identities. Large text uses labelled navigation icons on compact
windows, leaving accessible names and 48 dp or larger selectable touch targets.
Page headings, selected tab semantics, radio groups, and keyboard activation use
Compose semantics rather than display-string interpretation.
Navigation 3 renders each top-level root and Preferences' Appearance child.
Each destination retains its own navigation: Rust owns Passwords' directory,
entry, parent and revision; Preferences retains its child independently of tab
switches. Home and TOTP have root stacks, and Search hands a typed result to
Passwords. The TOTP root presents Rust shell availability; the TOTP list/detail
workflow is assigned to #107, discovery to #110, and full preferences to #104.
SavedStateHandle stores only the selected tab, Appearance child flag, and
Password directory/entry/revision identifiers. Navigation 3 deliberately has no
saveable screen-content decorator. Search text, passphrases, editors, decrypted
fields, codes, credentials and native handles never enter navigation saved
state. Existing Rust process-recreated authentication starts locked and checks
restored object revisions before opening an entry. Backgrounding does not renew
a lease. Leaving Passwords invalidates pending operations, clears protected
presentation, and revokes the lease without treating a tab switch as manual
search-history clearing. Navigation cancels setup, Home and Search work before switching destinations and
clears setup secrets before opening Appearance or another tab. Outgoing animated
entries do not cancel work belonging to the incoming destination; sequence/revision checks reject late native results. Cleanup registrations
use distinct owner tokens: removing a screen with the same surface callback cannot
remove another screen's protection. The unchanged immediate memory-pressure
masking assertion also covers setup destinations during screen replacement.
Appearance is read and written through Rust's existing mobile appearance API.
The shell's only decision is translating System/Light/Dark into Material color
schemes, using the OS preference for System. System-bar icon contrast follows the active
Material background while the activity remains edge-to-edge. Failed operations preserve the
last confirmed appearance. No Android preference store or domain policy is added.
Rust fixtures generate Loading, Empty, Ready, Locked, Error and Stale pages for
all five destinations; no repository or secret is needed to exercise them. Tests
cover initial async loading versus restored selection, stale completion rejection,
all fixture pages, compact/expanded navigation, large text, keyboard activation,
independent Preferences navigation and reconstruction from primitive saved state.
The native encrypted-store fixture checks appearance persistence and locked
restoration along with entry navigation and viewer operations.
Validation used ARM64 emulators on API 26 (4 KB), API 37 (4 KB), and API 37
(strict 16 KB), including app/core/bridge instrumentation and five cold
starts per device. Both supported ARM ABIs passed release packaging, native
linker, backup exclusion, architecture, dependency/license and SBOM gates.
All four Rust workspace gates passed.
Computer use in Android Studio's embedded emulator verified portrait bottom
navigation, landscape rail, Appearance navigation and light/dark/system changes.
TalkBack focus and activation were observed on Search and Preferences; text at
160% with 520 dpi display scaling retained accessible controls. Accessibility,
font and density settings were restored afterward. Instrumentation also exercises
keyboard activation and expanded navigation with 200% text. TalkBack audio was
not recorded; no fold-posture or desktop-window AVD was available, so those use
the adaptive library's directives without a claim of device-specific validation.
ARMv7 was built and packaged; the available live emulator images were ARM64.
The additive shared shell-state contract regenerated the hardened Swift bindings.
The iPhone and dependent watch simulator targets built after XcodeGen generation;
the iPhone app was installed over its existing container and computer use verified
locked folder navigation. Existing biometric enrollment and app data were retained.