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
diff --git a/src/com/android/server/telecom/CallAudioRouteController.java b/src/com/android/server/telecom/CallAudioRouteController.java
index 04f1934..6b7bbf0 100644
--- a/src/com/android/server/telecom/CallAudioRouteController.java
+++ b/src/com/android/server/telecom/CallAudioRouteController.java
@@ -978,12 +978,16 @@
      * @return {@link AudioRoute} of the BT device.
      */
     private AudioRoute getArbitraryBluetoothDevice() {
-        if (mActiveBluetoothDevice != null) {
-            return getBluetoothRoute(mActiveBluetoothDevice.first, mActiveBluetoothDevice.second);
-        } else if (!mBluetoothRoutes.isEmpty()) {
-            return mBluetoothRoutes.keySet().stream().toList().get(mBluetoothRoutes.size() - 1);
+        synchronized (mLock) {
+            if (mActiveBluetoothDevice != null) {
+                return getBluetoothRoute(
+                    mActiveBluetoothDevice.first, mActiveBluetoothDevice.second);
+            } else if (!mBluetoothRoutes.isEmpty()) {
+                return mBluetoothRoutes.keySet().stream().toList()
+                    .get(mBluetoothRoutes.size() - 1);
+            }
+            return null;
         }
-        return null;
     }
 
     private void handleSwitchHeadset() {
@@ -1450,8 +1454,11 @@
                 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,29 +1572,32 @@
      *                           address of the device.
      */
     public void updateActiveBluetoothDevice(Pair<Integer, String> device) {
-        mActiveDeviceCache.put(device.first, device.second);
-        // 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.
-            boolean hasActiveDevice = false;
-            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();
-                if (address != null) {
-                    hasActiveDevice = true;
-                    if (mFeatureFlags.resolveActiveBtRoutingAndBtTimingIssue()) {
-                        mActiveBluetoothDevice = new Pair<>(btAudioType, address);
+        synchronized (mLock) {
+            mActiveDeviceCache.put(device.first, device.second);
+            // 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.
+                boolean hasActiveDevice = false;
+                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();
+                    if (address != null) {
+                        hasActiveDevice = true;
+                        if (mFeatureFlags.resolveActiveBtRoutingAndBtTimingIssue()) {
+                            mActiveBluetoothDevice = new Pair<>(btAudioType, address);
+                        }
+                        break;
                     }
-                    break;
                 }
-            }
-            if (!hasActiveDevice) {
-                mActiveBluetoothDevice = null;
+                if (!hasActiveDevice) {
+                    mActiveBluetoothDevice = null;
+                }
             }
         }
     }