Loading packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java +0 −1 Original line number Diff line number Diff line Loading @@ -171,7 +171,6 @@ public class BluetoothEventManager { callback.onProfileConnectionStateChanged(device, state, bluetoothProfile); } } mDeviceManager.onProfileConnectionStateChanged(device, state, bluetoothProfile); } private void dispatchConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state) { Loading packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java +33 −6 Original line number Diff line number Diff line Loading @@ -29,6 +29,8 @@ import android.os.SystemClock; import android.text.TextUtils; import android.util.Log; import androidx.annotation.VisibleForTesting; import com.android.settingslib.R; import java.util.ArrayList; Loading @@ -36,8 +38,6 @@ import java.util.Collection; import java.util.Collections; import java.util.List; import androidx.annotation.VisibleForTesting; /** * CachedBluetoothDevice represents a remote Bluetooth device. It contains * attributes of the device (such as the address, name, RSSI, etc.) and Loading @@ -54,11 +54,12 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> private final Context mContext; private final BluetoothAdapter mLocalAdapter; private final LocalBluetoothProfileManager mProfileManager; private final BluetoothDevice mDevice; BluetoothDevice mDevice; private long mHiSyncId; // Need this since there is no method for getting RSSI private short mRssi; short mRssi; // mProfiles and mRemovedProfiles does not do swap() between main and sub device. It is // because current sub device is only for HearingAid and its profile is the same. private final List<LocalBluetoothProfile> mProfiles = Collections.synchronizedList(new ArrayList<>()); Loading @@ -69,7 +70,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> // Device supports PANU but not NAP: remove PanProfile after device disconnects from NAP private boolean mLocalNapRoleConnected; private boolean mJustDiscovered; boolean mJustDiscovered; private int mMessageRejectionCount; Loading @@ -92,6 +93,8 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> private boolean mIsActiveDeviceA2dp = false; private boolean mIsActiveDeviceHeadset = false; private boolean mIsActiveDeviceHearingAid = false; // Group second device for Hearing Aid private CachedBluetoothDevice mSubDevice; CachedBluetoothDevice(Context context, LocalBluetoothProfileManager profileManager, BluetoothDevice device) { Loading Loading @@ -1064,4 +1067,28 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> return hearingAidProfile != null && hearingAidProfile.getConnectionStatus(mDevice) == BluetoothProfile.STATE_CONNECTED; } public CachedBluetoothDevice getSubDevice() { return mSubDevice; } public void setSubDevice(CachedBluetoothDevice subDevice) { mSubDevice = subDevice; } public void switchSubDeviceContent() { // Backup from main device BluetoothDevice tmpDevice = mDevice; short tmpRssi = mRssi; boolean tmpJustDiscovered = mJustDiscovered; // Set main device from sub device mDevice = mSubDevice.mDevice; mRssi = mSubDevice.mRssi; mJustDiscovered = mSubDevice.mJustDiscovered; // Set sub device from backup mSubDevice.mDevice = tmpDevice; mSubDevice.mRssi = tmpRssi; mSubDevice.mJustDiscovered = tmpJustDiscovered; fetchActiveDevices(); } } packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java +56 −243 Original line number Diff line number Diff line Loading @@ -18,8 +18,6 @@ package com.android.settingslib.bluetooth; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHearingAid; import android.bluetooth.BluetoothProfile; import android.content.Context; import android.util.Log; Loading @@ -27,12 +25,8 @@ import com.android.internal.annotations.VisibleForTesting; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; /** * CachedBluetoothDeviceManager manages the set of remote Bluetooth devices. Loading @@ -45,20 +39,14 @@ public class CachedBluetoothDeviceManager { 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. final List<CachedBluetoothDevice> mCachedDevices = new ArrayList<CachedBluetoothDevice>(); @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>(); HearingAidDeviceManager mHearingAidDeviceManager; CachedBluetoothDeviceManager(Context context, LocalBluetoothManager localBtManager) { mContext = context; mBtManager = localBtManager; mHearingAidDeviceManager = new HearingAidDeviceManager(localBtManager, mCachedDevices); } public synchronized Collection<CachedBluetoothDevice> getCachedDevicesCopy() { Loading Loading @@ -92,12 +80,13 @@ public class CachedBluetoothDeviceManager { if (cachedDevice.getDevice().equals(device)) { return cachedDevice; } } for (CachedBluetoothDevice notCachedDevice : mHearingAidDevicesNotAddedInCache) { if (notCachedDevice.getDevice().equals(device)) { return notCachedDevice; // Check sub devices if it exists CachedBluetoothDevice subDevice = cachedDevice.getSubDevice(); if (subDevice != null && subDevice.getDevice().equals(device)) { return subDevice; } } return null; } Loading @@ -111,24 +100,10 @@ public class CachedBluetoothDeviceManager { LocalBluetoothProfileManager profileManager = mBtManager.getProfileManager(); CachedBluetoothDevice newDevice = new CachedBluetoothDevice(mContext, profileManager, device); 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 { mHearingAidDeviceManager.initHearingAidDeviceIfNeeded(newDevice); synchronized (this) { if (!mHearingAidDeviceManager.setSubDeviceIfNeeded(newDevice)) { mCachedDevices.add(newDevice); if (newDevice.getHiSyncId() != BluetoothHearingAid.HI_SYNC_ID_INVALID && !mCachedDevicesMapForHearingAids.containsKey(newDevice.getHiSyncId())) { mCachedDevicesMapForHearingAids.put(newDevice.getHiSyncId(), newDevice); } mBtManager.getEventManager().dispatchDeviceAdded(newDevice); } } Loading @@ -136,50 +111,19 @@ public class CachedBluetoothDeviceManager { 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, * @return Device summary, or if the pair does not exist or if it is 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(); } } public synchronized String getSubDeviceSummary(CachedBluetoothDevice device) { CachedBluetoothDevice subDevice = device.getSubDevice(); if (subDevice != null && subDevice.isConnected()) { return subDevice.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); return null; } /** Loading @@ -187,28 +131,8 @@ public class CachedBluetoothDeviceManager { * 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; } final Set<Long> syncIdChangedSet = new HashSet<Long>(); 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); syncIdChangedSet.add(newHiSyncId); } } for (Long syncId : syncIdChangedSet) { onHiSyncIdChanged(syncId); } public synchronized void updateHearingAidsDevices() { mHearingAidDeviceManager.updateHearingAidsDevices(); } /** Loading @@ -232,15 +156,21 @@ public class CachedBluetoothDeviceManager { } public synchronized void clearNonBondedDevices() { mCachedDevicesMapForHearingAids.entrySet().removeIf(entries -> entries.getValue().getBondState() == BluetoothDevice.BOND_NONE); clearNonBondedSubDevices(); mCachedDevices.removeIf(cachedDevice -> cachedDevice.getBondState() == BluetoothDevice.BOND_NONE); } mHearingAidDevicesNotAddedInCache.removeIf(hearingAidDevice -> hearingAidDevice.getBondState() == BluetoothDevice.BOND_NONE); private void clearNonBondedSubDevices() { for (int i = mCachedDevices.size() - 1; i >= 0; i--) { CachedBluetoothDevice cachedDevice = mCachedDevices.get(i); CachedBluetoothDevice subDevice = cachedDevice.getSubDevice(); if (subDevice != null && subDevice.getDevice().getBondState() == BluetoothDevice.BOND_NONE) { // Sub device exists and it is not bonded cachedDevice.setSubDevice(null); } } } public synchronized void onScanningStateChanged(boolean started) { Loading @@ -250,10 +180,10 @@ public class CachedBluetoothDeviceManager { for (int i = mCachedDevices.size() - 1; i >= 0; i--) { CachedBluetoothDevice cachedDevice = mCachedDevices.get(i); cachedDevice.setJustDiscovered(false); final CachedBluetoothDevice subDevice = cachedDevice.getSubDevice(); if (subDevice != null) { subDevice.setJustDiscovered(false); } for (int i = mHearingAidDevicesNotAddedInCache.size() - 1; i >= 0; i--) { CachedBluetoothDevice notCachedDevice = mHearingAidDevicesNotAddedInCache.get(i); notCachedDevice.setJustDiscovered(false); } } Loading @@ -277,21 +207,15 @@ public class CachedBluetoothDeviceManager { if (bluetoothState == BluetoothAdapter.STATE_TURNING_OFF) { for (int i = mCachedDevices.size() - 1; i >= 0; i--) { CachedBluetoothDevice cachedDevice = mCachedDevices.get(i); CachedBluetoothDevice subDevice = cachedDevice.getSubDevice(); if (subDevice != null) { if (subDevice.getBondState() != BluetoothDevice.BOND_BONDED) { cachedDevice.setSubDevice(null); } } 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()); } } } 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); } } } Loading @@ -305,134 +229,23 @@ 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 */ int indexToRemoveFromUi; CachedBluetoothDevice deviceToRemoveFromUi; // 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 it is 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. We will choose the device that // is not connected to be removed. if (cachedDevice.isConnected()) { indexToRemoveFromUi = firstMatchedIndex; deviceToRemoveFromUi = mCachedDevices.get(firstMatchedIndex); mCachedDevicesMapForHearingAids.put(hiSyncId, cachedDevice); } else { indexToRemoveFromUi = i; deviceToRemoveFromUi = cachedDevice; mCachedDevicesMapForHearingAids.put(hiSyncId, mCachedDevices.get(firstMatchedIndex)); } mCachedDevices.remove(indexToRemoveFromUi); mHearingAidDevicesNotAddedInCache.add(deviceToRemoveFromUi); log("onHiSyncIdChanged: removed from UI device=" + deviceToRemoveFromUi + ", with hiSyncId=" + hiSyncId); mBtManager.getEventManager().dispatchDeviceRemoved(deviceToRemoveFromUi); break; } else { mCachedDevicesMapForHearingAids.put(hiSyncId, cachedDevice); firstMatchedIndex = i; } } } } private CachedBluetoothDevice getHearingAidOtherDevice(CachedBluetoothDevice thisDevice, long hiSyncId) { if (hiSyncId == BluetoothHearingAid.HI_SYNC_ID_INVALID) { return null; } // Searched the lists for the other side device with the matching hiSyncId. for (CachedBluetoothDevice notCachedDevice : mHearingAidDevicesNotAddedInCache) { if ((hiSyncId == notCachedDevice.getHiSyncId()) && (!Objects.equals(notCachedDevice, thisDevice))) { return notCachedDevice; } } CachedBluetoothDevice cachedDevice = mCachedDevicesMapForHearingAids.get(hiSyncId); if (!Objects.equals(cachedDevice, thisDevice)) { return cachedDevice; } return null; } private void hearingAidSwitchDisplayDevice(CachedBluetoothDevice toDisplayDevice, CachedBluetoothDevice toHideDevice, long hiSyncId) { log("hearingAidSwitchDisplayDevice: toDisplayDevice=" + toDisplayDevice + ", toHideDevice=" + toHideDevice); // Remove the "toHideDevice" device from the UI. mHearingAidDevicesNotAddedInCache.add(toHideDevice); mCachedDevices.remove(toHideDevice); mBtManager.getEventManager().dispatchDeviceRemoved(toHideDevice); // Add the "toDisplayDevice" device to the UI. mHearingAidDevicesNotAddedInCache.remove(toDisplayDevice); mCachedDevices.add(toDisplayDevice); mCachedDevicesMapForHearingAids.put(hiSyncId, toDisplayDevice); mBtManager.getEventManager().dispatchDeviceAdded(toDisplayDevice); } public synchronized void onProfileConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state, int bluetoothProfile) { if (bluetoothProfile == BluetoothProfile.HEARING_AID && cachedDevice.getHiSyncId() != BluetoothHearingAid.HI_SYNC_ID_INVALID && cachedDevice.getBondState() == BluetoothDevice.BOND_BONDED) { long hiSyncId = cachedDevice.getHiSyncId(); CachedBluetoothDevice otherDevice = getHearingAidOtherDevice(cachedDevice, hiSyncId); if (otherDevice == null) { // no other side device. Nothing to do. return; } if (state == BluetoothProfile.STATE_CONNECTED && mHearingAidDevicesNotAddedInCache.contains(cachedDevice)) { hearingAidSwitchDisplayDevice(cachedDevice, otherDevice, hiSyncId); } else if (state == BluetoothProfile.STATE_DISCONNECTED && otherDevice.isConnected()) { CachedBluetoothDevice mapDevice = mCachedDevicesMapForHearingAids.get(hiSyncId); if ((mapDevice != null) && (Objects.equals(cachedDevice, mapDevice))) { hearingAidSwitchDisplayDevice(otherDevice, cachedDevice, hiSyncId); } } } public synchronized boolean onProfileConnectionStateChangedIfProcessed(CachedBluetoothDevice cachedDevice, int state) { return mHearingAidDeviceManager.onProfileConnectionStateChangedIfProcessed(cachedDevice, state); } 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; log("onDeviceUnpaired: Unpair device=" + cachedDevice); cachedDevice.unpair(); } } CachedBluetoothDevice mappedDevice = mCachedDevicesMapForHearingAids.get(hiSyncId); if ((mappedDevice != null) && (!Objects.equals(device, mappedDevice))) { log("onDeviceUnpaired: Unpair mapped device=" + mappedDevice); mappedDevice.unpair(); CachedBluetoothDevice mainDevice = mHearingAidDeviceManager.findMainDevice(device); CachedBluetoothDevice subDevice = device.getSubDevice(); if (subDevice != null) { // Main device is unpaired, to unpair sub device subDevice.unpair(); device.setSubDevice(null); } else if (mainDevice != null) { // Sub device unpaired, to unpair main device mainDevice.unpair(); mainDevice.setSubDevice(null); } } Loading packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidDeviceManager.java 0 → 100644 +223 −0 File added.Preview size limit exceeded, changes collapsed. Show changes packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java +1 −1 Original line number Diff line number Diff line Loading @@ -71,7 +71,7 @@ public class HearingAidProfile implements LocalBluetoothProfile { } // Check current list of CachedDevices to see if any are Hearing Aid devices. mDeviceManager.updateHearingAidsDevices(mProfileManager); mDeviceManager.updateHearingAidsDevices(); mIsProfileReady=true; } Loading Loading
packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java +0 −1 Original line number Diff line number Diff line Loading @@ -171,7 +171,6 @@ public class BluetoothEventManager { callback.onProfileConnectionStateChanged(device, state, bluetoothProfile); } } mDeviceManager.onProfileConnectionStateChanged(device, state, bluetoothProfile); } private void dispatchConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state) { Loading
packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java +33 −6 Original line number Diff line number Diff line Loading @@ -29,6 +29,8 @@ import android.os.SystemClock; import android.text.TextUtils; import android.util.Log; import androidx.annotation.VisibleForTesting; import com.android.settingslib.R; import java.util.ArrayList; Loading @@ -36,8 +38,6 @@ import java.util.Collection; import java.util.Collections; import java.util.List; import androidx.annotation.VisibleForTesting; /** * CachedBluetoothDevice represents a remote Bluetooth device. It contains * attributes of the device (such as the address, name, RSSI, etc.) and Loading @@ -54,11 +54,12 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> private final Context mContext; private final BluetoothAdapter mLocalAdapter; private final LocalBluetoothProfileManager mProfileManager; private final BluetoothDevice mDevice; BluetoothDevice mDevice; private long mHiSyncId; // Need this since there is no method for getting RSSI private short mRssi; short mRssi; // mProfiles and mRemovedProfiles does not do swap() between main and sub device. It is // because current sub device is only for HearingAid and its profile is the same. private final List<LocalBluetoothProfile> mProfiles = Collections.synchronizedList(new ArrayList<>()); Loading @@ -69,7 +70,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> // Device supports PANU but not NAP: remove PanProfile after device disconnects from NAP private boolean mLocalNapRoleConnected; private boolean mJustDiscovered; boolean mJustDiscovered; private int mMessageRejectionCount; Loading @@ -92,6 +93,8 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> private boolean mIsActiveDeviceA2dp = false; private boolean mIsActiveDeviceHeadset = false; private boolean mIsActiveDeviceHearingAid = false; // Group second device for Hearing Aid private CachedBluetoothDevice mSubDevice; CachedBluetoothDevice(Context context, LocalBluetoothProfileManager profileManager, BluetoothDevice device) { Loading Loading @@ -1064,4 +1067,28 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> return hearingAidProfile != null && hearingAidProfile.getConnectionStatus(mDevice) == BluetoothProfile.STATE_CONNECTED; } public CachedBluetoothDevice getSubDevice() { return mSubDevice; } public void setSubDevice(CachedBluetoothDevice subDevice) { mSubDevice = subDevice; } public void switchSubDeviceContent() { // Backup from main device BluetoothDevice tmpDevice = mDevice; short tmpRssi = mRssi; boolean tmpJustDiscovered = mJustDiscovered; // Set main device from sub device mDevice = mSubDevice.mDevice; mRssi = mSubDevice.mRssi; mJustDiscovered = mSubDevice.mJustDiscovered; // Set sub device from backup mSubDevice.mDevice = tmpDevice; mSubDevice.mRssi = tmpRssi; mSubDevice.mJustDiscovered = tmpJustDiscovered; fetchActiveDevices(); } }
packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java +56 −243 Original line number Diff line number Diff line Loading @@ -18,8 +18,6 @@ package com.android.settingslib.bluetooth; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHearingAid; import android.bluetooth.BluetoothProfile; import android.content.Context; import android.util.Log; Loading @@ -27,12 +25,8 @@ import com.android.internal.annotations.VisibleForTesting; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; /** * CachedBluetoothDeviceManager manages the set of remote Bluetooth devices. Loading @@ -45,20 +39,14 @@ public class CachedBluetoothDeviceManager { 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. final List<CachedBluetoothDevice> mCachedDevices = new ArrayList<CachedBluetoothDevice>(); @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>(); HearingAidDeviceManager mHearingAidDeviceManager; CachedBluetoothDeviceManager(Context context, LocalBluetoothManager localBtManager) { mContext = context; mBtManager = localBtManager; mHearingAidDeviceManager = new HearingAidDeviceManager(localBtManager, mCachedDevices); } public synchronized Collection<CachedBluetoothDevice> getCachedDevicesCopy() { Loading Loading @@ -92,12 +80,13 @@ public class CachedBluetoothDeviceManager { if (cachedDevice.getDevice().equals(device)) { return cachedDevice; } } for (CachedBluetoothDevice notCachedDevice : mHearingAidDevicesNotAddedInCache) { if (notCachedDevice.getDevice().equals(device)) { return notCachedDevice; // Check sub devices if it exists CachedBluetoothDevice subDevice = cachedDevice.getSubDevice(); if (subDevice != null && subDevice.getDevice().equals(device)) { return subDevice; } } return null; } Loading @@ -111,24 +100,10 @@ public class CachedBluetoothDeviceManager { LocalBluetoothProfileManager profileManager = mBtManager.getProfileManager(); CachedBluetoothDevice newDevice = new CachedBluetoothDevice(mContext, profileManager, device); 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 { mHearingAidDeviceManager.initHearingAidDeviceIfNeeded(newDevice); synchronized (this) { if (!mHearingAidDeviceManager.setSubDeviceIfNeeded(newDevice)) { mCachedDevices.add(newDevice); if (newDevice.getHiSyncId() != BluetoothHearingAid.HI_SYNC_ID_INVALID && !mCachedDevicesMapForHearingAids.containsKey(newDevice.getHiSyncId())) { mCachedDevicesMapForHearingAids.put(newDevice.getHiSyncId(), newDevice); } mBtManager.getEventManager().dispatchDeviceAdded(newDevice); } } Loading @@ -136,50 +111,19 @@ public class CachedBluetoothDeviceManager { 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, * @return Device summary, or if the pair does not exist or if it is 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(); } } public synchronized String getSubDeviceSummary(CachedBluetoothDevice device) { CachedBluetoothDevice subDevice = device.getSubDevice(); if (subDevice != null && subDevice.isConnected()) { return subDevice.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); return null; } /** Loading @@ -187,28 +131,8 @@ public class CachedBluetoothDeviceManager { * 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; } final Set<Long> syncIdChangedSet = new HashSet<Long>(); 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); syncIdChangedSet.add(newHiSyncId); } } for (Long syncId : syncIdChangedSet) { onHiSyncIdChanged(syncId); } public synchronized void updateHearingAidsDevices() { mHearingAidDeviceManager.updateHearingAidsDevices(); } /** Loading @@ -232,15 +156,21 @@ public class CachedBluetoothDeviceManager { } public synchronized void clearNonBondedDevices() { mCachedDevicesMapForHearingAids.entrySet().removeIf(entries -> entries.getValue().getBondState() == BluetoothDevice.BOND_NONE); clearNonBondedSubDevices(); mCachedDevices.removeIf(cachedDevice -> cachedDevice.getBondState() == BluetoothDevice.BOND_NONE); } mHearingAidDevicesNotAddedInCache.removeIf(hearingAidDevice -> hearingAidDevice.getBondState() == BluetoothDevice.BOND_NONE); private void clearNonBondedSubDevices() { for (int i = mCachedDevices.size() - 1; i >= 0; i--) { CachedBluetoothDevice cachedDevice = mCachedDevices.get(i); CachedBluetoothDevice subDevice = cachedDevice.getSubDevice(); if (subDevice != null && subDevice.getDevice().getBondState() == BluetoothDevice.BOND_NONE) { // Sub device exists and it is not bonded cachedDevice.setSubDevice(null); } } } public synchronized void onScanningStateChanged(boolean started) { Loading @@ -250,10 +180,10 @@ public class CachedBluetoothDeviceManager { for (int i = mCachedDevices.size() - 1; i >= 0; i--) { CachedBluetoothDevice cachedDevice = mCachedDevices.get(i); cachedDevice.setJustDiscovered(false); final CachedBluetoothDevice subDevice = cachedDevice.getSubDevice(); if (subDevice != null) { subDevice.setJustDiscovered(false); } for (int i = mHearingAidDevicesNotAddedInCache.size() - 1; i >= 0; i--) { CachedBluetoothDevice notCachedDevice = mHearingAidDevicesNotAddedInCache.get(i); notCachedDevice.setJustDiscovered(false); } } Loading @@ -277,21 +207,15 @@ public class CachedBluetoothDeviceManager { if (bluetoothState == BluetoothAdapter.STATE_TURNING_OFF) { for (int i = mCachedDevices.size() - 1; i >= 0; i--) { CachedBluetoothDevice cachedDevice = mCachedDevices.get(i); CachedBluetoothDevice subDevice = cachedDevice.getSubDevice(); if (subDevice != null) { if (subDevice.getBondState() != BluetoothDevice.BOND_BONDED) { cachedDevice.setSubDevice(null); } } 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()); } } } 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); } } } Loading @@ -305,134 +229,23 @@ 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 */ int indexToRemoveFromUi; CachedBluetoothDevice deviceToRemoveFromUi; // 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 it is 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. We will choose the device that // is not connected to be removed. if (cachedDevice.isConnected()) { indexToRemoveFromUi = firstMatchedIndex; deviceToRemoveFromUi = mCachedDevices.get(firstMatchedIndex); mCachedDevicesMapForHearingAids.put(hiSyncId, cachedDevice); } else { indexToRemoveFromUi = i; deviceToRemoveFromUi = cachedDevice; mCachedDevicesMapForHearingAids.put(hiSyncId, mCachedDevices.get(firstMatchedIndex)); } mCachedDevices.remove(indexToRemoveFromUi); mHearingAidDevicesNotAddedInCache.add(deviceToRemoveFromUi); log("onHiSyncIdChanged: removed from UI device=" + deviceToRemoveFromUi + ", with hiSyncId=" + hiSyncId); mBtManager.getEventManager().dispatchDeviceRemoved(deviceToRemoveFromUi); break; } else { mCachedDevicesMapForHearingAids.put(hiSyncId, cachedDevice); firstMatchedIndex = i; } } } } private CachedBluetoothDevice getHearingAidOtherDevice(CachedBluetoothDevice thisDevice, long hiSyncId) { if (hiSyncId == BluetoothHearingAid.HI_SYNC_ID_INVALID) { return null; } // Searched the lists for the other side device with the matching hiSyncId. for (CachedBluetoothDevice notCachedDevice : mHearingAidDevicesNotAddedInCache) { if ((hiSyncId == notCachedDevice.getHiSyncId()) && (!Objects.equals(notCachedDevice, thisDevice))) { return notCachedDevice; } } CachedBluetoothDevice cachedDevice = mCachedDevicesMapForHearingAids.get(hiSyncId); if (!Objects.equals(cachedDevice, thisDevice)) { return cachedDevice; } return null; } private void hearingAidSwitchDisplayDevice(CachedBluetoothDevice toDisplayDevice, CachedBluetoothDevice toHideDevice, long hiSyncId) { log("hearingAidSwitchDisplayDevice: toDisplayDevice=" + toDisplayDevice + ", toHideDevice=" + toHideDevice); // Remove the "toHideDevice" device from the UI. mHearingAidDevicesNotAddedInCache.add(toHideDevice); mCachedDevices.remove(toHideDevice); mBtManager.getEventManager().dispatchDeviceRemoved(toHideDevice); // Add the "toDisplayDevice" device to the UI. mHearingAidDevicesNotAddedInCache.remove(toDisplayDevice); mCachedDevices.add(toDisplayDevice); mCachedDevicesMapForHearingAids.put(hiSyncId, toDisplayDevice); mBtManager.getEventManager().dispatchDeviceAdded(toDisplayDevice); } public synchronized void onProfileConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state, int bluetoothProfile) { if (bluetoothProfile == BluetoothProfile.HEARING_AID && cachedDevice.getHiSyncId() != BluetoothHearingAid.HI_SYNC_ID_INVALID && cachedDevice.getBondState() == BluetoothDevice.BOND_BONDED) { long hiSyncId = cachedDevice.getHiSyncId(); CachedBluetoothDevice otherDevice = getHearingAidOtherDevice(cachedDevice, hiSyncId); if (otherDevice == null) { // no other side device. Nothing to do. return; } if (state == BluetoothProfile.STATE_CONNECTED && mHearingAidDevicesNotAddedInCache.contains(cachedDevice)) { hearingAidSwitchDisplayDevice(cachedDevice, otherDevice, hiSyncId); } else if (state == BluetoothProfile.STATE_DISCONNECTED && otherDevice.isConnected()) { CachedBluetoothDevice mapDevice = mCachedDevicesMapForHearingAids.get(hiSyncId); if ((mapDevice != null) && (Objects.equals(cachedDevice, mapDevice))) { hearingAidSwitchDisplayDevice(otherDevice, cachedDevice, hiSyncId); } } } public synchronized boolean onProfileConnectionStateChangedIfProcessed(CachedBluetoothDevice cachedDevice, int state) { return mHearingAidDeviceManager.onProfileConnectionStateChangedIfProcessed(cachedDevice, state); } 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; log("onDeviceUnpaired: Unpair device=" + cachedDevice); cachedDevice.unpair(); } } CachedBluetoothDevice mappedDevice = mCachedDevicesMapForHearingAids.get(hiSyncId); if ((mappedDevice != null) && (!Objects.equals(device, mappedDevice))) { log("onDeviceUnpaired: Unpair mapped device=" + mappedDevice); mappedDevice.unpair(); CachedBluetoothDevice mainDevice = mHearingAidDeviceManager.findMainDevice(device); CachedBluetoothDevice subDevice = device.getSubDevice(); if (subDevice != null) { // Main device is unpaired, to unpair sub device subDevice.unpair(); device.setSubDevice(null); } else if (mainDevice != null) { // Sub device unpaired, to unpair main device mainDevice.unpair(); mainDevice.setSubDevice(null); } } Loading
packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidDeviceManager.java 0 → 100644 +223 −0 File added.Preview size limit exceeded, changes collapsed. Show changes
packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java +1 −1 Original line number Diff line number Diff line Loading @@ -71,7 +71,7 @@ public class HearingAidProfile implements LocalBluetoothProfile { } // Check current list of CachedDevices to see if any are Hearing Aid devices. mDeviceManager.updateHearingAidsDevices(mProfileManager); mDeviceManager.updateHearingAidsDevices(); mIsProfileReady=true; } Loading