Loading packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java +152 −126 Original line number Diff line number Diff line Loading @@ -54,18 +54,17 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> private final Context mContext; private final BluetoothAdapter mLocalAdapter; private final LocalBluetoothProfileManager mProfileManager; private final Object mProfileLock = new Object(); BluetoothDevice mDevice; private long mHiSyncId; // Need this since there is no method for getting RSSI 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<>()); private final List<LocalBluetoothProfile> mProfiles = new ArrayList<>(); // List of profiles that were previously in mProfiles, but have been removed private final List<LocalBluetoothProfile> mRemovedProfiles = Collections.synchronizedList(new ArrayList<>()); private final List<LocalBluetoothProfile> mRemovedProfiles = new ArrayList<>(); // Device supports PANU but not NAP: remove PanProfile after device disconnects from NAP private boolean mLocalNapRoleConnected; Loading @@ -74,7 +73,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> private int mMessageRejectionCount; private final Collection<Callback> mCallbacks = new ArrayList<Callback>(); private final Collection<Callback> mCallbacks = new ArrayList<>(); // How many times user should reject the connection to make the choice persist. private final static int MESSAGE_REJECTION_COUNT_LIMIT_TO_PERSIST = 2; Loading Loading @@ -134,6 +133,8 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> } return; } synchronized (mProfileLock) { if (newProfileState == BluetoothProfile.STATE_CONNECTED) { if (profile instanceof MapProfile) { profile.setPreferred(mDevice, true); Loading @@ -141,30 +142,34 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> if (!mProfiles.contains(profile)) { mRemovedProfiles.remove(profile); mProfiles.add(profile); if (profile instanceof PanProfile && ((PanProfile) profile).isLocalRoleNap(mDevice)) { if (profile instanceof PanProfile && ((PanProfile) profile).isLocalRoleNap(mDevice)) { // Device doesn't support NAP, so remove PanProfile on disconnect mLocalNapRoleConnected = true; } } } else if (profile instanceof MapProfile && newProfileState == BluetoothProfile.STATE_DISCONNECTED) { } else if (profile instanceof MapProfile && newProfileState == BluetoothProfile.STATE_DISCONNECTED) { profile.setPreferred(mDevice, false); } else if (mLocalNapRoleConnected && profile instanceof PanProfile && ((PanProfile) profile).isLocalRoleNap(mDevice) && newProfileState == BluetoothProfile.STATE_DISCONNECTED) { } else if (mLocalNapRoleConnected && profile instanceof PanProfile && ((PanProfile) profile).isLocalRoleNap(mDevice) && newProfileState == BluetoothProfile.STATE_DISCONNECTED) { Log.d(TAG, "Removing PanProfile from device after NAP disconnect"); mProfiles.remove(profile); mRemovedProfiles.add(profile); mLocalNapRoleConnected = false; } } fetchActiveDevices(); } public void disconnect() { synchronized (mProfileLock) { for (LocalBluetoothProfile profile : mProfiles) { disconnect(profile); } } // Disconnect PBAP server in case its connected // This is to ensure all the profiles are disconnected as some CK/Hs do not // disconnect PBAP connection when HF connection is brought down Loading Loading @@ -210,11 +215,12 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> } private void connectWithoutResettingTimer(boolean connectAllProfiles) { synchronized (mProfileLock) { // Try to initialize the profiles if they were not. if (mProfiles.isEmpty()) { // if mProfiles is empty, then do not invoke updateProfiles. This causes a race // condition with carkits during pairing, wherein RemoteDevice.UUIDs have been updated // from bluetooth stack but ACTION.uuid is not sent yet. // condition with carkits during pairing, wherein RemoteDevice.UUIDs have been // updated from bluetooth stack but ACTION.uuid is not sent yet. // Eventually ACTION.uuid will be received which shall trigger the connection of the // various profiles // If UUIDs are not available yet, connect will be happen Loading @@ -225,7 +231,8 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> int preferredProfiles = 0; for (LocalBluetoothProfile profile : mProfiles) { if (connectAllProfiles ? profile.accessProfileEnabled() : profile.isAutoConnectable()) { if (connectAllProfiles ? profile.accessProfileEnabled() : profile.isAutoConnectable()) { if (profile.isPreferred(mDevice)) { ++preferredProfiles; connectInt(profile); Loading @@ -238,12 +245,14 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> connectAutoConnectableProfiles(); } } } private void connectAutoConnectableProfiles() { if (!ensurePaired()) { return; } synchronized (mProfileLock) { for (LocalBluetoothProfile profile : mProfiles) { if (profile.isAutoConnectable()) { profile.setPreferred(mDevice, true); Loading @@ -251,6 +260,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> } } } } /** * Connect this device to the specified profile. Loading Loading @@ -515,6 +525,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> * @return Whether it is connected. */ public boolean isConnected() { synchronized (mProfileLock) { for (LocalBluetoothProfile profile : mProfiles) { int status = getProfileConnectionState(profile); if (status == BluetoothProfile.STATE_CONNECTED) { Loading @@ -524,6 +535,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> return false; } } public boolean isConnectedProfile(LocalBluetoothProfile profile) { int status = getProfileConnectionState(profile); Loading @@ -532,6 +544,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> } public boolean isBusy() { synchronized (mProfileLock) { for (LocalBluetoothProfile profile : mProfiles) { int status = getProfileConnectionState(profile); if (status == BluetoothProfile.STATE_CONNECTING Loading @@ -541,6 +554,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> } return getBondState() == BluetoothDevice.BOND_BONDING; } } private boolean updateProfiles() { ParcelUuid[] uuids = mDevice.getUuids(); Loading @@ -554,8 +568,10 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> */ processPhonebookAccess(); synchronized (mProfileLock) { mProfileManager.updateProfiles(uuids, localUuids, mProfiles, mRemovedProfiles, mLocalNapRoleConnected, mDevice); } if (BluetoothUtils.D) { Log.e(TAG, "updating profiles for " + mDevice.getAliasName()); Loading Loading @@ -616,7 +632,9 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> void onBondingStateChanged(int bondState) { if (bondState == BluetoothDevice.BOND_NONE) { synchronized (mProfileLock) { mProfiles.clear(); } mDevice.setPhonebookAccessPermission(BluetoothDevice.ACCESS_UNKNOWN); mDevice.setMessageAccessPermission(BluetoothDevice.ACCESS_UNKNOWN); mDevice.setSimAccessPermission(BluetoothDevice.ACCESS_UNKNOWN); Loading Loading @@ -646,11 +664,13 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> public List<LocalBluetoothProfile> getConnectableProfiles() { List<LocalBluetoothProfile> connectableProfiles = new ArrayList<LocalBluetoothProfile>(); synchronized (mProfileLock) { for (LocalBluetoothProfile profile : mProfiles) { if (profile.accessProfileEnabled()) { connectableProfiles.add(profile); } } } return connectableProfiles; } Loading Loading @@ -823,12 +843,14 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> public int getMaxConnectionState() { int maxState = BluetoothProfile.STATE_DISCONNECTED; synchronized (mProfileLock) { for (LocalBluetoothProfile profile : getProfiles()) { int connectionStatus = getProfileConnectionState(profile); if (connectionStatus > maxState) { maxState = connectionStatus; } } } return maxState; } Loading @@ -843,6 +865,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> boolean hfpConnected = true; // HFP is connected boolean hearingAidConnected = true; // Hearing Aid is connected synchronized (mProfileLock) { for (LocalBluetoothProfile profile : getProfiles()) { int connectionStatus = getProfileConnectionState(profile); Loading @@ -858,11 +881,11 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> case BluetoothProfile.STATE_DISCONNECTED: if (profile.isProfileReady()) { if ((profile instanceof A2dpProfile) || (profile instanceof A2dpSinkProfile)) { if (profile instanceof A2dpProfile || profile instanceof A2dpSinkProfile) { a2dpConnected = false; } else if ((profile instanceof HeadsetProfile) || (profile instanceof HfpClientProfile)) { } else if (profile instanceof HeadsetProfile || profile instanceof HfpClientProfile) { hfpConnected = false; } else if (profile instanceof HearingAidProfile) { hearingAidConnected = false; Loading @@ -871,6 +894,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> break; } } } String batteryLevelPercentageString = null; // Android framework should only set mBatteryLevel to valid range [0-100] or Loading Loading @@ -924,6 +948,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> boolean hfpNotConnected = false; // HFP is preferred but not connected boolean hearingAidNotConnected = false; // Hearing Aid is preferred but not connected synchronized (mProfileLock) { for (LocalBluetoothProfile profile : getProfiles()) { int connectionStatus = getProfileConnectionState(profile); Loading @@ -939,11 +964,11 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> case BluetoothProfile.STATE_DISCONNECTED: if (profile.isProfileReady()) { if ((profile instanceof A2dpProfile) || (profile instanceof A2dpSinkProfile)){ if (profile instanceof A2dpProfile || profile instanceof A2dpSinkProfile) { a2dpNotConnected = true; } else if ((profile instanceof HeadsetProfile) || (profile instanceof HfpClientProfile)) { } else if (profile instanceof HeadsetProfile || profile instanceof HfpClientProfile) { hfpNotConnected = true; } else if (profile instanceof HearingAidProfile) { hearingAidNotConnected = true; Loading @@ -952,6 +977,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> break; } } } String batteryLevelPercentageString = null; // Android framework should only set mBatteryLevel to valid range [0-100] or Loading packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java +1 −1 Original line number Diff line number Diff line Loading @@ -50,7 +50,7 @@ public class CachedBluetoothDeviceManager { } public synchronized Collection<CachedBluetoothDevice> getCachedDevicesCopy() { return new ArrayList<CachedBluetoothDevice>(mCachedDevices); return new ArrayList<>(mCachedDevices); } public static boolean onDeviceDisappeared(CachedBluetoothDevice cachedDevice) { Loading Loading
packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java +152 −126 Original line number Diff line number Diff line Loading @@ -54,18 +54,17 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> private final Context mContext; private final BluetoothAdapter mLocalAdapter; private final LocalBluetoothProfileManager mProfileManager; private final Object mProfileLock = new Object(); BluetoothDevice mDevice; private long mHiSyncId; // Need this since there is no method for getting RSSI 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<>()); private final List<LocalBluetoothProfile> mProfiles = new ArrayList<>(); // List of profiles that were previously in mProfiles, but have been removed private final List<LocalBluetoothProfile> mRemovedProfiles = Collections.synchronizedList(new ArrayList<>()); private final List<LocalBluetoothProfile> mRemovedProfiles = new ArrayList<>(); // Device supports PANU but not NAP: remove PanProfile after device disconnects from NAP private boolean mLocalNapRoleConnected; Loading @@ -74,7 +73,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> private int mMessageRejectionCount; private final Collection<Callback> mCallbacks = new ArrayList<Callback>(); private final Collection<Callback> mCallbacks = new ArrayList<>(); // How many times user should reject the connection to make the choice persist. private final static int MESSAGE_REJECTION_COUNT_LIMIT_TO_PERSIST = 2; Loading Loading @@ -134,6 +133,8 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> } return; } synchronized (mProfileLock) { if (newProfileState == BluetoothProfile.STATE_CONNECTED) { if (profile instanceof MapProfile) { profile.setPreferred(mDevice, true); Loading @@ -141,30 +142,34 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> if (!mProfiles.contains(profile)) { mRemovedProfiles.remove(profile); mProfiles.add(profile); if (profile instanceof PanProfile && ((PanProfile) profile).isLocalRoleNap(mDevice)) { if (profile instanceof PanProfile && ((PanProfile) profile).isLocalRoleNap(mDevice)) { // Device doesn't support NAP, so remove PanProfile on disconnect mLocalNapRoleConnected = true; } } } else if (profile instanceof MapProfile && newProfileState == BluetoothProfile.STATE_DISCONNECTED) { } else if (profile instanceof MapProfile && newProfileState == BluetoothProfile.STATE_DISCONNECTED) { profile.setPreferred(mDevice, false); } else if (mLocalNapRoleConnected && profile instanceof PanProfile && ((PanProfile) profile).isLocalRoleNap(mDevice) && newProfileState == BluetoothProfile.STATE_DISCONNECTED) { } else if (mLocalNapRoleConnected && profile instanceof PanProfile && ((PanProfile) profile).isLocalRoleNap(mDevice) && newProfileState == BluetoothProfile.STATE_DISCONNECTED) { Log.d(TAG, "Removing PanProfile from device after NAP disconnect"); mProfiles.remove(profile); mRemovedProfiles.add(profile); mLocalNapRoleConnected = false; } } fetchActiveDevices(); } public void disconnect() { synchronized (mProfileLock) { for (LocalBluetoothProfile profile : mProfiles) { disconnect(profile); } } // Disconnect PBAP server in case its connected // This is to ensure all the profiles are disconnected as some CK/Hs do not // disconnect PBAP connection when HF connection is brought down Loading Loading @@ -210,11 +215,12 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> } private void connectWithoutResettingTimer(boolean connectAllProfiles) { synchronized (mProfileLock) { // Try to initialize the profiles if they were not. if (mProfiles.isEmpty()) { // if mProfiles is empty, then do not invoke updateProfiles. This causes a race // condition with carkits during pairing, wherein RemoteDevice.UUIDs have been updated // from bluetooth stack but ACTION.uuid is not sent yet. // condition with carkits during pairing, wherein RemoteDevice.UUIDs have been // updated from bluetooth stack but ACTION.uuid is not sent yet. // Eventually ACTION.uuid will be received which shall trigger the connection of the // various profiles // If UUIDs are not available yet, connect will be happen Loading @@ -225,7 +231,8 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> int preferredProfiles = 0; for (LocalBluetoothProfile profile : mProfiles) { if (connectAllProfiles ? profile.accessProfileEnabled() : profile.isAutoConnectable()) { if (connectAllProfiles ? profile.accessProfileEnabled() : profile.isAutoConnectable()) { if (profile.isPreferred(mDevice)) { ++preferredProfiles; connectInt(profile); Loading @@ -238,12 +245,14 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> connectAutoConnectableProfiles(); } } } private void connectAutoConnectableProfiles() { if (!ensurePaired()) { return; } synchronized (mProfileLock) { for (LocalBluetoothProfile profile : mProfiles) { if (profile.isAutoConnectable()) { profile.setPreferred(mDevice, true); Loading @@ -251,6 +260,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> } } } } /** * Connect this device to the specified profile. Loading Loading @@ -515,6 +525,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> * @return Whether it is connected. */ public boolean isConnected() { synchronized (mProfileLock) { for (LocalBluetoothProfile profile : mProfiles) { int status = getProfileConnectionState(profile); if (status == BluetoothProfile.STATE_CONNECTED) { Loading @@ -524,6 +535,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> return false; } } public boolean isConnectedProfile(LocalBluetoothProfile profile) { int status = getProfileConnectionState(profile); Loading @@ -532,6 +544,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> } public boolean isBusy() { synchronized (mProfileLock) { for (LocalBluetoothProfile profile : mProfiles) { int status = getProfileConnectionState(profile); if (status == BluetoothProfile.STATE_CONNECTING Loading @@ -541,6 +554,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> } return getBondState() == BluetoothDevice.BOND_BONDING; } } private boolean updateProfiles() { ParcelUuid[] uuids = mDevice.getUuids(); Loading @@ -554,8 +568,10 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> */ processPhonebookAccess(); synchronized (mProfileLock) { mProfileManager.updateProfiles(uuids, localUuids, mProfiles, mRemovedProfiles, mLocalNapRoleConnected, mDevice); } if (BluetoothUtils.D) { Log.e(TAG, "updating profiles for " + mDevice.getAliasName()); Loading Loading @@ -616,7 +632,9 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> void onBondingStateChanged(int bondState) { if (bondState == BluetoothDevice.BOND_NONE) { synchronized (mProfileLock) { mProfiles.clear(); } mDevice.setPhonebookAccessPermission(BluetoothDevice.ACCESS_UNKNOWN); mDevice.setMessageAccessPermission(BluetoothDevice.ACCESS_UNKNOWN); mDevice.setSimAccessPermission(BluetoothDevice.ACCESS_UNKNOWN); Loading Loading @@ -646,11 +664,13 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> public List<LocalBluetoothProfile> getConnectableProfiles() { List<LocalBluetoothProfile> connectableProfiles = new ArrayList<LocalBluetoothProfile>(); synchronized (mProfileLock) { for (LocalBluetoothProfile profile : mProfiles) { if (profile.accessProfileEnabled()) { connectableProfiles.add(profile); } } } return connectableProfiles; } Loading Loading @@ -823,12 +843,14 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> public int getMaxConnectionState() { int maxState = BluetoothProfile.STATE_DISCONNECTED; synchronized (mProfileLock) { for (LocalBluetoothProfile profile : getProfiles()) { int connectionStatus = getProfileConnectionState(profile); if (connectionStatus > maxState) { maxState = connectionStatus; } } } return maxState; } Loading @@ -843,6 +865,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> boolean hfpConnected = true; // HFP is connected boolean hearingAidConnected = true; // Hearing Aid is connected synchronized (mProfileLock) { for (LocalBluetoothProfile profile : getProfiles()) { int connectionStatus = getProfileConnectionState(profile); Loading @@ -858,11 +881,11 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> case BluetoothProfile.STATE_DISCONNECTED: if (profile.isProfileReady()) { if ((profile instanceof A2dpProfile) || (profile instanceof A2dpSinkProfile)) { if (profile instanceof A2dpProfile || profile instanceof A2dpSinkProfile) { a2dpConnected = false; } else if ((profile instanceof HeadsetProfile) || (profile instanceof HfpClientProfile)) { } else if (profile instanceof HeadsetProfile || profile instanceof HfpClientProfile) { hfpConnected = false; } else if (profile instanceof HearingAidProfile) { hearingAidConnected = false; Loading @@ -871,6 +894,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> break; } } } String batteryLevelPercentageString = null; // Android framework should only set mBatteryLevel to valid range [0-100] or Loading Loading @@ -924,6 +948,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> boolean hfpNotConnected = false; // HFP is preferred but not connected boolean hearingAidNotConnected = false; // Hearing Aid is preferred but not connected synchronized (mProfileLock) { for (LocalBluetoothProfile profile : getProfiles()) { int connectionStatus = getProfileConnectionState(profile); Loading @@ -939,11 +964,11 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> case BluetoothProfile.STATE_DISCONNECTED: if (profile.isProfileReady()) { if ((profile instanceof A2dpProfile) || (profile instanceof A2dpSinkProfile)){ if (profile instanceof A2dpProfile || profile instanceof A2dpSinkProfile) { a2dpNotConnected = true; } else if ((profile instanceof HeadsetProfile) || (profile instanceof HfpClientProfile)) { } else if (profile instanceof HeadsetProfile || profile instanceof HfpClientProfile) { hfpNotConnected = true; } else if (profile instanceof HearingAidProfile) { hearingAidNotConnected = true; Loading @@ -952,6 +977,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> break; } } } String batteryLevelPercentageString = null; // Android framework should only set mBatteryLevel to valid range [0-100] or Loading
packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java +1 −1 Original line number Diff line number Diff line Loading @@ -50,7 +50,7 @@ public class CachedBluetoothDeviceManager { } public synchronized Collection<CachedBluetoothDevice> getCachedDevicesCopy() { return new ArrayList<CachedBluetoothDevice>(mCachedDevices); return new ArrayList<>(mCachedDevices); } public static boolean onDeviceDisappeared(CachedBluetoothDevice cachedDevice) { Loading