DO NOT MERGE
Improve incoming call vibration logic.
1. Only check if the incoming call can bypass dnd mode only if dnd mode
is on. Otherwise this will override global silence settings for
ringtone.
2. Update missed call reason print method to debug missed call reason
debugging easier.
Bug: 255788343
Test: atest RingerTest
Change-Id: I02f78f3840ed60c0e9eda5036339dec752e11c3c
Merged-In: I02f78f3840ed60c0e9eda5036339dec752e11c3c
diff --git a/src/com/android/server/telecom/Analytics.java b/src/com/android/server/telecom/Analytics.java
index d6780ed..0aaeca9 100644
--- a/src/com/android/server/telecom/Analytics.java
+++ b/src/com/android/server/telecom/Analytics.java
@@ -48,6 +48,16 @@
import java.util.concurrent.LinkedBlockingDeque;
import java.util.stream.Collectors;
+import static android.provider.CallLog.Calls.AUTO_MISSED_EMERGENCY_CALL;
+import static android.provider.CallLog.Calls.AUTO_MISSED_MAXIMUM_DIALING;
+import static android.provider.CallLog.Calls.AUTO_MISSED_MAXIMUM_RINGING;
+import static android.provider.CallLog.Calls.USER_MISSED_CALL_FILTERS_TIMEOUT;
+import static android.provider.CallLog.Calls.USER_MISSED_CALL_SCREENING_SERVICE_SILENCED;
+import static android.provider.CallLog.Calls.USER_MISSED_DND_MODE;
+import static android.provider.CallLog.Calls.USER_MISSED_LOW_RING_VOLUME;
+import static android.provider.CallLog.Calls.USER_MISSED_NEVER_RANG;
+import static android.provider.CallLog.Calls.USER_MISSED_NO_VIBRATE;
+import static android.provider.CallLog.Calls.USER_MISSED_SHORT_RING;
import static android.telecom.ParcelableCallAnalytics.AnalyticsEvent;
import static android.telecom.TelecomAnalytics.SessionTiming;
@@ -542,7 +552,30 @@
private String getMissedReasonString() {
//TODO: Implement this
- return null;
+ StringBuilder s = new StringBuilder();
+ s.append('[');
+ if ((missedReason & AUTO_MISSED_EMERGENCY_CALL) != 0) {
+ s.append("emergency]");
+ return s.toString();
+ } else if ((missedReason & AUTO_MISSED_MAXIMUM_DIALING) != 0) {
+ s.append("max_dialing]");
+ return s.toString();
+ } else if ((missedReason & AUTO_MISSED_MAXIMUM_RINGING) != 0) {
+ s.append("max_ringing]");
+ return s.toString();
+ }
+
+ // user missed
+ if ((missedReason & USER_MISSED_SHORT_RING) != 0) s.append("short_ring ");
+ if ((missedReason & USER_MISSED_DND_MODE) != 0) s.append("dnd ");
+ if ((missedReason & USER_MISSED_LOW_RING_VOLUME) != 0) s.append("low_volume ");
+ if ((missedReason & USER_MISSED_NO_VIBRATE) != 0) s.append("no_vibrate ");
+ if ((missedReason & USER_MISSED_CALL_SCREENING_SERVICE_SILENCED) != 0)
+ s.append("css_silenced ");
+ if ((missedReason & USER_MISSED_CALL_FILTERS_TIMEOUT) != 0) s.append("filter_timeout ");
+ if ((missedReason & USER_MISSED_NEVER_RANG) != 0) s.append("no_ring ");
+ s.append("]");
+ return s.toString();
}
private String getInCallServicesString() {
diff --git a/src/com/android/server/telecom/Ringer.java b/src/com/android/server/telecom/Ringer.java
index bf678d2..c859fde 100644
--- a/src/com/android/server/telecom/Ringer.java
+++ b/src/com/android/server/telecom/Ringer.java
@@ -19,6 +19,7 @@
import static android.provider.CallLog.Calls.USER_MISSED_DND_MODE;
import static android.provider.CallLog.Calls.USER_MISSED_LOW_RING_VOLUME;
import static android.provider.CallLog.Calls.USER_MISSED_NO_VIBRATE;
+import static android.provider.Settings.Global.ZEN_MODE_OFF;
import android.app.Notification;
import android.app.NotificationManager;
@@ -507,10 +508,14 @@
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
+ NotificationManager notificationManager = context.getSystemService(
+ NotificationManager.class);
+ boolean zenModeOn = notificationManager != null
+ && notificationManager.getZenMode() != ZEN_MODE_OFF;
return mVibrator.hasVibrator()
&& mSystemSettingsUtil.isRingVibrationEnabled(context)
&& (audioManager.getRingerMode() != AudioManager.RINGER_MODE_SILENT
- || shouldRingForContact);
+ || (zenModeOn && shouldRingForContact));
}
private RingerAttributes getRingerAttributes(Call call, boolean isHfpDeviceAttached) {
diff --git a/tests/src/com/android/server/telecom/tests/ComponentContextFixture.java b/tests/src/com/android/server/telecom/tests/ComponentContextFixture.java
index 639ac22..477ca9f 100644
--- a/tests/src/com/android/server/telecom/tests/ComponentContextFixture.java
+++ b/tests/src/com/android/server/telecom/tests/ComponentContextFixture.java
@@ -260,6 +260,8 @@
return Context.PERMISSION_CHECKER_SERVICE;
} else if (svcClass == SensorPrivacyManager.class) {
return Context.SENSOR_PRIVACY_SERVICE;
+ } else if (svcClass == NotificationManager.class) {
+ return Context.NOTIFICATION_SERVICE;
}
throw new UnsupportedOperationException();
}
diff --git a/tests/src/com/android/server/telecom/tests/RingerTest.java b/tests/src/com/android/server/telecom/tests/RingerTest.java
index fbc08ba..12420a8 100644
--- a/tests/src/com/android/server/telecom/tests/RingerTest.java
+++ b/tests/src/com/android/server/telecom/tests/RingerTest.java
@@ -16,6 +16,24 @@
package com.android.server.telecom.tests;
+import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.ArgumentMatchers.nullable;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
import android.app.NotificationManager;
import android.content.Context;
import android.media.AudioAttributes;
@@ -48,21 +66,6 @@
import org.mockito.Mock;
import org.mockito.Spy;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.ArgumentMatchers.isNull;
-import static org.mockito.ArgumentMatchers.nullable;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
@@ -116,6 +119,7 @@
@Mock RingtoneFactory mockRingtoneFactory;
@Mock Vibrator mockVibrator;
@Mock InCallController mockInCallController;
+ @Mock NotificationManager mockNotificationManager;
@Spy Ringer.VibrationEffectProxy spyVibrationEffectProxy;
@Mock InCallTonePlayer mockTonePlayer;
@@ -141,10 +145,10 @@
(AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
when(mockAudioManager.getRingerMode()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
when(mockSystemSettingsUtil.isHapticPlaybackSupported(any(Context.class))).thenReturn(true);
- NotificationManager notificationManager =
+ mockNotificationManager =
(NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
when(mockTonePlayer.startTone()).thenReturn(true);
- when(notificationManager.matchesCallFilter(any(Bundle.class))).thenReturn(true);
+ when(mockNotificationManager.matchesCallFilter(any(Bundle.class))).thenReturn(true);
when(mockRingtoneFactory.hasHapticChannels(any(Ringtone.class))).thenReturn(false);
when(mockRingtonePlayer.play(any(RingtoneFactory.class), any(Call.class),
nullable(VolumeShaper.Configuration.class), anyBoolean(), anyBoolean()))
@@ -249,9 +253,7 @@
@Test
public void testCallWaitingButNoRingForSpecificContacts() {
mFuture.complete(false); // not using audio coupled haptics
- NotificationManager notificationManager =
- (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
- when(notificationManager.matchesCallFilter(any(Bundle.class))).thenReturn(false);
+ when(mockNotificationManager.matchesCallFilter(any(Bundle.class))).thenReturn(false);
// Start call waiting to make sure that it does stop when we start ringing
mRingerUnderTest.startCallWaiting(mockCall1);
verify(mockTonePlayer).startTone();
@@ -461,6 +463,7 @@
mRingerUnderTest.startCallWaiting(mockCall1);
Ringtone mockRingtone = mock(Ringtone.class);
when(mockRingtoneFactory.getRingtone(any(Call.class))).thenReturn(mockRingtone);
+ when(mockNotificationManager.getZenMode()).thenReturn(ZEN_MODE_IMPORTANT_INTERRUPTIONS);
when(mockAudioManager.getRingerMode()).thenReturn(AudioManager.RINGER_MODE_SILENT);
when(mockAudioManager.getStreamVolume(AudioManager.STREAM_RING)).thenReturn(100);
mFuture.complete(true); // using audio coupled haptics