[MusicService] Code Cleanup

This commit is contained in:
Prathamesh More 2022-05-16 12:51:06 +05:30
parent 32e6daf36d
commit 7e2881b5f0
2 changed files with 85 additions and 91 deletions

View file

@ -17,6 +17,7 @@ import android.annotation.SuppressLint
import android.app.NotificationManager import android.app.NotificationManager
import android.appwidget.AppWidgetManager import android.appwidget.AppWidgetManager
import android.bluetooth.BluetoothDevice import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothDevice.EXTRA_DEVICE
import android.content.* import android.content.*
import android.content.SharedPreferences.OnSharedPreferenceChangeListener import android.content.SharedPreferences.OnSharedPreferenceChangeListener
import android.content.pm.ServiceInfo import android.content.pm.ServiceInfo
@ -35,8 +36,6 @@ import android.support.v4.media.MediaDescriptionCompat
import android.support.v4.media.MediaMetadataCompat import android.support.v4.media.MediaMetadataCompat
import android.support.v4.media.session.MediaSessionCompat import android.support.v4.media.session.MediaSessionCompat
import android.support.v4.media.session.PlaybackStateCompat import android.support.v4.media.session.PlaybackStateCompat
import android.telephony.PhoneStateListener
import android.telephony.TelephonyManager
import android.util.Log import android.util.Log
import android.widget.Toast import android.widget.Toast
import androidx.core.content.edit import androidx.core.content.edit
@ -94,6 +93,9 @@ import com.bumptech.glide.request.target.CustomTarget
import com.bumptech.glide.request.target.Target import com.bumptech.glide.request.target.Target
import com.bumptech.glide.request.transition.Transition import com.bumptech.glide.request.transition.Transition
import com.google.android.gms.cast.framework.CastSession import com.google.android.gms.cast.framework.CastSession
import kotlinx.coroutines.*
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Dispatchers.Main
import org.koin.java.KoinJavaComponent.get import org.koin.java.KoinJavaComponent.get
import java.util.* import java.util.*
@ -117,6 +119,7 @@ class MusicService : MediaBrowserServiceCompat(),
private var mPackageValidator: PackageValidator? = null private var mPackageValidator: PackageValidator? = null
private val mMusicProvider = get<AutoMusicProvider>(AutoMusicProvider::class.java) private val mMusicProvider = get<AutoMusicProvider>(AutoMusicProvider::class.java)
private var trackEndedByCrossfade = false private var trackEndedByCrossfade = false
private val serviceScope = CoroutineScope(Job() + Main)
@JvmField @JvmField
var position = -1 var position = -1
@ -127,7 +130,7 @@ class MusicService : MediaBrowserServiceCompat(),
private val appWidgetText = AppWidgetText.instance private val appWidgetText = AppWidgetText.instance
private val appWidgetMd3 = AppWidgetMD3.instance private val appWidgetMd3 = AppWidgetMD3.instance
private val appWidgetCircle = AppWidgetCircle.instance private val appWidgetCircle = AppWidgetCircle.instance
private val widgetIntentReceiver: BroadcastReceiver = object : BroadcastReceiver() { private val widgetIntentReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) { override fun onReceive(context: Context, intent: Intent) {
val command = intent.getStringExtra(EXTRA_APP_WIDGET_NAME) val command = intent.getStringExtra(EXTRA_APP_WIDGET_NAME)
val ids = intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS) val ids = intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS)
@ -182,7 +185,7 @@ class MusicService : MediaBrowserServiceCompat(),
@JvmField @JvmField
var playingQueue = ArrayList<Song>() var playingQueue = ArrayList<Song>()
var isPausedByTransientLossOfFocus = false var isPausedByTransientLossOfFocus = false
private val becomingNoisyReceiver: BroadcastReceiver = object : BroadcastReceiver() { private val becomingNoisyReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) { override fun onReceive(context: Context, intent: Intent) {
if (intent.action != null if (intent.action != null
&& intent.action == AudioManager.ACTION_AUDIO_BECOMING_NOISY && intent.action == AudioManager.ACTION_AUDIO_BECOMING_NOISY
@ -197,13 +200,14 @@ class MusicService : MediaBrowserServiceCompat(),
} }
private var playingNotification: PlayingNotification? = null private var playingNotification: PlayingNotification? = null
private val updateFavoriteReceiver: BroadcastReceiver = object : BroadcastReceiver() { private val updateFavoriteReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) { override fun onReceive(context: Context, intent: Intent) {
playingNotification?.updateFavorite(currentSong) { startForegroundOrNotify() } playingNotification?.updateFavorite(currentSong) { startForegroundOrNotify() }
appWidgetCircle.notifyChange(this@MusicService, FAVORITE_STATE_CHANGED) appWidgetCircle.notifyChange(this@MusicService, FAVORITE_STATE_CHANGED)
} }
} }
private val lockScreenReceiver: BroadcastReceiver = object : BroadcastReceiver() {
private val lockScreenReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) { override fun onReceive(context: Context, intent: Intent) {
if (isLockScreen && isPlaying) { if (isLockScreen && isPlaying) {
val lockIntent = Intent(context, LockScreenActivity::class.java) val lockIntent = Intent(context, LockScreenActivity::class.java)
@ -234,32 +238,20 @@ class MusicService : MediaBrowserServiceCompat(),
var shuffleMode = 0 var shuffleMode = 0
private val songPlayCountHelper = SongPlayCountHelper() private val songPlayCountHelper = SongPlayCountHelper()
private val bluetoothReceiver: BroadcastReceiver = object : BroadcastReceiver() { private val bluetoothReceiver = object : BroadcastReceiver() {
@SuppressLint("MissingPermission")
override fun onReceive(context: Context, intent: Intent) { override fun onReceive(context: Context, intent: Intent) {
val action = intent.action val action = intent.action
val extra = intent.getParcelableExtra<BluetoothDevice>(EXTRA_DEVICE)!!
if (action != null) { if (action != null) {
if (BluetoothDevice.ACTION_ACL_CONNECTED == action && isBluetoothSpeaker) { if (BluetoothDevice.ACTION_ACL_CONNECTED == action && isBluetoothSpeaker) {
if (audioManager!!.isBluetoothA2dpOn) { if (extra.type == BluetoothDevice.DEVICE_TYPE_CLASSIC) play()
play()
}
} }
} }
} }
} }
private val phoneStateListener: PhoneStateListener = object : PhoneStateListener() { private val headsetReceiver = object : BroadcastReceiver() {
override fun onCallStateChanged(state: Int, incomingNumber: String) {
when (state) {
TelephonyManager.CALL_STATE_IDLE -> // Not in call: Play music
play()
TelephonyManager.CALL_STATE_RINGING, TelephonyManager.CALL_STATE_OFFHOOK -> // A call is dialing, active or on hold
pause()
}
super.onCallStateChanged(state, incomingNumber)
}
}
private val headsetReceiver: BroadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) { override fun onReceive(context: Context, intent: Intent) {
val action = intent.action val action = intent.action
if (action != null) { if (action != null) {
@ -279,8 +271,6 @@ class MusicService : MediaBrowserServiceCompat(),
private var isForeground = false private var isForeground = false
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()
val telephonyManager = getSystemService<TelephonyManager>()
telephonyManager?.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE)
val powerManager = getSystemService<PowerManager>() val powerManager = getSystemService<PowerManager>()
if (powerManager != null) { if (powerManager != null) {
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, javaClass.name) wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, javaClass.name)
@ -353,7 +343,7 @@ class MusicService : MediaBrowserServiceCompat(),
audioVolumeObserver.register(AudioManager.STREAM_MUSIC, this) audioVolumeObserver.register(AudioManager.STREAM_MUSIC, this)
registerOnSharedPreferenceChangedListener(this) registerOnSharedPreferenceChangedListener(this)
restoreState() restoreState()
sendBroadcast(Intent("code.name.monkey.retromusic.RETRO_MUSIC_SERVICE_CREATED")) sendBroadcast(Intent("$RETRO_MUSIC_PACKAGE_NAME.RETRO_MUSIC_SERVICE_CREATED"))
registerHeadsetEvents() registerHeadsetEvents()
registerBluetoothConnected() registerBluetoothConnected()
mPackageValidator = PackageValidator(this, R.xml.allowed_media_browser_callers) mPackageValidator = PackageValidator(this, R.xml.allowed_media_browser_callers)
@ -382,11 +372,11 @@ class MusicService : MediaBrowserServiceCompat(),
contentResolver.unregisterContentObserver(mediaStoreObserver) contentResolver.unregisterContentObserver(mediaStoreObserver)
unregisterOnSharedPreferenceChangedListener(this) unregisterOnSharedPreferenceChangedListener(this)
wakeLock?.release() wakeLock?.release()
sendBroadcast(Intent("code.name.monkey.retromusic.RETRO_MUSIC_SERVICE_DESTROYED")) sendBroadcast(Intent("$RETRO_MUSIC_PACKAGE_NAME.RETRO_MUSIC_SERVICE_DESTROYED"))
} }
private fun acquireWakeLock(milli: Long) { private fun acquireWakeLock() {
wakeLock?.acquire(milli) wakeLock?.acquire(30000)
} }
private var pausedByZeroVolume = false private var pausedByZeroVolume = false
@ -394,10 +384,8 @@ class MusicService : MediaBrowserServiceCompat(),
if (isPauseOnZeroVolume) { if (isPauseOnZeroVolume) {
if (isPlaying && currentVolume < 1) { if (isPlaying && currentVolume < 1) {
pause() pause()
println("Paused")
pausedByZeroVolume = true pausedByZeroVolume = true
} else if (pausedByZeroVolume && currentVolume >= 1) { } else if (pausedByZeroVolume && currentVolume >= 1) {
println("Played")
play() play()
pausedByZeroVolume = false pausedByZeroVolume = false
} }
@ -692,6 +680,7 @@ class MusicService : MediaBrowserServiceCompat(),
) { ) {
when (key) { when (key) {
PLAYBACK_SPEED, PLAYBACK_PITCH -> { PLAYBACK_SPEED, PLAYBACK_PITCH -> {
updateMediaSessionPlaybackState()
playbackManager.setPlaybackSpeedPitch(playbackSpeed, playbackPitch) playbackManager.setPlaybackSpeedPitch(playbackSpeed, playbackPitch)
} }
CROSS_FADE_DURATION -> { CROSS_FADE_DURATION -> {
@ -716,7 +705,6 @@ class MusicService : MediaBrowserServiceCompat(),
startForegroundOrNotify() startForegroundOrNotify()
} }
} }
PLAYBACK_SPEED -> updateMediaSessionPlaybackState()
TOGGLE_HEADSET -> registerHeadsetEvents() TOGGLE_HEADSET -> registerHeadsetEvents()
} }
} }
@ -724,6 +712,7 @@ class MusicService : MediaBrowserServiceCompat(),
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
if (intent != null && intent.action != null) { if (intent != null && intent.action != null) {
handleIntent(mediaSession, intent) handleIntent(mediaSession, intent)
serviceScope.launch {
restoreQueuesAndPositionIfNecessary() restoreQueuesAndPositionIfNecessary()
when (intent.action) { when (intent.action) {
ACTION_TOGGLE_PAUSE -> if (isPlaying) { ACTION_TOGGLE_PAUSE -> if (isPlaying) {
@ -744,17 +733,18 @@ class MusicService : MediaBrowserServiceCompat(),
TOGGLE_FAVORITE -> toggleFavorite(applicationContext, currentSong) TOGGLE_FAVORITE -> toggleFavorite(applicationContext, currentSong)
} }
} }
}
return START_NOT_STICKY return START_NOT_STICKY
} }
override fun onTrackEnded() { override fun onTrackEnded() {
acquireWakeLock(30000) acquireWakeLock()
playerHandler?.sendEmptyMessage(TRACK_ENDED) playerHandler?.sendEmptyMessage(TRACK_ENDED)
} }
override fun onTrackEndedWithCrossfade() { override fun onTrackEndedWithCrossfade() {
trackEndedByCrossfade = true trackEndedByCrossfade = true
acquireWakeLock(30000) acquireWakeLock()
playerHandler?.sendEmptyMessage(TRACK_ENDED) playerHandler?.sendEmptyMessage(TRACK_ENDED)
} }
@ -894,7 +884,12 @@ class MusicService : MediaBrowserServiceCompat(),
stopForeground(true) stopForeground(true)
notificationManager?.cancel(PlayingNotification.NOTIFICATION_ID) notificationManager?.cancel(PlayingNotification.NOTIFICATION_ID)
playbackManager.release() playbackManager.release()
audioManager?.abandonAudioFocus(audioFocusListener) AudioManagerCompat.abandonAudioFocusRequest(audioManager!!,
AudioFocusRequestCompat.Builder(AudioManagerCompat.AUDIOFOCUS_GAIN)
.setOnAudioFocusChangeListener(audioFocusListener)
.setAudioAttributes(
AudioAttributesCompat.Builder().setContentType(CONTENT_TYPE_MUSIC).build()
).build())
stopSelf() stopSelf()
} }
@ -954,23 +949,26 @@ class MusicService : MediaBrowserServiceCompat(),
} }
} }
@Synchronized private suspend fun restoreQueuesAndPositionIfNecessary() {
fun restoreQueuesAndPositionIfNecessary() {
if (!queuesRestored && playingQueue.isEmpty()) { if (!queuesRestored && playingQueue.isEmpty()) {
val restoredQueue = MusicPlaybackQueueStore.getInstance(this).savedPlayingQueue withContext(IO) {
val restoredQueue =
MusicPlaybackQueueStore.getInstance(this@MusicService).savedPlayingQueue
val restoredOriginalQueue = val restoredOriginalQueue =
MusicPlaybackQueueStore.getInstance(this).savedOriginalPlayingQueue MusicPlaybackQueueStore.getInstance(this@MusicService).savedOriginalPlayingQueue
val restoredPosition = PreferenceManager.getDefaultSharedPreferences(this).getInt( val restoredPosition =
PreferenceManager.getDefaultSharedPreferences(this@MusicService).getInt(
SAVED_POSITION, -1 SAVED_POSITION, -1
) )
val restoredPositionInTrack = val restoredPositionInTrack =
PreferenceManager.getDefaultSharedPreferences(this).getInt( PreferenceManager.getDefaultSharedPreferences(this@MusicService).getInt(
SAVED_POSITION_IN_TRACK, -1 SAVED_POSITION_IN_TRACK, -1
) )
if (restoredQueue.size > 0 && restoredQueue.size == restoredOriginalQueue.size && restoredPosition != -1) { if (restoredQueue.size > 0 && restoredQueue.size == restoredOriginalQueue.size && restoredPosition != -1) {
originalPlayingQueue = ArrayList(restoredOriginalQueue) originalPlayingQueue = ArrayList(restoredOriginalQueue)
playingQueue = ArrayList(restoredQueue) playingQueue = ArrayList(restoredQueue)
position = restoredPosition position = restoredPosition
withContext(Main) {
openCurrent { openCurrent {
prepareNext() prepareNext()
if (restoredPositionInTrack > 0) { if (restoredPositionInTrack > 0) {
@ -979,12 +977,15 @@ class MusicService : MediaBrowserServiceCompat(),
notHandledMetaChangedForCurrentTrack = true notHandledMetaChangedForCurrentTrack = true
sendChangeInternal(META_CHANGED) sendChangeInternal(META_CHANGED)
} }
}
sendChangeInternal(QUEUE_CHANGED) sendChangeInternal(QUEUE_CHANGED)
} }
} }
queuesRestored = true queuesRestored = true
} }
}
fun runOnUiThread(runnable: Runnable?) { fun runOnUiThread(runnable: Runnable?) {
uiThreadHandler?.post(runnable!!) uiThreadHandler?.post(runnable!!)
@ -1009,8 +1010,7 @@ class MusicService : MediaBrowserServiceCompat(),
@Synchronized @Synchronized
fun seek(millis: Int): Int { fun seek(millis: Int): Int {
return try { return try {
var newPosition = 0 val newPosition = playbackManager.seek(millis)
newPosition = playbackManager.seek(millis)
throttledSeekHandler?.notifySeek() throttledSeekHandler?.notifySeek()
newPosition newPosition
} catch (e: Exception) { } catch (e: Exception) {
@ -1271,8 +1271,7 @@ class MusicService : MediaBrowserServiceCompat(),
} }
private fun prepareNext() { private fun prepareNext() {
playerHandler?.removeMessages(PREPARE_NEXT) prepareNextImpl()
playerHandler?.obtainMessage(PREPARE_NEXT)?.sendToTarget()
} }
private fun registerBluetoothConnected() { private fun registerBluetoothConnected() {
@ -1319,8 +1318,9 @@ class MusicService : MediaBrowserServiceCompat(),
) )
handleAndSendChangeInternal(SHUFFLE_MODE_CHANGED) handleAndSendChangeInternal(SHUFFLE_MODE_CHANGED)
handleAndSendChangeInternal(REPEAT_MODE_CHANGED) handleAndSendChangeInternal(REPEAT_MODE_CHANGED)
playerHandler?.removeMessages(RESTORE_QUEUES) serviceScope.launch {
playerHandler?.sendEmptyMessage(RESTORE_QUEUES) restoreQueuesAndPositionIfNecessary()
}
} }
private fun savePosition() { private fun savePosition() {
@ -1420,13 +1420,9 @@ class MusicService : MediaBrowserServiceCompat(),
const val RELEASE_WAKELOCK = 0 const val RELEASE_WAKELOCK = 0
const val TRACK_ENDED = 1 const val TRACK_ENDED = 1
const val TRACK_WENT_TO_NEXT = 2 const val TRACK_WENT_TO_NEXT = 2
const val PLAY_SONG = 3 const val FOCUS_CHANGE = 3
const val PREPARE_NEXT = 4 const val DUCK = 4
const val SET_POSITION = 5 const val UNDUCK = 5
const val FOCUS_CHANGE = 6
const val DUCK = 7
const val UNDUCK = 8
const val RESTORE_QUEUES = 9
const val SHUFFLE_MODE_NONE = 0 const val SHUFFLE_MODE_NONE = 0
const val SHUFFLE_MODE_SHUFFLE = 1 const val SHUFFLE_MODE_SHUFFLE = 1
const val REPEAT_MODE_NONE = 0 const val REPEAT_MODE_NONE = 0

View file

@ -84,8 +84,6 @@ internal class PlaybackHandler(service: MusicService, looper: Looper) : Handler(
sendEmptyMessage(MusicService.RELEASE_WAKELOCK) sendEmptyMessage(MusicService.RELEASE_WAKELOCK)
} }
MusicService.RELEASE_WAKELOCK -> service.releaseWakeLock() MusicService.RELEASE_WAKELOCK -> service.releaseWakeLock()
MusicService.PREPARE_NEXT -> service.prepareNextImpl()
MusicService.RESTORE_QUEUES -> service.restoreQueuesAndPositionIfNecessary()
MusicService.FOCUS_CHANGE -> when (msg.arg1) { MusicService.FOCUS_CHANGE -> when (msg.arg1) {
AudioManager.AUDIOFOCUS_GAIN -> { AudioManager.AUDIOFOCUS_GAIN -> {
if (!service.isPlaying && service.isPausedByTransientLossOfFocus) { if (!service.isPlaying && service.isPausedByTransientLossOfFocus) {