Loading media/java/android/media/AudioSystem.java +22 −3 Original line number Diff line number Diff line Loading @@ -318,11 +318,12 @@ public class AudioSystem /** * @hide * Convert a Bluetooth codec to an audio format enum * Convert an A2DP Bluetooth codec to an audio format enum * @param btCodec the codec to convert. * @return the audio format, or {@link #AUDIO_FORMAT_DEFAULT} if unknown */ public static @AudioFormatNativeEnumForBtCodec int bluetoothCodecToAudioFormat(int btCodec) { public static @AudioFormatNativeEnumForBtCodec int bluetoothA2dpCodecToAudioFormat( int btCodec) { switch (btCodec) { case BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC: return AudioSystem.AUDIO_FORMAT_SBC; Loading @@ -339,7 +340,25 @@ public class AudioSystem case BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS: return AudioSystem.AUDIO_FORMAT_OPUS; default: Log.e(TAG, "Unknown BT codec 0x" + Integer.toHexString(btCodec) Log.e(TAG, "Unknown A2DP BT codec 0x" + Integer.toHexString(btCodec) + " for conversion to audio format"); // TODO returning DEFAULT is the current behavior, should this return INVALID? return AudioSystem.AUDIO_FORMAT_DEFAULT; } } /** * @hide * Convert a LE Audio Bluetooth codec to an audio format enum * @param btCodec the codec to convert. * @return the audio format, or {@link #AUDIO_FORMAT_DEFAULT} if unknown */ public static @AudioFormatNativeEnumForBtCodec int bluetoothLeCodecToAudioFormat(int btCodec) { switch (btCodec) { case BluetoothLeAudioCodecConfig.SOURCE_CODEC_TYPE_LC3: return AudioSystem.AUDIO_FORMAT_LC3; default: Log.e(TAG, "Unknown LE Audio BT codec 0x" + Integer.toHexString(btCodec) + " for conversion to audio format"); // TODO returning DEFAULT is the current behavior, should this return INVALID? return AudioSystem.AUDIO_FORMAT_DEFAULT; Loading services/core/java/com/android/server/audio/AudioDeviceBroker.java +15 −12 Original line number Diff line number Diff line Loading @@ -1595,8 +1595,8 @@ public class AudioDeviceBroker { sendILMsg(MSG_IL_BTA2DP_TIMEOUT, SENDMSG_QUEUE, a2dpCodec, address, delayMs); } /*package*/ void setLeAudioTimeout(String address, int device, int delayMs) { sendILMsg(MSG_IL_BTLEAUDIO_TIMEOUT, SENDMSG_QUEUE, device, address, delayMs); /*package*/ void setLeAudioTimeout(String address, int device, int codec, int delayMs) { sendIILMsg(MSG_IIL_BTLEAUDIO_TIMEOUT, SENDMSG_QUEUE, device, codec, address, delayMs); } /*package*/ void setAvrcpAbsoluteVolumeSupported(boolean supported) { Loading Loading @@ -1794,8 +1794,9 @@ public class AudioDeviceBroker { return; } @AudioSystem.AudioFormatNativeEnumForBtCodec final int codec = mBtHelper.getA2dpCodecWithFallbackToSBC( btInfo.mDevice, "MSG_L_SET_BT_ACTIVE_DEVICE"); mBtHelper.getCodecWithFallback(btInfo.mDevice, btInfo.mProfile, btInfo.mIsLeOutput, "MSG_L_SET_BT_ACTIVE_DEVICE"); mDeviceInventory.onSetBtActiveDevice(btInfo, codec, (btInfo.mProfile != BluetoothProfile.LE_AUDIO || btInfo.mIsLeOutput) Loading @@ -1819,22 +1820,24 @@ public class AudioDeviceBroker { case MSG_IL_BTA2DP_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_IL_BTLEAUDIO_TIMEOUT: case MSG_IIL_BTLEAUDIO_TIMEOUT: // msg.obj == address of LE Audio device synchronized (mDeviceStateLock) { mDeviceInventory.onMakeLeAudioDeviceUnavailableNow( (String) msg.obj, msg.arg1); (String) msg.obj, msg.arg1, msg.arg2); } break; case MSG_L_BLUETOOTH_DEVICE_CONFIG_CHANGE: { final BtDeviceInfo btInfo = (BtDeviceInfo) msg.obj; synchronized (mDeviceStateLock) { @AudioSystem.AudioFormatNativeEnumForBtCodec final int codec = mBtHelper.getA2dpCodecWithFallbackToSBC( btInfo.mDevice, "MSG_L_BLUETOOTH_DEVICE_CONFIG_CHANGE"); mBtHelper.getCodecWithFallback(btInfo.mDevice, btInfo.mProfile, btInfo.mIsLeOutput, "MSG_L_BLUETOOTH_DEVICE_CONFIG_CHANGE"); mDeviceInventory.onBluetoothDeviceConfigChange( btInfo, codec, BtHelper.EVENT_DEVICE_CONFIG_CHANGE); } Loading Loading @@ -2084,7 +2087,7 @@ public class AudioDeviceBroker { private static final int MSG_IL_SAVE_NDEF_DEVICE_FOR_STRATEGY = 47; private static final int MSG_IL_SAVE_REMOVE_NDEF_DEVICE_FOR_STRATEGY = 48; private static final int MSG_IL_BTLEAUDIO_TIMEOUT = 49; private static final int MSG_IIL_BTLEAUDIO_TIMEOUT = 49; private static final int MSG_L_NOTIFY_PREFERRED_AUDIOPROFILE_APPLIED = 52; private static final int MSG_L_CHECK_COMMUNICATION_DEVICE_REMOVAL = 53; Loading @@ -2104,7 +2107,7 @@ public class AudioDeviceBroker { case MSG_L_SET_WIRED_DEVICE_CONNECTION_STATE: case MSG_L_SET_BT_ACTIVE_DEVICE: case MSG_IL_BTA2DP_TIMEOUT: case MSG_IL_BTLEAUDIO_TIMEOUT: case MSG_IIL_BTLEAUDIO_TIMEOUT: case MSG_L_BLUETOOTH_DEVICE_CONFIG_CHANGE: case MSG_TOGGLE_HDMI: case MSG_L_A2DP_DEVICE_CONNECTION_CHANGE_EXT: Loading Loading @@ -2196,7 +2199,7 @@ public class AudioDeviceBroker { case MSG_L_SET_BT_ACTIVE_DEVICE: case MSG_L_SET_WIRED_DEVICE_CONNECTION_STATE: case MSG_IL_BTA2DP_TIMEOUT: case MSG_IL_BTLEAUDIO_TIMEOUT: case MSG_IIL_BTLEAUDIO_TIMEOUT: case MSG_L_BLUETOOTH_DEVICE_CONFIG_CHANGE: if (sLastDeviceConnectMsgTime >= time) { // add a little delay to make sure messages are ordered as expected Loading services/core/java/com/android/server/audio/AudioDeviceInventory.java +26 −19 Original line number Diff line number Diff line Loading @@ -689,9 +689,11 @@ public class AudioDeviceInventory { case BluetoothProfile.LE_AUDIO: case BluetoothProfile.LE_AUDIO_BROADCAST: if (switchToUnavailable) { makeLeAudioDeviceUnavailableNow(address, btInfo.mAudioSystemDevice); makeLeAudioDeviceUnavailableNow(address, btInfo.mAudioSystemDevice, di.mDeviceCodecFormat); } else if (switchToAvailable) { makeLeAudioDeviceAvailable(btInfo, streamType, "onSetBtActiveDevice"); makeLeAudioDeviceAvailable( btInfo, streamType, codec, "onSetBtActiveDevice"); } break; default: throw new IllegalArgumentException("Invalid profile " Loading Loading @@ -752,12 +754,13 @@ public class AudioDeviceInventory { if (event == BtHelper.EVENT_DEVICE_CONFIG_CHANGE) { boolean a2dpCodecChange = false; if (btInfo.mProfile == BluetoothProfile.A2DP) { boolean codecChange = false; if (btInfo.mProfile == BluetoothProfile.A2DP || btInfo.mProfile == BluetoothProfile.LE_AUDIO) { if (di.mDeviceCodecFormat != codec) { di.mDeviceCodecFormat = codec; mConnectedDevices.replace(key, di); a2dpCodecChange = true; codecChange = true; } final int res = mAudioSystem.handleDeviceConfigChange( btInfo.mAudioSystemDevice, address, BtHelper.getName(btDevice), codec); Loading @@ -782,7 +785,7 @@ public class AudioDeviceInventory { } } if (!a2dpCodecChange) { if (!codecChange) { updateBluetoothPreferredModes_l(btDevice /*connectedDevice*/); } } Loading @@ -796,9 +799,9 @@ public class AudioDeviceInventory { } } /*package*/ void onMakeLeAudioDeviceUnavailableNow(String address, int device) { /*package*/ void onMakeLeAudioDeviceUnavailableNow(String address, int device, int codec) { synchronized (mDevicesLock) { makeLeAudioDeviceUnavailableNow(address, device); makeLeAudioDeviceUnavailableNow(address, device, codec); } } Loading Loading @@ -1657,11 +1660,12 @@ public class AudioDeviceInventory { } synchronized (mDevicesLock) { final ArraySet<String> toRemove = new ArraySet<>(); final ArraySet<Pair<String, Integer>> toRemove = new ArraySet<>(); // Disconnect ALL DEVICE_OUT_BLE_HEADSET or DEVICE_OUT_BLE_BROADCAST devices mConnectedDevices.values().forEach(deviceInfo -> { if (deviceInfo.mDeviceType == device) { toRemove.add(deviceInfo.mDeviceAddress); toRemove.add( new Pair<>(deviceInfo.mDeviceAddress, deviceInfo.mDeviceCodecFormat)); } }); new MediaMetrics.Item(mMetricsId + "disconnectLeAudio") Loading @@ -1671,8 +1675,8 @@ public class AudioDeviceInventory { final int delay = checkSendBecomingNoisyIntentInt(device, AudioService.CONNECTION_STATE_DISCONNECTED, AudioSystem.DEVICE_NONE); toRemove.stream().forEach(deviceAddress -> makeLeAudioDeviceUnavailableLater(deviceAddress, device, delay) toRemove.stream().forEach(entry -> makeLeAudioDeviceUnavailableLater(entry.first, device, entry.second, delay) ); } } Loading Loading @@ -2216,7 +2220,8 @@ public class AudioDeviceInventory { @GuardedBy("mDevicesLock") private void makeLeAudioDeviceAvailable( AudioDeviceBroker.BtDeviceInfo btInfo, int streamType, String eventSource) { AudioDeviceBroker.BtDeviceInfo btInfo, int streamType, @AudioSystem.AudioFormatNativeEnumForBtCodec int codec, String eventSource) { final int volumeIndex = btInfo.mVolume == -1 ? -1 : btInfo.mVolume * 10; final int device = btInfo.mAudioSystemDevice; Loading Loading @@ -2250,7 +2255,7 @@ public class AudioDeviceInventory { AudioDeviceAttributes ada = new AudioDeviceAttributes(device, address, name); final int res = AudioSystem.setDeviceConnectionState(ada, AudioSystem.DEVICE_STATE_AVAILABLE, AudioSystem.AUDIO_FORMAT_DEFAULT); AudioSystem.DEVICE_STATE_AVAILABLE, codec); if (res != AudioSystem.AUDIO_STATUS_OK) { AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent( "APM failed to make available LE Audio device addr=" + address Loading @@ -2265,7 +2270,7 @@ public class AudioDeviceInventory { // Reset LEA suspend state each time a new sink is connected mDeviceBroker.clearLeAudioSuspended(true /* internalOnly */); mConnectedDevices.put(DeviceInfo.makeDeviceListKey(device, address), new DeviceInfo(device, name, address, AudioSystem.AUDIO_FORMAT_DEFAULT, new DeviceInfo(device, name, address, codec, peerAddress, groupId)); mDeviceBroker.postAccessoryPlugMediaUnmute(device); setCurrentAudioRouteNameIfPossible(name, /*fromA2dp=*/false); Loading @@ -2288,13 +2293,14 @@ public class AudioDeviceInventory { } @GuardedBy("mDevicesLock") private void makeLeAudioDeviceUnavailableNow(String address, int device) { private void makeLeAudioDeviceUnavailableNow(String address, int device, @AudioSystem.AudioFormatNativeEnumForBtCodec int codec) { AudioDeviceAttributes ada = null; if (device != AudioSystem.DEVICE_NONE) { ada = new AudioDeviceAttributes(device, address); final int res = AudioSystem.setDeviceConnectionState(ada, AudioSystem.DEVICE_STATE_UNAVAILABLE, AudioSystem.AUDIO_FORMAT_DEFAULT); codec); if (res != AudioSystem.AUDIO_STATUS_OK) { AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent( Loading @@ -2319,7 +2325,8 @@ public class AudioDeviceInventory { } @GuardedBy("mDevicesLock") private void makeLeAudioDeviceUnavailableLater(String address, int device, int delayMs) { private void makeLeAudioDeviceUnavailableLater( String address, int device, int codec, int delayMs) { // prevent any activity on the LEA output to avoid unwanted // reconnection of the sink. mDeviceBroker.setLeAudioSuspended( Loading @@ -2327,7 +2334,7 @@ public class AudioDeviceInventory { // the device will be made unavailable later, so consider it disconnected right away mConnectedDevices.remove(DeviceInfo.makeDeviceListKey(device, address)); // send the delayed message to make the device unavailable later mDeviceBroker.setLeAudioTimeout(address, device, delayMs); mDeviceBroker.setLeAudioTimeout(address, device, codec, delayMs); } @GuardedBy("mDevicesLock") Loading services/core/java/com/android/server/audio/BtHelper.java +62 −23 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHeadset; import android.bluetooth.BluetoothHearingAid; import android.bluetooth.BluetoothLeAudio; import android.bluetooth.BluetoothLeAudioCodecConfig; import android.bluetooth.BluetoothLeAudioCodecStatus; import android.bluetooth.BluetoothProfile; import android.content.Context; Loading Loading @@ -250,8 +251,10 @@ public class BtHelper { } } /*package*/ synchronized @AudioSystem.AudioFormatNativeEnumForBtCodec int getA2dpCodec( @NonNull BluetoothDevice device) { /*package*/ synchronized @AudioSystem.AudioFormatNativeEnumForBtCodec int getCodec( @NonNull BluetoothDevice device, @AudioService.BtProfile int profile) { switch (profile) { case BluetoothProfile.A2DP: { if (mA2dp == null) { return AudioSystem.AUDIO_FORMAT_DEFAULT; } Loading @@ -268,17 +271,53 @@ public class BtHelper { if (btCodecConfig == null) { return AudioSystem.AUDIO_FORMAT_DEFAULT; } return AudioSystem.bluetoothCodecToAudioFormat(btCodecConfig.getCodecType()); return AudioSystem.bluetoothA2dpCodecToAudioFormat(btCodecConfig.getCodecType()); } case BluetoothProfile.LE_AUDIO: { if (mLeAudio == null) { return AudioSystem.AUDIO_FORMAT_DEFAULT; } BluetoothLeAudioCodecStatus btLeCodecStatus = null; int groupId = mLeAudio.getGroupId(device); try { btLeCodecStatus = mLeAudio.getCodecStatus(groupId); } catch (Exception e) { Log.e(TAG, "Exception while getting status of " + device, e); } if (btLeCodecStatus == null) { return AudioSystem.AUDIO_FORMAT_DEFAULT; } BluetoothLeAudioCodecConfig btLeCodecConfig = btLeCodecStatus.getOutputCodecConfig(); if (btLeCodecConfig == null) { return AudioSystem.AUDIO_FORMAT_DEFAULT; } return AudioSystem.bluetoothLeCodecToAudioFormat(btLeCodecConfig.getCodecType()); } default: return AudioSystem.AUDIO_FORMAT_DEFAULT; } } /*package*/ synchronized @AudioSystem.AudioFormatNativeEnumForBtCodec int getA2dpCodecWithFallbackToSBC( @NonNull BluetoothDevice device, @NonNull String source) { @AudioSystem.AudioFormatNativeEnumForBtCodec int codec = getA2dpCodec(device); int getCodecWithFallback( @NonNull BluetoothDevice device, @AudioService.BtProfile int profile, boolean isLeOutput, @NonNull String source) { // For profiles other than A2DP and LE Audio output, the audio codec format must be // AUDIO_FORMAT_DEFAULT as native audio policy manager expects a specific audio format // only if audio HW module selection based on format is supported for the device type. if (!(profile == BluetoothProfile.A2DP || (profile == BluetoothProfile.LE_AUDIO && isLeOutput))) { return AudioSystem.AUDIO_FORMAT_DEFAULT; } @AudioSystem.AudioFormatNativeEnumForBtCodec int codec = getCodec(device, profile); if (codec == AudioSystem.AUDIO_FORMAT_DEFAULT) { AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent( "getA2dpCodec DEFAULT from " + source + " fallback to SBC")); return AudioSystem.AUDIO_FORMAT_SBC; "getCodec DEFAULT from " + source + " fallback to " + (profile == BluetoothProfile.A2DP ? "SBC" : "LC3"))); return profile == BluetoothProfile.A2DP ? AudioSystem.AUDIO_FORMAT_SBC : AudioSystem.AUDIO_FORMAT_LC3; } return codec; } Loading Loading
media/java/android/media/AudioSystem.java +22 −3 Original line number Diff line number Diff line Loading @@ -318,11 +318,12 @@ public class AudioSystem /** * @hide * Convert a Bluetooth codec to an audio format enum * Convert an A2DP Bluetooth codec to an audio format enum * @param btCodec the codec to convert. * @return the audio format, or {@link #AUDIO_FORMAT_DEFAULT} if unknown */ public static @AudioFormatNativeEnumForBtCodec int bluetoothCodecToAudioFormat(int btCodec) { public static @AudioFormatNativeEnumForBtCodec int bluetoothA2dpCodecToAudioFormat( int btCodec) { switch (btCodec) { case BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC: return AudioSystem.AUDIO_FORMAT_SBC; Loading @@ -339,7 +340,25 @@ public class AudioSystem case BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS: return AudioSystem.AUDIO_FORMAT_OPUS; default: Log.e(TAG, "Unknown BT codec 0x" + Integer.toHexString(btCodec) Log.e(TAG, "Unknown A2DP BT codec 0x" + Integer.toHexString(btCodec) + " for conversion to audio format"); // TODO returning DEFAULT is the current behavior, should this return INVALID? return AudioSystem.AUDIO_FORMAT_DEFAULT; } } /** * @hide * Convert a LE Audio Bluetooth codec to an audio format enum * @param btCodec the codec to convert. * @return the audio format, or {@link #AUDIO_FORMAT_DEFAULT} if unknown */ public static @AudioFormatNativeEnumForBtCodec int bluetoothLeCodecToAudioFormat(int btCodec) { switch (btCodec) { case BluetoothLeAudioCodecConfig.SOURCE_CODEC_TYPE_LC3: return AudioSystem.AUDIO_FORMAT_LC3; default: Log.e(TAG, "Unknown LE Audio BT codec 0x" + Integer.toHexString(btCodec) + " for conversion to audio format"); // TODO returning DEFAULT is the current behavior, should this return INVALID? return AudioSystem.AUDIO_FORMAT_DEFAULT; Loading
services/core/java/com/android/server/audio/AudioDeviceBroker.java +15 −12 Original line number Diff line number Diff line Loading @@ -1595,8 +1595,8 @@ public class AudioDeviceBroker { sendILMsg(MSG_IL_BTA2DP_TIMEOUT, SENDMSG_QUEUE, a2dpCodec, address, delayMs); } /*package*/ void setLeAudioTimeout(String address, int device, int delayMs) { sendILMsg(MSG_IL_BTLEAUDIO_TIMEOUT, SENDMSG_QUEUE, device, address, delayMs); /*package*/ void setLeAudioTimeout(String address, int device, int codec, int delayMs) { sendIILMsg(MSG_IIL_BTLEAUDIO_TIMEOUT, SENDMSG_QUEUE, device, codec, address, delayMs); } /*package*/ void setAvrcpAbsoluteVolumeSupported(boolean supported) { Loading Loading @@ -1794,8 +1794,9 @@ public class AudioDeviceBroker { return; } @AudioSystem.AudioFormatNativeEnumForBtCodec final int codec = mBtHelper.getA2dpCodecWithFallbackToSBC( btInfo.mDevice, "MSG_L_SET_BT_ACTIVE_DEVICE"); mBtHelper.getCodecWithFallback(btInfo.mDevice, btInfo.mProfile, btInfo.mIsLeOutput, "MSG_L_SET_BT_ACTIVE_DEVICE"); mDeviceInventory.onSetBtActiveDevice(btInfo, codec, (btInfo.mProfile != BluetoothProfile.LE_AUDIO || btInfo.mIsLeOutput) Loading @@ -1819,22 +1820,24 @@ public class AudioDeviceBroker { case MSG_IL_BTA2DP_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_IL_BTLEAUDIO_TIMEOUT: case MSG_IIL_BTLEAUDIO_TIMEOUT: // msg.obj == address of LE Audio device synchronized (mDeviceStateLock) { mDeviceInventory.onMakeLeAudioDeviceUnavailableNow( (String) msg.obj, msg.arg1); (String) msg.obj, msg.arg1, msg.arg2); } break; case MSG_L_BLUETOOTH_DEVICE_CONFIG_CHANGE: { final BtDeviceInfo btInfo = (BtDeviceInfo) msg.obj; synchronized (mDeviceStateLock) { @AudioSystem.AudioFormatNativeEnumForBtCodec final int codec = mBtHelper.getA2dpCodecWithFallbackToSBC( btInfo.mDevice, "MSG_L_BLUETOOTH_DEVICE_CONFIG_CHANGE"); mBtHelper.getCodecWithFallback(btInfo.mDevice, btInfo.mProfile, btInfo.mIsLeOutput, "MSG_L_BLUETOOTH_DEVICE_CONFIG_CHANGE"); mDeviceInventory.onBluetoothDeviceConfigChange( btInfo, codec, BtHelper.EVENT_DEVICE_CONFIG_CHANGE); } Loading Loading @@ -2084,7 +2087,7 @@ public class AudioDeviceBroker { private static final int MSG_IL_SAVE_NDEF_DEVICE_FOR_STRATEGY = 47; private static final int MSG_IL_SAVE_REMOVE_NDEF_DEVICE_FOR_STRATEGY = 48; private static final int MSG_IL_BTLEAUDIO_TIMEOUT = 49; private static final int MSG_IIL_BTLEAUDIO_TIMEOUT = 49; private static final int MSG_L_NOTIFY_PREFERRED_AUDIOPROFILE_APPLIED = 52; private static final int MSG_L_CHECK_COMMUNICATION_DEVICE_REMOVAL = 53; Loading @@ -2104,7 +2107,7 @@ public class AudioDeviceBroker { case MSG_L_SET_WIRED_DEVICE_CONNECTION_STATE: case MSG_L_SET_BT_ACTIVE_DEVICE: case MSG_IL_BTA2DP_TIMEOUT: case MSG_IL_BTLEAUDIO_TIMEOUT: case MSG_IIL_BTLEAUDIO_TIMEOUT: case MSG_L_BLUETOOTH_DEVICE_CONFIG_CHANGE: case MSG_TOGGLE_HDMI: case MSG_L_A2DP_DEVICE_CONNECTION_CHANGE_EXT: Loading Loading @@ -2196,7 +2199,7 @@ public class AudioDeviceBroker { case MSG_L_SET_BT_ACTIVE_DEVICE: case MSG_L_SET_WIRED_DEVICE_CONNECTION_STATE: case MSG_IL_BTA2DP_TIMEOUT: case MSG_IL_BTLEAUDIO_TIMEOUT: case MSG_IIL_BTLEAUDIO_TIMEOUT: case MSG_L_BLUETOOTH_DEVICE_CONFIG_CHANGE: if (sLastDeviceConnectMsgTime >= time) { // add a little delay to make sure messages are ordered as expected Loading
services/core/java/com/android/server/audio/AudioDeviceInventory.java +26 −19 Original line number Diff line number Diff line Loading @@ -689,9 +689,11 @@ public class AudioDeviceInventory { case BluetoothProfile.LE_AUDIO: case BluetoothProfile.LE_AUDIO_BROADCAST: if (switchToUnavailable) { makeLeAudioDeviceUnavailableNow(address, btInfo.mAudioSystemDevice); makeLeAudioDeviceUnavailableNow(address, btInfo.mAudioSystemDevice, di.mDeviceCodecFormat); } else if (switchToAvailable) { makeLeAudioDeviceAvailable(btInfo, streamType, "onSetBtActiveDevice"); makeLeAudioDeviceAvailable( btInfo, streamType, codec, "onSetBtActiveDevice"); } break; default: throw new IllegalArgumentException("Invalid profile " Loading Loading @@ -752,12 +754,13 @@ public class AudioDeviceInventory { if (event == BtHelper.EVENT_DEVICE_CONFIG_CHANGE) { boolean a2dpCodecChange = false; if (btInfo.mProfile == BluetoothProfile.A2DP) { boolean codecChange = false; if (btInfo.mProfile == BluetoothProfile.A2DP || btInfo.mProfile == BluetoothProfile.LE_AUDIO) { if (di.mDeviceCodecFormat != codec) { di.mDeviceCodecFormat = codec; mConnectedDevices.replace(key, di); a2dpCodecChange = true; codecChange = true; } final int res = mAudioSystem.handleDeviceConfigChange( btInfo.mAudioSystemDevice, address, BtHelper.getName(btDevice), codec); Loading @@ -782,7 +785,7 @@ public class AudioDeviceInventory { } } if (!a2dpCodecChange) { if (!codecChange) { updateBluetoothPreferredModes_l(btDevice /*connectedDevice*/); } } Loading @@ -796,9 +799,9 @@ public class AudioDeviceInventory { } } /*package*/ void onMakeLeAudioDeviceUnavailableNow(String address, int device) { /*package*/ void onMakeLeAudioDeviceUnavailableNow(String address, int device, int codec) { synchronized (mDevicesLock) { makeLeAudioDeviceUnavailableNow(address, device); makeLeAudioDeviceUnavailableNow(address, device, codec); } } Loading Loading @@ -1657,11 +1660,12 @@ public class AudioDeviceInventory { } synchronized (mDevicesLock) { final ArraySet<String> toRemove = new ArraySet<>(); final ArraySet<Pair<String, Integer>> toRemove = new ArraySet<>(); // Disconnect ALL DEVICE_OUT_BLE_HEADSET or DEVICE_OUT_BLE_BROADCAST devices mConnectedDevices.values().forEach(deviceInfo -> { if (deviceInfo.mDeviceType == device) { toRemove.add(deviceInfo.mDeviceAddress); toRemove.add( new Pair<>(deviceInfo.mDeviceAddress, deviceInfo.mDeviceCodecFormat)); } }); new MediaMetrics.Item(mMetricsId + "disconnectLeAudio") Loading @@ -1671,8 +1675,8 @@ public class AudioDeviceInventory { final int delay = checkSendBecomingNoisyIntentInt(device, AudioService.CONNECTION_STATE_DISCONNECTED, AudioSystem.DEVICE_NONE); toRemove.stream().forEach(deviceAddress -> makeLeAudioDeviceUnavailableLater(deviceAddress, device, delay) toRemove.stream().forEach(entry -> makeLeAudioDeviceUnavailableLater(entry.first, device, entry.second, delay) ); } } Loading Loading @@ -2216,7 +2220,8 @@ public class AudioDeviceInventory { @GuardedBy("mDevicesLock") private void makeLeAudioDeviceAvailable( AudioDeviceBroker.BtDeviceInfo btInfo, int streamType, String eventSource) { AudioDeviceBroker.BtDeviceInfo btInfo, int streamType, @AudioSystem.AudioFormatNativeEnumForBtCodec int codec, String eventSource) { final int volumeIndex = btInfo.mVolume == -1 ? -1 : btInfo.mVolume * 10; final int device = btInfo.mAudioSystemDevice; Loading Loading @@ -2250,7 +2255,7 @@ public class AudioDeviceInventory { AudioDeviceAttributes ada = new AudioDeviceAttributes(device, address, name); final int res = AudioSystem.setDeviceConnectionState(ada, AudioSystem.DEVICE_STATE_AVAILABLE, AudioSystem.AUDIO_FORMAT_DEFAULT); AudioSystem.DEVICE_STATE_AVAILABLE, codec); if (res != AudioSystem.AUDIO_STATUS_OK) { AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent( "APM failed to make available LE Audio device addr=" + address Loading @@ -2265,7 +2270,7 @@ public class AudioDeviceInventory { // Reset LEA suspend state each time a new sink is connected mDeviceBroker.clearLeAudioSuspended(true /* internalOnly */); mConnectedDevices.put(DeviceInfo.makeDeviceListKey(device, address), new DeviceInfo(device, name, address, AudioSystem.AUDIO_FORMAT_DEFAULT, new DeviceInfo(device, name, address, codec, peerAddress, groupId)); mDeviceBroker.postAccessoryPlugMediaUnmute(device); setCurrentAudioRouteNameIfPossible(name, /*fromA2dp=*/false); Loading @@ -2288,13 +2293,14 @@ public class AudioDeviceInventory { } @GuardedBy("mDevicesLock") private void makeLeAudioDeviceUnavailableNow(String address, int device) { private void makeLeAudioDeviceUnavailableNow(String address, int device, @AudioSystem.AudioFormatNativeEnumForBtCodec int codec) { AudioDeviceAttributes ada = null; if (device != AudioSystem.DEVICE_NONE) { ada = new AudioDeviceAttributes(device, address); final int res = AudioSystem.setDeviceConnectionState(ada, AudioSystem.DEVICE_STATE_UNAVAILABLE, AudioSystem.AUDIO_FORMAT_DEFAULT); codec); if (res != AudioSystem.AUDIO_STATUS_OK) { AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent( Loading @@ -2319,7 +2325,8 @@ public class AudioDeviceInventory { } @GuardedBy("mDevicesLock") private void makeLeAudioDeviceUnavailableLater(String address, int device, int delayMs) { private void makeLeAudioDeviceUnavailableLater( String address, int device, int codec, int delayMs) { // prevent any activity on the LEA output to avoid unwanted // reconnection of the sink. mDeviceBroker.setLeAudioSuspended( Loading @@ -2327,7 +2334,7 @@ public class AudioDeviceInventory { // the device will be made unavailable later, so consider it disconnected right away mConnectedDevices.remove(DeviceInfo.makeDeviceListKey(device, address)); // send the delayed message to make the device unavailable later mDeviceBroker.setLeAudioTimeout(address, device, delayMs); mDeviceBroker.setLeAudioTimeout(address, device, codec, delayMs); } @GuardedBy("mDevicesLock") Loading
services/core/java/com/android/server/audio/BtHelper.java +62 −23 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHeadset; import android.bluetooth.BluetoothHearingAid; import android.bluetooth.BluetoothLeAudio; import android.bluetooth.BluetoothLeAudioCodecConfig; import android.bluetooth.BluetoothLeAudioCodecStatus; import android.bluetooth.BluetoothProfile; import android.content.Context; Loading Loading @@ -250,8 +251,10 @@ public class BtHelper { } } /*package*/ synchronized @AudioSystem.AudioFormatNativeEnumForBtCodec int getA2dpCodec( @NonNull BluetoothDevice device) { /*package*/ synchronized @AudioSystem.AudioFormatNativeEnumForBtCodec int getCodec( @NonNull BluetoothDevice device, @AudioService.BtProfile int profile) { switch (profile) { case BluetoothProfile.A2DP: { if (mA2dp == null) { return AudioSystem.AUDIO_FORMAT_DEFAULT; } Loading @@ -268,17 +271,53 @@ public class BtHelper { if (btCodecConfig == null) { return AudioSystem.AUDIO_FORMAT_DEFAULT; } return AudioSystem.bluetoothCodecToAudioFormat(btCodecConfig.getCodecType()); return AudioSystem.bluetoothA2dpCodecToAudioFormat(btCodecConfig.getCodecType()); } case BluetoothProfile.LE_AUDIO: { if (mLeAudio == null) { return AudioSystem.AUDIO_FORMAT_DEFAULT; } BluetoothLeAudioCodecStatus btLeCodecStatus = null; int groupId = mLeAudio.getGroupId(device); try { btLeCodecStatus = mLeAudio.getCodecStatus(groupId); } catch (Exception e) { Log.e(TAG, "Exception while getting status of " + device, e); } if (btLeCodecStatus == null) { return AudioSystem.AUDIO_FORMAT_DEFAULT; } BluetoothLeAudioCodecConfig btLeCodecConfig = btLeCodecStatus.getOutputCodecConfig(); if (btLeCodecConfig == null) { return AudioSystem.AUDIO_FORMAT_DEFAULT; } return AudioSystem.bluetoothLeCodecToAudioFormat(btLeCodecConfig.getCodecType()); } default: return AudioSystem.AUDIO_FORMAT_DEFAULT; } } /*package*/ synchronized @AudioSystem.AudioFormatNativeEnumForBtCodec int getA2dpCodecWithFallbackToSBC( @NonNull BluetoothDevice device, @NonNull String source) { @AudioSystem.AudioFormatNativeEnumForBtCodec int codec = getA2dpCodec(device); int getCodecWithFallback( @NonNull BluetoothDevice device, @AudioService.BtProfile int profile, boolean isLeOutput, @NonNull String source) { // For profiles other than A2DP and LE Audio output, the audio codec format must be // AUDIO_FORMAT_DEFAULT as native audio policy manager expects a specific audio format // only if audio HW module selection based on format is supported for the device type. if (!(profile == BluetoothProfile.A2DP || (profile == BluetoothProfile.LE_AUDIO && isLeOutput))) { return AudioSystem.AUDIO_FORMAT_DEFAULT; } @AudioSystem.AudioFormatNativeEnumForBtCodec int codec = getCodec(device, profile); if (codec == AudioSystem.AUDIO_FORMAT_DEFAULT) { AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent( "getA2dpCodec DEFAULT from " + source + " fallback to SBC")); return AudioSystem.AUDIO_FORMAT_SBC; "getCodec DEFAULT from " + source + " fallback to " + (profile == BluetoothProfile.A2DP ? "SBC" : "LC3"))); return profile == BluetoothProfile.A2DP ? AudioSystem.AUDIO_FORMAT_SBC : AudioSystem.AUDIO_FORMAT_LC3; } return codec; } Loading