Loading android/app/src/com/android/bluetooth/a2dp/A2dpService.java +17 −21 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading Loading @@ -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) { Loading @@ -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; } Loading Loading @@ -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)); } } Loading android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java +9 −23 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -694,31 +695,16 @@ 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 { boolean stopAudio = device == null && (getConnectionState(mPreviousAudioDevice) != BluetoothProfile.STATE_CONNECTED); if (DBG) { Log.d(TAG, "Set Hearing Aid audio to connected"); Log.d(TAG, "Hearing Aid audio: " + mPreviousAudioDevice + " -> " + device + ". Stop audio: " + stopAudio); } if (mPreviousAudioDevice != null) { mAudioManager.setBluetoothHearingAidDeviceConnectionState( mPreviousAudioDevice, BluetoothProfile.STATE_DISCONNECTED, true, 0); } mAudioManager.setBluetoothHearingAidDeviceConnectionState( device, BluetoothProfile.STATE_CONNECTED, true, 0); mAudioManager.handleBluetoothActiveDeviceChanged(device, mPreviousAudioDevice, BtProfileConnectionInfo.hearingAidInfo(!stopAudio)); mPreviousAudioDevice = device; } } // Remove state machine if the bonding for a device is removed private class BondStateChangedReceiver extends BroadcastReceiver { Loading android/app/src/com/android/bluetooth/le_audio/LeAudioService.java +58 −70 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; BluetoothDevice previousInDevice = mActiveAudioInDevice; if (device == null) { Log.d(TAG, " device is null."); return inActiveDeviceReplace; } 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, Loading @@ -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; BluetoothDevice previousOutDevice = mActiveAudioOutDevice; if (device == null) { Log.d(TAG, " device is null."); return outActiveDeviceReplace; } 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; } /** Loading @@ -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); Loading android/app/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidServiceTest.java +5 −6 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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)); Loading Loading @@ -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)); } /** Loading Loading
android/app/src/com/android/bluetooth/a2dp/A2dpService.java +17 −21 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading Loading @@ -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) { Loading @@ -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; } Loading Loading @@ -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)); } } Loading
android/app/src/com/android/bluetooth/hearingaid/HearingAidService.java +9 −23 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -694,31 +695,16 @@ 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 { boolean stopAudio = device == null && (getConnectionState(mPreviousAudioDevice) != BluetoothProfile.STATE_CONNECTED); if (DBG) { Log.d(TAG, "Set Hearing Aid audio to connected"); Log.d(TAG, "Hearing Aid audio: " + mPreviousAudioDevice + " -> " + device + ". Stop audio: " + stopAudio); } if (mPreviousAudioDevice != null) { mAudioManager.setBluetoothHearingAidDeviceConnectionState( mPreviousAudioDevice, BluetoothProfile.STATE_DISCONNECTED, true, 0); } mAudioManager.setBluetoothHearingAidDeviceConnectionState( device, BluetoothProfile.STATE_CONNECTED, true, 0); mAudioManager.handleBluetoothActiveDeviceChanged(device, mPreviousAudioDevice, BtProfileConnectionInfo.hearingAidInfo(!stopAudio)); mPreviousAudioDevice = device; } } // Remove state machine if the bonding for a device is removed private class BondStateChangedReceiver extends BroadcastReceiver { Loading
android/app/src/com/android/bluetooth/le_audio/LeAudioService.java +58 −70 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; BluetoothDevice previousInDevice = mActiveAudioInDevice; if (device == null) { Log.d(TAG, " device is null."); return inActiveDeviceReplace; } 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, Loading @@ -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; BluetoothDevice previousOutDevice = mActiveAudioOutDevice; if (device == null) { Log.d(TAG, " device is null."); return outActiveDeviceReplace; } 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; } /** Loading @@ -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); Loading
android/app/tests/unit/src/com/android/bluetooth/hearingaid/HearingAidServiceTest.java +5 −6 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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)); Loading Loading @@ -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)); } /** Loading