diff options
author | wescande <wescande@google.com> | 2021-07-30 16:40:24 +0200 |
---|---|---|
committer | William Escande <wescande@google.com> | 2021-11-12 21:13:34 +0100 |
commit | 1d9c9bf43c31e5de472190e204d33f890e960cf3 (patch) | |
tree | 1d1c42b32203590a9b1692b2f1828b6452f82e31 | |
parent | 95e640f38c3e45fc4ecdbab36a81bf17d139e5ff (diff) | |
download | Bluetooth-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
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)); } /** |