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

Commit 484bc742 authored by Angela Wang's avatar Angela Wang
Browse files

Initialize hearing aid info if the device matches hearing aid scan filters

We only show connected hearing devices in the hearing devices page now.
When user pairing a device from pairing page and back to the hearing
devices page after the device is bonded, it's confusing no device shown
in the list because we can't get hearing aid info and thus don't know
it's a hearing aid while the profiles are not connected yet.

Init the device with empty hearing aid info if it matches the scan
filter. By doing this we can know it's a hearing aid before hearing aid
related profiles are connected and can show the connecting hearing aid
devices in the a11y hearing devices page to avoid confusion.

Bug: 283268686
Test: atest CachedBluetoothDeviceTest
Test: atest CachedBluetoothDeviceManagerTest
Test: atest HearingAidDeviceMangerTest
Change-Id: I3d3916f85a90c3f610a1d59ae244126788de0b2d
Merged-In: I3d3916f85a90c3f610a1d59ae244126788de0b2d
parent 267f49b1
Loading
Loading
Loading
Loading
+1 −5
Original line number Original line Diff line number Diff line
@@ -356,11 +356,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
        connectDevice();
        connectDevice();
    }
    }


    public HearingAidInfo getHearingAidInfo() {
    void setHearingAidInfo(HearingAidInfo hearingAidInfo) {
        return mHearingAidInfo;
    }

    public void setHearingAidInfo(HearingAidInfo hearingAidInfo) {
        mHearingAidInfo = hearingAidInfo;
        mHearingAidInfo = hearingAidInfo;
    }
    }


+14 −2
Original line number Original line Diff line number Diff line
@@ -20,6 +20,7 @@ import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothCsipSetCoordinator;
import android.bluetooth.BluetoothCsipSetCoordinator;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.le.ScanFilter;
import android.content.Context;
import android.content.Context;
import android.util.Log;
import android.util.Log;


@@ -114,10 +115,21 @@ public class CachedBluetoothDeviceManager {
    /**
    /**
     * Create and return a new {@link CachedBluetoothDevice}. This assumes
     * Create and return a new {@link CachedBluetoothDevice}. This assumes
     * that {@link #findDevice} has already been called and returned null.
     * that {@link #findDevice} has already been called and returned null.
     * @param device the address of the new Bluetooth device
     * @param device the new Bluetooth device
     * @return the newly created CachedBluetoothDevice object
     * @return the newly created CachedBluetoothDevice object
     */
     */
    public CachedBluetoothDevice addDevice(BluetoothDevice device) {
    public CachedBluetoothDevice addDevice(BluetoothDevice device) {
        return addDevice(device, /*leScanFilters=*/null);
    }

    /**
     * Create and return a new {@link CachedBluetoothDevice}. This assumes
     * that {@link #findDevice} has already been called and returned null.
     * @param device the new Bluetooth device
     * @param leScanFilters the BLE scan filters which the device matched
     * @return the newly created CachedBluetoothDevice object
     */
    public CachedBluetoothDevice addDevice(BluetoothDevice device, List<ScanFilter> leScanFilters) {
        CachedBluetoothDevice newDevice;
        CachedBluetoothDevice newDevice;
        final LocalBluetoothProfileManager profileManager = mBtManager.getProfileManager();
        final LocalBluetoothProfileManager profileManager = mBtManager.getProfileManager();
        synchronized (this) {
        synchronized (this) {
@@ -125,7 +137,7 @@ public class CachedBluetoothDeviceManager {
            if (newDevice == null) {
            if (newDevice == null) {
                newDevice = new CachedBluetoothDevice(mContext, profileManager, device);
                newDevice = new CachedBluetoothDevice(mContext, profileManager, device);
                mCsipDeviceManager.initCsipDeviceIfNeeded(newDevice);
                mCsipDeviceManager.initCsipDeviceIfNeeded(newDevice);
                mHearingAidDeviceManager.initHearingAidDeviceIfNeeded(newDevice);
                mHearingAidDeviceManager.initHearingAidDeviceIfNeeded(newDevice, leScanFilters);
                if (!mCsipDeviceManager.setMemberDeviceIfNeeded(newDevice)
                if (!mCsipDeviceManager.setMemberDeviceIfNeeded(newDevice)
                        && !mHearingAidDeviceManager.setSubDeviceIfNeeded(newDevice)) {
                        && !mHearingAidDeviceManager.setSubDeviceIfNeeded(newDevice)) {
                    mCachedDevices.add(newDevice);
                    mCachedDevices.add(newDevice);
+20 −1
Original line number Original line Diff line number Diff line
@@ -18,10 +18,13 @@ package com.android.settingslib.bluetooth;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHearingAid;
import android.bluetooth.BluetoothHearingAid;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothUuid;
import android.bluetooth.le.ScanFilter;
import android.content.ContentResolver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Context;
import android.media.AudioDeviceAttributes;
import android.media.AudioDeviceAttributes;
import android.media.audiopolicy.AudioProductStrategy;
import android.media.audiopolicy.AudioProductStrategy;
import android.os.ParcelUuid;
import android.provider.Settings;
import android.provider.Settings;
import android.util.Log;
import android.util.Log;


@@ -59,7 +62,8 @@ public class HearingAidDeviceManager {
        mRoutingHelper = routingHelper;
        mRoutingHelper = routingHelper;
    }
    }


    void initHearingAidDeviceIfNeeded(CachedBluetoothDevice newDevice) {
    void initHearingAidDeviceIfNeeded(CachedBluetoothDevice newDevice,
            List<ScanFilter> leScanFilters) {
        long hiSyncId = getHiSyncId(newDevice.getDevice());
        long hiSyncId = getHiSyncId(newDevice.getDevice());
        if (isValidHiSyncId(hiSyncId)) {
        if (isValidHiSyncId(hiSyncId)) {
            // Once hiSyncId is valid, assign hearing aid info
            // Once hiSyncId is valid, assign hearing aid info
@@ -68,6 +72,21 @@ public class HearingAidDeviceManager {
                    .setAshaDeviceMode(getDeviceMode(newDevice.getDevice()))
                    .setAshaDeviceMode(getDeviceMode(newDevice.getDevice()))
                    .setHiSyncId(hiSyncId);
                    .setHiSyncId(hiSyncId);
            newDevice.setHearingAidInfo(infoBuilder.build());
            newDevice.setHearingAidInfo(infoBuilder.build());
        } else if (leScanFilters != null && !newDevice.isHearingAidDevice()) {
            // If the device is added with hearing aid scan filter during pairing, set an empty
            // hearing aid info to indicate it's a hearing aid device. The info will be updated
            // when corresponding profiles connected.
            for (ScanFilter leScanFilter: leScanFilters) {
                final ParcelUuid serviceUuid = leScanFilter.getServiceUuid();
                final ParcelUuid serviceDataUuid = leScanFilter.getServiceDataUuid();
                if (BluetoothUuid.HEARING_AID.equals(serviceUuid)
                        || BluetoothUuid.HAS.equals(serviceUuid)
                        || BluetoothUuid.HEARING_AID.equals(serviceDataUuid)
                        || BluetoothUuid.HAS.equals(serviceDataUuid)) {
                    newDevice.setHearingAidInfo(new HearingAidInfo.Builder().build());
                    break;
                }
            }
        }
        }
    }
    }


+35 −2
Original line number Original line Diff line number Diff line
@@ -33,6 +33,8 @@ import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHearingAid;
import android.bluetooth.BluetoothHearingAid;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothUuid;
import android.bluetooth.le.ScanFilter;
import android.content.Context;
import android.content.Context;
import android.media.AudioAttributes;
import android.media.AudioAttributes;
import android.media.AudioDeviceAttributes;
import android.media.AudioDeviceAttributes;
@@ -147,7 +149,7 @@ public class HearingAidDeviceManagerTest {
                HearingAidProfile.DeviceSide.SIDE_RIGHT);
                HearingAidProfile.DeviceSide.SIDE_RIGHT);


        assertThat(mCachedDevice1.getHiSyncId()).isNotEqualTo(HISYNCID1);
        assertThat(mCachedDevice1.getHiSyncId()).isNotEqualTo(HISYNCID1);
        mHearingAidDeviceManager.initHearingAidDeviceIfNeeded(mCachedDevice1);
        mHearingAidDeviceManager.initHearingAidDeviceIfNeeded(mCachedDevice1, null);


        assertThat(mCachedDevice1.getHiSyncId()).isEqualTo(HISYNCID1);
        assertThat(mCachedDevice1.getHiSyncId()).isEqualTo(HISYNCID1);
        assertThat(mCachedDevice1.getDeviceMode()).isEqualTo(
        assertThat(mCachedDevice1.getDeviceMode()).isEqualTo(
@@ -164,11 +166,42 @@ public class HearingAidDeviceManagerTest {
        when(mHearingAidProfile.getHiSyncId(mDevice1)).thenReturn(
        when(mHearingAidProfile.getHiSyncId(mDevice1)).thenReturn(
                BluetoothHearingAid.HI_SYNC_ID_INVALID);
                BluetoothHearingAid.HI_SYNC_ID_INVALID);


        mHearingAidDeviceManager.initHearingAidDeviceIfNeeded(mCachedDevice1);
        mHearingAidDeviceManager.initHearingAidDeviceIfNeeded(mCachedDevice1, null);


        verify(mCachedDevice1, never()).setHearingAidInfo(any(HearingAidInfo.class));
        verify(mCachedDevice1, never()).setHearingAidInfo(any(HearingAidInfo.class));
    }
    }


    /**
     * Test initHearingAidDeviceIfNeeded, an invalid HiSyncId and hearing aid scan filter, set an
     * empty hearing aid info on the device.
     */
    @Test
    public void initHearingAidDeviceIfNeeded_hearingAidScanFilter_setHearingAidInfo() {
        when(mHearingAidProfile.getHiSyncId(mDevice1)).thenReturn(
                BluetoothHearingAid.HI_SYNC_ID_INVALID);
        final ScanFilter scanFilter = new ScanFilter.Builder()
                .setServiceData(BluetoothUuid.HEARING_AID, new byte[]{0}).build();

        mHearingAidDeviceManager.initHearingAidDeviceIfNeeded(mCachedDevice1, List.of(scanFilter));

        assertThat(mCachedDevice1.isHearingAidDevice()).isTrue();
    }

    /**
     * Test initHearingAidDeviceIfNeeded, an invalid HiSyncId and random scan filter, not to set
     * hearing aid info on the device.
     */
    @Test
    public void initHearingAidDeviceIfNeeded_randomScanFilter_notToSetHearingAidInfo() {
        when(mHearingAidProfile.getHiSyncId(mDevice1)).thenReturn(
                BluetoothHearingAid.HI_SYNC_ID_INVALID);
        final ScanFilter scanFilter = new ScanFilter.Builder().build();

        mHearingAidDeviceManager.initHearingAidDeviceIfNeeded(mCachedDevice1, List.of(scanFilter));

        assertThat(mCachedDevice1.isHearingAidDevice()).isFalse();
    }

    /**
    /**
     * Test setSubDeviceIfNeeded, a device with same HiSyncId will be set as sub device
     * Test setSubDeviceIfNeeded, a device with same HiSyncId will be set as sub device
     */
     */