Architecture
Architecture
Section titled “Architecture”System boundary
Section titled “System boundary”┌───────────────────────────────────────────────────────────────┐│ Android UI ││ Folder browser · Queue · Now playing · Inspector · Settings │└──────────────────────────────┬────────────────────────────────┘ │┌──────────────────────────────▼────────────────────────────────┐│ Playback/application layer ││ QueueBuilder · Browser state · Progress · Filter policies ││ Media3 MediaSessionService · renewable URL handling │└──────────────────────────────┬────────────────────────────────┘ │ AudioSource ┌─────────────────┼──────────────────┐ │ │ │┌────────────▼──────────┐ ┌────▼─────────────┐ ┌──▼──────────────┐│ Native pCloud source │ │ WebDAV source │ │ Local/SAF source││ official Java SDK │ │ fallback/testing │ │ future │└───────────────────────┘ └──────────────────┘ └─────────────────┘Core invariants
Section titled “Core invariants”- Folder and filename are first-class metadata, never incidental strings derived after scanning.
- A queue item preserves
sourceId, provider node ID, parent folder ID, and filename. - The now-playing model always knows its containing folder, enabling player → folder navigation.
- Stream URLs are capabilities with expiry times, not permanent file identities.
- Progress is keyed by stable source/node identity and guarded by content revision/hash when available.
- Tag data enriches a file; it does not replace the file’s path identity.
- Remote mutation is opt-in, previewed, and revision-aware.
Native pCloud flow
Section titled “Native pCloud flow”OAuth AuthorizationActivity → bearer token + regional API location → encrypted local token store → reusable ApiClient → listFolder(folderId) → AudioFolder / AudioTrack nodes → createFileLink(fileId) → Media3 MediaItem URIgetfilelink URLs expire. Before playback begins, and after HTTP expiry/failure, the playback resolver obtains a new link from the stable pCloud file ID. Queue persistence stores node IDs, never direct URLs.
Authentication
Section titled “Authentication”The official Android authorization module expects a registered pCloud application and an OAuth redirect URI of the form:
pcloud-oauth://dev.properpcloud.appThe source adapter itself depends on the portable java-core artifact. The Android OAuth feature depends separately on the android artifact; pCloud does not publish the Android artifact with a transitive java-core dependency. The OAuth client ID is build configuration, not a secret. OAuth and legacy auth tokens are credentials and must be stored with Android Keystore-backed encryption. OAuth requires no password exposure to properpcloud; the explicitly interim direct-login adapter handles a password only for one allowlisted regional HTTPS token request and never persists it.
The WebDAV fallback uses the account email/password and therefore has a larger credential-handling surface. It should support Android credential storage but remain optional.
Queue semantics
Section titled “Queue semantics”Folder actions:
- Play folder: replace queue with direct audio children.
- Play subtree: recursively enumerate descendants, preserving folder grouping.
- Play next: insert sorted folder content after current item.
- Append: add sorted folder content to queue.
- Shuffle folder: shuffle only after deterministic enumeration.
Default sort precedence:
disc number → track number → natural filenameUnknown tag numbers sort after known values. Users can switch to natural filename, tagged title, or modification time.
Progress model
Section titled “Progress model”Persist at least:
source_id: pcloudnode_id: pcloud:file:123456content_revision: provider hash when availableposition_ms: 1842050duration_ms: 7312000playback_speed: 1.15updated_at: 2026-08-01T21:00:00Zcompleted: falseMusic defaults to track-level resume disabled. Long-form audio defaults to resume enabled. The threshold and per-folder policy are configurable.
Metadata inspection and repair
Section titled “Metadata inspection and repair”Inspection presents three layers without silently conflating them:
- filesystem/provider metadata;
- embedded audio tags;
- effective display and sort values.
Repair pipeline, later phase:
scan → propose → diff → user approval → download/edit/upload → verify hash/tagspCloud revisions provide recovery after replacement, but the app must still expose a dry-run and never mass-edit silently.
Extensibility seam
Section titled “Extensibility seam”AudioSource deliberately exposes only browser, stream resolution, and inspection. Mutation, sync, thumbnails, search, and change feeds should be capability interfaces rather than continuously expanding one provider interface.
Suggested future capabilities:
interface SearchableSourceinterface MutableSourceinterface ChangeFeedSourceinterface ThumbnailSourceinterface OfflineCacheSource