Fix vibration issue in DND mode.

Currently if user turn on the vibrator or set a ringtone with haptic
channel, we only evaluate the ringer mode using
AudioManager#getRingerMode. While in DND mode, this value will always be
SILENT. For cases that some call can bypass the dnd check, we need
bypass the ringer mode check when we try to start the vibration.

Bug: 244887005
Test: TelecomUnitTestCases:RingerTest
Change-Id: Ic327d81e247c429a44f2aaec34e1897c00338427
diff --git a/src/com/android/server/telecom/Ringer.java b/src/com/android/server/telecom/Ringer.java
index c9bb742..bf678d2 100644
--- a/src/com/android/server/telecom/Ringer.java
+++ b/src/com/android/server/telecom/Ringer.java
@@ -275,7 +275,7 @@
         VibrationEffect effect;
         CompletableFuture<Boolean> hapticsFuture = null;
         // Determine if the settings and DND mode indicate that the vibrator can be used right now.
-        boolean isVibratorEnabled = isVibratorEnabled(mContext);
+        boolean isVibratorEnabled = isVibratorEnabled(mContext, attributes.shouldRingForContact());
         boolean shouldApplyRampingRinger =
                 isVibratorEnabled && mSystemSettingsUtil.isRampingRingerEnabled(mContext);
         if (attributes.isRingerAudible()) {
@@ -367,7 +367,7 @@
                         "hasVibrator=%b, userRequestsVibrate=%b, ringerMode=%d, isVibrating=%b",
                         mVibrator.hasVibrator(),
                         mSystemSettingsUtil.isRingVibrationEnabled(mContext),
-                        mAudioManager.getRingerModeInternal(), mIsVibrating);
+                        mAudioManager.getRingerMode(), mIsVibrating);
                 if (mSystemSettingsUtil.isRampingRingerEnabled(mContext) && isRingerAudible) {
                     Log.i(this, "start vibration for ramping ringer.");
                 } else {
@@ -381,7 +381,7 @@
                         "hasVibrator=%b, userRequestsVibrate=%b, ringerMode=%d, isVibrating=%b",
                         mVibrator.hasVibrator(),
                         mSystemSettingsUtil.isRingVibrationEnabled(mContext),
-                        mAudioManager.getRingerModeInternal(), mIsVibrating);
+                        mAudioManager.getRingerMode(), mIsVibrating);
             }
         }
     }
@@ -503,13 +503,14 @@
         }
     }
 
-    private boolean isVibratorEnabled(Context context) {
+    private boolean isVibratorEnabled(Context context, boolean shouldRingForContact) {
         AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
         // Use AudioManager#getRingerMode for more accurate result, instead of
         // AudioManager#getRingerModeInternal which only useful for volume controllers
         return mVibrator.hasVibrator()
                 && mSystemSettingsUtil.isRingVibrationEnabled(context)
-                && audioManager.getRingerMode() != AudioManager.RINGER_MODE_SILENT;
+                && (audioManager.getRingerMode() != AudioManager.RINGER_MODE_SILENT
+                || shouldRingForContact);
     }
 
     private RingerAttributes getRingerAttributes(Call call, boolean isHfpDeviceAttached) {
diff --git a/tests/src/com/android/server/telecom/tests/RingerTest.java b/tests/src/com/android/server/telecom/tests/RingerTest.java
index 2094fab..fbc08ba 100644
--- a/tests/src/com/android/server/telecom/tests/RingerTest.java
+++ b/tests/src/com/android/server/telecom/tests/RingerTest.java
@@ -455,6 +455,23 @@
                 .vibrate(any(VibrationEffect.class), any(VibrationAttributes.class));
     }
 
+    @SmallTest
+    @Test
+    public void testRingAndVibrateForAllowedCallInDndMode() throws Exception {
+        mRingerUnderTest.startCallWaiting(mockCall1);
+        Ringtone mockRingtone = mock(Ringtone.class);
+        when(mockRingtoneFactory.getRingtone(any(Call.class))).thenReturn(mockRingtone);
+        when(mockAudioManager.getRingerMode()).thenReturn(AudioManager.RINGER_MODE_SILENT);
+        when(mockAudioManager.getStreamVolume(AudioManager.STREAM_RING)).thenReturn(100);
+        mFuture.complete(true); // using audio coupled haptics
+        enableVibrationWhenRinging();
+        assertTrue(mRingerUnderTest.startRinging(mockCall2, true));
+        mRingCompletionFuture.get();
+        verify(mockTonePlayer).stopTone();
+        verify(mockRingtonePlayer).play(any(RingtoneFactory.class), any(Call.class), eq(null),
+                eq(true) /* isRingerAudible */, eq(true) /* isVibrationEnabled */);
+    }
+
     private void ensureRingerIsAudible() {
         Ringtone mockRingtone = mock(Ringtone.class);
         when(mockRingtoneFactory.getRingtone(any(Call.class))).thenReturn(mockRingtone);