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

Commit de321aed authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Refine the sync in CachedBluetoothDevice"

parents 328d4426 1eb10ece
Loading
Loading
Loading
Loading
+152 −126
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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);
@@ -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
@@ -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
@@ -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);
@@ -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);
@@ -251,6 +260,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
                }
            }
        }
    }

    /**
     * Connect this device to the specified profile.
@@ -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) {
@@ -524,6 +535,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>

            return false;
        }
    }

    public boolean isConnectedProfile(LocalBluetoothProfile profile) {
        int status = getProfileConnectionState(profile);
@@ -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
@@ -541,6 +554,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
            }
            return getBondState() == BluetoothDevice.BOND_BONDING;
        }
    }

    private boolean updateProfiles() {
        ParcelUuid[] uuids = mDevice.getUuids();
@@ -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());
@@ -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);
@@ -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;
    }

@@ -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;
    }

@@ -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);

@@ -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;
@@ -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
@@ -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);

@@ -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;
@@ -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
+1 −1
Original line number Diff line number Diff line
@@ -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) {