iOS FS suits Resonator better

iOS: one Unix user, sandbox profiles, capabilities. Every app runs as the same Unix user (mobile); isolation comes from a per-app sandbox profile, not from ownership bits. “On My iPhone” in Files is just a view of app containers that opted in. When the user picks a folder in another app’s container, the system mints a sandbox extension: a kernel-enforced capability for that exact path, handed to the picking app. From then on that app opens the real path with ordinary POSIX calls: open, mmap of the -shm file, flock. The filesystem was always shared; the sandbox just would not let the app name the path until the user granted it. That is why SQLite in WAL mode works across vendors there.

Android: one Unix user per app, SELinux, Binder. Each app is its own Linux UID. Its private directory is owned by that UID, mode 0700, and SELinux labels it with the owner’s category, so another UID cannot even stat it, and no user gesture changes that. Android’s picker (the Storage Access Framework) therefore does not hand out a path; it hands out a content URI backed by the owning app’s DocumentsProvider, i.e. a Binder RPC that streams bytes. You can get a file descriptor for a single document, but SQLite must open the database, the -wal, and the -shm by path itself and coordinate locks across processes on real files, which no RPC gives you. Shared external storage is the other candidate and is FUSE-mediated with scoped-storage rules, where WAL’s shared memory and locking are not reliable; Android’s own guidance forbids databases there.

The consequence. On iOS, “user picks a folder” equals “user grants filesystem access”, so cross-vendor sharing of one live database is legitimate. On Android, the only way to become “the same user” is sharedUserId, which is why v1 there is same-signature apps; anything across vendors has to go through IPC to a host app that owns the file, with the host doing every read and write on the others’ behalf.