Merge "Keep ringer changes in priority only dnd"
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 0a87097..1a19698 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -107,7 +107,7 @@
     @VisibleForTesting protected int mZenMode;
     private int mUser = UserHandle.USER_SYSTEM;
     @VisibleForTesting protected ZenModeConfig mConfig;
-    private AudioManagerInternal mAudioManager;
+    @VisibleForTesting protected AudioManagerInternal mAudioManager;
     protected PackageManager mPm;
     private long mSuppressedEffects;
 
@@ -886,7 +886,8 @@
                 exceptionPackages);
     }
 
-    private void applyZenToRingerMode() {
+    @VisibleForTesting
+    protected void applyZenToRingerMode() {
         if (mAudioManager == null) return;
         // force the ringer mode into compliance
         final int ringerModeInternal = mAudioManager.getRingerModeInternal();
@@ -901,15 +902,8 @@
                 break;
             case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS:
                 if (ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted(mConfig)) {
-                    if (ringerModeInternal != AudioManager.RINGER_MODE_SILENT) {
-                        setPreviousRingerModeSetting(ringerModeInternal);
-                        newRingerModeInternal = AudioManager.RINGER_MODE_SILENT;
-                    }
-                } else {
-                    if (ringerModeInternal == AudioManager.RINGER_MODE_SILENT) {
-                        newRingerModeInternal = getPreviousRingerModeSetting();
-                        setPreviousRingerModeSetting(null);
-                    }
+                    setPreviousRingerModeSetting(ringerModeInternal);
+                    newRingerModeInternal = AudioManager.RINGER_MODE_SILENT;
                 }
                 break;
             case Global.ZEN_MODE_OFF:
@@ -1003,7 +997,8 @@
         }
     }
 
-    private final class RingerModeDelegate implements AudioManagerInternal.RingerModeDelegate {
+    @VisibleForTesting
+    protected final class RingerModeDelegate implements AudioManagerInternal.RingerModeDelegate {
         @Override
         public String toString() {
             return TAG;
@@ -1040,9 +1035,14 @@
                     }
                     break;
             }
+
             if (newZen != -1) {
                 setManualZenMode(newZen, null, "ringerModeInternal", null,
                         false /*setRingerMode*/);
+            } else if (mZenMode == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS
+                    && !ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted(mConfig)) {
+                // in priority only with ringer not muted, save ringer mode changes
+                setPreviousRingerModeSetting(ringerModeNew);
             }
 
             if (isChange || newZen != -1 || ringerModeExternal != ringerModeExternalOut) {
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
index 6144c51..6948b72 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
@@ -26,6 +26,7 @@
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
@@ -37,7 +38,12 @@
 import android.content.Context;
 import android.content.res.Resources;
 import android.media.AudioAttributes;
+import android.media.AudioManager;
+import android.media.AudioManagerInternal;
+import android.media.VolumePolicy;
 import android.provider.Settings;
+import android.provider.Settings.Global;
+import android.service.notification.ZenModeConfig;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
@@ -241,4 +247,119 @@
         verify(mNotificationManager, never()).notify(eq(ZenModeHelper.TAG),
                 eq(SystemMessage.NOTE_ZEN_UPGRADE), any());
     }
+
+    @Test
+    public void testZenSetInternalRinger_AllPriorityNotificationSoundsMuted() {
+        AudioManagerInternal mAudioManager = mock(AudioManagerInternal.class);
+        mZenModeHelperSpy.mAudioManager = mAudioManager;
+        Global.putString(mContext.getContentResolver(), Global.ZEN_MODE_RINGER_LEVEL,
+                Integer.toString(AudioManager.RINGER_MODE_NORMAL));
+
+        // 1. Current ringer is normal
+        when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
+        // Set zen to priority-only with all notification sounds muted (so ringer will be muted)
+        mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+        mZenModeHelperSpy.mConfig.allowReminders = false;
+        mZenModeHelperSpy.mConfig.allowCalls = false;
+        mZenModeHelperSpy.mConfig.allowMessages = false;
+        mZenModeHelperSpy.mConfig.allowEvents = false;
+        mZenModeHelperSpy.mConfig.allowRepeatCallers= false;
+
+        // 2. apply priority only zen - verify ringer is set to silent
+        mZenModeHelperSpy.applyZenToRingerMode();
+        verify(mAudioManager, atLeastOnce()).setRingerModeInternal(AudioManager.RINGER_MODE_SILENT,
+                mZenModeHelperSpy.TAG);
+
+        // 3. apply zen off - verify zen is set to prevoius ringer (normal)
+        when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT);
+        mZenModeHelperSpy.mZenMode = Global.ZEN_MODE_OFF;
+        mZenModeHelperSpy.applyZenToRingerMode();
+        verify(mAudioManager, atLeastOnce()).setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
+                mZenModeHelperSpy.TAG);
+    }
+
+    @Test
+    public void testZenSetInternalRinger_NotAllPriorityNotificationSoundsMuted_StartNormal() {
+        AudioManagerInternal mAudioManager = mock(AudioManagerInternal.class);
+        mZenModeHelperSpy.mAudioManager = mAudioManager;
+        Global.putString(mContext.getContentResolver(), Global.ZEN_MODE_RINGER_LEVEL,
+                Integer.toString(AudioManager.RINGER_MODE_NORMAL));
+
+        // 1. Current ringer is normal
+        when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
+        mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+        mZenModeHelperSpy.mConfig.allowReminders = true;
+
+        // 2. apply priority only zen - verify ringer is normal
+        mZenModeHelperSpy.applyZenToRingerMode();
+        verify(mAudioManager, atLeastOnce()).setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
+                mZenModeHelperSpy.TAG);
+
+        // 3.  apply zen off - verify ringer remains normal
+        when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
+        mZenModeHelperSpy.mZenMode = Global.ZEN_MODE_OFF;
+        mZenModeHelperSpy.applyZenToRingerMode();
+        verify(mAudioManager, atLeastOnce()).setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
+                mZenModeHelperSpy.TAG);
+    }
+
+    @Test
+    public void testZenSetInternalRinger_NotAllPriorityNotificationSoundsMuted_StartSilent() {
+        AudioManagerInternal mAudioManager = mock(AudioManagerInternal.class);
+        mZenModeHelperSpy.mAudioManager = mAudioManager;
+        Global.putString(mContext.getContentResolver(), Global.ZEN_MODE_RINGER_LEVEL,
+                Integer.toString(AudioManager.RINGER_MODE_SILENT));
+
+        // 1. Current ringer is silent
+        when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT);
+        mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+        mZenModeHelperSpy.mConfig.allowReminders = true;
+
+        // 2. apply priority only zen - verify ringer is silent
+        mZenModeHelperSpy.applyZenToRingerMode();
+        verify(mAudioManager, atLeastOnce()).setRingerModeInternal(AudioManager.RINGER_MODE_SILENT,
+                mZenModeHelperSpy.TAG);
+
+        // 3. apply zen-off - verify ringer is still silent
+        when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT);
+        mZenModeHelperSpy.mZenMode = Global.ZEN_MODE_OFF;
+        mZenModeHelperSpy.applyZenToRingerMode();
+        verify(mAudioManager, atLeastOnce()).setRingerModeInternal(AudioManager.RINGER_MODE_SILENT,
+                mZenModeHelperSpy.TAG);
+    }
+
+    @Test
+    public void testZenSetInternalRinger_NotAllPriorityNotificationSoundsMuted_RingerChanges() {
+        AudioManagerInternal mAudioManager = mock(AudioManagerInternal.class);
+        mZenModeHelperSpy.mAudioManager = mAudioManager;
+        Global.putString(mContext.getContentResolver(), Global.ZEN_MODE_RINGER_LEVEL,
+                Integer.toString(AudioManager.RINGER_MODE_NORMAL));
+
+        // 1. Current ringer is normal
+        when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
+        // Set zen to priority-only with all notification sounds muted (so ringer will be muted)
+        mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+        mZenModeHelperSpy.mConfig.allowReminders = true;
+
+        // 2. apply priority only zen - verify zen will still be normal
+        mZenModeHelperSpy.applyZenToRingerMode();
+        verify(mAudioManager, atLeastOnce()).setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
+                mZenModeHelperSpy.TAG);
+
+        // 3. change ringer from normal to silent, verify previous ringer set to new rigner (silent)
+        ZenModeHelper.RingerModeDelegate ringerModeDelegate =
+                mZenModeHelperSpy.new RingerModeDelegate();
+        ringerModeDelegate.onSetRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
+                AudioManager.RINGER_MODE_SILENT, "test", AudioManager.RINGER_MODE_NORMAL,
+                VolumePolicy.DEFAULT);
+        assertEquals(AudioManager.RINGER_MODE_SILENT, Global.getInt(mContext.getContentResolver(),
+                Global.ZEN_MODE_RINGER_LEVEL, AudioManager.RINGER_MODE_NORMAL));
+
+        // 4.  apply zen off - verify ringer still silenced
+        when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT);
+        mZenModeHelperSpy.mZenMode = Global.ZEN_MODE_OFF;
+        mZenModeHelperSpy.applyZenToRingerMode();
+        verify(mAudioManager, atLeastOnce()).setRingerModeInternal(AudioManager.RINGER_MODE_SILENT,
+                mZenModeHelperSpy.TAG);
+    }
 }