Modernize AudioFocusHandler

This commit is contained in:
tzugen 2021-04-22 10:25:17 +02:00
parent 8640d39438
commit 5f8e3ce851
No known key found for this signature in database
GPG Key ID: 61E9C34BC10EC930
1 changed files with 94 additions and 33 deletions

View File

@ -1,8 +1,14 @@
package org.moire.ultrasonic.service
import android.content.Context
import android.media.AudioAttributes
import android.media.AudioManager
import android.media.AudioManager.OnAudioFocusChangeListener
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.media.AudioAttributesCompat
import androidx.media.AudioFocusRequestCompat
import androidx.media.AudioManagerCompat
import org.koin.java.KoinJavaComponent.inject
import org.moire.ultrasonic.domain.PlayerState
import org.moire.ultrasonic.util.Constants
@ -11,54 +17,109 @@ import timber.log.Timber
class AudioFocusHandler(private val context: Context) {
// TODO: This is a circular reference, try to remove it
// This should be doable by using the native MediaController framework
private val mediaPlayerControllerLazy = inject(MediaPlayerController::class.java)
private val audioManager by lazy {
context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
}
private val preferences by lazy {
Util.getPreferences(context)
}
private val lossPref: Int
get() = preferences.getString(Constants.PREFERENCES_KEY_TEMP_LOSS, "1")!!.toInt()
private val audioAttributesCompat by lazy {
AudioAttributesCompat.Builder()
.setUsage(AudioAttributesCompat.USAGE_MEDIA)
.setContentType(AudioAttributesCompat.CONTENT_TYPE_MUSIC)
.setLegacyStreamType(AudioManager.STREAM_MUSIC)
.build()
}
fun requestAudioFocus() {
if (!hasFocus) {
val audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
hasFocus = true
AudioManagerCompat.requestAudioFocus(audioManager, focusRequest)
}
}
private val listener = OnAudioFocusChangeListener { focusChange ->
audioManager.requestAudioFocus(object : OnAudioFocusChangeListener {
override fun onAudioFocusChange(focusChange: Int) {
val mediaPlayerController = mediaPlayerControllerLazy.value
if ((focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT || focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) && !mediaPlayerController.isJukeboxEnabled) {
Timber.v("Lost Audio Focus")
if (mediaPlayerController.playerState === PlayerState.STARTED) {
val preferences = Util.getPreferences(context)
val lossPref = preferences.getString(Constants.PREFERENCES_KEY_TEMP_LOSS, "1")!!.toInt()
if (lossPref == 2 || lossPref == 1 && focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) {
lowerFocus = true
mediaPlayerController.setVolume(0.1f)
} else if (lossPref == 0 || lossPref == 1) {
pauseFocus = true
mediaPlayerController.pause()
}
val mediaPlayerController = mediaPlayerControllerLazy.value
when (focusChange) {
AudioManager.AUDIOFOCUS_GAIN -> {
Timber.v("Regained Audio Focus")
if (pauseFocus) {
pauseFocus = false
mediaPlayerController.start()
} else if (lowerFocus) {
lowerFocus = false
mediaPlayerController.setVolume(1.0f)
}
}
AudioManager.AUDIOFOCUS_LOSS -> {
if (!mediaPlayerController.isJukeboxEnabled) {
hasFocus = false
mediaPlayerController.pause()
AudioManagerCompat.abandonAudioFocusRequest(audioManager, focusRequest)
Timber.v("Abandoned Audio Focus")
}
}
AudioManager.AUDIOFOCUS_LOSS_TRANSIENT -> {
if (!mediaPlayerController.isJukeboxEnabled) {
Timber.v("Lost Audio Focus")
if (mediaPlayerController.playerState === PlayerState.STARTED) {
if (lossPref == 0 || lossPref == 1) {
pauseFocus = true
mediaPlayerController.pause()
}
} else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
Timber.v("Regained Audio Focus")
if (pauseFocus) {
pauseFocus = false
mediaPlayerController.start()
} else if (lowerFocus) {
lowerFocus = false
mediaPlayerController.setVolume(1.0f)
}
} else if (focusChange == AudioManager.AUDIOFOCUS_LOSS && !mediaPlayerController.isJukeboxEnabled) {
hasFocus = false
mediaPlayerController.pause()
audioManager.abandonAudioFocus(this)
Timber.v("Abandoned Audio Focus")
}
}
}, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN)
Timber.v("Got Audio Focus")
}
AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK -> {
if (!mediaPlayerController.isJukeboxEnabled) {
Timber.v("Lost Audio Focus")
if (mediaPlayerController.playerState === PlayerState.STARTED) {
if (lossPref == 2 || lossPref == 1) {
lowerFocus = true
mediaPlayerController.setVolume(0.1f)
} else if (lossPref == 0 || lossPref == 1) {
pauseFocus = true
mediaPlayerController.pause()
}
}
}
}
}
}
private val focusRequest: AudioFocusRequestCompat by lazy {
AudioFocusRequestCompat.Builder(AudioManagerCompat.AUDIOFOCUS_GAIN)
.setAudioAttributes(audioAttributesCompat)
.setWillPauseWhenDucked(true)
.setOnAudioFocusChangeListener(listener)
.build()
}
companion object {
private var hasFocus = false
private var pauseFocus = false
private var lowerFocus = false
// TODO: This can be removed if we switch to androidx.media2.player
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
fun getAudioAttributes(): AudioAttributes {
return AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.setLegacyStreamType(AudioManager.STREAM_MUSIC)
.build()
}
}
}
}