Loading android/app/src/com/android/bluetooth/le_audio/LeAudioService.java +37 −6 Original line number Diff line number Diff line Loading @@ -2205,7 +2205,7 @@ public class LeAudioService extends ProfileService { + groupId + " is inactivated due to blocked media context"); groupDescriptor.mInactivatedDueToContextType = true; setActiveGroupWithDevice(null, true); setActiveGroupWithDevice(null, false); } } default: Loading Loading @@ -2729,16 +2729,45 @@ public class LeAudioService extends ProfileService { BluetoothLeAudio.GROUP_STATUS_INACTIVE); } } boolean availableContextChanged = Integer.bitCount(descriptor.mAvailableContexts) != Integer.bitCount(available_contexts); descriptor.mDirection = direction; descriptor.mAvailableContexts = available_contexts; updateInbandRingtoneForTheGroup(groupId); boolean mediaIsAvailable = ((descriptor.mAvailableContexts & BluetoothLeAudio.CONTEXT_TYPE_MEDIA) != 0); if (!availableContextChanged) { Log.d( TAG, " Context did not changed for " + groupId + ": " + descriptor.mAvailableContexts); return; } if (descriptor.mInactivatedDueToContextType && mediaIsAvailable) { Log.i(TAG, " Media context type again available for " + groupId); if (descriptor.mAvailableContexts == 0) { if (descriptor.mIsActive) { Log.i( TAG, " Inactivating group " + groupId + " due to unavailable context types"); descriptor.mInactivatedDueToContextType = true; setActiveGroupWithDevice(null, false); } return; } if (descriptor.mInactivatedDueToContextType) { Log.i( TAG, " Some context got available again for " + groupId + ", try it out: " + descriptor.mAvailableContexts); descriptor.mInactivatedDueToContextType = false; setActiveGroupWithDevice(getLeadDeviceForTheGroup(groupId), true); } } else { Loading Loading @@ -3236,6 +3265,7 @@ public class LeAudioService extends ProfileService { if (getConnectedPeerDevices(groupId).isEmpty()) { descriptor.mIsConnected = false; descriptor.mInactivatedDueToContextType = false; if (descriptor.mIsActive) { /* Notify Native layer */ removeActiveDevice(hasFallbackDevice); Loading Loading @@ -3316,6 +3346,7 @@ public class LeAudioService extends ProfileService { if (getConnectedPeerDevices(deviceDescriptor.mGroupId).isEmpty()) { descriptor.mIsConnected = false; descriptor.mInactivatedDueToContextType = false; if (descriptor.mIsActive) { /* Notify Native layer */ removeActiveDevice(hasFallbackDevice); Loading android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioServiceTest.java +83 −2 Original line number Diff line number Diff line Loading @@ -2495,4 +2495,85 @@ public class LeAudioServiceTest { assertThat(mService.getActiveDevices().contains(mSingleDevice)).isTrue(); assertThat(mService.sendPreferredAudioProfileChangeToAudioFramework()).isEqualTo(2); } @Test public void testInactivateDeviceWhenNoAvailableContextTypes() { int groupId = 1; /* AUDIO_DIRECTION_OUTPUT_BIT = 0x01 */ int direction = 1; int snkAudioLocation = 3; int srcAudioLocation = 4; int availableContexts = 5 + BluetoothLeAudio.CONTEXT_TYPE_RINGTONE; doReturn(true).when(mNativeInterface).connectLeAudio(any(BluetoothDevice.class)); connectTestDevice(mLeftDevice, groupId); connectTestDevice(mRightDevice, groupId); // Checks group device lists for groupId 1 List<BluetoothDevice> groupDevicesById = mService.getGroupDevices(groupId); assertThat(groupDevicesById.size()).isEqualTo(2); assertThat(groupDevicesById.contains(mLeftDevice)).isTrue(); assertThat(groupDevicesById.contains(mRightDevice)).isTrue(); // Add location support LeAudioStackEvent audioConfChangedEvent = new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_AUDIO_CONF_CHANGED); 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. injectGroupStatusChange(groupId, LeAudioStackEvent.GROUP_STATUS_ACTIVE); verify(mAudioManager, times(1)) .handleBluetoothActiveDeviceChanged( any(BluetoothDevice.class), eq(null), any(BluetoothProfileConnectionInfo.class)); reset(mAudioManager); reset(mNativeInterface); /* Don't expect any change. */ mService.messageFromNative(audioConfChangedEvent); verify(mNativeInterface, times(0)).groupSetActive(groupId); reset(mNativeInterface); /* Expect device to be incactive */ audioConfChangedEvent.valueInt5 = 0; mService.messageFromNative(audioConfChangedEvent); verify(mNativeInterface, times(1)).groupSetActive(-1); injectGroupStatusChange(groupId, LeAudioStackEvent.GROUP_STATUS_INACTIVE); verify(mAudioManager, times(1)) .handleBluetoothActiveDeviceChanged( eq(null), any(BluetoothDevice.class), any(BluetoothProfileConnectionInfo.class)); reset(mNativeInterface); reset(mAudioManager); /* Expect device to be incactive */ audioConfChangedEvent.valueInt5 = 1; mService.messageFromNative(audioConfChangedEvent); verify(mNativeInterface).groupSetActive(groupId); reset(mNativeInterface); // Set group and device as active. injectGroupStatusChange(groupId, LeAudioStackEvent.GROUP_STATUS_ACTIVE); verify(mAudioManager, times(1)) .handleBluetoothActiveDeviceChanged( any(BluetoothDevice.class), eq(null), any(BluetoothProfileConnectionInfo.class)); } } Loading
android/app/src/com/android/bluetooth/le_audio/LeAudioService.java +37 −6 Original line number Diff line number Diff line Loading @@ -2205,7 +2205,7 @@ public class LeAudioService extends ProfileService { + groupId + " is inactivated due to blocked media context"); groupDescriptor.mInactivatedDueToContextType = true; setActiveGroupWithDevice(null, true); setActiveGroupWithDevice(null, false); } } default: Loading Loading @@ -2729,16 +2729,45 @@ public class LeAudioService extends ProfileService { BluetoothLeAudio.GROUP_STATUS_INACTIVE); } } boolean availableContextChanged = Integer.bitCount(descriptor.mAvailableContexts) != Integer.bitCount(available_contexts); descriptor.mDirection = direction; descriptor.mAvailableContexts = available_contexts; updateInbandRingtoneForTheGroup(groupId); boolean mediaIsAvailable = ((descriptor.mAvailableContexts & BluetoothLeAudio.CONTEXT_TYPE_MEDIA) != 0); if (!availableContextChanged) { Log.d( TAG, " Context did not changed for " + groupId + ": " + descriptor.mAvailableContexts); return; } if (descriptor.mInactivatedDueToContextType && mediaIsAvailable) { Log.i(TAG, " Media context type again available for " + groupId); if (descriptor.mAvailableContexts == 0) { if (descriptor.mIsActive) { Log.i( TAG, " Inactivating group " + groupId + " due to unavailable context types"); descriptor.mInactivatedDueToContextType = true; setActiveGroupWithDevice(null, false); } return; } if (descriptor.mInactivatedDueToContextType) { Log.i( TAG, " Some context got available again for " + groupId + ", try it out: " + descriptor.mAvailableContexts); descriptor.mInactivatedDueToContextType = false; setActiveGroupWithDevice(getLeadDeviceForTheGroup(groupId), true); } } else { Loading Loading @@ -3236,6 +3265,7 @@ public class LeAudioService extends ProfileService { if (getConnectedPeerDevices(groupId).isEmpty()) { descriptor.mIsConnected = false; descriptor.mInactivatedDueToContextType = false; if (descriptor.mIsActive) { /* Notify Native layer */ removeActiveDevice(hasFallbackDevice); Loading Loading @@ -3316,6 +3346,7 @@ public class LeAudioService extends ProfileService { if (getConnectedPeerDevices(deviceDescriptor.mGroupId).isEmpty()) { descriptor.mIsConnected = false; descriptor.mInactivatedDueToContextType = false; if (descriptor.mIsActive) { /* Notify Native layer */ removeActiveDevice(hasFallbackDevice); Loading
android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioServiceTest.java +83 −2 Original line number Diff line number Diff line Loading @@ -2495,4 +2495,85 @@ public class LeAudioServiceTest { assertThat(mService.getActiveDevices().contains(mSingleDevice)).isTrue(); assertThat(mService.sendPreferredAudioProfileChangeToAudioFramework()).isEqualTo(2); } @Test public void testInactivateDeviceWhenNoAvailableContextTypes() { int groupId = 1; /* AUDIO_DIRECTION_OUTPUT_BIT = 0x01 */ int direction = 1; int snkAudioLocation = 3; int srcAudioLocation = 4; int availableContexts = 5 + BluetoothLeAudio.CONTEXT_TYPE_RINGTONE; doReturn(true).when(mNativeInterface).connectLeAudio(any(BluetoothDevice.class)); connectTestDevice(mLeftDevice, groupId); connectTestDevice(mRightDevice, groupId); // Checks group device lists for groupId 1 List<BluetoothDevice> groupDevicesById = mService.getGroupDevices(groupId); assertThat(groupDevicesById.size()).isEqualTo(2); assertThat(groupDevicesById.contains(mLeftDevice)).isTrue(); assertThat(groupDevicesById.contains(mRightDevice)).isTrue(); // Add location support LeAudioStackEvent audioConfChangedEvent = new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_AUDIO_CONF_CHANGED); 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. injectGroupStatusChange(groupId, LeAudioStackEvent.GROUP_STATUS_ACTIVE); verify(mAudioManager, times(1)) .handleBluetoothActiveDeviceChanged( any(BluetoothDevice.class), eq(null), any(BluetoothProfileConnectionInfo.class)); reset(mAudioManager); reset(mNativeInterface); /* Don't expect any change. */ mService.messageFromNative(audioConfChangedEvent); verify(mNativeInterface, times(0)).groupSetActive(groupId); reset(mNativeInterface); /* Expect device to be incactive */ audioConfChangedEvent.valueInt5 = 0; mService.messageFromNative(audioConfChangedEvent); verify(mNativeInterface, times(1)).groupSetActive(-1); injectGroupStatusChange(groupId, LeAudioStackEvent.GROUP_STATUS_INACTIVE); verify(mAudioManager, times(1)) .handleBluetoothActiveDeviceChanged( eq(null), any(BluetoothDevice.class), any(BluetoothProfileConnectionInfo.class)); reset(mNativeInterface); reset(mAudioManager); /* Expect device to be incactive */ audioConfChangedEvent.valueInt5 = 1; mService.messageFromNative(audioConfChangedEvent); verify(mNativeInterface).groupSetActive(groupId); reset(mNativeInterface); // Set group and device as active. injectGroupStatusChange(groupId, LeAudioStackEvent.GROUP_STATUS_ACTIVE); verify(mAudioManager, times(1)) .handleBluetoothActiveDeviceChanged( any(BluetoothDevice.class), eq(null), any(BluetoothProfileConnectionInfo.class)); } }