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

Commit 564c9301 authored by Angela Wang's avatar Angela Wang
Browse files

Remove hearing device local data when the device is unpaired

Clear local data if the device is unpaired. The device address will be
different if the same device is paired again.

Flag: com.android.settingslib.flags.hearing_devices_ambient_volume_control
Bug: 357878944
Test: atest HearingDeviceLocalDataManagerTest
Test: atest CachedBluetoothDeviceManagerTest
Change-Id: Ice8a1f32bbad9a3d2ca75122ff799b8439665695
parent de9d574d
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -153,7 +153,7 @@ public class CachedBluetoothDeviceManager {
    /**
     * Returns device summary of the pair of the hearing aid / CSIP passed as the parameter.
     *
     * @param CachedBluetoothDevice device
     * @param device the remote device
     * @return Device summary, or if the pair does not exist or if it is not a hearing aid or
     * a CSIP set member, then {@code null}.
     */
@@ -394,6 +394,7 @@ public class CachedBluetoothDeviceManager {
    }

    public synchronized void onDeviceUnpaired(CachedBluetoothDevice device) {
        mHearingAidDeviceManager.clearLocalDataIfNeeded(device);
        device.setGroupId(BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
        CachedBluetoothDevice mainDevice = mCsipDeviceManager.findMainDevice(device);
        // Should iterate through the cloned set to avoid ConcurrentModificationException
+4 −0
Original line number Diff line number Diff line
@@ -308,6 +308,10 @@ public class HearingAidDeviceManager {
        }
    }

    void clearLocalDataIfNeeded(CachedBluetoothDevice device) {
        HearingDeviceLocalDataManager.clear(mContext, device.getDevice());
    }

    private void setAudioRoutingConfig(CachedBluetoothDevice device) {
        AudioDeviceAttributes hearingDeviceAttributes =
                mRoutingHelper.getMatchedHearingDeviceAttributes(device);
+35 −1
Original line number Diff line number Diff line
@@ -86,6 +86,17 @@ public class HearingDeviceLocalDataManager {
        mSettingsObserver = new SettingsObserver(ThreadUtils.getUiThreadHandler());
    }

    /**
     * Clears the local data of the device. This method should be called when the device is
     * unpaired.
     */
    public static void clear(@NonNull Context context, @NonNull BluetoothDevice device) {
        HearingDeviceLocalDataManager manager = new HearingDeviceLocalDataManager(context);
        manager.getLocalDataFromSettings();
        manager.remove(device);
        manager.putAmbientVolumeSettings();
    }

    /** Starts the manager. Loads the data from Settings and start observing any changes. */
    public synchronized void start() {
        if (mIsStarted) {
@@ -141,6 +152,7 @@ public class HearingDeviceLocalDataManager {
     * Puts the local data of the corresponding hearing device.
     *
     * @param device the device to update the local data
     * @param data the local data to be stored
     */
    private void put(BluetoothDevice device, Data data) {
        if (device == null) {
@@ -148,13 +160,35 @@ public class HearingDeviceLocalDataManager {
        }
        synchronized (sLock) {
            final String addr = device.getAnonymizedAddress();
            if (data == null) {
                mAddrToDataMap.remove(addr);
            } else {
                mAddrToDataMap.put(addr, data);
            }
            if (mListener != null && mListenerExecutor != null) {
                mListenerExecutor.execute(() -> mListener.onDeviceLocalDataChange(addr, data));
            }
        }
    }

    /**
     * Removes the local data of the corresponding hearing device.
     *
     * @param device the device to remove the local data
     */
    private void remove(BluetoothDevice device) {
        if (device == null) {
            return;
        }
        synchronized (sLock) {
            final String addr = device.getAnonymizedAddress();
            mAddrToDataMap.remove(addr);
            if (mListener != null && mListenerExecutor != null) {
                mListenerExecutor.execute(() -> mListener.onDeviceLocalDataChange(addr, null));
            }
        }
    }

    /**
     * Updates the ambient volume of the corresponding hearing device. This should be called after
     * {@link #start()} is called().
+11 −6
Original line number Diff line number Diff line
@@ -139,6 +139,11 @@ public class CachedBluetoothDeviceManagerTest {
        mCachedDevice1 = spy(new CachedBluetoothDevice(mContext, mLocalProfileManager, mDevice1));
        mCachedDevice2 = spy(new CachedBluetoothDevice(mContext, mLocalProfileManager, mDevice2));
        mCachedDevice3 = spy(new CachedBluetoothDevice(mContext, mLocalProfileManager, mDevice3));

        mHearingAidDeviceManager = spy(new HearingAidDeviceManager(mContext, mLocalBluetoothManager,
                mCachedDeviceManager.mCachedDevices));
        mCachedDeviceManager.mHearingAidDeviceManager = mHearingAidDeviceManager;
        doNothing().when(mHearingAidDeviceManager).clearLocalDataIfNeeded(any());
    }

    /**
@@ -338,6 +343,8 @@ public class CachedBluetoothDeviceManagerTest {

        // Call onDeviceUnpaired for the one in mCachedDevices.
        mCachedDeviceManager.onDeviceUnpaired(cachedDevice2);

        verify(mHearingAidDeviceManager).clearLocalDataIfNeeded(cachedDevice2);
        verify(mDevice1).removeBond();
    }

@@ -353,6 +360,8 @@ public class CachedBluetoothDeviceManagerTest {

        // Call onDeviceUnpaired for the one in mCachedDevices.
        mCachedDeviceManager.onDeviceUnpaired(cachedDevice1);

        verify(mHearingAidDeviceManager).clearLocalDataIfNeeded(cachedDevice1);
        verify(mDevice2).removeBond();
    }

@@ -406,9 +415,6 @@ public class CachedBluetoothDeviceManagerTest {
     */
    @Test
    public void updateHearingAidDevices_directToHearingAidDeviceManager() {
        mHearingAidDeviceManager = spy(new HearingAidDeviceManager(mContext, mLocalBluetoothManager,
                mCachedDeviceManager.mCachedDevices));
        mCachedDeviceManager.mHearingAidDeviceManager = mHearingAidDeviceManager;
        mCachedDeviceManager.updateHearingAidsDevices();

        verify(mHearingAidDeviceManager).updateHearingAidsDevices();
@@ -535,6 +541,7 @@ public class CachedBluetoothDeviceManagerTest {
        // Call onDeviceUnpaired for the one in mCachedDevices.
        mCachedDeviceManager.onDeviceUnpaired(cachedDevice1);

        verify(mHearingAidDeviceManager).clearLocalDataIfNeeded(cachedDevice1);
        verify(mDevice2).removeBond();
        assertThat(cachedDevice1.getGroupId()).isEqualTo(
                BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
@@ -559,6 +566,7 @@ public class CachedBluetoothDeviceManagerTest {
        // Call onDeviceUnpaired for the one in mCachedDevices.
        mCachedDeviceManager.onDeviceUnpaired(cachedDevice2);

        verify(mHearingAidDeviceManager).clearLocalDataIfNeeded(cachedDevice2);
        verify(mDevice1).removeBond();
        assertThat(cachedDevice2.getGroupId()).isEqualTo(
                BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
@@ -611,10 +619,7 @@ public class CachedBluetoothDeviceManagerTest {

    @Test
    public void onActiveDeviceChanged_validHiSyncId_callExpectedFunction() {
        mHearingAidDeviceManager = spy(new HearingAidDeviceManager(mContext, mLocalBluetoothManager,
                mCachedDeviceManager.mCachedDevices));
        doNothing().when(mHearingAidDeviceManager).onActiveDeviceChanged(any());
        mCachedDeviceManager.mHearingAidDeviceManager = mHearingAidDeviceManager;
        when(mDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
        CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
        cachedDevice1.setHearingAidInfo(
+13 −0
Original line number Diff line number Diff line
@@ -194,6 +194,19 @@ public class HearingDeviceLocalDataManagerTest {
        verify(mListener).onDeviceLocalDataChange(TEST_ADDRESS, newData);
    }

    @Test
    public void clear_dataIsRemoved() {
        String settings = Settings.Global.getStringForUser(mContext.getContentResolver(),
                Settings.Global.HEARING_DEVICE_LOCAL_AMBIENT_VOLUME, UserHandle.USER_SYSTEM);
        assertThat(settings.contains(TEST_ADDRESS)).isTrue();

        HearingDeviceLocalDataManager.clear(mContext, mDevice);

        settings = Settings.Global.getStringForUser(mContext.getContentResolver(),
                Settings.Global.HEARING_DEVICE_LOCAL_AMBIENT_VOLUME, UserHandle.USER_SYSTEM);
        assertThat(settings.contains(TEST_ADDRESS)).isFalse();
    }

    private void prepareTestDataInSettings() {
        String data = generateSettingsString(TEST_ADDRESS, TEST_AMBIENT, TEST_GROUP_AMBIENT,
                TEST_AMBIENT_CONTROL_EXPANDED);