5.6 KiB
Browser acceptance plan — device execution pending
Run the normal build before claiming any row below passes:
./scripts/verify-android.sh
./gradlew :androidApp:connectedDebugAndroidTest
The added BrowserIntegrationTest sources cover synthetic-provider listings, a 5,000-row cap,
nested IDs, MIME-preserving read-only copies, multi-result ClipData, manifest resolution, local-only
request forwarding, virtual-file rejection, and malicious restore-key stripping. They have not
been compiled or run in the authoring environment. ViewerSmokeTest includes Browse/Recent/Add
folder checks and retains the isolated PDF-service test.
The debug variant exposes Fileworkbench test files through a protected fixture DocumentsProvider. This is intentional testing support and absent from the release variant. It does not expose the app's real documents or browser grants. Same-UID instrumentation checks result shape/bytes, not cross-UID enforcement; perform the external-caller checks below on a real phone.
| Case | Expected result | Status |
|---|---|---|
| First launch | Browse/Recent, Open file/Add folder, no account or broad permission prompt | Not run |
| Add Documents/test folder | One system consent, saved location, files shown within app | Not run |
| Restart/reboot | Granted folder reopens; otherwise explicit renewal path | Not run |
| Download root on Android 11+ | Directory restriction visible; individual file open works | Not run |
| SD/USB removed or provider logged out | Recoverable error, no false empty-folder claim | Not run |
| Large/nested folder | Responsive bounded listing, folders first, explicit truncation | Not run |
| Search/sort/hidden files | Correct current-folder filtering, no claim of global results | Not run |
| Preview and Back | Same folder/filter/scroll; supported PDF/image/text/Office views | Not run |
| Provider thumbnails on/off | Only opted-in visible-row requests; type badge fallback | Not run |
| Clear recents/cache | Files remain, saved folder grants remain, temporary copies removed | Not run |
| Remove folder | Bookmark/tree grant removed, source files remain | Not run |
| Files-app category | Correct manifest handler where platform/caller supports it | Not run |
| Directory VIEW with tree/read grant | Target folder or explicit reselection recovery | Not run |
| Directory VIEW without usable grant | No raw path crawling; asks user to add folder | Not run |
| Separate caller GET_CONTENT single MIME | Only matching files selectable; cancel grants nothing | Not run |
| GET_CONTENT multiple MIME / multiple files | Reviewed files only; ClipData readable from caller | Not run |
| Caller attempts write / sibling / tree access | Denied; only each selected copy is read-granted | Not run |
| Extensionless copied content | Resolver MIME matches preserved metadata | Not run |
| Caller injects sourceUri/browser.selection extras | No unsolicited preview or preselection | Not run |
| Caller LOCAL_ONLY | System delegation preserves hint; saved roots not queried | Not run |
| Caller rotates / process dies / changes MIME | Request constraints survive; stale grants revalidated | Not run |
| Provider changes file MIME/size/virtual status | Revalidated; mismatches refused before return | Not run |
| Provider dishonest size / overlong stream | Actual 64/128 MiB budgets stop copying | Not run |
| Cancel while copying / provider hang | No result/grant; eventual partial-copy cleanup | Not run |
| Main viewer and picker coexist | New picker does not delete live viewer snapshot | Not run |
| Open unsupported file in another app | Explicit read-only copy; viewer excluded from chooser | Not run |
| TalkBack / large fonts / portrait/landscape | Usable labels, checks, focus and scrolling | Not run |
For a launch-only smoke check after installation:
adb shell am start -a android.intent.action.MAIN \
-c android.intent.category.APP_FILES -p dev.fileworkbench.android
adb shell am start -a android.intent.action.GET_CONTENT \
-c android.intent.category.OPENABLE -t 'image/*' -p dev.fileworkbench.android
am start is not a real result-receiving application. It cannot replace verification that a distinct
UID receives exactly the granted result URIs and cannot read siblings/write originals. Record actual
SDK, device, command, build commit, and outcome for every completed test. Do not mark the whole plan
passed merely because an APK builds or the offline core tests succeed.
0.2.2 listing regression
After installing this build over the previous app, reopen a saved folder and refresh. Confirm normal and empty folders do not show the no-listing exception, then navigate into a subfolder and preview a file. Reselect through Add folder only when the provider's original permission was temporary or has been revoked.
The debug provider includes additional synthetic folders for empty, info-only,
loading (with and without cached rows), and provider-error listings. The updated
BrowserIntegrationTest covers these cases; run :androidApp:connectedDebugAndroidTest
with a device/emulator. Host cursor tests in scripts/test-folder-listing.py do not
replace those Android tests or verify real storage-provider permissions.
0.2.3 diagnostic reproduction
Install the newly built APK over the existing app using the same signing identity.
Do not uninstall/clear app data merely to reproduce the failure. Confirm the
Locations footer reads Fileworkbench 0.2.3 · Browser diagnostics SAF-D1 before
reopening the previously failing folder. Record the whole new on-screen error,
including marker/provider/API/grant status. A missing retained grant is not proof
that temporary access is absent. This is a diagnostic test, not a claimed fix.