Skip to content

Add rewind after interruptions setting - #5611

Open
mpgirro wants to merge 2 commits into
Automattic:mainfrom
mpgirro:feature/rewind-after-interruptions
Open

Add rewind after interruptions setting#5611
mpgirro wants to merge 2 commits into
Automattic:mainfrom
mpgirro:feature/rewind-after-interruptions

Conversation

@mpgirro

@mpgirro mpgirro commented Jul 19, 2026

Copy link
Copy Markdown

Description

This PR adds an optional "Rewind after interruptions" setting: when playback resumes after an audio interruption (phone call, alarm, Assistant, Android Auto navigation prompt or another app taking audio focus), Pocket Casts seeks back a configurable number of seconds so listeners don't lose context. This is especially useful in the car, where navigation prompts regularly interrupt playback. A matching PR with identical behavior is open for iOS: Automattic/pocket-casts-ios#4788.

Behavior

  • New row in Settings > Playback, directly below Intelligent playback resumption: radio dialog with Off, 5, 10, 15, 30, 60 seconds (default: 5 seconds once the feature flag is enabled).
  • Rewind applies on both automatic resume (focus regained) and manual resume after an interruption-caused pause.
  • When Intelligent playback resumption would also rewind the same resume, the larger amount wins - the two never stack.
  • Only pauses caused by audio focus loss count as interruptions: ducking, headphone unplug (becoming noisy) and interruptions while already paused never trigger it; the rewind clamps at 0:00. Users who want every navigation prompt to trigger the rewind can set "Play over notifications" to never, making prompts pause playback.
  • Android Auto inherits the behavior automatically via the shared playback engine. On Automotive, a permanent focus loss stops playback (deactivating the MediaSession) as before - a stop is session teardown, not a pause, so no interruption rewind applies there by design.
  • Behind the new interruption_rewind feature flag (default: debug/prototype builds only). The setting is device-local; adding it to named-settings sync would need a server-side key and is left as a possible follow-up for maintainers.

Implementation notes

  • PlaybackManager.onFocusLoss marks its pause as interruption-caused; the marker travels through pauseSuspend and is consumed (and cleared) in onPlayerPaused, so pauses reaching that callback via other paths (sleep timer, cast receiver, error paths) can never reuse a stale value.
  • ResumptionHelper computes the existing pause-length ladder and the interruption rewind separately and applies maxOf() of the two.

Testing Instructions

  1. Run a debug build (flag interruption_rewind is on by default there) and start playing an episode.
  2. Go to Settings > Playback > Rewind after interruptions and pick e.g. 30 seconds.
  3. With "Play over notifications" set to never, trigger an interruption while playing: set an alarm that fires, or receive a phone call.
  4. When the alarm is dismissed / call ends, playback resumes and starts ~30 seconds before the interruption point.
  5. For a long interruption (>2 min, no auto-resume): press play manually - the rewind still applies.
  6. Set the setting to Off and verify resume happens exactly where playback stopped (for pauses shorter than 5 minutes).
  7. Verify no stacking: with interruption rewind 60s, interrupt for >5 minutes, resume - playback rewinds 60s (not 70s). A manual pause of >5 minutes still gets the unchanged Intelligent playback resumption rewind (10s).
  8. Verify a sleep-timer pause or headphone unplug followed by resume does not trigger the interruption rewind.

Screenshots or Screencast

The new settings row reuses the existing SettingRadioDialogRow component below Intelligent playback resumption.

Checklist

  • If this is a user-facing change, I have added an entry in CHANGELOG.md
  • Ensure the linter passes (./gradlew spotlessApply to automatically apply formatting/linting)
  • I have considered whether it makes sense to add tests for my changes
  • All strings that need to be localized are in modules/services/localization/src/main/res/values/strings.xml
  • Any jetpack compose components I added or changed are covered by compose previews
  • I have updated (or requested that someone edit) the Event Horizon schema to reflect any new or changed analytics. Maintainer action needed: the setting change should track a SettingsGeneralInterruptionRewindChangedEvent (value property = chosen seconds); the event type comes from the generated Event Horizon library, which I can't extend as an external contributor - there is a TODO at the call site in PlaybackSettingsFragment.

I have tested any UI changes...

  • with different themes
  • with a landscape orientation
  • with the device set to have a large display and font size
  • for accessibility with TalkBack

Rewinds playback by a configurable number of seconds (off, 5-60s,
default 5s) when it resumes after an audio interruption such as a
call, alarm or navigation prompt. When both this and intelligent
playback resumption would rewind the same resume, the larger amount
wins so they never stack. Ducking does not trigger a rewind, only
pauses caused by audio focus loss do.

Behind the interruption_rewind feature flag. Device-local setting,
not synced.
@mpgirro
mpgirro requested a review from a team as a code owner July 19, 2026 09:44
@mpgirro
mpgirro requested review from geekygecko and removed request for a team July 19, 2026 09:44
@CLAassistant

CLAassistant commented Jul 19, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants