Loading android/app/src/com/android/bluetooth/btservice/ActiveDeviceManager.java +17 −4 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothClass; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHearingAid; import android.bluetooth.BluetoothLeAudio; import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothSinkAudioPolicy; import android.media.AudioDeviceCallback; Loading Loading @@ -569,8 +570,8 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac boolean hasFallbackDevice = false; if (Objects.equals(mLeAudioActiveDevice, device)) { hasFallbackDevice = setFallbackDeviceActiveLocked(device); if (!hasFallbackDevice) { setLeAudioActiveDevice(null, false); if (!hasFallbackDevice && !Flags.admFixDisconnectOfSetMember()) { leAudioService.removeActiveDevice(false); } } leAudioService.deviceDisconnected(device, hasFallbackDevice); Loading Loading @@ -1095,13 +1096,25 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac return false; } if (firstDevice == null || secondDevice == null) { return false; } final LeAudioService leAudioService = mFactory.getLeAudioService(); if (leAudioService == null) { Log.e(TAG, "LeAudioService not available"); return false; } return leAudioService.getGroupId(firstDevice) == leAudioService.getGroupId(secondDevice); int groupIdFirst = leAudioService.getGroupId(firstDevice); int groupIdSecond = leAudioService.getGroupId(secondDevice); if (groupIdFirst == BluetoothLeAudio.GROUP_ID_INVALID || groupIdSecond == BluetoothLeAudio.GROUP_ID_INVALID) { return false; } return groupIdFirst == groupIdSecond; } /** Loading @@ -1113,7 +1126,7 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac */ @GuardedBy("mLock") private boolean setFallbackDeviceActiveLocked(BluetoothDevice recentlyRemovedDevice) { Log.d(TAG, "setFallbackDeviceActive"); Log.d(TAG, "setFallbackDeviceActive, recently removed: " + recentlyRemovedDevice); mDbManager = mAdapterService.getDatabase(); List<BluetoothDevice> connectedHearingAidDevices = new ArrayList<>(); if (!mHearingAidConnectedDevices.isEmpty()) { Loading android/app/tests/unit/src/com/android/bluetooth/btservice/ActiveDeviceManagerTest.java +83 −41 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import android.media.AudioDeviceInfo; import android.media.AudioDevicePort; import android.media.AudioManager; import android.os.test.TestLooper; import android.platform.test.annotations.DisableFlags; import android.platform.test.annotations.EnableFlags; import android.platform.test.flag.junit.SetFlagsRule; import android.util.ArrayMap; Loading Loading @@ -385,10 +386,13 @@ public class ActiveDeviceManagerTest { @Test public void headsetRemoveActive_fallbackToLeAudio() { when(mHeadsetService.getFallbackDevice()).thenReturn(mHeadsetDevice); when(mLeAudioService.getGroupId(mLeAudioDevice)).thenReturn(1); InOrder order = inOrder(mLeAudioService); leAudioConnected(mLeAudioDevice); mTestLooper.dispatchAll(); verify(mLeAudioService, times(1)).setActiveDevice(mLeAudioDevice); order.verify(mLeAudioService, times(1)).setActiveDevice(mLeAudioDevice); headsetConnected(mHeadsetDevice, false); mTestLooper.dispatchAll(); Loading Loading @@ -827,7 +831,28 @@ public class ActiveDeviceManagerTest { /** One LE Audio is connected and disconnected later. Should then set active device to null. */ @Test @EnableFlags(Flags.FLAG_ADM_FIX_DISCONNECT_OF_SET_MEMBER) public void lastLeAudioDisconnected_clearLeAudioActive() { when(mLeAudioService.getGroupId(mLeAudioDevice)).thenReturn(1); when(mLeAudioService.getLeadDevice(mLeAudioDevice)).thenReturn(mLeAudioDevice); leAudioConnected(mLeAudioDevice); mTestLooper.dispatchAll(); verify(mLeAudioService).setActiveDevice(mLeAudioDevice); leAudioDisconnected(mLeAudioDevice); mTestLooper.dispatchAll(); verify(mLeAudioService, never()).removeActiveDevice(anyBoolean()); verify(mLeAudioService).deviceDisconnected(mLeAudioDevice, false); } /** One LE Audio is connected and disconnected later. Should then set active device to null. */ @Test @DisableFlags(Flags.FLAG_ADM_FIX_DISCONNECT_OF_SET_MEMBER) public void lastLeAudioDisconnected_clearLeAudioActive_NoFixDisconnectFlag() { when(mLeAudioService.getGroupId(mLeAudioDevice)).thenReturn(1); when(mLeAudioService.getLeadDevice(mLeAudioDevice)).thenReturn(mLeAudioDevice); leAudioConnected(mLeAudioDevice); mTestLooper.dispatchAll(); verify(mLeAudioService).setActiveDevice(mLeAudioDevice); Loading Loading @@ -857,11 +882,16 @@ public class ActiveDeviceManagerTest { } /** * Two LE Audio are connected and the current active is then disconnected. Should then set * active device to fallback device. * Two LE Audio Sets are connected and the current active Set is disconnected. The other * connected LeAudio Set shall become an active device. */ @Test public void leAudioSecondDeviceDisconnected_fallbackDeviceActive() { when(mLeAudioService.getGroupId(mLeAudioDevice)).thenReturn(1); when(mLeAudioService.getGroupId(mLeAudioDevice2)).thenReturn(2); when(mLeAudioService.getLeadDevice(mLeAudioDevice)).thenReturn(mLeAudioDevice); when(mLeAudioService.getLeadDevice(mLeAudioDevice2)).thenReturn(mLeAudioDevice2); leAudioConnected(mLeAudioDevice); mTestLooper.dispatchAll(); verify(mLeAudioService).setActiveDevice(mLeAudioDevice); Loading Loading @@ -1101,6 +1131,7 @@ public class ActiveDeviceManagerTest { @Test public void leAudioAndA2dpConnectedThenA2dpDisconnected_fallbackToLeAudio() { when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_NORMAL); when(mLeAudioService.getGroupId(mLeAudioDevice)).thenReturn(1); leAudioConnected(mLeAudioDevice); mTestLooper.dispatchAll(); Loading Loading @@ -1143,13 +1174,13 @@ public class ActiveDeviceManagerTest { } /** * An LE Audio set connected. The active bud disconnected. Set active device returns false * indicating an issue (the other bud is also disconnected). Then the active device should be * removed and hasFallback should be set to false. * An LE Audio set connected. The active bud disconnected. Active device manager should not * choose other set member as active device. */ @Test public void leAudioSetConnectedThenActiveOneDisconnected_noFallback() { when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_NORMAL); when(mLeAudioService.getLeadDevice(any())).thenReturn(mLeAudioDevice); leAudioConnected(mLeAudioDevice); mTestLooper.dispatchAll(); Loading @@ -1157,71 +1188,76 @@ public class ActiveDeviceManagerTest { leAudioConnected(mLeAudioDevice2); mTestLooper.dispatchAll(); verify(mLeAudioService).setActiveDevice(mLeAudioDevice2); Mockito.clearInvocations(mLeAudioService); // Return false to indicate an issue when setting new active device // (e.g. the other device disconnected as well). when(mLeAudioService.setActiveDevice(any())).thenReturn(false); verify(mLeAudioService, never()).setActiveDevice(mLeAudioDevice2); leAudioDisconnected(mLeAudioDevice2); mTestLooper.dispatchAll(); verify(mLeAudioService).removeActiveDevice(false); verify(mLeAudioService, never()).removeActiveDevice(anyBoolean()); verify(mLeAudioService).deviceDisconnected(mLeAudioDevice2, false); } /** * An LE Audio set connected. The active bud disconnected. Set active device returns true * indicating the other bud is going to be the active device. Then the active device should * change and hasFallback should be set to true. */ @Test public void leAudioSetConnectedThenActiveOneDisconnected_hasFallback() { @EnableFlags(Flags.FLAG_ADM_FIX_DISCONNECT_OF_SET_MEMBER) public void leAudioSetConnectedGroupThenDisconnected_noFallback() { when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_NORMAL); when(mLeAudioService.getGroupId(mLeAudioDevice)).thenReturn(1); when(mLeAudioService.getGroupId(mLeAudioDevice2)).thenReturn(1); when(mLeAudioService.getLeadDevice(mLeAudioDevice2)).thenReturn(mLeAudioDevice); when(mLeAudioService.getLeadDevice(mLeAudioDevice)).thenReturn(mLeAudioDevice); InOrder order = inOrder(mLeAudioService); leAudioConnected(mLeAudioDevice); mTestLooper.dispatchAll(); verify(mLeAudioService).setActiveDevice(mLeAudioDevice); order.verify(mLeAudioService).setActiveDevice(mLeAudioDevice); leAudioConnected(mLeAudioDevice2); mTestLooper.dispatchAll(); verify(mLeAudioService).setActiveDevice(mLeAudioDevice2); Mockito.clearInvocations(mLeAudioService); order.verify(mLeAudioService, never()).setActiveDevice(any()); leAudioDisconnected(mLeAudioDevice2); mTestLooper.dispatchAll(); verify(mLeAudioService).setActiveDevice(mLeAudioDevice); verify(mLeAudioService).deviceDisconnected(mLeAudioDevice2, true); order.verify(mLeAudioService, never()).setActiveDevice(any()); order.verify(mLeAudioService, never()).removeActiveDevice(anyBoolean()); order.verify(mLeAudioService).deviceDisconnected(mLeAudioDevice2, false); leAudioDisconnected(mLeAudioDevice); mTestLooper.dispatchAll(); order.verify(mLeAudioService, never()).removeActiveDevice(anyBoolean()); order.verify(mLeAudioService).deviceDisconnected(mLeAudioDevice, false); } @Test public void leAudioSetConnectedGroupThenDisconnected_noFallback() { @DisableFlags(Flags.FLAG_ADM_FIX_DISCONNECT_OF_SET_MEMBER) public void leAudioSetConnectedGroupThenDisconnected_noFallback_NoFixDisconnectFlag() { when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_NORMAL); when(mLeAudioService.getGroupId(mLeAudioDevice)).thenReturn(1); when(mLeAudioService.getGroupId(mLeAudioDevice2)).thenReturn(1); when(mLeAudioService.getLeadDevice(mLeAudioDevice2)).thenReturn(mLeAudioDevice); when(mLeAudioService.getLeadDevice(mLeAudioDevice)).thenReturn(mLeAudioDevice); InOrder order = inOrder(mLeAudioService); leAudioConnected(mLeAudioDevice); mTestLooper.dispatchAll(); verify(mLeAudioService).setActiveDevice(mLeAudioDevice); Mockito.clearInvocations(mLeAudioService); order.verify(mLeAudioService).setActiveDevice(mLeAudioDevice); when(mLeAudioService.getLeadDevice(mLeAudioDevice2)).thenReturn(mLeAudioDevice); leAudioConnected(mLeAudioDevice2); mTestLooper.dispatchAll(); verify(mLeAudioService, never()).setActiveDevice(any()); Mockito.clearInvocations(mLeAudioService); order.verify(mLeAudioService, never()).setActiveDevice(any()); leAudioDisconnected(mLeAudioDevice2); mTestLooper.dispatchAll(); verify(mLeAudioService, never()).setActiveDevice(any()); verify(mLeAudioService, never()).removeActiveDevice(anyBoolean()); order.verify(mLeAudioService, never()).setActiveDevice(any()); order.verify(mLeAudioService, never()).removeActiveDevice(anyBoolean()); order.verify(mLeAudioService).deviceDisconnected(mLeAudioDevice2, false); leAudioDisconnected(mLeAudioDevice); mTestLooper.dispatchAll(); verify(mLeAudioService).removeActiveDevice(false); verify(mLeAudioService).deviceDisconnected(mLeAudioDevice2, false); order.verify(mLeAudioService).removeActiveDevice(false); order.verify(mLeAudioService).deviceDisconnected(mLeAudioDevice, false); } /** Loading Loading @@ -1255,6 +1291,11 @@ public class ActiveDeviceManagerTest { @Test @EnableFlags(Flags.FLAG_ADM_VERIFY_ACTIVE_FALLBACK_DEVICE) public void sameDeviceAsAshaAndLeAudio_noFallbackOnSwitch() { /* Dual mode ASHA/LeAudio device from group 1 */ when(mLeAudioService.getGroupId(mHearingAidDevice)).thenReturn(1); /* Different LeAudio only device from group 2 */ when(mLeAudioService.getGroupId(mLeAudioDevice)).thenReturn(2); when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_NORMAL); /* Connect first device as ASHA */ Loading @@ -1262,11 +1303,12 @@ public class ActiveDeviceManagerTest { mTestLooper.dispatchAll(); verify(mHearingAidService).setActiveDevice(mHearingAidDevice); /* Connect first device as LE Audio */ leAudioConnected(mHearingAidDevice); /* Disconnect ASHA and connect first device as LE Audio */ hearingAidDisconnected(mHearingAidDevice); mTestLooper.dispatchAll(); verify(mHearingAidService).removeActiveDevice(false); verify(mHearingAidService).removeActiveDevice(true /* stop audio */); leAudioConnected(mHearingAidDevice); mTestLooper.dispatchAll(); verify(mLeAudioService).setActiveDevice(mHearingAidDevice); /* Connect second device as LE Audio. First device is disconnected with fallback to Loading Loading
android/app/src/com/android/bluetooth/btservice/ActiveDeviceManager.java +17 −4 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothClass; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHearingAid; import android.bluetooth.BluetoothLeAudio; import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothSinkAudioPolicy; import android.media.AudioDeviceCallback; Loading Loading @@ -569,8 +570,8 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac boolean hasFallbackDevice = false; if (Objects.equals(mLeAudioActiveDevice, device)) { hasFallbackDevice = setFallbackDeviceActiveLocked(device); if (!hasFallbackDevice) { setLeAudioActiveDevice(null, false); if (!hasFallbackDevice && !Flags.admFixDisconnectOfSetMember()) { leAudioService.removeActiveDevice(false); } } leAudioService.deviceDisconnected(device, hasFallbackDevice); Loading Loading @@ -1095,13 +1096,25 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac return false; } if (firstDevice == null || secondDevice == null) { return false; } final LeAudioService leAudioService = mFactory.getLeAudioService(); if (leAudioService == null) { Log.e(TAG, "LeAudioService not available"); return false; } return leAudioService.getGroupId(firstDevice) == leAudioService.getGroupId(secondDevice); int groupIdFirst = leAudioService.getGroupId(firstDevice); int groupIdSecond = leAudioService.getGroupId(secondDevice); if (groupIdFirst == BluetoothLeAudio.GROUP_ID_INVALID || groupIdSecond == BluetoothLeAudio.GROUP_ID_INVALID) { return false; } return groupIdFirst == groupIdSecond; } /** Loading @@ -1113,7 +1126,7 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac */ @GuardedBy("mLock") private boolean setFallbackDeviceActiveLocked(BluetoothDevice recentlyRemovedDevice) { Log.d(TAG, "setFallbackDeviceActive"); Log.d(TAG, "setFallbackDeviceActive, recently removed: " + recentlyRemovedDevice); mDbManager = mAdapterService.getDatabase(); List<BluetoothDevice> connectedHearingAidDevices = new ArrayList<>(); if (!mHearingAidConnectedDevices.isEmpty()) { Loading
android/app/tests/unit/src/com/android/bluetooth/btservice/ActiveDeviceManagerTest.java +83 −41 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import android.media.AudioDeviceInfo; import android.media.AudioDevicePort; import android.media.AudioManager; import android.os.test.TestLooper; import android.platform.test.annotations.DisableFlags; import android.platform.test.annotations.EnableFlags; import android.platform.test.flag.junit.SetFlagsRule; import android.util.ArrayMap; Loading Loading @@ -385,10 +386,13 @@ public class ActiveDeviceManagerTest { @Test public void headsetRemoveActive_fallbackToLeAudio() { when(mHeadsetService.getFallbackDevice()).thenReturn(mHeadsetDevice); when(mLeAudioService.getGroupId(mLeAudioDevice)).thenReturn(1); InOrder order = inOrder(mLeAudioService); leAudioConnected(mLeAudioDevice); mTestLooper.dispatchAll(); verify(mLeAudioService, times(1)).setActiveDevice(mLeAudioDevice); order.verify(mLeAudioService, times(1)).setActiveDevice(mLeAudioDevice); headsetConnected(mHeadsetDevice, false); mTestLooper.dispatchAll(); Loading Loading @@ -827,7 +831,28 @@ public class ActiveDeviceManagerTest { /** One LE Audio is connected and disconnected later. Should then set active device to null. */ @Test @EnableFlags(Flags.FLAG_ADM_FIX_DISCONNECT_OF_SET_MEMBER) public void lastLeAudioDisconnected_clearLeAudioActive() { when(mLeAudioService.getGroupId(mLeAudioDevice)).thenReturn(1); when(mLeAudioService.getLeadDevice(mLeAudioDevice)).thenReturn(mLeAudioDevice); leAudioConnected(mLeAudioDevice); mTestLooper.dispatchAll(); verify(mLeAudioService).setActiveDevice(mLeAudioDevice); leAudioDisconnected(mLeAudioDevice); mTestLooper.dispatchAll(); verify(mLeAudioService, never()).removeActiveDevice(anyBoolean()); verify(mLeAudioService).deviceDisconnected(mLeAudioDevice, false); } /** One LE Audio is connected and disconnected later. Should then set active device to null. */ @Test @DisableFlags(Flags.FLAG_ADM_FIX_DISCONNECT_OF_SET_MEMBER) public void lastLeAudioDisconnected_clearLeAudioActive_NoFixDisconnectFlag() { when(mLeAudioService.getGroupId(mLeAudioDevice)).thenReturn(1); when(mLeAudioService.getLeadDevice(mLeAudioDevice)).thenReturn(mLeAudioDevice); leAudioConnected(mLeAudioDevice); mTestLooper.dispatchAll(); verify(mLeAudioService).setActiveDevice(mLeAudioDevice); Loading Loading @@ -857,11 +882,16 @@ public class ActiveDeviceManagerTest { } /** * Two LE Audio are connected and the current active is then disconnected. Should then set * active device to fallback device. * Two LE Audio Sets are connected and the current active Set is disconnected. The other * connected LeAudio Set shall become an active device. */ @Test public void leAudioSecondDeviceDisconnected_fallbackDeviceActive() { when(mLeAudioService.getGroupId(mLeAudioDevice)).thenReturn(1); when(mLeAudioService.getGroupId(mLeAudioDevice2)).thenReturn(2); when(mLeAudioService.getLeadDevice(mLeAudioDevice)).thenReturn(mLeAudioDevice); when(mLeAudioService.getLeadDevice(mLeAudioDevice2)).thenReturn(mLeAudioDevice2); leAudioConnected(mLeAudioDevice); mTestLooper.dispatchAll(); verify(mLeAudioService).setActiveDevice(mLeAudioDevice); Loading Loading @@ -1101,6 +1131,7 @@ public class ActiveDeviceManagerTest { @Test public void leAudioAndA2dpConnectedThenA2dpDisconnected_fallbackToLeAudio() { when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_NORMAL); when(mLeAudioService.getGroupId(mLeAudioDevice)).thenReturn(1); leAudioConnected(mLeAudioDevice); mTestLooper.dispatchAll(); Loading Loading @@ -1143,13 +1174,13 @@ public class ActiveDeviceManagerTest { } /** * An LE Audio set connected. The active bud disconnected. Set active device returns false * indicating an issue (the other bud is also disconnected). Then the active device should be * removed and hasFallback should be set to false. * An LE Audio set connected. The active bud disconnected. Active device manager should not * choose other set member as active device. */ @Test public void leAudioSetConnectedThenActiveOneDisconnected_noFallback() { when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_NORMAL); when(mLeAudioService.getLeadDevice(any())).thenReturn(mLeAudioDevice); leAudioConnected(mLeAudioDevice); mTestLooper.dispatchAll(); Loading @@ -1157,71 +1188,76 @@ public class ActiveDeviceManagerTest { leAudioConnected(mLeAudioDevice2); mTestLooper.dispatchAll(); verify(mLeAudioService).setActiveDevice(mLeAudioDevice2); Mockito.clearInvocations(mLeAudioService); // Return false to indicate an issue when setting new active device // (e.g. the other device disconnected as well). when(mLeAudioService.setActiveDevice(any())).thenReturn(false); verify(mLeAudioService, never()).setActiveDevice(mLeAudioDevice2); leAudioDisconnected(mLeAudioDevice2); mTestLooper.dispatchAll(); verify(mLeAudioService).removeActiveDevice(false); verify(mLeAudioService, never()).removeActiveDevice(anyBoolean()); verify(mLeAudioService).deviceDisconnected(mLeAudioDevice2, false); } /** * An LE Audio set connected. The active bud disconnected. Set active device returns true * indicating the other bud is going to be the active device. Then the active device should * change and hasFallback should be set to true. */ @Test public void leAudioSetConnectedThenActiveOneDisconnected_hasFallback() { @EnableFlags(Flags.FLAG_ADM_FIX_DISCONNECT_OF_SET_MEMBER) public void leAudioSetConnectedGroupThenDisconnected_noFallback() { when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_NORMAL); when(mLeAudioService.getGroupId(mLeAudioDevice)).thenReturn(1); when(mLeAudioService.getGroupId(mLeAudioDevice2)).thenReturn(1); when(mLeAudioService.getLeadDevice(mLeAudioDevice2)).thenReturn(mLeAudioDevice); when(mLeAudioService.getLeadDevice(mLeAudioDevice)).thenReturn(mLeAudioDevice); InOrder order = inOrder(mLeAudioService); leAudioConnected(mLeAudioDevice); mTestLooper.dispatchAll(); verify(mLeAudioService).setActiveDevice(mLeAudioDevice); order.verify(mLeAudioService).setActiveDevice(mLeAudioDevice); leAudioConnected(mLeAudioDevice2); mTestLooper.dispatchAll(); verify(mLeAudioService).setActiveDevice(mLeAudioDevice2); Mockito.clearInvocations(mLeAudioService); order.verify(mLeAudioService, never()).setActiveDevice(any()); leAudioDisconnected(mLeAudioDevice2); mTestLooper.dispatchAll(); verify(mLeAudioService).setActiveDevice(mLeAudioDevice); verify(mLeAudioService).deviceDisconnected(mLeAudioDevice2, true); order.verify(mLeAudioService, never()).setActiveDevice(any()); order.verify(mLeAudioService, never()).removeActiveDevice(anyBoolean()); order.verify(mLeAudioService).deviceDisconnected(mLeAudioDevice2, false); leAudioDisconnected(mLeAudioDevice); mTestLooper.dispatchAll(); order.verify(mLeAudioService, never()).removeActiveDevice(anyBoolean()); order.verify(mLeAudioService).deviceDisconnected(mLeAudioDevice, false); } @Test public void leAudioSetConnectedGroupThenDisconnected_noFallback() { @DisableFlags(Flags.FLAG_ADM_FIX_DISCONNECT_OF_SET_MEMBER) public void leAudioSetConnectedGroupThenDisconnected_noFallback_NoFixDisconnectFlag() { when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_NORMAL); when(mLeAudioService.getGroupId(mLeAudioDevice)).thenReturn(1); when(mLeAudioService.getGroupId(mLeAudioDevice2)).thenReturn(1); when(mLeAudioService.getLeadDevice(mLeAudioDevice2)).thenReturn(mLeAudioDevice); when(mLeAudioService.getLeadDevice(mLeAudioDevice)).thenReturn(mLeAudioDevice); InOrder order = inOrder(mLeAudioService); leAudioConnected(mLeAudioDevice); mTestLooper.dispatchAll(); verify(mLeAudioService).setActiveDevice(mLeAudioDevice); Mockito.clearInvocations(mLeAudioService); order.verify(mLeAudioService).setActiveDevice(mLeAudioDevice); when(mLeAudioService.getLeadDevice(mLeAudioDevice2)).thenReturn(mLeAudioDevice); leAudioConnected(mLeAudioDevice2); mTestLooper.dispatchAll(); verify(mLeAudioService, never()).setActiveDevice(any()); Mockito.clearInvocations(mLeAudioService); order.verify(mLeAudioService, never()).setActiveDevice(any()); leAudioDisconnected(mLeAudioDevice2); mTestLooper.dispatchAll(); verify(mLeAudioService, never()).setActiveDevice(any()); verify(mLeAudioService, never()).removeActiveDevice(anyBoolean()); order.verify(mLeAudioService, never()).setActiveDevice(any()); order.verify(mLeAudioService, never()).removeActiveDevice(anyBoolean()); order.verify(mLeAudioService).deviceDisconnected(mLeAudioDevice2, false); leAudioDisconnected(mLeAudioDevice); mTestLooper.dispatchAll(); verify(mLeAudioService).removeActiveDevice(false); verify(mLeAudioService).deviceDisconnected(mLeAudioDevice2, false); order.verify(mLeAudioService).removeActiveDevice(false); order.verify(mLeAudioService).deviceDisconnected(mLeAudioDevice, false); } /** Loading Loading @@ -1255,6 +1291,11 @@ public class ActiveDeviceManagerTest { @Test @EnableFlags(Flags.FLAG_ADM_VERIFY_ACTIVE_FALLBACK_DEVICE) public void sameDeviceAsAshaAndLeAudio_noFallbackOnSwitch() { /* Dual mode ASHA/LeAudio device from group 1 */ when(mLeAudioService.getGroupId(mHearingAidDevice)).thenReturn(1); /* Different LeAudio only device from group 2 */ when(mLeAudioService.getGroupId(mLeAudioDevice)).thenReturn(2); when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_NORMAL); /* Connect first device as ASHA */ Loading @@ -1262,11 +1303,12 @@ public class ActiveDeviceManagerTest { mTestLooper.dispatchAll(); verify(mHearingAidService).setActiveDevice(mHearingAidDevice); /* Connect first device as LE Audio */ leAudioConnected(mHearingAidDevice); /* Disconnect ASHA and connect first device as LE Audio */ hearingAidDisconnected(mHearingAidDevice); mTestLooper.dispatchAll(); verify(mHearingAidService).removeActiveDevice(false); verify(mHearingAidService).removeActiveDevice(true /* stop audio */); leAudioConnected(mHearingAidDevice); mTestLooper.dispatchAll(); verify(mLeAudioService).setActiveDevice(mHearingAidDevice); /* Connect second device as LE Audio. First device is disconnected with fallback to Loading