Integrate the new frequency profile APIs with the vibrator HAL.

Bug: 347034419
Flag: android.os.vibrator.normalized_pwle_effects
Test: libvibratorservice_test
Change-Id: I59b280e4b22863daa62d5e32c6b1c566845fc786
diff --git a/services/vibratorservice/VibratorHalWrapper.cpp b/services/vibratorservice/VibratorHalWrapper.cpp
index 4ac1618..b06ee3b 100644
--- a/services/vibratorservice/VibratorHalWrapper.cpp
+++ b/services/vibratorservice/VibratorHalWrapper.cpp
@@ -107,6 +107,10 @@
         mInfoCache.mMaxEnvelopeEffectControlPointDuration =
                 getMaxEnvelopeEffectControlPointDurationInternal();
     }
+    if (mInfoCache.mFrequencyToOutputAccelerationMap.isFailed()) {
+        mInfoCache.mFrequencyToOutputAccelerationMap =
+                getFrequencyToOutputAccelerationMapInternal();
+    }
     return mInfoCache.get();
 }
 
@@ -239,6 +243,13 @@
     return HalResult<milliseconds>::unsupported();
 }
 
+HalResult<std::vector<PwleV2OutputMapEntry>>
+HalWrapper::getFrequencyToOutputAccelerationMapInternal() {
+    ALOGV("Skipped getFrequencyToOutputAccelerationMapInternal because it's not "
+          "available in Vibrator HAL");
+    return HalResult<std::vector<PwleV2OutputMapEntry>>::unsupported();
+}
+
 // -------------------------------------------------------------------------------------------------
 
 HalResult<void> AidlHalWrapper::ping() {
@@ -487,6 +498,15 @@
     return HalResultFactory::fromStatus<milliseconds>(std::move(status), milliseconds(durationMs));
 }
 
+HalResult<std::vector<PwleV2OutputMapEntry>>
+AidlHalWrapper::getFrequencyToOutputAccelerationMapInternal() {
+    std::vector<PwleV2OutputMapEntry> frequencyToOutputAccelerationMap;
+    auto status =
+            getHal()->getPwleV2FrequencyToOutputAccelerationMap(&frequencyToOutputAccelerationMap);
+    return HalResultFactory::fromStatus<
+            std::vector<PwleV2OutputMapEntry>>(std::move(status), frequencyToOutputAccelerationMap);
+}
+
 std::shared_ptr<Aidl::IVibrator> AidlHalWrapper::getHal() {
     std::lock_guard<std::mutex> lock(mHandleMutex);
     return mHandle;
diff --git a/services/vibratorservice/include/vibratorservice/VibratorHalWrapper.h b/services/vibratorservice/include/vibratorservice/VibratorHalWrapper.h
index 4938b15..b2bfffc 100644
--- a/services/vibratorservice/include/vibratorservice/VibratorHalWrapper.h
+++ b/services/vibratorservice/include/vibratorservice/VibratorHalWrapper.h
@@ -243,6 +243,7 @@
     using EffectStrength = aidl::android::hardware::vibrator::EffectStrength;
     using CompositePrimitive = aidl::android::hardware::vibrator::CompositePrimitive;
     using Braking = aidl::android::hardware::vibrator::Braking;
+    using PwleV2OutputMapEntry = aidl::android::hardware::vibrator::PwleV2OutputMapEntry;
 
     const HalResult<Capabilities> capabilities;
     const HalResult<std::vector<Effect>> supportedEffects;
@@ -261,6 +262,7 @@
     const HalResult<int32_t> maxEnvelopeEffectSize;
     const HalResult<std::chrono::milliseconds> minEnvelopeEffectControlPointDuration;
     const HalResult<std::chrono::milliseconds> maxEnvelopeEffectControlPointDuration;
+    const HalResult<std::vector<PwleV2OutputMapEntry>> frequencyToOutputAccelerationMap;
 
     void logFailures() const {
         logFailure<Capabilities>(capabilities, "getCapabilities");
@@ -284,6 +286,8 @@
                                               "getMinEnvelopeEffectControlPointDuration");
         logFailure<std::chrono::milliseconds>(maxEnvelopeEffectControlPointDuration,
                                               "getMaxEnvelopeEffectControlPointDuration");
+        logFailure<std::vector<PwleV2OutputMapEntry>>(frequencyToOutputAccelerationMap,
+                                                      "getfrequencyToOutputAccelerationMap");
     }
 
     bool shouldRetry() const {
@@ -296,7 +300,8 @@
                 qFactor.shouldRetry() || maxAmplitudes.shouldRetry() ||
                 maxEnvelopeEffectSize.shouldRetry() ||
                 minEnvelopeEffectControlPointDuration.shouldRetry() ||
-                maxEnvelopeEffectControlPointDuration.shouldRetry();
+                maxEnvelopeEffectControlPointDuration.shouldRetry() ||
+                frequencyToOutputAccelerationMap.shouldRetry();
     }
 
 private:
@@ -327,7 +332,8 @@
                 mMaxAmplitudes,
                 mMaxEnvelopeEffectSize,
                 mMinEnvelopeEffectControlPointDuration,
-                mMaxEnvelopeEffectControlPointDuration};
+                mMaxEnvelopeEffectControlPointDuration,
+                mFrequencyToOutputAccelerationMap};
     }
 
 private:
@@ -359,6 +365,8 @@
             HalResult<std::chrono::milliseconds>::transactionFailed(MSG);
     HalResult<std::chrono::milliseconds> mMaxEnvelopeEffectControlPointDuration =
             HalResult<std::chrono::milliseconds>::transactionFailed(MSG);
+    HalResult<std::vector<Info::PwleV2OutputMapEntry>> mFrequencyToOutputAccelerationMap =
+            HalResult<std::vector<Info::PwleV2OutputMapEntry>>::transactionFailed(MSG);
 
     friend class HalWrapper;
 };
@@ -442,6 +450,8 @@
     virtual HalResult<int32_t> getMaxEnvelopeEffectSizeInternal();
     virtual HalResult<std::chrono::milliseconds> getMinEnvelopeEffectControlPointDurationInternal();
     virtual HalResult<std::chrono::milliseconds> getMaxEnvelopeEffectControlPointDurationInternal();
+    virtual HalResult<std::vector<PwleV2OutputMapEntry>>
+    getFrequencyToOutputAccelerationMapInternal();
 
 private:
     std::mutex mInfoMutex;
@@ -518,12 +528,12 @@
     HalResult<float> getQFactorInternal() override final;
     HalResult<std::vector<float>> getMaxAmplitudesInternal() override final;
     HalResult<int32_t> getMaxEnvelopeEffectSizeInternal() override final;
-
     HalResult<std::chrono::milliseconds> getMinEnvelopeEffectControlPointDurationInternal()
             override final;
-
     HalResult<std::chrono::milliseconds> getMaxEnvelopeEffectControlPointDurationInternal()
             override final;
+    HalResult<std::vector<PwleV2OutputMapEntry>> getFrequencyToOutputAccelerationMapInternal()
+            override final;
 
 private:
     const reconnect_fn mReconnectFn;
diff --git a/services/vibratorservice/test/VibratorHalWrapperAidlTest.cpp b/services/vibratorservice/test/VibratorHalWrapperAidlTest.cpp
index 17f384d..d42aa56 100644
--- a/services/vibratorservice/test/VibratorHalWrapperAidlTest.cpp
+++ b/services/vibratorservice/test/VibratorHalWrapperAidlTest.cpp
@@ -39,6 +39,7 @@
 using aidl::android::hardware::vibrator::IVibrator;
 using aidl::android::hardware::vibrator::IVibratorCallback;
 using aidl::android::hardware::vibrator::PrimitivePwle;
+using aidl::android::hardware::vibrator::PwleV2OutputMapEntry;
 using aidl::android::hardware::vibrator::PwleV2Primitive;
 using aidl::android::hardware::vibrator::VendorEffect;
 using aidl::android::os::PersistableBundle;
@@ -242,6 +243,11 @@
     std::vector<CompositePrimitive> supportedPrimitives = {CompositePrimitive::CLICK};
     std::vector<Braking> supportedBraking = {Braking::CLAB};
     std::vector<float> amplitudes = {0.f, 1.f, 0.f};
+    std::vector<PwleV2OutputMapEntry>
+            frequencyToOutputAccelerationMap{PwleV2OutputMapEntry(/*frequency=*/30.0f,
+                                                                  /*maxOutputAcceleration=*/0.2),
+                                             PwleV2OutputMapEntry(/*frequency=*/60.0f,
+                                                                  /*maxOutputAcceleration=*/0.8)};
 
     std::vector<std::chrono::milliseconds> primitiveDurations;
     constexpr auto primitiveRange = ndk::enum_range<CompositePrimitive>();
@@ -323,6 +329,11 @@
             .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_SECURITY)))
             .WillOnce(DoAll(SetArgPointee<0>(PWLE_V2_MIN_REQUIRED_PRIMITIVE_MAX_DURATION_MS),
                             Return(ndk::ScopedAStatus::ok())));
+    EXPECT_CALL(*mMockHal.get(), getPwleV2FrequencyToOutputAccelerationMap(_))
+            .Times(Exactly(2))
+            .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_SECURITY)))
+            .WillOnce(DoAll(SetArgPointee<0>(frequencyToOutputAccelerationMap),
+                            Return(ndk::ScopedAStatus::ok())));
 
     vibrator::Info failed = mWrapper->getInfo();
     ASSERT_TRUE(failed.capabilities.isFailed());
@@ -342,6 +353,7 @@
     ASSERT_TRUE(failed.maxEnvelopeEffectSize.isFailed());
     ASSERT_TRUE(failed.minEnvelopeEffectControlPointDuration.isFailed());
     ASSERT_TRUE(failed.maxEnvelopeEffectControlPointDuration.isFailed());
+    ASSERT_TRUE(failed.frequencyToOutputAccelerationMap.isFailed());
 
     vibrator::Info successful = mWrapper->getInfo();
     ASSERT_EQ(vibrator::Capabilities::ON_CALLBACK, successful.capabilities.value());
@@ -364,6 +376,8 @@
               successful.minEnvelopeEffectControlPointDuration.value());
     ASSERT_EQ(std::chrono::milliseconds(PWLE_V2_MIN_REQUIRED_PRIMITIVE_MAX_DURATION_MS),
               successful.maxEnvelopeEffectControlPointDuration.value());
+    ASSERT_EQ(frequencyToOutputAccelerationMap,
+              successful.frequencyToOutputAccelerationMap.value());
 }
 
 TEST_F(VibratorHalWrapperAidlTest, TestGetInfoCachesResult) {
@@ -377,6 +391,11 @@
     constexpr int32_t PWLE_V2_MAX_ALLOWED_PRIMITIVE_MIN_DURATION_MS = 20;
     constexpr int32_t PWLE_V2_MIN_REQUIRED_PRIMITIVE_MAX_DURATION_MS = 1000;
     std::vector<Effect> supportedEffects = {Effect::CLICK, Effect::TICK};
+    std::vector<PwleV2OutputMapEntry>
+            frequencyToOutputAccelerationMap{PwleV2OutputMapEntry(/*frequency=*/30.0f,
+                                                                  /*maxOutputAcceleration=*/0.2),
+                                             PwleV2OutputMapEntry(/*frequency=*/60.0f,
+                                                                  /*maxOutputAcceleration=*/0.8)};
 
     EXPECT_CALL(*mMockHal.get(), getCapabilities(_))
             .Times(Exactly(1))
@@ -432,6 +451,10 @@
             .Times(Exactly(1))
             .WillOnce(DoAll(SetArgPointee<0>(PWLE_V2_MIN_REQUIRED_PRIMITIVE_MAX_DURATION_MS),
                             Return(ndk::ScopedAStatus::ok())));
+    EXPECT_CALL(*mMockHal.get(), getPwleV2FrequencyToOutputAccelerationMap(_))
+            .Times(Exactly(1))
+            .WillOnce(DoAll(SetArgPointee<0>(frequencyToOutputAccelerationMap),
+                            Return(ndk::ScopedAStatus::ok())));
 
     std::vector<std::thread> threads;
     for (int i = 0; i < 10; i++) {
@@ -460,6 +483,7 @@
               info.minEnvelopeEffectControlPointDuration.value());
     ASSERT_EQ(std::chrono::milliseconds(PWLE_V2_MIN_REQUIRED_PRIMITIVE_MAX_DURATION_MS),
               info.maxEnvelopeEffectControlPointDuration.value());
+    ASSERT_EQ(frequencyToOutputAccelerationMap, info.frequencyToOutputAccelerationMap.value());
 }
 
 TEST_F(VibratorHalWrapperAidlTest, TestPerformEffectWithCallbackSupport) {
diff --git a/services/vibratorservice/test/VibratorHalWrapperHidlV1_0Test.cpp b/services/vibratorservice/test/VibratorHalWrapperHidlV1_0Test.cpp
index a09ddec..d6dab8d 100644
--- a/services/vibratorservice/test/VibratorHalWrapperHidlV1_0Test.cpp
+++ b/services/vibratorservice/test/VibratorHalWrapperHidlV1_0Test.cpp
@@ -223,6 +223,7 @@
     ASSERT_TRUE(info.maxEnvelopeEffectSize.isUnsupported());
     ASSERT_TRUE(info.minEnvelopeEffectControlPointDuration.isUnsupported());
     ASSERT_TRUE(info.maxEnvelopeEffectControlPointDuration.isUnsupported());
+    ASSERT_TRUE(info.frequencyToOutputAccelerationMap.isUnsupported());
 }
 
 TEST_F(VibratorHalWrapperHidlV1_0Test, TestGetInfoWithoutAmplitudeControl) {
@@ -259,6 +260,7 @@
     ASSERT_TRUE(info.maxEnvelopeEffectSize.isUnsupported());
     ASSERT_TRUE(info.minEnvelopeEffectControlPointDuration.isUnsupported());
     ASSERT_TRUE(info.maxEnvelopeEffectControlPointDuration.isUnsupported());
+    ASSERT_TRUE(info.frequencyToOutputAccelerationMap.isUnsupported());
 }
 
 TEST_F(VibratorHalWrapperHidlV1_0Test, TestPerformEffect) {