Add mono audio to SoundSettings

Bug: 15283594
Bug: 22700363
Change-Id: Ic4571dee4567a94265bbcf11d08108b19687b284
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 86a6195..d32aeb2 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -5597,6 +5597,15 @@
     <!-- Sound: Title for the option managing whether or not to vibrate when ringing. [CHAR LIMIT=30] -->
     <string name="vibrate_when_ringing_title">Also vibrate for calls</string>
 
+    <!-- Sound: Title for the option managing mono audio output. [CHAR LIMIT=30] -->
+    <string name="master_mono_title">Mono playback</string>
+
+    <!-- Sound: Mono audio: Summary for mono audio output when enabled.  [CHAR LIMIT=40] -->
+    <string name="master_mono_on">Always play back audio in mono</string>
+
+    <!-- Sound: Mono audio: Summary for mono audio output when disabled.  [CHAR LIMIT=40] -->
+    <string name="master_mono_off">Always play back audio in mono</string>
+
     <!-- Sound: Title for the other sounds option and associated settings page. [CHAR LIMIT=30] -->
     <string name="other_sound_settings">Other sounds</string>
 
diff --git a/res/xml/sound_settings.xml b/res/xml/sound_settings.xml
index 652310f..2cdebc4 100644
--- a/res/xml/sound_settings.xml
+++ b/res/xml/sound_settings.xml
@@ -50,6 +50,14 @@
                 android:title="@string/vibrate_when_ringing_title"
                 android:persistent="false" />
 
+        <!-- Master mono -->
+        <SwitchPreference
+                android:key="master_mono"
+                android:title="@string/master_mono_title"
+                android:persistent="false"
+                android:summaryOn="@string/master_mono_on"
+                android:summaryOff="@string/master_mono_off" />
+
         <!-- Interruptions -->
         <PreferenceScreen
                 android:key="zen_mode"
diff --git a/src/com/android/settings/notification/SoundSettings.java b/src/com/android/settings/notification/SoundSettings.java
index 11517ea..1c21329 100644
--- a/src/com/android/settings/notification/SoundSettings.java
+++ b/src/com/android/settings/notification/SoundSettings.java
@@ -74,6 +74,7 @@
     private static final String KEY_PHONE_RINGTONE = "ringtone";
     private static final String KEY_NOTIFICATION_RINGTONE = "notification_ringtone";
     private static final String KEY_VIBRATE_WHEN_RINGING = "vibrate_when_ringing";
+    private static final String KEY_MASTER_MONO = "master_mono";
     private static final String KEY_WIFI_DISPLAY = "wifi_display";
     private static final String KEY_ZEN_MODE = "zen_mode";
     private static final String KEY_CELL_BROADCAST_SETTINGS = "cell_broadcast_settings";
@@ -103,6 +104,7 @@
     private Preference mPhoneRingtonePreference;
     private Preference mNotificationRingtonePreference;
     private TwoStatePreference mVibrateWhenRinging;
+    private TwoStatePreference mMasterMono;
     private ComponentName mSuppressor;
     private int mRingerMode = -1;
 
@@ -166,6 +168,7 @@
         }
         initRingtones();
         initVibrateWhenRinging();
+        initMasterMono();
         updateRingerMode();
         updateEffectsSuppressor();
     }
@@ -419,6 +422,33 @@
                 Settings.System.VIBRATE_WHEN_RINGING, 0) != 0);
     }
 
+    // === Master mono ===
+
+    private void initMasterMono() {
+        mMasterMono =
+                (TwoStatePreference) getPreferenceScreen().findPreference(KEY_MASTER_MONO);
+        if (mMasterMono == null) {
+            Log.i(TAG, "Preference not found: " + KEY_MASTER_MONO);
+            return;
+        }
+
+        mMasterMono.setPersistent(false);
+        updateMasterMono();
+        mMasterMono.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
+            @Override
+            public boolean onPreferenceChange(Preference preference, Object newValue) {
+                final boolean val = (Boolean) newValue;
+                mAudioManager.setMasterMono(val);
+                return true;
+            }
+        });
+    }
+
+    private void updateMasterMono() {
+        if (mMasterMono == null) return;
+        mMasterMono.setChecked(mAudioManager.isMasterMono());
+    }
+
     // === Callbacks ===
 
     private final class SettingsObserver extends ContentObserver {
@@ -453,6 +483,7 @@
         private static final int STOP_SAMPLE = 3;
         private static final int UPDATE_EFFECTS_SUPPRESSOR = 4;
         private static final int UPDATE_RINGER_MODE = 5;
+        private static final int UPDATE_MASTER_MONO = 6;
 
         private H() {
             super(Looper.getMainLooper());
@@ -476,6 +507,9 @@
                 case UPDATE_RINGER_MODE:
                     updateRingerMode();
                     break;
+                case UPDATE_MASTER_MONO:
+                    updateMasterMono();
+                    break;
             }
         }
     }
@@ -489,6 +523,7 @@
                 final IntentFilter filter = new IntentFilter();
                 filter.addAction(NotificationManager.ACTION_EFFECTS_SUPPRESSOR_CHANGED);
                 filter.addAction(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION);
+                filter.addAction(AudioManager.MASTER_MONO_CHANGED_ACTION);
                 mContext.registerReceiver(this, filter);
             } else {
                 mContext.unregisterReceiver(this);
@@ -503,6 +538,8 @@
                 mHandler.sendEmptyMessage(H.UPDATE_EFFECTS_SUPPRESSOR);
             } else if (AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION.equals(action)) {
                 mHandler.sendEmptyMessage(H.UPDATE_RINGER_MODE);
+            } else if (AudioManager.MASTER_MONO_CHANGED_ACTION.equals(action)) {
+                mHandler.sendEmptyMessage(H.UPDATE_MASTER_MONO);
             }
         }
     }