Skip to content

Commit

Permalink
fix(MediaPlayerService): playback being resumed without audio focus
Browse files Browse the repository at this point in the history
on clicking play action button in notification
  • Loading branch information
ashutoshgngwr committed Jun 18, 2019
1 parent 1666900 commit 25e642a
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class MediaPlayerService : Service(), SoundManager.OnPlaybackStateChangeListener
private lateinit var mAudioManager: AudioManager
private lateinit var mSoundManager: SoundManager

private var hasAudioFocus = false
private var playbackDelayed = false
private var resumeOnFocusGain = false

Expand Down Expand Up @@ -91,7 +92,9 @@ class MediaPlayerService : Service(), SoundManager.OnPlaybackStateChangeListener
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
when (intent?.getIntExtra("action", 0)) {
RC_START_PLAYBACK -> {
mSoundManager.resumePlayback()
if (hasAudioFocus) {
mSoundManager.resumePlayback()
}
}

RC_STOP_PLAYBACK -> {
Expand Down Expand Up @@ -148,6 +151,7 @@ class MediaPlayerService : Service(), SoundManager.OnPlaybackStateChangeListener
when (focusChange) {
AudioManager.AUDIOFOCUS_GAIN -> {
Log.d(TAG, "Gained audio focus...")
hasAudioFocus = true
if (playbackDelayed || resumeOnFocusGain) {
Log.d(TAG, "Resume playback after audio focus gain...")
playbackDelayed = false
Expand All @@ -156,13 +160,15 @@ class MediaPlayerService : Service(), SoundManager.OnPlaybackStateChangeListener
}
}
AudioManager.AUDIOFOCUS_LOSS -> {
Log.d(TAG, "Permanently lost audio focus! Pause playback...")
Log.d(TAG, "Permanently lost audio focus! Stop playback...")
hasAudioFocus = false
resumeOnFocusGain = false
playbackDelayed = false
mSoundManager.pausePlayback()
mSoundManager.stopPlayback()
}
AudioManager.AUDIOFOCUS_LOSS_TRANSIENT -> {
Log.d(TAG, "Temporarily lost audio focus! Pause playback...")
hasAudioFocus = false
resumeOnFocusGain = true
playbackDelayed = false
mSoundManager.pausePlayback()
Expand Down Expand Up @@ -191,12 +197,17 @@ class MediaPlayerService : Service(), SoundManager.OnPlaybackStateChangeListener
AudioManager.AUDIOFOCUS_REQUEST_DELAYED -> {
Log.d(TAG, "Audio focus request was delayed! Pause playback for now.")
playbackDelayed = true
hasAudioFocus = false
mSoundManager.pausePlayback()
}
AudioManager.AUDIOFOCUS_REQUEST_FAILED -> {
Log.d(TAG, "Failed to get audio focus! Stop playback...")
hasAudioFocus = false
mSoundManager.stopPlayback()
}
AudioManager.AUDIOFOCUS_REQUEST_GRANTED -> {
hasAudioFocus = true
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,23 @@ class MediaPlayerServiceTest {
assert(!binder.getSoundManager().isPaused() && binder.getSoundManager().isPlaying)
}

@Test
fun `should not resume playback on receiving start playback intent if focus request was delayed`() {
serviceController = Robolectric.buildService(
MediaPlayerService::class.java,
Shadow.newInstanceOf(Intent::class.java)
.putExtra("action", MediaPlayerService.RC_START_PLAYBACK)
).create()

val binder = serviceController.get()
.onBind(Shadow.newInstanceOf(Intent::class.java)) as MediaPlayerService.PlaybackBinder

binder.getSoundManager().play(LIBRARY[0].key)
serviceController.get().handleAudioFocusRequestResult(AudioManager.AUDIOFOCUS_REQUEST_DELAYED)
serviceController.startCommand(0, 0)
assert(binder.getSoundManager().isPaused() && !binder.getSoundManager().isPlaying)
}

@Test
fun `should pause playback on receiving stop playback intent`() {
serviceController = Robolectric.buildService(
Expand Down Expand Up @@ -202,7 +219,7 @@ class MediaPlayerServiceTest {

@Test
@Config(sdk = [23, 28])
fun `should pause playback on permanent audio focus loss`() {
fun `should stop playback on permanent audio focus loss`() {
val mSoundPoolShadow = shadowOf(binder.getSoundManager().mSoundPool)
binder.getSoundManager().play(LIBRARY[0].key)
assert(
Expand All @@ -211,10 +228,7 @@ class MediaPlayerServiceTest {
)

serviceController.get().onAudioFocusChange(AudioManager.AUDIOFOCUS_LOSS)
assert(binder.getSoundManager().isPaused())

// and finally stop playback to increase coverage..? :D
binder.getSoundManager().stopPlayback()
assert(!binder.getSoundManager().isPlaying && !binder.getSoundManager().isPaused())
}

@Test
Expand Down

0 comments on commit 25e642a

Please sign in to comment.