diff options
| author | 2018-05-22 15:44:21 -0700 | |
|---|---|---|
| committer | 2018-05-22 17:56:09 -0700 | |
| commit | 8c3a767b2dea8cc8fa75f39c600252e3cd1f76e9 (patch) | |
| tree | 1b6f20f4198c7e785157f2d53b9e34933f0d2c81 | |
| parent | 8dd9ef190bf580fae6aa8e850f60985458b70c21 (diff) | |
Avoid race condition when broadcasting device list changed.
Since broadcastDeviceListChanged could be called in different threads,
there would be race condition causing mutilple callback due to
mPreviousPorts is not thread safe.
Bug: 80138804
Test: run TestDeviceList app in toolbox and cts
Change-Id: I0aa70dc45594bca263ea6f36703f22fe0293f679
| -rw-r--r-- | media/java/android/media/AudioManager.java | 40 |
1 files changed, 21 insertions, 19 deletions
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index 3057501ea726..6c9a01b89977 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -4717,7 +4717,7 @@ public class AudioManager { NativeEventHandlerDelegate delegate = new NativeEventHandlerDelegate(callback, handler); mDeviceCallbacks.put(callback, delegate); - broadcastDeviceListChange(delegate.getHandler()); + broadcastDeviceListChange_sync(delegate.getHandler()); } } } @@ -4836,9 +4836,9 @@ public class AudioManager { /** * Internal method to compute and generate add/remove messages and then send to any - * registered callbacks. + * registered callbacks. Must be called synchronized on mDeviceCallbacks. */ - private void broadcastDeviceListChange(Handler handler) { + private void broadcastDeviceListChange_sync(Handler handler) { int status; // Get the new current set of ports @@ -4860,20 +4860,18 @@ public class AudioManager { AudioDeviceInfo[] removed_devices = calcListDeltas(current_ports, mPreviousPorts, GET_DEVICES_ALL); if (added_devices.length != 0 || removed_devices.length != 0) { - synchronized (mDeviceCallbacks) { - for (int i = 0; i < mDeviceCallbacks.size(); i++) { - handler = mDeviceCallbacks.valueAt(i).getHandler(); - if (handler != null) { - if (removed_devices.length != 0) { - handler.sendMessage(Message.obtain(handler, - MSG_DEVICES_DEVICES_REMOVED, - removed_devices)); - } - if (added_devices.length != 0) { - handler.sendMessage(Message.obtain(handler, - MSG_DEVICES_DEVICES_ADDED, - added_devices)); - } + for (int i = 0; i < mDeviceCallbacks.size(); i++) { + handler = mDeviceCallbacks.valueAt(i).getHandler(); + if (handler != null) { + if (removed_devices.length != 0) { + handler.sendMessage(Message.obtain(handler, + MSG_DEVICES_DEVICES_REMOVED, + removed_devices)); + } + if (added_devices.length != 0) { + handler.sendMessage(Message.obtain(handler, + MSG_DEVICES_DEVICES_ADDED, + added_devices)); } } } @@ -4889,7 +4887,9 @@ public class AudioManager { private class OnAmPortUpdateListener implements AudioManager.OnAudioPortUpdateListener { static final String TAG = "OnAmPortUpdateListener"; public void onAudioPortListUpdate(AudioPort[] portList) { - broadcastDeviceListChange(null); + synchronized (mDeviceCallbacks) { + broadcastDeviceListChange_sync(null); + } } /** @@ -4903,7 +4903,9 @@ public class AudioManager { * Callback method called when the mediaserver dies */ public void onServiceDied() { - broadcastDeviceListChange(null); + synchronized (mDeviceCallbacks) { + broadcastDeviceListChange_sync(null); + } } } |