service: handle non-native start
Restore the state by default when another app starts the service. A simple first step to ensure service independence (no clue if it's enough)
This commit is contained in:
parent
800ebfe77e
commit
3a4ddb43b9
3 changed files with 47 additions and 9 deletions
|
@ -20,6 +20,7 @@ package org.oxycblt.auxio
|
|||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import android.os.IBinder
|
||||
import androidx.core.app.ServiceCompat
|
||||
import androidx.media3.session.MediaLibraryService
|
||||
import androidx.media3.session.MediaSession
|
||||
|
@ -41,6 +42,27 @@ class AuxioService : MediaLibraryService(), ForegroundListener {
|
|||
indexingFragment.attach(this)
|
||||
}
|
||||
|
||||
override fun onBind(intent: Intent?): IBinder? {
|
||||
handleIntent(intent)
|
||||
return super.onBind(intent)
|
||||
}
|
||||
|
||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||
// TODO: Start command occurring from a foreign service basically implies a detached
|
||||
// service, we might need more handling here.
|
||||
handleIntent(intent)
|
||||
return super.onStartCommand(intent, flags, startId)
|
||||
}
|
||||
|
||||
private fun handleIntent(intent: Intent?) {
|
||||
val nativeStart = intent?.getBooleanExtra(INTENT_KEY_NATIVE_START, false) ?: false
|
||||
if (!nativeStart) {
|
||||
// Some foreign code started us, no guarantees about foreground stability. Figure
|
||||
// out what to do.
|
||||
mediaSessionFragment.handleNonNativeStart()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onTaskRemoved(rootIntent: Intent?) {
|
||||
super.onTaskRemoved(rootIntent)
|
||||
mediaSessionFragment.handleTaskRemoved()
|
||||
|
@ -78,6 +100,11 @@ class AuxioService : MediaLibraryService(), ForegroundListener {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
// This is only meant for Auxio to internally ensure that it's state management will work.
|
||||
const val INTENT_KEY_NATIVE_START = BuildConfig.APPLICATION_ID + ".service.NATIVE_START"
|
||||
}
|
||||
}
|
||||
|
||||
interface ForegroundListener {
|
||||
|
|
|
@ -69,7 +69,9 @@ class MainActivity : AppCompatActivity() {
|
|||
override fun onResume() {
|
||||
super.onResume()
|
||||
|
||||
startService(Intent(this, AuxioService::class.java))
|
||||
startService(
|
||||
Intent(this, AuxioService::class.java)
|
||||
.putExtra(AuxioService.INTENT_KEY_NATIVE_START, true))
|
||||
|
||||
if (!startIntentAction(intent)) {
|
||||
// No intent action to do, just restore the previously saved state.
|
||||
|
|
|
@ -50,7 +50,9 @@ import org.oxycblt.auxio.IntegerTable
|
|||
import org.oxycblt.auxio.R
|
||||
import org.oxycblt.auxio.image.service.MediaSessionBitmapLoader
|
||||
import org.oxycblt.auxio.music.service.MediaItemBrowser
|
||||
import org.oxycblt.auxio.playback.state.DeferredPlayback
|
||||
import org.oxycblt.auxio.playback.state.PlaybackStateManager
|
||||
import org.oxycblt.auxio.util.logD
|
||||
|
||||
class MediaSessionServiceFragment
|
||||
@Inject
|
||||
|
@ -103,14 +105,11 @@ constructor(
|
|||
}
|
||||
}
|
||||
|
||||
fun release() {
|
||||
waitJob.cancel()
|
||||
mediaSession.release()
|
||||
actionHandler.release()
|
||||
exoHolder.release()
|
||||
playbackManager.removeListener(this)
|
||||
mediaSession.release()
|
||||
foregroundListener = null
|
||||
fun handleNonNativeStart() {
|
||||
// At minimum we want to ensure an active playback state.
|
||||
// TODO: Possibly also force to go foreground?
|
||||
logD("Handling non-native start.")
|
||||
playbackManager.playDeferred(DeferredPlayback.RestoreState)
|
||||
}
|
||||
|
||||
fun hasNotification(): Boolean = exoHolder.sessionOngoing
|
||||
|
@ -124,6 +123,16 @@ constructor(
|
|||
post(wrapMediaNotification(notification))
|
||||
}
|
||||
|
||||
fun release() {
|
||||
waitJob.cancel()
|
||||
mediaSession.release()
|
||||
actionHandler.release()
|
||||
exoHolder.release()
|
||||
playbackManager.removeListener(this)
|
||||
mediaSession.release()
|
||||
foregroundListener = null
|
||||
}
|
||||
|
||||
private fun wrapMediaNotification(notification: MediaNotification): MediaNotification {
|
||||
// Pulled from MediaNotificationManager: Need to specify MediaSession token manually
|
||||
// in notification
|
||||
|
|
Loading…
Reference in a new issue