From 6b62eb6a05aa6a869a9168202334b0468da5effd Mon Sep 17 00:00:00 2001
From: Stephan Ritscher <stephan.ritscher@gmail.com>
Date: Tue, 28 Dec 2021 22:44:08 +0100
Subject: [PATCH] Add option to ignore audio focus

---
 app/src/main/java/org/y20k/transistor/Keys.kt      |  2 ++
 .../main/java/org/y20k/transistor/MainActivity.kt  |  4 ++++
 .../java/org/y20k/transistor/SettingsFragment.kt   | 10 ++++++++++
 .../y20k/transistor/helpers/PreferencesHelper.kt   |  4 ++++
 .../org/y20k/transistor/playback/PlayerService.kt  | 14 ++++++++++++++
 app/src/main/res/values-de/strings.xml             |  2 ++
 app/src/main/res/values/strings.xml                |  2 ++
 7 files changed, 38 insertions(+)

diff --git a/app/src/main/java/org/y20k/transistor/Keys.kt b/app/src/main/java/org/y20k/transistor/Keys.kt
index 8daeb11a..541984b3 100644
--- a/app/src/main/java/org/y20k/transistor/Keys.kt
+++ b/app/src/main/java/org/y20k/transistor/Keys.kt
@@ -72,6 +72,7 @@ object Keys {
     const val CMD_DISMISS_NOTIFICATION: String = "DISMISS_NOTIFICATION"
     const val CMD_NEXT_STATION: String = "NEXT_STATION"
     const val CMD_PREVIOUS_STATION: String = "PREVIOUS_STATION"
+    const val CMD_UPDATE_AUDIO_FOCUS_SETTING: String = "UPDATE_AUDIO_FOCUS_SETTING"
 
 
     // preferences
@@ -91,6 +92,7 @@ object Keys {
     const val PREF_PLAYER_STATE_BOTTOM_SHEET_STATE: String = "PLAYER_STATE_BOTTOM_SHEET_STATE"
     const val PREF_PLAYER_STATE_SLEEP_TIMER_STATE: String = "PLAYER_STATE_SLEEP_TIMER_STATE"
     const val PREF_PLAYER_METADATA_HISTORY: String = "PREF_PLAYER_METADATA_HISTORY"
+    const val PREF_HANDLE_AUDIO_FOCUS: String = "PREF_HANDLE_AUDIO_FOCUS"
 
     // states
     const val STATE_SLEEP_TIMER_STOPPED: Int = 0
diff --git a/app/src/main/java/org/y20k/transistor/MainActivity.kt b/app/src/main/java/org/y20k/transistor/MainActivity.kt
index f9c2d7e9..4a02a578 100644
--- a/app/src/main/java/org/y20k/transistor/MainActivity.kt
+++ b/app/src/main/java/org/y20k/transistor/MainActivity.kt
@@ -16,6 +16,7 @@ package org.y20k.transistor
 
 import android.content.SharedPreferences
 import android.os.Bundle
+import android.support.v4.media.session.MediaControllerCompat
 import androidx.appcompat.app.AppCompatActivity
 import androidx.appcompat.widget.Toolbar
 import androidx.navigation.fragment.NavHostFragment
@@ -90,6 +91,9 @@ class MainActivity: AppCompatActivity() {
             Keys.PREF_THEME_SELECTION -> {
                 AppThemeHelper.setTheme(PreferencesHelper.loadThemeSelection())
             }
+            Keys.PREF_HANDLE_AUDIO_FOCUS -> {
+                MediaControllerCompat.getMediaController(this).sendCommand(Keys.CMD_UPDATE_AUDIO_FOCUS_SETTING, null, null)
+            }
         }
     }
     /*
diff --git a/app/src/main/java/org/y20k/transistor/SettingsFragment.kt b/app/src/main/java/org/y20k/transistor/SettingsFragment.kt
index bf404af5..cff48785 100644
--- a/app/src/main/java/org/y20k/transistor/SettingsFragment.kt
+++ b/app/src/main/java/org/y20k/transistor/SettingsFragment.kt
@@ -85,6 +85,14 @@ class SettingsFragment: PreferenceFragmentCompat(), YesNoDialog.YesNoDialogListe
             }
         }
 
+        // set up "Handle Audio Focus" preference
+        val preferenceHandleAudioFocus: CheckBoxPreference = CheckBoxPreference(activity as Context)
+        preferenceHandleAudioFocus.title = getString(R.string.pref_handle_audio_focus_title)
+        preferenceHandleAudioFocus.key = Keys.PREF_HANDLE_AUDIO_FOCUS
+        preferenceHandleAudioFocus.summary = getString(R.string.pref_handle_audio_focus_summary)
+        preferenceHandleAudioFocus.setDefaultValue(true)
+        
+
         // set up "Update Station Images" preference
         val preferenceUpdateStationImages: Preference = Preference(activity as Context)
         preferenceUpdateStationImages.title = getString(R.string.pref_update_station_images_title)
@@ -155,6 +163,7 @@ class SettingsFragment: PreferenceFragmentCompat(), YesNoDialog.YesNoDialogListe
         val preferenceCategoryGeneral: PreferenceCategory = PreferenceCategory(activity as Context)
         preferenceCategoryGeneral.title = getString(R.string.pref_general_title)
         preferenceCategoryGeneral.contains(preferenceThemeSelection)
+        preferenceCategoryGeneral.contains(preferenceHandleAudioFocus)
 
         val preferenceCategoryMaintenance: PreferenceCategory = PreferenceCategory(activity as Context)
         preferenceCategoryMaintenance.title = getString(R.string.pref_maintenance_title)
@@ -171,6 +180,7 @@ class SettingsFragment: PreferenceFragmentCompat(), YesNoDialog.YesNoDialogListe
         // setup preference screen
         screen.addPreference(preferenceCategoryGeneral)
         screen.addPreference(preferenceThemeSelection)
+        screen.addPreference(preferenceHandleAudioFocus)
         screen.addPreference(preferenceCategoryMaintenance)
         screen.addPreference(preferenceUpdateStationImages)
         screen.addPreference(preferenceUpdateCollection)
diff --git a/app/src/main/java/org/y20k/transistor/helpers/PreferencesHelper.kt b/app/src/main/java/org/y20k/transistor/helpers/PreferencesHelper.kt
index 6cb84b92..8b412638 100644
--- a/app/src/main/java/org/y20k/transistor/helpers/PreferencesHelper.kt
+++ b/app/src/main/java/org/y20k/transistor/helpers/PreferencesHelper.kt
@@ -245,4 +245,8 @@ object PreferencesHelper {
         return sharedPreferences.getBoolean(Keys.PREF_DOWNLOAD_OVER_MOBILE, Keys.DEFAULT_DOWNLOAD_OVER_MOBILE)
     }
 
+    /* Loads handling of audio focus */
+    fun loadHandleAudioFocus(): Boolean {
+        return sharedPreferences.getBoolean(Keys.PREF_HANDLE_AUDIO_FOCUS, true)
+    }
 }
diff --git a/app/src/main/java/org/y20k/transistor/playback/PlayerService.kt b/app/src/main/java/org/y20k/transistor/playback/PlayerService.kt
index f1dc1a94..e84c1d7a 100644
--- a/app/src/main/java/org/y20k/transistor/playback/PlayerService.kt
+++ b/app/src/main/java/org/y20k/transistor/playback/PlayerService.kt
@@ -92,6 +92,7 @@ class PlayerService(): MediaBrowserServiceCompat() {
     private lateinit var sleepTimer: CountDownTimer
     private var sleepTimerTimeRemaining: Long = 0L
     private var playbackRestartCounter: Int = 0
+    private var handleAudioFocus: Boolean = true
 
     private val attributes = AudioAttributes.Builder()
             .setContentType(C.CONTENT_TYPE_MUSIC)
@@ -132,6 +133,10 @@ class PlayerService(): MediaBrowserServiceCompat() {
         // fetch the metadata history
         metadataHistory = PreferencesHelper.loadMetadataHistory()
 
+        // fetch handle audio focus setting
+        handleAudioFocus = PreferencesHelper.loadHandleAudioFocus()
+        player.setAudioAttributes(attributes, handleAudioFocus)
+
         // create a new MediaSession
         createMediaSession()
 
@@ -800,6 +805,15 @@ class PlayerService(): MediaBrowserServiceCompat() {
                     notificationHelper.hideNotification()
                     return true
                 }
+                Keys.CMD_UPDATE_AUDIO_FOCUS_SETTING -> {
+                    if (player is SimpleExoPlayer) {
+                        handleAudioFocus = PreferencesHelper.loadHandleAudioFocus()
+                        player.setAudioAttributes(attributes, handleAudioFocus)
+                        return true
+                    } else {
+                        return false
+                    }
+                }
                 else -> {
                     return false
                 }
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index bebe0011..0732955b 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -118,6 +118,8 @@
     <string name="pref_theme_selection_mode_device_default">Identisch zum Gerät</string>
     <string name="pref_theme_selection_mode_dark">Dunkler Modus</string>
     <string name="pref_general_title">Allgemein</string>
+    <string name="pref_handle_audio_focus_title">Audio Focus berücksichtigen</string>
+    <string name="pref_handle_audio_focus_summary">Wiedergabe stoppen wenn andere Anwendung Audio ausgibt oder Telefonanruf gestartet wird</string>
     <string name="pref_delete_all_title">Downloads löschen</string>
     <string name="toastmessage_error_missing_storage_permission">Erteile die Berechtigung „Speicher lesen“, um diese Datei zu öffnen.</string>
     <string name="dialog_yes_no_positive_button_update_covers">Aktualisieren</string>
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index acca4b91..6fef8ee7 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -76,6 +76,8 @@
     <string name="pref_app_version_title">App Version</string>
     <string name="pref_delete_all_title">Delete Downloads</string>
     <string name="pref_general_title">General</string>
+    <string name="pref_handle_audio_focus_title">Handle Audio Focus</string>
+    <string name="pref_handle_audio_focus_summary">Stop playback when other app starts playback or phone call is started</string>
     <string name="pref_maintenance_title">Maintenance</string>
     <string name="pref_m3u_export_summary">Save your radio stations to an M3U playlist file that can be imported into other players.</string>
     <string name="pref_m3u_export_title">Export M3U</string>