Performance UX and storage freshness
Purpose
Treeger should feel ready when a browse surface appears. Opening Home, Gallery, Documents, or Recents must not routinely expose discovery work, replace useful content with a progress indicator, or move the user’s reading position when fresher data arrives.
This design separates three concerns:
-
presentation continuity: keep a stable, useful screen;
-
catalogue freshness: discover external storage changes without blocking navigation;
-
measured performance: optimize queries and rendering only after the user journey is stable.
User experience contract
Home
-
The first Home frame uses persisted Recently Used and Recently Added data.
-
Recent sections do not appear after the rest of Home has already settled.
-
A new item may update a deck while the user is at its start.
-
When the user has moved away from the start, Treeger preserves position and offers the existing new-items affordance instead of forcing a jump.
Content spaces
-
A persisted snapshot is displayed immediately after process recreation or a cold launch.
-
Routine background reconciliation does not replace a usable snapshot with a loading state.
-
Progressive scan indicators are not inserted above visible content.
-
A blocking loading state is allowed only when no persisted or in-memory snapshot exists.
-
A completed empty snapshot is different from data that has not loaded yet.
-
A failed refresh leaves the last usable snapshot visible.
Hierarchical folders and pickers
-
Explorer, Add Pin, and the transfer destination picker share one folder-session model.
-
A folder snapshot is keyed by URI and listing-affecting sort settings, not by a built-in Space ID.
-
A persisted listing is displayed while the live directory is reconciled.
-
A first visit with no snapshot shows a stable loading state.
-
An unreadable folder is an error; it is never presented as an empty folder.
-
A completed empty listing is persisted and remains distinct from data that has not loaded.
Truthfulness
Persisted content is a last-known projection, not a promise that every file still exists. Treeger validates files when they are opened and reconciles moved or deleted entries during refresh. The product UI must not expose scan counters or implementation diagnostics during routine browsing.
Data ownership
Room is the source of truth for persisted browse snapshots. The cache stores the complete model required by the current UI, including:
-
stable URI;
-
name, size, MIME type, and modified date;
-
media date used by Gallery sorting;
-
ancestor names and URIs used by location labels and Show in folder;
-
Recently Added activity time and location label;
-
a definition key that invalidates a snapshot when its Space definition changes.
The UI continues to observe ViewModel state. The ViewModel hydrates that state from Room, reconciles against the platform source, then replaces the snapshot atomically. Partial discovery results are useful on a first-ever load, but they never replace an existing complete snapshot.
Cold-launch sequence
-
Read preferences, Recently Used, and the small Recently Added snapshot.
-
Render Home from persisted state.
-
When a content Space opens, read its persisted snapshot.
-
When a hierarchical folder or picker opens, read its persisted direct-child snapshot.
-
Start platform reconciliation asynchronously.
-
Publish a complete replacement and persist it in one transaction.
An install, cleared app data, or the first visit to a Space has no previous snapshot. That path may show a stable initial loading state until the first usable results arrive. Home reserves the Recently Added deck geometry with a quiet placeholder so the sections below it do not jump when that first result arrives.
Storage change sources
Changes made by Treeger
Treeger writes its own successful copy, move, rename, trash, and restore results into browse state immediately. It must not wait for MediaStore to report an operation Treeger already knows completed.
Changes while the process is alive
ContentObserver notifications mark affected projections stale. Notifications are debounced and trigger reconciliation; they do not clear visible data. Media-specific spaces should observe or query the narrowest useful MediaStore collections.
Changes while the process is absent
A later delivery can use a content-URI-triggered WorkManager request for MediaStore Images, Video, Downloads, and the broader Files collection where required. The work is system scheduled and may be batched; it is not a real-time daemon.
On Android 11 and newer, synchronization should record MediaStore version and generation values and query additions or modifications incrementally. Android 10 requires a bounded-query fallback plus occasional reconciliation.
Coverage limits
There is no ordinary-app API that continuously observes every filesystem and document-provider mutation while Treeger is not running. FileObserver is appropriate only for selected real directories while a process owns it. MediaStore covers camera output, screenshots, media, and many downloads. Resume-time and occasional constrained reconciliation remain necessary for non-indexed files and providers.
Delivery stages
Stage 1: continuity
-
Persist complete content snapshots and Recently Added.
-
Hydrate them before the corresponding first useful frame.
-
Keep snapshots visible during refresh.
-
Remove progress rows above visible Gallery content.
-
Restart an incomplete scan when a user returns to a Space.
-
Narrow media-only MediaStore queries before Kotlin-side filtering.
-
Persist and retain hierarchical folder listings across Explorer and both folder pickers.
-
Gate navigation on all persisted UI state needed by Home and immediately reachable screens.
Stage 2: background freshness
-
Add content-URI-triggered work.
-
Persist MediaStore version and generation checkpoints.
-
Apply Treeger-owned mutations directly to cached projections.
-
Scope invalidation by content kind instead of refreshing every visible content Space.
Stage 3: measured optimization
-
Add cold and warm startup Macrobenchmarks.
-
Measure Home layout stability, Gallery time to usable content, and scroll frame timing on a physical device.
-
Use traces to choose query, database, thumbnail, and recomposition optimizations.
-
Add Baseline and Startup Profiles after the critical journeys are stable.
Verification
Automated coverage should include:
-
database migration and snapshot replacement;
-
Space-definition invalidation;
-
empty-complete versus never-loaded state;
-
cancelled incomplete discovery restarting on re-entry;
-
media-only selection being pushed into the MediaStore query;
-
cached Recently Added ordering and timestamps.
Physical-device review should cover:
-
cold launch with existing data;
-
first launch with no cache;
-
opening Gallery twice;
-
leaving Gallery during discovery and returning;
-
adding a camera image or download while Treeger is foregrounded;
-
returning after an external change without losing scroll position.
-
reopening an Explorer folder after process recreation;
-
navigating Add Pin and transfer destinations through empty and populated folders;
-
a folder read failure showing Retry rather than an empty-folder message.
Thumbnail persistence and the full-screen Peek pipeline are separate performance work. Archive parsing is also outside this continuity delivery unless device measurements show it is a material delay.