mirror of
https://gitlab.com/ultrasonic/ultrasonic.git
synced 2026-10-22 23:42:14 +03:00
Surface jukebox error message before falling back to local playback
This commit is contained in:
1 parent
1ce70142a1
commit
f3dd7808ac
2 files changed
+61
-8
No files matched your search
@@ -20,6 +20,7 @@ import android.os.Looper
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
import androidx.core.app.TaskStackBuilder
|
||||
import androidx.core.text.HtmlCompat
|
||||
import androidx.media3.common.AudioAttributes
|
||||
import androidx.media3.common.C
|
||||
import androidx.media3.common.C.USAGE_MEDIA
|
||||
@@ -556,7 +557,62 @@ class PlaybackService :
|
||||
* Connectivity failures additionally trigger a background reachability probe; only a
|
||||
* failed probe - never the playback error itself - switches the library to automatic
|
||||
* offline mode.
|
||||
* Surfaces the reason why Jukebox playback failed before [updateBackend] falls back to
|
||||
* local playback. Jukebox errors carry a string resource as their error code (see
|
||||
* [JukeboxMediaPlayer.onError]); those messages are shown in an error notification.
|
||||
* Any other error is only logged.
|
||||
*/
|
||||
private fun notifyJukeboxError(error: PlaybackException) {
|
||||
val messageRes = when (error.errorCode) {
|
||||
R.string.download_jukebox_not_authorized,
|
||||
R.string.download_jukebox_server_too_old,
|
||||
R.string.download_jukebox_offline -> error.errorCode
|
||||
|
||||
else -> return
|
||||
}
|
||||
|
||||
val notificationManagerCompat = NotificationManagerCompat.from(this@PlaybackService)
|
||||
NotificationUtil.ensureNotificationChannel(
|
||||
id = NOTIFICATION_CHANNEL_ID,
|
||||
name = NOTIFICATION_CHANNEL_NAME,
|
||||
notificationManager = notificationManagerCompat
|
||||
)
|
||||
|
||||
// The Jukebox messages contain inline markup (e.g. <b>), render it for the notification
|
||||
val message = HtmlCompat.fromHtml(
|
||||
getString(messageRes),
|
||||
HtmlCompat.FROM_HTML_MODE_LEGACY
|
||||
)
|
||||
val fallback = getString(R.string.jukebox_fallback_text)
|
||||
|
||||
val builder =
|
||||
NotificationCompat.Builder(this@PlaybackService, NOTIFICATION_CHANNEL_ID)
|
||||
.setContentIntent(createContentPendingIntent())
|
||||
.setSmallIcon(R.drawable.media3_notification_small_icon)
|
||||
.setContentTitle(getString(R.string.jukebox_error_title))
|
||||
.setStyle(
|
||||
NotificationCompat.BigTextStyle().bigText(
|
||||
"$message\n\n$fallback"
|
||||
)
|
||||
)
|
||||
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
|
||||
.setAutoCancel(true)
|
||||
|
||||
NotificationUtil.postNotificationIfPermitted(
|
||||
notificationManagerCompat,
|
||||
JUKEBOX_ERROR_NOTIFICATION_ID,
|
||||
builder.build()
|
||||
)
|
||||
}
|
||||
|
||||
private fun createContentPendingIntent(): PendingIntent =
|
||||
TaskStackBuilder.create(this@PlaybackService).run {
|
||||
addNextIntent(Intent(this@PlaybackService, NavigationActivity::class.java))
|
||||
|
||||
val immutableFlag = FLAG_IMMUTABLE or FLAG_UPDATE_CURRENT
|
||||
getPendingIntent(0, immutableFlag)!!
|
||||
}
|
||||
|
||||
private fun recoverFromPlaybackError(error: PlaybackException) {
|
||||
val connectivity = error.hasTransientConnectivityFailure()
|
||||
if (!connectivity && !error.hasOfflineCause()) return
|
||||
@@ -639,6 +695,7 @@ class PlaybackService :
|
||||
Timber.w(error, "Playback error")
|
||||
if (actualBackend == PlaybackBackend.JUKEBOX) {
|
||||
mainHandler.post {
|
||||
notifyJukeboxError(error)
|
||||
updateBackend(PlaybackBackend.LOCAL, retainDownloadsOnly = false)
|
||||
}
|
||||
return
|
||||
@@ -822,16 +879,9 @@ class PlaybackService :
|
||||
name = NOTIFICATION_CHANNEL_NAME,
|
||||
notificationManager = notificationManagerCompat
|
||||
)
|
||||
val pendingIntent =
|
||||
TaskStackBuilder.create(this@PlaybackService).run {
|
||||
addNextIntent(Intent(this@PlaybackService, NavigationActivity::class.java))
|
||||
|
||||
val immutableFlag = FLAG_IMMUTABLE or FLAG_UPDATE_CURRENT
|
||||
getPendingIntent(0, immutableFlag)
|
||||
}
|
||||
val builder =
|
||||
NotificationCompat.Builder(this@PlaybackService, NOTIFICATION_CHANNEL_ID)
|
||||
.setContentIntent(pendingIntent)
|
||||
.setContentIntent(createContentPendingIntent())
|
||||
.setSmallIcon(R.drawable.media3_notification_small_icon)
|
||||
.setContentTitle(getString(R.string.foreground_exception_title))
|
||||
.setStyle(
|
||||
@@ -874,5 +924,6 @@ class PlaybackService :
|
||||
const val COMMAND_ARGUMENT_FROM_START = "fromStart"
|
||||
const val COMMAND_ARGUMENT_BACKEND = "backend"
|
||||
private const val NOTIFICATION_ID = 3009
|
||||
private const val JUKEBOX_ERROR_NOTIFICATION_ID = 3010
|
||||
}
|
||||
}
|
||||
@@ -65,6 +65,8 @@
|
||||
<string name="download.jukebox_offline">Remote control is not available in offline mode.</string>
|
||||
<string name="download.jukebox_on">Turned on remote control. Music is played on server.</string>
|
||||
<string name="download.jukebox_server_too_old">Remote control is not supported. Please upgrade your Subsonic server.</string>
|
||||
<string name="jukebox_error_title">Jukebox playback failed</string>
|
||||
<string name="jukebox_fallback_text">Switching to local playback on this device.</string>
|
||||
<string name="download.menu_equalizer">Equalizer</string>
|
||||
<string name="download.menu_jukebox_off">Jukebox Off</string>
|
||||
<string name="download.menu_jukebox_on">Jukebox On</string>
|
||||
|
||||
Reference in new issue
Block a user