FR-PLAT-AND-1 — library access on Android obtained exclusively through the Storage Access Framework. No SAF code exists.
The state of it
No ACTION_OPEN_DOCUMENT_TREE, no takePersistableUriPermission, no DocumentsContract. Android reaches a library through a Nextcloud account or a folder, over paths, like the desktop.
This requirement previously carried two tags and both have been removed, because what they rested on was intent rather than code:
A SourceRef::Document variant constructed only inside #[cfg(test)]. LocalStorage::open refuses it, and the test proving so is named a_reference_of_the_wrong_kind_is_refused_rather_than_guessed_at.
dr_plat::imports_supported, which returns false on Android, and whose own documentation says it "stops being false when a SAF implementation lands". That tag documented the absence of the thing it was counted as evidence for.
CONTRIBUTING.md and code-health.md CH-4 both warn about exactly this case: plumbing a future feature would use, counted as the feature.
Why it is the keystone of the Android cluster
It blocks:
#26 — FR-PLAT-AND-2 cannot detect the loss of a granted tree permission until there is a permission to lose.
Spike S10 — whether SAF at 10k files meets NFR-P1/P3 — which has no code to measure.
And §4.8 observes that publishing on Play is what turns SAF from a preference into a constraint (see #31).
Acceptance
A tree grant obtained through ACTION_OPEN_DOCUMENT_TREE and persisted.
SourceRef::Document is resolvable outside tests; LocalStorage::open honours it.
dr_plat::imports_supported returns true on Android, and its documentation stops describing a future.
Measured at 10k files (spike S10) before it is claimed.
See docs/outstanding.md §5.
**FR-PLAT-AND-1 — library access on Android obtained exclusively through the Storage Access Framework.** No SAF code exists.
## The state of it
No `ACTION_OPEN_DOCUMENT_TREE`, no `takePersistableUriPermission`, no `DocumentsContract`. Android reaches a library through a Nextcloud account or a folder, **over paths, like the desktop**.
This requirement previously carried two tags and both have been removed, because what they rested on was intent rather than code:
- A `SourceRef::Document` variant constructed only inside `#[cfg(test)]`. `LocalStorage::open` refuses it, and the test proving so is named `a_reference_of_the_wrong_kind_is_refused_rather_than_guessed_at`.
- `dr_plat::imports_supported`, which **returns false on Android**, and whose own documentation says it "stops being false when a SAF implementation lands". That tag documented the absence of the thing it was counted as evidence for.
`CONTRIBUTING.md` and `code-health.md` CH-4 both warn about exactly this case: plumbing a future feature would use, counted as the feature.
## Why it is the keystone of the Android cluster
It blocks:
- #26 — FR-PLAT-AND-2 cannot detect the loss of a granted tree permission until there is a permission to lose.
- Spike S10 — whether SAF at 10k files meets NFR-P1/P3 — which has no code to measure.
And §4.8 observes that publishing on Play is what turns SAF from a preference into a constraint (see #31).
## Acceptance
- [ ] A tree grant obtained through `ACTION_OPEN_DOCUMENT_TREE` and persisted.
- [ ] `SourceRef::Document` is resolvable outside tests; `LocalStorage::open` honours it.
- [ ] `dr_plat::imports_supported` returns true on Android, and its documentation stops describing a future.
- [ ] Measured at 10k files (spike S10) before it is claimed.
See `docs/outstanding.md` §5.
Blocks#26 (no permission to lose) and spike S10 (no SAF code to measure). Design alongside#29 — the portal picker on Linux is the same problem with a different API, and LocalStorage::grant is where both land. Informed by#31 — whether Play makes this binding.
**Blocks** #26 (no permission to lose) and spike S10 (no SAF code to measure).
**Design alongside** #29 — the portal picker on Linux is the same problem with a different API, and `LocalStorage::grant` is where both land.
**Informed by** #31 — whether Play makes this binding.
caae65c7, in v0.19.3, makes dr_plat::imports_supported true on Android, but not through SAF. So this issue stays open, and one of its premises has changed.
An import reads the camera card by path (/storage/9C33-6BBD) with "all files access" (MANAGE_EXTERNAL_STORAGE), not through a tree grant. Cards.java lists the volumes through StorageManager. Until the user grants access, the import page asks for it and opens the system settings page. SAF was not used for two reasons:
Since API 30, ACTION_OPEN_DOCUMENT_TREE refuses the root of an SD card.
Reading through SAF would need a second storage implementation under the importer, where reading by path needs none.
What this means for the acceptance list above:
dr_plat::imports_supported returns true on Android. Its documentation now describes the path route instead of a future SAF implementation.
Still open: the tree grant, SourceRef::Document, and S10. The library still reaches its files through an account or a folder, as before.
Two points need a decision:
The requirement's wording. FR-PLAT-AND-1 says "exclusively" through SAF. Either the requirement scopes that word to the library, or the card import has to move to SAF.
Play.MANAGE_EXTERNAL_STORAGE is one of the permissions Play restricts. That is fine while DarkRoom is sideloaded, but it changes what S11 (#31) would conclude if Play is ever a channel.
**caae65c7, in v0.19.3, makes `dr_plat::imports_supported` true on Android, but not through SAF.** So this issue stays open, and one of its premises has changed.
An import reads the camera card by path (`/storage/9C33-6BBD`) with "all files access" (`MANAGE_EXTERNAL_STORAGE`), not through a tree grant. `Cards.java` lists the volumes through `StorageManager`. Until the user grants access, the import page asks for it and opens the system settings page. SAF was not used for two reasons:
- Since API 30, `ACTION_OPEN_DOCUMENT_TREE` refuses the root of an SD card.
- Reading through SAF would need a second storage implementation under the importer, where reading by path needs none.
What this means for the acceptance list above:
- [x] `dr_plat::imports_supported` returns true on Android. Its documentation now describes the path route instead of a future SAF implementation.
- [ ] Still open: the tree grant, `SourceRef::Document`, and S10. The *library* still reaches its files through an account or a folder, as before.
Two points need a decision:
- **The requirement's wording.** FR-PLAT-AND-1 says "exclusively" through SAF. Either the requirement scopes that word to the library, or the card import has to move to SAF.
- **Play.** `MANAGE_EXTERNAL_STORAGE` is one of the permissions Play restricts. That is fine while DarkRoom is sideloaded, but it changes what S11 (#31) would conclude if Play is ever a channel.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
FR-PLAT-AND-1 — library access on Android obtained exclusively through the Storage Access Framework. No SAF code exists.
The state of it
No
ACTION_OPEN_DOCUMENT_TREE, notakePersistableUriPermission, noDocumentsContract. Android reaches a library through a Nextcloud account or a folder, over paths, like the desktop.This requirement previously carried two tags and both have been removed, because what they rested on was intent rather than code:
SourceRef::Documentvariant constructed only inside#[cfg(test)].LocalStorage::openrefuses it, and the test proving so is nameda_reference_of_the_wrong_kind_is_refused_rather_than_guessed_at.dr_plat::imports_supported, which returns false on Android, and whose own documentation says it "stops being false when a SAF implementation lands". That tag documented the absence of the thing it was counted as evidence for.CONTRIBUTING.mdandcode-health.mdCH-4 both warn about exactly this case: plumbing a future feature would use, counted as the feature.Why it is the keystone of the Android cluster
It blocks:
And §4.8 observes that publishing on Play is what turns SAF from a preference into a constraint (see #31).
Acceptance
ACTION_OPEN_DOCUMENT_TREEand persisted.SourceRef::Documentis resolvable outside tests;LocalStorage::openhonours it.dr_plat::imports_supportedreturns true on Android, and its documentation stops describing a future.See
docs/outstanding.md§5.Blocks #26 (no permission to lose) and spike S10 (no SAF code to measure).
Design alongside #29 — the portal picker on Linux is the same problem with a different API, and
LocalStorage::grantis where both land.Informed by #31 — whether Play makes this binding.
caae65c7, in v0.19.3, makesdr_plat::imports_supportedtrue on Android, but not through SAF. So this issue stays open, and one of its premises has changed.An import reads the camera card by path (
/storage/9C33-6BBD) with "all files access" (MANAGE_EXTERNAL_STORAGE), not through a tree grant.Cards.javalists the volumes throughStorageManager. Until the user grants access, the import page asks for it and opens the system settings page. SAF was not used for two reasons:ACTION_OPEN_DOCUMENT_TREErefuses the root of an SD card.What this means for the acceptance list above:
dr_plat::imports_supportedreturns true on Android. Its documentation now describes the path route instead of a future SAF implementation.SourceRef::Document, and S10. The library still reaches its files through an account or a folder, as before.Two points need a decision:
MANAGE_EXTERNAL_STORAGEis one of the permissions Play restricts. That is fine while DarkRoom is sideloaded, but it changes what S11 (#31) would conclude if Play is ever a channel.