audio flinger: Bluetooth latency mode control
Add APIs to discover support and control the use
of latency mode control over Bluetooth link.
Bug: 257922898
Test: make
Change-Id: I8d23a40f21465d566f0adc553cfc77e64571395e
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index c683531..5faa8f3 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -2459,6 +2459,23 @@
return af->getSupportedLatencyModes(output, modes);
}
+status_t AudioSystem::setBluetoothLatencyModesEnabled(bool enabled) {
+ const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ if (af == nullptr) {
+ return PERMISSION_DENIED;
+ }
+ return af->setBluetoothLatencyModesEnabled(enabled);
+}
+
+status_t AudioSystem::supportsBluetoothLatencyModes(
+ bool *support) {
+ const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ if (af == nullptr) {
+ return PERMISSION_DENIED;
+ }
+ return af->supportsBluetoothLatencyModes(support);
+}
+
class CaptureStateListenerImpl : public media::BnCaptureStateListener,
public IBinder::DeathRecipient {
public:
diff --git a/media/libaudioclient/IAudioFlinger.cpp b/media/libaudioclient/IAudioFlinger.cpp
index 81abfc2..ba3e703 100644
--- a/media/libaudioclient/IAudioFlinger.cpp
+++ b/media/libaudioclient/IAudioFlinger.cpp
@@ -846,6 +846,21 @@
return NO_ERROR;
}
+status_t AudioFlingerClientAdapter::setBluetoothLatencyModesEnabled(bool enabled) {
+ return statusTFromBinderStatus(mDelegate->setBluetoothLatencyModesEnabled(enabled));
+}
+
+status_t AudioFlingerClientAdapter::supportsBluetoothLatencyModes(bool* support) {
+ if (support == nullptr) {
+ return BAD_VALUE;
+ }
+
+ RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
+ mDelegate->supportsBluetoothLatencyModes(support)));
+
+ return NO_ERROR;
+}
+
status_t AudioFlingerClientAdapter::getSoundDoseInterface(
const sp<media::ISoundDoseCallback> &callback,
sp<media::ISoundDose>* soundDose) {
@@ -1374,6 +1389,14 @@
return Status::ok();
}
+Status AudioFlingerServerAdapter::setBluetoothLatencyModesEnabled(bool enabled) {
+ return Status::fromStatusT(mDelegate->setBluetoothLatencyModesEnabled(enabled));
+}
+
+Status AudioFlingerServerAdapter::supportsBluetoothLatencyModes(bool *support) {
+ return Status::fromStatusT(mDelegate->supportsBluetoothLatencyModes(support));
+}
+
Status AudioFlingerServerAdapter::getSoundDoseInterface(
const sp<media::ISoundDoseCallback>& callback,
sp<media::ISoundDose>* soundDose)
diff --git a/media/libaudioclient/aidl/android/media/IAudioFlingerService.aidl b/media/libaudioclient/aidl/android/media/IAudioFlingerService.aidl
index b94af6e..6497447 100644
--- a/media/libaudioclient/aidl/android/media/IAudioFlingerService.aidl
+++ b/media/libaudioclient/aidl/android/media/IAudioFlingerService.aidl
@@ -247,6 +247,21 @@
LatencyMode[] getSupportedLatencyModes(int output);
/**
+ * Requests if the implementation supports controlling the latency modes
+ * over the Bleutooth A2DP or LE Audio links. If it does,
+ * setRequestedLatencyMode() and getSupportedLatencyModes() APIs can also be used
+ * for streams routed to Bluetooth and not just for the spatializer output.
+ */
+ boolean supportsBluetoothLatencyModes();
+
+ /**
+ * Enables or disables the variable Bluetooth latency control mechanism in the
+ * audio framework and the audio HAL. This does not apply to the latency mode control
+ * on the spatializer output with is a built-in feature.
+ */
+ void setBluetoothLatencyModesEnabled(boolean enabled);
+
+ /**
* Registers the sound dose callback and returns the interface for executing
* sound dose methods on the audio server.
*/
diff --git a/media/libaudioclient/include/media/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h
index e04b82e..e2806c7 100644
--- a/media/libaudioclient/include/media/AudioSystem.h
+++ b/media/libaudioclient/include/media/AudioSystem.h
@@ -629,6 +629,10 @@
static status_t getSupportedLatencyModes(audio_io_handle_t output,
std::vector<audio_latency_mode_t>* modes);
+ static status_t setBluetoothLatencyModesEnabled(bool enabled);
+
+ static status_t supportsBluetoothLatencyModes(bool *support);
+
static status_t getSupportedMixerAttributes(audio_port_handle_t portId,
std::vector<audio_mixer_attributes_t> *mixerAttrs);
static status_t setPreferredMixerAttributes(const audio_attributes_t *attr,
diff --git a/media/libaudioclient/include/media/IAudioFlinger.h b/media/libaudioclient/include/media/IAudioFlinger.h
index 05630bb..57dd2c1 100644
--- a/media/libaudioclient/include/media/IAudioFlinger.h
+++ b/media/libaudioclient/include/media/IAudioFlinger.h
@@ -374,6 +374,10 @@
sp<media::ISoundDose>* soundDose) = 0;
virtual status_t invalidateTracks(const std::vector<audio_port_handle_t>& portIds) = 0;
+
+ virtual status_t setBluetoothLatencyModesEnabled(bool enabled) = 0;
+
+ virtual status_t supportsBluetoothLatencyModes(bool* support) = 0;
};
/**
@@ -479,6 +483,8 @@
audio_latency_mode_t mode) override;
status_t getSupportedLatencyModes(
audio_io_handle_t output, std::vector<audio_latency_mode_t>* modes) override;
+ status_t setBluetoothLatencyModesEnabled(bool enabled) override;
+ status_t supportsBluetoothLatencyModes(bool* support) override;
status_t getSoundDoseInterface(const sp<media::ISoundDoseCallback>& callback,
sp<media::ISoundDose>* soundDose) override;
status_t invalidateTracks(const std::vector<audio_port_handle_t>& portIds) override;
@@ -572,6 +578,10 @@
SET_DEVICE_CONNECTED_STATE = media::BnAudioFlingerService::TRANSACTION_setDeviceConnectedState,
SET_REQUESTED_LATENCY_MODE = media::BnAudioFlingerService::TRANSACTION_setRequestedLatencyMode,
GET_SUPPORTED_LATENCY_MODES = media::BnAudioFlingerService::TRANSACTION_getSupportedLatencyModes,
+ SET_BLUETOOTH_LATENCY_MODES_ENABLED =
+ media::BnAudioFlingerService::TRANSACTION_setBluetoothLatencyModesEnabled,
+ SUPPORTS_BLUETOOTH_LATENCY_MODES =
+ media::BnAudioFlingerService::TRANSACTION_supportsBluetoothLatencyModes,
GET_SOUND_DOSE_INTERFACE = media::BnAudioFlingerService::TRANSACTION_getSoundDoseInterface,
INVALIDATE_TRACKS = media::BnAudioFlingerService::TRANSACTION_invalidateTracks,
};
@@ -697,6 +707,8 @@
Status setRequestedLatencyMode(int output, media::LatencyMode mode) override;
Status getSupportedLatencyModes(int output,
std::vector<media::LatencyMode>* _aidl_return) override;
+ Status setBluetoothLatencyModesEnabled(bool enabled) override;
+ Status supportsBluetoothLatencyModes(bool* support) override;
Status getSoundDoseInterface(const sp<media::ISoundDoseCallback>& callback,
sp<media::ISoundDose>* _aidl_return) override;
Status invalidateTracks(const std::vector<int32_t>& portIds) override;
diff --git a/media/libaudiohal/impl/DeviceHalHidl.h b/media/libaudiohal/impl/DeviceHalHidl.h
index f6519b6..727e92f 100644
--- a/media/libaudiohal/impl/DeviceHalHidl.h
+++ b/media/libaudiohal/impl/DeviceHalHidl.h
@@ -132,6 +132,11 @@
return INVALID_OPERATION;
}
+ int32_t supportsBluetoothLatencyModes(bool* supports __unused) override {
+ // TODO: Implement the HAL query when moving to AIDL HAL.
+ return INVALID_OPERATION;
+ }
+
status_t setConnectedState(const struct audio_port_v7 *port, bool connected) override;
error::Result<audio_hw_sync_t> getHwAvSync() override;
diff --git a/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h b/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
index d27ad4c..6379521 100644
--- a/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
+++ b/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
@@ -128,6 +128,7 @@
std::vector<media::audio::common::AudioMMapPolicyInfo> *policyInfos) = 0;
virtual int32_t getAAudioMixerBurstCount() = 0;
virtual int32_t getAAudioHardwareBurstMinUsec() = 0;
+ virtual int32_t supportsBluetoothLatencyModes(bool* supports) = 0;
// Update the connection status of an external device.
virtual status_t setConnectedState(const struct audio_port_v7 *port, bool connected) = 0;
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index d03bacb..33ccf32 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -231,6 +231,8 @@
BINDER_METHOD_ENTRY(setDeviceConnectedState) \
BINDER_METHOD_ENTRY(setRequestedLatencyMode) \
BINDER_METHOD_ENTRY(getSupportedLatencyModes) \
+BINDER_METHOD_ENTRY(setBluetoothLatencyModesEnabled) \
+BINDER_METHOD_ENTRY(supportsBluetoothLatencyModes) \
BINDER_METHOD_ENTRY(getSoundDoseInterface) \
// singleton for Binder Method Statistics for IAudioFlinger
@@ -327,7 +329,8 @@
mPatchCommandThread(sp<PatchCommandThread>::make()),
mDeviceEffectManager(sp<DeviceEffectManager>::make(*this)),
mMelReporter(sp<MelReporter>::make(*this)),
- mSystemReady(false)
+ mSystemReady(false),
+ mBluetoothLatencyModesEnabled(true)
{
// Move the audio session unique ID generator start base as time passes to limit risk of
// generating the same ID again after an audioserver restart.
@@ -1666,6 +1669,36 @@
return thread->getSupportedLatencyModes(modes);
}
+status_t AudioFlinger::setBluetoothLatencyModesEnabled(bool enabled) {
+ Mutex::Autolock _l(mLock);
+ status_t status = INVALID_OPERATION;
+ for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
+ // Success if at least one PlaybackThread supports Bluetooth latency modes
+ if (mPlaybackThreads.valueAt(i)->setBluetoothLatencyModesEnabled(enabled) == NO_ERROR) {
+ status = NO_ERROR;
+ }
+ }
+ if (status == NO_ERROR) {
+ mBluetoothLatencyModesEnabled.store(enabled);
+ }
+ return status;
+}
+
+status_t AudioFlinger::supportsBluetoothLatencyModes(bool* support) {
+ if (support == nullptr) {
+ return BAD_VALUE;
+ }
+ Mutex::Autolock _l(mLock);
+ *support = false;
+ for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
+ if (mAudioHwDevs.valueAt(i)->supportsBluetoothLatencyModes()) {
+ *support = true;
+ break;
+ }
+ }
+ return NO_ERROR;
+}
+
status_t AudioFlinger::getSoundDoseInterface(const sp<media::ISoundDoseCallback>& callback,
sp<media::ISoundDose>* soundDose) {
if (soundDose == nullptr) {
@@ -2579,6 +2612,13 @@
flags = static_cast<AudioHwDevice::Flags>(flags | AudioHwDevice::AHWD_IS_INSERT);
}
+
+ if (bool supports = false;
+ dev->supportsBluetoothLatencyModes(&supports) == NO_ERROR && supports) {
+ flags = static_cast<AudioHwDevice::Flags>(flags |
+ AudioHwDevice::AHWD_SUPPORTS_BT_LATENCY_MODES);
+ }
+
audio_module_handle_t handle = (audio_module_handle_t) nextUniqueId(AUDIO_UNIQUE_ID_USE_MODULE);
AudioHwDevice *audioDevice = new AudioHwDevice(handle, name, dev, flags);
if (strcmp(name, AUDIO_HARDWARE_MODULE_ID_PRIMARY) == 0) {
@@ -2952,6 +2992,7 @@
if (thread->isMsdDevice()) {
thread->setDownStreamPatch(&patch);
}
+ thread->setBluetoothLatencyModesEnabled(mBluetoothLatencyModesEnabled.load());
return thread;
}
}
@@ -4655,7 +4696,9 @@
case TransactionCode::SYSTEM_READY:
case TransactionCode::SET_AUDIO_HAL_PIDS:
case TransactionCode::SET_VIBRATOR_INFOS:
- case TransactionCode::UPDATE_SECONDARY_OUTPUTS: {
+ case TransactionCode::UPDATE_SECONDARY_OUTPUTS:
+ case TransactionCode::SET_BLUETOOTH_LATENCY_MODES_ENABLED:
+ case TransactionCode::SUPPORTS_BLUETOOTH_LATENCY_MODES: {
if (!isServiceUid(IPCThreadState::self()->getCallingUid())) {
ALOGW("%s: transaction %d received from PID %d unauthorized UID %d",
__func__, code, IPCThreadState::self()->getCallingPid(),
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 7daa4c4..16ad964 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -305,6 +305,10 @@
virtual status_t getSupportedLatencyModes(audio_io_handle_t output,
std::vector<audio_latency_mode_t>* modes);
+ virtual status_t setBluetoothLatencyModesEnabled(bool enabled);
+
+ virtual status_t supportsBluetoothLatencyModes(bool* support);
+
virtual status_t getSoundDoseInterface(const sp<media::ISoundDoseCallback>& callback,
sp<media::ISoundDose>* soundDose);
@@ -1053,6 +1057,9 @@
/** Interface for interacting with the AudioService. */
mediautils::atomic_sp<IAudioManager> mAudioManager;
+
+ // Bluetooth Variable latency control logic is enabled or disabled
+ std::atomic_bool mBluetoothLatencyModesEnabled;
};
#undef INCLUDING_FROM_AUDIOFLINGER_H
diff --git a/services/audioflinger/AudioHwDevice.h b/services/audioflinger/AudioHwDevice.h
index 8c5d239..0e840a6 100644
--- a/services/audioflinger/AudioHwDevice.h
+++ b/services/audioflinger/AudioHwDevice.h
@@ -40,6 +40,8 @@
// Means that this isn't a terminal module, and software patches
// are used to transport audio data further.
AHWD_IS_INSERT = 0x4,
+ // This Module supports BT Latency mode control
+ AHWD_SUPPORTS_BT_LATENCY_MODES = 0x8,
};
AudioHwDevice(audio_module_handle_t handle,
@@ -64,6 +66,10 @@
return (0 != (mFlags & AHWD_IS_INSERT));
}
+ bool supportsBluetoothLatencyModes() const {
+ return (0 != (mFlags & AHWD_SUPPORTS_BT_LATENCY_MODES));
+ }
+
audio_module_handle_t handle() const { return mHandle; }
const char *moduleName() const { return mModuleName; }
sp<DeviceHalInterface> hwDevice() const { return mHwDevice; }
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 0dd915a..e6d38cc 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -2089,7 +2089,8 @@
mHwSupportsPause(false), mHwPaused(false), mFlushPending(false),
mLeftVolFloat(-1.0), mRightVolFloat(-1.0),
mDownStreamPatch{},
- mIsTimestampAdvancing(kMinimumTimeBetweenTimestampChecksNs)
+ mIsTimestampAdvancing(kMinimumTimeBetweenTimestampChecksNs),
+ mBluetoothLatencyModesEnabled(true)
{
snprintf(mThreadName, kThreadNameLength, "AudioOut_%X", id);
mNBLogWriter = audioFlinger->newWriter_l(kLogSize, mThreadName);
@@ -7601,6 +7602,15 @@
return NO_ERROR;
}
+status_t AudioFlinger::PlaybackThread::setBluetoothLatencyModesEnabled(bool enabled) {
+ if (mOutput == nullptr || mOutput->audioHwDev == nullptr
+ || !mOutput->audioHwDev->supportsBluetoothLatencyModes()) {
+ return INVALID_OPERATION;
+ }
+ mBluetoothLatencyModesEnabled.store(enabled);
+ return NO_ERROR;
+}
+
void AudioFlinger::SpatializerThread::checkOutputStageEffects()
{
bool hasVirtualizer = false;
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 01ea5d9..247c609 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -1102,6 +1102,8 @@
return INVALID_OPERATION;
}
+ virtual status_t setBluetoothLatencyModesEnabled(bool enabled);
+
void startMelComputation(const sp<audio_utils::MelProcessor>& processor);
void stopMelComputation();
@@ -1460,6 +1462,9 @@
virtual void flushHw_l() {
mIsTimestampAdvancing.clear();
}
+
+ // Bluetooth Variable latency control logic is enabled or disabled for this thread
+ std::atomic_bool mBluetoothLatencyModesEnabled;
};
class MixerThread : public PlaybackThread {