Fix data race
Fixes a race in BluetoothControllerImpl that could lead
to a ConcurrentModificationException, by moving the manipulation
of the callbacks array to the handler.
Change-Id: I7c3be74d239d4706f55357f54e539b7b6439e76d
Fixes: 29390132
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 6439bea..014cc49 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
@@ -40,7 +40,6 @@
private static final String TAG = "BluetoothController";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
- private final ArrayList<Callback> mCallbacks = new ArrayList<Callback>();
private final LocalBluetoothManager mLocalBluetoothManager;
private final UserManager mUserManager;
private final int mCurrentUser;
@@ -78,7 +77,7 @@
pw.print(" mEnabled="); pw.println(mEnabled);
pw.print(" mConnectionState="); pw.println(stateToString(mConnectionState));
pw.print(" mLastDevice="); pw.println(mLastDevice);
- pw.print(" mCallbacks.size="); pw.println(mCallbacks.size());
+ pw.print(" mCallbacks.size="); pw.println(mHandler.mCallbacks.size());
pw.println(" Bluetooth Devices:");
for (CachedBluetoothDevice device :
mLocalBluetoothManager.getCachedDeviceManager().getCachedDevicesCopy()) {
@@ -106,13 +105,13 @@
@Override
public void addStateChangedCallback(Callback cb) {
- mCallbacks.add(cb);
+ mHandler.obtainMessage(H.MSG_ADD_CALLBACK, cb).sendToTarget();
mHandler.sendEmptyMessage(H.MSG_STATE_CHANGED);
}
@Override
public void removeStateChangedCallback(Callback cb) {
- mCallbacks.remove(cb);
+ mHandler.obtainMessage(H.MSG_REMOVE_CALLBACK, cb).sendToTarget();
}
@Override
@@ -236,8 +235,12 @@
}
private final class H extends Handler {
+ private final ArrayList<BluetoothController.Callback> mCallbacks = new ArrayList<>();
+
private static final int MSG_PAIRED_DEVICES_CHANGED = 1;
private static final int MSG_STATE_CHANGED = 2;
+ private static final int MSG_ADD_CALLBACK = 3;
+ private static final int MSG_REMOVE_CALLBACK = 4;
@Override
public void handleMessage(Message msg) {
@@ -248,6 +251,12 @@
case MSG_STATE_CHANGED:
fireStateChange();
break;
+ case MSG_ADD_CALLBACK:
+ mCallbacks.add((BluetoothController.Callback) msg.obj);
+ break;
+ case MSG_REMOVE_CALLBACK:
+ mCallbacks.remove((BluetoothController.Callback) msg.obj);
+ break;
}
}