Merge "Enable HapticGenerator AIDL effect" into 24D1-dev
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index c48b2c3..8b03ccf 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -1356,7 +1356,7 @@
}
}
-status_t EffectModule::setVolume(uint32_t* left, uint32_t* right, bool controller) {
+status_t EffectModule::setVolume(uint32_t* left, uint32_t* right, bool controller, bool force) {
AutoLockReentrant _l(mutex(), mSetVolumeReentrantTid);
if (mStatus != NO_ERROR) {
return mStatus;
@@ -1364,7 +1364,7 @@
status_t status = NO_ERROR;
// Send volume indication if EFFECT_FLAG_VOLUME_IND is set and read back altered volume
// if controller flag is set (Note that controller == TRUE => EFFECT_FLAG_VOLUME_CTRL set)
- if (isProcessEnabled() &&
+ if ((isProcessEnabled() || force) &&
((mDescriptor.flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_CTRL ||
(mDescriptor.flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_IND ||
(mDescriptor.flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_MONITOR)) {
@@ -1375,6 +1375,14 @@
status_t EffectModule::setVolumeInternal(
uint32_t *left, uint32_t *right, bool controller) {
+ if (mVolume.has_value() && *left == mVolume.value()[0] && *right == mVolume.value()[1]) {
+ LOG_ALWAYS_FATAL_IF(
+ !mReturnedVolume.has_value(),
+ "The cached returned volume must not be null when the cached volume has value");
+ *left = mReturnedVolume.value()[0];
+ *right = mReturnedVolume.value()[1];
+ return NO_ERROR;
+ }
uint32_t volume[2] = {*left, *right};
uint32_t *pVolume = controller ? volume : nullptr;
uint32_t size = sizeof(volume);
@@ -1384,8 +1392,10 @@
&size,
pVolume);
if (controller && status == NO_ERROR && size == sizeof(volume)) {
+ mVolume = {*left, *right}; // Cache the value that has been set
*left = volume[0];
*right = volume[1];
+ mReturnedVolume = {*left, *right};
}
return status;
}
@@ -2327,10 +2337,11 @@
effect->setCallback(mEffectCallback);
effect_descriptor_t desc = effect->desc();
+ ssize_t idx_insert = 0;
if ((desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
// Auxiliary effects are inserted at the beginning of mEffects vector as
// they are processed first and accumulated in chain input buffer
- mEffects.insertAt(effect, 0);
+ mEffects.insertAt(effect, idx_insert);
// the input buffer for auxiliary effect contains mono samples in
// 32 bit format. This is to avoid saturation in AudoMixer
@@ -2350,7 +2361,7 @@
// by insert effects
effect->setOutBuffer(mInBuffer);
} else {
- ssize_t idx_insert = getInsertIndex_l(desc);
+ idx_insert = getInsertIndex_l(desc);
if (idx_insert < 0) {
return INVALID_OPERATION;
}
@@ -2399,6 +2410,18 @@
}
effect->configure_l();
+ if (effect->isVolumeControl()) {
+ const auto volumeControlIndex = findVolumeControl_l(0, mEffects.size());
+ if (!volumeControlIndex.has_value() || (ssize_t)volumeControlIndex.value() < idx_insert) {
+ // If this effect will be the new volume control effect when it is enabled, force
+ // initializing the volume as 0 for volume control effect for safer ramping. The actual
+ // volume will be set from setVolume_l.
+ uint32_t left = 0;
+ uint32_t right = 0;
+ effect->setVolume(&left, &right, true /*controller*/, true /*force*/);
+ }
+ }
+
return NO_ERROR;
}
@@ -2606,22 +2629,18 @@
}
return volumeControlIndex.has_value();
}
+ mVolumeControlEffect = volumeControlEffect;
- if (volumeControlEffect != cachedVolumeControlEffect) {
- // The volume control effect is a new one. Set the old one as full volume. Set the new onw
- // as zero for safe ramping.
- if (cachedVolumeControlEffect != nullptr) {
+ for (int i = 0; i < ctrlIdx; ++i) {
+ // For all volume control effects before the effect that controls volume, set the volume
+ // to maximum to avoid double attenuation.
+ if (mEffects[i]->isVolumeControl()) {
uint32_t leftMax = 1 << 24;
uint32_t rightMax = 1 << 24;
- cachedVolumeControlEffect->setVolume(&leftMax, &rightMax, true /*controller*/);
+ mEffects[i]->setVolume(&leftMax, &rightMax, true /*controller*/, true /*force*/);
}
- if (volumeControlEffect != nullptr) {
- uint32_t leftZero = 0;
- uint32_t rightZero = 0;
- volumeControlEffect->setVolume(&leftZero, &rightZero, true /*controller*/);
- }
- mVolumeControlEffect = volumeControlEffect;
}
+
mLeftVolume = newLeft;
mRightVolume = newRight;
diff --git a/services/audioflinger/Effects.h b/services/audioflinger/Effects.h
index 505f3b3..d374b2c 100644
--- a/services/audioflinger/Effects.h
+++ b/services/audioflinger/Effects.h
@@ -25,6 +25,8 @@
#include <private/media/AudioEffectShared.h>
#include <map> // avoid transitive dependency
+#include <optional>
+#include <vector>
namespace android {
@@ -215,7 +217,7 @@
}
status_t setDevices(const AudioDeviceTypeAddrVector& devices) final EXCLUDES_EffectBase_Mutex;
status_t setInputDevice(const AudioDeviceTypeAddr& device) final EXCLUDES_EffectBase_Mutex;
- status_t setVolume(uint32_t *left, uint32_t *right, bool controller) final;
+ status_t setVolume(uint32_t *left, uint32_t *right, bool controller, bool force) final;
status_t setMode(audio_mode_t mode) final EXCLUDES_EffectBase_Mutex;
status_t setAudioSource(audio_source_t source) final EXCLUDES_EffectBase_Mutex;
status_t start_l() final REQUIRES(audio_utils::EffectChain_Mutex) EXCLUDES_EffectBase_Mutex;
@@ -304,6 +306,12 @@
static constexpr pid_t INVALID_PID = (pid_t)-1;
// this tid is allowed to call setVolume() without acquiring the mutex.
pid_t mSetVolumeReentrantTid = INVALID_PID;
+
+ // Cache the volume that has been set successfully.
+ std::optional<std::vector<uint32_t>> mVolume;
+ // Cache the volume that returned from the effect when setting volume successfully. The value
+ // here is used to indicate the volume to apply before this effect.
+ std::optional<std::vector<uint32_t>> mReturnedVolume;
};
// The EffectHandle class implements the IEffect interface. It provides resources
diff --git a/services/audioflinger/IAfEffect.h b/services/audioflinger/IAfEffect.h
index 0c8e9e3..d5adeb4 100644
--- a/services/audioflinger/IAfEffect.h
+++ b/services/audioflinger/IAfEffect.h
@@ -163,7 +163,8 @@
virtual int16_t *inBuffer() const = 0;
virtual status_t setDevices(const AudioDeviceTypeAddrVector &devices) = 0;
virtual status_t setInputDevice(const AudioDeviceTypeAddr &device) = 0;
- virtual status_t setVolume(uint32_t *left, uint32_t *right, bool controller) = 0;
+ virtual status_t setVolume(uint32_t *left, uint32_t *right, bool controller,
+ bool force = false) = 0;
virtual status_t setOffloaded_l(bool offloaded, audio_io_handle_t io) = 0;
virtual bool isOffloaded_l() const = 0;