Skip to content

Clean up orphaned MediaScratchFileProvider scratch-space URIs #284

Description

@inthewaves

MediaScratchFileProvider stores temporary media under the application's cache directory, but it has no general cleanup mechanism. Most attachment-oriented users explicitly delete scratch-space URIs when their owner is discarded or replaced by permanent telephony parts. External preview, sharing, and vCard-import handoffs can create scratch copies without an application-controlled deletion path, leaving those files until Android happens to evict the application cache. Android documentation says to not rely on this system cache evict behavior (https://developer.android.com/training/data-storage/app-specific#internal-remove-cache) and that caches should be explicitly managed

Current behavior

UriUtil.persistContentToScratchSpace() creates a new scratch-space URI and returns it without associating an owner, purpose, expiration, or cleanup callback with the file. In practice, cleanup is caller-owned: each caller is responsible for deleting its scratch-space URI through the content resolver once the file is no longer needed.

Existing cleanup behavior

Missing terminal cleanup

External activities may read a granted URI asynchronously, so deleting these files immediately after startActivity() would be unsafe. However, relying solely on opportunistic cache eviction means repeated previews, shares, and contact imports can accumulate private copies indefinitely from the application's perspective.

Android's app-specific storage guidance explicitly says applications should maintain their own internal cache files rather than rely on the system to clean them up.

Impact

  • A vCard scratch copy can retain names, phone numbers, email addresses, and other contact data after the import activity has finished and after the originating message or conversation is deleted.
  • Preview and sharing scratch copies can retain images, documents, or other attachment content after the receiving activity has finished and after the original source is deleted.
  • The files remain in application-private credential-encrypted cache storage, limiting ordinary cross-application exposure, but that does not make retaining content beyond its useful or user-expected lifetime desirable.

Proposed approach

  • Add a bounded cleanup mechanism for orphaned MediaScratchFileProvider files.
  • Keep active draft, pending-message, sending-message, and retryable failed-message attachments until they are discarded or replaced by permanent telephony parts.
  • Delete files immediately where completion is observable, preserving the existing conversion and attachment cleanup behavior.
  • Mark or isolate external-handoff files so they can be pruned conservatively by age after a grace period long enough for external consumers to finish reading them.
  • Run orphan cleanup at a safe maintenance point such as application startup, excluding files referenced by known active owners.
  • Make cleanup idempotent and tolerate files already removed by Android's cache eviction.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions