Loading src/com/android/server/telecom/CallAudioRouteStateMachine.java +8 −14 Original line number Diff line number Diff line Loading @@ -265,7 +265,6 @@ public class CallAudioRouteStateMachine extends StateMachine { } else { removedRoutes |= ROUTE_BLUETOOTH; } // TODO: update in-call app on the list of BT devices. isHandled = HANDLED; break; case SWITCH_BASELINE_ROUTE: Loading @@ -276,6 +275,10 @@ public class CallAudioRouteStateMachine extends StateMachine { sendInternalMessage(calculateBaselineRouteMessage(true, msg.arg1 == INCLUDE_BLUETOOTH_IN_BASELINE)); return HANDLED; case USER_SWITCH_BLUETOOTH: // If the user tries to switch to BT, reset the explicitly-switched-away flag. mHasUserExplicitlyLeftBluetooth = false; return NOT_HANDLED; case SWITCH_FOCUS: mAudioFocusType = msg.arg1; return NOT_HANDLED; Loading @@ -283,10 +286,12 @@ public class CallAudioRouteStateMachine extends StateMachine { return NOT_HANDLED; } if (addedRoutes != 0 || removedRoutes != 0) { if (addedRoutes != 0 || removedRoutes != 0 || msg.what == BLUETOOTH_DEVICE_LIST_CHANGED) { mAvailableRoutes = modifyRoutes(mAvailableRoutes, removedRoutes, addedRoutes, true); mDeviceSupportedRoutes = modifyRoutes(mDeviceSupportedRoutes, removedRoutes, addedRoutes, false); updateSystemAudioState(); } return isHandled; Loading Loading @@ -467,18 +472,15 @@ public class CallAudioRouteStateMachine extends StateMachine { } else { Log.i(this, "Not switching to BT route from earpiece because user has " + "explicitly disconnected."); updateSystemAudioState(); } return HANDLED; case DISCONNECT_BLUETOOTH: updateSystemAudioState(); // No change in audio route required return HANDLED; case DISCONNECT_WIRED_HEADSET: Log.e(this, new IllegalStateException(), "Wired headset should not go from connected to not when on " + "earpiece"); updateSystemAudioState(); return HANDLED; case BT_AUDIO_DISCONNECTED: // This may be sent as a confirmation by the BT stack after switch off BT. Loading Loading @@ -657,8 +659,6 @@ public class CallAudioRouteStateMachine extends StateMachine { case CONNECT_WIRED_HEADSET: Log.e(this, new IllegalStateException(), "Wired headset should already be connected."); mAvailableRoutes |= ROUTE_WIRED_HEADSET; updateSystemAudioState(); return HANDLED; case CONNECT_BLUETOOTH: if (!mHasUserExplicitlyLeftBluetooth) { Loading @@ -666,11 +666,9 @@ public class CallAudioRouteStateMachine extends StateMachine { } else { Log.i(this, "Not switching to BT route from headset because user has " + "explicitly disconnected."); updateSystemAudioState(); } return HANDLED; case DISCONNECT_BLUETOOTH: updateSystemAudioState(); // No change in audio route required return HANDLED; case DISCONNECT_WIRED_HEADSET: Loading Loading @@ -975,7 +973,6 @@ public class CallAudioRouteStateMachine extends StateMachine { mWasOnSpeaker = false; return HANDLED; case DISCONNECT_WIRED_HEADSET: updateSystemAudioState(); // No change in audio route required return HANDLED; case CONNECT_DOCK: Loading Loading @@ -1009,7 +1006,7 @@ public class CallAudioRouteStateMachine extends StateMachine { setBluetoothOff(); CallAudioState newState = new CallAudioState(mIsMuted, ROUTE_SPEAKER, mAvailableRoutes, null, mBluetoothRouteManager.getConnectedDevices()); setSystemAudioState(newState); setSystemAudioState(newState, true); updateInternalCallAudioState(); } Loading Loading @@ -1175,15 +1172,12 @@ public class CallAudioRouteStateMachine extends StateMachine { } else { Log.i(this, "Not switching to BT route from speaker because user has " + "explicitly disconnected."); updateSystemAudioState(); } return HANDLED; case DISCONNECT_BLUETOOTH: updateSystemAudioState(); // No change in audio route required return HANDLED; case DISCONNECT_WIRED_HEADSET: updateSystemAudioState(); // No change in audio route required return HANDLED; case BT_AUDIO_DISCONNECTED: Loading tests/src/com/android/server/telecom/tests/CallAudioRouteStateMachineTest.java +97 −9 Original line number Diff line number Diff line Loading @@ -45,9 +45,11 @@ import org.mockito.stubbing.Answer; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.ArgumentMatchers.nullable; import static org.mockito.Matchers.any; import static org.mockito.Matchers.same; Loading Loading @@ -229,10 +231,11 @@ public class CallAudioRouteStateMachineTest waitForHandlerAction(stateMachine.getHandler(), TEST_TIMEOUT); waitForHandlerAction(stateMachine.getHandler(), TEST_TIMEOUT); verifyNewSystemCallAudioState(initState, expectedMiddleState); resetMocks(true); resetMocks(); stateMachine.sendMessageWithSessionInfo( CallAudioRouteStateMachine.DISCONNECT_WIRED_HEADSET); waitForStateMachineActionCompletion(stateMachine, CallAudioRouteStateMachine.RUN_RUNNABLE); verifyNewSystemCallAudioState(expectedMiddleState, initState); } Loading Loading @@ -267,7 +270,7 @@ public class CallAudioRouteStateMachineTest waitForStateMachineActionCompletion(stateMachine, CallAudioRouteStateMachine.RUN_RUNNABLE); verifyNewSystemCallAudioState(initState, expectedEndState); resetMocks(false); resetMocks(); stateMachine.sendMessageWithSessionInfo( CallAudioRouteStateMachine.DISCONNECT_BLUETOOTH); stateMachine.sendMessageWithSessionInfo( Loading @@ -277,6 +280,77 @@ public class CallAudioRouteStateMachineTest assertEquals(expectedEndState, stateMachine.getCurrentCallAudioState()); } @MediumTest public void testUserBluetoothSwitchOffAndOnAgain() { CallAudioRouteStateMachine stateMachine = new CallAudioRouteStateMachine( mContext, mockCallsManager, mockBluetoothRouteManager, mockWiredHeadsetManager, mockStatusBarNotifier, mAudioServiceFactory, true); Collection<BluetoothDevice> availableDevices = Collections.singleton(bluetoothDevice1); when(mockBluetoothRouteManager.isBluetoothAudioConnectedOrPending()).thenReturn(false); when(mockBluetoothRouteManager.isBluetoothAvailable()).thenReturn(true); when(mockBluetoothRouteManager.getConnectedDevices()).thenReturn(availableDevices); CallAudioState initState = new CallAudioState(false, CallAudioState.ROUTE_BLUETOOTH, CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_BLUETOOTH); stateMachine.initialize(initState); stateMachine.sendMessageWithSessionInfo(CallAudioRouteStateMachine.SWITCH_FOCUS, CallAudioRouteStateMachine.ACTIVE_FOCUS); stateMachine.sendMessageWithSessionInfo(CallAudioRouteStateMachine.BT_AUDIO_CONNECTED); // Switch off the BT route explicitly. stateMachine.sendMessageWithSessionInfo( CallAudioRouteStateMachine.USER_SWITCH_BASELINE_ROUTE, CallAudioRouteStateMachine.NO_INCLUDE_BLUETOOTH_IN_BASELINE); CallAudioState expectedMidState = new CallAudioState(false, CallAudioState.ROUTE_EARPIECE, CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_BLUETOOTH, null, availableDevices); waitForStateMachineActionCompletion(stateMachine, CallAudioRouteStateMachine.RUN_RUNNABLE); verifyNewSystemCallAudioState(initState, expectedMidState); resetMocks(); // Now, switch back to BT explicitly when(mockBluetoothRouteManager.isBluetoothAudioConnectedOrPending()).thenReturn(false); when(mockBluetoothRouteManager.isBluetoothAvailable()).thenReturn(true); when(mockBluetoothRouteManager.getConnectedDevices()).thenReturn(availableDevices); doAnswer(invocation -> { when(mockBluetoothRouteManager.getBluetoothAudioConnectedDevice()) .thenReturn(bluetoothDevice1); stateMachine.sendMessageWithSessionInfo(CallAudioRouteStateMachine.BT_AUDIO_CONNECTED); return null; }).when(mockBluetoothRouteManager).connectBluetoothAudio(nullable(String.class)); stateMachine.sendMessageWithSessionInfo(CallAudioRouteStateMachine.USER_SWITCH_BLUETOOTH); CallAudioState expectedEndState = new CallAudioState(false, CallAudioState.ROUTE_BLUETOOTH, CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_BLUETOOTH, bluetoothDevice1, availableDevices); waitForStateMachineActionCompletion(stateMachine, CallAudioRouteStateMachine.RUN_RUNNABLE); // second wait needed for the BT_AUDIO_CONNECTED message waitForStateMachineActionCompletion(stateMachine, CallAudioRouteStateMachine.RUN_RUNNABLE); verifyNewSystemCallAudioState(expectedMidState, expectedEndState); stateMachine.sendMessageWithSessionInfo( CallAudioRouteStateMachine.DISCONNECT_BLUETOOTH); when(mockBluetoothRouteManager.getBluetoothAudioConnectedDevice()) .thenReturn(null); stateMachine.sendMessageWithSessionInfo( CallAudioRouteStateMachine.CONNECT_BLUETOOTH); waitForStateMachineActionCompletion(stateMachine, CallAudioRouteStateMachine.RUN_RUNNABLE); // second wait needed for the BT_AUDIO_CONNECTED message waitForStateMachineActionCompletion(stateMachine, CallAudioRouteStateMachine.RUN_RUNNABLE); // Verify that we're still on bluetooth. assertEquals(expectedEndState, stateMachine.getCurrentCallAudioState()); } @MediumTest public void testBluetoothRinging() { CallAudioRouteStateMachine stateMachine = new CallAudioRouteStateMachine( Loading Loading @@ -320,7 +394,7 @@ public class CallAudioRouteStateMachineTest mockStatusBarNotifier, mAudioServiceFactory, true); setInBandRing(false); when(mockBluetoothRouteManager.isBluetoothAudioConnectedOrPending()).thenReturn(false); when(mockBluetoothRouteManager.isBluetoothAvailable()).thenReturn(false); when(mockAudioManager.isSpeakerphoneOn()).thenReturn(false); Loading @@ -330,15 +404,23 @@ public class CallAudioRouteStateMachineTest stateMachine.sendMessageWithSessionInfo(CallAudioRouteStateMachine.SWITCH_FOCUS, CallAudioRouteStateMachine.RINGING_FOCUS); // Wait for the state machine to finish transiting to ActiveEarpiece before hooking up // bluetooth mocks waitForStateMachineActionCompletion(stateMachine, CallAudioRouteStateMachine.RUN_RUNNABLE); when(mockBluetoothRouteManager.isBluetoothAvailable()).thenReturn(true); when(mockBluetoothRouteManager.getConnectedDevices()) .thenReturn(Collections.singletonList(bluetoothDevice1)); stateMachine.sendMessageWithSessionInfo( CallAudioRouteStateMachine.BLUETOOTH_DEVICE_LIST_CHANGED); stateMachine.sendMessageWithSessionInfo(CallAudioRouteStateMachine.CONNECT_BLUETOOTH); waitForStateMachineActionCompletion(stateMachine, CallAudioRouteStateMachine.RUN_RUNNABLE); verify(mockBluetoothRouteManager, never()).connectBluetoothAudio(null); CallAudioState expectedEndState = new CallAudioState(false, CallAudioState.ROUTE_BLUETOOTH, CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_BLUETOOTH); CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_BLUETOOTH, null, Collections.singletonList(bluetoothDevice1)); verifyNewSystemCallAudioState(initState, expectedEndState); stateMachine.sendMessageWithSessionInfo(CallAudioRouteStateMachine.SWITCH_FOCUS, Loading Loading @@ -879,7 +961,7 @@ public class CallAudioRouteStateMachineTest private void runParametrizedTestCaseWithFocus(final RoutingTestParameters params) throws Throwable { resetMocks(true); resetMocks(); // Construct a fresh state machine on every case final CallAudioRouteStateMachine stateMachine = new CallAudioRouteStateMachine( Loading Loading @@ -908,7 +990,7 @@ public class CallAudioRouteStateMachineTest waitForStateMachineActionCompletion(stateMachine, CallAudioRouteStateMachine.RUN_RUNNABLE); // Reset mocks one more time to discard stuff from initialization resetMocks(false); resetMocks(); setupMocksForParams(stateMachine, params); stateMachine.sendMessageWithSessionInfo(params.action); Loading Loading @@ -984,7 +1066,7 @@ public class CallAudioRouteStateMachineTest private void runParametrizedTestCaseWithoutFocus(final RoutingTestParameters params) throws Throwable { resetMocks(true); resetMocks(); // Construct a fresh state machine on every case final CallAudioRouteStateMachine stateMachine = new CallAudioRouteStateMachine( Loading Loading @@ -1050,12 +1132,18 @@ public class CallAudioRouteStateMachineTest verify(mockConnectionServiceWrapper, timeout(TEST_TIMEOUT).atLeastOnce()) .onCallAudioStateChanged(same(fakeCall), newStateCaptor2.capture()); assertTrue(oldStateCaptor.getValue().equals(expectedOldState)); assertTrue(oldStateCaptor.getAllValues().get(0).equals(expectedOldState)); assertTrue(newStateCaptor1.getValue().equals(expectedNewState)); assertTrue(newStateCaptor2.getValue().equals(expectedNewState)); } private void resetMocks(boolean resetNotificationFilter) { private void setInBandRing(boolean enabled) { mComponentContextFixture.putBooleanResource( com.android.internal.R.bool.config_bluetooth_hfp_inband_ringing_support, enabled); } private void resetMocks() { reset(mockAudioManager, mockBluetoothRouteManager, mockCallsManager, mockConnectionServiceWrapper, fakeCall); when(mockCallsManager.getForegroundCall()).thenReturn(fakeCall); Loading Loading
src/com/android/server/telecom/CallAudioRouteStateMachine.java +8 −14 Original line number Diff line number Diff line Loading @@ -265,7 +265,6 @@ public class CallAudioRouteStateMachine extends StateMachine { } else { removedRoutes |= ROUTE_BLUETOOTH; } // TODO: update in-call app on the list of BT devices. isHandled = HANDLED; break; case SWITCH_BASELINE_ROUTE: Loading @@ -276,6 +275,10 @@ public class CallAudioRouteStateMachine extends StateMachine { sendInternalMessage(calculateBaselineRouteMessage(true, msg.arg1 == INCLUDE_BLUETOOTH_IN_BASELINE)); return HANDLED; case USER_SWITCH_BLUETOOTH: // If the user tries to switch to BT, reset the explicitly-switched-away flag. mHasUserExplicitlyLeftBluetooth = false; return NOT_HANDLED; case SWITCH_FOCUS: mAudioFocusType = msg.arg1; return NOT_HANDLED; Loading @@ -283,10 +286,12 @@ public class CallAudioRouteStateMachine extends StateMachine { return NOT_HANDLED; } if (addedRoutes != 0 || removedRoutes != 0) { if (addedRoutes != 0 || removedRoutes != 0 || msg.what == BLUETOOTH_DEVICE_LIST_CHANGED) { mAvailableRoutes = modifyRoutes(mAvailableRoutes, removedRoutes, addedRoutes, true); mDeviceSupportedRoutes = modifyRoutes(mDeviceSupportedRoutes, removedRoutes, addedRoutes, false); updateSystemAudioState(); } return isHandled; Loading Loading @@ -467,18 +472,15 @@ public class CallAudioRouteStateMachine extends StateMachine { } else { Log.i(this, "Not switching to BT route from earpiece because user has " + "explicitly disconnected."); updateSystemAudioState(); } return HANDLED; case DISCONNECT_BLUETOOTH: updateSystemAudioState(); // No change in audio route required return HANDLED; case DISCONNECT_WIRED_HEADSET: Log.e(this, new IllegalStateException(), "Wired headset should not go from connected to not when on " + "earpiece"); updateSystemAudioState(); return HANDLED; case BT_AUDIO_DISCONNECTED: // This may be sent as a confirmation by the BT stack after switch off BT. Loading Loading @@ -657,8 +659,6 @@ public class CallAudioRouteStateMachine extends StateMachine { case CONNECT_WIRED_HEADSET: Log.e(this, new IllegalStateException(), "Wired headset should already be connected."); mAvailableRoutes |= ROUTE_WIRED_HEADSET; updateSystemAudioState(); return HANDLED; case CONNECT_BLUETOOTH: if (!mHasUserExplicitlyLeftBluetooth) { Loading @@ -666,11 +666,9 @@ public class CallAudioRouteStateMachine extends StateMachine { } else { Log.i(this, "Not switching to BT route from headset because user has " + "explicitly disconnected."); updateSystemAudioState(); } return HANDLED; case DISCONNECT_BLUETOOTH: updateSystemAudioState(); // No change in audio route required return HANDLED; case DISCONNECT_WIRED_HEADSET: Loading Loading @@ -975,7 +973,6 @@ public class CallAudioRouteStateMachine extends StateMachine { mWasOnSpeaker = false; return HANDLED; case DISCONNECT_WIRED_HEADSET: updateSystemAudioState(); // No change in audio route required return HANDLED; case CONNECT_DOCK: Loading Loading @@ -1009,7 +1006,7 @@ public class CallAudioRouteStateMachine extends StateMachine { setBluetoothOff(); CallAudioState newState = new CallAudioState(mIsMuted, ROUTE_SPEAKER, mAvailableRoutes, null, mBluetoothRouteManager.getConnectedDevices()); setSystemAudioState(newState); setSystemAudioState(newState, true); updateInternalCallAudioState(); } Loading Loading @@ -1175,15 +1172,12 @@ public class CallAudioRouteStateMachine extends StateMachine { } else { Log.i(this, "Not switching to BT route from speaker because user has " + "explicitly disconnected."); updateSystemAudioState(); } return HANDLED; case DISCONNECT_BLUETOOTH: updateSystemAudioState(); // No change in audio route required return HANDLED; case DISCONNECT_WIRED_HEADSET: updateSystemAudioState(); // No change in audio route required return HANDLED; case BT_AUDIO_DISCONNECTED: Loading
tests/src/com/android/server/telecom/tests/CallAudioRouteStateMachineTest.java +97 −9 Original line number Diff line number Diff line Loading @@ -45,9 +45,11 @@ import org.mockito.stubbing.Answer; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.ArgumentMatchers.nullable; import static org.mockito.Matchers.any; import static org.mockito.Matchers.same; Loading Loading @@ -229,10 +231,11 @@ public class CallAudioRouteStateMachineTest waitForHandlerAction(stateMachine.getHandler(), TEST_TIMEOUT); waitForHandlerAction(stateMachine.getHandler(), TEST_TIMEOUT); verifyNewSystemCallAudioState(initState, expectedMiddleState); resetMocks(true); resetMocks(); stateMachine.sendMessageWithSessionInfo( CallAudioRouteStateMachine.DISCONNECT_WIRED_HEADSET); waitForStateMachineActionCompletion(stateMachine, CallAudioRouteStateMachine.RUN_RUNNABLE); verifyNewSystemCallAudioState(expectedMiddleState, initState); } Loading Loading @@ -267,7 +270,7 @@ public class CallAudioRouteStateMachineTest waitForStateMachineActionCompletion(stateMachine, CallAudioRouteStateMachine.RUN_RUNNABLE); verifyNewSystemCallAudioState(initState, expectedEndState); resetMocks(false); resetMocks(); stateMachine.sendMessageWithSessionInfo( CallAudioRouteStateMachine.DISCONNECT_BLUETOOTH); stateMachine.sendMessageWithSessionInfo( Loading @@ -277,6 +280,77 @@ public class CallAudioRouteStateMachineTest assertEquals(expectedEndState, stateMachine.getCurrentCallAudioState()); } @MediumTest public void testUserBluetoothSwitchOffAndOnAgain() { CallAudioRouteStateMachine stateMachine = new CallAudioRouteStateMachine( mContext, mockCallsManager, mockBluetoothRouteManager, mockWiredHeadsetManager, mockStatusBarNotifier, mAudioServiceFactory, true); Collection<BluetoothDevice> availableDevices = Collections.singleton(bluetoothDevice1); when(mockBluetoothRouteManager.isBluetoothAudioConnectedOrPending()).thenReturn(false); when(mockBluetoothRouteManager.isBluetoothAvailable()).thenReturn(true); when(mockBluetoothRouteManager.getConnectedDevices()).thenReturn(availableDevices); CallAudioState initState = new CallAudioState(false, CallAudioState.ROUTE_BLUETOOTH, CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_BLUETOOTH); stateMachine.initialize(initState); stateMachine.sendMessageWithSessionInfo(CallAudioRouteStateMachine.SWITCH_FOCUS, CallAudioRouteStateMachine.ACTIVE_FOCUS); stateMachine.sendMessageWithSessionInfo(CallAudioRouteStateMachine.BT_AUDIO_CONNECTED); // Switch off the BT route explicitly. stateMachine.sendMessageWithSessionInfo( CallAudioRouteStateMachine.USER_SWITCH_BASELINE_ROUTE, CallAudioRouteStateMachine.NO_INCLUDE_BLUETOOTH_IN_BASELINE); CallAudioState expectedMidState = new CallAudioState(false, CallAudioState.ROUTE_EARPIECE, CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_BLUETOOTH, null, availableDevices); waitForStateMachineActionCompletion(stateMachine, CallAudioRouteStateMachine.RUN_RUNNABLE); verifyNewSystemCallAudioState(initState, expectedMidState); resetMocks(); // Now, switch back to BT explicitly when(mockBluetoothRouteManager.isBluetoothAudioConnectedOrPending()).thenReturn(false); when(mockBluetoothRouteManager.isBluetoothAvailable()).thenReturn(true); when(mockBluetoothRouteManager.getConnectedDevices()).thenReturn(availableDevices); doAnswer(invocation -> { when(mockBluetoothRouteManager.getBluetoothAudioConnectedDevice()) .thenReturn(bluetoothDevice1); stateMachine.sendMessageWithSessionInfo(CallAudioRouteStateMachine.BT_AUDIO_CONNECTED); return null; }).when(mockBluetoothRouteManager).connectBluetoothAudio(nullable(String.class)); stateMachine.sendMessageWithSessionInfo(CallAudioRouteStateMachine.USER_SWITCH_BLUETOOTH); CallAudioState expectedEndState = new CallAudioState(false, CallAudioState.ROUTE_BLUETOOTH, CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_BLUETOOTH, bluetoothDevice1, availableDevices); waitForStateMachineActionCompletion(stateMachine, CallAudioRouteStateMachine.RUN_RUNNABLE); // second wait needed for the BT_AUDIO_CONNECTED message waitForStateMachineActionCompletion(stateMachine, CallAudioRouteStateMachine.RUN_RUNNABLE); verifyNewSystemCallAudioState(expectedMidState, expectedEndState); stateMachine.sendMessageWithSessionInfo( CallAudioRouteStateMachine.DISCONNECT_BLUETOOTH); when(mockBluetoothRouteManager.getBluetoothAudioConnectedDevice()) .thenReturn(null); stateMachine.sendMessageWithSessionInfo( CallAudioRouteStateMachine.CONNECT_BLUETOOTH); waitForStateMachineActionCompletion(stateMachine, CallAudioRouteStateMachine.RUN_RUNNABLE); // second wait needed for the BT_AUDIO_CONNECTED message waitForStateMachineActionCompletion(stateMachine, CallAudioRouteStateMachine.RUN_RUNNABLE); // Verify that we're still on bluetooth. assertEquals(expectedEndState, stateMachine.getCurrentCallAudioState()); } @MediumTest public void testBluetoothRinging() { CallAudioRouteStateMachine stateMachine = new CallAudioRouteStateMachine( Loading Loading @@ -320,7 +394,7 @@ public class CallAudioRouteStateMachineTest mockStatusBarNotifier, mAudioServiceFactory, true); setInBandRing(false); when(mockBluetoothRouteManager.isBluetoothAudioConnectedOrPending()).thenReturn(false); when(mockBluetoothRouteManager.isBluetoothAvailable()).thenReturn(false); when(mockAudioManager.isSpeakerphoneOn()).thenReturn(false); Loading @@ -330,15 +404,23 @@ public class CallAudioRouteStateMachineTest stateMachine.sendMessageWithSessionInfo(CallAudioRouteStateMachine.SWITCH_FOCUS, CallAudioRouteStateMachine.RINGING_FOCUS); // Wait for the state machine to finish transiting to ActiveEarpiece before hooking up // bluetooth mocks waitForStateMachineActionCompletion(stateMachine, CallAudioRouteStateMachine.RUN_RUNNABLE); when(mockBluetoothRouteManager.isBluetoothAvailable()).thenReturn(true); when(mockBluetoothRouteManager.getConnectedDevices()) .thenReturn(Collections.singletonList(bluetoothDevice1)); stateMachine.sendMessageWithSessionInfo( CallAudioRouteStateMachine.BLUETOOTH_DEVICE_LIST_CHANGED); stateMachine.sendMessageWithSessionInfo(CallAudioRouteStateMachine.CONNECT_BLUETOOTH); waitForStateMachineActionCompletion(stateMachine, CallAudioRouteStateMachine.RUN_RUNNABLE); verify(mockBluetoothRouteManager, never()).connectBluetoothAudio(null); CallAudioState expectedEndState = new CallAudioState(false, CallAudioState.ROUTE_BLUETOOTH, CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_BLUETOOTH); CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_BLUETOOTH, null, Collections.singletonList(bluetoothDevice1)); verifyNewSystemCallAudioState(initState, expectedEndState); stateMachine.sendMessageWithSessionInfo(CallAudioRouteStateMachine.SWITCH_FOCUS, Loading Loading @@ -879,7 +961,7 @@ public class CallAudioRouteStateMachineTest private void runParametrizedTestCaseWithFocus(final RoutingTestParameters params) throws Throwable { resetMocks(true); resetMocks(); // Construct a fresh state machine on every case final CallAudioRouteStateMachine stateMachine = new CallAudioRouteStateMachine( Loading Loading @@ -908,7 +990,7 @@ public class CallAudioRouteStateMachineTest waitForStateMachineActionCompletion(stateMachine, CallAudioRouteStateMachine.RUN_RUNNABLE); // Reset mocks one more time to discard stuff from initialization resetMocks(false); resetMocks(); setupMocksForParams(stateMachine, params); stateMachine.sendMessageWithSessionInfo(params.action); Loading Loading @@ -984,7 +1066,7 @@ public class CallAudioRouteStateMachineTest private void runParametrizedTestCaseWithoutFocus(final RoutingTestParameters params) throws Throwable { resetMocks(true); resetMocks(); // Construct a fresh state machine on every case final CallAudioRouteStateMachine stateMachine = new CallAudioRouteStateMachine( Loading Loading @@ -1050,12 +1132,18 @@ public class CallAudioRouteStateMachineTest verify(mockConnectionServiceWrapper, timeout(TEST_TIMEOUT).atLeastOnce()) .onCallAudioStateChanged(same(fakeCall), newStateCaptor2.capture()); assertTrue(oldStateCaptor.getValue().equals(expectedOldState)); assertTrue(oldStateCaptor.getAllValues().get(0).equals(expectedOldState)); assertTrue(newStateCaptor1.getValue().equals(expectedNewState)); assertTrue(newStateCaptor2.getValue().equals(expectedNewState)); } private void resetMocks(boolean resetNotificationFilter) { private void setInBandRing(boolean enabled) { mComponentContextFixture.putBooleanResource( com.android.internal.R.bool.config_bluetooth_hfp_inband_ringing_support, enabled); } private void resetMocks() { reset(mockAudioManager, mockBluetoothRouteManager, mockCallsManager, mockConnectionServiceWrapper, fakeCall); when(mockCallsManager.getForegroundCall()).thenReturn(fakeCall); Loading