Loading android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp +17 −1 Original line number Diff line number Diff line Loading @@ -72,6 +72,7 @@ static jmethodID method_aclStateChangeCallback; static jmethodID method_discoveryStateChangeCallback; static jmethodID method_linkQualityReportCallback; static jmethodID method_switchBufferSizeCallback; static jmethodID method_switchCodecCallback; static jmethodID method_setWakeAlarm; static jmethodID method_acquireWakeLock; static jmethodID method_releaseWakeLock; Loading Loading @@ -611,6 +612,17 @@ static void switch_buffer_size_callback(bool is_low_latency_buffer_size) { (jboolean)is_low_latency_buffer_size); } static void switch_codec_callback(bool is_low_latency_buffer_size) { CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; ALOGV("%s: SwitchCodecCallback: %s", __func__, is_low_latency_buffer_size ? "true" : "false"); sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_switchCodecCallback, (jboolean)is_low_latency_buffer_size); } static void callback_thread_event(bt_cb_thread_evt event) { if (event == ASSOCIATE_JVM) { JavaVMAttachArgs args; Loading Loading @@ -688,7 +700,8 @@ static bt_callbacks_t sBluetoothCallbacks = {sizeof(sBluetoothCallbacks), energy_info_recv_callback, link_quality_report_callback, generate_local_oob_data_callback, switch_buffer_size_callback}; switch_buffer_size_callback, switch_codec_callback}; // The callback to call when the wake alarm fires. static alarm_cb sAlarmCallback; Loading Loading @@ -910,6 +923,9 @@ static void classInitNative(JNIEnv* env, jclass clazz) { method_switchBufferSizeCallback = env->GetMethodID(jniCallbackClass, "switchBufferSizeCallback", "(Z)V"); method_switchCodecCallback = env->GetMethodID(jniCallbackClass, "switchCodecCallback", "(Z)V"); method_setWakeAlarm = env->GetMethodID(clazz, "setWakeAlarm", "(JZ)Z"); method_acquireWakeLock = env->GetMethodID(clazz, "acquireWakeLock", "(Ljava/lang/String;)Z"); Loading android/app/src/com/android/bluetooth/btservice/AdapterService.java +46 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,8 @@ import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothAdapter.ActiveDeviceProfile; import android.bluetooth.BluetoothAdapter.ActiveDeviceUse; import android.bluetooth.BluetoothClass; import android.bluetooth.BluetoothCodecConfig; import android.bluetooth.BluetoothCodecStatus; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothProtoEnums; Loading Loading @@ -851,6 +853,50 @@ public class AdapterService extends Service { sendBroadcast(switchBufferSizeIntent); } void switchCodecCallback(boolean isLowLatencyBufferSize) { List<BluetoothDevice> activeDevices = getActiveDevices(BluetoothProfile.A2DP); if (activeDevices.size() != 1) { errorLog( "Cannot switch buffer size. The number of A2DP active devices is " + activeDevices.size()); } BluetoothCodecConfig codecConfig = null; BluetoothCodecStatus currentCodecStatus = mA2dpService.getCodecStatus(activeDevices.get(0)); int currentCodec = currentCodecStatus.getCodecConfig().getCodecType(); if (isLowLatencyBufferSize) { if (currentCodec == BluetoothCodecConfig.SOURCE_CODEC_TYPE_LC3) { Log.w(TAG, "Current codec is already LC3. No need to change it."); return; } codecConfig = new BluetoothCodecConfig( BluetoothCodecConfig.SOURCE_CODEC_TYPE_LC3, BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST, BluetoothCodecConfig.SAMPLE_RATE_48000, BluetoothCodecConfig.BITS_PER_SAMPLE_16, BluetoothCodecConfig.CHANNEL_MODE_STEREO, 0, 0x1 << 2, 0, 0); } else { if (currentCodec != BluetoothCodecConfig.SOURCE_CODEC_TYPE_LC3) { Log.w(TAG, "Current codec is not LC3. No need to change it."); return; } List<BluetoothCodecConfig> selectableCodecs = currentCodecStatus.getCodecsSelectableCapabilities(); for (BluetoothCodecConfig config : selectableCodecs) { // Find a non LC3 codec if (config.getCodecType() != BluetoothCodecConfig.SOURCE_CODEC_TYPE_LC3) { codecConfig = config; break; } } if (codecConfig == null) { Log.e(TAG, "Cannot find a non LC3 codec compatible with the remote device"); return; } } mA2dpService.setCodecConfigPreference(activeDevices.get(0), codecConfig); } /** * Enable/disable BluetoothInCallService * Loading android/app/src/com/android/bluetooth/btservice/JniCallbacks.java +4 −0 Original line number Diff line number Diff line Loading @@ -110,4 +110,8 @@ final class JniCallbacks { mAdapterService.switchBufferSizeCallback(is_low_latency_buffer_size); } void switchCodecCallback(boolean is_low_latency_buffer_size) { mAdapterService.switchCodecCallback(is_low_latency_buffer_size); } } system/audio_hal_interface/aidl/bluetooth_audio_port_impl.cc +2 −1 Original line number Diff line number Diff line Loading @@ -32,9 +32,10 @@ BluetoothAudioPortImpl::BluetoothAudioPortImpl( BluetoothAudioPortImpl::~BluetoothAudioPortImpl() {} ndk::ScopedAStatus BluetoothAudioPortImpl::startStream() { ndk::ScopedAStatus BluetoothAudioPortImpl::startStream(bool is_low_latency) { StopWatchLegacy stop_watch(__func__); BluetoothAudioCtrlAck ack = transport_instance_->StartRequest(); invoke_switch_codec_cb(is_low_latency); if (ack != BluetoothAudioCtrlAck::PENDING) { auto aidl_retval = provider_->streamStarted(BluetoothAudioCtrlAckToHalStatus(ack)); Loading system/audio_hal_interface/aidl/bluetooth_audio_port_impl.h +4 −1 Original line number Diff line number Diff line Loading @@ -37,7 +37,7 @@ class BluetoothAudioPortImpl : public BnBluetoothAudioPort { IBluetoothTransportInstance* transport_instance, const std::shared_ptr<IBluetoothAudioProvider>& provider); ndk::ScopedAStatus startStream() override; ndk::ScopedAStatus startStream(bool is_low_latency) override; ndk::ScopedAStatus suspendStream() override; Loading @@ -60,6 +60,9 @@ class BluetoothAudioPortImpl : public BnBluetoothAudioPort { IBluetoothTransportInstance* transport_instance_; const std::shared_ptr<IBluetoothAudioProvider> provider_; PresentationPosition::TimeSpec timespec_convert_to_hal(const timespec& ts); private: ndk::ScopedAStatus switchCodec(bool isLowLatency); }; } // namespace aidl Loading Loading
android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp +17 −1 Original line number Diff line number Diff line Loading @@ -72,6 +72,7 @@ static jmethodID method_aclStateChangeCallback; static jmethodID method_discoveryStateChangeCallback; static jmethodID method_linkQualityReportCallback; static jmethodID method_switchBufferSizeCallback; static jmethodID method_switchCodecCallback; static jmethodID method_setWakeAlarm; static jmethodID method_acquireWakeLock; static jmethodID method_releaseWakeLock; Loading Loading @@ -611,6 +612,17 @@ static void switch_buffer_size_callback(bool is_low_latency_buffer_size) { (jboolean)is_low_latency_buffer_size); } static void switch_codec_callback(bool is_low_latency_buffer_size) { CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid()) return; ALOGV("%s: SwitchCodecCallback: %s", __func__, is_low_latency_buffer_size ? "true" : "false"); sCallbackEnv->CallVoidMethod(sJniCallbacksObj, method_switchCodecCallback, (jboolean)is_low_latency_buffer_size); } static void callback_thread_event(bt_cb_thread_evt event) { if (event == ASSOCIATE_JVM) { JavaVMAttachArgs args; Loading Loading @@ -688,7 +700,8 @@ static bt_callbacks_t sBluetoothCallbacks = {sizeof(sBluetoothCallbacks), energy_info_recv_callback, link_quality_report_callback, generate_local_oob_data_callback, switch_buffer_size_callback}; switch_buffer_size_callback, switch_codec_callback}; // The callback to call when the wake alarm fires. static alarm_cb sAlarmCallback; Loading Loading @@ -910,6 +923,9 @@ static void classInitNative(JNIEnv* env, jclass clazz) { method_switchBufferSizeCallback = env->GetMethodID(jniCallbackClass, "switchBufferSizeCallback", "(Z)V"); method_switchCodecCallback = env->GetMethodID(jniCallbackClass, "switchCodecCallback", "(Z)V"); method_setWakeAlarm = env->GetMethodID(clazz, "setWakeAlarm", "(JZ)Z"); method_acquireWakeLock = env->GetMethodID(clazz, "acquireWakeLock", "(Ljava/lang/String;)Z"); Loading
android/app/src/com/android/bluetooth/btservice/AdapterService.java +46 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,8 @@ import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothAdapter.ActiveDeviceProfile; import android.bluetooth.BluetoothAdapter.ActiveDeviceUse; import android.bluetooth.BluetoothClass; import android.bluetooth.BluetoothCodecConfig; import android.bluetooth.BluetoothCodecStatus; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothProtoEnums; Loading Loading @@ -851,6 +853,50 @@ public class AdapterService extends Service { sendBroadcast(switchBufferSizeIntent); } void switchCodecCallback(boolean isLowLatencyBufferSize) { List<BluetoothDevice> activeDevices = getActiveDevices(BluetoothProfile.A2DP); if (activeDevices.size() != 1) { errorLog( "Cannot switch buffer size. The number of A2DP active devices is " + activeDevices.size()); } BluetoothCodecConfig codecConfig = null; BluetoothCodecStatus currentCodecStatus = mA2dpService.getCodecStatus(activeDevices.get(0)); int currentCodec = currentCodecStatus.getCodecConfig().getCodecType(); if (isLowLatencyBufferSize) { if (currentCodec == BluetoothCodecConfig.SOURCE_CODEC_TYPE_LC3) { Log.w(TAG, "Current codec is already LC3. No need to change it."); return; } codecConfig = new BluetoothCodecConfig( BluetoothCodecConfig.SOURCE_CODEC_TYPE_LC3, BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST, BluetoothCodecConfig.SAMPLE_RATE_48000, BluetoothCodecConfig.BITS_PER_SAMPLE_16, BluetoothCodecConfig.CHANNEL_MODE_STEREO, 0, 0x1 << 2, 0, 0); } else { if (currentCodec != BluetoothCodecConfig.SOURCE_CODEC_TYPE_LC3) { Log.w(TAG, "Current codec is not LC3. No need to change it."); return; } List<BluetoothCodecConfig> selectableCodecs = currentCodecStatus.getCodecsSelectableCapabilities(); for (BluetoothCodecConfig config : selectableCodecs) { // Find a non LC3 codec if (config.getCodecType() != BluetoothCodecConfig.SOURCE_CODEC_TYPE_LC3) { codecConfig = config; break; } } if (codecConfig == null) { Log.e(TAG, "Cannot find a non LC3 codec compatible with the remote device"); return; } } mA2dpService.setCodecConfigPreference(activeDevices.get(0), codecConfig); } /** * Enable/disable BluetoothInCallService * Loading
android/app/src/com/android/bluetooth/btservice/JniCallbacks.java +4 −0 Original line number Diff line number Diff line Loading @@ -110,4 +110,8 @@ final class JniCallbacks { mAdapterService.switchBufferSizeCallback(is_low_latency_buffer_size); } void switchCodecCallback(boolean is_low_latency_buffer_size) { mAdapterService.switchCodecCallback(is_low_latency_buffer_size); } }
system/audio_hal_interface/aidl/bluetooth_audio_port_impl.cc +2 −1 Original line number Diff line number Diff line Loading @@ -32,9 +32,10 @@ BluetoothAudioPortImpl::BluetoothAudioPortImpl( BluetoothAudioPortImpl::~BluetoothAudioPortImpl() {} ndk::ScopedAStatus BluetoothAudioPortImpl::startStream() { ndk::ScopedAStatus BluetoothAudioPortImpl::startStream(bool is_low_latency) { StopWatchLegacy stop_watch(__func__); BluetoothAudioCtrlAck ack = transport_instance_->StartRequest(); invoke_switch_codec_cb(is_low_latency); if (ack != BluetoothAudioCtrlAck::PENDING) { auto aidl_retval = provider_->streamStarted(BluetoothAudioCtrlAckToHalStatus(ack)); Loading
system/audio_hal_interface/aidl/bluetooth_audio_port_impl.h +4 −1 Original line number Diff line number Diff line Loading @@ -37,7 +37,7 @@ class BluetoothAudioPortImpl : public BnBluetoothAudioPort { IBluetoothTransportInstance* transport_instance, const std::shared_ptr<IBluetoothAudioProvider>& provider); ndk::ScopedAStatus startStream() override; ndk::ScopedAStatus startStream(bool is_low_latency) override; ndk::ScopedAStatus suspendStream() override; Loading @@ -60,6 +60,9 @@ class BluetoothAudioPortImpl : public BnBluetoothAudioPort { IBluetoothTransportInstance* transport_instance_; const std::shared_ptr<IBluetoothAudioProvider> provider_; PresentationPosition::TimeSpec timespec_convert_to_hal(const timespec& ts); private: ndk::ScopedAStatus switchCodec(bool isLowLatency); }; } // namespace aidl Loading