From a4b5486a7061cf099a02706b35935b57964937cb Mon Sep 17 00:00:00 2001 From: Adrian Roos Date: Fri, 17 Jun 2016 14:28:27 -0700 Subject: [PATCH] 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 --- .../policy/BluetoothControllerImpl.java | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) 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 6439bea104e62..014cc4944a743 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 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa private static final String TAG = "BluetoothController"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); - private final ArrayList mCallbacks = new ArrayList(); private final LocalBluetoothManager mLocalBluetoothManager; private final UserManager mUserManager; private final int mCurrentUser; @@ -78,7 +77,7 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa 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 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa @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 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa } private final class H extends Handler { + private final ArrayList 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 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa 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; } }