diff --git a/app/src/main/java/org/oxycblt/auxio/AuxioService.kt b/app/src/main/java/org/oxycblt/auxio/AuxioService.kt index e0d6c7def..bb2d7b1af 100644 --- a/app/src/main/java/org/oxycblt/auxio/AuxioService.kt +++ b/app/src/main/java/org/oxycblt/auxio/AuxioService.kt @@ -76,9 +76,8 @@ class AuxioService : } private fun onHandleForeground(intent: Intent?) { - val startId = intent?.getIntExtra(INTENT_KEY_START_ID, -1) ?: -1 musicFragment.start() - playbackFragment.start(startId) + playbackFragment.start(intent) } override fun onTaskRemoved(rootIntent: Intent?) { diff --git a/app/src/main/java/org/oxycblt/auxio/IntegerTable.kt b/app/src/main/java/org/oxycblt/auxio/IntegerTable.kt index 55907bb0d..6ea713010 100644 --- a/app/src/main/java/org/oxycblt/auxio/IntegerTable.kt +++ b/app/src/main/java/org/oxycblt/auxio/IntegerTable.kt @@ -65,6 +65,8 @@ object IntegerTable { const val START_ID_ACTIVITY = 0xA050 /** Tasker AuxioService Start ID */ const val START_ID_TASKER = 0xA051 + /** MediaButtonReceiver AuxioService Start ID */ + const val START_ID_MEDIA_BUTTON = 0xA052 /** RepeatMode.NONE */ const val REPEAT_MODE_NONE = 0xA100 /** RepeatMode.ALL */ diff --git a/app/src/main/java/org/oxycblt/auxio/playback/service/MediaButtonReceiver.kt b/app/src/main/java/org/oxycblt/auxio/playback/service/MediaButtonReceiver.kt index 22ad735a6..16141d4f9 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/service/MediaButtonReceiver.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/service/MediaButtonReceiver.kt @@ -26,6 +26,7 @@ import androidx.core.content.ContextCompat import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject import org.oxycblt.auxio.AuxioService +import org.oxycblt.auxio.IntegerTable import org.oxycblt.auxio.playback.state.PlaybackStateManager import timber.log.Timber as L @@ -47,8 +48,11 @@ class MediaButtonReceiver : BroadcastReceiver() { // stupid this is with the state of foreground services on modern android. One // wrong action at the wrong time will result in the app crashing, and there is // nothing I can do about it. + // TODO: Think I finally have an alternative with the changes I made to accomodate + // tasker L.d("Delivering media button intent $intent") intent.component = ComponentName(context, AuxioService::class.java) + intent.putExtra(AuxioService.INTENT_KEY_START_ID, IntegerTable.START_ID_MEDIA_BUTTON) ContextCompat.startForegroundService(context, intent) } } diff --git a/app/src/main/java/org/oxycblt/auxio/playback/service/MediaSessionHolder.kt b/app/src/main/java/org/oxycblt/auxio/playback/service/MediaSessionHolder.kt index 0cba44c5c..d90ddb8b7 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/service/MediaSessionHolder.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/service/MediaSessionHolder.kt @@ -20,6 +20,7 @@ package org.oxycblt.auxio.playback.service import android.annotation.SuppressLint import android.content.Context +import android.content.Intent import android.graphics.Bitmap import android.support.v4.media.MediaMetadataCompat import android.support.v4.media.session.MediaSessionCompat @@ -28,6 +29,7 @@ import androidx.annotation.DrawableRes import androidx.car.app.mediaextensions.MetadataExtras import androidx.core.app.NotificationCompat import androidx.media.app.NotificationCompat.MediaStyle +import androidx.media.session.MediaButtonReceiver import javax.inject.Inject import org.oxycblt.auxio.BuildConfig import org.oxycblt.auxio.ForegroundListener @@ -108,6 +110,9 @@ private constructor( } } + fun tryMediaButtonIntent(intent: Intent): Boolean = + MediaButtonReceiver.handleIntent(mediaSession, intent) != null + /** * Release this instance, closing the [MediaSessionCompat] and preventing any further updates to * the [PlaybackNotification]. diff --git a/app/src/main/java/org/oxycblt/auxio/playback/service/PlaybackServiceFragment.kt b/app/src/main/java/org/oxycblt/auxio/playback/service/PlaybackServiceFragment.kt index a49438472..2b90f2f38 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/service/PlaybackServiceFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/service/PlaybackServiceFragment.kt @@ -19,9 +19,11 @@ package org.oxycblt.auxio.playback.service import android.content.Context +import android.content.Intent import android.support.v4.media.session.MediaSessionCompat import javax.inject.Inject import kotlinx.coroutines.Job +import org.oxycblt.auxio.AuxioService.Companion.INTENT_KEY_START_ID import org.oxycblt.auxio.ForegroundListener import org.oxycblt.auxio.ForegroundServiceNotification import org.oxycblt.auxio.IntegerTable @@ -83,18 +85,34 @@ private constructor( } } - fun start(startedBy: Int) { + fun start(intent: Intent?) { // At minimum we want to ensure an active playback state. // TODO: Possibly also force to go foreground? - L.d("Handling non-native start.") + val startId = intent?.getIntExtra(INTENT_KEY_START_ID, -1) val action = - when (startedBy) { + when (startId) { IntegerTable.START_ID_ACTIVITY -> null IntegerTable.START_ID_TASKER -> DeferredPlayback.RestoreState( play = true, fallback = DeferredPlayback.ShuffleAll) - // External services using Auxio better know what they are doing. - else -> DeferredPlayback.RestoreState(play = false) + IntegerTable.START_ID_MEDIA_BUTTON -> { + if (!sessionHolder.tryMediaButtonIntent(intent)) { + // Malformed intent, need to restore state immediately + DeferredPlayback.RestoreState( + play = true, fallback = DeferredPlayback.ShuffleAll) + } else { + null + } + } + else -> { + L.d("Handling non-native start.") + if (intent != null && sessionHolder.tryMediaButtonIntent(intent)) { + // Just a media button intent, move on. + return + } + // External services using Auxio better know what they are doing. + DeferredPlayback.RestoreState(play = false) + } } if (action != null) { L.d("Initing service fragment using action $action")