summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Jean-Michel Trivi <jmtrivi@google.com> 2019-10-25 15:43:38 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2019-10-25 15:43:38 +0000
commit4f27cd6f468dabaff1ab2da555b47624fd54ea9e (patch)
tree132566de7bc60a2df77ae246f8eb78a936e4ce64
parent68617d8d746b575d6b72166930f92c9924cfdfc6 (diff)
parent261a9f94828187e7cf08034a45259eb18a51f80c (diff)
Merge "AudioService: simplify/document locking"
-rw-r--r--services/core/java/com/android/server/audio/AudioDeviceBroker.java515
-rw-r--r--services/core/java/com/android/server/audio/AudioDeviceInventory.java3
-rw-r--r--services/core/java/com/android/server/audio/AudioService.java70
-rw-r--r--services/core/java/com/android/server/audio/BtHelper.java30
-rw-r--r--services/tests/servicestests/src/com/android/server/audio/AudioDeviceBrokerTest.java16
5 files changed, 303 insertions, 331 deletions
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index 6010b1dc88c4..f7ac04041ed6 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -57,13 +57,6 @@ import java.io.PrintWriter;
private final @NonNull AudioService mAudioService;
private final @NonNull Context mContext;
- /** Forced device usage for communications sent to AudioSystem */
- private int mForcedUseForComm;
- /**
- * Externally reported force device usage state returned by getters: always consistent
- * with requests by setters */
- private int mForcedUseForCommExt;
-
// Manages all connected devices, only ever accessed on the message loop
private final AudioDeviceInventory mDeviceInventory;
// Manages notifications to BT service
@@ -71,24 +64,34 @@ import java.io.PrintWriter;
//-------------------------------------------------------------------
- // we use a different lock than mDeviceStateLock so as not to create
- // lock contention between enqueueing a message and handling them
- private static final Object sLastDeviceConnectionMsgTimeLock = new Object();
- @GuardedBy("sLastDeviceConnectionMsgTimeLock")
+ /**
+ * Lock to guard:
+ * - any changes to the message queue: enqueueing or removing any message
+ * - state of A2DP enabled
+ * - force use for communication + SCO changes
+ */
+ private final Object mDeviceBrokerLock = new Object();
+
+ @GuardedBy("mDeviceBrokerLock")
private static long sLastDeviceConnectMsgTime = 0;
- // General lock to be taken whenever the state of the audio devices is to be checked or changed
- private final Object mDeviceStateLock = new Object();
- // Request to override default use of A2DP for media.
- @GuardedBy("mDeviceStateLock")
+ /** Request to override default use of A2DP for media */
+ @GuardedBy("mDeviceBrokerLock")
private boolean mBluetoothA2dpEnabled;
- // lock always taken when accessing AudioService.mSetModeDeathHandlers
- // TODO do not "share" the lock between AudioService and BtHelpr, see b/123769055
- /*package*/ final Object mSetModeLock = new Object();
+ /** Forced device usage for communications sent to AudioSystem */
+ @GuardedBy("mDeviceBrokerLock")
+ private int mForcedUseForComm;
+ /**
+ * Externally reported force device usage state returned by getters: always consistent
+ * with requests by setters */
+ @GuardedBy("mDeviceBrokerLock")
+ private int mForcedUseForCommExt;
+
//-------------------------------------------------------------------
+ /** Normal constructor used by AudioService */
/*package*/ AudioDeviceBroker(@NonNull Context context, @NonNull AudioService service) {
mContext = context;
mAudioService = service;
@@ -127,38 +130,37 @@ import java.io.PrintWriter;
// All post* methods are asynchronous
/*package*/ void onSystemReady() {
- synchronized (mSetModeLock) {
- synchronized (mDeviceStateLock) {
- mBtHelper.onSystemReady();
- }
- }
+ mBtHelper.onSystemReady();
}
/*package*/ void onAudioServerDied() {
// Restore forced usage for communications and record
- synchronized (mDeviceStateLock) {
+ synchronized (mDeviceBrokerLock) {
AudioSystem.setParameters(
"BT_SCO=" + (mForcedUseForComm == AudioSystem.FORCE_BT_SCO ? "on" : "off"));
onSetForceUse(AudioSystem.FOR_COMMUNICATION, mForcedUseForComm, "onAudioServerDied");
onSetForceUse(AudioSystem.FOR_RECORD, mForcedUseForComm, "onAudioServerDied");
+
+ // restore devices
+ sendMsgNoDelay(MSG_RESTORE_DEVICES, SENDMSG_REPLACE);
}
- // restore devices
- sendMsgNoDelay(MSG_RESTORE_DEVICES, SENDMSG_REPLACE);
}
/*package*/ void setForceUse_Async(int useCase, int config, String eventSource) {
- sendIILMsgNoDelay(MSG_IIL_SET_FORCE_USE, SENDMSG_QUEUE,
- useCase, config, eventSource);
+ synchronized (mDeviceBrokerLock) {
+ sendIILMsgNoDelay(MSG_IIL_SET_FORCE_USE, SENDMSG_QUEUE,
+ useCase, config, eventSource);
+ }
}
/*package*/ void toggleHdmiIfConnected_Async() {
- sendMsgNoDelay(MSG_TOGGLE_HDMI, SENDMSG_QUEUE);
+ synchronized (mDeviceBrokerLock) {
+ sendMsgNoDelay(MSG_TOGGLE_HDMI, SENDMSG_QUEUE);
+ }
}
/*package*/ void disconnectAllBluetoothProfiles() {
- synchronized (mDeviceStateLock) {
mBtHelper.disconnectAllBluetoothProfiles();
- }
}
/**
@@ -168,15 +170,11 @@ import java.io.PrintWriter;
* @param intent
*/
/*package*/ void receiveBtEvent(@NonNull Intent intent) {
- synchronized (mSetModeLock) {
- synchronized (mDeviceStateLock) {
- mBtHelper.receiveBtEvent(intent);
- }
- }
+ mBtHelper.receiveBtEvent(intent);
}
/*package*/ void setBluetoothA2dpOn_Async(boolean on, String source) {
- synchronized (mDeviceStateLock) {
+ synchronized (mDeviceBrokerLock) {
if (mBluetoothA2dpEnabled == on) {
return;
}
@@ -196,7 +194,7 @@ import java.io.PrintWriter;
* @return true if speakerphone state changed
*/
/*package*/ boolean setSpeakerphoneOn(boolean on, String eventSource) {
- synchronized (mDeviceStateLock) {
+ synchronized (mDeviceBrokerLock) {
final boolean wasOn = isSpeakerphoneOn();
if (on) {
if (mForcedUseForComm == AudioSystem.FORCE_BT_SCO) {
@@ -214,7 +212,7 @@ import java.io.PrintWriter;
}
/*package*/ boolean isSpeakerphoneOn() {
- synchronized (mDeviceStateLock) {
+ synchronized (mDeviceBrokerLock) {
return (mForcedUseForCommExt == AudioSystem.FORCE_SPEAKER);
}
}
@@ -223,9 +221,7 @@ import java.io.PrintWriter;
@AudioService.ConnectionState int state, String address, String name,
String caller) {
//TODO move logging here just like in setBluetooth* methods
- synchronized (mDeviceStateLock) {
- mDeviceInventory.setWiredDeviceConnectionState(type, state, address, name, caller);
- }
+ mDeviceInventory.setWiredDeviceConnectionState(type, state, address, name, caller);
}
private static final class BtDeviceConnectionInfo {
@@ -259,27 +255,24 @@ import java.io.PrintWriter;
final BtDeviceConnectionInfo info = new BtDeviceConnectionInfo(device, state, profile,
suppressNoisyIntent, a2dpVolume);
- // when receiving a request to change the connection state of a device, this last request
- // is the source of truth, so cancel all previous requests
- removeAllA2dpConnectionEvents(device);
-
- sendLMsgNoDelay(
- state == BluetoothProfile.STATE_CONNECTED
- ? MSG_L_A2DP_DEVICE_CONNECTION_CHANGE_EXT_CONNECTION
- : MSG_L_A2DP_DEVICE_CONNECTION_CHANGE_EXT_DISCONNECTION,
- SENDMSG_QUEUE, info);
- }
-
- /** remove all previously scheduled connection and disconnection events for the given device */
- private void removeAllA2dpConnectionEvents(@NonNull BluetoothDevice device) {
- mBrokerHandler.removeMessages(MSG_L_A2DP_DEVICE_CONNECTION_CHANGE_EXT_DISCONNECTION,
- device);
- mBrokerHandler.removeMessages(MSG_L_A2DP_DEVICE_CONNECTION_CHANGE_EXT_CONNECTION,
- device);
- mBrokerHandler.removeMessages(MSG_IL_SET_A2DP_SINK_CONNECTION_STATE_CONNECTED,
- device);
- mBrokerHandler.removeMessages(MSG_IL_SET_A2DP_SINK_CONNECTION_STATE_DISCONNECTED,
- device);
+ synchronized (mDeviceBrokerLock) {
+ // when receiving a request to change the connection state of a device, this last
+ // request is the source of truth, so cancel all previous requests
+ mBrokerHandler.removeMessages(MSG_L_A2DP_DEVICE_CONNECTION_CHANGE_EXT_DISCONNECTION,
+ device);
+ mBrokerHandler.removeMessages(MSG_L_A2DP_DEVICE_CONNECTION_CHANGE_EXT_CONNECTION,
+ device);
+ mBrokerHandler.removeMessages(MSG_IL_SET_A2DP_SINK_CONNECTION_STATE_CONNECTED,
+ device);
+ mBrokerHandler.removeMessages(MSG_IL_SET_A2DP_SINK_CONNECTION_STATE_DISCONNECTED,
+ device);
+
+ sendLMsgNoDelay(
+ state == BluetoothProfile.STATE_CONNECTED
+ ? MSG_L_A2DP_DEVICE_CONNECTION_CHANGE_EXT_CONNECTION
+ : MSG_L_A2DP_DEVICE_CONNECTION_CHANGE_EXT_DISCONNECTION,
+ SENDMSG_QUEUE, info);
+ }
}
private static final class HearingAidDeviceConnectionInfo {
@@ -305,28 +298,31 @@ import java.io.PrintWriter;
boolean suppressNoisyIntent, int musicDevice, @NonNull String eventSource) {
final HearingAidDeviceConnectionInfo info = new HearingAidDeviceConnectionInfo(
device, state, suppressNoisyIntent, musicDevice, eventSource);
- sendLMsgNoDelay(MSG_L_HEARING_AID_DEVICE_CONNECTION_CHANGE_EXT, SENDMSG_QUEUE, info);
+ synchronized (mDeviceBrokerLock) {
+ sendLMsgNoDelay(MSG_L_HEARING_AID_DEVICE_CONNECTION_CHANGE_EXT, SENDMSG_QUEUE, info);
+ }
}
// never called by system components
/*package*/ void setBluetoothScoOnByApp(boolean on) {
- synchronized (mDeviceStateLock) {
+ synchronized (mDeviceBrokerLock) {
mForcedUseForCommExt = on ? AudioSystem.FORCE_BT_SCO : AudioSystem.FORCE_NONE;
}
}
/*package*/ boolean isBluetoothScoOnForApp() {
- synchronized (mDeviceStateLock) {
+ synchronized (mDeviceBrokerLock) {
return mForcedUseForCommExt == AudioSystem.FORCE_BT_SCO;
}
}
/*package*/ void setBluetoothScoOn(boolean on, String eventSource) {
//Log.i(TAG, "setBluetoothScoOnInt: " + on + " " + eventSource);
- synchronized (mDeviceStateLock) {
+ final boolean isBtScoOn = mBtHelper.isBluetoothScoOn();
+ synchronized (mDeviceBrokerLock) {
if (on) {
// do not accept SCO ON if SCO audio is not connected
- if (!mBtHelper.isBluetoothScoOn()) {
+ if (!isBtScoOn) {
mForcedUseForCommExt = AudioSystem.FORCE_BT_SCO;
return;
}
@@ -346,58 +342,55 @@ import java.io.PrintWriter;
}
/*package*/ AudioRoutesInfo startWatchingRoutes(IAudioRoutesObserver observer) {
- synchronized (mDeviceStateLock) {
- return mDeviceInventory.startWatchingRoutes(observer);
- }
+ return mDeviceInventory.startWatchingRoutes(observer);
+
}
/*package*/ AudioRoutesInfo getCurAudioRoutes() {
- synchronized (mDeviceStateLock) {
- return mDeviceInventory.getCurAudioRoutes();
- }
+ return mDeviceInventory.getCurAudioRoutes();
}
/*package*/ boolean isAvrcpAbsoluteVolumeSupported() {
- synchronized (mDeviceStateLock) {
- return mBtHelper.isAvrcpAbsoluteVolumeSupported();
- }
+ return mBtHelper.isAvrcpAbsoluteVolumeSupported();
}
/*package*/ boolean isBluetoothA2dpOn() {
- synchronized (mDeviceStateLock) {
+ synchronized (mDeviceBrokerLock) {
return mBluetoothA2dpEnabled;
}
}
/*package*/ void postSetAvrcpAbsoluteVolumeIndex(int index) {
- sendIMsgNoDelay(MSG_I_SET_AVRCP_ABSOLUTE_VOLUME, SENDMSG_REPLACE, index);
+ synchronized (mDeviceBrokerLock) {
+ sendIMsgNoDelay(MSG_I_SET_AVRCP_ABSOLUTE_VOLUME, SENDMSG_REPLACE, index);
+ }
}
/*package*/ void postSetHearingAidVolumeIndex(int index, int streamType) {
- sendIIMsgNoDelay(MSG_II_SET_HEARING_AID_VOLUME, SENDMSG_REPLACE, index, streamType);
+ synchronized (mDeviceBrokerLock) {
+ sendIIMsgNoDelay(MSG_II_SET_HEARING_AID_VOLUME, SENDMSG_REPLACE, index, streamType);
+ }
}
/*package*/ void postDisconnectBluetoothSco(int exceptPid) {
- sendIMsgNoDelay(MSG_I_DISCONNECT_BT_SCO, SENDMSG_REPLACE, exceptPid);
+ synchronized (mDeviceBrokerLock) {
+ sendIMsgNoDelay(MSG_I_DISCONNECT_BT_SCO, SENDMSG_REPLACE, exceptPid);
+ }
}
/*package*/ void postBluetoothA2dpDeviceConfigChange(@NonNull BluetoothDevice device) {
- sendLMsgNoDelay(MSG_L_A2DP_DEVICE_CONFIG_CHANGE, SENDMSG_QUEUE, device);
+ synchronized (mDeviceBrokerLock) {
+ sendLMsgNoDelay(MSG_L_A2DP_DEVICE_CONFIG_CHANGE, SENDMSG_QUEUE, device);
+ }
}
- @GuardedBy("mSetModeLock")
/*package*/ void startBluetoothScoForClient_Sync(IBinder cb, int scoAudioMode,
@NonNull String eventSource) {
- synchronized (mDeviceStateLock) {
- mBtHelper.startBluetoothScoForClient(cb, scoAudioMode, eventSource);
- }
+ mBtHelper.startBluetoothScoForClient(cb, scoAudioMode, eventSource);
}
- @GuardedBy("mSetModeLock")
/*package*/ void stopBluetoothScoForClient_Sync(IBinder cb, @NonNull String eventSource) {
- synchronized (mDeviceStateLock) {
- mBtHelper.stopBluetoothScoForClient(cb, eventSource);
- }
+ mBtHelper.stopBluetoothScoForClient(cb, eventSource);
}
//---------------------------------------------------------------------
@@ -460,77 +453,109 @@ import java.io.PrintWriter;
//---------------------------------------------------------------------
// Message handling on behalf of helper classes
/*package*/ void postBroadcastScoConnectionState(int state) {
- sendIMsgNoDelay(MSG_I_BROADCAST_BT_CONNECTION_STATE, SENDMSG_QUEUE, state);
+ synchronized (mDeviceBrokerLock) {
+ sendIMsgNoDelay(MSG_I_BROADCAST_BT_CONNECTION_STATE, SENDMSG_QUEUE, state);
+ }
}
/*package*/ void postBroadcastBecomingNoisy() {
- sendMsgNoDelay(MSG_BROADCAST_AUDIO_BECOMING_NOISY, SENDMSG_REPLACE);
+ synchronized (mDeviceBrokerLock) {
+ sendMsgNoDelay(MSG_BROADCAST_AUDIO_BECOMING_NOISY, SENDMSG_REPLACE);
+ }
}
/*package*/ void postA2dpSinkConnection(@AudioService.BtProfileConnectionState int state,
@NonNull BtHelper.BluetoothA2dpDeviceInfo btDeviceInfo, int delay) {
- sendILMsg(state == BluetoothA2dp.STATE_CONNECTED
- ? MSG_IL_SET_A2DP_SINK_CONNECTION_STATE_CONNECTED
- : MSG_IL_SET_A2DP_SINK_CONNECTION_STATE_DISCONNECTED,
- SENDMSG_QUEUE,
- state, btDeviceInfo, delay);
+ synchronized (mDeviceBrokerLock) {
+ sendILMsg(state == BluetoothA2dp.STATE_CONNECTED
+ ? MSG_IL_SET_A2DP_SINK_CONNECTION_STATE_CONNECTED
+ : MSG_IL_SET_A2DP_SINK_CONNECTION_STATE_DISCONNECTED,
+ SENDMSG_QUEUE,
+ state, btDeviceInfo, delay);
+ }
}
/*package*/ void postA2dpSourceConnection(@AudioService.BtProfileConnectionState int state,
@NonNull BtHelper.BluetoothA2dpDeviceInfo btDeviceInfo, int delay) {
- sendILMsg(MSG_IL_SET_A2DP_SOURCE_CONNECTION_STATE, SENDMSG_QUEUE,
- state, btDeviceInfo, delay);
+ synchronized (mDeviceBrokerLock) {
+ sendILMsg(MSG_IL_SET_A2DP_SOURCE_CONNECTION_STATE, SENDMSG_QUEUE,
+ state, btDeviceInfo, delay);
+ }
}
/*package*/ void postSetWiredDeviceConnectionState(
AudioDeviceInventory.WiredDeviceConnectionState connectionState, int delay) {
- sendLMsg(MSG_L_SET_WIRED_DEVICE_CONNECTION_STATE, SENDMSG_QUEUE, connectionState, delay);
+ synchronized (mDeviceBrokerLock) {
+ sendLMsg(MSG_L_SET_WIRED_DEVICE_CONNECTION_STATE, SENDMSG_QUEUE,
+ connectionState, delay);
+ }
}
/*package*/ void postSetHearingAidConnectionState(
@AudioService.BtProfileConnectionState int state,
@NonNull BluetoothDevice device, int delay) {
- sendILMsg(MSG_IL_SET_HEARING_AID_CONNECTION_STATE, SENDMSG_QUEUE,
- state,
- device,
- delay);
+ synchronized (mDeviceBrokerLock) {
+ sendILMsg(MSG_IL_SET_HEARING_AID_CONNECTION_STATE, SENDMSG_QUEUE,
+ state,
+ device,
+ delay);
+ }
}
/*package*/ void postDisconnectA2dp() {
- sendMsgNoDelay(MSG_DISCONNECT_A2DP, SENDMSG_QUEUE);
+ synchronized (mDeviceBrokerLock) {
+ sendMsgNoDelay(MSG_DISCONNECT_A2DP, SENDMSG_QUEUE);
+ }
}
/*package*/ void postDisconnectA2dpSink() {
- sendMsgNoDelay(MSG_DISCONNECT_A2DP_SINK, SENDMSG_QUEUE);
+ synchronized (mDeviceBrokerLock) {
+ sendMsgNoDelay(MSG_DISCONNECT_A2DP_SINK, SENDMSG_QUEUE);
+ }
}
/*package*/ void postDisconnectHearingAid() {
- sendMsgNoDelay(MSG_DISCONNECT_BT_HEARING_AID, SENDMSG_QUEUE);
+ synchronized (mDeviceBrokerLock) {
+ sendMsgNoDelay(MSG_DISCONNECT_BT_HEARING_AID, SENDMSG_QUEUE);
+ }
}
/*package*/ void postDisconnectHeadset() {
- sendMsgNoDelay(MSG_DISCONNECT_BT_HEADSET, SENDMSG_QUEUE);
+ synchronized (mDeviceBrokerLock) {
+ sendMsgNoDelay(MSG_DISCONNECT_BT_HEADSET, SENDMSG_QUEUE);
+ }
}
/*package*/ void postBtA2dpProfileConnected(BluetoothA2dp a2dpProfile) {
- sendLMsgNoDelay(MSG_L_BT_SERVICE_CONNECTED_PROFILE_A2DP, SENDMSG_QUEUE, a2dpProfile);
+ synchronized (mDeviceBrokerLock) {
+ sendLMsgNoDelay(MSG_L_BT_SERVICE_CONNECTED_PROFILE_A2DP, SENDMSG_QUEUE, a2dpProfile);
+ }
}
/*package*/ void postBtA2dpSinkProfileConnected(BluetoothProfile profile) {
- sendLMsgNoDelay(MSG_L_BT_SERVICE_CONNECTED_PROFILE_A2DP_SINK, SENDMSG_QUEUE, profile);
+ synchronized (mDeviceBrokerLock) {
+ sendLMsgNoDelay(MSG_L_BT_SERVICE_CONNECTED_PROFILE_A2DP_SINK, SENDMSG_QUEUE, profile);
+ }
}
/*package*/ void postBtHeasetProfileConnected(BluetoothHeadset headsetProfile) {
- sendLMsgNoDelay(MSG_L_BT_SERVICE_CONNECTED_PROFILE_HEADSET, SENDMSG_QUEUE, headsetProfile);
+ synchronized (mDeviceBrokerLock) {
+ sendLMsgNoDelay(MSG_L_BT_SERVICE_CONNECTED_PROFILE_HEADSET, SENDMSG_QUEUE,
+ headsetProfile);
+ }
}
/*package*/ void postBtHearingAidProfileConnected(BluetoothHearingAid hearingAidProfile) {
- sendLMsgNoDelay(MSG_L_BT_SERVICE_CONNECTED_PROFILE_HEARING_AID, SENDMSG_QUEUE,
- hearingAidProfile);
+ synchronized (mDeviceBrokerLock) {
+ sendLMsgNoDelay(MSG_L_BT_SERVICE_CONNECTED_PROFILE_HEARING_AID, SENDMSG_QUEUE,
+ hearingAidProfile);
+ }
}
/*package*/ void postScoClientDied(Object obj) {
- sendLMsgNoDelay(MSG_L_SCOCLIENT_DIED, SENDMSG_QUEUE, obj);
+ synchronized (mDeviceBrokerLock) {
+ sendLMsgNoDelay(MSG_L_SCOCLIENT_DIED, SENDMSG_QUEUE, obj);
+ }
}
//---------------------------------------------------------------------
@@ -545,7 +570,7 @@ import java.io.PrintWriter;
.append(") from u/pid:").append(Binder.getCallingUid()).append("/")
.append(Binder.getCallingPid()).append(" src:").append(source).toString();
- synchronized (mDeviceStateLock) {
+ synchronized (mDeviceBrokerLock) {
mBluetoothA2dpEnabled = on;
mBrokerHandler.removeMessages(MSG_IIL_SET_FORCE_BT_A2DP_USE);
onSetForceUse(
@@ -557,71 +582,85 @@ import java.io.PrintWriter;
/*package*/ boolean handleDeviceConnection(boolean connect, int device, String address,
String deviceName) {
- synchronized (mDeviceStateLock) {
- return mDeviceInventory.handleDeviceConnection(connect, device, address, deviceName);
- }
+ return mDeviceInventory.handleDeviceConnection(connect, device, address, deviceName);
}
/*package*/ void postSetA2dpSourceConnectionState(@BluetoothProfile.BtProfileState int state,
@NonNull BtHelper.BluetoothA2dpDeviceInfo btDeviceInfo) {
final int intState = (state == BluetoothA2dp.STATE_CONNECTED) ? 1 : 0;
- sendILMsgNoDelay(MSG_IL_SET_A2DP_SOURCE_CONNECTION_STATE, SENDMSG_QUEUE, state,
- btDeviceInfo);
+ synchronized (mDeviceBrokerLock) {
+ sendILMsgNoDelay(MSG_IL_SET_A2DP_SOURCE_CONNECTION_STATE, SENDMSG_QUEUE, state,
+ btDeviceInfo);
+ }
}
/*package*/ void handleFailureToConnectToBtHeadsetService(int delay) {
- sendMsg(MSG_BT_HEADSET_CNCT_FAILED, SENDMSG_REPLACE, delay);
+ synchronized (mDeviceBrokerLock) {
+ sendMsg(MSG_BT_HEADSET_CNCT_FAILED, SENDMSG_REPLACE, delay);
+ }
}
/*package*/ void handleCancelFailureToConnectToBtHeadsetService() {
- mBrokerHandler.removeMessages(MSG_BT_HEADSET_CNCT_FAILED);
+ synchronized (mDeviceBrokerLock) {
+ mBrokerHandler.removeMessages(MSG_BT_HEADSET_CNCT_FAILED);
+ }
}
/*package*/ void postReportNewRoutes() {
- sendMsgNoDelay(MSG_REPORT_NEW_ROUTES, SENDMSG_NOOP);
+ synchronized (mDeviceBrokerLock) {
+ sendMsgNoDelay(MSG_REPORT_NEW_ROUTES, SENDMSG_NOOP);
+ }
}
/*package*/ void cancelA2dpDockTimeout() {
- mBrokerHandler.removeMessages(MSG_IL_BTA2DP_DOCK_TIMEOUT);
+ synchronized (mDeviceBrokerLock) {
+ mBrokerHandler.removeMessages(MSG_IL_BTA2DP_DOCK_TIMEOUT);
+ }
}
+ // FIXME: used by?
/*package*/ void postA2dpActiveDeviceChange(
@NonNull BtHelper.BluetoothA2dpDeviceInfo btDeviceInfo) {
- sendLMsgNoDelay(MSG_L_A2DP_ACTIVE_DEVICE_CHANGE, SENDMSG_QUEUE, btDeviceInfo);
+ synchronized (mDeviceBrokerLock) {
+ sendLMsgNoDelay(MSG_L_A2DP_ACTIVE_DEVICE_CHANGE, SENDMSG_QUEUE, btDeviceInfo);
+ }
}
/*package*/ boolean hasScheduledA2dpDockTimeout() {
- return mBrokerHandler.hasMessages(MSG_IL_BTA2DP_DOCK_TIMEOUT);
+ synchronized (mDeviceBrokerLock) {
+ return mBrokerHandler.hasMessages(MSG_IL_BTA2DP_DOCK_TIMEOUT);
+ }
}
// must be called synchronized on mConnectedDevices
/*package*/ boolean hasScheduledA2dpSinkConnectionState(BluetoothDevice btDevice) {
- return (mBrokerHandler.hasMessages(MSG_IL_SET_A2DP_SINK_CONNECTION_STATE_CONNECTED,
- new BtHelper.BluetoothA2dpDeviceInfo(btDevice))
- || mBrokerHandler.hasMessages(MSG_IL_SET_A2DP_SINK_CONNECTION_STATE_DISCONNECTED,
- new BtHelper.BluetoothA2dpDeviceInfo(btDevice)));
+ synchronized (mDeviceBrokerLock) {
+ return (mBrokerHandler.hasMessages(MSG_IL_SET_A2DP_SINK_CONNECTION_STATE_CONNECTED,
+ new BtHelper.BluetoothA2dpDeviceInfo(btDevice))
+ || mBrokerHandler.hasMessages(
+ MSG_IL_SET_A2DP_SINK_CONNECTION_STATE_DISCONNECTED,
+ new BtHelper.BluetoothA2dpDeviceInfo(btDevice)));
+ }
}
/*package*/ void setA2dpDockTimeout(String address, int a2dpCodec, int delayMs) {
- sendILMsg(MSG_IL_BTA2DP_DOCK_TIMEOUT, SENDMSG_QUEUE, a2dpCodec, address, delayMs);
+ synchronized (mDeviceBrokerLock) {
+ sendILMsg(MSG_IL_BTA2DP_DOCK_TIMEOUT, SENDMSG_QUEUE, a2dpCodec, address, delayMs);
+ }
}
/*package*/ void setAvrcpAbsoluteVolumeSupported(boolean supported) {
- synchronized (mDeviceStateLock) {
- mBtHelper.setAvrcpAbsoluteVolumeSupported(supported);
- }
+ mBtHelper.setAvrcpAbsoluteVolumeSupported(supported);
}
/*package*/ boolean getBluetoothA2dpEnabled() {
- synchronized (mDeviceStateLock) {
+ synchronized (mDeviceBrokerLock) {
return mBluetoothA2dpEnabled;
}
}
/*package*/ int getA2dpCodec(@NonNull BluetoothDevice device) {
- synchronized (mDeviceStateLock) {
- return mBtHelper.getA2dpCodec(device);
- }
+ return mBtHelper.getA2dpCodec(device);
}
/*package*/ void dump(PrintWriter pw, String prefix) {
@@ -709,156 +748,101 @@ import java.io.PrintWriter;
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_RESTORE_DEVICES:
- synchronized (mDeviceStateLock) {
- mDeviceInventory.onRestoreDevices();
- mBtHelper.onAudioServerDiedRestoreA2dp();
- }
+ mDeviceInventory.onRestoreDevices();
+ mBtHelper.onAudioServerDiedRestoreA2dp();
break;
case MSG_L_SET_WIRED_DEVICE_CONNECTION_STATE:
- synchronized (mDeviceStateLock) {
- mDeviceInventory.onSetWiredDeviceConnectionState(
- (AudioDeviceInventory.WiredDeviceConnectionState) msg.obj);
- }
+ mDeviceInventory.onSetWiredDeviceConnectionState(
+ (AudioDeviceInventory.WiredDeviceConnectionState) msg.obj);
break;
case MSG_I_BROADCAST_BT_CONNECTION_STATE:
- synchronized (mDeviceStateLock) {
- mBtHelper.onBroadcastScoConnectionState(msg.arg1);
- }
+ mBtHelper.onBroadcastScoConnectionState(msg.arg1);
break;
case MSG_IIL_SET_FORCE_USE: // intended fall-through
case MSG_IIL_SET_FORCE_BT_A2DP_USE:
onSetForceUse(msg.arg1, msg.arg2, (String) msg.obj);
break;
case MSG_REPORT_NEW_ROUTES:
- synchronized (mDeviceStateLock) {
- mDeviceInventory.onReportNewRoutes();
- }
+ mDeviceInventory.onReportNewRoutes();
break;
case MSG_IL_SET_A2DP_SINK_CONNECTION_STATE_CONNECTED:
case MSG_IL_SET_A2DP_SINK_CONNECTION_STATE_DISCONNECTED:
- synchronized (mDeviceStateLock) {
- mDeviceInventory.onSetA2dpSinkConnectionState(
- (BtHelper.BluetoothA2dpDeviceInfo) msg.obj, msg.arg1);
- }
+ mDeviceInventory.onSetA2dpSinkConnectionState(
+ (BtHelper.BluetoothA2dpDeviceInfo) msg.obj, msg.arg1);
break;
case MSG_IL_SET_A2DP_SOURCE_CONNECTION_STATE:
- synchronized (mDeviceStateLock) {
- mDeviceInventory.onSetA2dpSourceConnectionState(
- (BtHelper.BluetoothA2dpDeviceInfo) msg.obj, msg.arg1);
- }
+ mDeviceInventory.onSetA2dpSourceConnectionState(
+ (BtHelper.BluetoothA2dpDeviceInfo) msg.obj, msg.arg1);
break;
case MSG_IL_SET_HEARING_AID_CONNECTION_STATE:
- synchronized (mDeviceStateLock) {
- mDeviceInventory.onSetHearingAidConnectionState(
- (BluetoothDevice) msg.obj, msg.arg1,
- mAudioService.getHearingAidStreamType());
- }
+ mDeviceInventory.onSetHearingAidConnectionState(
+ (BluetoothDevice) msg.obj, msg.arg1,
+ mAudioService.getHearingAidStreamType());
break;
case MSG_BT_HEADSET_CNCT_FAILED:
- synchronized (mSetModeLock) {
- synchronized (mDeviceStateLock) {
- mBtHelper.resetBluetoothSco();
- }
- }
+ mBtHelper.resetBluetoothSco();
break;
case MSG_IL_BTA2DP_DOCK_TIMEOUT:
// msg.obj == address of BTA2DP device
- synchronized (mDeviceStateLock) {
- mDeviceInventory.onMakeA2dpDeviceUnavailableNow((String) msg.obj, msg.arg1);
- }
+ mDeviceInventory.onMakeA2dpDeviceUnavailableNow((String) msg.obj, msg.arg1);
break;
case MSG_L_A2DP_DEVICE_CONFIG_CHANGE:
final int a2dpCodec;
final BluetoothDevice btDevice = (BluetoothDevice) msg.obj;
- synchronized (mDeviceStateLock) {
- a2dpCodec = mBtHelper.getA2dpCodec(btDevice);
- mDeviceInventory.onBluetoothA2dpActiveDeviceChange(
- new BtHelper.BluetoothA2dpDeviceInfo(btDevice, -1, a2dpCodec),
- BtHelper.EVENT_DEVICE_CONFIG_CHANGE);
- }
+ // FIXME why isn't the codec coming with the request? codec should be
+ // provided by BT when it calls
+ // AudioManager.handleBluetoothA2dpDeviceConfigChange(BluetoothDevice)
+ a2dpCodec = mBtHelper.getA2dpCodec(btDevice);
+ mDeviceInventory.onBluetoothA2dpActiveDeviceChange(
+ new BtHelper.BluetoothA2dpDeviceInfo(btDevice, -1, a2dpCodec),
+ BtHelper.EVENT_DEVICE_CONFIG_CHANGE);
break;
case MSG_BROADCAST_AUDIO_BECOMING_NOISY:
onSendBecomingNoisyIntent();
break;
case MSG_II_SET_HEARING_AID_VOLUME:
- synchronized (mDeviceStateLock) {
- mBtHelper.setHearingAidVolume(msg.arg1, msg.arg2);
- }
+ mBtHelper.setHearingAidVolume(msg.arg1, msg.arg2);
break;
case MSG_I_SET_AVRCP_ABSOLUTE_VOLUME:
- synchronized (mDeviceStateLock) {
- mBtHelper.setAvrcpAbsoluteVolumeIndex(msg.arg1);
- }
+ mBtHelper.setAvrcpAbsoluteVolumeIndex(msg.arg1);
break;
case MSG_I_DISCONNECT_BT_SCO:
- synchronized (mSetModeLock) {
- synchronized (mDeviceStateLock) {
- mBtHelper.disconnectBluetoothSco(msg.arg1);
- }
- }
+ mBtHelper.disconnectBluetoothSco(msg.arg1);
break;
case MSG_L_SCOCLIENT_DIED:
- synchronized (mSetModeLock) {
- synchronized (mDeviceStateLock) {
- mBtHelper.scoClientDied(msg.obj);
- }
- }
+ mBtHelper.scoClientDied(msg.obj);
break;
case MSG_TOGGLE_HDMI:
- synchronized (mDeviceStateLock) {
- mDeviceInventory.onToggleHdmi();
- }
+ mDeviceInventory.onToggleHdmi();
break;
case MSG_L_A2DP_ACTIVE_DEVICE_CHANGE:
- synchronized (mDeviceStateLock) {
- mDeviceInventory.onBluetoothA2dpActiveDeviceChange(
- (BtHelper.BluetoothA2dpDeviceInfo) msg.obj,
- BtHelper.EVENT_ACTIVE_DEVICE_CHANGE);
- }
+ mDeviceInventory.onBluetoothA2dpActiveDeviceChange(
+ (BtHelper.BluetoothA2dpDeviceInfo) msg.obj,
+ BtHelper.EVENT_ACTIVE_DEVICE_CHANGE);
break;
case MSG_DISCONNECT_A2DP:
- synchronized (mDeviceStateLock) {
- mDeviceInventory.disconnectA2dp();
- }
+ mDeviceInventory.disconnectA2dp();
break;
case MSG_DISCONNECT_A2DP_SINK:
- synchronized (mDeviceStateLock) {
- mDeviceInventory.disconnectA2dpSink();
- }
+ mDeviceInventory.disconnectA2dpSink();
break;
case MSG_DISCONNECT_BT_HEARING_AID:
- synchronized (mDeviceStateLock) {
- mDeviceInventory.disconnectHearingAid();
- }
+ mDeviceInventory.disconnectHearingAid();
break;
case MSG_DISCONNECT_BT_HEADSET:
- synchronized (mSetModeLock) {
- synchronized (mDeviceStateLock) {
- mBtHelper.disconnectHeadset();
- }
- }
+ mBtHelper.disconnectHeadset();
break;
case MSG_L_BT_SERVICE_CONNECTED_PROFILE_A2DP:
- synchronized (mDeviceStateLock) {
- mBtHelper.onA2dpProfileConnected((BluetoothA2dp) msg.obj);
- }
+ mBtHelper.onA2dpProfileConnected((BluetoothA2dp) msg.obj);
break;
case MSG_L_BT_SERVICE_CONNECTED_PROFILE_A2DP_SINK:
- synchronized (mDeviceStateLock) {
- mBtHelper.onA2dpSinkProfileConnected((BluetoothProfile) msg.obj);
- }
+ mBtHelper.onA2dpSinkProfileConnected((BluetoothProfile) msg.obj);
break;
case MSG_L_BT_SERVICE_CONNECTED_PROFILE_HEARING_AID:
- synchronized (mDeviceStateLock) {
- mBtHelper.onHearingAidProfileConnected((BluetoothHearingAid) msg.obj);
- }
+ mBtHelper.onHearingAidProfileConnected((BluetoothHearingAid) msg.obj);
break;
case MSG_L_BT_SERVICE_CONNECTED_PROFILE_HEADSET:
- synchronized (mSetModeLock) {
- synchronized (mDeviceStateLock) {
- mBtHelper.onHeadsetProfileConnected((BluetoothHeadset) msg.obj);
- }
- }
+ mBtHelper.onHeadsetProfileConnected((BluetoothHeadset) msg.obj);
break;
case MSG_L_A2DP_DEVICE_CONNECTION_CHANGE_EXT_CONNECTION:
case MSG_L_A2DP_DEVICE_CONNECTION_CHANGE_EXT_DISCONNECTION: {
@@ -871,11 +855,9 @@ import java.io.PrintWriter;
+ " addr=" + info.mDevice.getAddress()
+ " prof=" + info.mProfile + " supprNoisy=" + info.mSupprNoisy
+ " vol=" + info.mVolume)).printLog(TAG));
- synchronized (mDeviceStateLock) {
- mDeviceInventory.setBluetoothA2dpDeviceConnectionState(
- info.mDevice, info.mState, info.mProfile, info.mSupprNoisy,
- AudioSystem.DEVICE_NONE, info.mVolume);
- }
+ mDeviceInventory.setBluetoothA2dpDeviceConnectionState(
+ info.mDevice, info.mState, info.mProfile, info.mSupprNoisy,
+ AudioSystem.DEVICE_NONE, info.mVolume);
} break;
case MSG_L_HEARING_AID_DEVICE_CONNECTION_CHANGE_EXT: {
final HearingAidDeviceConnectionInfo info =
@@ -885,10 +867,8 @@ import java.io.PrintWriter;
+ " addr=" + info.mDevice.getAddress()
+ " supprNoisy=" + info.mSupprNoisy
+ " src=" + info.mEventSource)).printLog(TAG));
- synchronized (mDeviceStateLock) {
- mDeviceInventory.setBluetoothHearingAidDeviceConnectionState(
- info.mDevice, info.mState, info.mSupprNoisy, info.mMusicDevice);
- }
+ mDeviceInventory.setBluetoothHearingAidDeviceConnectionState(
+ info.mDevice, info.mState, info.mSupprNoisy, info.mMusicDevice);
} break;
default:
Log.wtf(TAG, "Invalid message " + msg.what);
@@ -973,46 +953,57 @@ import java.io.PrintWriter;
/** If the msg is already queued, queue this one and leave the old. */
private static final int SENDMSG_QUEUE = 2;
+ @GuardedBy("mDeviceBrokerLock")
private void sendMsg(int msg, int existingMsgPolicy, int delay) {
sendIILMsg(msg, existingMsgPolicy, 0, 0, null, delay);
}
+ @GuardedBy("mDeviceBrokerLock")
private void sendILMsg(int msg, int existingMsgPolicy, int arg, Object obj, int delay) {
sendIILMsg(msg, existingMsgPolicy, arg, 0, obj, delay);
}
+ @GuardedBy("mDeviceBrokerLock")
private void sendLMsg(int msg, int existingMsgPolicy, Object obj, int delay) {
sendIILMsg(msg, existingMsgPolicy, 0, 0, obj, delay);
}
+ @GuardedBy("mDeviceBrokerLock")
private void sendIMsg(int msg, int existingMsgPolicy, int arg, int delay) {
sendIILMsg(msg, existingMsgPolicy, arg, 0, null, delay);
}
+ @GuardedBy("mDeviceBrokerLock")
private void sendMsgNoDelay(int msg, int existingMsgPolicy) {
sendIILMsg(msg, existingMsgPolicy, 0, 0, null, 0);
}
+ @GuardedBy("mDeviceBrokerLock")
private void sendIMsgNoDelay(int msg, int existingMsgPolicy, int arg) {
sendIILMsg(msg, existingMsgPolicy, arg, 0, null, 0);
}
+ @GuardedBy("mDeviceBrokerLock")
private void sendIIMsgNoDelay(int msg, int existingMsgPolicy, int arg1, int arg2) {
sendIILMsg(msg, existingMsgPolicy, arg1, arg2, null, 0);
}
+ @GuardedBy("mDeviceBrokerLock")
private void sendILMsgNoDelay(int msg, int existingMsgPolicy, int arg, Object obj) {
sendIILMsg(msg, existingMsgPolicy, arg, 0, obj, 0);
}
+ @GuardedBy("mDeviceBrokerLock")
private void sendLMsgNoDelay(int msg, int existingMsgPolicy, Object obj) {
sendIILMsg(msg, existingMsgPolicy, 0, 0, obj, 0);
}
+ @GuardedBy("mDeviceBrokerLock")
private void sendIILMsgNoDelay(int msg, int existingMsgPolicy, int arg1, int arg2, Object obj) {
sendIILMsg(msg, existingMsgPolicy, arg1, arg2, obj, 0);
}
+ @GuardedBy("mDeviceBrokerLock")
private void sendIILMsg(int msg, int existingMsgPolicy, int arg1, int arg2, Object obj,
int delay) {
if (existingMsgPolicy == SENDMSG_REPLACE) {
@@ -1031,31 +1022,29 @@ import java.io.PrintWriter;
Binder.restoreCallingIdentity(identity);
}
- synchronized (sLastDeviceConnectionMsgTimeLock) {
- long time = SystemClock.uptimeMillis() + delay;
-
- switch (msg) {
- case MSG_IL_SET_A2DP_SOURCE_CONNECTION_STATE:
- case MSG_IL_SET_A2DP_SINK_CONNECTION_STATE_CONNECTED:
- case MSG_IL_SET_A2DP_SINK_CONNECTION_STATE_DISCONNECTED:
- case MSG_IL_SET_HEARING_AID_CONNECTION_STATE:
- case MSG_L_SET_WIRED_DEVICE_CONNECTION_STATE:
- case MSG_IL_BTA2DP_DOCK_TIMEOUT:
- case MSG_L_A2DP_DEVICE_CONFIG_CHANGE:
- case MSG_L_A2DP_ACTIVE_DEVICE_CHANGE:
- if (sLastDeviceConnectMsgTime >= time) {
- // add a little delay to make sure messages are ordered as expected
- time = sLastDeviceConnectMsgTime + 30;
- }
- sLastDeviceConnectMsgTime = time;
- break;
- default:
- break;
- }
+ long time = SystemClock.uptimeMillis() + delay;
- mBrokerHandler.sendMessageAtTime(mBrokerHandler.obtainMessage(msg, arg1, arg2, obj),
- time);
+ switch (msg) {
+ case MSG_IL_SET_A2DP_SOURCE_CONNECTION_STATE:
+ case MSG_IL_SET_A2DP_SINK_CONNECTION_STATE_CONNECTED:
+ case MSG_IL_SET_A2DP_SINK_CONNECTION_STATE_DISCONNECTED:
+ case MSG_IL_SET_HEARING_AID_CONNECTION_STATE:
+ case MSG_L_SET_WIRED_DEVICE_CONNECTION_STATE:
+ case MSG_IL_BTA2DP_DOCK_TIMEOUT:
+ case MSG_L_A2DP_DEVICE_CONFIG_CHANGE:
+ case MSG_L_A2DP_ACTIVE_DEVICE_CHANGE:
+ if (sLastDeviceConnectMsgTime >= time) {
+ // add a little delay to make sure messages are ordered as expected
+ time = sLastDeviceConnectMsgTime + 30;
+ }
+ sLastDeviceConnectMsgTime = time;
+ break;
+ default:
+ break;
}
+
+ mBrokerHandler.sendMessageAtTime(mBrokerHandler.obtainMessage(msg, arg1, arg2, obj),
+ time);
}
//-------------------------------------------------------------
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index 90973a888a9d..3933fb2d5f46 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -159,7 +159,6 @@ public class AudioDeviceInventory {
}
// only public for mocking/spying
- @GuardedBy("AudioDeviceBroker.mDeviceStateLock")
@VisibleForTesting
public void onSetA2dpSinkConnectionState(@NonNull BtHelper.BluetoothA2dpDeviceInfo btInfo,
@AudioService.BtProfileConnectionState int state) {
@@ -284,7 +283,6 @@ public class AudioDeviceInventory {
}
}
- @GuardedBy("AudioDeviceBroker.mDeviceStateLock")
/*package*/ void onBluetoothA2dpActiveDeviceChange(
@NonNull BtHelper.BluetoothA2dpDeviceInfo btInfo, int event) {
final BluetoothDevice btDevice = btInfo.getBtDevice();
@@ -557,7 +555,6 @@ public class AudioDeviceInventory {
}
// only public for mocking/spying
- @GuardedBy("AudioDeviceBroker.mDeviceStateLock")
@VisibleForTesting
public void setBluetoothA2dpDeviceConnectionState(
@NonNull BluetoothDevice device, @AudioService.BtProfileConnectionState int state,
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 0d493b825133..cc50e37d2b61 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -470,12 +470,11 @@ public class AudioService extends IAudioService.Stub
// List of binder death handlers for setMode() client processes.
// The last process to have called setMode() is at the top of the list.
- // package-private so it can be accessed in AudioDeviceBroker.getSetModeDeathHandlers
- //TODO candidate to be moved to separate class that handles synchronization
- @GuardedBy("mDeviceBroker.mSetModeLock")
- /*package*/ final ArrayList<SetModeDeathHandler> mSetModeDeathHandlers =
+ private final ArrayList<SetModeDeathHandler> mSetModeDeathHandlers =
new ArrayList<SetModeDeathHandler>();
+ private volatile int mCurrentModeOwnerPid = 0;
+
// true if boot sequence has been completed
private boolean mSystemReady;
// true if Intent.ACTION_USER_SWITCHED has ever been received
@@ -3192,15 +3191,10 @@ public class AudioService extends IAudioService.Stub
* @return 0 if nobody owns the mode
*/
/*package*/ int getModeOwnerPid() {
- int modeOwnerPid = 0;
- try {
- modeOwnerPid = mSetModeDeathHandlers.get(0).getPid();
- } catch (Exception e) {
- // nothing to do, modeOwnerPid is not modified
- }
- return modeOwnerPid;
+ return mCurrentModeOwnerPid;
}
+
private class SetModeDeathHandler implements IBinder.DeathRecipient {
private IBinder mCb; // To be notified of client's death
private int mPid;
@@ -3214,7 +3208,7 @@ public class AudioService extends IAudioService.Stub
public void binderDied() {
int oldModeOwnerPid = 0;
int newModeOwnerPid = 0;
- synchronized (mDeviceBroker.mSetModeLock) {
+ synchronized (mSetModeDeathHandlers) {
Log.w(TAG, "setMode() client died");
if (!mSetModeDeathHandlers.isEmpty()) {
oldModeOwnerPid = mSetModeDeathHandlers.get(0).getPid();
@@ -3225,11 +3219,15 @@ public class AudioService extends IAudioService.Stub
} else {
newModeOwnerPid = setModeInt(AudioSystem.MODE_NORMAL, mCb, mPid, TAG);
}
- }
- // when entering RINGTONE, IN_CALL or IN_COMMUNICATION mode, clear all
- // SCO connections not started by the application changing the mode when pid changes
- if ((newModeOwnerPid != oldModeOwnerPid) && (newModeOwnerPid != 0)) {
- mDeviceBroker.postDisconnectBluetoothSco(newModeOwnerPid);
+
+ if (newModeOwnerPid != oldModeOwnerPid) {
+ mCurrentModeOwnerPid = newModeOwnerPid;
+ // when entering RINGTONE, IN_CALL or IN_COMMUNICATION mode, clear all SCO
+ // connections not started by the application changing the mode when pid changes
+ if (newModeOwnerPid != 0) {
+ mDeviceBroker.postDisconnectBluetoothSco(newModeOwnerPid);
+ }
+ }
}
}
@@ -3252,15 +3250,17 @@ public class AudioService extends IAudioService.Stub
/** @see AudioManager#setMode(int) */
public void setMode(int mode, IBinder cb, String callingPackage) {
- if (DEBUG_MODE) { Log.v(TAG, "setMode(mode=" + mode + ", callingPackage=" + callingPackage + ")"); }
+ if (DEBUG_MODE) {
+ Log.v(TAG, "setMode(mode=" + mode + ", callingPackage=" + callingPackage + ")");
+ }
if (!checkAudioSettingsPermission("setMode()")) {
return;
}
- if ( (mode == AudioSystem.MODE_IN_CALL) &&
- (mContext.checkCallingOrSelfPermission(
+ if ((mode == AudioSystem.MODE_IN_CALL)
+ && (mContext.checkCallingOrSelfPermission(
android.Manifest.permission.MODIFY_PHONE_STATE)
- != PackageManager.PERMISSION_GRANTED)) {
+ != PackageManager.PERMISSION_GRANTED)) {
Log.w(TAG, "MODIFY_PHONE_STATE Permission Denial: setMode(MODE_IN_CALL) from pid="
+ Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
return;
@@ -3272,7 +3272,7 @@ public class AudioService extends IAudioService.Stub
int oldModeOwnerPid = 0;
int newModeOwnerPid = 0;
- synchronized (mDeviceBroker.mSetModeLock) {
+ synchronized (mSetModeDeathHandlers) {
if (!mSetModeDeathHandlers.isEmpty()) {
oldModeOwnerPid = mSetModeDeathHandlers.get(0).getPid();
}
@@ -3280,17 +3280,21 @@ public class AudioService extends IAudioService.Stub
mode = mMode;
}
newModeOwnerPid = setModeInt(mode, cb, Binder.getCallingPid(), callingPackage);
- }
- // when entering RINGTONE, IN_CALL or IN_COMMUNICATION mode, clear all
- // SCO connections not started by the application changing the mode when pid changes
- if ((newModeOwnerPid != oldModeOwnerPid) && (newModeOwnerPid != 0)) {
- mDeviceBroker.postDisconnectBluetoothSco(newModeOwnerPid);
+
+ if (newModeOwnerPid != oldModeOwnerPid) {
+ mCurrentModeOwnerPid = newModeOwnerPid;
+ // when entering RINGTONE, IN_CALL or IN_COMMUNICATION mode, clear all
+ // SCO connections not started by the application changing the mode when pid changes
+ if (newModeOwnerPid != 0) {
+ mDeviceBroker.postDisconnectBluetoothSco(newModeOwnerPid);
+ }
+ }
}
}
// setModeInt() returns a valid PID if the audio mode was successfully set to
// any mode other than NORMAL.
- @GuardedBy("mDeviceBroker.mSetModeLock")
+ @GuardedBy("mSetModeDeathHandlers")
private int setModeInt(int mode, IBinder cb, int pid, String caller) {
if (DEBUG_MODE) { Log.v(TAG, "setModeInt(mode=" + mode + ", pid=" + pid + ", caller="
+ caller + ")"); }
@@ -3629,9 +3633,7 @@ public class AudioService extends IAudioService.Stub
!mSystemReady) {
return;
}
- synchronized (mDeviceBroker.mSetModeLock) {
- mDeviceBroker.startBluetoothScoForClient_Sync(cb, scoAudioMode, eventSource);
- }
+ mDeviceBroker.startBluetoothScoForClient_Sync(cb, scoAudioMode, eventSource);
}
/** @see AudioManager#stopBluetoothSco() */
@@ -3643,9 +3645,7 @@ public class AudioService extends IAudioService.Stub
final String eventSource = new StringBuilder("stopBluetoothSco()")
.append(") from u/pid:").append(Binder.getCallingUid()).append("/")
.append(Binder.getCallingPid()).toString();
- synchronized (mDeviceBroker.mSetModeLock) {
- mDeviceBroker.stopBluetoothScoForClient_Sync(cb, eventSource);
- }
+ mDeviceBroker.stopBluetoothScoForClient_Sync(cb, eventSource);
}
@@ -4406,7 +4406,7 @@ public class AudioService extends IAudioService.Stub
// NOTE: Locking order for synchronized objects related to volume or ringer mode management:
// 1 mScoclient OR mSafeMediaVolumeState
- // 2 mSetModeLock
+ // 2 mSetModeDeathHandlers
// 3 mSettingsLock
// 4 VolumeStreamState.class
private class VolumeStreamState {
diff --git a/services/core/java/com/android/server/audio/BtHelper.java b/services/core/java/com/android/server/audio/BtHelper.java
index 9f1a6bd15ac3..625b6b690443 100644
--- a/services/core/java/com/android/server/audio/BtHelper.java
+++ b/services/core/java/com/android/server/audio/BtHelper.java
@@ -171,8 +171,6 @@ public class BtHelper {
//----------------------------------------------------------------------
// Interface for AudioDeviceBroker
- // @GuardedBy("AudioDeviceBroker.mSetModeLock")
- @GuardedBy("AudioDeviceBroker.mDeviceStateLock")
/*package*/ synchronized void onSystemReady() {
mScoConnectionState = android.media.AudioManager.SCO_AUDIO_STATE_ERROR;
resetBluetoothSco();
@@ -245,8 +243,6 @@ public class BtHelper {
return mapBluetoothCodecToAudioFormat(btCodecConfig.getCodecType());
}
- // @GuardedBy("AudioDeviceBroker.mSetModeLock")
- @GuardedBy("AudioDeviceBroker.mDeviceStateLock")
/*package*/ synchronized void receiveBtEvent(Intent intent) {
final String action = intent.getAction();
if (action.equals(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED)) {
@@ -333,8 +329,6 @@ public class BtHelper {
*
* @param exceptPid pid whose SCO connections through {@link AudioManager} should be kept
*/
- // @GuardedBy("AudioDeviceBroker.mSetModeLock")
- @GuardedBy("AudioDeviceBroker.mDeviceStateLock")
/*package*/ synchronized void disconnectBluetoothSco(int exceptPid) {
checkScoAudioState();
if (mScoAudioState == SCO_STATE_ACTIVE_EXTERNAL) {
@@ -343,8 +337,6 @@ public class BtHelper {
clearAllScoClients(exceptPid, true);
}
- // @GuardedBy("AudioDeviceBroker.mSetModeLock")
- @GuardedBy("AudioDeviceBroker.mDeviceStateLock")
/*package*/ synchronized void startBluetoothScoForClient(IBinder cb, int scoAudioMode,
@NonNull String eventSource) {
ScoClient client = getScoClient(cb, true);
@@ -364,8 +356,6 @@ public class BtHelper {
Binder.restoreCallingIdentity(ident);
}
- // @GuardedBy("AudioDeviceBroker.mSetModeLock")
- @GuardedBy("AudioDeviceBroker.mDeviceStateLock")
/*package*/ synchronized void stopBluetoothScoForClient(IBinder cb,
@NonNull String eventSource) {
ScoClient client = getScoClient(cb, false);
@@ -423,8 +413,6 @@ public class BtHelper {
mDeviceBroker.postDisconnectHearingAid();
}
- // @GuardedBy("AudioDeviceBroker.mSetModeLock")
- @GuardedBy("AudioDeviceBroker.mDeviceStateLock")
/*package*/ synchronized void resetBluetoothSco() {
clearAllScoClients(0, false);
mScoAudioState = SCO_STATE_INACTIVE;
@@ -433,8 +421,6 @@ public class BtHelper {
mDeviceBroker.setBluetoothScoOn(false, "resetBluetoothSco");
}
- // @GuardedBy("AudioDeviceBroker.mSetModeLock")
- @GuardedBy("AudioDeviceBroker.mDeviceStateLock")
/*package*/ synchronized void disconnectHeadset() {
setBtScoActiveDevice(null);
mBluetoothHeadset = null;
@@ -480,8 +466,6 @@ public class BtHelper {
/*eventSource*/ "mBluetoothProfileServiceListener");
}
- // @GuardedBy("AudioDeviceBroker.mSetModeLock")
- @GuardedBy("AudioDeviceBroker.mDeviceStateLock")
/*package*/ synchronized void onHeadsetProfileConnected(BluetoothHeadset headset) {
// Discard timeout message
mDeviceBroker.handleCancelFailureToConnectToBtHeadsetService();
@@ -568,8 +552,6 @@ public class BtHelper {
return result;
}
- // @GuardedBy("AudioDeviceBroker.mSetModeLock")
- //@GuardedBy("AudioDeviceBroker.mDeviceStateLock")
@GuardedBy("BtHelper.this")
private void setBtScoActiveDevice(BluetoothDevice btDevice) {
Log.i(TAG, "setBtScoActiveDevice: " + mBluetoothHeadsetDevice + " -> " + btDevice);
@@ -652,8 +634,6 @@ public class BtHelper {
};
//----------------------------------------------------------------------
- // @GuardedBy("AudioDeviceBroker.mSetModeLock")
- @GuardedBy("AudioDeviceBroker.mDeviceStateLock")
/*package*/ synchronized void scoClientDied(Object obj) {
final ScoClient client = (ScoClient) obj;
Log.w(TAG, "SCO client died");
@@ -684,8 +664,6 @@ public class BtHelper {
mDeviceBroker.postScoClientDied(this);
}
- // @GuardedBy("AudioDeviceBroker.mSetModeLock")
- // @GuardedBy("AudioDeviceBroker.mDeviceStateLock")
@GuardedBy("BtHelper.this")
void incCount(int scoAudioMode) {
if (!requestScoState(BluetoothHeadset.STATE_AUDIO_CONNECTED, scoAudioMode)) {
@@ -705,8 +683,6 @@ public class BtHelper {
mStartcount++;
}
- // @GuardedBy("AudioDeviceBroker.mSetModeLock")
- // @GuardedBy("AudioDeviceBroker.mDeviceStateLock")
@GuardedBy("BtHelper.this")
void decCount() {
if (mStartcount == 0) {
@@ -726,8 +702,6 @@ public class BtHelper {
}
}
- // @GuardedBy("AudioDeviceBroker.mSetModeLock")
- // @GuardedBy("AudioDeviceBroker.mDeviceStateLock")
@GuardedBy("BtHelper.this")
void clearCount(boolean stopSco) {
if (mStartcount != 0) {
@@ -764,8 +738,6 @@ public class BtHelper {
return count;
}
- // @GuardedBy("AudioDeviceBroker.mSetModeLock")
- //@GuardedBy("AudioDeviceBroker.mDeviceStateLock")
@GuardedBy("BtHelper.this")
private boolean requestScoState(int state, int scoAudioMode) {
checkScoAudioState();
@@ -959,8 +931,6 @@ public class BtHelper {
return null;
}
- // @GuardedBy("AudioDeviceBroker.mSetModeLock")
- //@GuardedBy("AudioDeviceBroker.mDeviceStateLock")
@GuardedBy("BtHelper.this")
private void clearAllScoClients(int exceptPid, boolean stopSco) {
ScoClient savedClient = null;
diff --git a/services/tests/servicestests/src/com/android/server/audio/AudioDeviceBrokerTest.java b/services/tests/servicestests/src/com/android/server/audio/AudioDeviceBrokerTest.java
index 5c2ad94720f0..29a8dada7d89 100644
--- a/services/tests/servicestests/src/com/android/server/audio/AudioDeviceBrokerTest.java
+++ b/services/tests/servicestests/src/com/android/server/audio/AudioDeviceBrokerTest.java
@@ -126,6 +126,22 @@ public class AudioDeviceBrokerTest {
doTestConnectionDisconnectionReconnection(AudioService.BECOMING_NOISY_DELAY_MS / 2);
}
+ /**
+ * Verify connecting an A2DP sink will call into AudioService to unmute media
+ */
+ @Test
+ public void testA2dpConnectionUnmutesMedia() throws Exception {
+ Log.i(TAG, "testA2dpConnectionUnmutesMedia");
+ Assert.assertNotNull("invalid null BT device", mFakeBtDevice);
+
+ mAudioDeviceBroker.postBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(mFakeBtDevice,
+ BluetoothProfile.STATE_CONNECTED, BluetoothProfile.A2DP, true, 1);
+ Thread.sleep(MAX_MESSAGE_HANDLING_DELAY_MS);
+ verify(mMockAudioService, times(1)).postAccessoryPlugMediaUnmute(
+ ArgumentMatchers.eq(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP));
+
+ }
+
private void doTestConnectionDisconnectionReconnection(int delayAfterDisconnection)
throws Exception {
when(mMockAudioService.getDeviceForStream(AudioManager.STREAM_MUSIC))