From c44003907abf1b0d622047f885fc8ce36923ea46 Mon Sep 17 00:00:00 2001 From: OxygenCobalt Date: Sat, 5 Dec 2020 09:42:09 -0700 Subject: [PATCH] Add audio settings Add some settings to control how audio is being played. --- .../oxycblt/auxio/playback/PlaybackService.kt | 26 +++++++++----- .../oxycblt/auxio/settings/SettingsManager.kt | 35 ++++++++++++------- .../org/oxycblt/auxio/ui/InterfaceUtils.kt | 2 +- .../java/org/oxycblt/auxio/ui/ThemeUtils.kt | 21 ++++++++--- app/src/main/res/values/strings.xml | 10 +++++- app/src/main/res/xml-v27/prefs_main.xml | 30 +++++++++++++--- app/src/main/res/xml/prefs_main.xml | 28 +++++++++++++-- 7 files changed, 117 insertions(+), 35 deletions(-) diff --git a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackService.kt b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackService.kt index 4ac6d8ca2..a1ca1c53d 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackService.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackService.kt @@ -63,6 +63,10 @@ class PlaybackService : Service(), Player.EventListener, PlaybackStateManager.Ca private lateinit var mediaSession: MediaSessionCompat private lateinit var systemReceiver: SystemEventReceiver + private val audioAttributes = AudioAttributes.Builder() + .setUsage(C.USAGE_MEDIA) + .setContentType(C.CONTENT_TYPE_MUSIC) + .build() private lateinit var notificationManager: NotificationManager private lateinit var notification: NotificationCompat.Builder @@ -95,11 +99,7 @@ class PlaybackService : Service(), Player.EventListener, PlaybackStateManager.Ca // Set up AudioFocus/AudioAttributes player.setAudioAttributes( - AudioAttributes.Builder() - .setUsage(C.USAGE_MEDIA) - .setContentType(C.CONTENT_TYPE_MUSIC) - .build(), - true + audioAttributes, settingsManager.doAudioFocus ) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { @@ -323,6 +323,13 @@ class PlaybackService : Service(), Player.EventListener, PlaybackStateManager.Ca startForegroundOrNotify("Notif action update") } + override fun onAudioFocusUpdate(doAudioFocus: Boolean) { + player.setAudioAttributes( + audioAttributes, + doAudioFocus + ) + } + // --- OTHER FUNCTIONS --- private fun restorePlayer() { @@ -392,8 +399,9 @@ class PlaybackService : Service(), Player.EventListener, PlaybackStateManager.Ca } private fun startForegroundOrNotify(reason: String) { - // Start the service in the foreground if haven't already. - if (playbackManager.hasPlayed) { + // Don't start the foreground if the playback hasn't started yet AND if the playback hasn't + // been restored + if (playbackManager.hasPlayed && playbackManager.isRestored) { Log.d(this::class.simpleName, "Starting foreground/notifying because of $reason") if (!isForeground) { @@ -501,7 +509,7 @@ class PlaybackService : Service(), Player.EventListener, PlaybackStateManager.Ca } private fun resume() { - if (playbackManager.song != null) { + if (playbackManager.song != null && settingsManager.doPlugMgt) { Log.d(this::class.simpleName, "Device connected, resuming...") playbackManager.setPlayingStatus(true) @@ -509,7 +517,7 @@ class PlaybackService : Service(), Player.EventListener, PlaybackStateManager.Ca } private fun pause() { - if (playbackManager.song != null) { + if (playbackManager.song != null && settingsManager.doPlugMgt) { Log.d(this::class.simpleName, "Device disconnected, pausing...") playbackManager.setPlayingStatus(false) diff --git a/app/src/main/java/org/oxycblt/auxio/settings/SettingsManager.kt b/app/src/main/java/org/oxycblt/auxio/settings/SettingsManager.kt index 1d5278f4d..512039e36 100644 --- a/app/src/main/java/org/oxycblt/auxio/settings/SettingsManager.kt +++ b/app/src/main/java/org/oxycblt/auxio/settings/SettingsManager.kt @@ -22,9 +22,7 @@ class SettingsManager private constructor(context: Context) : // --- VALUES --- val theme: Int - get() { - return sharedPrefs.getString(Keys.KEY_THEME, EntryNames.THEME_AUTO)!!.toThemeInt() - } + get() = sharedPrefs.getString(Keys.KEY_THEME, EntryNames.THEME_AUTO)!!.toThemeInt() var accent: Pair get() { @@ -44,19 +42,13 @@ class SettingsManager private constructor(context: Context) : } val edgeEnabled: Boolean - get() { - return sharedPrefs.getBoolean(Keys.KEY_EDGE_TO_EDGE, false) - } + get() = sharedPrefs.getBoolean(Keys.KEY_EDGE_TO_EDGE, false) val colorizeNotif: Boolean - get() { - return sharedPrefs.getBoolean(Keys.KEY_COLORIZE_NOTIFICATION, true) - } + get() = sharedPrefs.getBoolean(Keys.KEY_COLORIZE_NOTIFICATION, true) val useAltNotifAction: Boolean - get() { - return sharedPrefs.getBoolean(Keys.KEY_USE_ALT_NOTIFICATION_ACTION, false) - } + get() = sharedPrefs.getBoolean(Keys.KEY_USE_ALT_NOTIFICATION_ACTION, false) val libraryDisplayMode: DisplayMode get() { @@ -68,6 +60,12 @@ class SettingsManager private constructor(context: Context) : ) } + val doAudioFocus: Boolean + get() = sharedPrefs.getBoolean(Keys.KEY_AUDIO_FOCUS, true) + + val doPlugMgt: Boolean + get() = sharedPrefs.getBoolean(Keys.KEY_PLUG_MANAGEMENT, true) + var librarySortMode: SortMode get() { return SortMode.fromInt( @@ -110,6 +108,10 @@ class SettingsManager private constructor(context: Context) : Keys.KEY_LIBRARY_DISPLAY_MODE -> callbacks.forEach { it.onLibDisplayModeUpdate(libraryDisplayMode) } + + Keys.KEY_AUDIO_FOCUS -> callbacks.forEach { + it.onAudioFocusUpdate(doAudioFocus) + } } } @@ -149,6 +151,9 @@ class SettingsManager private constructor(context: Context) : const val KEY_COLORIZE_NOTIFICATION = "KEY_COLOR_NOTIF" const val KEY_USE_ALT_NOTIFICATION_ACTION = "KEY_ALT_NOTIF_ACTION" const val KEY_LIBRARY_DISPLAY_MODE = "KEY_LIBRARY_DISPLAY_MODE" + const val KEY_AUDIO_FOCUS = "KEY_AUDIO_FOCUS" + const val KEY_PLUG_MANAGEMENT = "KEY_PLUG_MGT" + const val KEY_LIBRARY_SORT_MODE = "KEY_LIBRARY_SORT_MODE" } @@ -158,9 +163,15 @@ class SettingsManager private constructor(context: Context) : const val THEME_DARK = "DARK" } + /** + * An safe interface for receiving some preference updates. Use this instead of + * [SharedPreferences.OnSharedPreferenceChangeListener] if possible, as it doesn't require a + * context. + */ interface Callback { fun onColorizeNotifUpdate(doColorize: Boolean) {} fun onNotifActionUpdate(useAltAction: Boolean) {} fun onLibDisplayModeUpdate(displayMode: DisplayMode) {} + fun onAudioFocusUpdate(doAudioFocus: Boolean) {} } } diff --git a/app/src/main/java/org/oxycblt/auxio/ui/InterfaceUtils.kt b/app/src/main/java/org/oxycblt/auxio/ui/InterfaceUtils.kt index 3d1e64f53..d5b0a909c 100644 --- a/app/src/main/java/org/oxycblt/auxio/ui/InterfaceUtils.kt +++ b/app/src/main/java/org/oxycblt/auxio/ui/InterfaceUtils.kt @@ -73,7 +73,7 @@ fun Spanned.render(): Spanned { } /** - * Handle the new transparent system bars on light mode. Adapted from Music Player GO + * Handle transparent system bars. Adapted from Music Player GO * (https://github.com/enricocid/Music-Player-GO) */ @TargetApi(Build.VERSION_CODES.O_MR1) diff --git a/app/src/main/java/org/oxycblt/auxio/ui/ThemeUtils.kt b/app/src/main/java/org/oxycblt/auxio/ui/ThemeUtils.kt index 155a07b5a..03829da0c 100644 --- a/app/src/main/java/org/oxycblt/auxio/ui/ThemeUtils.kt +++ b/app/src/main/java/org/oxycblt/auxio/ui/ThemeUtils.kt @@ -1,7 +1,9 @@ package org.oxycblt.auxio.ui import android.content.Context +import android.content.res.Resources import android.text.Spanned +import android.util.Log import android.util.TypedValue import androidx.annotation.AttrRes import androidx.annotation.ColorInt @@ -14,7 +16,9 @@ import java.util.Locale // Functions for managing colors/accents. -// Pairs of the base accent and its theme +/** + * An array of the base accents and their respective themes. + */ val ACCENTS = arrayOf( Pair(R.color.red, R.style.Theme_Red), // 0 Pair(R.color.pink, R.style.Theme_Pink), // 1 @@ -37,8 +41,10 @@ val ACCENTS = arrayOf( Pair(R.color.blue_grey, R.style.Theme_BlueGrey) // 18 ) -// The names for each colors. These are translatable, so make sure to use these instead of getting -// the color name directly. +/** + * An array of strings for each accent, use these instead of [Resources.getResourceName] so that + * the accent names are translated. + */ private val ACCENT_NAMES = arrayOf( R.string.color_label_red, R.string.color_label_pink, R.string.color_label_purple, R.string.color_label_deep_purple, @@ -52,6 +58,9 @@ private val ACCENT_NAMES = arrayOf( R.string.color_label_blue_grey ) +/** + * The programmatically accessible accent, reflects the currently set accent. + */ lateinit var accent: Pair /** @@ -86,7 +95,9 @@ fun getInactiveAlpha(@ColorRes color: Int): Int { fun Int.toColor(context: Context): Int { return try { ContextCompat.getColor(context, this) - } catch (e: Exception) { + } catch (e: Resources.NotFoundException) { + Log.e(this::class.simpleName, "Attempted color load failed.") + // Default to the emergency color [Black] if the loading fails. ContextCompat.getColor(context, android.R.color.black) } @@ -127,7 +138,7 @@ fun getAccentItemSummary(context: Context, newAccent: Pair): String { } /** - * Get the name [in bold]] and the hex value of a theme. + * Get the name (in bold) and the hex value of a theme. */ fun getDetailedAccentSummary(context: Context, newAccent: Pair): Spanned { val name = getAccentItemSummary(context, newAccent) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 49cc485ef..e201bfd9c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -43,6 +43,7 @@ Light Dark Accent + Unknown Accent Edge-To-Edge Edge-to-edge is enabled Edge-to-edge is disabled @@ -54,6 +55,13 @@ Use alternate notification action Prefer repeat mode action Prefer shuffle action + Audio + Audio focus + Audio focus is enabled + Audio focus is disabled + Headset plug management + Headset plug management is enabled + Headset plug management is disabled State saved @@ -98,7 +106,7 @@ Deep Purple Indigo Blue - Light blue + Light Blue Cyan Teal Green diff --git a/app/src/main/res/xml-v27/prefs_main.xml b/app/src/main/res/xml-v27/prefs_main.xml index 10eb68138..8571df925 100644 --- a/app/src/main/res/xml-v27/prefs_main.xml +++ b/app/src/main/res/xml-v27/prefs_main.xml @@ -17,7 +17,7 @@ app:key="KEY_ACCENT" android:title="@string/setting_accent" android:icon="@drawable/ic_accent" - app:summary="@string/setting_accent" /> + app:summary="@string/setting_accent_unknown" /> + app:defaultValue="false" /> + app:defaultValue="true" /> + app:allowDividerBelow="false" + app:defaultValue="false" /> + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/xml/prefs_main.xml b/app/src/main/res/xml/prefs_main.xml index 447b6f1d9..708d53e72 100644 --- a/app/src/main/res/xml/prefs_main.xml +++ b/app/src/main/res/xml/prefs_main.xml @@ -17,7 +17,7 @@ app:key="KEY_ACCENT" android:title="@string/setting_accent" android:icon="@drawable/ic_accent" - app:summary="@string/setting_accent" /> + app:summary="@string/setting_accent_unknown" /> + app:defaultValue="true" /> + app:allowDividerBelow="false" + app:defaultValue="false" /> + + + + + + + \ No newline at end of file