Use vibrator information to initialize HapticGenerator.
Use vibrator's resonant frequency and Q factor to initialize
HapticGenerator when they are available. Otherwise, use default value.
Bug: 182612056
Test: atest HapticGeneratorTest, manual
Change-Id: Ib861e7fbb0ede3a33c0a93fbca8d80c022461d9a
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 7a89805..7cdac30 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -278,6 +278,21 @@
return NO_ERROR;
}
+status_t AudioFlinger::setVibratorInfos(
+ const std::vector<media::AudioVibratorInfo>& vibratorInfos) {
+ Mutex::Autolock _l(mLock);
+ mAudioVibratorInfos = vibratorInfos;
+ return NO_ERROR;
+}
+
+// getDefaultVibratorInfo_l must be called with AudioFlinger lock held.
+const media::AudioVibratorInfo* AudioFlinger::getDefaultVibratorInfo_l() {
+ if (mAudioVibratorInfos.empty()) {
+ return nullptr;
+ }
+ return &mAudioVibratorInfos.front();
+}
+
AudioFlinger::~AudioFlinger()
{
while (!mRecordThreads.isEmpty()) {
@@ -4122,7 +4137,8 @@
case TransactionCode::SET_MIC_MUTE:
case TransactionCode::SET_LOW_RAM_DEVICE:
case TransactionCode::SYSTEM_READY:
- case TransactionCode::SET_AUDIO_HAL_PIDS: {
+ case TransactionCode::SET_AUDIO_HAL_PIDS:
+ case TransactionCode::SET_VIBRATOR_INFOS: {
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 1cfdffc..a980752 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -267,6 +267,8 @@
virtual status_t setAudioHalPids(const std::vector<pid_t>& pids);
+ virtual status_t setVibratorInfos(const std::vector<media::AudioVibratorInfo>& vibratorInfos);
+
status_t onPreTransact(TransactionCode code, const Parcel& data, uint32_t flags) override;
// end of IAudioFlinger interface
@@ -296,6 +298,8 @@
void updateDownStreamPatches_l(const struct audio_patch *patch,
const std::set<audio_io_handle_t> streams);
+ const media::AudioVibratorInfo* getDefaultVibratorInfo_l();
+
private:
// FIXME The 400 is temporarily too high until a leak of writers in media.log is fixed.
static const size_t kLogMemorySize = 400 * 1024;
@@ -971,6 +975,8 @@
SimpleLog mAppSetParameterLog;
SimpleLog mSystemSetParameterLog;
+ std::vector<media::AudioVibratorInfo> mAudioVibratorInfos;
+
static inline constexpr const char *mMetricsId = AMEDIAMETRICS_KEY_AUDIO_FLINGER;
};
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index 031e0cf..d75b13b 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -1585,6 +1585,34 @@
return status;
}
+status_t AudioFlinger::EffectModule::setVibratorInfo(const media::AudioVibratorInfo* vibratorInfo)
+{
+ if (mStatus != NO_ERROR) {
+ return mStatus;
+ }
+ if (!isHapticGenerator()) {
+ ALOGW("Should not set vibrator info for effects that are not HapticGenerator");
+ return INVALID_OPERATION;
+ }
+
+ std::vector<uint8_t> request(
+ sizeof(effect_param_t) + sizeof(int32_t) + 2 * sizeof(float));
+ effect_param_t *param = (effect_param_t*) request.data();
+ param->psize = sizeof(int32_t);
+ param->vsize = 2 * sizeof(float);
+ *(int32_t*)param->data = HG_PARAM_VIBRATOR_INFO;
+ float* vibratorInfoPtr = reinterpret_cast<float*>(param->data + sizeof(int32_t));
+ vibratorInfoPtr[0] = vibratorInfo->resonantFrequency;
+ vibratorInfoPtr[1] = vibratorInfo->qFactor;
+ std::vector<uint8_t> response;
+ status_t status = command(EFFECT_CMD_SET_PARAM, request, sizeof(int32_t), &response);
+ if (status == NO_ERROR) {
+ LOG_ALWAYS_FATAL_IF(response.size() != sizeof(status_t));
+ status = *reinterpret_cast<const status_t*>(response.data());
+ }
+ return status;
+}
+
static std::string dumpInOutBuffer(bool isInput, const sp<EffectBufferHalInterface> &buffer) {
std::stringstream ss;
diff --git a/services/audioflinger/Effects.h b/services/audioflinger/Effects.h
index 8e82d53..9da95bc 100644
--- a/services/audioflinger/Effects.h
+++ b/services/audioflinger/Effects.h
@@ -258,6 +258,7 @@
bool isHapticGenerator() const;
status_t setHapticIntensity(int id, int intensity);
+ status_t setVibratorInfo(const media::AudioVibratorInfo* vibratorInfo);
void dump(int fd, const Vector<String16>& args);
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 7f91a54..f1bcfcd 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -1439,6 +1439,16 @@
effect->setMode(mAudioFlinger->getMode());
effect->setAudioSource(mAudioSource);
}
+ if (effect->isHapticGenerator()) {
+ // TODO(b/184194057): Use the vibrator information from the vibrator that will be used
+ // for the HapticGenerator.
+ const media::AudioVibratorInfo* defaultVibratorInfo =
+ mAudioFlinger->getDefaultVibratorInfo_l();
+ if (defaultVibratorInfo != nullptr) {
+ // Only set the vibrator info when it is a valid one.
+ effect->setVibratorInfo(defaultVibratorInfo);
+ }
+ }
// create effect handle and connect it to effect module
handle = new EffectHandle(effect, client, effectClient, priority);
lStatus = handle->initCheck();