Loading packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java +2 −2 Original line number Original line Diff line number Diff line Loading @@ -228,7 +228,7 @@ public class HearingDevicesDialogDelegate implements SystemUIDialog.Delegate, mHearingDeviceItemList = getHearingDevicesList(); mHearingDeviceItemList = getHearingDevicesList(); if (mPresetsController != null) { if (mPresetsController != null) { activeHearingDevice = getActiveHearingDevice(mHearingDeviceItemList); activeHearingDevice = getActiveHearingDevice(mHearingDeviceItemList); mPresetsController.setActiveHearingDevice(activeHearingDevice); mPresetsController.setHearingDeviceIfSupportHap(activeHearingDevice); } else { } else { activeHearingDevice = null; activeHearingDevice = null; } } Loading Loading @@ -336,7 +336,7 @@ public class HearingDevicesDialogDelegate implements SystemUIDialog.Delegate, } } final CachedBluetoothDevice activeHearingDevice = getActiveHearingDevice( final CachedBluetoothDevice activeHearingDevice = getActiveHearingDevice( mHearingDeviceItemList); mHearingDeviceItemList); mPresetsController.setActiveHearingDevice(activeHearingDevice); mPresetsController.setHearingDeviceIfSupportHap(activeHearingDevice); mPresetInfoAdapter = new ArrayAdapter<>(dialog.getContext(), mPresetInfoAdapter = new ArrayAdapter<>(dialog.getContext(), R.layout.hearing_devices_preset_spinner_selected, R.layout.hearing_devices_preset_spinner_selected, Loading packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesPresetsController.java +22 −11 Original line number Original line Diff line number Diff line Loading @@ -113,7 +113,7 @@ public class HearingDevicesPresetsController implements @Override @Override public void onPresetSelectionForGroupFailed(int hapGroupId, int reason) { public void onPresetSelectionForGroupFailed(int hapGroupId, int reason) { if (mActiveHearingDevice == null) { if (mActiveHearingDevice == null || mHapClientProfile == null) { return; return; } } if (hapGroupId == mHapClientProfile.getHapGroup(mActiveHearingDevice.getDevice())) { if (hapGroupId == mHapClientProfile.getHapGroup(mActiveHearingDevice.getDevice())) { Loading @@ -137,7 +137,7 @@ public class HearingDevicesPresetsController implements @Override @Override public void onSetPresetNameForGroupFailed(int hapGroupId, int reason) { public void onSetPresetNameForGroupFailed(int hapGroupId, int reason) { if (mActiveHearingDevice == null) { if (mActiveHearingDevice == null || mHapClientProfile == null) { return; return; } } if (hapGroupId == mHapClientProfile.getHapGroup(mActiveHearingDevice.getDevice())) { if (hapGroupId == mHapClientProfile.getHapGroup(mActiveHearingDevice.getDevice())) { Loading Loading @@ -177,22 +177,33 @@ public class HearingDevicesPresetsController implements } } /** /** * Sets the hearing device for this controller to control the preset. * Sets the hearing device for this controller to control the preset if it supports * {@link HapClientProfile}. * * * @param activeHearingDevice the {@link CachedBluetoothDevice} need to be hearing aid device * @param activeHearingDevice the {@link CachedBluetoothDevice} need to be hearing aid device * and support {@link HapClientProfile}. */ */ public void setActiveHearingDevice(CachedBluetoothDevice activeHearingDevice) { public void setHearingDeviceIfSupportHap(CachedBluetoothDevice activeHearingDevice) { if (mHapClientProfile == null || activeHearingDevice == null) { mActiveHearingDevice = null; return; } if (activeHearingDevice.getProfiles().stream().anyMatch( profile -> profile instanceof HapClientProfile)) { mActiveHearingDevice = activeHearingDevice; mActiveHearingDevice = activeHearingDevice; } else { mActiveHearingDevice = null; } } } /** /** * Selects the currently active preset for {@code mActiveHearingDevice} individual device or * Selects the currently active preset for {@code mActiveHearingDevice} individual device or * the device group accoridng to whether it supports synchronized presets or not. * the device group according to whether it supports synchronized presets or not. * * * @param presetIndex an index of one of the available presets * @param presetIndex an index of one of the available presets */ */ public void selectPreset(int presetIndex) { public void selectPreset(int presetIndex) { if (mActiveHearingDevice == null) { if (mActiveHearingDevice == null || mHapClientProfile == null) { return; return; } } mSelectedPresetIndex = presetIndex; mSelectedPresetIndex = presetIndex; Loading @@ -217,7 +228,7 @@ public class HearingDevicesPresetsController implements * @return a list of all known preset info * @return a list of all known preset info */ */ public List<BluetoothHapPresetInfo> getAllPresetInfo() { public List<BluetoothHapPresetInfo> getAllPresetInfo() { if (mActiveHearingDevice == null) { if (mActiveHearingDevice == null || mHapClientProfile == null) { return emptyList(); return emptyList(); } } return mHapClientProfile.getAllPresetInfo(mActiveHearingDevice.getDevice()).stream().filter( return mHapClientProfile.getAllPresetInfo(mActiveHearingDevice.getDevice()).stream().filter( Loading @@ -230,14 +241,14 @@ public class HearingDevicesPresetsController implements * @return active preset index * @return active preset index */ */ public int getActivePresetIndex() { public int getActivePresetIndex() { if (mActiveHearingDevice == null) { if (mActiveHearingDevice == null || mHapClientProfile == null) { return BluetoothHapClient.PRESET_INDEX_UNAVAILABLE; return BluetoothHapClient.PRESET_INDEX_UNAVAILABLE; } } return mHapClientProfile.getActivePresetIndex(mActiveHearingDevice.getDevice()); return mHapClientProfile.getActivePresetIndex(mActiveHearingDevice.getDevice()); } } private void selectPresetSynchronously(int groupId, int presetIndex) { private void selectPresetSynchronously(int groupId, int presetIndex) { if (mActiveHearingDevice == null) { if (mActiveHearingDevice == null || mHapClientProfile == null) { return; return; } } if (DEBUG) { if (DEBUG) { Loading @@ -250,7 +261,7 @@ public class HearingDevicesPresetsController implements } } private void selectPresetIndependently(int presetIndex) { private void selectPresetIndependently(int presetIndex) { if (mActiveHearingDevice == null) { if (mActiveHearingDevice == null || mHapClientProfile == null) { return; return; } } if (DEBUG) { if (DEBUG) { Loading packages/SystemUI/tests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesPresetsControllerTest.java 0 → 100644 +285 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.systemui.accessibility.hearingaid; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyList; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static java.util.Collections.emptyList; import android.bluetooth.BluetoothCsipSetCoordinator; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHapClient; import android.bluetooth.BluetoothHapPresetInfo; import android.testing.TestableLooper; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.settingslib.bluetooth.HapClientProfile; import com.android.settingslib.bluetooth.LocalBluetoothProfile; import com.android.settingslib.bluetooth.LocalBluetoothProfileManager; import com.android.systemui.SysuiTestCase; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; import java.util.List; import java.util.concurrent.Executor; /** Tests for {@link HearingDevicesPresetsController}. */ @RunWith(AndroidJUnit4.class) @TestableLooper.RunWithLooper(setAsMainLooper = true) @SmallTest public class HearingDevicesPresetsControllerTest extends SysuiTestCase { private static final int TEST_PRESET_INDEX = 1; private static final String TEST_PRESET_NAME = "test_preset"; private static final int TEST_HAP_GROUP_ID = 1; private static final int TEST_REASON = 1024; @Rule public MockitoRule mockito = MockitoJUnit.rule(); @Mock private LocalBluetoothProfileManager mProfileManager; @Mock private HapClientProfile mHapClientProfile; @Mock private CachedBluetoothDevice mCachedBluetoothDevice; @Mock private CachedBluetoothDevice mSubCachedBluetoothDevice; @Mock private BluetoothDevice mBluetoothDevice; @Mock private BluetoothDevice mSubBluetoothDevice; @Mock private HearingDevicesPresetsController.PresetCallback mCallback; private HearingDevicesPresetsController mController; @Before public void setUp() { when(mProfileManager.getHapClientProfile()).thenReturn(mHapClientProfile); when(mHapClientProfile.isProfileReady()).thenReturn(true); when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice); when(mCachedBluetoothDevice.getSubDevice()).thenReturn(mSubCachedBluetoothDevice); when(mSubCachedBluetoothDevice.getDevice()).thenReturn(mSubBluetoothDevice); mController = new HearingDevicesPresetsController(mProfileManager, mCallback); } @Test public void onServiceConnected_callExpectedCallback() { mController.onServiceConnected(); verify(mHapClientProfile).registerCallback(any(Executor.class), any(BluetoothHapClient.Callback.class)); verify(mCallback).onPresetInfoUpdated(anyList(), anyInt()); } @Test public void getAllPresetInfo_setInvalidHearingDevice_getEmpty() { when(mCachedBluetoothDevice.getProfiles()).thenReturn(emptyList()); mController.setHearingDeviceIfSupportHap(mCachedBluetoothDevice); BluetoothHapPresetInfo hapPresetInfo = getHapPresetInfo(true); when(mHapClientProfile.getAllPresetInfo(mBluetoothDevice)).thenReturn( List.of(hapPresetInfo)); assertThat(mController.getAllPresetInfo()).isEmpty(); } @Test public void getAllPresetInfo_containsNotAvailablePresetInfo_getEmpty() { setValidHearingDeviceSupportHap(); BluetoothHapPresetInfo hapPresetInfo = getHapPresetInfo(false); when(mHapClientProfile.getAllPresetInfo(mBluetoothDevice)).thenReturn( List.of(hapPresetInfo)); assertThat(mController.getAllPresetInfo()).isEmpty(); } @Test public void getAllPresetInfo_containsOnePresetInfo_getOnePresetInfo() { setValidHearingDeviceSupportHap(); BluetoothHapPresetInfo hapPresetInfo = getHapPresetInfo(true); when(mHapClientProfile.getAllPresetInfo(mBluetoothDevice)).thenReturn( List.of(hapPresetInfo)); assertThat(mController.getAllPresetInfo()).contains(hapPresetInfo); } @Test public void getActivePresetIndex_getExpectedIndex() { setValidHearingDeviceSupportHap(); when(mHapClientProfile.getActivePresetIndex(mBluetoothDevice)).thenReturn( TEST_PRESET_INDEX); assertThat(mController.getActivePresetIndex()).isEqualTo(TEST_PRESET_INDEX); } @Test public void onPresetSelected_presetIndex_callOnPresetInfoUpdatedWithExpectedPresetIndex() { setValidHearingDeviceSupportHap(); BluetoothHapPresetInfo hapPresetInfo = getHapPresetInfo(true); when(mHapClientProfile.getAllPresetInfo(mBluetoothDevice)).thenReturn( List.of(hapPresetInfo)); when(mHapClientProfile.getActivePresetIndex(mBluetoothDevice)).thenReturn( TEST_PRESET_INDEX); mController.onPresetSelected(mBluetoothDevice, TEST_PRESET_INDEX, TEST_REASON); verify(mCallback).onPresetInfoUpdated(eq(List.of(hapPresetInfo)), eq(TEST_PRESET_INDEX)); } @Test public void onPresetInfoChanged_presetIndex_callOnPresetInfoUpdatedWithExpectedPresetIndex() { setValidHearingDeviceSupportHap(); BluetoothHapPresetInfo hapPresetInfo = getHapPresetInfo(true); when(mHapClientProfile.getAllPresetInfo(mBluetoothDevice)).thenReturn( List.of(hapPresetInfo)); when(mHapClientProfile.getActivePresetIndex(mBluetoothDevice)).thenReturn( TEST_PRESET_INDEX); mController.onPresetInfoChanged(mBluetoothDevice, List.of(hapPresetInfo), TEST_REASON); verify(mCallback).onPresetInfoUpdated(List.of(hapPresetInfo), TEST_PRESET_INDEX); } @Test public void onPresetSelectionFailed_callOnPresetCommandFailed() { setValidHearingDeviceSupportHap(); mController.onPresetSelectionFailed(mBluetoothDevice, TEST_REASON); verify(mCallback).onPresetCommandFailed(TEST_REASON); } @Test public void onSetPresetNameFailed_callOnPresetCommandFailed() { setValidHearingDeviceSupportHap(); mController.onSetPresetNameFailed(mBluetoothDevice, TEST_REASON); verify(mCallback).onPresetCommandFailed(TEST_REASON); } @Test public void onPresetSelectionForGroupFailed_callSelectPresetIndividual() { setValidHearingDeviceSupportHap(); mController.selectPreset(TEST_PRESET_INDEX); Mockito.reset(mHapClientProfile); when(mHapClientProfile.getHapGroup(mBluetoothDevice)).thenReturn(TEST_HAP_GROUP_ID); mController.onPresetSelectionForGroupFailed(TEST_HAP_GROUP_ID, TEST_REASON); verify(mHapClientProfile).selectPreset(mBluetoothDevice, TEST_PRESET_INDEX); verify(mHapClientProfile).selectPreset(mSubBluetoothDevice, TEST_PRESET_INDEX); } @Test public void onSetPresetNameForGroupFailed_callOnPresetCommandFailed() { setValidHearingDeviceSupportHap(); mController.onSetPresetNameForGroupFailed(TEST_HAP_GROUP_ID, TEST_REASON); verify(mCallback).onPresetCommandFailed(TEST_REASON); } @Test public void registerHapCallback_callHapRegisterCallback() { mController.registerHapCallback(); verify(mHapClientProfile).registerCallback(any(Executor.class), any(BluetoothHapClient.Callback.class)); } @Test public void unregisterHapCallback_callHapUnregisterCallback() { mController.unregisterHapCallback(); verify(mHapClientProfile).unregisterCallback(any(BluetoothHapClient.Callback.class)); } @Test public void selectPreset_supportSynchronized_validGroupId_callSelectPresetForGroup() { setValidHearingDeviceSupportHap(); when(mHapClientProfile.supportsSynchronizedPresets(mBluetoothDevice)).thenReturn(true); when(mHapClientProfile.getHapGroup(mBluetoothDevice)).thenReturn(TEST_HAP_GROUP_ID); mController.selectPreset(TEST_PRESET_INDEX); verify(mHapClientProfile).selectPresetForGroup(TEST_HAP_GROUP_ID, TEST_PRESET_INDEX); } @Test public void selectPreset_supportSynchronized_invalidGroupId_callSelectPresetIndividual() { setValidHearingDeviceSupportHap(); when(mHapClientProfile.supportsSynchronizedPresets(mBluetoothDevice)).thenReturn(true); when(mHapClientProfile.getHapGroup(mBluetoothDevice)).thenReturn( BluetoothCsipSetCoordinator.GROUP_ID_INVALID); mController.selectPreset(TEST_PRESET_INDEX); verify(mHapClientProfile).selectPreset(mBluetoothDevice, TEST_PRESET_INDEX); verify(mHapClientProfile).selectPreset(mSubBluetoothDevice, TEST_PRESET_INDEX); } @Test public void selectPreset_notSupportSynchronized_validGroupId_callSelectPresetIndividual() { setValidHearingDeviceSupportHap(); when(mHapClientProfile.supportsSynchronizedPresets(mBluetoothDevice)).thenReturn(false); when(mHapClientProfile.getHapGroup(mBluetoothDevice)).thenReturn(TEST_HAP_GROUP_ID); mController.selectPreset(TEST_PRESET_INDEX); verify(mHapClientProfile).selectPreset(mBluetoothDevice, TEST_PRESET_INDEX); verify(mHapClientProfile).selectPreset(mSubBluetoothDevice, TEST_PRESET_INDEX); } private BluetoothHapPresetInfo getHapPresetInfo(boolean available) { BluetoothHapPresetInfo info = mock(BluetoothHapPresetInfo.class); when(info.getName()).thenReturn(TEST_PRESET_NAME); when(info.getIndex()).thenReturn(TEST_PRESET_INDEX); when(info.isAvailable()).thenReturn(available); return info; } private void setValidHearingDeviceSupportHap() { LocalBluetoothProfile hapClientProfile = mock(HapClientProfile.class); List<LocalBluetoothProfile> profiles = List.of(hapClientProfile); when(mCachedBluetoothDevice.getProfiles()).thenReturn(profiles); mController.setHearingDeviceIfSupportHap(mCachedBluetoothDevice); } } Loading
packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java +2 −2 Original line number Original line Diff line number Diff line Loading @@ -228,7 +228,7 @@ public class HearingDevicesDialogDelegate implements SystemUIDialog.Delegate, mHearingDeviceItemList = getHearingDevicesList(); mHearingDeviceItemList = getHearingDevicesList(); if (mPresetsController != null) { if (mPresetsController != null) { activeHearingDevice = getActiveHearingDevice(mHearingDeviceItemList); activeHearingDevice = getActiveHearingDevice(mHearingDeviceItemList); mPresetsController.setActiveHearingDevice(activeHearingDevice); mPresetsController.setHearingDeviceIfSupportHap(activeHearingDevice); } else { } else { activeHearingDevice = null; activeHearingDevice = null; } } Loading Loading @@ -336,7 +336,7 @@ public class HearingDevicesDialogDelegate implements SystemUIDialog.Delegate, } } final CachedBluetoothDevice activeHearingDevice = getActiveHearingDevice( final CachedBluetoothDevice activeHearingDevice = getActiveHearingDevice( mHearingDeviceItemList); mHearingDeviceItemList); mPresetsController.setActiveHearingDevice(activeHearingDevice); mPresetsController.setHearingDeviceIfSupportHap(activeHearingDevice); mPresetInfoAdapter = new ArrayAdapter<>(dialog.getContext(), mPresetInfoAdapter = new ArrayAdapter<>(dialog.getContext(), R.layout.hearing_devices_preset_spinner_selected, R.layout.hearing_devices_preset_spinner_selected, Loading
packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesPresetsController.java +22 −11 Original line number Original line Diff line number Diff line Loading @@ -113,7 +113,7 @@ public class HearingDevicesPresetsController implements @Override @Override public void onPresetSelectionForGroupFailed(int hapGroupId, int reason) { public void onPresetSelectionForGroupFailed(int hapGroupId, int reason) { if (mActiveHearingDevice == null) { if (mActiveHearingDevice == null || mHapClientProfile == null) { return; return; } } if (hapGroupId == mHapClientProfile.getHapGroup(mActiveHearingDevice.getDevice())) { if (hapGroupId == mHapClientProfile.getHapGroup(mActiveHearingDevice.getDevice())) { Loading @@ -137,7 +137,7 @@ public class HearingDevicesPresetsController implements @Override @Override public void onSetPresetNameForGroupFailed(int hapGroupId, int reason) { public void onSetPresetNameForGroupFailed(int hapGroupId, int reason) { if (mActiveHearingDevice == null) { if (mActiveHearingDevice == null || mHapClientProfile == null) { return; return; } } if (hapGroupId == mHapClientProfile.getHapGroup(mActiveHearingDevice.getDevice())) { if (hapGroupId == mHapClientProfile.getHapGroup(mActiveHearingDevice.getDevice())) { Loading Loading @@ -177,22 +177,33 @@ public class HearingDevicesPresetsController implements } } /** /** * Sets the hearing device for this controller to control the preset. * Sets the hearing device for this controller to control the preset if it supports * {@link HapClientProfile}. * * * @param activeHearingDevice the {@link CachedBluetoothDevice} need to be hearing aid device * @param activeHearingDevice the {@link CachedBluetoothDevice} need to be hearing aid device * and support {@link HapClientProfile}. */ */ public void setActiveHearingDevice(CachedBluetoothDevice activeHearingDevice) { public void setHearingDeviceIfSupportHap(CachedBluetoothDevice activeHearingDevice) { if (mHapClientProfile == null || activeHearingDevice == null) { mActiveHearingDevice = null; return; } if (activeHearingDevice.getProfiles().stream().anyMatch( profile -> profile instanceof HapClientProfile)) { mActiveHearingDevice = activeHearingDevice; mActiveHearingDevice = activeHearingDevice; } else { mActiveHearingDevice = null; } } } /** /** * Selects the currently active preset for {@code mActiveHearingDevice} individual device or * Selects the currently active preset for {@code mActiveHearingDevice} individual device or * the device group accoridng to whether it supports synchronized presets or not. * the device group according to whether it supports synchronized presets or not. * * * @param presetIndex an index of one of the available presets * @param presetIndex an index of one of the available presets */ */ public void selectPreset(int presetIndex) { public void selectPreset(int presetIndex) { if (mActiveHearingDevice == null) { if (mActiveHearingDevice == null || mHapClientProfile == null) { return; return; } } mSelectedPresetIndex = presetIndex; mSelectedPresetIndex = presetIndex; Loading @@ -217,7 +228,7 @@ public class HearingDevicesPresetsController implements * @return a list of all known preset info * @return a list of all known preset info */ */ public List<BluetoothHapPresetInfo> getAllPresetInfo() { public List<BluetoothHapPresetInfo> getAllPresetInfo() { if (mActiveHearingDevice == null) { if (mActiveHearingDevice == null || mHapClientProfile == null) { return emptyList(); return emptyList(); } } return mHapClientProfile.getAllPresetInfo(mActiveHearingDevice.getDevice()).stream().filter( return mHapClientProfile.getAllPresetInfo(mActiveHearingDevice.getDevice()).stream().filter( Loading @@ -230,14 +241,14 @@ public class HearingDevicesPresetsController implements * @return active preset index * @return active preset index */ */ public int getActivePresetIndex() { public int getActivePresetIndex() { if (mActiveHearingDevice == null) { if (mActiveHearingDevice == null || mHapClientProfile == null) { return BluetoothHapClient.PRESET_INDEX_UNAVAILABLE; return BluetoothHapClient.PRESET_INDEX_UNAVAILABLE; } } return mHapClientProfile.getActivePresetIndex(mActiveHearingDevice.getDevice()); return mHapClientProfile.getActivePresetIndex(mActiveHearingDevice.getDevice()); } } private void selectPresetSynchronously(int groupId, int presetIndex) { private void selectPresetSynchronously(int groupId, int presetIndex) { if (mActiveHearingDevice == null) { if (mActiveHearingDevice == null || mHapClientProfile == null) { return; return; } } if (DEBUG) { if (DEBUG) { Loading @@ -250,7 +261,7 @@ public class HearingDevicesPresetsController implements } } private void selectPresetIndependently(int presetIndex) { private void selectPresetIndependently(int presetIndex) { if (mActiveHearingDevice == null) { if (mActiveHearingDevice == null || mHapClientProfile == null) { return; return; } } if (DEBUG) { if (DEBUG) { Loading
packages/SystemUI/tests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesPresetsControllerTest.java 0 → 100644 +285 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.systemui.accessibility.hearingaid; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyList; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static java.util.Collections.emptyList; import android.bluetooth.BluetoothCsipSetCoordinator; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHapClient; import android.bluetooth.BluetoothHapPresetInfo; import android.testing.TestableLooper; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.settingslib.bluetooth.HapClientProfile; import com.android.settingslib.bluetooth.LocalBluetoothProfile; import com.android.settingslib.bluetooth.LocalBluetoothProfileManager; import com.android.systemui.SysuiTestCase; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; import java.util.List; import java.util.concurrent.Executor; /** Tests for {@link HearingDevicesPresetsController}. */ @RunWith(AndroidJUnit4.class) @TestableLooper.RunWithLooper(setAsMainLooper = true) @SmallTest public class HearingDevicesPresetsControllerTest extends SysuiTestCase { private static final int TEST_PRESET_INDEX = 1; private static final String TEST_PRESET_NAME = "test_preset"; private static final int TEST_HAP_GROUP_ID = 1; private static final int TEST_REASON = 1024; @Rule public MockitoRule mockito = MockitoJUnit.rule(); @Mock private LocalBluetoothProfileManager mProfileManager; @Mock private HapClientProfile mHapClientProfile; @Mock private CachedBluetoothDevice mCachedBluetoothDevice; @Mock private CachedBluetoothDevice mSubCachedBluetoothDevice; @Mock private BluetoothDevice mBluetoothDevice; @Mock private BluetoothDevice mSubBluetoothDevice; @Mock private HearingDevicesPresetsController.PresetCallback mCallback; private HearingDevicesPresetsController mController; @Before public void setUp() { when(mProfileManager.getHapClientProfile()).thenReturn(mHapClientProfile); when(mHapClientProfile.isProfileReady()).thenReturn(true); when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice); when(mCachedBluetoothDevice.getSubDevice()).thenReturn(mSubCachedBluetoothDevice); when(mSubCachedBluetoothDevice.getDevice()).thenReturn(mSubBluetoothDevice); mController = new HearingDevicesPresetsController(mProfileManager, mCallback); } @Test public void onServiceConnected_callExpectedCallback() { mController.onServiceConnected(); verify(mHapClientProfile).registerCallback(any(Executor.class), any(BluetoothHapClient.Callback.class)); verify(mCallback).onPresetInfoUpdated(anyList(), anyInt()); } @Test public void getAllPresetInfo_setInvalidHearingDevice_getEmpty() { when(mCachedBluetoothDevice.getProfiles()).thenReturn(emptyList()); mController.setHearingDeviceIfSupportHap(mCachedBluetoothDevice); BluetoothHapPresetInfo hapPresetInfo = getHapPresetInfo(true); when(mHapClientProfile.getAllPresetInfo(mBluetoothDevice)).thenReturn( List.of(hapPresetInfo)); assertThat(mController.getAllPresetInfo()).isEmpty(); } @Test public void getAllPresetInfo_containsNotAvailablePresetInfo_getEmpty() { setValidHearingDeviceSupportHap(); BluetoothHapPresetInfo hapPresetInfo = getHapPresetInfo(false); when(mHapClientProfile.getAllPresetInfo(mBluetoothDevice)).thenReturn( List.of(hapPresetInfo)); assertThat(mController.getAllPresetInfo()).isEmpty(); } @Test public void getAllPresetInfo_containsOnePresetInfo_getOnePresetInfo() { setValidHearingDeviceSupportHap(); BluetoothHapPresetInfo hapPresetInfo = getHapPresetInfo(true); when(mHapClientProfile.getAllPresetInfo(mBluetoothDevice)).thenReturn( List.of(hapPresetInfo)); assertThat(mController.getAllPresetInfo()).contains(hapPresetInfo); } @Test public void getActivePresetIndex_getExpectedIndex() { setValidHearingDeviceSupportHap(); when(mHapClientProfile.getActivePresetIndex(mBluetoothDevice)).thenReturn( TEST_PRESET_INDEX); assertThat(mController.getActivePresetIndex()).isEqualTo(TEST_PRESET_INDEX); } @Test public void onPresetSelected_presetIndex_callOnPresetInfoUpdatedWithExpectedPresetIndex() { setValidHearingDeviceSupportHap(); BluetoothHapPresetInfo hapPresetInfo = getHapPresetInfo(true); when(mHapClientProfile.getAllPresetInfo(mBluetoothDevice)).thenReturn( List.of(hapPresetInfo)); when(mHapClientProfile.getActivePresetIndex(mBluetoothDevice)).thenReturn( TEST_PRESET_INDEX); mController.onPresetSelected(mBluetoothDevice, TEST_PRESET_INDEX, TEST_REASON); verify(mCallback).onPresetInfoUpdated(eq(List.of(hapPresetInfo)), eq(TEST_PRESET_INDEX)); } @Test public void onPresetInfoChanged_presetIndex_callOnPresetInfoUpdatedWithExpectedPresetIndex() { setValidHearingDeviceSupportHap(); BluetoothHapPresetInfo hapPresetInfo = getHapPresetInfo(true); when(mHapClientProfile.getAllPresetInfo(mBluetoothDevice)).thenReturn( List.of(hapPresetInfo)); when(mHapClientProfile.getActivePresetIndex(mBluetoothDevice)).thenReturn( TEST_PRESET_INDEX); mController.onPresetInfoChanged(mBluetoothDevice, List.of(hapPresetInfo), TEST_REASON); verify(mCallback).onPresetInfoUpdated(List.of(hapPresetInfo), TEST_PRESET_INDEX); } @Test public void onPresetSelectionFailed_callOnPresetCommandFailed() { setValidHearingDeviceSupportHap(); mController.onPresetSelectionFailed(mBluetoothDevice, TEST_REASON); verify(mCallback).onPresetCommandFailed(TEST_REASON); } @Test public void onSetPresetNameFailed_callOnPresetCommandFailed() { setValidHearingDeviceSupportHap(); mController.onSetPresetNameFailed(mBluetoothDevice, TEST_REASON); verify(mCallback).onPresetCommandFailed(TEST_REASON); } @Test public void onPresetSelectionForGroupFailed_callSelectPresetIndividual() { setValidHearingDeviceSupportHap(); mController.selectPreset(TEST_PRESET_INDEX); Mockito.reset(mHapClientProfile); when(mHapClientProfile.getHapGroup(mBluetoothDevice)).thenReturn(TEST_HAP_GROUP_ID); mController.onPresetSelectionForGroupFailed(TEST_HAP_GROUP_ID, TEST_REASON); verify(mHapClientProfile).selectPreset(mBluetoothDevice, TEST_PRESET_INDEX); verify(mHapClientProfile).selectPreset(mSubBluetoothDevice, TEST_PRESET_INDEX); } @Test public void onSetPresetNameForGroupFailed_callOnPresetCommandFailed() { setValidHearingDeviceSupportHap(); mController.onSetPresetNameForGroupFailed(TEST_HAP_GROUP_ID, TEST_REASON); verify(mCallback).onPresetCommandFailed(TEST_REASON); } @Test public void registerHapCallback_callHapRegisterCallback() { mController.registerHapCallback(); verify(mHapClientProfile).registerCallback(any(Executor.class), any(BluetoothHapClient.Callback.class)); } @Test public void unregisterHapCallback_callHapUnregisterCallback() { mController.unregisterHapCallback(); verify(mHapClientProfile).unregisterCallback(any(BluetoothHapClient.Callback.class)); } @Test public void selectPreset_supportSynchronized_validGroupId_callSelectPresetForGroup() { setValidHearingDeviceSupportHap(); when(mHapClientProfile.supportsSynchronizedPresets(mBluetoothDevice)).thenReturn(true); when(mHapClientProfile.getHapGroup(mBluetoothDevice)).thenReturn(TEST_HAP_GROUP_ID); mController.selectPreset(TEST_PRESET_INDEX); verify(mHapClientProfile).selectPresetForGroup(TEST_HAP_GROUP_ID, TEST_PRESET_INDEX); } @Test public void selectPreset_supportSynchronized_invalidGroupId_callSelectPresetIndividual() { setValidHearingDeviceSupportHap(); when(mHapClientProfile.supportsSynchronizedPresets(mBluetoothDevice)).thenReturn(true); when(mHapClientProfile.getHapGroup(mBluetoothDevice)).thenReturn( BluetoothCsipSetCoordinator.GROUP_ID_INVALID); mController.selectPreset(TEST_PRESET_INDEX); verify(mHapClientProfile).selectPreset(mBluetoothDevice, TEST_PRESET_INDEX); verify(mHapClientProfile).selectPreset(mSubBluetoothDevice, TEST_PRESET_INDEX); } @Test public void selectPreset_notSupportSynchronized_validGroupId_callSelectPresetIndividual() { setValidHearingDeviceSupportHap(); when(mHapClientProfile.supportsSynchronizedPresets(mBluetoothDevice)).thenReturn(false); when(mHapClientProfile.getHapGroup(mBluetoothDevice)).thenReturn(TEST_HAP_GROUP_ID); mController.selectPreset(TEST_PRESET_INDEX); verify(mHapClientProfile).selectPreset(mBluetoothDevice, TEST_PRESET_INDEX); verify(mHapClientProfile).selectPreset(mSubBluetoothDevice, TEST_PRESET_INDEX); } private BluetoothHapPresetInfo getHapPresetInfo(boolean available) { BluetoothHapPresetInfo info = mock(BluetoothHapPresetInfo.class); when(info.getName()).thenReturn(TEST_PRESET_NAME); when(info.getIndex()).thenReturn(TEST_PRESET_INDEX); when(info.isAvailable()).thenReturn(available); return info; } private void setValidHearingDeviceSupportHap() { LocalBluetoothProfile hapClientProfile = mock(HapClientProfile.class); List<LocalBluetoothProfile> profiles = List.of(hapClientProfile); when(mCachedBluetoothDevice.getProfiles()).thenReturn(profiles); mController.setHearingDeviceIfSupportHap(mCachedBluetoothDevice); } }