Skip to content

Treat KEYCODE_MEDIA_PLAY as explicit play instead of a play/pause toggle#5426

Draft
joashrajin wants to merge 1 commit into
mainfrom
fix/3919-android-auto-media-play-toggle
Draft

Treat KEYCODE_MEDIA_PLAY as explicit play instead of a play/pause toggle#5426
joashrajin wants to merge 1 commit into
mainfrom
fix/3919-android-auto-media-play-toggle

Conversation

@joashrajin

Copy link
Copy Markdown
Contributor

Description

Car head units and some other media controllers send an explicit
KEYCODE_MEDIA_PLAY to resume playback — for example, a Chinese head unit
running ZLink5/Android Auto sends it when shifting out of reverse. Both
media-session code paths mapped KEYCODE_MEDIA_PLAY to a single-tap
play/pause toggle, so when audio was already playing the toggle paused it.
This matches the reporter's logs: a KEYCODE_MEDIA_PLAY from gearhead
immediately followed by "Paused - Not transient".

KEYCODE_MEDIA_PLAY is an explicit play command, distinct from
KEYCODE_MEDIA_PLAY_PAUSE (toggle) and KEYCODE_HEADSETHOOK (toggle). This PR
makes a single tap originating from KEYCODE_MEDIA_PLAY resume playback
rather than toggle, so it never pauses already-playing audio.

The key still flows through MediaEventQueue, preserving the existing
suppression of the spurious KEYCODE_MEDIA_PLAY that some Bluetooth headphones
(e.g. Pixel Buds) emit right after a next/previous gesture. KEYCODE_MEDIA_PAUSE
was already handled correctly and is unchanged.

Changed in both playback paths so the fix applies regardless of the
media3_session feature flag:

  • Media3SessionCallback — the Media3 rollout path
  • MediaSessionManager — the legacy path that ships on release builds today

Fixes #3919

Testing Instructions

These steps simulate the car's media-button behaviour with ADB (keycode 126 =
KEYCODE_MEDIA_PLAY, 85 = KEYCODE_MEDIA_PLAY_PAUSE). Repeat with the Media3
MediaSession
dev toggle both OFF and ON to cover both code paths.

  • Start playing an episode.
  • With audio playing, run adb shell input keyevent 126.
  • Verify playback continues (it must NOT pause). Before this fix it paused.
  • Pause the episode, then run adb shell input keyevent 126 again.
  • Verify playback resumes.
  • With audio playing, run adb shell input keyevent 85.
  • Verify KEYCODE_MEDIA_PLAY_PAUSE still toggles (pauses), confirming toggle behaviour is unchanged.
  • Verify wired/Bluetooth headset single-tap (play/pause) and double/triple-tap (next/previous) still behave as before.
  • (If a compatible head unit is available) Confirm playback no longer stops when shifting out of reverse.

Automated coverage: Media3SessionCallbackTest
KEYCODE_MEDIA_PLAY resumes playback instead of toggling (updated), and the
existing KEYCODE_MEDIA_PLAY_PAUSE single tap calls playPause still passes.

Screenshots or Screencast

⚠️ TODO (manual): n/a — no in-app UI changes. A screencast of the head-unit gear-shift scenario would be ideal but requires the reporter's hardware.

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 spreadsheet to reflect any new or changed analytics.

I have tested any UI changes...

⚠️ TODO (manual): n/a — this PR contains no UI changes.

Car head units (and other media controllers) send an explicit
KEYCODE_MEDIA_PLAY to resume playback - e.g. ZLink5/Android Auto sends
it when shifting out of reverse. Both media-session paths mapped it to a
single-tap play/pause toggle, so it paused already-playing audio.

Keep KEYCODE_MEDIA_PLAY routed through MediaEventQueue (preserving the
Pixel Buds spurious-duplicate suppression after next/previous), but when
a single tap originates from KEYCODE_MEDIA_PLAY, resume instead of
toggling. PLAY_PAUSE/HEADSETHOOK still toggle.

Fixes #3919
Copilot AI review requested due to automatic review settings June 15, 2026 10:39
@dangermattic

Copy link
Copy Markdown
Collaborator
1 Message
📖 This PR is still a Draft: some checks will be skipped.

Generated by 🚫 Danger

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes an Android Auto / car head-unit regression where an explicit KEYCODE_MEDIA_PLAY event (commonly sent to resume playback) was being treated as a play/pause toggle, causing already-playing audio to pause unexpectedly. The change is applied in both the Media3 and legacy MediaSession paths to ensure consistent behavior regardless of the media3_session feature flag.

Changes:

  • Treat KEYCODE_MEDIA_PLAY single-tap as an explicit play/resume command (calls playQueueSuspend) instead of playPause toggle.
  • Preserve KEYCODE_MEDIA_PLAY_PAUSE and KEYCODE_HEADSETHOOK as toggle behavior.
  • Update/adjust unit test coverage to assert the new KEYCODE_MEDIA_PLAY semantics.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
modules/services/repositories/src/main/java/au/com/shiftyjelly/pocketcasts/repositories/playback/Media3SessionCallback.kt In the Media3 session callback path, route KEYCODE_MEDIA_PLAY single-taps to explicit resume (playQueueSuspend) instead of toggling.
modules/services/repositories/src/main/java/au/com/shiftyjelly/pocketcasts/repositories/playback/MediaSessionManager.kt In the legacy MediaSessionCompat callback path, treat KEYCODE_MEDIA_PLAY single-taps as explicit play/resume while leaving toggle keys unchanged.
modules/services/repositories/src/test/java/au/com/shiftyjelly/pocketcasts/repositories/playback/Media3SessionCallbackTest.kt Update the regression test to verify KEYCODE_MEDIA_PLAY triggers playQueueSuspend and never calls playPause.

@joashrajin joashrajin added the [Area] Android Auto Android Auto integration through a phone label Jun 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Area] Android Auto Android Auto integration through a phone

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Android Auto: Playback stops when shifting out of reverse

3 participants