Merge "Rename the flag of keep_bt_devices_cache_updated" into main
diff --git a/flags/telecom_ringer_flag_declarations.aconfig b/flags/telecom_ringer_flag_declarations.aconfig
index 6517e0f..f954b09 100644
--- a/flags/telecom_ringer_flag_declarations.aconfig
+++ b/flags/telecom_ringer_flag_declarations.aconfig
@@ -15,4 +15,16 @@
namespace: "telecom"
description: "Gates whether to ensure that when a user is in their car, they are able to hear ringing for an incoming call."
bug: "348708398"
+}
+
+
+# OWNER=tjstuart TARGET=25Q1
+flag {
+ name: "get_ringer_mode_anom_report"
+ namespace: "telecom"
+ description: "getRingerMode & getRingerModeInternal should return the same val when dnd is off"
+ bug: "307389562"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
}
\ No newline at end of file
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index 9670d6a..22b28b5 100644
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -703,7 +703,7 @@
ringtoneFactory, systemVibrator,
new Ringer.VibrationEffectProxy(), mInCallController,
mContext.getSystemService(NotificationManager.class),
- accessibilityManagerAdapter, featureFlags);
+ accessibilityManagerAdapter, featureFlags, mAnomalyReporter);
if (featureFlags.telecomResolveHiddenDependencies()) {
// This is now deprecated
mCallRecordingTonePlayer = null;
diff --git a/src/com/android/server/telecom/Ringer.java b/src/com/android/server/telecom/Ringer.java
index 12778b0..bfaadf0 100644
--- a/src/com/android/server/telecom/Ringer.java
+++ b/src/com/android/server/telecom/Ringer.java
@@ -59,6 +59,7 @@
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
+import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
@@ -176,6 +177,11 @@
private static VolumeShaper.Configuration mVolumeShaperConfig;
+ public static final UUID GET_RINGER_MODE_ANOMALY_UUID =
+ UUID.fromString("eb10505b-4d7b-4fab-b4a1-a18186799065");
+ public static final String GET_RINGER_MODE_ANOMALY_MSG = "AM#GetRingerMode() and"
+ + " AM#GetRingerModeInternal() are returning diff values when DoNotDisturb is OFF!";
+
/**
* Used to keep ordering of unanswered incoming calls. There can easily exist multiple incoming
* calls and explicit ordering is useful for maintaining the proper state of the ringer.
@@ -191,6 +197,8 @@
private final boolean mIsHapticPlaybackSupportedByDevice;
private final FeatureFlags mFlags;
private final boolean mRingtoneVibrationSupported;
+ private final AnomalyReporterAdapter mAnomalyReporter;
+
/**
* For unit testing purposes only; when set, {@link #startRinging(Call, boolean)} will complete
* the future provided by the test using {@link #setBlockOnRingingFuture(CompletableFuture)}.
@@ -237,7 +245,8 @@
InCallController inCallController,
NotificationManager notificationManager,
AccessibilityManagerAdapter accessibilityManagerAdapter,
- FeatureFlags featureFlags) {
+ FeatureFlags featureFlags,
+ AnomalyReporterAdapter anomalyReporter) {
mLock = new Object();
mSystemSettingsUtil = systemSettingsUtil;
@@ -252,6 +261,7 @@
mVibrationEffectProxy = vibrationEffectProxy;
mNotificationManager = notificationManager;
mAccessibilityManagerAdapter = accessibilityManagerAdapter;
+ mAnomalyReporter = anomalyReporter;
mDefaultVibrationEffect =
loadDefaultRingVibrationEffect(
@@ -405,10 +415,9 @@
// If ringer is not audible for this call, then the phone is in "Vibrate" mode.
// Use haptic-only ringtone or do not play anything.
isHapticOnly = true;
- if (DEBUG_RINGER) {
- Log.i(this, "Set ringtone as haptic only: " + isHapticOnly);
- }
+ Log.i(this, "Set ringtone as haptic only: " + isHapticOnly);
} else {
+ Log.i(this, "ringer & haptics are off, user missed alerts for call");
foregroundCall.setUserMissed(USER_MISSED_NO_VIBRATE);
Log.addEvent(foregroundCall, LogUtils.Events.SKIP_VIBRATION,
vibratorAttrs);
@@ -437,7 +446,7 @@
ringtoneInfoSupplier = () -> mRingtoneFactory.getRingtone(
foregroundCall, null, false);
}
-
+ Log.i(this, "isRingtoneInfoSupplierNull=[%b]", ringtoneInfoSupplier == null);
// If vibration will be done, reserve the vibrator.
boolean vibratorReserved = isVibratorEnabled && attributes.shouldRingForContact()
&& tryReserveVibration(foregroundCall);
@@ -706,12 +715,43 @@
// AudioManager#getRingerModeInternal which only useful for volume controllers
boolean zenModeOn = mNotificationManager != null
&& mNotificationManager.getZenMode() != ZEN_MODE_OFF;
+ maybeGenAnomReportForGetRingerMode(zenModeOn, audioManager);
return mVibrator.hasVibrator()
&& mSystemSettingsUtil.isRingVibrationEnabled(context)
&& (audioManager.getRingerMode() != AudioManager.RINGER_MODE_SILENT
|| (zenModeOn && shouldRingForContact));
}
+ /**
+ * There are 3 settings for haptics:
+ * - AudioManager.RINGER_MODE_SILENT
+ * - AudioManager.RINGER_MODE_VIBRATE
+ * - AudioManager.RINGER_MODE_NORMAL
+ * If the user does not have {@link AudioManager#RINGER_MODE_SILENT} set, the user should
+ * have haptic feeback
+ *
+ * Note: If DND/ZEN_MODE is on, {@link AudioManager#getRingerMode()} will return
+ * {@link AudioManager#RINGER_MODE_SILENT}, regardless of the user setting. Therefore,
+ * getRingerModeInternal is the source of truth instead of {@link AudioManager#getRingerMode()}.
+ * However, if DND/ZEN_MOD is off, the APIs should return the same value. Generate an anomaly
+ * report if they diverge.
+ */
+ private void maybeGenAnomReportForGetRingerMode(boolean isZenModeOn, AudioManager am) {
+ if (!mFlags.getRingerModeAnomReport()) {
+ return;
+ }
+ if (!isZenModeOn) {
+ int ringerMode = am.getRingerMode();
+ int ringerModeInternal = am.getRingerModeInternal();
+ if (ringerMode != ringerModeInternal) {
+ Log.i(this, "getRingerMode=[%d], getRingerModeInternal=[%d]",
+ ringerMode, ringerModeInternal);
+ mAnomalyReporter.reportAnomaly(GET_RINGER_MODE_ANOMALY_UUID,
+ GET_RINGER_MODE_ANOMALY_MSG);
+ }
+ }
+ }
+
private RingerAttributes getRingerAttributes(Call call, boolean isHfpDeviceAttached) {
mAudioManager = mContext.getSystemService(AudioManager.class);
RingerAttributes.Builder builder = new RingerAttributes.Builder();
diff --git a/tests/src/com/android/server/telecom/tests/RingerTest.java b/tests/src/com/android/server/telecom/tests/RingerTest.java
index c4d9678..46916fd 100644
--- a/tests/src/com/android/server/telecom/tests/RingerTest.java
+++ b/tests/src/com/android/server/telecom/tests/RingerTest.java
@@ -66,6 +66,7 @@
import androidx.test.filters.SmallTest;
+import com.android.server.telecom.AnomalyReporterAdapter;
import com.android.server.telecom.AsyncRingtonePlayer;
import com.android.server.telecom.Call;
import com.android.server.telecom.CallState;
@@ -123,6 +124,7 @@
@Mock NotificationManager mockNotificationManager;
@Mock Ringer.AccessibilityManagerAdapter mockAccessibilityManagerAdapter;
@Mock private FeatureFlags mFeatureFlags;
+ @Mock private AnomalyReporterAdapter mAnomalyReporterAdapter;
@Spy Ringer.VibrationEffectProxy spyVibrationEffectProxy;
@@ -178,7 +180,7 @@
mRingerUnderTest = new Ringer(mockPlayerFactory, mContext, mockSystemSettingsUtil,
asyncRingtonePlayer, mockRingtoneFactory, mockVibrator, spyVibrationEffectProxy,
mockInCallController, mockNotificationManager, mockAccessibilityManagerAdapter,
- mFeatureFlags);
+ mFeatureFlags, mAnomalyReporterAdapter);
// This future is used to wait for AsyncRingtonePlayer to finish its part.
mRingerUnderTest.setBlockOnRingingFuture(mRingCompletionFuture);
}