MANAGE_EXTERNAL_STORAGE (needed to read the store at
/storage/emulated/0/...) cannot be requested with a runtime
permission dialog; the user must toggle it in system settings.
Port the mechanism from the pad app:
- Permissions.java: a Fragment registered at window attach that
launches Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION
(per-app settings screen) when Environment.isExternalStorageManager()
is false on API 30+ (runtime READ_EXTERNAL_STORAGE request on
older APIs). The guard means the screen appears only until the
user grants it.
- The compiled classes ship in PgpConnect.jar's directory jar
(Permissions.jar); gogio picks *.jar up from the package dir and
dexes them. go:generate now rebuilds it.
- jni_android.c/h: registerPermissionsFragment(), mirroring
registerFragment() for PgpConnect.
- Impl wiring: call it from the AndroidViewEvent handler right
after InitPgp.
Verified on the x86_64 emulator: with the appop denied the system
settings screen opens automatically on launch; after granting it,
launch is clean and list + OpenKeychain decryption from
/sdcard/Pass work end to end.
Found by running and debugging the Linux build on a virtual display:
- impl_linux.go: set fontSize (16, like Darwin). It was only defined
for the Android and Darwin builds, so on Linux every label and
button was rendered at size zero (all text invisible).
- ui.go: extend the Button click area to the full button width, not
just the label width. Short labels (e.g. a few characters in a
full-width list row) had a tiny tap target that was easy to miss.
- main.go: set Color: black on the insert-page buttons (<, >, generate,
@, #). A zero-value NRGBA has A=0 (transparent), so their labels
were invisible even though the buttons worked.
- main.go: gofmt (modern operator spacing).
- Event loop: call w.Event() and FrameEvent.Frame() on the same
goroutine; no channel bridge (the bridge broke frame rendering).
- clip: use clip.UniformRRect(...).Push(gtx.Ops) / Pop() for real
clipping in layoutRRect (old .Add(ops) painted unclipped).
- Window clear color is white in v0.10.2.
- Fonts: always provide gofont; on Android use
WithCollection(gofont.Collection()).
- Button labels: explicitly set Color (zero-value NRGBA has A=0,
i.e. transparent, so labels were invisible).
- Filter: detect changes by comparing the editor text, since
material.Editor.Layout consumes the editor's input events
internally and a later FilterEd.Update(gtx) never sees them.
- idPage: persist the manually entered ID with store.SetID (on
Android nativeIdentities is unimplemented, so there are no id
buttons to click).
- Use U+2026 (gofont) instead of U+22EE (not in gofont) for the
menu button.
- Split getConfDir/noidLabelText out into impl_linux.go for the
Linux build.
- Update to //go:build tags, gofmt, and the android-35 javac template
in //go:generate.
- GetStore: reset store.Empty when the store directory exists (it was
only set true when the dir was missing, so a reconfigured store kept
the stale 'Empty' state and showed the configure button).
- Rebuild PgpConnect.jar (android-35).
fsnotify v1.4.x's inotify_poller uses the legacy epoll_wait(2) syscall,
which is blocked by seccomp on x86_64 Android emulators (SIGSYS crash on
launch). v1.8.0 uses blocking reads on the inotify fd instead.
Also drop the unused git.wow.st/gmp/jni dependency.