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

Commit 38b952f2 authored by Pranav Madapurmath's avatar Pranav Madapurmath Committed by Android Build Coastguard Worker
Browse files

Synchronize active bluetooth device

Ensure that we synchronize read/write on the active bluetooth device reference so that another thread doesn't modify it while it's being referenced. We were seeing instances where the active device was null even though there was an explicit NPE check before referencing it.

Bug: 382590000
Test: atest CallAudioRouteControllerTest
Flag: EXEMPT bugfix
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:f47041c250b8f9dbff3db71b7b8f4aaff97ffe67)
Merged-In: I4eddb6e696717e136771c97f5f8f89a7173e646d
Change-Id: I4eddb6e696717e136771c97f5f8f89a7173e646d
parent 009fd3b6
Loading
Loading
Loading
Loading
+37 −27
Original line number Diff line number Diff line
@@ -978,13 +978,17 @@ public class CallAudioRouteController implements CallAudioRouteAdapter {
     * @return {@link AudioRoute} of the BT device.
     */
    private AudioRoute getArbitraryBluetoothDevice() {
        synchronized (mLock) {
            if (mActiveBluetoothDevice != null) {
            return getBluetoothRoute(mActiveBluetoothDevice.first, mActiveBluetoothDevice.second);
                return getBluetoothRoute(
                    mActiveBluetoothDevice.first, mActiveBluetoothDevice.second);
            } else if (!mBluetoothRoutes.isEmpty()) {
            return mBluetoothRoutes.keySet().stream().toList().get(mBluetoothRoutes.size() - 1);
                return mBluetoothRoutes.keySet().stream().toList()
                    .get(mBluetoothRoutes.size() - 1);
            }
            return null;
        }
    }

    private void handleSwitchHeadset() {
        AudioRoute headsetRoute = mTypeRoutes.get(AudioRoute.TYPE_WIRED);
@@ -1450,8 +1454,11 @@ public class CallAudioRouteController implements CallAudioRouteAdapter {
                continue;
            }
            // Check if the most recently active device is a watch device.
            boolean isActiveDevice = mActiveBluetoothDevice != null
            boolean isActiveDevice;
            synchronized (mLock) {
                isActiveDevice = mActiveBluetoothDevice != null
                    && device.getAddress().equals(mActiveBluetoothDevice.second);
            }
            if (i == (bluetoothRoutes.size() - 1) && mBluetoothRouteManager.isWatch(device)
                    && (device.equals(mCallAudioState.getActiveBluetoothDevice())
                    || isActiveDevice)) {
@@ -1565,16 +1572,18 @@ public class CallAudioRouteController implements CallAudioRouteAdapter {
     *                           address of the device.
     */
    public void updateActiveBluetoothDevice(Pair<Integer, String> device) {
        synchronized (mLock) {
            mActiveDeviceCache.put(device.first, device.second);
        // Update most recently active device if address isn't null (meaning some device is active).
            // Update most recently active device if address isn't null (meaning
            // some device is active).
            if (device.second != null) {
                mActiveBluetoothDevice = device;
            } else {
            // If a device was removed, check to ensure that no other device is still considered
            // active.
                // If a device was removed, check to ensure that no other device is
                //still considered active.
                boolean hasActiveDevice = false;
            List<Map.Entry<Integer, String>> activeBtDevices = new ArrayList<>(
                    mActiveDeviceCache.entrySet());
                List<Map.Entry<Integer, String>> activeBtDevices =
                        new ArrayList<>(mActiveDeviceCache.entrySet());
                for (Map.Entry<Integer, String> activeDevice : activeBtDevices) {
                    Integer btAudioType = activeDevice.getKey();
                    String address = activeDevice.getValue();
@@ -1591,6 +1600,7 @@ public class CallAudioRouteController implements CallAudioRouteAdapter {
                }
            }
        }
    }

    private void updateAvailableRoutes(AudioRoute route, boolean includeRoute) {
        if (includeRoute) {