Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2b4afe18 authored by Thomas Stuart's avatar Thomas Stuart Committed by Android (Google) Code Review
Browse files

Merge "add anom report and more logs to Ringer haptics" into main

parents b5d6a65e 422b0d24
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -16,3 +16,15 @@ flag {
  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
+1 −1
Original line number Diff line number Diff line
@@ -703,7 +703,7 @@ public class CallsManager extends Call.ListenerBase
                ringtoneFactory, systemVibrator,
                new Ringer.VibrationEffectProxy(), mInCallController,
                mContext.getSystemService(NotificationManager.class),
                accessibilityManagerAdapter, featureFlags);
                accessibilityManagerAdapter, featureFlags, mAnomalyReporter);
        if (featureFlags.telecomResolveHiddenDependencies()) {
            // This is now deprecated
            mCallRecordingTonePlayer = null;
+45 −5
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ import java.io.InputStream;
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 @@ public class Ringer {

    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 @@ public class Ringer {
    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 @@ public class Ringer {
            InCallController inCallController,
            NotificationManager notificationManager,
            AccessibilityManagerAdapter accessibilityManagerAdapter,
            FeatureFlags featureFlags) {
            FeatureFlags featureFlags,
            AnomalyReporterAdapter anomalyReporter) {

        mLock = new Object();
        mSystemSettingsUtil = systemSettingsUtil;
@@ -252,6 +261,7 @@ public class Ringer {
        mVibrationEffectProxy = vibrationEffectProxy;
        mNotificationManager = notificationManager;
        mAccessibilityManagerAdapter = accessibilityManagerAdapter;
        mAnomalyReporter = anomalyReporter;

        mDefaultVibrationEffect =
                loadDefaultRingVibrationEffect(
@@ -405,10 +415,9 @@ public class Ringer {
                    // 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);
                    }
                } 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 @@ public class Ringer {
                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 @@ public class Ringer {
        // 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();
+3 −1
Original line number Diff line number Diff line
@@ -66,6 +66,7 @@ import android.util.Pair;

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 @@ public class RingerTest extends TelecomTestCase {
    @Mock NotificationManager mockNotificationManager;
    @Mock Ringer.AccessibilityManagerAdapter mockAccessibilityManagerAdapter;
    @Mock private FeatureFlags mFeatureFlags;
    @Mock private AnomalyReporterAdapter mAnomalyReporterAdapter;

    @Spy Ringer.VibrationEffectProxy spyVibrationEffectProxy;

@@ -178,7 +180,7 @@ public class RingerTest extends TelecomTestCase {
        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);
    }