Fetch bluetooth cached device name outside synchronized block.
mConnectedDevices is being accessed from both main and background thread
in BluetoothControllerImpl. This is leading to an ANR in cases where the
resource is being used in the background thread, and the main thread
is trying to update it in a synchronized block.
Bug: 323995015
Test: local CPU profiling
Flag: NONE
Change-Id: I72d1a0b61038b29a273c1b712461837e5e065e5e
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index 56576f1..407873e 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -420,3 +420,12 @@
}
}
+flag {
+ name: "get_connected_device_name_unsynchronized"
+ namespace: "systemui"
+ description: "Decide whether to fetch the connected bluetooth device name outside a synchronized block."
+ bug: "323995015"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
index fc2f6e9..c089092 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
@@ -35,6 +35,7 @@
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.bluetooth.LocalBluetoothProfile;
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
+import com.android.systemui.Flags;
import com.android.systemui.bluetooth.BluetoothLogger;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Background;
@@ -240,9 +241,21 @@
@WorkerThread
@Override
public String getConnectedDeviceName() {
- synchronized (mConnectedDevices) {
- if (mConnectedDevices.size() == 1) {
- return mConnectedDevices.get(0).getName();
+ if (Flags.getConnectedDeviceNameUnsynchronized()) {
+ CachedBluetoothDevice connectedDevice = null;
+ // Calling the getName() API for CachedBluetoothDevice outside the synchronized block
+ // so that the main thread is not blocked.
+ synchronized (mConnectedDevices) {
+ if (mConnectedDevices.size() == 1) {
+ connectedDevice = mConnectedDevices.get(0);
+ }
+ }
+ return connectedDevice != null ? connectedDevice.getName() : null;
+ } else {
+ synchronized (mConnectedDevices) {
+ if (mConnectedDevices.size() == 1) {
+ return mConnectedDevices.get(0).getName();
+ }
}
}
return null;