Skip to content

Commit b6dce0b

Browse files
davidlnHeemin Seog
authored andcommitted
Concurrent collections for Bluetooth callbacks.
This allows callback classes to remove themselves or add additional callbacks in response to state change dispatches. Bug: 129060225 Bug: 144357642 Test: build and deploy, pair multiple devices, switch users Change-Id: I8eed81bbc9c12321ec41b2491d006764e2e483d6 Merged-In: I8eed81bbc9c12321ec41b2491d006764e2e483d6
1 parent cb0b5e2 commit b6dce0b

2 files changed

Lines changed: 47 additions & 79 deletions

File tree

packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java

Lines changed: 41 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,12 @@
3535

3636
import com.android.settingslib.R;
3737

38-
import java.util.ArrayList;
3938
import java.util.Collection;
4039
import java.util.HashMap;
4140
import java.util.Map;
4241
import java.util.Objects;
4342
import java.util.Set;
43+
import java.util.concurrent.CopyOnWriteArrayList;
4444

4545
/**
4646
* BluetoothEventManager receives broadcasts and callbacks from the Bluetooth
@@ -56,7 +56,7 @@ public class BluetoothEventManager {
5656
private final Map<String, Handler> mHandlerMap;
5757
private final BroadcastReceiver mBroadcastReceiver = new BluetoothBroadcastReceiver();
5858
private final BroadcastReceiver mProfileBroadcastReceiver = new BluetoothBroadcastReceiver();
59-
private final Collection<BluetoothCallback> mCallbacks = new ArrayList<>();
59+
private final Collection<BluetoothCallback> mCallbacks = new CopyOnWriteArrayList<>();
6060
private final android.os.Handler mReceiverHandler;
6161
private final UserHandle mUserHandle;
6262
private final Context mContext;
@@ -93,8 +93,10 @@ interface Handler {
9393
new ConnectionStateChangedHandler());
9494

9595
// Discovery broadcasts
96-
addHandler(BluetoothAdapter.ACTION_DISCOVERY_STARTED, new ScanningStateChangedHandler(true));
97-
addHandler(BluetoothAdapter.ACTION_DISCOVERY_FINISHED, new ScanningStateChangedHandler(false));
96+
addHandler(BluetoothAdapter.ACTION_DISCOVERY_STARTED,
97+
new ScanningStateChangedHandler(true));
98+
addHandler(BluetoothAdapter.ACTION_DISCOVERY_FINISHED,
99+
new ScanningStateChangedHandler(false));
98100
addHandler(BluetoothDevice.ACTION_FOUND, new DeviceFoundHandler());
99101
addHandler(BluetoothDevice.ACTION_NAME_CHANGED, new NameChangedHandler());
100102
addHandler(BluetoothDevice.ACTION_ALIAS_CHANGED, new NameChangedHandler());
@@ -128,16 +130,12 @@ interface Handler {
128130

129131
/** Register to start receiving callbacks for Bluetooth events. */
130132
public void registerCallback(BluetoothCallback callback) {
131-
synchronized (mCallbacks) {
132-
mCallbacks.add(callback);
133-
}
133+
mCallbacks.add(callback);
134134
}
135135

136136
/** Unregister to stop receiving callbacks for Bluetooth events. */
137137
public void unregisterCallback(BluetoothCallback callback) {
138-
synchronized (mCallbacks) {
139-
mCallbacks.remove(callback);
140-
}
138+
mCallbacks.remove(callback);
141139
}
142140

143141
@VisibleForTesting
@@ -189,63 +187,48 @@ boolean readPairedDevices() {
189187
}
190188

191189
void dispatchDeviceAdded(CachedBluetoothDevice cachedDevice) {
192-
synchronized (mCallbacks) {
193-
for (BluetoothCallback callback : mCallbacks) {
194-
callback.onDeviceAdded(cachedDevice);
195-
}
190+
for (BluetoothCallback callback : mCallbacks) {
191+
callback.onDeviceAdded(cachedDevice);
196192
}
197193
}
198194

199195
void dispatchDeviceRemoved(CachedBluetoothDevice cachedDevice) {
200-
synchronized (mCallbacks) {
201-
for (BluetoothCallback callback : mCallbacks) {
202-
callback.onDeviceDeleted(cachedDevice);
203-
}
196+
for (BluetoothCallback callback : mCallbacks) {
197+
callback.onDeviceDeleted(cachedDevice);
204198
}
205199
}
206200

207201
void dispatchProfileConnectionStateChanged(CachedBluetoothDevice device, int state,
208202
int bluetoothProfile) {
209-
synchronized (mCallbacks) {
210-
for (BluetoothCallback callback : mCallbacks) {
211-
callback.onProfileConnectionStateChanged(device, state, bluetoothProfile);
212-
}
203+
for (BluetoothCallback callback : mCallbacks) {
204+
callback.onProfileConnectionStateChanged(device, state, bluetoothProfile);
213205
}
214206
}
215207

216208
private void dispatchConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state) {
217-
synchronized (mCallbacks) {
218-
for (BluetoothCallback callback : mCallbacks) {
219-
callback.onConnectionStateChanged(cachedDevice, state);
220-
}
209+
for (BluetoothCallback callback : mCallbacks) {
210+
callback.onConnectionStateChanged(cachedDevice, state);
221211
}
222212
}
223213

224214
private void dispatchAudioModeChanged() {
225215
mDeviceManager.dispatchAudioModeChanged();
226-
synchronized (mCallbacks) {
227-
for (BluetoothCallback callback : mCallbacks) {
228-
callback.onAudioModeChanged();
229-
}
216+
for (BluetoothCallback callback : mCallbacks) {
217+
callback.onAudioModeChanged();
230218
}
231219
}
232220

233221
private void dispatchActiveDeviceChanged(CachedBluetoothDevice activeDevice,
234222
int bluetoothProfile) {
235223
mDeviceManager.onActiveDeviceChanged(activeDevice, bluetoothProfile);
236-
synchronized (mCallbacks) {
237-
for (BluetoothCallback callback : mCallbacks) {
238-
callback.onActiveDeviceChanged(activeDevice, bluetoothProfile);
239-
}
224+
for (BluetoothCallback callback : mCallbacks) {
225+
callback.onActiveDeviceChanged(activeDevice, bluetoothProfile);
240226
}
241227
}
242228

243-
private void dispatchAclStateChanged(CachedBluetoothDevice activeDevice,
244-
int state) {
245-
synchronized (mCallbacks) {
246-
for (BluetoothCallback callback : mCallbacks) {
247-
callback.onAclConnectionStateChanged(activeDevice, state);
248-
}
229+
private void dispatchAclStateChanged(CachedBluetoothDevice activeDevice, int state) {
230+
for (BluetoothCallback callback : mCallbacks) {
231+
callback.onAclConnectionStateChanged(activeDevice, state);
249232
}
250233
}
251234

@@ -270,17 +253,14 @@ public void onReceive(Context context, Intent intent) {
270253
}
271254

272255
private class AdapterStateChangedHandler implements Handler {
273-
public void onReceive(Context context, Intent intent,
274-
BluetoothDevice device) {
256+
public void onReceive(Context context, Intent intent, BluetoothDevice device) {
275257
int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
276258
BluetoothAdapter.ERROR);
277259
// update local profiles and get paired devices
278260
mLocalAdapter.setBluetoothStateInt(state);
279261
// send callback to update UI and possibly start scanning
280-
synchronized (mCallbacks) {
281-
for (BluetoothCallback callback : mCallbacks) {
282-
callback.onBluetoothStateChanged(state);
283-
}
262+
for (BluetoothCallback callback : mCallbacks) {
263+
callback.onBluetoothStateChanged(state);
284264
}
285265
// Inform CachedDeviceManager that the adapter state has changed
286266
mDeviceManager.onBluetoothStateChanged(state);
@@ -293,12 +273,10 @@ private class ScanningStateChangedHandler implements Handler {
293273
ScanningStateChangedHandler(boolean started) {
294274
mStarted = started;
295275
}
296-
public void onReceive(Context context, Intent intent,
297-
BluetoothDevice device) {
298-
synchronized (mCallbacks) {
299-
for (BluetoothCallback callback : mCallbacks) {
300-
callback.onScanningStateChanged(mStarted);
301-
}
276+
277+
public void onReceive(Context context, Intent intent, BluetoothDevice device) {
278+
for (BluetoothCallback callback : mCallbacks) {
279+
callback.onScanningStateChanged(mStarted);
302280
}
303281
mDeviceManager.onScanningStateChanged(mStarted);
304282
}
@@ -317,7 +295,7 @@ public void onReceive(Context context, Intent intent,
317295
Log.d(TAG, "DeviceFoundHandler created new CachedBluetoothDevice: "
318296
+ cachedDevice);
319297
} else if (cachedDevice.getBondState() == BluetoothDevice.BOND_BONDED
320-
&&!cachedDevice.getDevice().isConnected()) {
298+
&& !cachedDevice.getDevice().isConnected()) {
321299
// Dispatch device add callback to show bonded but
322300
// not connected devices in discovery mode
323301
dispatchDeviceAdded(cachedDevice);
@@ -350,8 +328,7 @@ public void onReceive(Context context, Intent intent,
350328
}
351329

352330
private class BondStateChangedHandler implements Handler {
353-
public void onReceive(Context context, Intent intent,
354-
BluetoothDevice device) {
331+
public void onReceive(Context context, Intent intent, BluetoothDevice device) {
355332
if (device == null) {
356333
Log.e(TAG, "ACTION_BOND_STATE_CHANGED with no EXTRA_DEVICE");
357334
return;
@@ -365,10 +342,8 @@ public void onReceive(Context context, Intent intent,
365342
cachedDevice = mDeviceManager.addDevice(device);
366343
}
367344

368-
synchronized (mCallbacks) {
369-
for (BluetoothCallback callback : mCallbacks) {
370-
callback.onDeviceBondStateChanged(cachedDevice, bondState);
371-
}
345+
for (BluetoothCallback callback : mCallbacks) {
346+
callback.onDeviceBondStateChanged(cachedDevice, bondState);
372347
}
373348
cachedDevice.onBondingStateChanged(bondState);
374349

@@ -388,12 +363,12 @@ public void onReceive(Context context, Intent intent,
388363
* Called when we have reached the unbonded state.
389364
*
390365
* @param reason one of the error reasons from
391-
* BluetoothDevice.UNBOND_REASON_*
366+
* BluetoothDevice.UNBOND_REASON_*
392367
*/
393368
private void showUnbondMessage(Context context, String name, int reason) {
394369
int errorMsg;
395370

396-
switch(reason) {
371+
switch (reason) {
397372
case BluetoothDevice.UNBOND_REASON_AUTH_FAILED:
398373
errorMsg = R.string.bluetooth_pairing_pin_error_message;
399374
break;
@@ -410,16 +385,16 @@ private void showUnbondMessage(Context context, String name, int reason) {
410385
errorMsg = R.string.bluetooth_pairing_error_message;
411386
break;
412387
default:
413-
Log.w(TAG, "showUnbondMessage: Not displaying any message for reason: " + reason);
388+
Log.w(TAG,
389+
"showUnbondMessage: Not displaying any message for reason: " + reason);
414390
return;
415391
}
416392
BluetoothUtils.showError(context, name, errorMsg);
417393
}
418394
}
419395

420396
private class ClassChangedHandler implements Handler {
421-
public void onReceive(Context context, Intent intent,
422-
BluetoothDevice device) {
397+
public void onReceive(Context context, Intent intent, BluetoothDevice device) {
423398
CachedBluetoothDevice cachedDevice = mDeviceManager.findDevice(device);
424399
if (cachedDevice != null) {
425400
cachedDevice.refresh();
@@ -428,8 +403,7 @@ public void onReceive(Context context, Intent intent,
428403
}
429404

430405
private class UuidChangedHandler implements Handler {
431-
public void onReceive(Context context, Intent intent,
432-
BluetoothDevice device) {
406+
public void onReceive(Context context, Intent intent, BluetoothDevice device) {
433407
CachedBluetoothDevice cachedDevice = mDeviceManager.findDevice(device);
434408
if (cachedDevice != null) {
435409
cachedDevice.onUuidChanged();
@@ -438,8 +412,7 @@ public void onReceive(Context context, Intent intent,
438412
}
439413

440414
private class BatteryLevelChangedHandler implements Handler {
441-
public void onReceive(Context context, Intent intent,
442-
BluetoothDevice device) {
415+
public void onReceive(Context context, Intent intent, BluetoothDevice device) {
443416
CachedBluetoothDevice cachedDevice = mDeviceManager.findDevice(device);
444417
if (cachedDevice != null) {
445418
cachedDevice.refresh();

packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import java.util.Collection;
4040
import java.util.Collections;
4141
import java.util.List;
42+
import java.util.concurrent.CopyOnWriteArrayList;
4243

4344
/**
4445
* CachedBluetoothDevice represents a remote Bluetooth device. It contains
@@ -75,7 +76,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
7576

7677
boolean mJustDiscovered;
7778

78-
private final Collection<Callback> mCallbacks = new ArrayList<>();
79+
private final Collection<Callback> mCallbacks = new CopyOnWriteArrayList<>();
7980

8081
/**
8182
* Last time a bt profile auto-connect was attempted.
@@ -679,22 +680,16 @@ public List<LocalBluetoothProfile> getRemovedProfiles() {
679680
}
680681

681682
public void registerCallback(Callback callback) {
682-
synchronized (mCallbacks) {
683-
mCallbacks.add(callback);
684-
}
683+
mCallbacks.add(callback);
685684
}
686685

687686
public void unregisterCallback(Callback callback) {
688-
synchronized (mCallbacks) {
689-
mCallbacks.remove(callback);
690-
}
687+
mCallbacks.remove(callback);
691688
}
692689

693690
void dispatchAttributesChanged() {
694-
synchronized (mCallbacks) {
695-
for (Callback callback : mCallbacks) {
696-
callback.onDeviceAttributesChanged();
697-
}
691+
for (Callback callback : mCallbacks) {
692+
callback.onDeviceAttributesChanged();
698693
}
699694
}
700695

0 commit comments

Comments
 (0)