Fix pair other ear button not hidden correctly for dual device

If the device is a dual device which supports both ASHA + LE Audio, it'll pair the other ear with CSIP and group it as a member device. If LE Audio is not enabled, the current logic will fail to recognize the other ear is already paired. Update the logic to well handling this situation.

Bug: 296646732
Test: atest BluetoothDetailsPairOtherControllerTest
Change-Id: Iba9655488203a242ad0e87764d6bf4df595e977d
This commit is contained in:
Angela Wang
2023-09-28 08:13:49 +00:00
parent 747d86fef5
commit 79c7623f1b
2 changed files with 74 additions and 102 deletions

View File

@@ -16,6 +16,7 @@
package com.android.settings.bluetooth; package com.android.settings.bluetooth;
import android.bluetooth.BluetoothDevice;
import android.content.Context; import android.content.Context;
import androidx.preference.PreferenceFragmentCompat; import androidx.preference.PreferenceFragmentCompat;
@@ -75,7 +76,6 @@ public class BluetoothDetailsPairOtherController extends BluetoothDetailsControl
protected void refresh() { protected void refresh() {
updateButtonPreferenceTitle(mPreference); updateButtonPreferenceTitle(mPreference);
setPreferencesVisibility(getButtonPreferenceVisibility(mCachedDevice)); setPreferencesVisibility(getButtonPreferenceVisibility(mCachedDevice));
} }
private void updateButtonPreferenceTitle(ButtonPreference preference) { private void updateButtonPreferenceTitle(ButtonPreference preference) {
@@ -97,7 +97,7 @@ public class BluetoothDetailsPairOtherController extends BluetoothDetailsControl
if (!cachedDevice.isConnectedHearingAidDevice()) { if (!cachedDevice.isConnectedHearingAidDevice()) {
return false; return false;
} }
return isBinauralMode(cachedDevice) && !isOtherSideConnected(cachedDevice); return isBinauralMode(cachedDevice) && !isOtherSideBonded(cachedDevice);
} }
private void launchPairingDetail() { private void launchPairingDetail() {
@@ -112,25 +112,16 @@ public class BluetoothDetailsPairOtherController extends BluetoothDetailsControl
return cachedDevice.getDeviceMode() == HearingAidInfo.DeviceMode.MODE_BINAURAL; return cachedDevice.getDeviceMode() == HearingAidInfo.DeviceMode.MODE_BINAURAL;
} }
private boolean isOtherSideConnected(CachedBluetoothDevice cachedDevice) { private boolean isOtherSideBonded(CachedBluetoothDevice cachedDevice) {
// Check sub device for ASHA hearing aid final CachedBluetoothDevice subDevice = cachedDevice.getSubDevice();
if (cachedDevice.isConnectedAshaHearingAidDevice()) { final boolean subDeviceBonded =
final CachedBluetoothDevice subDevice = cachedDevice.getSubDevice(); subDevice != null && subDevice.getBondState() == BluetoothDevice.BOND_BONDED;
if (subDevice != null && subDevice.isConnectedAshaHearingAidDevice()) {
return true;
}
}
// Check member device for LE audio hearing aid final Set<CachedBluetoothDevice> memberDevice = cachedDevice.getMemberDevice();
if (cachedDevice.isConnectedLeAudioHearingAidDevice()) { final boolean allMemberDevicesBonded =
final Set<CachedBluetoothDevice> memberDevices = cachedDevice.getMemberDevice(); !memberDevice.isEmpty() && memberDevice.stream().allMatch(
for (CachedBluetoothDevice memberDevice : memberDevices) { device -> device.getBondState() == BluetoothDevice.BOND_BONDED);
if (memberDevice.isConnectedLeAudioHearingAidDevice()) {
return true;
}
}
}
return false; return subDeviceBonded || allMemberDevicesBonded;
} }
} }

View File

@@ -20,6 +20,8 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import android.bluetooth.BluetoothDevice;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.applications.SpacePreference; import com.android.settings.applications.SpacePreference;
import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.settingslib.bluetooth.CachedBluetoothDevice;
@@ -65,7 +67,7 @@ public class BluetoothDetailsPairOtherControllerTest extends BluetoothDetailsCon
/** Test the pair other side button title during initialization. */ /** Test the pair other side button title during initialization. */
@Test @Test
public void init_leftSideDevice_pairRightSideButtonTitle() { public void init_deviceIsLeftSide_showPairRightSideTitle() {
when(mCachedDevice.getDeviceSide()).thenReturn(HearingAidInfo.DeviceSide.SIDE_LEFT); when(mCachedDevice.getDeviceSide()).thenReturn(HearingAidInfo.DeviceSide.SIDE_LEFT);
mController.init(mScreen); mController.init(mScreen);
@@ -76,7 +78,7 @@ public class BluetoothDetailsPairOtherControllerTest extends BluetoothDetailsCon
/** Test the pair other side button title during initialization. */ /** Test the pair other side button title during initialization. */
@Test @Test
public void init_rightSideDevice_pairLeftSideButtonTitle() { public void init_deviceIsRightSide_showPairLeftSideTitle() {
when(mCachedDevice.getDeviceSide()).thenReturn(HearingAidInfo.DeviceSide.SIDE_RIGHT); when(mCachedDevice.getDeviceSide()).thenReturn(HearingAidInfo.DeviceSide.SIDE_RIGHT);
mController.init(mScreen); mController.init(mScreen);
@@ -87,7 +89,7 @@ public class BluetoothDetailsPairOtherControllerTest extends BluetoothDetailsCon
/** Test the pair other side button visibility during initialization. */ /** Test the pair other side button visibility during initialization. */
@Test @Test
public void init_isNotConnectedHearingAidDevice_preferenceIsNotVisible() { public void init_deviceIsNotConnectedHearingAid_preferenceIsNotVisible() {
when(mCachedDevice.isConnectedHearingAidDevice()).thenReturn(false); when(mCachedDevice.isConnectedHearingAidDevice()).thenReturn(false);
mController.init(mScreen); mController.init(mScreen);
@@ -99,13 +101,13 @@ public class BluetoothDetailsPairOtherControllerTest extends BluetoothDetailsCon
/** /**
* Test if the controller is available. * Test if the controller is available.
* Conditions: * Conditions:
* 1. Hearing aids is not connected * 1. The device is not a connected hearing aid
* Expected result: * Expected result:
* The controller is not available. No need to show pair other side hint for * The controller is not available. No need to show pair other side hint for
* not connected device. * non-hearing aid device or not connected device.
*/ */
@Test @Test
public void isAvailable_isNotConnectedHearingAidDevice_notAvailable() { public void isAvailable_deviceIsNotConnectedHearingAid_notAvailable() {
when(mCachedDevice.isConnectedHearingAidDevice()).thenReturn(false); when(mCachedDevice.isConnectedHearingAidDevice()).thenReturn(false);
assertThat(mController.isAvailable()).isFalse(); assertThat(mController.isAvailable()).isFalse();
@@ -114,13 +116,13 @@ public class BluetoothDetailsPairOtherControllerTest extends BluetoothDetailsCon
/** /**
* Test if the controller is available. * Test if the controller is available.
* Conditions: * Conditions:
* 1. Monaural hearing aids * 1. Monaural hearing aid
* Expected result: * Expected result:
* The controller is not available. No need to show pair other side hint for * The controller is not available. No need to show pair other side hint for
* monaural device. * monaural device.
*/ */
@Test @Test
public void isAvailable_isConnectedHearingAidDevice_isMonaural_notAvailable() { public void isAvailable_deviceIsConnectedHearingAid_isMonaural_notAvailable() {
when(mCachedDevice.isConnectedHearingAidDevice()).thenReturn(true); when(mCachedDevice.isConnectedHearingAidDevice()).thenReturn(true);
when(mCachedDevice.getDeviceMode()).thenReturn(HearingAidInfo.DeviceMode.MODE_MONAURAL); when(mCachedDevice.getDeviceMode()).thenReturn(HearingAidInfo.DeviceMode.MODE_MONAURAL);
@@ -130,18 +132,17 @@ public class BluetoothDetailsPairOtherControllerTest extends BluetoothDetailsCon
/** /**
* Test if the controller is available. * Test if the controller is available.
* Conditions: * Conditions:
* 1. Binaural ASHA hearing aids * 1. Binaural hearing aids
* 2. Sub device is added * 2. Sub device is added
* 3. Sub device is connected * 3. Sub device is bonded
* Expected result: * Expected result:
* The controller is not available. Both sides are already paired and connected. * The controller is not available. Both sides are already paired.
*/ */
@Test @Test
public void isAvailable_ashaDevice_otherDeviceIsConnected_notAvailable() { public void isAvailable_deviceIsConnectedHearingAid_subDeviceIsBonded_notAvailable() {
when(mCachedDevice.isConnectedHearingAidDevice()).thenReturn(true); when(mCachedDevice.isConnectedHearingAidDevice()).thenReturn(true);
when(mCachedDevice.isConnectedAshaHearingAidDevice()).thenReturn(true);
when(mCachedDevice.getDeviceMode()).thenReturn(HearingAidInfo.DeviceMode.MODE_BINAURAL); when(mCachedDevice.getDeviceMode()).thenReturn(HearingAidInfo.DeviceMode.MODE_BINAURAL);
when(mSubCachedDevice.isConnectedAshaHearingAidDevice()).thenReturn(true); when(mSubCachedDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
when(mCachedDevice.getSubDevice()).thenReturn(mSubCachedDevice); when(mCachedDevice.getSubDevice()).thenReturn(mSubCachedDevice);
assertThat(mController.isAvailable()).isFalse(); assertThat(mController.isAvailable()).isFalse();
@@ -150,18 +151,17 @@ public class BluetoothDetailsPairOtherControllerTest extends BluetoothDetailsCon
/** /**
* Test if the controller is available. * Test if the controller is available.
* Conditions: * Conditions:
* 1. Binaural ASHA hearing aids * 1. Binaural hearing aids
* 2. Sub device is added * 2. Sub device is added
* 3. Sub device is not connected * 3. Sub device is not bonded
* Expected result: * Expected result:
* The controller is available. Need to show the hint to pair the other side. * The controller is available. Need to show the hint to pair the other side.
*/ */
@Test @Test
public void isAvailable_ashaDevice_otherDeviceIsNotConnected_available() { public void isAvailable_deviceIsConnectedHearingAid_subDeviceIsNotBonded_available() {
when(mCachedDevice.isConnectedHearingAidDevice()).thenReturn(true); when(mCachedDevice.isConnectedHearingAidDevice()).thenReturn(true);
when(mCachedDevice.isConnectedAshaHearingAidDevice()).thenReturn(true);
when(mCachedDevice.getDeviceMode()).thenReturn(HearingAidInfo.DeviceMode.MODE_BINAURAL); when(mCachedDevice.getDeviceMode()).thenReturn(HearingAidInfo.DeviceMode.MODE_BINAURAL);
when(mSubCachedDevice.isConnectedAshaHearingAidDevice()).thenReturn(false); when(mSubCachedDevice.getBondState()).thenReturn(BluetoothDevice.BOND_NONE);
when(mCachedDevice.getSubDevice()).thenReturn(mSubCachedDevice); when(mCachedDevice.getSubDevice()).thenReturn(mSubCachedDevice);
assertThat(mController.isAvailable()).isTrue(); assertThat(mController.isAvailable()).isTrue();
@@ -170,74 +170,55 @@ public class BluetoothDetailsPairOtherControllerTest extends BluetoothDetailsCon
/** /**
* Test if the controller is available. * Test if the controller is available.
* Conditions: * Conditions:
* 1. Binaural ASHA hearing aids * 1. Binaural hearing aids
* 2. No sub device added * 2. Member device is added
* 3. Member device is bonded
* Expected result:
* The controller is not available. Both sides are already paired.
*/
@Test
public void isAvailable_deviceIsConnectedHearingAid_memberDeviceIsBonded_notAvailable() {
when(mCachedDevice.isConnectedHearingAidDevice()).thenReturn(true);
when(mCachedDevice.getDeviceMode()).thenReturn(HearingAidInfo.DeviceMode.MODE_BINAURAL);
when(mSubCachedDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
when(mCachedDevice.getMemberDevice()).thenReturn(Set.of(mSubCachedDevice));
assertThat(mController.isAvailable()).isFalse();
}
/**
* Test if the controller is available.
* Conditions:
* 1. Binaural hearing aids
* 2. Member device is added
* 3. Member device is not bonded
* Expected result: * Expected result:
* The controller is available. Need to show the hint to pair the other side. * The controller is available. Need to show the hint to pair the other side.
*/ */
@Test @Test
public void isAvailable_ashaDevice_otherDeviceIsNotExist_available() { public void isAvailable_deviceIsConnectedHearingAid_memberDeviceIsNotBonded_available() {
when(mCachedDevice.isConnectedHearingAidDevice()).thenReturn(true);
when(mCachedDevice.getDeviceMode()).thenReturn(HearingAidInfo.DeviceMode.MODE_BINAURAL);
when(mSubCachedDevice.getBondState()).thenReturn(BluetoothDevice.BOND_NONE);
when(mCachedDevice.getMemberDevice()).thenReturn(Set.of(mSubCachedDevice));
assertThat(mController.isAvailable()).isTrue();
}
/**
* Test if the controller is available.
* Conditions:
* 1. Binaural hearing aids
* 2. No sub device is added
* 2. No member device is added
* Expected result:
* The controller is available. Need to show the hint to pair the other side.
*/
@Test
public void isAvailable_deviceIsConnectedHearingAid_otherDeviceIsNotExist_available() {
when(mCachedDevice.isConnectedHearingAidDevice()).thenReturn(true); when(mCachedDevice.isConnectedHearingAidDevice()).thenReturn(true);
when(mCachedDevice.isConnectedAshaHearingAidDevice()).thenReturn(true);
when(mCachedDevice.getDeviceMode()).thenReturn(HearingAidInfo.DeviceMode.MODE_BINAURAL); when(mCachedDevice.getDeviceMode()).thenReturn(HearingAidInfo.DeviceMode.MODE_BINAURAL);
when(mCachedDevice.getSubDevice()).thenReturn(null); when(mCachedDevice.getSubDevice()).thenReturn(null);
assertThat(mController.isAvailable()).isTrue();
}
/**
* Test if the controller is available.
* Conditions:
* 1. Binaural LE Audio hearing aids
* 2. Member device is added
* 3. Member device is connected
* Expected result:
* The controller is not available. Both sides are already paired and connected.
*/
@Test
public void isAvailable_leAudioDevice_otherDeviceIsConnected_notAvailable() {
when(mCachedDevice.isConnectedHearingAidDevice()).thenReturn(true);
when(mCachedDevice.isConnectedLeAudioHearingAidDevice()).thenReturn(true);
when(mCachedDevice.getDeviceMode()).thenReturn(HearingAidInfo.DeviceMode.MODE_BINAURAL);
when(mSubCachedDevice.isConnectedLeAudioHearingAidDevice()).thenReturn(true);
when(mCachedDevice.getMemberDevice()).thenReturn(Set.of(mSubCachedDevice));
assertThat(mController.isAvailable()).isFalse();
}
/**
* Test if the controller is available.
* Conditions:
* 1. Binaural LE Audio hearing aids
* 2. Member device is added
* 3. Member device is not connected
* Expected result:
* The controller is available. Need to show the hint to pair the other side.
*/
@Test
public void isAvailable_leAudioDevice_otherDeviceIsNotConnected_available() {
when(mCachedDevice.isConnectedHearingAidDevice()).thenReturn(true);
when(mCachedDevice.isConnectedLeAudioHearingAidDevice()).thenReturn(true);
when(mCachedDevice.getDeviceMode()).thenReturn(HearingAidInfo.DeviceMode.MODE_BINAURAL);
when(mSubCachedDevice.isConnectedLeAudioHearingAidDevice()).thenReturn(false);
when(mCachedDevice.getMemberDevice()).thenReturn(Set.of(mSubCachedDevice));
assertThat(mController.isAvailable()).isTrue();
}
/**
* Test if the controller is available.
* Conditions:
* 1. Binaural LE Audio hearing aids
* 2. No member device added
* Expected result:
* The controller is available. Need to show the hint to pair the other side.
*/
@Test
public void isAvailable_leAudioDevice_otherDeviceIsNotExist_available() {
when(mCachedDevice.isConnectedHearingAidDevice()).thenReturn(true);
when(mCachedDevice.isConnectedLeAudioHearingAidDevice()).thenReturn(true);
when(mCachedDevice.getDeviceMode()).thenReturn(HearingAidInfo.DeviceMode.MODE_BINAURAL);
when(mCachedDevice.getMemberDevice()).thenReturn(new HashSet<>()); when(mCachedDevice.getMemberDevice()).thenReturn(new HashSet<>());
assertThat(mController.isAvailable()).isTrue(); assertThat(mController.isAvailable()).isTrue();
@@ -245,7 +226,7 @@ public class BluetoothDetailsPairOtherControllerTest extends BluetoothDetailsCon
/** Test the pair other side button title after refreshing. */ /** Test the pair other side button title after refreshing. */
@Test @Test
public void refresh_rightSideDevice_pairLeftSideButtonTitle() { public void refresh_deviceIsRightSide_showPairLeftSideTitle() {
when(mCachedDevice.getDeviceSide()).thenReturn(HearingAidInfo.DeviceSide.SIDE_RIGHT); when(mCachedDevice.getDeviceSide()).thenReturn(HearingAidInfo.DeviceSide.SIDE_RIGHT);
mController.init(mScreen); mController.init(mScreen);
@@ -257,7 +238,7 @@ public class BluetoothDetailsPairOtherControllerTest extends BluetoothDetailsCon
/** Test the pair other side button visibility after refreshing. */ /** Test the pair other side button visibility after refreshing. */
@Test @Test
public void refresh_isNotConnectedHearingAidDevice_preferenceIsNotVisible() { public void refresh_deviceIsNotConnectedHearingAid_preferenceIsNotVisible() {
when(mCachedDevice.isConnectedHearingAidDevice()).thenReturn(false); when(mCachedDevice.isConnectedHearingAidDevice()).thenReturn(false);
mController.init(mScreen); mController.init(mScreen);