Implement Rust-backed Android name search (#101)
Android ARM verification / rust (push) Failing after 47m11s
Android ARM verification / android (push) Failing after 9s
Dependency security audit / rustsec (push) Successful in 23s

This commit is contained in:
hugo committed 2026-10-09 19:30:15 +02:00
1 parent a06f39af23
commit c7703d8efd
21 files changed
+910 -27

No files matched your search

+53
View File
@@ -0,0 +1,53 @@
# Android name search
Search uses the shared `MobilePasswordPage` search rules in `crates/storage`.
Queries are trimmed, Unicode-lowercased, and matched as literal substrings of the
canonical entry path, including its folders and filename without `.gpg`.
This is lowercase matching, not locale collation or Unicode normalization. `/`
is the canonical separator; backslashes and regex characters remain literal.
Ordinary dot-prefixed entries are searchable; `.extensions` is excluded by the
shared password-store rules. No entry is read or decrypted to search its name.
The private-runtime API supplies typed rows with canonical folder context and
an object revision. Opening a result validates its identifier and current
revision in Rust under the private-runtime lock, then returns the same directory
navigation and structured viewer model used by Passwords. Deleted/replaced
objects clear selection and expose the existing stale-selection recovery.
No Kotlin matching, traversal, path splitting, or identity reconstruction occurs.
The Search destination is injected into `ShellViewModel`. Its repository exposes
StateFlow query/loading/results/error state and debounces typing by 250 ms.
Every query, refresh, cancellation, and manual clear invalidates pending work;
uncancellable native completions cannot publish an older query. Keyboard Search
refreshes immediately. Results are lazy, retain canonical location labels, and
expose accessible labelled click actions. Empty, loading, cancelled, error/retry,
and clear states work in compact and expanded windows.
Only the current query is retained in memory across rotation/window changes and
returning to the destination. It is not written to SavedStateHandle, disk, logs,
analytics, or history. Under this policy names remain available while the store
is locked, but manual lock clears query/results synchronously and a new process
starts empty. Decrypted entry values still follow the stricter background
revocation and native-cover policy documented in presentation-security.md.
Result lists clear when Search stops and reload on resume, incorporating external
repository changes without reusing the old objects.
Rust fixtures cover Unicode/case behavior, literal separators, duplicate names,
shared-rule equivalence, invalid ciphertext, stale replacement/deletion,
repository refresh, invalid identifiers, and 5,000 entries. Coroutine tests cover
debounce, cancelled/uncancellable work, latest-query wins, retry, empty input,
and metadata clearing. Android UI tests exercise canonical location/action
semantics, keyboard Search, compact/expanded layouts, and empty/error recovery;
native facade instrumentation connects real Rust search to the existing viewer.
Validation passed for all four required Rust workspace gates and the complete
Android debug/release/AAB, unit, lint, formatting, architecture, package and
dependency gates. App/core/bridge instrumentation, native-load checks and five
cold starts passed on ARM64 API 26/4 KB, API 37/4 KB and strict API 37/16 KB.
Computer use in the existing Android Studio embedded emulator exercised the
public result fixture and the live Rust-backed Search destination. Native
ViewModel instrumentation verifies query survival through actual recreation,
serialized saved-state exclusion, and synchronous manual-lock clearing.
Accessibility semantics/actions were tested; spoken TalkBack output was not
claimed. ARMv7 build/package checks passed; no suitable ARMv7 emulator image is
available. Physical devices are excluded from this milestone's validation scope.