From 94ea2569ee34a28c88923b8cf2af7df648c2cce4 Mon Sep 17 00:00:00 2001 From: Duncan Tourolle Date: Sat, 26 Sep 2026 16:08:22 -0400 Subject: [PATCH] Tag the SAF export path FR-EXP-10 only, not FR-PLAT-AND-1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit saf.rs and the export path's SAF branch shipped tagged FR-PLAT-AND-1, and the matrix counted the requirement as covered. Its subject is the library — reached through SAF grants — and Android still reaches a library over a Nextcloud account or a folder path. What the SAF code does is give an album a folder on the tablet, which is FR-EXP-10. outstanding.md said the figure overstated it and should be read with this one subtracted; it now says the tags were narrowed, and coverage reads 161 of 192. --- docs/dev/outstanding.md | 12 ++++++------ ui/dr-ui/src/export.rs | 2 +- ui/dr-ui/src/saf.rs | 6 +++++- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/docs/dev/outstanding.md b/docs/dev/outstanding.md index ff531dc..2e167fb 100644 --- a/docs/dev/outstanding.md +++ b/docs/dev/outstanding.md @@ -250,12 +250,12 @@ about. 0.17.0 brought the first real SAF code, for albums (FR-EXP-10): `FolderPicker.java` starts `ACTION_OPEN_DOCUMENT_TREE` from a translucent activity of its own (the main activity is `NativeActivity`, whose results are not ours) and takes a persistable grant; `Saf.java` writes each -export through `DocumentsContract`; `ui/dr-ui/src/saf.rs` is the JNI bridge. `saf.rs` and the export -path now carry `TRACES: FR-PLAT-AND-1`, and the matrix counts the requirement as covered. **That -overstates it.** The mechanism is the one the requirement names, but its subject is the library, and -Android still reaches a library through a Nextcloud account or a folder, over paths, like the -desktop. Either the tags narrow to FR-EXP-10 or the requirement is met for the library too; until -one of those, read the coverage figure with this one subtracted. +export through `DocumentsContract`; `ui/dr-ui/src/saf.rs` is the JNI bridge. They shipped tagged +`TRACES: FR-PLAT-AND-1`, which made the matrix count the requirement as covered, and that overstated +it: the mechanism is the one the requirement names, but its subject is the library, and Android +still reaches a library through a Nextcloud account or a folder, over paths, like the desktop. The +tags now say FR-EXP-10 alone (0.17.1), so FR-PLAT-AND-1 reads as uncovered again until the library +itself is reached through SAF. That has a consequence for the rest of the cluster: **FR-PLAT-AND-2** — detecting the loss of a granted tree permission and marking images offline rather than deleting rows — is still blocked for diff --git a/ui/dr-ui/src/export.rs b/ui/dr-ui/src/export.rs index d89c74f..9e98cea 100644 --- a/ui/dr-ui/src/export.rs +++ b/ui/dr-ui/src/export.rs @@ -213,7 +213,7 @@ pub fn place( if destination.trim().is_empty() { return Err("No export folder is set. Choose an album to export to.".into()); } - // TRACES: FR-EXP-10 | FR-PLAT-AND-1 + // TRACES: FR-EXP-10 // A SAF tree on Android: written through the provider, which may // rename on a collision, so the name it reports is the one kept. #[cfg(target_os = "android")] diff --git a/ui/dr-ui/src/saf.rs b/ui/dr-ui/src/saf.rs index 38d6e06..cc77f6e 100644 --- a/ui/dr-ui/src/saf.rs +++ b/ui/dr-ui/src/saf.rs @@ -1,6 +1,10 @@ -//! TRACES: FR-EXP-10 | FR-PLAT-AND-1 +//! TRACES: FR-EXP-10 //! Android's Storage Access Framework, for an album's folder on the device. //! +//! Export folders only. FR-PLAT-AND-1 asks for the *library* to be reached +//! through SAF, and it still is not — a library on the tablet is a server — +//! so this module does not claim it. +//! //! The folder is chosen in the system's own picker, which can make a new //! folder too, and comes back as a tree URI with a persisted grant. Exports //! are then written into it through `DocumentsContract` — a tree URI is not a