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

Commit 6a5995e1 authored by Hall Liu's avatar Hall Liu
Browse files

Don't acquire audio focus if ringtone will not play

When the system volume is at some level that prevents an audible
ringtone from playing, don't grab audio focus so as to not interrupt
music that is playing.

Fix: 31319655

Change-Id: Ia2e4bc4b2ca8fe88e893cfd307d33e94de2b33ba
parent e32d0275
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -422,8 +422,8 @@ public class CallAudioManager extends CallsManagerListenerBase {
    }

    @VisibleForTesting
    public void startRinging() {
        mRinger.startRinging(mForegroundCall);
    public boolean startRinging() {
        return mRinger.startRinging(mForegroundCall);
    }

    @VisibleForTesting
+13 −10
Original line number Diff line number Diff line
@@ -201,6 +201,7 @@ public class CallAudioModeStateMachine extends StateMachine {
        @Override
        public void enter() {
            Log.i(LOG_TAG, "Audio focus entering RINGING state");
            if (mCallAudioManager.startRinging()) {
                mAudioManager.requestAudioFocusForCall(AudioManager.STREAM_RING,
                        AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
                if (mMostRecentMode == AudioManager.MODE_IN_CALL) {
@@ -210,10 +211,12 @@ public class CallAudioModeStateMachine extends StateMachine {
                    mAudioManager.setMode(AudioManager.MODE_NORMAL);
                }
                mAudioManager.setMode(AudioManager.MODE_RINGTONE);
                mCallAudioManager.setCallAudioRouteFocusState(CallAudioRouteStateMachine.RINGING_FOCUS);
            } else {
                Log.i(LOG_TAG, "Entering RINGING but not acquiring focus -- silent ringtone");
            }

            mCallAudioManager.stopCallWaiting();
            mCallAudioManager.startRinging();
            mCallAudioManager.setCallAudioRouteFocusState(CallAudioRouteStateMachine.RINGING_FOCUS);
        }

        @Override
+13 −9
Original line number Diff line number Diff line
@@ -94,30 +94,32 @@ public class Ringer {
        mInCallController = inCallController;
    }

    public void startRinging(Call foregroundCall) {
    public boolean startRinging(Call foregroundCall) {
        AudioManager audioManager =
                (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
        boolean isRingerAudible = audioManager.getStreamVolume(AudioManager.STREAM_RING) > 0;

        if (mSystemSettingsUtil.isTheaterModeOn(mContext)) {
            return;
            return false;
        }

        if (foregroundCall == null) {
            Log.wtf(this, "startRinging called with null foreground call.");
            return;
            return false;
        }

        if (mInCallController.doesConnectedDialerSupportRinging()) {
            Log.event(foregroundCall, Log.Events.SKIP_RINGING);
            return;
            return isRingerAudible;
        }

        stopCallWaiting();

        if (!shouldRingForContact(foregroundCall.getContactUri())) {
            return;
            return false;
        }

        AudioManager audioManager =
                (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
        if (audioManager.getStreamVolume(AudioManager.STREAM_RING) > 0) {
        if (isRingerAudible) {
            mRingingCall = foregroundCall;
            Log.event(foregroundCall, Log.Events.START_RINGER);
            // Because we wait until a contact info query to complete before processing a
@@ -126,7 +128,7 @@ public class Ringer {
            // request the custom ringtone from the call and expect it to be current.
            mRingtonePlayer.play(mRingtoneFactory, foregroundCall);
        } else {
            Log.v(this, "startRingingOrCallWaiting, skipping because volume is 0");
            Log.i(this, "startRingingOrCallWaiting, skipping because volume is 0");
        }

        if (shouldVibrate(mContext) && !mIsVibrating) {
@@ -134,6 +136,8 @@ public class Ringer {
                    VIBRATION_ATTRIBUTES);
            mIsVibrating = true;
        }

        return isRingerAudible;
    }

    public void startCallWaiting(Call call) {
+34 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.server.telecom.tests;

import android.media.AudioManager;
import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.SmallTest;

import com.android.server.telecom.CallAudioManager;
import com.android.server.telecom.CallAudioModeStateMachine;
@@ -32,6 +33,7 @@ import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

public class CallAudioModeStateMachineTest extends StateMachineTestBase<CallAudioModeStateMachine> {
    private static class ModeTestParameters extends TestParameters {
@@ -100,6 +102,37 @@ public class CallAudioModeStateMachineTest extends StateMachineTestBase<CallAudi
        parametrizedTestStateMachine(testCases);
    }

    @SmallTest
    public void testNoFocusWhenRingerSilenced() throws Throwable {
        CallAudioModeStateMachine sm = new CallAudioModeStateMachine(mAudioManager);
        sm.setCallAudioManager(mCallAudioManager);
        sm.sendMessage(CallAudioModeStateMachine.ABANDON_FOCUS_FOR_TESTING);
        waitForStateMachineActionCompletion(sm, CallAudioModeStateMachine.RUN_RUNNABLE);

        resetMocks();
        when(mCallAudioManager.startRinging()).thenReturn(false);

        sm.sendMessage(CallAudioModeStateMachine.NEW_RINGING_CALL,
                new CallAudioModeStateMachine.MessageArgs(
                        false, // hasActiveOrDialingCalls
                        true, // hasRingingCalls
                        false, // hasHoldingCalls
                        false, // isTonePlaying
                        false, // foregroundCallIsVoip
                        null // session
                ));
        waitForStateMachineActionCompletion(sm, CallAudioModeStateMachine.RUN_RUNNABLE);

        assertEquals(CallAudioModeStateMachine.RING_STATE_NAME, sm.getCurrentStateName());

        verify(mAudioManager, never()).requestAudioFocusForCall(anyInt(), anyInt());
        verify(mAudioManager, never()).setMode(anyInt());

        verify(mCallAudioManager, never()).stopRinging();

        verify(mCallAudioManager).stopCallWaiting();
    }

    private List<ModeTestParameters> generateTestCases() {
        List<ModeTestParameters> result = new ArrayList<>();
        result.add(new ModeTestParameters(
@@ -516,6 +549,7 @@ public class CallAudioModeStateMachineTest extends StateMachineTestBase<CallAudi
        waitForStateMachineActionCompletion(sm, CallAudioModeStateMachine.RUN_RUNNABLE);

        resetMocks();
        when(mCallAudioManager.startRinging()).thenReturn(true);

        sm.sendMessage(params.messageType, params.externalState);
        waitForStateMachineActionCompletion(sm, CallAudioModeStateMachine.RUN_RUNNABLE);