Loading android/app/src/com/android/bluetooth/le_audio/LeAudioService.java +19 −7 Original line number Diff line number Diff line Loading @@ -1212,6 +1212,14 @@ public class LeAudioService extends ProfileService { this, intent, BLUETOOTH_CONNECT, Utils.getTempAllowlistBroadcastOptions()); } void sentActiveDeviceChangeIntent(BluetoothDevice device) { Intent intent = new Intent(BluetoothLeAudio.ACTION_LE_AUDIO_ACTIVE_DEVICE_CHANGED); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); intent.addFlags( Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); sendBroadcast(intent, BLUETOOTH_CONNECT); } /** * Send broadcast intent about LeAudio active device. * This is called when AudioManager confirms, LeAudio device Loading @@ -1225,11 +1233,8 @@ public class LeAudioService extends ProfileService { } mAdapterService.handleActiveDeviceChange(BluetoothProfile.LE_AUDIO, device); Intent intent = new Intent(BluetoothLeAudio.ACTION_LE_AUDIO_ACTIVE_DEVICE_CHANGED); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); sendBroadcast(intent, BLUETOOTH_CONNECT); sentActiveDeviceChangeIntent(device); mExposedActiveDevice = device; } boolean isScannerNeeded() { Loading Loading @@ -1330,7 +1335,6 @@ public class LeAudioService extends ProfileService { continue; } mExposedActiveDevice = device; notifyActiveDeviceChanged(device); return; } Loading Loading @@ -1487,7 +1491,15 @@ public class LeAudioService extends ProfileService { if (groupId == currentlyActiveGroupId) { if (groupId != LE_AUDIO_GROUP_ID_INVALID) { Log.w(TAG, "group is already active: device=" + device + ", groupId = " + groupId); Log.w( TAG, "group is already active: device=" + device + ", groupId = " + groupId + ", exposedDevice: " + mExposedActiveDevice); sentActiveDeviceChangeIntent(mExposedActiveDevice); } return; } Loading android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioServiceTest.java +65 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; Loading Loading @@ -1109,6 +1110,70 @@ public class LeAudioServiceTest { verify(mTbsService).clearInbandRingtoneSupport(mSingleDevice); } /** Test setting active device group for already active group */ @Test public void testSetActiveDeviceGroupTwice() { int groupId = 1; /* AUDIO_DIRECTION_OUTPUT_BIT = 0x01 */ int direction = 1; int snkAudioLocation = 3; int srcAudioLocation = 4; int availableContexts = 5 + BluetoothLeAudio.CONTEXT_TYPE_RINGTONE; // Not connected device assertThat(mService.setActiveDevice(mSingleDevice)).isFalse(); // Connected device doReturn(true).when(mNativeInterface).connectLeAudio(any(BluetoothDevice.class)); connectTestDevice(mSingleDevice, testGroupId); // 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(mSingleDevice)).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(mTbsService).setInbandRingtoneSupport(mSingleDevice); /* Expect 2 calles to Audio Manager - one for output as this is * Ringtone use case */ verify(mAudioManager, times(1)) .handleBluetoothActiveDeviceChanged( any(), any(), any(BluetoothProfileConnectionInfo.class)); /* Since LeAudioService called AudioManager - assume Audio manager calles properly callback * mAudioManager.onAudioDeviceAdded */ mService.notifyActiveDeviceChanged(mSingleDevice); reset(mNativeInterface); // set active device again assertThat(mService.setActiveDevice(mSingleDevice)).isTrue(); verify(mNativeInterface, times(0)).groupSetActive(groupId); String action = BluetoothLeAudio.ACTION_LE_AUDIO_ACTIVE_DEVICE_CHANGED; Intent intent = TestUtils.waitForIntent(TIMEOUT_MS, mDeviceQueueMap.get(mSingleDevice)); assertThat(intent).isNotNull(); assertThat(action).isEqualTo(intent.getAction()); assertThat(mSingleDevice) .isEqualTo(intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)); } /** * Test setting active device group without Ringtone context */ Loading Loading
android/app/src/com/android/bluetooth/le_audio/LeAudioService.java +19 −7 Original line number Diff line number Diff line Loading @@ -1212,6 +1212,14 @@ public class LeAudioService extends ProfileService { this, intent, BLUETOOTH_CONNECT, Utils.getTempAllowlistBroadcastOptions()); } void sentActiveDeviceChangeIntent(BluetoothDevice device) { Intent intent = new Intent(BluetoothLeAudio.ACTION_LE_AUDIO_ACTIVE_DEVICE_CHANGED); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); intent.addFlags( Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); sendBroadcast(intent, BLUETOOTH_CONNECT); } /** * Send broadcast intent about LeAudio active device. * This is called when AudioManager confirms, LeAudio device Loading @@ -1225,11 +1233,8 @@ public class LeAudioService extends ProfileService { } mAdapterService.handleActiveDeviceChange(BluetoothProfile.LE_AUDIO, device); Intent intent = new Intent(BluetoothLeAudio.ACTION_LE_AUDIO_ACTIVE_DEVICE_CHANGED); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); sendBroadcast(intent, BLUETOOTH_CONNECT); sentActiveDeviceChangeIntent(device); mExposedActiveDevice = device; } boolean isScannerNeeded() { Loading Loading @@ -1330,7 +1335,6 @@ public class LeAudioService extends ProfileService { continue; } mExposedActiveDevice = device; notifyActiveDeviceChanged(device); return; } Loading Loading @@ -1487,7 +1491,15 @@ public class LeAudioService extends ProfileService { if (groupId == currentlyActiveGroupId) { if (groupId != LE_AUDIO_GROUP_ID_INVALID) { Log.w(TAG, "group is already active: device=" + device + ", groupId = " + groupId); Log.w( TAG, "group is already active: device=" + device + ", groupId = " + groupId + ", exposedDevice: " + mExposedActiveDevice); sentActiveDeviceChangeIntent(mExposedActiveDevice); } return; } Loading
android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioServiceTest.java +65 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; Loading Loading @@ -1109,6 +1110,70 @@ public class LeAudioServiceTest { verify(mTbsService).clearInbandRingtoneSupport(mSingleDevice); } /** Test setting active device group for already active group */ @Test public void testSetActiveDeviceGroupTwice() { int groupId = 1; /* AUDIO_DIRECTION_OUTPUT_BIT = 0x01 */ int direction = 1; int snkAudioLocation = 3; int srcAudioLocation = 4; int availableContexts = 5 + BluetoothLeAudio.CONTEXT_TYPE_RINGTONE; // Not connected device assertThat(mService.setActiveDevice(mSingleDevice)).isFalse(); // Connected device doReturn(true).when(mNativeInterface).connectLeAudio(any(BluetoothDevice.class)); connectTestDevice(mSingleDevice, testGroupId); // 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(mSingleDevice)).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(mTbsService).setInbandRingtoneSupport(mSingleDevice); /* Expect 2 calles to Audio Manager - one for output as this is * Ringtone use case */ verify(mAudioManager, times(1)) .handleBluetoothActiveDeviceChanged( any(), any(), any(BluetoothProfileConnectionInfo.class)); /* Since LeAudioService called AudioManager - assume Audio manager calles properly callback * mAudioManager.onAudioDeviceAdded */ mService.notifyActiveDeviceChanged(mSingleDevice); reset(mNativeInterface); // set active device again assertThat(mService.setActiveDevice(mSingleDevice)).isTrue(); verify(mNativeInterface, times(0)).groupSetActive(groupId); String action = BluetoothLeAudio.ACTION_LE_AUDIO_ACTIVE_DEVICE_CHANGED; Intent intent = TestUtils.waitForIntent(TIMEOUT_MS, mDeviceQueueMap.get(mSingleDevice)); assertThat(intent).isNotNull(); assertThat(action).isEqualTo(intent.getAction()); assertThat(mSingleDevice) .isEqualTo(intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)); } /** * Test setting active device group without Ringtone context */ Loading