Merge "OPP: Fix leaked IntentReceiver issue" into q-keystone-qcom-dev
diff --git a/src/com/android/bluetooth/a2dp/A2dpService.java b/src/com/android/bluetooth/a2dp/A2dpService.java
index 81ba906..3c8435b 100755
--- a/src/com/android/bluetooth/a2dp/A2dpService.java
+++ b/src/com/android/bluetooth/a2dp/A2dpService.java
@@ -84,6 +84,7 @@
private final Object mActiveDeviceLock = new Object();
private final Object mVariableLock = new Object();
private final ReentrantReadWriteLock mA2dpNativeInterfaceLock = new ReentrantReadWriteLock();
+ private final Object mAudioManagerLock = new Object();
@VisibleForTesting
A2dpNativeInterface mA2dpNativeInterface;
@@ -138,7 +139,7 @@
switch (msg.what) {
case SET_EBMONO_CFG:
Log.d(TAG, "setparameters to Mono");
- synchronized (mVariableLock) {
+ synchronized (mAudioManagerLock) {
if(mAudioManager != null)
mAudioManager.setParameters("TwsChannelConfig=mono");
}
@@ -146,7 +147,7 @@
break;
case SET_EBDUALMONO_CFG:
Log.d(TAG, "setparameters to Dual-Mono");
- synchronized (mVariableLock) {
+ synchronized (mAudioManagerLock) {
if(mAudioManager != null)
mAudioManager.setParameters("TwsChannelConfig=dual-mono");
}
@@ -191,11 +192,14 @@
mA2dpNativeInterfaceLock.writeLock().unlock();
}
BluetoothCodecConfig[] OffloadCodecConfig;
- synchronized (mVariableLock) {
+
+ synchronized (mAudioManagerLock) {
mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
Objects.requireNonNull(mAudioManager,
"AudioManager cannot be null when A2dpService starts");
+ }
+ synchronized (mVariableLock) {
// Step 2: Get maximum number of connected audio devices
mMaxConnectedAudioDevices = mAdapterService.getMaxConnectedAudioDevices();
mSetMaxConnectedAudioDevices = mMaxConnectedAudioDevices;
@@ -240,7 +244,9 @@
// Step 5: Setup codec config
mA2dpCodecConfig = new A2dpCodecConfig(this, mA2dpNativeInterface);
+ }
+ synchronized (mAudioManagerLock) {
// Step 6: Initialize native interface
List<BluetoothCodecConfig> mCodecConfigOffload;
mCodecConfigOffload = mAudioManager.getHwOffloadEncodingFormatsSupportedForA2DP();
@@ -258,13 +264,13 @@
}
synchronized (mVariableLock) {
-
// Step 7: Check if A2DP is in offload mode
mA2dpOffloadEnabled = mAdapterService.isA2dpOffloadEnabled();
if (DBG) {
Log.d(TAG, "A2DP offload flag set to " + mA2dpOffloadEnabled);
}
}
+
// Step 8: Setup broadcast receivers
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
@@ -358,13 +364,16 @@
}
} else {
mMaxConnectedAudioDevices = 1;
- }
+ }
mSetMaxConnectedAudioDevices = 1;
// Step 1: Clear AdapterService, A2dpNativeInterface, AudioManager
- mAudioManager = null;
mAdapterService = null;
}
+ synchronized (mAudioManagerLock) {
+ mAudioManager = null;
+ }
+
try {
mA2dpNativeInterfaceLock.writeLock().lock();
mA2dpNativeInterface = null;
@@ -673,9 +682,11 @@
}
}
int connectionState = BluetoothProfile.STATE_DISCONNECTED;
- A2dpStateMachine sm = mStateMachines.get(device);
- if (sm != null) {
- connectionState = sm.getConnectionState();
+ synchronized (mBtA2dpLock) {
+ A2dpStateMachine sm = mStateMachines.get(device);
+ if (sm != null) {
+ connectionState = sm.getConnectionState();
+ }
}
for (int state : states) {
if (connectionState == state) {
@@ -760,7 +771,7 @@
isBAActive = (mBatService != null) && (mBatService.isBATActive());
Log.d(TAG," removeActiveDevice: BA active " + isBAActive);
// If BA streaming is ongoing, we don't want to pause music player
- synchronized (mVariableLock ) {
+ synchronized (mAudioManagerLock) {
if(!isBAActive && mAudioManager != null) {
mAudioManager.handleBluetoothA2dpActiveDeviceChange(
previousActiveDevice, BluetoothProfile.STATE_DISCONNECTED,
@@ -916,10 +927,12 @@
storeActiveDeviceVolume();
if(previousActiveDevice != null && !tws_switch && isA2dpPlaying(previousActiveDevice)) {
- if (mAudioManager != null && !mAudioManager.isStreamMute(AudioManager.STREAM_MUSIC)) {
- mAudioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC,
- AudioManager.ADJUST_MUTE,
- mAudioManager.FLAG_BLUETOOTH_ABS_VOLUME);
+ synchronized (mAudioManagerLock) {
+ if (mAudioManager != null && !mAudioManager.isStreamMute(AudioManager.STREAM_MUSIC)) {
+ mAudioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC,
+ AudioManager.ADJUST_MUTE,
+ mAudioManager.FLAG_BLUETOOTH_ABS_VOLUME);
+ }
}
}
@@ -943,8 +956,10 @@
updateAndBroadcastActiveDevice(device);
Log.d(TAG, "setActiveDevice(" + device + "): completed");
- if(mAvrcp_ext != null)
- mAvrcp_ext.setActiveDevice(device);
+ synchronized (mBtAvrcpLock) {
+ if (mAvrcp_ext != null)
+ mAvrcp_ext.setActiveDevice(device);
+ }
// Send an intent with the active device codec config
if (codecStatus != null) {
broadcastCodecConfig(mActiveDevice, codecStatus);
@@ -958,9 +973,11 @@
rememberedVolume = mAvrcp_ext.getVolume(device);
Log.d(TAG,"volume = " + rememberedVolume);
}
+ }
+
// Make sure the Audio Manager knows the previous Active device is disconnected,
// and the new Active device is connected.
-
+ synchronized (mAudioManagerLock) {
if (!isBAActive && mAudioManager != null) {
// Make sure the Audio Manager knows the previous
// Active device is disconnected, and the new Active
@@ -973,6 +990,7 @@
mActiveDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.A2DP,
true, rememberedVolume);
}
+ }
// Inform the Audio Service about the codec configuration
// change, so the Audio Service can reset accordingly the audio
@@ -980,6 +998,7 @@
// Split A2dp will be enabled by default
boolean isSplitA2dpEnabled = true;
+ synchronized (mVariableLock) {
AdapterService adapterService = AdapterService.getAdapterService();
if (adapterService != null){
@@ -990,9 +1009,11 @@
}
}
// Don't update the absVolume flags when disconnect one device in multicast mode
- if (!a2dpMulticast || previousActiveDevice == null) {
- if (mAvrcp_ext != null && !tws_switch) {
- mAvrcp_ext.setAbsVolumeFlag(device);
+ synchronized (mBtAvrcpLock) {
+ if (!a2dpMulticast || previousActiveDevice == null) {
+ if (mAvrcp_ext != null && !tws_switch) {
+ mAvrcp_ext.setAbsVolumeFlag(device);
+ }
}
}
tws_switch = false;
@@ -1089,11 +1110,13 @@
public void storeDeviceAudioVolume(BluetoothDevice device) {
if (device != null)
{
- if (AvrcpTargetService.get() != null) {
- AvrcpTargetService.get().storeVolumeForDevice(device);
- } else if (mAvrcp_ext != null) {
- //store volume in multi-a2dp for the device doesn't set as active
- mAvrcp_ext.storeVolumeForDevice(device);
+ synchronized (mBtAvrcpLock) {
+ if (AvrcpTargetService.get() != null) {
+ AvrcpTargetService.get().storeVolumeForDevice(device);
+ } else if (mAvrcp_ext != null) {
+ //store volume in multi-a2dp for the device doesn't set as active
+ mAvrcp_ext.storeVolumeForDevice(device);
+ }
}
}
}
@@ -1377,6 +1400,7 @@
BluetoothDevice device = stackEvent.device;
A2dpStateMachine sm = mStateMachines.get(device);
if (sm == null) {
+ Log.d(TAG, "messageFromNative: stackEvent.type: " + stackEvent.type);
if (stackEvent.type == A2dpStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED) {
switch (stackEvent.valueInt) {
case A2dpStackEvent.CONNECTION_STATE_CONNECTED:
@@ -1421,7 +1445,9 @@
}
}
} else {
+ Log.d(TAG, "messageFromNative: Going to acquire mVariableLock.");
synchronized (mVariableLock) {
+ Log.d(TAG, "messageFromNative: Acquired mVariableLock");
if (mAdapterService != null && mAdapterService.isVendorIntfEnabled()) {
switch (sm.getConnectionState()) {
case BluetoothProfile.STATE_DISCONNECTED:
@@ -1433,6 +1459,7 @@
}
}
}
+ Log.d(TAG, "messageFromNative: Released mVariableLock");
}
if (sm == null) {
Log.e(TAG, "Cannot process stack event: no state machine: " + stackEvent);
@@ -1448,6 +1475,7 @@
sA2dpSinkService.disconnect(src);
}
}
+ Log.d(TAG, "messageFromNative: Sending STACK_EVENT: " + stackEvent + " to sm.");
sm.sendMessage(A2dpStateMachine.STACK_EVENT, stackEvent);
}
}
@@ -1495,9 +1523,11 @@
// parameters in the Audio HAL to the Bluetooth stack.
int rememberedVolume = -1;
if (isActiveDevice(device) && !sameAudioFeedingParameters) {
- if (mAvrcp_ext != null)
- rememberedVolume = mAvrcp_ext.getVolume(device);
- synchronized (mVariableLock) {
+ synchronized (mBtAvrcpLock) {
+ if (mAvrcp_ext != null)
+ rememberedVolume = mAvrcp_ext.getVolume(device);
+ }
+ synchronized (mAudioManagerLock) {
if (mAudioManager != null) {
mAudioManager.handleBluetoothA2dpActiveDeviceChange(device,
BluetoothProfile.STATE_CONNECTED, BluetoothProfile.A2DP,
@@ -1508,13 +1538,14 @@
}
void updateTwsChannelMode(int state, BluetoothDevice device) {
+ Log.d(TAG, "updateTwsChannelMode: mIsTwsPlusMonoSupported: " + mIsTwsPlusMonoSupported);
if (mIsTwsPlusMonoSupported) {
BluetoothDevice peerTwsDevice = null;
synchronized (mVariableLock) {
if (mAdapterService != null)
peerTwsDevice = mAdapterService.getTwsPlusPeerDevice(device);
}
- Log.d(TAG, "TwsChannelMode: " + mTwsPlusChannelMode);
+ Log.d(TAG, "TwsChannelMode: " + mTwsPlusChannelMode + " state: " + state);
synchronized(mBtTwsLock) {
if ("mono".equals(mTwsPlusChannelMode)) {
if ((state == BluetoothA2dp.STATE_PLAYING) && (peerTwsDevice!= null)
@@ -1523,11 +1554,14 @@
Message msg = mHandler.obtainMessage(SET_EBDUALMONO_CFG);
mHandler.sendMessageDelayed(msg, DualMonoCfg_Timeout);
} else if (state == BluetoothA2dp.STATE_PLAYING) {
- Log.d(TAG, "setparameters to Mono");
- synchronized (mVariableLock) {
- if (mAudioManager != null)
+ Log.d(TAG, "updateTwsChannelMode: setparameters to Mono");
+ synchronized (mAudioManagerLock) {
+ if (mAudioManager != null) {
+ Log.d(TAG, "updateTwsChannelMode: Acquired mAudioManagerLock");
mAudioManager.setParameters("TwsChannelConfig=mono");
+ }
}
+ Log.d(TAG, "updateTwsChannelMode: Released mAudioManagerLock");
}
if ((state == BluetoothA2dp.STATE_NOT_PLAYING) &&
isA2dpPlaying(peerTwsDevice)) {
@@ -1553,7 +1587,7 @@
if ((state == BluetoothA2dp.STATE_NOT_PLAYING)
&& isA2dpPlaying(peerTwsDevice)) {
Log.d(TAG, "setparameters to Mono");
- synchronized (mVariableLock) {
+ synchronized (mAudioManagerLock) {
if (mAudioManager != null)
mAudioManager.setParameters("TwsChannelConfig=mono");
}
@@ -1576,7 +1610,7 @@
if(isBAActive) {
return;
}
- synchronized (mVariableLock) {
+ synchronized (mAudioManagerLock) {
if (mAudioManager != null)
mAudioManager.setParameters("reconfigA2dp=true");
}
@@ -1689,15 +1723,16 @@
if (sm.getConnectionState() != BluetoothProfile.STATE_DISCONNECTED) {
return;
}
+ }
+ synchronized (mBtAvrcpLock) {
if (mFactory.getAvrcpTargetService() != null) {
mFactory.getAvrcpTargetService().removeStoredVolumeForDevice(device);
}
if (mAvrcp_ext != null) {
mAvrcp_ext.removeVolumeForDevice(device);
}
-
- removeStateMachine(device);
}
+ removeStateMachine(device);
}
private void removeStateMachine(BluetoothDevice device) {
diff --git a/src/com/android/bluetooth/a2dp/A2dpStateMachine.java b/src/com/android/bluetooth/a2dp/A2dpStateMachine.java
index 01018d0..94ad8da 100644
--- a/src/com/android/bluetooth/a2dp/A2dpStateMachine.java
+++ b/src/com/android/bluetooth/a2dp/A2dpStateMachine.java
@@ -572,6 +572,7 @@
// in Connected state
private void processAudioStateEvent(int state) {
+ Log.i(TAG, "Connected: processAudioStateEvent: state: " + state + " mIsPlaying: " + mIsPlaying);
switch (state) {
case A2dpStackEvent.AUDIO_STATE_STARTED:
synchronized (this) {