Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4db16f11 authored by Angela Wang's avatar Angela Wang
Browse files

Try select preset independently after group operation failed

For some binaural models, when only one side is connected and call a group operation, the remote device will return ERROR_REMOTE_OPERATION_REJECTED. We can re-try to selectthe  preset for each device independently in this case. After the other device is reconnected, the preset should automatically sync in the remote side.

Bug: 300015207
Test: manual test with Gn Resound LE sample and verify it works
Test: atest BluetoothDetailsHearingAidsPresetsControllerTest
Change-Id: I3ea621577c248c974505b9ce65d8ef260f5b87e1
parent de9a8884
Loading
Loading
Loading
Loading
+65 −40
Original line number Diff line number Diff line
@@ -110,46 +110,25 @@ public class BluetoothDetailsHearingAidsPresetsController extends
                    && preference instanceof final ListPreference listPreference) {
                final int index = listPreference.findIndexOfValue(value);
                final String presetName = listPreference.getEntries()[index].toString();
                final int presetIndex = Integer.parseInt(
                        listPreference.getEntryValues()[index].toString());
                final int presetIndex = Integer.parseInt(value);
                listPreference.setSummary(presetName);
                boolean supportSynchronizedPresets = mHapClientProfile.supportsSynchronizedPresets(
                        mCachedDevice.getDevice());
                int hapGroupId = mHapClientProfile.getHapGroup(mCachedDevice.getDevice());
                if (supportSynchronizedPresets
                        && hapGroupId != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) {
                if (DEBUG) {
                        Log.d(TAG, "onPreferenceChange, selectPresetForGroup "
                                + ", presetName: " + presetName
                    Log.d(TAG, "onPreferenceChange"
                            + ", presetIndex: " + presetIndex
                                + ", hapGroupId: "  + hapGroupId
                                + ", device: " + mCachedDevice.getAddress());
                            + ", presetName: "  + presetName);
                }
                    mHapClientProfile.selectPresetForGroup(hapGroupId, presetIndex);
                boolean supportSynchronizedPresets = mHapClientProfile.supportsSynchronizedPresets(
                        mCachedDevice.getDevice());
                int hapGroupId = mHapClientProfile.getHapGroup(mCachedDevice.getDevice());
                if (supportSynchronizedPresets) {
                    if (hapGroupId != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) {
                        selectPresetSynchronously(hapGroupId, presetIndex);
                    } else {
                    if (DEBUG) {
                        Log.d(TAG, "onPreferenceChange, selectPreset "
                                + ", presetName: " + presetName
                                + ", presetIndex: " + presetIndex
                                + ", device: " + mCachedDevice.getAddress());
                    }
                    mHapClientProfile.selectPreset(mCachedDevice.getDevice(), presetIndex);
                    final CachedBluetoothDevice subDevice = mCachedDevice.getSubDevice();
                    if (subDevice != null) {
                        if (DEBUG) {
                            Log.d(TAG, "onPreferenceChange, selectPreset for subDevice"
                                    + ", device: " + subDevice.getAddress());
                        }
                        mHapClientProfile.selectPreset(subDevice.getDevice(), presetIndex);
                    }
                    for (final CachedBluetoothDevice memberDevice :
                            mCachedDevice.getMemberDevice()) {
                        if (DEBUG) {
                            Log.d(TAG, "onPreferenceChange, selectPreset for memberDevice"
                                    + ", device: " + memberDevice.getAddress());
                        }
                        mHapClientProfile.selectPreset(memberDevice.getDevice(), presetIndex);
                        Log.w(TAG, "supportSynchronizedPresets but hapGroupId is invalid.");
                        selectPresetIndependently(presetIndex);
                    }
                } else {
                    selectPresetIndependently(presetIndex);
                }
                return true;
            }
@@ -181,6 +160,9 @@ public class BluetoothDetailsHearingAidsPresetsController extends

        loadAllPresetInfo();
        if (mPreference.getEntries().length == 0) {
            if (DEBUG) {
                Log.w(TAG, "Disable the preference since preset info size = 0");
            }
            mPreference.setEnabled(false);
        } else {
            int activePresetIndex = mHapClientProfile.getActivePresetIndex(
@@ -235,10 +217,10 @@ public class BluetoothDetailsHearingAidsPresetsController extends
                Log.d(TAG, "onPresetSelectionForGroupFailed, group: " + hapGroupId
                        + ", reason: " + reason);
            }
            mContext.getMainExecutor().execute(() -> {
                refresh();
                showErrorToast();
            });
            // Try to set the preset independently if group operation failed
            if (mPreference != null) {
                selectPresetIndependently(Integer.parseInt(mPreference.getValue()));
            }
        }
    }

@@ -248,8 +230,10 @@ public class BluetoothDetailsHearingAidsPresetsController extends
        if (device.equals(mCachedDevice.getDevice())) {
            if (DEBUG) {
                Log.d(TAG, "onPresetInfoChanged, device: " + device.getAddress()
                        + ", reason: " + reason
                        + ", infoList: " + presetInfoList);
                        + ", reason: " + reason);
                for (BluetoothHapPresetInfo info: presetInfoList) {
                    Log.d(TAG, "    preset " + info.getIndex() + ": " + info.getName());
                }
            }
            mContext.getMainExecutor().execute(this::refresh);
        }
@@ -304,6 +288,9 @@ public class BluetoothDetailsHearingAidsPresetsController extends
        for (int i = 0; i < infoList.size(); i++) {
            presetNames[i] = infoList.get(i).getName();
            presetIndexes[i] = Integer.toString(infoList.get(i).getIndex());
            if (DEBUG) {
                Log.d(TAG, "loadAllPresetInfo, preset " + presetIndexes[i] + ": " + presetNames[i]);
            }
        }
        mPreference.setEntries(presetNames);
        mPreference.setEntryValues(presetIndexes);
@@ -356,4 +343,42 @@ public class BluetoothDetailsHearingAidsPresetsController extends
    public void onServiceDisconnected() {
        // Do nothing
    }

    private void selectPresetSynchronously(int groupId, int presetIndex) {
        if (mPreference == null) {
            return;
        }
        if (DEBUG) {
            Log.d(TAG, "selectPresetSynchronously"
                    + ", presetIndex: " + presetIndex
                    + ", groupId: "  + groupId
                    + ", device: " + mCachedDevice.getAddress());
        }
        mHapClientProfile.selectPresetForGroup(groupId, presetIndex);
    }
    private void selectPresetIndependently(int presetIndex) {
        if (mPreference == null) {
            return;
        }
        if (DEBUG) {
            Log.d(TAG, "selectPresetIndependently"
                    + ", presetIndex: " + presetIndex
                    + ", device: " + mCachedDevice.getAddress());
        }
        mHapClientProfile.selectPreset(mCachedDevice.getDevice(), presetIndex);
        final CachedBluetoothDevice subDevice = mCachedDevice.getSubDevice();
        if (subDevice != null) {
            if (DEBUG) {
                Log.d(TAG, "selectPreset for subDevice, device: " + subDevice);
            }
            mHapClientProfile.selectPreset(subDevice.getDevice(), presetIndex);
        }
        for (final CachedBluetoothDevice memberDevice :
                mCachedDevice.getMemberDevice()) {
            if (DEBUG) {
                Log.d(TAG, "selectPreset for memberDevice, device: " + memberDevice);
            }
            mHapClientProfile.selectPreset(memberDevice.getDevice(), presetIndex);
        }
    }
}
+11 −0
Original line number Diff line number Diff line
@@ -87,6 +87,7 @@ public class BluetoothDetailsHearingAidsPresetsControllerTest extends

        when(mLocalManager.getProfileManager()).thenReturn(mProfileManager);
        when(mProfileManager.getHapClientProfile()).thenReturn(mHapClientProfile);
        when(mCachedDevice.getDevice()).thenReturn(mDevice);
        when(mCachedDevice.getProfiles()).thenReturn(List.of(mHapClientProfile));
        when(mCachedDevice.isConnectedHapClientDevice()).thenReturn(true);
        when(mCachedChildDevice.getDevice()).thenReturn(mChildDevice);
@@ -251,6 +252,16 @@ public class BluetoothDetailsHearingAidsPresetsControllerTest extends
        assertThat(mController.getPreference().getSummary()).isNotNull();
    }

    @Test
    public void onPresetSelectionForGroupFailed_selectPresetIsCalled() {
        when(mHapClientProfile.getHapGroup(mDevice)).thenReturn(TEST_HAP_GROUP_ID);
        mController.getPreference().setValue(String.valueOf(TEST_PRESET_INDEX));

        mController.onPresetSelectionForGroupFailed(TEST_HAP_GROUP_ID, TEST_PRESET_INDEX);

        verify(mHapClientProfile).selectPreset(mDevice, TEST_PRESET_INDEX);
    }

    private BluetoothHapPresetInfo getTestPresetInfo() {
        BluetoothHapPresetInfo info = mock(BluetoothHapPresetInfo.class);
        when(info.getName()).thenReturn(TEST_PRESET_NAME);