diff options
4 files changed, 88 insertions, 0 deletions
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java index 245fe6edd601..d39468b2adaf 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java @@ -1788,4 +1788,40 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> boolean getUnpairing() { return mUnpairing; } + + ListenableFuture<Void> syncProfileForMemberDevice() { + return ThreadUtils.getBackgroundExecutor() + .submit( + () -> { + List<Pair<LocalBluetoothProfile, Boolean>> toSync = + Stream.of( + mProfileManager.getA2dpProfile(), + mProfileManager.getHeadsetProfile(), + mProfileManager.getHearingAidProfile(), + mProfileManager.getLeAudioProfile(), + mProfileManager.getLeAudioBroadcastAssistantProfile()) + .filter(Objects::nonNull) + .map(profile -> new Pair<>(profile, profile.isEnabled(mDevice))) + .toList(); + + for (var t : toSync) { + LocalBluetoothProfile profile = t.first; + boolean enabledForMain = t.second; + + for (var member : mMemberDevices) { + BluetoothDevice btDevice = member.getDevice(); + + if (enabledForMain != profile.isEnabled(btDevice)) { + Log.d(TAG, "Syncing profile " + profile + " to " + + enabledForMain + " for member device " + + btDevice.getAnonymizedAddress() + " of main device " + + mDevice.getAnonymizedAddress()); + profile.setEnabled(btDevice, enabledForMain); + } + } + } + return null; + } + ); + } } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java index a6536a8c47d9..89fe268b3258 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java @@ -349,6 +349,7 @@ public class CachedBluetoothDeviceManager { if (profileId == BluetoothProfile.HEADSET || profileId == BluetoothProfile.A2DP || profileId == BluetoothProfile.LE_AUDIO + || profileId == BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT || profileId == BluetoothProfile.CSIP_SET_COORDINATOR) { return mCsipDeviceManager.onProfileConnectionStateChangedIfProcessed(cachedDevice, state); diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CsipDeviceManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CsipDeviceManager.java index a49314aae1b3..e67ec48d3401 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CsipDeviceManager.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CsipDeviceManager.java @@ -379,6 +379,7 @@ public class CsipDeviceManager { if (hasChanged) { log("addMemberDevicesIntoMainDevice: After changed, CachedBluetoothDevice list: " + mCachedDevices); + preferredMainDevice.syncProfileForMemberDevice(); } return hasChanged; } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java index ed545ab5c81d..9db8b47e9644 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java @@ -18,7 +18,9 @@ package com.android.settingslib.bluetooth; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; @@ -56,6 +58,8 @@ import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import org.robolectric.shadow.api.Shadow; +import java.util.concurrent.ExecutionException; + @RunWith(RobolectricTestRunner.class) @Config(shadows = {ShadowBluetoothAdapter.class}) public class CachedBluetoothDeviceTest { @@ -1815,6 +1819,52 @@ public class CachedBluetoothDeviceTest { assertThat(mCachedDevice.isConnectedHearingAidDevice()).isFalse(); } + @Test + public void syncProfileForMemberDevice_hasDiff_shouldSync() + throws ExecutionException, InterruptedException { + mCachedDevice.addMemberDevice(mSubCachedDevice); + when(mProfileManager.getA2dpProfile()).thenReturn(mA2dpProfile); + when(mProfileManager.getHearingAidProfile()).thenReturn(mHearingAidProfile); + when(mProfileManager.getLeAudioProfile()).thenReturn(mLeAudioProfile); + + when(mA2dpProfile.isEnabled(mDevice)).thenReturn(true); + when(mHearingAidProfile.isEnabled(mDevice)).thenReturn(true); + when(mLeAudioProfile.isEnabled(mDevice)).thenReturn(true); + + when(mA2dpProfile.isEnabled(mSubDevice)).thenReturn(true); + when(mHearingAidProfile.isEnabled(mSubDevice)).thenReturn(false); + when(mLeAudioProfile.isEnabled(mSubDevice)).thenReturn(false); + + mCachedDevice.syncProfileForMemberDevice().get(); + + verify(mA2dpProfile, never()).setEnabled(any(BluetoothDevice.class), anyBoolean()); + verify(mHearingAidProfile).setEnabled(any(BluetoothDevice.class), eq(true)); + verify(mLeAudioProfile).setEnabled(any(BluetoothDevice.class), eq(true)); + } + + @Test + public void syncProfileForMemberDevice_noDiff_shouldNotSync() + throws ExecutionException, InterruptedException { + mCachedDevice.addMemberDevice(mSubCachedDevice); + when(mProfileManager.getA2dpProfile()).thenReturn(mA2dpProfile); + when(mProfileManager.getHearingAidProfile()).thenReturn(mHearingAidProfile); + when(mProfileManager.getLeAudioProfile()).thenReturn(mLeAudioProfile); + + when(mA2dpProfile.isEnabled(mDevice)).thenReturn(false); + when(mHearingAidProfile.isEnabled(mDevice)).thenReturn(false); + when(mLeAudioProfile.isEnabled(mDevice)).thenReturn(true); + + when(mA2dpProfile.isEnabled(mSubDevice)).thenReturn(false); + when(mHearingAidProfile.isEnabled(mSubDevice)).thenReturn(false); + when(mLeAudioProfile.isEnabled(mSubDevice)).thenReturn(true); + + mCachedDevice.syncProfileForMemberDevice().get(); + + verify(mA2dpProfile, never()).setEnabled(any(BluetoothDevice.class), anyBoolean()); + verify(mHearingAidProfile, never()).setEnabled(any(BluetoothDevice.class), anyBoolean()); + verify(mLeAudioProfile, never()).setEnabled(any(BluetoothDevice.class), anyBoolean()); + } + private HearingAidInfo getLeftAshaHearingAidInfo() { return new HearingAidInfo.Builder() .setAshaDeviceSide(HearingAidProfile.DeviceSide.SIDE_LEFT) |