Persists master mute state, overlay-able

Bug: 80541413
Test: adb shell input keyevent 164
Change-Id: I1626692885c67a0ff81bf88b57b8d00aad093b01
diff --git a/car-lib/src/android/car/media/CarAudioManager.java b/car-lib/src/android/car/media/CarAudioManager.java
index c9aef74..7257255 100644
--- a/car-lib/src/android/car/media/CarAudioManager.java
+++ b/car-lib/src/android/car/media/CarAudioManager.java
@@ -47,6 +47,13 @@
         return VOLUME_SETTINGS_KEY_FOR_GROUP_PREFIX + groupId;
     }
 
+    /**
+     * Key to persist master mute state in {@link Settings.Global}
+     *
+     * @hide
+     */
+    public static final String VOLUME_SETTINGS_KEY_MASTER_MUTE = "android.car.MASTER_MUTE";
+
     private final ContentResolver mContentResolver;
     private final ICarAudio mService;
 
diff --git a/service/res/values/config.xml b/service/res/values/config.xml
index 45e6e0b..8244231 100644
--- a/service/res/values/config.xml
+++ b/service/res/values/config.xml
@@ -24,6 +24,9 @@
           dynamic audio routing is disabled and audio works in legacy mode. It may be useful
           during initial development where audio hal does not support bus based addressing yet. -->
     <bool name="audioUseDynamicRouting">false</bool>
+    <!--  Configuration to persist master mute state. If this is set to true,
+          Android will restore the master mute state on boot. -->
+    <bool name="audioPersistMasterMuteState">true</bool>
     <!-- Whether to block other audio while media audio is muted with display off. When set to true,
          other sounds cannot be played either while display is off. If false, only media is muted
          and other sounds can be still played. -->
diff --git a/service/src/com/android/car/CarAudioService.java b/service/src/com/android/car/CarAudioService.java
index 1b7ee67..2e0583c 100644
--- a/service/src/com/android/car/CarAudioService.java
+++ b/service/src/com/android/car/CarAudioService.java
@@ -18,6 +18,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.car.Car;
+import android.car.media.CarAudioManager;
 import android.car.media.CarAudioPatchHandle;
 import android.car.media.ICarAudio;
 import android.car.media.ICarVolumeCallback;
@@ -45,6 +46,7 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.RemoteException;
+import android.provider.Settings;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.Log;
@@ -125,6 +127,7 @@
     private final TelephonyManager mTelephonyManager;
     private final AudioManager mAudioManager;
     private final boolean mUseDynamicRouting;
+    private final boolean mPersistMasterMuteState;
     private final SparseIntArray mContextToBus = new SparseIntArray();
     private final SparseArray<CarAudioDeviceInfo> mCarAudioDeviceInfos = new SparseArray<>();
 
@@ -203,6 +206,8 @@
         mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
         mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
         mUseDynamicRouting = mContext.getResources().getBoolean(R.bool.audioUseDynamicRouting);
+        mPersistMasterMuteState = mContext.getResources().getBoolean(
+                R.bool.audioPersistMasterMuteState);
     }
 
     /**
@@ -219,6 +224,13 @@
                 setupDynamicRouting();
                 setupVolumeGroups();
             }
+
+            // Restore master mute state if applicable
+            if (mPersistMasterMuteState) {
+                boolean storedMasterMute = Settings.Global.getInt(mContext.getContentResolver(),
+                        CarAudioManager.VOLUME_SETTINGS_KEY_MASTER_MUTE, 0) != 0;
+                mAudioManager.setMasterMute(storedMasterMute, 0);
+            }
         }
     }
 
@@ -242,7 +254,8 @@
     public void dump(PrintWriter writer) {
         writer.println("*CarAudioService*");
         writer.println("\tRun in legacy mode? " + (!mUseDynamicRouting));
-        writer.println("\tMaster mute? " + mAudioManager.isMasterMute());
+        writer.println("\tPersist master mute state? " + mPersistMasterMuteState);
+        writer.println("\tMaster muted? " + mAudioManager.isMasterMute());
         // Empty line for comfortable reading
         writer.println();
         if (mUseDynamicRouting) {
@@ -292,6 +305,13 @@
                 Log.e(CarLog.TAG_AUDIO, "Failed to callback onMasterMuteChanged", e);
             }
         }
+
+        // Persists master mute state if applicable
+        if (mPersistMasterMuteState) {
+            Settings.Global.putInt(mContext.getContentResolver(),
+                    CarAudioManager.VOLUME_SETTINGS_KEY_MASTER_MUTE,
+                    mAudioManager.isMasterMute() ? 1 : 0);
+        }
     }
 
     /**