Merge "Hide pair other ear button after device connected via CSIP" into main

This commit is contained in:
Angela Wang
2023-09-20 05:59:08 +00:00
committed by Android (Google) Code Review
4 changed files with 152 additions and 55 deletions

View File

@@ -42,9 +42,10 @@ public final class HearingAidUtils {
*/ */
public static void launchHearingAidPairingDialog(FragmentManager fragmentManager, public static void launchHearingAidPairingDialog(FragmentManager fragmentManager,
@NonNull CachedBluetoothDevice device, int launchPage) { @NonNull CachedBluetoothDevice device, int launchPage) {
// No need to show the pair another ear dialog if the device supports and enables CSIP. // No need to show the pair another ear dialog if the device supports CSIP.
// CSIP will pair other devices in the same set automatically. // CSIP will pair other devices in the same set automatically.
if (isCsipSupportedAndEnabled(device)) { if (device.getProfiles().stream().anyMatch(
profile -> profile instanceof CsipSetCoordinatorProfile)) {
return; return;
} }
if (device.isConnectedAshaHearingAidDevice() if (device.isConnectedAshaHearingAidDevice()
@@ -63,10 +64,4 @@ public final class HearingAidUtils {
HearingAidPairingDialogFragment.newInstance(device.getAddress(), launchPage) HearingAidPairingDialogFragment.newInstance(device.getAddress(), launchPage)
.show(fragmentManager, HearingAidPairingDialogFragment.TAG); .show(fragmentManager, HearingAidPairingDialogFragment.TAG);
} }
private static boolean isCsipSupportedAndEnabled(@NonNull CachedBluetoothDevice device) {
return device.getProfiles().stream().anyMatch(
profile -> (profile instanceof CsipSetCoordinatorProfile)
&& (profile.isEnabled(device.getDevice())));
}
} }

View File

@@ -31,6 +31,8 @@ import com.android.settingslib.widget.ButtonPreference;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
import java.util.Set;
/** /**
* This class handles button preference logic to display for hearing aid device. * This class handles button preference logic to display for hearing aid device.
*/ */
@@ -91,7 +93,11 @@ public class BluetoothDetailsPairOtherController extends BluetoothDetailsControl
} }
private boolean getButtonPreferenceVisibility(CachedBluetoothDevice cachedDevice) { private boolean getButtonPreferenceVisibility(CachedBluetoothDevice cachedDevice) {
return isBinauralMode(cachedDevice) && isOnlyOneSideConnected(cachedDevice); // The device is not connected yet. Don't show the button.
if (!cachedDevice.isConnectedHearingAidDevice()) {
return false;
}
return isBinauralMode(cachedDevice) && !isOtherSideConnected(cachedDevice);
} }
private void launchPairingDetail() { private void launchPairingDetail() {
@@ -106,16 +112,25 @@ public class BluetoothDetailsPairOtherController extends BluetoothDetailsControl
return cachedDevice.getDeviceMode() == HearingAidInfo.DeviceMode.MODE_BINAURAL; return cachedDevice.getDeviceMode() == HearingAidInfo.DeviceMode.MODE_BINAURAL;
} }
private boolean isOnlyOneSideConnected(CachedBluetoothDevice cachedDevice) { private boolean isOtherSideConnected(CachedBluetoothDevice cachedDevice) {
if (!cachedDevice.isConnectedAshaHearingAidDevice()) { // Check sub device for ASHA hearing aid
return false; if (cachedDevice.isConnectedAshaHearingAidDevice()) {
final CachedBluetoothDevice subDevice = cachedDevice.getSubDevice();
if (subDevice != null && subDevice.isConnectedAshaHearingAidDevice()) {
return true;
}
} }
final CachedBluetoothDevice subDevice = cachedDevice.getSubDevice(); // Check member device for LE audio hearing aid
if (subDevice != null && subDevice.isConnectedAshaHearingAidDevice()) { if (cachedDevice.isConnectedLeAudioHearingAidDevice()) {
return false; final Set<CachedBluetoothDevice> memberDevices = cachedDevice.getMemberDevice();
for (CachedBluetoothDevice memberDevice : memberDevices) {
if (memberDevice.isConnectedLeAudioHearingAidDevice()) {
return true;
}
}
} }
return true; return false;
} }
} }

View File

@@ -156,14 +156,13 @@ public class HearingAidUtilsTest {
} }
@Test @Test
public void launchHearingAidPairingDialog_deviceSupportsCsip_csipEnabled_noDialog() { public void launchHearingAidPairingDialog_deviceSupportsCsip_noDialog() {
when(mCachedBluetoothDevice.isConnectedAshaHearingAidDevice()).thenReturn(true); when(mCachedBluetoothDevice.isConnectedAshaHearingAidDevice()).thenReturn(true);
when(mCachedBluetoothDevice.getDeviceMode()).thenReturn( when(mCachedBluetoothDevice.getDeviceMode()).thenReturn(
HearingAidInfo.DeviceMode.MODE_BINAURAL); HearingAidInfo.DeviceMode.MODE_BINAURAL);
when(mCachedBluetoothDevice.getDeviceSide()).thenReturn( when(mCachedBluetoothDevice.getDeviceSide()).thenReturn(
HearingAidInfo.DeviceSide.SIDE_LEFT); HearingAidInfo.DeviceSide.SIDE_LEFT);
makeDeviceSupportCsip(); makeDeviceSupportCsip();
makeDeviceEnableCsip(true);
HearingAidUtils.launchHearingAidPairingDialog(mFragmentManager, mCachedBluetoothDevice, HearingAidUtils.launchHearingAidPairingDialog(mFragmentManager, mCachedBluetoothDevice,
TEST_LAUNCH_PAGE); TEST_LAUNCH_PAGE);
@@ -173,24 +172,6 @@ public class HearingAidUtilsTest {
assertThat(dialog).isNull(); assertThat(dialog).isNull();
} }
@Test
public void launchHearingAidPairingDialog_deviceSupportsCsip_csipDisabled_dialogShown() {
when(mCachedBluetoothDevice.isConnectedAshaHearingAidDevice()).thenReturn(true);
when(mCachedBluetoothDevice.getDeviceMode()).thenReturn(
HearingAidInfo.DeviceMode.MODE_BINAURAL);
when(mCachedBluetoothDevice.getDeviceSide()).thenReturn(
HearingAidInfo.DeviceSide.SIDE_LEFT);
makeDeviceSupportCsip();
makeDeviceEnableCsip(false);
HearingAidUtils.launchHearingAidPairingDialog(mFragmentManager, mCachedBluetoothDevice,
TEST_LAUNCH_PAGE);
shadowMainLooper().idle();
final AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
assertThat(dialog.isShowing()).isTrue();
}
@Test @Test
public void launchHearingAidPairingDialog_dialogShown() { public void launchHearingAidPairingDialog_dialogShown() {
when(mCachedBluetoothDevice.isConnectedAshaHearingAidDevice()).thenReturn(true); when(mCachedBluetoothDevice.isConnectedAshaHearingAidDevice()).thenReturn(true);
@@ -213,11 +194,6 @@ public class HearingAidUtilsTest {
when(mCachedBluetoothDevice.getProfiles()).thenReturn(uuids); when(mCachedBluetoothDevice.getProfiles()).thenReturn(uuids);
} }
private void makeDeviceEnableCsip(boolean enabled) {
when(mCsipSetCoordinatorProfile.isEnabled(mCachedBluetoothDevice.getDevice()))
.thenReturn(enabled);
}
private void setupEnvironment() { private void setupEnvironment() {
ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBluetoothManager; ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBluetoothManager;
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

View File

@@ -34,6 +34,9 @@ import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule; import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner; import org.robolectric.RobolectricTestRunner;
import java.util.HashSet;
import java.util.Set;
/** Tests for {@link BluetoothDetailsPairOtherController}. */ /** Tests for {@link BluetoothDetailsPairOtherController}. */
@RunWith(RobolectricTestRunner.class) @RunWith(RobolectricTestRunner.class)
public class BluetoothDetailsPairOtherControllerTest extends BluetoothDetailsControllerTestBase { public class BluetoothDetailsPairOtherControllerTest extends BluetoothDetailsControllerTestBase {
@@ -60,8 +63,9 @@ public class BluetoothDetailsPairOtherControllerTest extends BluetoothDetailsCon
mScreen.addPreference(mSpacePreference); mScreen.addPreference(mSpacePreference);
} }
/** Test the pair other side button title during initialization. */
@Test @Test
public void init_leftSideDevice_rightSideButtonTitle() { public void init_leftSideDevice_pairRightSideButtonTitle() {
when(mCachedDevice.getDeviceSide()).thenReturn(HearingAidInfo.DeviceSide.SIDE_LEFT); when(mCachedDevice.getDeviceSide()).thenReturn(HearingAidInfo.DeviceSide.SIDE_LEFT);
mController.init(mScreen); mController.init(mScreen);
@@ -70,8 +74,9 @@ public class BluetoothDetailsPairOtherControllerTest extends BluetoothDetailsCon
mContext.getString(R.string.bluetooth_pair_right_ear_button)); mContext.getString(R.string.bluetooth_pair_right_ear_button));
} }
/** Test the pair other side button title during initialization. */
@Test @Test
public void init_rightSideDevice_leftSideButtonTitle() { public void init_rightSideDevice_pairLeftSideButtonTitle() {
when(mCachedDevice.getDeviceSide()).thenReturn(HearingAidInfo.DeviceSide.SIDE_RIGHT); when(mCachedDevice.getDeviceSide()).thenReturn(HearingAidInfo.DeviceSide.SIDE_RIGHT);
mController.init(mScreen); mController.init(mScreen);
@@ -80,9 +85,10 @@ public class BluetoothDetailsPairOtherControllerTest extends BluetoothDetailsCon
mContext.getString(R.string.bluetooth_pair_left_ear_button)); mContext.getString(R.string.bluetooth_pair_left_ear_button));
} }
/** Test the pair other side button visibility during initialization. */
@Test @Test
public void init_isNotConnectedAshaHearingAidDevice_notVisiblePreference() { public void init_isNotConnectedHearingAidDevice_preferenceIsNotVisible() {
when(mCachedDevice.isConnectedAshaHearingAidDevice()).thenReturn(false); when(mCachedDevice.isConnectedHearingAidDevice()).thenReturn(false);
mController.init(mScreen); mController.init(mScreen);
@@ -90,23 +96,49 @@ public class BluetoothDetailsPairOtherControllerTest extends BluetoothDetailsCon
assertThat(mSpacePreference.isVisible()).isFalse(); assertThat(mSpacePreference.isVisible()).isFalse();
} }
/**
* Test if the controller is available.
* Conditions:
* 1. Hearing aids is not connected
* Expected result:
* The controller is not available. No need to show pair other side hint for
* not connected device.
*/
@Test @Test
public void isAvailable_isNotConnectedAshaHearingAidDevice_notAvailable() { public void isAvailable_isNotConnectedHearingAidDevice_notAvailable() {
when(mCachedDevice.isConnectedAshaHearingAidDevice()).thenReturn(false); when(mCachedDevice.isConnectedHearingAidDevice()).thenReturn(false);
assertThat(mController.isAvailable()).isFalse(); assertThat(mController.isAvailable()).isFalse();
} }
/**
* Test if the controller is available.
* Conditions:
* 1. Monaural hearing aids
* Expected result:
* The controller is not available. No need to show pair other side hint for
* monaural device.
*/
@Test @Test
public void isAvailable_isConnectedAshaHearingAidDevice_isMonaural_notAvailable() { public void isAvailable_isConnectedHearingAidDevice_isMonaural_notAvailable() {
when(mCachedDevice.isConnectedAshaHearingAidDevice()).thenReturn(true); when(mCachedDevice.isConnectedHearingAidDevice()).thenReturn(true);
when(mCachedDevice.getDeviceMode()).thenReturn(HearingAidInfo.DeviceMode.MODE_MONAURAL); when(mCachedDevice.getDeviceMode()).thenReturn(HearingAidInfo.DeviceMode.MODE_MONAURAL);
assertThat(mController.isAvailable()).isFalse(); assertThat(mController.isAvailable()).isFalse();
} }
/**
* Test if the controller is available.
* Conditions:
* 1. Binaural ASHA hearing aids
* 2. Sub device is added
* 3. Sub device is connected
* Expected result:
* The controller is not available. Both sides are already paired and connected.
*/
@Test @Test
public void isAvailable_subDeviceIsConnectedAshaHearingAidDevice_notAvailable() { public void isAvailable_ashaDevice_otherDeviceIsConnected_notAvailable() {
when(mCachedDevice.isConnectedHearingAidDevice()).thenReturn(true);
when(mCachedDevice.isConnectedAshaHearingAidDevice()).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.isConnectedAshaHearingAidDevice()).thenReturn(true);
@@ -115,8 +147,18 @@ public class BluetoothDetailsPairOtherControllerTest extends BluetoothDetailsCon
assertThat(mController.isAvailable()).isFalse(); assertThat(mController.isAvailable()).isFalse();
} }
/**
* Test if the controller is available.
* Conditions:
* 1. Binaural ASHA hearing aids
* 2. Sub device is added
* 3. Sub device is not connected
* Expected result:
* The controller is available. Need to show the hint to pair the other side.
*/
@Test @Test
public void isAvailable_subDeviceIsNotConnectedAshaHearingAidDevice_available() { public void isAvailable_ashaDevice_otherDeviceIsNotConnected_available() {
when(mCachedDevice.isConnectedHearingAidDevice()).thenReturn(true);
when(mCachedDevice.isConnectedAshaHearingAidDevice()).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.isConnectedAshaHearingAidDevice()).thenReturn(false);
@@ -125,8 +167,17 @@ public class BluetoothDetailsPairOtherControllerTest extends BluetoothDetailsCon
assertThat(mController.isAvailable()).isTrue(); assertThat(mController.isAvailable()).isTrue();
} }
/**
* Test if the controller is available.
* Conditions:
* 1. Binaural ASHA hearing aids
* 2. No sub device added
* Expected result:
* The controller is available. Need to show the hint to pair the other side.
*/
@Test @Test
public void isAvailable_subDeviceNotExist_available() { public void isAvailable_ashaDevice_otherDeviceIsNotExist_available() {
when(mCachedDevice.isConnectedHearingAidDevice()).thenReturn(true);
when(mCachedDevice.isConnectedAshaHearingAidDevice()).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);
@@ -134,8 +185,67 @@ public class BluetoothDetailsPairOtherControllerTest extends BluetoothDetailsCon
assertThat(mController.isAvailable()).isTrue(); 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 @Test
public void refresh_leftSideDevice_leftSideButtonTitle() { 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<>());
assertThat(mController.isAvailable()).isTrue();
}
/** Test the pair other side button title after refreshing. */
@Test
public void refresh_rightSideDevice_pairLeftSideButtonTitle() {
when(mCachedDevice.getDeviceSide()).thenReturn(HearingAidInfo.DeviceSide.SIDE_RIGHT); when(mCachedDevice.getDeviceSide()).thenReturn(HearingAidInfo.DeviceSide.SIDE_RIGHT);
mController.init(mScreen); mController.init(mScreen);
@@ -145,9 +255,10 @@ public class BluetoothDetailsPairOtherControllerTest extends BluetoothDetailsCon
mContext.getString(R.string.bluetooth_pair_left_ear_button)); mContext.getString(R.string.bluetooth_pair_left_ear_button));
} }
/** Test the pair other side button visibility after refreshing. */
@Test @Test
public void refresh_isNotConnectedAshaHearingAidDevice_notVisiblePreference() { public void refresh_isNotConnectedHearingAidDevice_preferenceIsNotVisible() {
when(mCachedDevice.isConnectedAshaHearingAidDevice()).thenReturn(false); when(mCachedDevice.isConnectedHearingAidDevice()).thenReturn(false);
mController.init(mScreen); mController.init(mScreen);
mController.refresh(); mController.refresh();