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

Commit b1226999 authored by Isha Bobra's avatar Isha Bobra Committed by android-build-merger
Browse files

Merge "Show only 1 entry for hearing aid device after killing the activity."...

Merge "Show only 1 entry for hearing aid device after killing the activity." into pi-dev am: ed344d17
am: c19f0a66

Change-Id: I315316c0c50c94689ba80e548d554f73fa63043d
parents 725df7a1 c19f0a66
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -272,6 +272,14 @@ public class BluetoothEventManager {
        }
    }

    void dispatchDeviceRemoved(CachedBluetoothDevice cachedDevice) {
        synchronized (mCallbacks) {
            for (BluetoothCallback callback : mCallbacks) {
                callback.onDeviceDeleted(cachedDevice);
            }
        }
    }

    private class DeviceDisappearedHandler implements Handler {
        public void onReceive(Context context, Intent intent,
                BluetoothDevice device) {
@@ -331,6 +339,10 @@ public class BluetoothEventManager {
            cachedDevice.onBondingStateChanged(bondState);

            if (bondState == BluetoothDevice.BOND_NONE) {
                /* Check if we need to remove other Hearing Aid devices */
                if (cachedDevice.getHiSyncId() != BluetoothHearingAid.HI_SYNC_ID_INVALID) {
                    mDeviceManager.onDeviceUnpaired(cachedDevice);
                }
                int reason = intent.getIntExtra(BluetoothDevice.EXTRA_REASON,
                        BluetoothDevice.ERROR);

+15 −1
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.settingslib.bluetooth;

import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHearingAid;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothUuid;
import android.content.Context;
@@ -53,6 +54,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
    private final BluetoothDevice mDevice;
    //TODO: consider remove, BluetoothDevice.getName() is already cached
    private String mName;
    private long mHiSyncId;
    // Need this since there is no method for getting RSSI
    private short mRssi;
    //TODO: consider remove, BluetoothDevice.getBluetoothClass() is already cached
@@ -94,6 +96,17 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
     */
    private boolean mIsConnectingErrorPossible;

    public long getHiSyncId() {
        return mHiSyncId;
    }

    public void setHiSyncId(long id) {
        if (Utils.D) {
            Log.d(TAG, "setHiSyncId: mDevice " + mDevice + ", id " + id);
        }
        mHiSyncId = id;
    }

    /**
     * Last time a bt profile auto-connect was attempted.
     * If an ACTION_UUID intent comes in within
@@ -175,6 +188,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
        mDevice = device;
        mProfileConnectionState = new HashMap<LocalBluetoothProfile, Integer>();
        fillData();
        mHiSyncId = BluetoothHearingAid.HI_SYNC_ID_INVALID;
    }

    public void disconnect() {
+187 −12
Original line number Diff line number Diff line
@@ -18,12 +18,17 @@ package com.android.settingslib.bluetooth;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHearingAid;
import android.content.Context;
import android.util.Log;

import com.android.internal.annotations.VisibleForTesting;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
@@ -34,10 +39,20 @@ public class CachedBluetoothDeviceManager {
    private static final boolean DEBUG = Utils.D;

    private Context mContext;
    private final List<CachedBluetoothDevice> mCachedDevices =
            new ArrayList<CachedBluetoothDevice>();
    private final LocalBluetoothManager mBtManager;

    @VisibleForTesting
    final List<CachedBluetoothDevice> mCachedDevices =
        new ArrayList<CachedBluetoothDevice>();
    // Contains the list of hearing aid devices that should not be shown in the UI.
    @VisibleForTesting
    final List<CachedBluetoothDevice> mHearingAidDevicesNotAddedInCache
        = new ArrayList<CachedBluetoothDevice>();
    // Maintains a list of devices which are added in mCachedDevices and have hiSyncIds.
    @VisibleForTesting
    final Map<Long, CachedBluetoothDevice> mCachedDevicesMapForHearingAids
        = new HashMap<Long, CachedBluetoothDevice>();

    CachedBluetoothDeviceManager(Context context, LocalBluetoothManager localBtManager) {
        mContext = context;
        mBtManager = localBtManager;
@@ -75,6 +90,11 @@ public class CachedBluetoothDeviceManager {
                return cachedDevice;
            }
        }
        for (CachedBluetoothDevice notCachedDevice : mHearingAidDevicesNotAddedInCache) {
            if (notCachedDevice.getDevice().equals(device)) {
                return notCachedDevice;
            }
        }
        return null;
    }

@@ -89,13 +109,102 @@ public class CachedBluetoothDeviceManager {
            BluetoothDevice device) {
        CachedBluetoothDevice newDevice = new CachedBluetoothDevice(mContext, adapter,
            profileManager, device);
        synchronized (mCachedDevices) {
        if (profileManager.getHearingAidProfile() != null
            && profileManager.getHearingAidProfile().getHiSyncId(newDevice.getDevice())
                != BluetoothHearingAid.HI_SYNC_ID_INVALID) {
            newDevice.setHiSyncId(profileManager.getHearingAidProfile()
                .getHiSyncId(newDevice.getDevice()));
        }
        // Just add one of the hearing aids from a pair in the list that is shown in the UI.
        if (isPairAddedInCache(newDevice.getHiSyncId())) {
            synchronized (this) {
                mHearingAidDevicesNotAddedInCache.add(newDevice);
            }
        } else {
            synchronized (this) {
                mCachedDevices.add(newDevice);
                if (newDevice.getHiSyncId() != BluetoothHearingAid.HI_SYNC_ID_INVALID
                    && !mCachedDevicesMapForHearingAids.containsKey(newDevice.getHiSyncId())) {
                    mCachedDevicesMapForHearingAids.put(newDevice.getHiSyncId(), newDevice);
                }
                mBtManager.getEventManager().dispatchDeviceAdded(newDevice);
            }
        }

        return newDevice;
    }

    /**
     * Returns true if the one of the two hearing aid devices is already cached for UI.
     *
     * @param long hiSyncId
     * @return {@code True} if one of the two hearing aid devices is is already cached for UI.
     */
    private synchronized boolean isPairAddedInCache(long hiSyncId) {
        if (hiSyncId == BluetoothHearingAid.HI_SYNC_ID_INVALID) {
            return false;
        }
        if(mCachedDevicesMapForHearingAids.containsKey(hiSyncId)) {
            return true;
        }
        return false;
    }

    /**
     * Returns device summary of the pair of the hearing aid passed as the parameter.
     *
     * @param CachedBluetoothDevice device
     * @return Device summary, or if the pair does not exist or if its not a hearing aid,
     * then {@code null}.
     */
    public synchronized String getHearingAidPairDeviceSummary(CachedBluetoothDevice device) {
        String pairDeviceSummary = null;
        if (device.getHiSyncId() != BluetoothHearingAid.HI_SYNC_ID_INVALID) {
            for (CachedBluetoothDevice hearingAidDevice : mHearingAidDevicesNotAddedInCache) {
                if (hearingAidDevice.getHiSyncId() != BluetoothHearingAid.HI_SYNC_ID_INVALID
                    && hearingAidDevice.getHiSyncId() == device.getHiSyncId()) {
                    pairDeviceSummary = hearingAidDevice.getConnectionSummary();
                }
            }
        }
        return pairDeviceSummary;
    }

    /**
     * Adds the 2nd hearing aid in a pair in a list that maintains the hearing aids that are
     * not dispalyed in the UI.
     *
     * @param CachedBluetoothDevice device
     */
    public synchronized void addDeviceNotaddedInMap(CachedBluetoothDevice device) {
        mHearingAidDevicesNotAddedInCache.add(device);
    }

    /**
     * Updates the Hearing Aid devices; specifically the HiSyncId's. This routine is called when the
     * Hearing Aid Service is connected and the HiSyncId's are now available.
     * @param LocalBluetoothProfileManager profileManager
     */
    public synchronized void updateHearingAidsDevices(LocalBluetoothProfileManager profileManager) {
        HearingAidProfile profileProxy = profileManager.getHearingAidProfile();
        if (profileProxy == null) {
            log("updateHearingAidsDevices: getHearingAidProfile() is null");
            return;
        }
        for (CachedBluetoothDevice cachedDevice : mCachedDevices) {
            if (cachedDevice.getHiSyncId() != BluetoothHearingAid.HI_SYNC_ID_INVALID) {
                continue;
            }

            long newHiSyncId = profileProxy.getHiSyncId(cachedDevice.getDevice());

            if (newHiSyncId != BluetoothHearingAid.HI_SYNC_ID_INVALID) {
                cachedDevice.setHiSyncId(newHiSyncId);
                onHiSyncIdChanged(newHiSyncId);
            }
        }
    }

    /**
     * Attempts to get the name of a remote device, otherwise returns the address.
     *
@@ -117,23 +226,29 @@ public class CachedBluetoothDeviceManager {
    }

    public synchronized void clearNonBondedDevices() {
        for (int i = mCachedDevices.size() - 1; i >= 0; i--) {
            CachedBluetoothDevice cachedDevice = mCachedDevices.get(i);
            if (cachedDevice.getBondState() == BluetoothDevice.BOND_NONE) {
                mCachedDevices.remove(i);
            }
        }

        mCachedDevicesMapForHearingAids.entrySet().removeIf(entries
            -> entries.getValue().getBondState() == BluetoothDevice.BOND_NONE);

        mCachedDevices.removeIf(cachedDevice
            -> cachedDevice.getBondState() == BluetoothDevice.BOND_NONE);

        mHearingAidDevicesNotAddedInCache.removeIf(hearingAidDevice
            -> hearingAidDevice.getBondState() == BluetoothDevice.BOND_NONE);
    }

    public synchronized void onScanningStateChanged(boolean started) {
        if (!started) return;

        // If starting a new scan, clear old visibility
        // Iterate in reverse order since devices may be removed.
        for (int i = mCachedDevices.size() - 1; i >= 0; i--) {
            CachedBluetoothDevice cachedDevice = mCachedDevices.get(i);
            cachedDevice.setJustDiscovered(false);
        }
        for (int i = mHearingAidDevicesNotAddedInCache.size() - 1; i >= 0; i--) {
            CachedBluetoothDevice notCachedDevice = mHearingAidDevicesNotAddedInCache.get(i);
            notCachedDevice.setJustDiscovered(false);
        }
    }

    public synchronized void onBtClassChanged(BluetoothDevice device) {
@@ -159,6 +274,11 @@ public class CachedBluetoothDeviceManager {
                if (cachedDevice.getBondState() != BluetoothDevice.BOND_BONDED) {
                    cachedDevice.setJustDiscovered(false);
                    mCachedDevices.remove(i);
                    if (cachedDevice.getHiSyncId() != BluetoothHearingAid.HI_SYNC_ID_INVALID
                        && mCachedDevicesMapForHearingAids.containsKey(cachedDevice.getHiSyncId()))
                    {
                        mCachedDevicesMapForHearingAids.remove(cachedDevice.getHiSyncId());
                    }
                } else {
                    // For bonded devices, we need to clear the connection status so that
                    // when BT is enabled next time, device connection status shall be retrieved
@@ -166,6 +286,18 @@ public class CachedBluetoothDeviceManager {
                    cachedDevice.clearProfileConnectionState();
                }
            }
            for (int i = mHearingAidDevicesNotAddedInCache.size() - 1; i >= 0; i--) {
                CachedBluetoothDevice notCachedDevice = mHearingAidDevicesNotAddedInCache.get(i);
                if (notCachedDevice.getBondState() != BluetoothDevice.BOND_BONDED) {
                    notCachedDevice.setJustDiscovered(false);
                    mHearingAidDevicesNotAddedInCache.remove(i);
                } else {
                    // For bonded devices, we need to clear the connection status so that
                    // when BT is enabled next time, device connection status shall be retrieved
                    // by making a binder call.
                    notCachedDevice.clearProfileConnectionState();
                }
            }
        }
    }

@@ -177,6 +309,49 @@ public class CachedBluetoothDeviceManager {
        }
    }

    public synchronized void onHiSyncIdChanged(long hiSyncId) {
        int firstMatchedIndex = -1;

        for (int i = mCachedDevices.size() - 1; i >= 0; i--) {
            CachedBluetoothDevice cachedDevice = mCachedDevices.get(i);
            if (cachedDevice.getHiSyncId() == hiSyncId) {
                if (firstMatchedIndex != -1) {
                    /* Found the second one */
                    mCachedDevices.remove(i);
                    mHearingAidDevicesNotAddedInCache.add(cachedDevice);
                    // Since the hiSyncIds have been updated for a connected pair of hearing aids,
                    // we remove the entry of one the hearing aids from the UI. Unless the
                    // hiSyncId get updated, the system does not know its a hearing aid, so we add
                    // both the hearing aids as separate entries in the UI first, then remove one
                    // of them after the hiSyncId is populated.
                    log("onHiSyncIdChanged: removed device=" + cachedDevice + ", with hiSyncId="
                        + hiSyncId);
                    mBtManager.getEventManager().dispatchDeviceRemoved(cachedDevice);
                    break;
                } else {
                    mCachedDevicesMapForHearingAids.put(hiSyncId, cachedDevice);
                    firstMatchedIndex = i;
                }
            }
        }
    }

    public synchronized void onDeviceUnpaired(CachedBluetoothDevice device) {
        final long hiSyncId = device.getHiSyncId();

        if (hiSyncId == BluetoothHearingAid.HI_SYNC_ID_INVALID) return;

        for (int i = mHearingAidDevicesNotAddedInCache.size() - 1; i >= 0; i--) {
            CachedBluetoothDevice cachedDevice = mHearingAidDevicesNotAddedInCache.get(i);
            if (cachedDevice.getHiSyncId() == hiSyncId) {
                // TODO: Look for more cleanups on unpairing the device.
                mHearingAidDevicesNotAddedInCache.remove(i);
                if (device == cachedDevice) continue;
                cachedDevice.unpair();
            }
        }
    }

    private void log(String msg) {
        if (DEBUG) {
            Log.d(TAG, msg);
+9 −2
Original line number Diff line number Diff line
@@ -67,12 +67,19 @@ public class HearingAidProfile implements LocalBluetoothProfile {
                CachedBluetoothDevice device = mDeviceManager.findDevice(nextDevice);
                // we may add a new device here, but generally this should not happen
                if (device == null) {
                    Log.w(TAG, "HearingAidProfile found new device: " + nextDevice);
                    if (V) {
                        Log.d(TAG, "HearingAidProfile found new device: " + nextDevice);
                    }
                    device = mDeviceManager.addDevice(mLocalAdapter, mProfileManager, nextDevice);
                }
                device.onProfileStateChanged(HearingAidProfile.this, BluetoothProfile.STATE_CONNECTED);
                device.onProfileStateChanged(HearingAidProfile.this,
                        BluetoothProfile.STATE_CONNECTED);
                device.refresh();
            }

            // Check current list of CachedDevices to see if any are Hearing Aid devices.
            mDeviceManager.updateHearingAidsDevices(mProfileManager);

            mIsProfileReady=true;
        }

+16 −0
Original line number Diff line number Diff line
@@ -354,6 +354,22 @@ public class LocalBluetoothProfileManager {
                    oldState == BluetoothProfile.STATE_CONNECTING) {
                Log.i(TAG, "Failed to connect " + mProfile + " device");
            }

            if (getHearingAidProfile() != null &&
                mProfile instanceof HearingAidProfile &&
                (newState == BluetoothProfile.STATE_CONNECTED)) {
                // Check if the HiSyncID has being initialized
                if (cachedDevice.getHiSyncId() == BluetoothHearingAid.HI_SYNC_ID_INVALID) {

                    long newHiSyncId = getHearingAidProfile().getHiSyncId(cachedDevice.getDevice());

                    if (newHiSyncId != BluetoothHearingAid.HI_SYNC_ID_INVALID) {
                        cachedDevice.setHiSyncId(newHiSyncId);
                        mDeviceManager.onHiSyncIdChanged(newHiSyncId);
                    }
                }
            }

            cachedDevice.onProfileStateChanged(mProfile, newState);
            cachedDevice.refresh();
        }
Loading