M4: Fix download notification Share (ENG-270) #32

Merged demi.dev
targeting main from stoopkidddd/eng-270-fix-download-notification-share
Merged opened by and assigned to demi.dev
targeting main from stoopkidddd/eng-270-fix-download-notification-share

Linear: https://linear.app/engineereddev/issue/ENG-270 (M4 gate; bug from ENG-266)

The M4 gate's release-build run found that Share on the download-complete notification did nothing: the ACTION_CHOOSER wrapper carried a pneumo://download/share data URI (for PendingIntent identity), so it resolved to no activity (ActivityNotFoundException in SystemUI). Home's Share worked.

What's in this PR (7 files):

  • New non-exported, no-display trampoline notify/DownloadShareActivity (taskAffinity="", noHistory, excludeFromRecents), mirroring DownloadOpenActivity. The notification's Share PendingIntent targets it with the file's content URI and MIME as intent data/type (per-notification identity); it starts a data-free system chooser for that file and finishes. Only content:// URIs are accepted.
  • DownloadActions.kt: Share PendingIntent built for the trampoline. Notification ids/tags, group/summary rules and the progress throttle are unchanged.
  • Tests: DownloadActionsTest (fails on the old code on API 26 and 34: the Share intent resolves; two files get two distinct Share targets); RealServerSmokeTest now fires the completed notification's real Share PendingIntent and checks the chooser's file URI, MIME, clip data and read grant.
  • docs/SPEC.md §14.2: one sentence noting the two library-merged permissions (WAKE_LOCK from WorkManager, the signature-level DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION from androidx.core), found by the gate's merged-manifest check.

Verify (lead, on 0261414):

  • mise run check:android → exit 0
  • ./gradlew testDebugUnitTest --rerun → exit 0 (355 tests, 0 failures)
  • mise run e2e:android → exit 0 (real-server smoke incl. Share; secret scan 0 matches; full cleanup)

🤖 Generated with Claude Code

Commits 1

M4: Fix download notification Share (ENG-270)