Android verification — 2026-10-06
Android verification — 2026-10-06
Device and environment
- Physical Google Pixel 9 Pro (
caiman), Android 17 / API 37, buildCP2A.260805.005. - Portrait display: 960 × 2142 pixels, density 360; locale
en-CA, timezoneAmerica/Vancouver. - The phone was attached to WSL through usbipd, but Linux USB permissions initially prevented ADB access. Access was limited to the
apexuser on the attached phone’s temporary USB node; no broad world-write permission was granted. -
ADB 37.0.1 uses an isolated filesystem socket because normal TCP discovery stalled in this environment:
export ADB_SERVER_SOCKET=localfilesystem:/tmp/papernest-adb-server.sock /tmp/papernest-android-tools/platform-tools/adb devices -l
The requested Android Automation skill was read. Its inspected, read-only device_info.py script was run successfully; the ADB screenshot, hierarchy, interaction, and logcat workflow is used where compatible with Kivy.
Baseline provenance
PaperNest was not installed when the phone was connected. No existing PaperNest database was found through package discovery, and no app was cleared or uninstalled. Consequently, a baseline requires building and installing the existing repository version rather than inspecting a preinstalled app.
The baseline source is a git archive of commit 1fe104c, staged at /tmp/papernest-device-baseline/source. The temporary build specification limits compilation to the phone’s arm64-v8a architecture and excludes non-runtime agent/configuration directories. Runtime application source is unchanged for the baseline build.
Android SDK 36, NDK 28c and native build caches are isolated under /tmp; Gradle uses its normal user cache. The same toolchain builds both APKs: python-for-android 58d21141, Python 3.14.2, Kivy 2.3.1 and KivyMD 1.2.0. Missing standard Linux compiler prerequisites were installed with approved package-manager access. A temporary python-for-android FreeType recipe uses the project’s SourceForge release mirror because the original Savannah host timed out; the dependency version is unchanged.
Verification status
Baseline and updated APK builds, installation, launch, and navigation passed on the physical phone. The baseline test receipt (ID 1, QA group ID 2, date 2026-10-06, amount 123456.78, long display name) survived an adb install -r upgrade unchanged. No app data was cleared or app uninstalled.
The real Accurate UI workflow imported the HMSHost fixture through Android DocumentsUI, performed recognition on worker threads, and populated June 3, 2026 / $25.95 after three passes in about 4.7 seconds. Home navigation during an earlier scan remained responsive and safely canceled stale work. The camera-permission denial produced an actionable message and retained the selected image. Manual amount keypad entry and Android Back to Home were exercised.
The first updated APK revealed clipped large totals and white status icons on a white background. Both were fixed and rechecked on the phone: corrected Home. Native activity launch times were 580 ms baseline and 306 ms first update; these are single am start -W measurements, not full Python/UI-ready latency.
The Android hierarchy exposes only five container nodes ending in SurfaceView; individual Kivy controls are not represented. Screenshot and coordinate interaction checks therefore do not establish TalkBack compatibility.
The unchanged-service ten-receipt baseline is android-baseline.json. The first update is android-first-update.json. The final result is android-after.json; android-alias-stage.json preserves the intermediate known-brand correction run. Desktop test/benchmark results are separate.
Temporary evidence is under /tmp/papernest-device-baseline; build output is /tmp/papernest-android-baseline-build.log. The initial launcher screenshot is diagnostic only and is not an app screenshot or visual baseline.
Benchmark method
The existing tools/benchmark_ocr_receipts.py runner processes the ten real, filename-labeled images in tests/TestRecipts inside the Android app runtime. Temporary debug-only entrypoint bytecode starts a worker; the original packaged entrypoint is restored afterward. Application OCR source and image inputs are unchanged by the timing harness. Initialization is excluded; recognition timing includes bitmap decode and the ML Kit task wait.
PyJNIus 1.7.0 cannot resolve some app classes from a newly attached Python worker using its direct JNI class lookup. Initial harness attempts exposed this failure. Priming Task, Text, and the reusable recognizer on Kivy’s attached thread resolved it. Those failed diagnostic attempts are excluded from benchmark JSON; the same priming is used for both successful comparison runs and informed the production worker fix. Recognition, preprocessing, scoring and parsing stay on workers.
Final physical-device results
| Metric, same ten real receipts | Baseline | Final |
|---|---|---|
| Date accuracy | 9/10 | 9/10 |
| Amount accuracy | 10/10 | 10/10 |
| Merchant accuracy | 6/10 | 10/10 |
| All fields correct | 5/10 | 9/10 |
| Mean total OCR time | 3,829.97 ms | 2,602.37 ms |
| Median | 3,653.05 ms | 3,184.98 ms |
| p95 | 4,838.06 ms | 4,753.68 ms |
| Average recognition passes | 3.4 | 3.3 |
| First-pass success | 0% | 30% |
| Fallback frequency | 80% | 70% |
| Processing failure | 0% | 0% |
Mean time decreased 32.1%; median decreased 12.8%; p95 decreased 1.7%. These are single sequential runs on one phone, not a randomized latency study. The remaining Triple O’s date miss is preserved rather than guessed. Final OCR ran with source 49cd298; the subsequent 8c61a72 change only reserves search-helper space and does not affect OCR.
A bounded 1600-pixel cap experiment on the Jugo Juice and long Uber $94.80 fixtures retained both receipts’ fields and recognition counts. It reduced their combined mean from approximately 1,897 ms to 1,791 ms. This two-image, warm-order comparison does not justify changing the default 2560 cap; input size and small-text accuracy need broader study.
| Physical check | Observed result |
|---|---|
| Home and system bars | Full six-digit total visible; dark status/navigation icons on light background. |
| Accurate single import | Native file picker → ML Kit → correct date/amount and provenance labels; navigation remained responsive and stale work canceled. |
| Two-image batch | Native multi-select Jugo Juice + HMSHost; Scan All returned 2 complete, 0 partial, 0 failed in 5,431 ms. Reviewed and saved each; first save advanced to second. Database confirmed exact dates, amounts and names for IDs 2 and 3. |
| Amount correction | Clear, numeric entry, backspace and Enter applied 26.00 to an edit; cancel left the saved record unchanged. Final keypad helper and buttons have readable contrast and no clipping. |
| Search and keyboard | No-match query, Clear search, keyboard Back dismissal; focused helper no longer overlaps the next controls. |
| Sort | Oldest-first showed Jun 2, Jun 3, Oct 6 in order across three saved QA records. |
| Groups | Browse groups, select custom group, rename to QA_Renamed; database ID remained 2. |
| Back | Scan screen returned Home; keyboard Back dismissed keyboard without navigating the library. |
| Image viewer | Saved image opened; drag and double-tap reset exercised. Two-finger pinch was not independently verified. |
| Camera permission | Denial produced an actionable settings message and preserved selected image. Physical camera capture was not performed. |
Evidence: Home, keypad, focused search, batch review, sorted library, group rename, image viewer, clean empty Home. Earlier stage screenshots are labeled by their tested behavior; desktop screenshots in the same directory are not phone evidence.
Final artifact and cleanup
Installed final debug APK: bin/papernest-1.0.0-debug.apk, runtime source 8c61a7227c6b148e4dd6d409a3028c173a3a960c, arm64-v8a. SHA-256:
178a12c4f2f590662248e3b76796d7b8c48472e1431c9f1d54754a423c2c99a3
Only QA-created receipt IDs 1, 2 and 3 were removed after checking their exact expected names, using normal receipt deletion services. The now-empty QA group ID 2 and the known unsaved imported image were removed. Verification found zero receipts and only the default General group. The exact temporary QA Downloads folder was removed; the pre-existing PaperNest folder and all unrelated phone data were untouched. No clear-data or uninstall command was used. Temporary debug entrypoint instrumentation was removed and packaged main bytecode restored; the APK itself contains no benchmark or cleanup hook.
Final normal launch logcat has no Python traceback, fatal Java exception, or JNI fatal error. Full physical-device checks of PDFs, CSV export/share destinations, real camera capture, TalkBack, two-finger pinch, landscape/alternative densities, and prolonged memory/battery behavior remain unverified. Desktop layout/unit checks are documented separately and do not close these device coverage gaps.