Loading android/app/src/com/android/bluetooth/le_audio/LeAudioService.java +33 −16 Original line number Diff line number Diff line Loading @@ -1677,9 +1677,10 @@ public class LeAudioService extends ProfileService { } if (device != null && mActiveAudioInDevice != null) { LeAudioDeviceDescriptor deviceDescriptor = getDeviceDescriptor(device); LeAudioDeviceDescriptor deviceDescriptor = getDeviceDescriptor(mActiveAudioInDevice); if (deviceDescriptor == null) { Log.e(TAG, "updateActiveInDevice: No valid descriptor for device: " + device); Log.e(TAG, "updateActiveInDevice: No valid descriptor for device: " + mActiveAudioInDevice); return false; } Loading Loading @@ -1744,9 +1745,10 @@ public class LeAudioService extends ProfileService { } if (device != null && mActiveAudioOutDevice != null) { LeAudioDeviceDescriptor deviceDescriptor = getDeviceDescriptor(device); LeAudioDeviceDescriptor deviceDescriptor = getDeviceDescriptor(mActiveAudioOutDevice); if (deviceDescriptor == null) { Log.e(TAG, "updateActiveOutDevice: No valid descriptor for device: " + device); Log.e(TAG, "updateActiveOutDevice: No valid descriptor for device: " + mActiveAudioOutDevice); return false; } Loading Loading @@ -2375,30 +2377,45 @@ public class LeAudioService extends ProfileService { + ", mExposedActiveDevice: " + mExposedActiveDevice); LeAudioGroupDescriptor groupDescriptor = getGroupDescriptor(currentlyActiveGroupId); if (isBroadcastActive() && currentlyActiveGroupId == LE_AUDIO_GROUP_ID_INVALID && mUnicastGroupIdDeactivatedForBroadcastTransition != LE_AUDIO_GROUP_ID_INVALID) { LeAudioGroupDescriptor fallbackGroupDescriptor = getGroupDescriptor(groupId); // If broadcast is ongoing and need to update unicast fallback active group // we need to update the cached group id and skip changing the active device updateFallbackUnicastGroupIdForBroadcast(groupId); if (fallbackGroupDescriptor != null) { if (groupId == LE_AUDIO_GROUP_ID_INVALID) { /* In case of removing fallback unicast group, monitoring input device should be * removed from active devices. */ if (groupDescriptor != null && groupId == LE_AUDIO_GROUP_ID_INVALID) { updateActiveDevices( groupId, groupDescriptor.mDirection, fallbackGroupDescriptor.mDirection, AUDIO_DIRECTION_NONE, false, groupDescriptor.mHasFallbackDeviceWhenGettingInactive, fallbackGroupDescriptor.mHasFallbackDeviceWhenGettingInactive, false); } else { if (mActiveAudioInDevice != null) { updateActiveDevices( groupId, fallbackGroupDescriptor.mDirection, AUDIO_DIRECTION_INPUT_BIT, false, fallbackGroupDescriptor.mHasFallbackDeviceWhenGettingInactive, true); } } } return true; } LeAudioGroupDescriptor groupDescriptor = getGroupDescriptor(currentlyActiveGroupId); if (groupDescriptor != null && groupId == currentlyActiveGroupId) { /* Make sure active group is already exposed to audio framework. * If not, lets wait for it and don't sent additional intent. Loading android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBroadcastServiceTest.java +59 −20 Original line number Diff line number Diff line Loading @@ -56,6 +56,7 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.Spy; Loading @@ -76,6 +77,7 @@ public class LeAudioBroadcastServiceTest { private BluetoothAdapter mAdapter; private BluetoothDevice mDevice; private BluetoothDevice mDevice2; private BluetoothDevice mBroadcastDevice; private Context mTargetContext; Loading Loading @@ -234,6 +236,7 @@ public class LeAudioBroadcastServiceTest { mTargetContext.registerReceiver(mLeAudioIntentReceiver, filter); mDevice = TestUtils.getTestDevice(mAdapter, 0); mDevice2 = TestUtils.getTestDevice(mAdapter, 1); mBroadcastDevice = TestUtils.getTestDevice(mAdapter, 1); when(mAdapterService.getDeviceFromByte(Utils.getBytesFromAddress("FF:FF:FF:FF:FF:FF"))) .thenReturn(mBroadcastDevice); Loading Loading @@ -534,7 +537,9 @@ public class LeAudioBroadcastServiceTest { public void testCreateBroadcast_updateQualityToStandard() { byte[] code = {0x00, 0x01, 0x00, 0x02}; int groupId = 1; prepareConnectedUnicastDevice(groupId); initializeNative(); prepareConnectedUnicastDevice(groupId, mDevice); synchronized (mService.mBroadcastCallbacks) { mService.mBroadcastCallbacks.register(mCallbacks); Loading Loading @@ -771,61 +776,61 @@ public class LeAudioBroadcastServiceTest { } } private void prepareConnectedUnicastDevice(int groupId) { int direction = 3; int snkAudioLocation = 3; int srcAudioLocation = 4; int availableContexts = 5 + BluetoothLeAudio.CONTEXT_TYPE_RINGTONE; /* Initialize native */ private void initializeNative() { LeAudioStackEvent stackEvent = new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_NATIVE_INITIALIZED); mService.messageFromNative(stackEvent); Assert.assertTrue(mService.mLeAudioNativeIsInitialized); } private void prepareConnectedUnicastDevice(int groupId, BluetoothDevice device) { int direction = 3; int snkAudioLocation = 3; int srcAudioLocation = 4; int availableContexts = 5 + BluetoothLeAudio.CONTEXT_TYPE_RINGTONE; /* Prepare active group to cause pending broadcast */ doReturn(BluetoothDevice.BOND_BONDED) .when(mAdapterService) .getBondState(any(BluetoothDevice.class)); doReturn(true).when(mLeAudioNativeInterface).connectLeAudio(any(BluetoothDevice.class)); when(mDatabaseManager.getProfileConnectionPolicy(mDevice, BluetoothProfile.LE_AUDIO)) when(mDatabaseManager.getProfileConnectionPolicy(device, BluetoothProfile.LE_AUDIO)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); doReturn(new ParcelUuid[] {BluetoothUuid.LE_AUDIO}) .when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); Assert.assertTrue(mService.connect(mDevice)); Assert.assertTrue(mService.connect(device)); // Verify the connection state broadcast, and that we are in Connected state verifyConnectionStateIntent( TIMEOUT_MS, mDevice, device, BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED); Assert.assertEquals( BluetoothProfile.STATE_CONNECTING, mService.getConnectionState(mDevice)); Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, mService.getConnectionState(device)); LeAudioStackEvent create_event = new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); create_event.device = mDevice; create_event.device = device; create_event.valueInt1 = LeAudioStackEvent.CONNECTION_STATE_CONNECTED; mService.messageFromNative(create_event); verifyConnectionStateIntent( TIMEOUT_MS, mDevice, device, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_CONNECTING); Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDevice)); Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(device)); create_event = new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_GROUP_NODE_STATUS_CHANGED); create_event.device = mDevice; create_event.device = device; create_event.valueInt1 = groupId; create_event.valueInt2 = LeAudioStackEvent.GROUP_NODE_ADDED; mService.messageFromNative(create_event); create_event = new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_AUDIO_CONF_CHANGED); create_event.device = mDevice; create_event.device = device; create_event.valueInt1 = direction; create_event.valueInt2 = groupId; create_event.valueInt3 = snkAudioLocation; Loading @@ -848,7 +853,8 @@ public class LeAudioBroadcastServiceTest { mSetFlagsRule.enableFlags(Flags.FLAG_AUDIO_ROUTING_CENTRALIZATION); mSetFlagsRule.enableFlags(Flags.FLAG_LEAUDIO_BIG_DEPENDS_ON_AUDIO_STATE); prepareConnectedUnicastDevice(groupId); initializeNative(); prepareConnectedUnicastDevice(groupId, mDevice); LeAudioStackEvent stackEvent = new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_GROUP_STATUS_CHANGED); Loading Loading @@ -953,7 +959,8 @@ public class LeAudioBroadcastServiceTest { mService.mBroadcastCallbacks.register(mCallbacks); } prepareConnectedUnicastDevice(groupId); initializeNative(); prepareConnectedUnicastDevice(groupId, mDevice); LeAudioStackEvent create_event = new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_GROUP_STATUS_CHANGED); Loading Loading @@ -1490,6 +1497,38 @@ public class LeAudioBroadcastServiceTest { verify(mBassClientService, times(1)).resumeReceiversSourceSynchronization(); } @Test public void testUpdateFallbackInputDevice() { mSetFlagsRule.disableFlags(Flags.FLAG_LEAUDIO_USE_AUDIO_MODE_LISTENER); int groupId = 1; int groupId2 = 2; int broadcastId = 243; byte[] code = {0x00, 0x01, 0x00, 0x02}; initializeNative(); prepareConnectedUnicastDevice(groupId2, mDevice2); prepareHandoverStreamingBroadcast(groupId, broadcastId, code); Assert.assertEquals(mService.mUnicastGroupIdDeactivatedForBroadcastTransition, groupId); reset(mAudioManager); /* Update fallback active device (only input is active) */ ArgumentCaptor<BluetoothProfileConnectionInfo> connectionInfoArgumentCaptor = ArgumentCaptor.forClass(BluetoothProfileConnectionInfo.class); Assert.assertTrue(mService.setActiveDevice(mDevice2)); verify(mAudioManager, times(1)) .handleBluetoothActiveDeviceChanged( eq(mDevice2), eq(mDevice), connectionInfoArgumentCaptor.capture()); List<BluetoothProfileConnectionInfo> connInfos = connectionInfoArgumentCaptor.getAllValues(); Assert.assertEquals(connInfos.size(), 1); Assert.assertFalse(connInfos.get(0).isLeOutput()); Assert.assertEquals(mService.mUnicastGroupIdDeactivatedForBroadcastTransition, groupId2); } private class LeAudioIntentReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Loading android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioServiceTest.java +62 −0 Original line number Diff line number Diff line Loading @@ -1464,6 +1464,68 @@ public class LeAudioServiceTest { .isEqualTo(intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)); } /** Test setting active devices from the same group */ @Test public void testSetActiveDevicesFromSameGroup() { int groupId = 1; /* AUDIO_DIRECTION_OUTPUT_BIT = 0x01 */ /* AUDIO_DIRECTION_INPUT_BIT = 0x02 */ int direction = 3; int snkAudioLocation = 3; int srcAudioLocation = 4; int availableContexts = 5 + BluetoothLeAudio.CONTEXT_TYPE_RINGTONE; ArgumentCaptor<BluetoothProfileConnectionInfo> connectionInfoArgumentCaptor = ArgumentCaptor.forClass(BluetoothProfileConnectionInfo.class); // Not connected device assertThat(mService.setActiveDevice(mSingleDevice)).isFalse(); // Connected device doReturn(true).when(mNativeInterface).connectLeAudio(any(BluetoothDevice.class)); connectTestDevice(mLeftDevice, groupId); connectTestDevice(mRightDevice, groupId); // Add location support LeAudioStackEvent audioConfChangedEvent = new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_AUDIO_CONF_CHANGED); audioConfChangedEvent.device = mSingleDevice; audioConfChangedEvent.valueInt1 = direction; audioConfChangedEvent.valueInt2 = groupId; audioConfChangedEvent.valueInt3 = snkAudioLocation; audioConfChangedEvent.valueInt4 = srcAudioLocation; audioConfChangedEvent.valueInt5 = availableContexts; mService.messageFromNative(audioConfChangedEvent); assertThat(mService.setActiveDevice(mLeftDevice)).isTrue(); verify(mNativeInterface).groupSetActive(groupId); // Set group and device as active LeAudioStackEvent groupStatusChangedEvent = new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_GROUP_STATUS_CHANGED); groupStatusChangedEvent.valueInt1 = groupId; groupStatusChangedEvent.valueInt2 = LeAudioStackEvent.GROUP_STATUS_ACTIVE; mService.messageFromNative(groupStatusChangedEvent); verify(mAudioManager, times(2)) .handleBluetoothActiveDeviceChanged( eq(mLeftDevice), eq(null), connectionInfoArgumentCaptor.capture()); List<BluetoothProfileConnectionInfo> connInfos = connectionInfoArgumentCaptor.getAllValues(); assertThat(connInfos.size()).isEqualTo(2); assertThat(connInfos.get(0).isLeOutput()).isEqualTo(true); assertThat(connInfos.get(1).isLeOutput()).isEqualTo(false); reset(mAudioManager); assertThat(mService.setActiveDevice(mRightDevice)).isTrue(); verify(mAudioManager, times(0)) .handleBluetoothActiveDeviceChanged( any(), any(), any(BluetoothProfileConnectionInfo.class)); connInfos = connectionInfoArgumentCaptor.getAllValues(); assertThat(connInfos.size()).isEqualTo(2); } /** Test setting active device group with not available contexts */ @Test public void testSetActiveDeviceGroupWithNoContextTypes() { Loading Loading
android/app/src/com/android/bluetooth/le_audio/LeAudioService.java +33 −16 Original line number Diff line number Diff line Loading @@ -1677,9 +1677,10 @@ public class LeAudioService extends ProfileService { } if (device != null && mActiveAudioInDevice != null) { LeAudioDeviceDescriptor deviceDescriptor = getDeviceDescriptor(device); LeAudioDeviceDescriptor deviceDescriptor = getDeviceDescriptor(mActiveAudioInDevice); if (deviceDescriptor == null) { Log.e(TAG, "updateActiveInDevice: No valid descriptor for device: " + device); Log.e(TAG, "updateActiveInDevice: No valid descriptor for device: " + mActiveAudioInDevice); return false; } Loading Loading @@ -1744,9 +1745,10 @@ public class LeAudioService extends ProfileService { } if (device != null && mActiveAudioOutDevice != null) { LeAudioDeviceDescriptor deviceDescriptor = getDeviceDescriptor(device); LeAudioDeviceDescriptor deviceDescriptor = getDeviceDescriptor(mActiveAudioOutDevice); if (deviceDescriptor == null) { Log.e(TAG, "updateActiveOutDevice: No valid descriptor for device: " + device); Log.e(TAG, "updateActiveOutDevice: No valid descriptor for device: " + mActiveAudioOutDevice); return false; } Loading Loading @@ -2375,30 +2377,45 @@ public class LeAudioService extends ProfileService { + ", mExposedActiveDevice: " + mExposedActiveDevice); LeAudioGroupDescriptor groupDescriptor = getGroupDescriptor(currentlyActiveGroupId); if (isBroadcastActive() && currentlyActiveGroupId == LE_AUDIO_GROUP_ID_INVALID && mUnicastGroupIdDeactivatedForBroadcastTransition != LE_AUDIO_GROUP_ID_INVALID) { LeAudioGroupDescriptor fallbackGroupDescriptor = getGroupDescriptor(groupId); // If broadcast is ongoing and need to update unicast fallback active group // we need to update the cached group id and skip changing the active device updateFallbackUnicastGroupIdForBroadcast(groupId); if (fallbackGroupDescriptor != null) { if (groupId == LE_AUDIO_GROUP_ID_INVALID) { /* In case of removing fallback unicast group, monitoring input device should be * removed from active devices. */ if (groupDescriptor != null && groupId == LE_AUDIO_GROUP_ID_INVALID) { updateActiveDevices( groupId, groupDescriptor.mDirection, fallbackGroupDescriptor.mDirection, AUDIO_DIRECTION_NONE, false, groupDescriptor.mHasFallbackDeviceWhenGettingInactive, fallbackGroupDescriptor.mHasFallbackDeviceWhenGettingInactive, false); } else { if (mActiveAudioInDevice != null) { updateActiveDevices( groupId, fallbackGroupDescriptor.mDirection, AUDIO_DIRECTION_INPUT_BIT, false, fallbackGroupDescriptor.mHasFallbackDeviceWhenGettingInactive, true); } } } return true; } LeAudioGroupDescriptor groupDescriptor = getGroupDescriptor(currentlyActiveGroupId); if (groupDescriptor != null && groupId == currentlyActiveGroupId) { /* Make sure active group is already exposed to audio framework. * If not, lets wait for it and don't sent additional intent. Loading
android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBroadcastServiceTest.java +59 −20 Original line number Diff line number Diff line Loading @@ -56,6 +56,7 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.Spy; Loading @@ -76,6 +77,7 @@ public class LeAudioBroadcastServiceTest { private BluetoothAdapter mAdapter; private BluetoothDevice mDevice; private BluetoothDevice mDevice2; private BluetoothDevice mBroadcastDevice; private Context mTargetContext; Loading Loading @@ -234,6 +236,7 @@ public class LeAudioBroadcastServiceTest { mTargetContext.registerReceiver(mLeAudioIntentReceiver, filter); mDevice = TestUtils.getTestDevice(mAdapter, 0); mDevice2 = TestUtils.getTestDevice(mAdapter, 1); mBroadcastDevice = TestUtils.getTestDevice(mAdapter, 1); when(mAdapterService.getDeviceFromByte(Utils.getBytesFromAddress("FF:FF:FF:FF:FF:FF"))) .thenReturn(mBroadcastDevice); Loading Loading @@ -534,7 +537,9 @@ public class LeAudioBroadcastServiceTest { public void testCreateBroadcast_updateQualityToStandard() { byte[] code = {0x00, 0x01, 0x00, 0x02}; int groupId = 1; prepareConnectedUnicastDevice(groupId); initializeNative(); prepareConnectedUnicastDevice(groupId, mDevice); synchronized (mService.mBroadcastCallbacks) { mService.mBroadcastCallbacks.register(mCallbacks); Loading Loading @@ -771,61 +776,61 @@ public class LeAudioBroadcastServiceTest { } } private void prepareConnectedUnicastDevice(int groupId) { int direction = 3; int snkAudioLocation = 3; int srcAudioLocation = 4; int availableContexts = 5 + BluetoothLeAudio.CONTEXT_TYPE_RINGTONE; /* Initialize native */ private void initializeNative() { LeAudioStackEvent stackEvent = new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_NATIVE_INITIALIZED); mService.messageFromNative(stackEvent); Assert.assertTrue(mService.mLeAudioNativeIsInitialized); } private void prepareConnectedUnicastDevice(int groupId, BluetoothDevice device) { int direction = 3; int snkAudioLocation = 3; int srcAudioLocation = 4; int availableContexts = 5 + BluetoothLeAudio.CONTEXT_TYPE_RINGTONE; /* Prepare active group to cause pending broadcast */ doReturn(BluetoothDevice.BOND_BONDED) .when(mAdapterService) .getBondState(any(BluetoothDevice.class)); doReturn(true).when(mLeAudioNativeInterface).connectLeAudio(any(BluetoothDevice.class)); when(mDatabaseManager.getProfileConnectionPolicy(mDevice, BluetoothProfile.LE_AUDIO)) when(mDatabaseManager.getProfileConnectionPolicy(device, BluetoothProfile.LE_AUDIO)) .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED); doReturn(new ParcelUuid[] {BluetoothUuid.LE_AUDIO}) .when(mAdapterService) .getRemoteUuids(any(BluetoothDevice.class)); Assert.assertTrue(mService.connect(mDevice)); Assert.assertTrue(mService.connect(device)); // Verify the connection state broadcast, and that we are in Connected state verifyConnectionStateIntent( TIMEOUT_MS, mDevice, device, BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED); Assert.assertEquals( BluetoothProfile.STATE_CONNECTING, mService.getConnectionState(mDevice)); Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, mService.getConnectionState(device)); LeAudioStackEvent create_event = new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED); create_event.device = mDevice; create_event.device = device; create_event.valueInt1 = LeAudioStackEvent.CONNECTION_STATE_CONNECTED; mService.messageFromNative(create_event); verifyConnectionStateIntent( TIMEOUT_MS, mDevice, device, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_CONNECTING); Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDevice)); Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(device)); create_event = new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_GROUP_NODE_STATUS_CHANGED); create_event.device = mDevice; create_event.device = device; create_event.valueInt1 = groupId; create_event.valueInt2 = LeAudioStackEvent.GROUP_NODE_ADDED; mService.messageFromNative(create_event); create_event = new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_AUDIO_CONF_CHANGED); create_event.device = mDevice; create_event.device = device; create_event.valueInt1 = direction; create_event.valueInt2 = groupId; create_event.valueInt3 = snkAudioLocation; Loading @@ -848,7 +853,8 @@ public class LeAudioBroadcastServiceTest { mSetFlagsRule.enableFlags(Flags.FLAG_AUDIO_ROUTING_CENTRALIZATION); mSetFlagsRule.enableFlags(Flags.FLAG_LEAUDIO_BIG_DEPENDS_ON_AUDIO_STATE); prepareConnectedUnicastDevice(groupId); initializeNative(); prepareConnectedUnicastDevice(groupId, mDevice); LeAudioStackEvent stackEvent = new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_GROUP_STATUS_CHANGED); Loading Loading @@ -953,7 +959,8 @@ public class LeAudioBroadcastServiceTest { mService.mBroadcastCallbacks.register(mCallbacks); } prepareConnectedUnicastDevice(groupId); initializeNative(); prepareConnectedUnicastDevice(groupId, mDevice); LeAudioStackEvent create_event = new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_GROUP_STATUS_CHANGED); Loading Loading @@ -1490,6 +1497,38 @@ public class LeAudioBroadcastServiceTest { verify(mBassClientService, times(1)).resumeReceiversSourceSynchronization(); } @Test public void testUpdateFallbackInputDevice() { mSetFlagsRule.disableFlags(Flags.FLAG_LEAUDIO_USE_AUDIO_MODE_LISTENER); int groupId = 1; int groupId2 = 2; int broadcastId = 243; byte[] code = {0x00, 0x01, 0x00, 0x02}; initializeNative(); prepareConnectedUnicastDevice(groupId2, mDevice2); prepareHandoverStreamingBroadcast(groupId, broadcastId, code); Assert.assertEquals(mService.mUnicastGroupIdDeactivatedForBroadcastTransition, groupId); reset(mAudioManager); /* Update fallback active device (only input is active) */ ArgumentCaptor<BluetoothProfileConnectionInfo> connectionInfoArgumentCaptor = ArgumentCaptor.forClass(BluetoothProfileConnectionInfo.class); Assert.assertTrue(mService.setActiveDevice(mDevice2)); verify(mAudioManager, times(1)) .handleBluetoothActiveDeviceChanged( eq(mDevice2), eq(mDevice), connectionInfoArgumentCaptor.capture()); List<BluetoothProfileConnectionInfo> connInfos = connectionInfoArgumentCaptor.getAllValues(); Assert.assertEquals(connInfos.size(), 1); Assert.assertFalse(connInfos.get(0).isLeOutput()); Assert.assertEquals(mService.mUnicastGroupIdDeactivatedForBroadcastTransition, groupId2); } private class LeAudioIntentReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Loading
android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioServiceTest.java +62 −0 Original line number Diff line number Diff line Loading @@ -1464,6 +1464,68 @@ public class LeAudioServiceTest { .isEqualTo(intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)); } /** Test setting active devices from the same group */ @Test public void testSetActiveDevicesFromSameGroup() { int groupId = 1; /* AUDIO_DIRECTION_OUTPUT_BIT = 0x01 */ /* AUDIO_DIRECTION_INPUT_BIT = 0x02 */ int direction = 3; int snkAudioLocation = 3; int srcAudioLocation = 4; int availableContexts = 5 + BluetoothLeAudio.CONTEXT_TYPE_RINGTONE; ArgumentCaptor<BluetoothProfileConnectionInfo> connectionInfoArgumentCaptor = ArgumentCaptor.forClass(BluetoothProfileConnectionInfo.class); // Not connected device assertThat(mService.setActiveDevice(mSingleDevice)).isFalse(); // Connected device doReturn(true).when(mNativeInterface).connectLeAudio(any(BluetoothDevice.class)); connectTestDevice(mLeftDevice, groupId); connectTestDevice(mRightDevice, groupId); // Add location support LeAudioStackEvent audioConfChangedEvent = new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_AUDIO_CONF_CHANGED); audioConfChangedEvent.device = mSingleDevice; audioConfChangedEvent.valueInt1 = direction; audioConfChangedEvent.valueInt2 = groupId; audioConfChangedEvent.valueInt3 = snkAudioLocation; audioConfChangedEvent.valueInt4 = srcAudioLocation; audioConfChangedEvent.valueInt5 = availableContexts; mService.messageFromNative(audioConfChangedEvent); assertThat(mService.setActiveDevice(mLeftDevice)).isTrue(); verify(mNativeInterface).groupSetActive(groupId); // Set group and device as active LeAudioStackEvent groupStatusChangedEvent = new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_GROUP_STATUS_CHANGED); groupStatusChangedEvent.valueInt1 = groupId; groupStatusChangedEvent.valueInt2 = LeAudioStackEvent.GROUP_STATUS_ACTIVE; mService.messageFromNative(groupStatusChangedEvent); verify(mAudioManager, times(2)) .handleBluetoothActiveDeviceChanged( eq(mLeftDevice), eq(null), connectionInfoArgumentCaptor.capture()); List<BluetoothProfileConnectionInfo> connInfos = connectionInfoArgumentCaptor.getAllValues(); assertThat(connInfos.size()).isEqualTo(2); assertThat(connInfos.get(0).isLeOutput()).isEqualTo(true); assertThat(connInfos.get(1).isLeOutput()).isEqualTo(false); reset(mAudioManager); assertThat(mService.setActiveDevice(mRightDevice)).isTrue(); verify(mAudioManager, times(0)) .handleBluetoothActiveDeviceChanged( any(), any(), any(BluetoothProfileConnectionInfo.class)); connInfos = connectionInfoArgumentCaptor.getAllValues(); assertThat(connInfos.size()).isEqualTo(2); } /** Test setting active device group with not available contexts */ @Test public void testSetActiveDeviceGroupWithNoContextTypes() { Loading