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

Commit a19b0964 authored by Grace Jia's avatar Grace Jia
Browse files

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
parent fd4d7c2d
Loading
Loading
Loading
Loading
+6 −5
Original line number Original line Diff line number Diff line
@@ -275,7 +275,7 @@ public class Ringer {
        VibrationEffect effect;
        VibrationEffect effect;
        CompletableFuture<Boolean> hapticsFuture = null;
        CompletableFuture<Boolean> hapticsFuture = null;
        // Determine if the settings and DND mode indicate that the vibrator can be used right now.
        // 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 =
        boolean shouldApplyRampingRinger =
                isVibratorEnabled && mSystemSettingsUtil.isRampingRingerEnabled(mContext);
                isVibratorEnabled && mSystemSettingsUtil.isRampingRingerEnabled(mContext);
        if (attributes.isRingerAudible()) {
        if (attributes.isRingerAudible()) {
@@ -367,7 +367,7 @@ public class Ringer {
                        "hasVibrator=%b, userRequestsVibrate=%b, ringerMode=%d, isVibrating=%b",
                        "hasVibrator=%b, userRequestsVibrate=%b, ringerMode=%d, isVibrating=%b",
                        mVibrator.hasVibrator(),
                        mVibrator.hasVibrator(),
                        mSystemSettingsUtil.isRingVibrationEnabled(mContext),
                        mSystemSettingsUtil.isRingVibrationEnabled(mContext),
                        mAudioManager.getRingerModeInternal(), mIsVibrating);
                        mAudioManager.getRingerMode(), mIsVibrating);
                if (mSystemSettingsUtil.isRampingRingerEnabled(mContext) && isRingerAudible) {
                if (mSystemSettingsUtil.isRampingRingerEnabled(mContext) && isRingerAudible) {
                    Log.i(this, "start vibration for ramping ringer.");
                    Log.i(this, "start vibration for ramping ringer.");
                } else {
                } else {
@@ -381,7 +381,7 @@ public class Ringer {
                        "hasVibrator=%b, userRequestsVibrate=%b, ringerMode=%d, isVibrating=%b",
                        "hasVibrator=%b, userRequestsVibrate=%b, ringerMode=%d, isVibrating=%b",
                        mVibrator.hasVibrator(),
                        mVibrator.hasVibrator(),
                        mSystemSettingsUtil.isRingVibrationEnabled(mContext),
                        mSystemSettingsUtil.isRingVibrationEnabled(mContext),
                        mAudioManager.getRingerModeInternal(), mIsVibrating);
                        mAudioManager.getRingerMode(), mIsVibrating);
            }
            }
        }
        }
    }
    }
@@ -503,13 +503,14 @@ public class Ringer {
        }
        }
    }
    }


    private boolean isVibratorEnabled(Context context) {
    private boolean isVibratorEnabled(Context context, boolean shouldRingForContact) {
        AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
        AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
        // Use AudioManager#getRingerMode for more accurate result, instead of
        // Use AudioManager#getRingerMode for more accurate result, instead of
        // AudioManager#getRingerModeInternal which only useful for volume controllers
        // AudioManager#getRingerModeInternal which only useful for volume controllers
        return mVibrator.hasVibrator()
        return mVibrator.hasVibrator()
                && mSystemSettingsUtil.isRingVibrationEnabled(context)
                && mSystemSettingsUtil.isRingVibrationEnabled(context)
                && audioManager.getRingerMode() != AudioManager.RINGER_MODE_SILENT;
                && (audioManager.getRingerMode() != AudioManager.RINGER_MODE_SILENT
                || shouldRingForContact);
    }
    }


    private RingerAttributes getRingerAttributes(Call call, boolean isHfpDeviceAttached) {
    private RingerAttributes getRingerAttributes(Call call, boolean isHfpDeviceAttached) {
+17 −0
Original line number Original line Diff line number Diff line
@@ -455,6 +455,23 @@ public class RingerTest extends TelecomTestCase {
                .vibrate(any(VibrationEffect.class), any(VibrationAttributes.class));
                .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() {
    private void ensureRingerIsAudible() {
        Ringtone mockRingtone = mock(Ringtone.class);
        Ringtone mockRingtone = mock(Ringtone.class);
        when(mockRingtoneFactory.getRingtone(any(Call.class))).thenReturn(mockRingtone);
        when(mockRingtoneFactory.getRingtone(any(Call.class))).thenReturn(mockRingtone);