summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwescande <wescande@google.com>2021-07-30 16:40:24 +0200
committerWilliam Escande <wescande@google.com>2021-11-12 21:13:34 +0100
commit1d9c9bf43c31e5de472190e204d33f890e960cf3 (patch)
tree1d1c42b32203590a9b1692b2f1828b6452f82e31
parent95e640f38c3e45fc4ecdbab36a81bf17d139e5ff (diff)
downloadBluetooth-1d9c9bf43c31e5de472190e204d33f890e960cf3.tar.gz
A2DP switch device refactor
Replace 3 hidden api by a common one. Test: Manual Tag: #refactor Bug: 190422401 Merged-In: I21bd61187a8f2490c3345a61974e0a1f1563637f Change-Id: I21bd61187a8f2490c3345a61974e0a1f1563637f
-rw-r--r--src/com/android/bluetooth/a2dp/A2dpService.java38
-rw-r--r--src/com/android/bluetooth/hearingaid/HearingAidService.java32
-rw-r--r--src/com/android/bluetooth/le_audio/LeAudioService.java128
-rw-r--r--tests/unit/src/com/android/bluetooth/hearingaid/HearingAidServiceTest.java11
4 files changed, 89 insertions, 120 deletions
diff --git a/src/com/android/bluetooth/a2dp/A2dpService.java b/src/com/android/bluetooth/a2dp/A2dpService.java
index 542509ed5..557f3b2b0 100644
--- a/src/com/android/bluetooth/a2dp/A2dpService.java
+++ b/src/com/android/bluetooth/a2dp/A2dpService.java
@@ -37,6 +37,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioManager;
+import android.media.BtProfileConnectionInfo;
import android.os.HandlerThread;
import android.util.Log;
@@ -462,13 +463,10 @@ public class A2dpService extends ProfileService {
// device, the user has explicitly switched the output to the local device and music
// should continue playing. Otherwise, the remote device has been indeed disconnected
// and audio should be suspended before switching the output to the local device.
- boolean suppressNoisyIntent = !forceStopPlayingAudio
- && (getConnectionState(previousActiveDevice)
- == BluetoothProfile.STATE_CONNECTED);
- Log.i(TAG, "removeActiveDevice: suppressNoisyIntent=" + suppressNoisyIntent);
- mAudioManager.setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(
- previousActiveDevice, BluetoothProfile.STATE_DISCONNECTED,
- BluetoothProfile.A2DP, suppressNoisyIntent, -1);
+ boolean stopAudio = forceStopPlayingAudio || (getConnectionState(previousActiveDevice)
+ != BluetoothProfile.STATE_CONNECTED);
+ mAudioManager.handleBluetoothActiveDeviceChanged(null, previousActiveDevice,
+ BtProfileConnectionInfo.a2dpInfo(!stopAudio, -1));
synchronized (mStateMachines) {
// Make sure the Active device in native layer is set to null and audio is off
@@ -552,13 +550,6 @@ public class A2dpService extends ProfileService {
// This needs to happen before we inform the audio manager that the device
// disconnected. Please see comment in updateAndBroadcastActiveDevice() for why.
updateAndBroadcastActiveDevice(device);
- // Make sure the Audio Manager knows the previous Active device is disconnected,
- // and the new Active device is connected.
- if (previousActiveDevice != null) {
- mAudioManager.setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(
- previousActiveDevice, BluetoothProfile.STATE_DISCONNECTED,
- BluetoothProfile.A2DP, true, -1);
- }
BluetoothDevice newActiveDevice = null;
synchronized (mStateMachines) {
@@ -583,13 +574,13 @@ public class A2dpService extends ProfileService {
rememberedVolume = mFactory.getAvrcpTargetService()
.getRememberedVolumeForDevice(newActiveDevice);
}
- mAudioManager.setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(
- newActiveDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.A2DP,
- true, rememberedVolume);
- // Inform the Audio Service about the codec configuration
+ // Make sure the Audio Manager knows the previous Active device is disconnected,
+ // and the new Active device is connected.
+ // And inform the Audio Service about the codec configuration
// change, so the Audio Service can reset accordingly the audio
// feeding parameters in the Audio HAL to the Bluetooth stack.
- mAudioManager.handleBluetoothA2dpDeviceConfigChange(newActiveDevice);
+ mAudioManager.handleBluetoothActiveDeviceChanged(newActiveDevice, previousActiveDevice,
+ BtProfileConnectionInfo.a2dpInfo(true, rememberedVolume));
}
return true;
}
@@ -972,8 +963,13 @@ public class A2dpService extends ProfileService {
// Inform the Audio Service about the codec configuration change,
// so the Audio Service can reset accordingly the audio feeding
// parameters in the Audio HAL to the Bluetooth stack.
- if (isActiveDevice(device) && !sameAudioFeedingParameters) {
- mAudioManager.handleBluetoothA2dpDeviceConfigChange(device);
+ // Until we are able to detect from device_port_proxy if the config has changed or not,
+ // the Bluetooth stack can only disable the audio session and need to ask audioManager to
+ // restart the session even if feeding parameter are the same. (sameAudioFeedingParameters
+ // is left unused until there)
+ if (isActiveDevice(device)) {
+ mAudioManager.handleBluetoothActiveDeviceChanged(device, device,
+ BtProfileConnectionInfo.a2dpInfo(false, -1));
}
}
diff --git a/src/com/android/bluetooth/hearingaid/HearingAidService.java b/src/com/android/bluetooth/hearingaid/HearingAidService.java
index 2ab14cb17..6199ff1e1 100644
--- a/src/com/android/bluetooth/hearingaid/HearingAidService.java
+++ b/src/com/android/bluetooth/hearingaid/HearingAidService.java
@@ -30,6 +30,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioManager;
+import android.media.BtProfileConnectionInfo;
import android.os.HandlerThread;
import android.os.ParcelUuid;
import android.util.Log;
@@ -694,30 +695,15 @@ public class HearingAidService extends ProfileService {
| Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
sendBroadcast(intent, BLUETOOTH_CONNECT, Utils.getTempAllowlistBroadcastOptions());
- if (device == null) {
- if (DBG) {
- Log.d(TAG, "Set Hearing Aid audio to disconnected");
- }
- boolean suppressNoisyIntent =
- (getConnectionState(mPreviousAudioDevice) == BluetoothProfile.STATE_CONNECTED);
- mAudioManager.setBluetoothHearingAidDeviceConnectionState(
- mPreviousAudioDevice, BluetoothProfile.STATE_DISCONNECTED,
- suppressNoisyIntent, 0);
- mPreviousAudioDevice = null;
- } else {
- if (DBG) {
- Log.d(TAG, "Set Hearing Aid audio to connected");
- }
- if (mPreviousAudioDevice != null) {
- mAudioManager.setBluetoothHearingAidDeviceConnectionState(
- mPreviousAudioDevice, BluetoothProfile.STATE_DISCONNECTED,
- true, 0);
- }
- mAudioManager.setBluetoothHearingAidDeviceConnectionState(
- device, BluetoothProfile.STATE_CONNECTED,
- true, 0);
- mPreviousAudioDevice = device;
+ boolean stopAudio = device == null
+ && (getConnectionState(mPreviousAudioDevice) != BluetoothProfile.STATE_CONNECTED);
+ if (DBG) {
+ Log.d(TAG, "Hearing Aid audio: " + mPreviousAudioDevice + " -> " + device
+ + ". Stop audio: " + stopAudio);
}
+ mAudioManager.handleBluetoothActiveDeviceChanged(device, mPreviousAudioDevice,
+ BtProfileConnectionInfo.hearingAidInfo(!stopAudio));
+ mPreviousAudioDevice = device;
}
// Remove state machine if the bonding for a device is removed
diff --git a/src/com/android/bluetooth/le_audio/LeAudioService.java b/src/com/android/bluetooth/le_audio/LeAudioService.java
index 975dfa180..60f31f71e 100644
--- a/src/com/android/bluetooth/le_audio/LeAudioService.java
+++ b/src/com/android/bluetooth/le_audio/LeAudioService.java
@@ -40,6 +40,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.media.AudioManager;
+import android.media.BtProfileConnectionInfo;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.ParcelUuid;
@@ -93,8 +94,8 @@ public class LeAudioService extends ProfileService {
private AdapterService mAdapterService;
private DatabaseManager mDatabaseManager;
private HandlerThread mStateMachinesThread;
- private BluetoothDevice mPreviousAudioOutDevice;
- private BluetoothDevice mPreviousAudioInDevice;
+ private BluetoothDevice mActiveAudioOutDevice;
+ private BluetoothDevice mActiveAudioInDevice;
ServiceFactory mServiceFactory = new ServiceFactory();
LeAudioNativeInterface mLeAudioNativeInterface;
@@ -664,49 +665,44 @@ public class LeAudioService extends ProfileService {
boolean newSupportedByDeviceInput = (newSupportedAudioDirections
& AUDIO_DIRECTION_INPUT_BIT) != 0;
- if (device != null && mPreviousAudioInDevice != null) {
- int previousGroupId = getGroupId(mPreviousAudioInDevice);
+ if (device != null && mActiveAudioInDevice != null) {
+ int previousGroupId = getGroupId(mActiveAudioInDevice);
if (previousGroupId == groupId) {
/* This is thes same group as aleady notified to the system.
* Therefore do not change the device we have connected to the group,
* unless, previous one is disconnected now
*/
- if (mPreviousAudioInDevice.isConnected())
- device = mPreviousAudioInDevice;
+ if (mActiveAudioInDevice.isConnected()) {
+ device = mActiveAudioInDevice;
+ }
}
}
- /* Disconnect input:
- * - If active input device changed (to none or any)
- * - If device stops supporting input
- */
- boolean inActiveDeviceReplace = (device != mPreviousAudioInDevice);
- if (inActiveDeviceReplace && (mPreviousAudioInDevice != null)) {
- mAudioManager.setBluetoothLeAudioInDeviceConnectionState(
- mPreviousAudioInDevice, BluetoothProfile.STATE_DISCONNECTED);
- }
-
- mPreviousAudioInDevice = device;
-
- if (device == null) {
- Log.d(TAG, " device is null.");
- return inActiveDeviceReplace;
- }
+ BluetoothDevice previousInDevice = mActiveAudioInDevice;
- if (inActiveDeviceReplace == false ||
- (oldSupportedByDeviceInput == newSupportedByDeviceInput)) {
- Log.d(TAG, " Nothing to do.");
- return inActiveDeviceReplace;
+ /*
+ * Do not update input if neither previous nor current device support input
+ */
+ if (!oldSupportedByDeviceInput && !newSupportedByDeviceInput) {
+ Log.d(TAG, "updateActiveInDevice: Device does not support input.");
+ return false;
}
- /* Connect input:
- * - If active input device changed
- * - If device starts support input
+ /*
+ * Update input if:
+ * - Device changed
+ * OR
+ * - Device stops / starts supporting input
*/
- mAudioManager.setBluetoothLeAudioInDeviceConnectionState(
- device, BluetoothProfile.STATE_CONNECTED);
-
- return inActiveDeviceReplace;
+ if (!Objects.equals(device, previousInDevice)
+ || (oldSupportedByDeviceInput != newSupportedByDeviceInput)) {
+ mActiveAudioInDevice = newSupportedByDeviceInput ? device : null;
+ mAudioManager.handleBluetoothActiveDeviceChanged(mActiveAudioInDevice, previousInDevice,
+ BtProfileConnectionInfo.leAudio(false, false));
+ return true;
+ }
+ Log.d(TAG, "updateActiveInDevice: Nothing to do.");
+ return false;
}
private boolean updateActiveOutDevice(BluetoothDevice device, Integer groupId,
@@ -722,53 +718,46 @@ public class LeAudioService extends ProfileService {
boolean newSupportedByDeviceOutput = (newSupportedAudioDirections
& AUDIO_DIRECTION_OUTPUT_BIT) != 0;
-
- if (device != null && mPreviousAudioOutDevice != null) {
- int previousGroupId = getGroupId(mPreviousAudioOutDevice);
+ if (device != null && mActiveAudioOutDevice != null) {
+ int previousGroupId = getGroupId(mActiveAudioOutDevice);
if (previousGroupId == groupId) {
/* This is the same group as already notified to the system.
* Therefore do not change the device we have connected to the group,
* unless, previous one is disconnected now
*/
- if (mPreviousAudioOutDevice.isConnected())
- device = mPreviousAudioOutDevice;
+ if (mActiveAudioOutDevice.isConnected()) {
+ device = mActiveAudioOutDevice;
+ }
}
}
- /* Disconnect output:
- * - If active output device changed (to none or any)
- * - If device stops supporting output
- */
- boolean outActiveDeviceReplace = (device != mPreviousAudioOutDevice);
- if (outActiveDeviceReplace && (mPreviousAudioOutDevice != null)) {
- boolean suppressNoisyIntent =
- (getConnectionState(mPreviousAudioOutDevice) ==
- BluetoothProfile.STATE_CONNECTED);
- mAudioManager.setBluetoothLeAudioOutDeviceConnectionState(
- mPreviousAudioOutDevice, BluetoothProfile.STATE_DISCONNECTED,
- suppressNoisyIntent);
- }
-
- mPreviousAudioOutDevice = device;
-
- if (device == null) {
- Log.d(TAG, " device is null.");
- return outActiveDeviceReplace;
- }
+ BluetoothDevice previousOutDevice = mActiveAudioOutDevice;
- if (outActiveDeviceReplace == false ||
- (oldSupportedByDeviceOutput == newSupportedByDeviceOutput)) {
- Log.d(TAG, " Nothing to do.");
- return outActiveDeviceReplace;
+ /*
+ * Do not update output if neither previous nor current device support output
+ */
+ if (!oldSupportedByDeviceOutput && !newSupportedByDeviceOutput) {
+ Log.d(TAG, "updateActiveOutDevice: Device does not support output.");
+ return false;
}
- /* Connect output:
- * - If active output device changed
- * - If device starts support output
+ /*
+ * Update output if:
+ * - Device changed
+ * OR
+ * - Device stops / starts supporting output
*/
- mAudioManager.setBluetoothLeAudioOutDeviceConnectionState(
- device, BluetoothProfile.STATE_CONNECTED, true);
- return outActiveDeviceReplace;
+ if (!Objects.equals(device, previousOutDevice)
+ || (oldSupportedByDeviceOutput != newSupportedByDeviceOutput)) {
+ mActiveAudioOutDevice = newSupportedByDeviceOutput ? device : null;
+ final boolean suppressNoisyIntent = (mActiveAudioOutDevice != null)
+ || (getConnectionState(previousOutDevice) == BluetoothProfile.STATE_CONNECTED);
+ mAudioManager.handleBluetoothActiveDeviceChanged(mActiveAudioOutDevice,
+ previousOutDevice, BtProfileConnectionInfo.leAudio(suppressNoisyIntent, true));
+ return true;
+ }
+ Log.d(TAG, "updateActiveOutDevice: Nothing to do.");
+ return false;
}
/**
@@ -786,13 +775,12 @@ public class LeAudioService extends ProfileService {
boolean outReplaced =
updateActiveOutDevice(device, groupId, oldActiveContexts, newActiveContexts);
-
boolean inReplaced =
updateActiveInDevice(device, groupId, oldActiveContexts, newActiveContexts);
if (outReplaced || inReplaced) {
Intent intent = new Intent(BluetoothLeAudio.ACTION_LE_AUDIO_ACTIVE_DEVICE_CHANGED);
- intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mPreviousAudioOutDevice);
+ intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mActiveAudioOutDevice);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
| Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
sendBroadcast(intent, BLUETOOTH_CONNECT);
diff --git a/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidServiceTest.java b/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidServiceTest.java
index dab30994e..b2996f9a9 100644
--- a/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidServiceTest.java
+++ b/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidServiceTest.java
@@ -28,6 +28,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioManager;
+import android.media.BtProfileConnectionInfo;
import android.os.Looper;
import android.os.ParcelUuid;
@@ -521,9 +522,8 @@ public class HearingAidServiceTest {
Assert.assertTrue(mService.getConnectedDevices().contains(mRightDevice));
// Verify the audio is routed to Hearing Aid Profile
- verify(mAudioManager).setBluetoothHearingAidDeviceConnectionState(
- any(BluetoothDevice.class), eq(BluetoothProfile.STATE_CONNECTED),
- eq(true), eq(0));
+ verify(mAudioManager).handleBluetoothActiveDeviceChanged(
+ any(BluetoothDevice.class), eq(null), any(BtProfileConnectionInfo.class));
// Send a disconnect request
Assert.assertTrue("Disconnect failed", mService.disconnect(mLeftDevice));
@@ -570,9 +570,8 @@ public class HearingAidServiceTest {
Assert.assertFalse(mService.getConnectedDevices().contains(mRightDevice));
// Verify the audio is not routed to Hearing Aid Profile
- verify(mAudioManager).setBluetoothHearingAidDeviceConnectionState(
- any(BluetoothDevice.class), eq(BluetoothProfile.STATE_DISCONNECTED),
- eq(false), eq(0));
+ verify(mAudioManager).handleBluetoothActiveDeviceChanged(
+ eq(null), any(BluetoothDevice.class), any(BtProfileConnectionInfo.class));
}
/**