androidx / media

Jetpack Media3 support libraries for media use cases, including ExoPlayer, an extensible media player for Android
Apache License 2.0
1.36k stars 322 forks source link

The first pause key press on a bluetooth headset isn't handled correctly #159

Open nitehu opened 1 year ago

nitehu commented 1 year ago

Media3 Version

1.0.0-beta02

Devices that reproduce the issue

Samsung Galaxy Note 9 with Android 10, Soundcore Spirit BT Headset

Devices that do not reproduce the issue

No response

Reproducible in the demo app?

Yes

Reproduction steps

  1. Start a song in the Session Demo app
  2. send app to background
  3. stop playback and dismiss notification
  4. press start/pause on BT Headset - playback starts
  5. press start/pause on BT Headset - nothing happens
  6. press start/pause on BT Headset - playback pauses

Expected result

Playback should pause when pressing the play/pause button for the first time on the BT headset

Actual result

Playback only pauses when pressing the play/pause button twice on the BT headset

Media

Any media from the session demo app

Bug Report

nitehu commented 1 year ago

Logcat: logcat.txt

From the logs, it is not clear if it is an android problem or a media3 one. It can possibly be reproduced with any BT Headsets with a single play/pause button, at least my car radio had this problem too.

The first key press is interpreted as KEYCODE_MEDIA_PLAY, however the music is already playing, and it should be a pause. Only the second key press appears as KEYCODE_MEDIA_PAUSE.

As I remember, we had to implement a workaround for this when we used the old media library. When we received a KEYCODE_MEDIA_PLAY, we checked if media was already playing, and paused it if it was.

I'm not sure what we can do to solve this now with media3, as media3 implements its own BT key handling. Should we somehow disable all that and use our own solution? Or do you know any better alternatives?

marcbaechinger commented 1 year ago

I can not repro this behaviour I'm afraid. I tested on Android 13 with a Pixel 5 and on Android 8 and Android 10 with a Pixel and I see that the key events sent to the app are reliably the ones I would expect (126 - KEYCODE_MEDIA_PLAY and 127 - KEYCODE_MEDIA_PAUSE).

The key event is first delivered to MediaSessionLegacyStub.onMediaButtonEvent but it is not handled there (returns false) and then onPlay()/onPause() is called as expected.

Do you see this on another Android version than 10 as well?

2022-08-31 18:32:12.058   902-2166  MediaSessionService     pid-902                              D  Sending KeyEvent { action=ACTION_DOWN, keyCode=KEYCODE_MEDIA_PLAY, scanCode=0, metaState=0, flags=0x0, repeatCount=0, eventTime=0, downTime=0, deviceId=-1, source=0x0 } to androidx.media3.demo.session/androidx.media3.session.id. (userId=0)
2022-08-31 18:32:12.075   902-2166  MediaSessionService     pid-902                              D  Sending KeyEvent { action=ACTION_UP, keyCode=KEYCODE_MEDIA_PLAY, scanCode=0, metaState=0, flags=0x0, repeatCount=0, eventTime=0, downTime=0, deviceId=-1, source=0x0 } to androidx.media3.demo.session/androidx.media3.session.id. (userId=0)
2022-08-31 18:32:12.089 24591-24591 onMediaButtonEvent      androidx.media3.demo.session         D  received keyCode: 126, string: KeyEvent { action=ACTION_DOWN, keyCode=KEYCODE_MEDIA_PLAY, scanCode=0, metaState=0, flags=0x0, repeatCount=0, eventTime=0, downTime=0, deviceId=-1, source=0x0 }
2022-08-31 18:32:12.099 24591-24591 onMediaButtonEvent      androidx.media3.demo.session         D  onPlay()
2022-08-31 18:32:30.246   902-1515  MediaSessionService     pid-902                              D  Sending KeyEvent { action=ACTION_DOWN, keyCode=KEYCODE_MEDIA_PAUSE, scanCode=0, metaState=0, flags=0x0, repeatCount=0, eventTime=0, downTime=0, deviceId=-1, source=0x0 } to androidx.media3.demo.session/androidx.media3.session.id. (userId=0)
2022-08-31 18:32:30.255 24591-24591 onMediaButtonEvent      androidx.media3.demo.session         D  received keyCode: 127, string: KeyEvent { action=ACTION_DOWN, keyCode=KEYCODE_MEDIA_PAUSE, scanCode=0, metaState=0, flags=0x0, repeatCount=0, eventTime=0, downTime=0, deviceId=-1, source=0x0 }
2022-08-31 18:32:30.259 24591-24591 onMediaButtonEvent      androidx.media3.demo.session         D  onPause()
2022-08-31 18:32:30.262   902-1515  MediaSessionService     pid-902                              D  Sending KeyEvent { action=ACTION_UP, keyCode=KEYCODE_MEDIA_PAUSE, scanCode=0, metaState=0, flags=0x0, repeatCount=0, eventTime=0, downTime=0, deviceId=-1, source=0x0 } to androidx.media3.demo.session/androidx.media3.session.id. (userId=0)
2022-08-31 18:32:35.582   902-2166  MediaSessionService     pid-902                              D  Sending KeyEvent { action=ACTION_DOWN, keyCode=KEYCODE_MEDIA_PLAY, scanCode=0, metaState=0, flags=0x0, repeatCount=0, eventTime=0, downTime=0, deviceId=-1, source=0x0 } to androidx.media3.demo.session/androidx.media3.session.id. (userId=0)
2022-08-31 18:32:35.596 24591-24591 onMediaButtonEvent      androidx.media3.demo.session         D  received keyCode: 126, string: KeyEvent { action=ACTION_DOWN, keyCode=KEYCODE_MEDIA_PLAY, scanCode=0, metaState=0, flags=0x0, repeatCount=0, eventTime=0, downTime=0, deviceId=-1, source=0x0 }
2022-08-31 18:32:35.605   902-2166  MediaSessionService     pid-902                              D  Sending KeyEvent { action=ACTION_UP, keyCode=KEYCODE_MEDIA_PLAY, scanCode=0, metaState=0, flags=0x0, repeatCount=0, eventTime=0, downTime=0, deviceId=-1, source=0x0 } to androidx.media3.demo.session/androidx.media3.session.id. (userId=0)
2022-08-31 18:32:35.606 24591-24591 onMediaButtonEvent      androidx.media3.demo.session         D  onPlay()
nitehu commented 1 year ago

I think it started with Android 9. At least we've found the issue when we started to use API28. This is the original issue when the bug was found. Unfortunately this is not easy to reproduce as it happens only with some older BT devices (maybe it has something to do with the BT version?) I can totally understand if you don't want to add some ugly workaround for some old hardware, but it would be nice if we could somehow correct the keycodes in our app.

marcbaechinger commented 1 year ago

I can totally understand if you don't want to add some ugly workaround for some old hardware

I think we totally want to support this.

The first key press is interpreted as KEYCODE_MEDIA_PLAY, however the music is already playing, and it should be a pause. Only the second key press appears as KEYCODE_MEDIA_PAUSE.

I'm not sure I can follow the repro steps and this statement above. In the repro step 3 you say 'stop playback'. I think you mean pause, but however, the above statement says, that first key press is interpreted as KEYCODE_MEDIA_PLAY, however the music is already playing which is not matching the repro steps as the player is paused.

To understand that better and assuming you can change the code of the app. Can you add an EventLogger to the ExoPlayer and then repro again, do a bug report and then upload here? This would allow me to see what events are coming from MediaSessionService and what the response of the player is (which may be none in the case you are describing).

I can try some other BT hardware in the meanwhile (I have two others I can try, one of them about 5 years old).

nitehu commented 1 year ago

Sorry, maybe I wasn't clear. The Repro steps in the issue description are the correct ones. You should fully stop playback by pressing pause in the notification and then dismissing the notification (3.). This manages to confuse my soundcore spirit headset, which sends PLAY for the next two button presses.

But I've just tested, and I have a better one, my JVC headunit only sends PLAY for every key press and never PAUSE, so it is a very easy repro (for me). I'll try to create and send the bug report on the weekend.

nitehu commented 1 year ago

I've sent the reports to the dev.exoplayer email, if that's OK. I didn't want to upload them here, as the phone is my main phone so the logs may contain sensitive data.

nitehu commented 1 year ago

Did you guys receive the logs? We are still very much interested in a solution to this. Let me know how can I help.