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

Commit 6b75393d authored by Jack He's avatar Jack He Committed by android-build-merger
Browse files

Bluetooth: Enable in-band ringing in vibration mode (4/4)

am: f9bb06ab

Change-Id: I0fe1068c42049059123640eab07235983d365f3a
parents 46d9ab33 f9bb06ab
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -93,6 +93,7 @@ public class CallAudioManager extends CallsManagerListenerBase {

        mPlayerFactory.setCallAudioManager(this);
        mCallAudioModeStateMachine.setCallAudioManager(this);
        mCallAudioRouteStateMachine.setCallAudioManager(this);
    }

    @Override
@@ -385,6 +386,11 @@ public class CallAudioManager extends CallsManagerListenerBase {
                CallAudioRouteStateMachine.TOGGLE_MUTE);
    }

    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
    public void onRingerModeChange() {
        mCallAudioModeStateMachine.sendMessage(CallAudioModeStateMachine.RINGER_MODE_CHANGE);
    }

    @VisibleForTesting
    public void mute(boolean shouldMute) {
        Log.v(this, "mute, shouldMute: %b", shouldMute);
+17 −5
Original line number Diff line number Diff line
@@ -93,6 +93,8 @@ public class CallAudioModeStateMachine extends StateMachine {

    public static final int FOREGROUND_VOIP_MODE_CHANGE = 4001;

    public static final int RINGER_MODE_CHANGE = 5001;

    public static final int RUN_RUNNABLE = 9001;

    private static final SparseArray<String> MESSAGE_CODE_TO_NAME = new SparseArray<String>() {{
@@ -111,6 +113,7 @@ public class CallAudioModeStateMachine extends StateMachine {
        put(TONE_STARTED_PLAYING, "TONE_STARTED_PLAYING");
        put(TONE_STOPPED_PLAYING, "TONE_STOPPED_PLAYING");
        put(FOREGROUND_VOIP_MODE_CHANGE, "FOREGROUND_VOIP_MODE_CHANGE");
        put(RINGER_MODE_CHANGE, "RINGER_MODE_CHANGE");

        put(RUN_RUNNABLE, "RUN_RUNNABLE");
    }};
@@ -208,18 +211,22 @@ public class CallAudioModeStateMachine extends StateMachine {
    }

    private class RingingFocusState extends BaseState {
        @Override
        public void enter() {
            Log.i(LOG_TAG, "Audio focus entering RINGING state");
        private void tryStartRinging() {
            if (mCallAudioManager.startRinging()) {
                mAudioManager.requestAudioFocusForCall(AudioManager.STREAM_RING,
                        AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
                mAudioManager.setMode(AudioManager.MODE_RINGTONE);
                mCallAudioManager.setCallAudioRouteFocusState(CallAudioRouteStateMachine.RINGING_FOCUS);
                mCallAudioManager.setCallAudioRouteFocusState(
                        CallAudioRouteStateMachine.RINGING_FOCUS);
            } else {
                Log.i(LOG_TAG, "Entering RINGING but not acquiring focus -- silent ringtone");
                Log.i(LOG_TAG, "RINGING state, try start ringing but not acquiring audio focus");
            }
        }

        @Override
        public void enter() {
            Log.i(LOG_TAG, "Audio focus entering RINGING state");
            tryStartRinging();
            mCallAudioManager.stopCallWaiting();
        }

@@ -281,6 +288,11 @@ public class CallAudioModeStateMachine extends StateMachine {
                    transitionTo(args.foregroundCallIsVoip
                            ? mVoipCallFocusState : mSimCallFocusState);
                    return HANDLED;
                case RINGER_MODE_CHANGE: {
                    Log.i(LOG_TAG, "RINGING state, received RINGER_MODE_CHANGE");
                    tryStartRinging();
                    return HANDLED;
                }
                default:
                    // The forced focus switch commands are handled by BaseState.
                    return NOT_HANDLED;
+13 −0
Original line number Diff line number Diff line
@@ -747,6 +747,10 @@ public class CallAudioRouteStateMachine extends StateMachine {
                    mBluetoothRouteManager.getConnectedDevices());
            setSystemAudioState(newState, true);
            updateInternalCallAudioState();
            // Do not send RINGER_MODE_CHANGE if no Bluetooth SCO audio device is available
            if (mBluetoothRouteManager.getBluetoothAudioConnectedDevice() != null) {
                mCallAudioManager.onRingerModeChange();
            }
        }

        @Override
@@ -772,6 +776,9 @@ public class CallAudioRouteStateMachine extends StateMachine {
                    }
                    return HANDLED;
                case BT_AUDIO_CONNECTED:
                    // Send ringer mode change because we transit to ActiveBluetoothState even
                    // when HFP is connecting
                    mCallAudioManager.onRingerModeChange();
                    // Update the in-call app on the new active BT device in case that changed.
                    updateSystemAudioState();
                    return HANDLED;
@@ -1284,6 +1291,8 @@ public class CallAudioRouteStateMachine extends StateMachine {
    private CallAudioState mCurrentCallAudioState;
    private CallAudioState mLastKnownCallAudioState;

    private CallAudioManager mCallAudioManager;

    public CallAudioRouteStateMachine(
            Context context,
            CallsManager callsManager,
@@ -1340,6 +1349,10 @@ public class CallAudioRouteStateMachine extends StateMachine {
        mRouteCodeToQuiescentState.put(ROUTE_WIRED_HEADSET, mQuiescentHeadsetRoute);
    }

    public void setCallAudioManager(CallAudioManager callAudioManager) {
        mCallAudioManager = callAudioManager;
    }

    /**
     * Initializes the state machine with info on initial audio route, supported audio routes,
     * and mute status.
+46 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.test.suitebuilder.annotation.SmallTest;

import com.android.server.telecom.CallAudioManager;
import com.android.server.telecom.CallAudioModeStateMachine;
import com.android.server.telecom.CallAudioRouteStateMachine;

import org.junit.Before;
import org.junit.Test;
@@ -80,6 +81,51 @@ public class CallAudioModeStateMachineTest extends TelecomTestCase {
        verify(mCallAudioManager).stopCallWaiting();
    }

    @SmallTest
    @Test
    public void testRegainFocusWhenHfpIsConnectedSilenced() throws Throwable {
        CallAudioModeStateMachine sm = new CallAudioModeStateMachine(mAudioManager);
        sm.setCallAudioManager(mCallAudioManager);
        sm.sendMessage(CallAudioModeStateMachine.ABANDON_FOCUS_FOR_TESTING);
        waitForHandlerAction(sm.getHandler(), TEST_TIMEOUT);

        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
                ));
        waitForHandlerAction(sm.getHandler(), TEST_TIMEOUT);

        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();

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

        sm.sendMessage(CallAudioModeStateMachine.RINGER_MODE_CHANGE);
        waitForHandlerAction(sm.getHandler(), TEST_TIMEOUT);

        verify(mCallAudioManager).startRinging();
        verify(mAudioManager).requestAudioFocusForCall(AudioManager.STREAM_RING,
                AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
        verify(mAudioManager).setMode(AudioManager.MODE_RINGTONE);
        verify(mCallAudioManager).setCallAudioRouteFocusState(
                CallAudioRouteStateMachine.RINGING_FOCUS);
    }


    private void resetMocks() {
        reset(mCallAudioManager, mAudioManager);
    }
+12 −0
Original line number Diff line number Diff line
@@ -82,6 +82,7 @@ public class CallAudioRouteStateMachineTest extends TelecomSystemTest {
    @Mock WiredHeadsetManager mockWiredHeadsetManager;
    @Mock StatusBarNotifier mockStatusBarNotifier;
    @Mock Call fakeCall;
    @Mock CallAudioManager mockCallAudioManager;

    private CallAudioManager.AudioServiceFactory mAudioServiceFactory;
    private static final int TEST_TIMEOUT = 500;
@@ -187,6 +188,7 @@ public class CallAudioRouteStateMachineTest extends TelecomSystemTest {
                mockStatusBarNotifier,
                mAudioServiceFactory,
                CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED);
        stateMachine.setCallAudioManager(mockCallAudioManager);

        when(mockBluetoothRouteManager.isBluetoothAudioConnectedOrPending()).thenReturn(false);
        when(mockBluetoothRouteManager.isBluetoothAvailable()).thenReturn(true);
@@ -229,6 +231,7 @@ public class CallAudioRouteStateMachineTest extends TelecomSystemTest {
                mockStatusBarNotifier,
                mAudioServiceFactory,
                CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED);
        stateMachine.setCallAudioManager(mockCallAudioManager);
        Collection<BluetoothDevice> availableDevices = Collections.singleton(bluetoothDevice1);

        when(mockBluetoothRouteManager.isBluetoothAudioConnectedOrPending()).thenReturn(false);
@@ -301,6 +304,7 @@ public class CallAudioRouteStateMachineTest extends TelecomSystemTest {
                mockStatusBarNotifier,
                mAudioServiceFactory,
                CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED);
        stateMachine.setCallAudioManager(mockCallAudioManager);

        when(mockBluetoothRouteManager.isBluetoothAudioConnectedOrPending()).thenReturn(false);
        when(mockBluetoothRouteManager.isBluetoothAvailable()).thenReturn(true);
@@ -335,6 +339,7 @@ public class CallAudioRouteStateMachineTest extends TelecomSystemTest {
                mockStatusBarNotifier,
                mAudioServiceFactory,
                CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED);
        stateMachine.setCallAudioManager(mockCallAudioManager);
        setInBandRing(false);
        when(mockBluetoothRouteManager.isBluetoothAudioConnectedOrPending()).thenReturn(false);
        when(mockBluetoothRouteManager.isBluetoothAvailable()).thenReturn(false);
@@ -369,6 +374,12 @@ public class CallAudioRouteStateMachineTest extends TelecomSystemTest {
                CallAudioRouteStateMachine.ACTIVE_FOCUS);
        waitForHandlerAction(stateMachine.getHandler(), TEST_TIMEOUT);
        verify(mockBluetoothRouteManager, times(1)).connectBluetoothAudio(null);

        when(mockBluetoothRouteManager.getBluetoothAudioConnectedDevice())
                .thenReturn(bluetoothDevice1);
        stateMachine.sendMessage(CallAudioRouteStateMachine.BT_AUDIO_CONNECTED);
        waitForHandlerAction(stateMachine.getHandler(), TEST_TIMEOUT);
        verify(mockCallAudioManager, times(1)).onRingerModeChange();
    }

    @SmallTest
@@ -382,6 +393,7 @@ public class CallAudioRouteStateMachineTest extends TelecomSystemTest {
                mockStatusBarNotifier,
                mAudioServiceFactory,
                CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED);
        stateMachine.setCallAudioManager(mockCallAudioManager);
        List<BluetoothDevice> availableDevices =
                Arrays.asList(bluetoothDevice1, bluetoothDevice2, bluetoothDevice3);

Loading