Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Since 1.9.0, skip buttons in SLOT_BACK / SLOT_FORWARD reach legacy controllers as custom actions

Open
#3,495 1 comment 0 reactions 1 assignee View on GitHub

Maintainers usually reply within 4 days

@marcbaechinger is already working on this.

Since Oct 28, 2026.

Assessment

This issue has not been assessed yet.

Description

bug
Version

Media3 1.11.1

More version details

The behaviour starts in 1.9.0 and is the same on main. 1.8.x does not have it.

The session sets media button preferences with setMediaButtonPreferences. They include a CommandButton with player command COMMAND_SEEK_TO_PREVIOUS in SLOT_BACK and one with COMMAND_SEEK_TO_NEXT in SLOT_FORWARD.

1.9.0 and later. Commit 8b334e45a9 "Use standard commands in custom layout conversion" (in 1.9.0 as cherry-pick 0527f5a2de) makes this intentional. The 1.9.0 release note:

Add backwards-compatibility for CommandButton instances using Player.Command or non-custom SessionCommand to define their action. These are now correctly represented in platform media sessions, for example for System UI or Android Auto.

CommandButton.getCustomLayoutFromMediaButtonPreferences now accepts any button that can execute its action, and converts it with convertToPredefinedCustomCommandButton. That method names it after the player command (CommandButton.java#L1635-L1637):

    } else {
      customCommandName = CUSTOM_COMMAND_PLAYER_COMMAND_PREFIX + playerCommand;
    }

with (CommandButton.java#L506-L507):

  private static final String CUSTOM_COMMAND_PLAYER_COMMAND_PREFIX =
      "androidx.media3.session.PLAYER_COMMAND_";

MediaSessionLegacyStub.createPlaybackStateCompat then removes the standard skip action for a filled slot (MediaSessionLegacyStub.java#L1923-L1930):

    if (!mediaButtonPreferences.isEmpty()
        && CommandButton.containsButtonForSlot(customLayout, CommandButton.SLOT_BACK)) {
      actions &= ~PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS;
    }
    if (!mediaButtonPreferences.isEmpty()
        && CommandButton.containsButtonForSlot(customLayout, CommandButton.SLOT_FORWARD)) {
      actions &= ~PlaybackStateCompat.ACTION_SKIP_TO_NEXT;
    }

So the legacy session publishes custom actions androidx.media3.session.PLAYER_COMMAND_7 and androidx.media3.session.PLAYER_COMMAND_9, in that order (Previous, then Next). It does not publish ACTION_SKIP_TO_PREVIOUS or ACTION_SKIP_TO_NEXT.

1.8.x. getCustomLayoutFromMediaButtonPreferences skips a button without a custom session command (CommandButton.java#L1592-L1597):

      CommandButton button = mediaButtonPreferences.get(i);
      if (!button.isEnabled
          || button.sessionCommand == null
          || button.sessionCommand.commandCode != COMMAND_CODE_CUSTOM) {
        continue;
      }

The skip buttons do not fill a slot, so the session keeps the standard skip actions. The same app code gives a correct car layout on 1.8.x.

The Media3 guide for mobile surfaces documents the new result: when the media button preferences contain a button for SLOT_BACK, that slot shows "Custom".

Devices that reproduce the issue
  • Android Automotive OS emulator, android-35-ext15 automotive Play Store image, car media app
  • Android Auto (Desktop Head Unit)
  • Phone system media controls
Devices that do not reproduce the issue

None known.

Reproducible in the demo app?

Not tested.

Reproduction steps
  1. In a MediaLibraryService, call setMediaButtonPreferences with:
    • a CommandButton with Player.COMMAND_SEEK_TO_PREVIOUS, ICON_PREVIOUS, slot SLOT_BACK
    • a CommandButton with Player.COMMAND_SEEK_TO_NEXT, ICON_NEXT, slot SLOT_FORWARD
  2. Give the playing MediaItem a heart rating (MediaMetadata.Builder.setUserRating(HeartRating(false))), as an app with favorites does.
  3. Start playback.
  4. Read MediaControllerCompat.getPlaybackState() from a legacy controller. Check the actions and the custom actions.
  5. Open the playback view in the Android Automotive OS car media app.
Expected result

A button whose command is the standard skip command, in its own slot, is published as ACTION_SKIP_TO_PREVIOUS / ACTION_SKIP_TO_NEXT, as before 1.9.0. It is not published as a custom action.

Actual result

The playback state has no skip actions. It has custom actions PLAYER_COMMAND_7 and PLAYER_COMMAND_9, in that order.

On Android Automotive OS the order on screen is wrong. The cause is in the AOSP car media app (packages/apps/Car/libs, car-media-common), not in Media3's order:

  • PlaybackViewModel.getCustomActions puts the rating action first, for a RATING_HEART session, then the session's custom actions.
  • MediaButtonController.updateCustomActions fills slots by list position. With no standard skip actions, the first custom action goes in the left slot, the second in the right slot, and the rest outside.

With the heart rating from step 2, the bar on the emulator reads:

Next, rating star, play/pause, Previous

Without a rating, Previous and Next land left and right of play/pause. The order then looks right, but the buttons are still custom actions.

On phone system media controls and Android Auto, the layout is right. The only difference is the icons: they draw Media3's icons, not the surface's own skip icons.

Workaround: leave the skip buttons out of setMediaButtonPreferences. The session then keeps the standard skip actions, and each surface draws its own skip buttons. This works on Android Auto (DHU), Android 13 and 16 phone media controls, the Android 12L notification, and the Android Automotive OS emulator. The slots are not always reserved: the seek bar workaround in MediaSessionLegacyStub (needsButtonReservationWorkaroundForSeekbar) never reserves the next slot.

The mobile surfaces table shows Previous and Next when the back and forward slots are empty, so apps can leave skip out. But placing skip in its own slot is a natural reading of the slot API, and since 1.9.0 it gives a wrong layout on car UIs.

Request: for a skip button in its own slot, please publish the standard skip action, as in 1.8.x. If that is not possible, please document that apps should leave skip out of the media button preferences.

Media

Not applicable — no specific media needed.

Bug Report

Will provide on request.

Dominant language
Java
Stars
3.1k
Forks
998
Avg merge
6d 8h
Merged PRs (30d)
2

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from androidx/media

All issues in androidx/media

Similar issues

More Java issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.