Implement PWLE support

Implement support to new API method composePwle and related frequency
control getters.

Bug: 167947076
Test: libvibratorservice_test
Change-Id: I6f47ea771a19b1ae46370c5d82671f6420e39f8b
diff --git a/services/vibratorservice/VibratorHalWrapper.cpp b/services/vibratorservice/VibratorHalWrapper.cpp
index 3ebf9b6..1010aa5 100644
--- a/services/vibratorservice/VibratorHalWrapper.cpp
+++ b/services/vibratorservice/VibratorHalWrapper.cpp
@@ -26,10 +26,12 @@
 #include <vibratorservice/VibratorCallbackScheduler.h>
 #include <vibratorservice/VibratorHalWrapper.h>
 
+using android::hardware::vibrator::Braking;
 using android::hardware::vibrator::CompositeEffect;
 using android::hardware::vibrator::CompositePrimitive;
 using android::hardware::vibrator::Effect;
 using android::hardware::vibrator::EffectStrength;
+using android::hardware::vibrator::PrimitivePwle;
 
 using std::chrono::milliseconds;
 
@@ -46,20 +48,6 @@
 // -------------------------------------------------------------------------------------------------
 
 template <class T>
-HalResult<T> loadCached(const std::function<HalResult<T>()>& loadFn, std::optional<T>& cache) {
-    if (cache.has_value()) {
-        // Return copy of cached value.
-        return HalResult<T>::ok(*cache);
-    }
-    HalResult<T> ret = loadFn();
-    if (ret.isOk()) {
-        // Cache copy of returned value.
-        cache.emplace(ret.value());
-    }
-    return ret;
-}
-
-template <class T>
 bool isStaticCastValid(Effect effect) {
     T castEffect = static_cast<T>(effect);
     auto iter = hardware::hidl_enum_range<T>();
@@ -141,15 +129,39 @@
     if (mInfoCache.mSupportedEffects.isFailed()) {
         mInfoCache.mSupportedEffects = getSupportedEffectsInternal();
     }
+    if (mInfoCache.mSupportedBraking.isFailed()) {
+        mInfoCache.mSupportedBraking = getSupportedBrakingInternal();
+    }
+    if (mInfoCache.mMinFrequency.isFailed()) {
+        mInfoCache.mMinFrequency = getMinFrequencyInternal();
+    }
     if (mInfoCache.mResonantFrequency.isFailed()) {
         mInfoCache.mResonantFrequency = getResonantFrequencyInternal();
     }
+    if (mInfoCache.mFrequencyResolution.isFailed()) {
+        mInfoCache.mFrequencyResolution = getFrequencyResolutionInternal();
+    }
     if (mInfoCache.mQFactor.isFailed()) {
         mInfoCache.mQFactor = getQFactorInternal();
     }
+    if (mInfoCache.mMaxAmplitudes.isFailed()) {
+        mInfoCache.mMaxAmplitudes = getMaxAmplitudesInternal();
+    }
     return mInfoCache.get();
 }
 
+HalResult<milliseconds> HalWrapper::performComposedEffect(const std::vector<CompositeEffect>&,
+                                                          const std::function<void()>&) {
+    ALOGV("Skipped performComposedEffect because it's not available in Vibrator HAL");
+    return HalResult<milliseconds>::unsupported();
+}
+
+HalResult<void> HalWrapper::performPwleEffect(const std::vector<PrimitivePwle>&,
+                                              const std::function<void()>&) {
+    ALOGV("Skipped performPwleEffect because it's not available in Vibrator HAL");
+    return HalResult<void>::unsupported();
+}
+
 HalResult<Capabilities> HalWrapper::getCapabilities() {
     std::lock_guard<std::mutex> lock(mInfoMutex);
     if (mInfoCache.mCapabilities.isFailed()) {
@@ -178,6 +190,11 @@
     return HalResult<std::vector<Effect>>::unsupported();
 }
 
+HalResult<std::vector<Braking>> HalWrapper::getSupportedBrakingInternal() {
+    ALOGV("Skipped getSupportedBraking because it's not available in Vibrator HAL");
+    return HalResult<std::vector<Braking>>::unsupported();
+}
+
 HalResult<std::vector<CompositePrimitive>> HalWrapper::getSupportedPrimitivesInternal() {
     ALOGV("Skipped getSupportedPrimitives because it's not available in Vibrator HAL");
     return HalResult<std::vector<CompositePrimitive>>::unsupported();
@@ -189,16 +206,31 @@
     return HalResult<std::vector<milliseconds>>::unsupported();
 }
 
+HalResult<float> HalWrapper::getMinFrequencyInternal() {
+    ALOGV("Skipped getMinFrequency because it's not available in Vibrator HAL");
+    return HalResult<float>::unsupported();
+}
+
 HalResult<float> HalWrapper::getResonantFrequencyInternal() {
     ALOGV("Skipped getResonantFrequency because it's not available in Vibrator HAL");
     return HalResult<float>::unsupported();
 }
 
+HalResult<float> HalWrapper::getFrequencyResolutionInternal() {
+    ALOGV("Skipped getFrequencyResolution because it's not available in Vibrator HAL");
+    return HalResult<float>::unsupported();
+}
+
 HalResult<float> HalWrapper::getQFactorInternal() {
     ALOGV("Skipped getQFactor because it's not available in Vibrator HAL");
     return HalResult<float>::unsupported();
 }
 
+HalResult<std::vector<float>> HalWrapper::getMaxAmplitudesInternal() {
+    ALOGV("Skipped getMaxAmplitudes because it's not available in Vibrator HAL");
+    return HalResult<std::vector<float>>::unsupported();
+}
+
 // -------------------------------------------------------------------------------------------------
 
 HalResult<void> AidlHalWrapper::ping() {
@@ -272,14 +304,14 @@
 }
 
 HalResult<milliseconds> AidlHalWrapper::performComposedEffect(
-        const std::vector<CompositeEffect>& primitiveEffects,
+        const std::vector<CompositeEffect>& primitives,
         const std::function<void()>& completionCallback) {
     // This method should always support callbacks, so no need to double check.
     auto cb = new HalCallbackWrapper(completionCallback);
 
     auto durations = getPrimitiveDurations().valueOr({});
     milliseconds duration(0);
-    for (const auto& effect : primitiveEffects) {
+    for (const auto& effect : primitives) {
         auto primitiveIdx = static_cast<size_t>(effect.primitive);
         if (primitiveIdx < durations.size()) {
             duration += durations[primitiveIdx];
@@ -290,7 +322,14 @@
         duration += milliseconds(effect.delayMs);
     }
 
-    return HalResult<milliseconds>::fromStatus(getHal()->compose(primitiveEffects, cb), duration);
+    return HalResult<milliseconds>::fromStatus(getHal()->compose(primitives, cb), duration);
+}
+
+HalResult<void> AidlHalWrapper::performPwleEffect(const std::vector<PrimitivePwle>& primitives,
+                                                  const std::function<void()>& completionCallback) {
+    // This method should always support callbacks, so no need to double check.
+    auto cb = new HalCallbackWrapper(completionCallback);
+    return HalResult<void>::fromStatus(getHal()->composePwle(primitives, cb));
 }
 
 HalResult<Capabilities> AidlHalWrapper::getCapabilitiesInternal() {
@@ -305,6 +344,12 @@
     return HalResult<std::vector<Effect>>::fromStatus(result, supportedEffects);
 }
 
+HalResult<std::vector<Braking>> AidlHalWrapper::getSupportedBrakingInternal() {
+    std::vector<Braking> supportedBraking;
+    auto result = getHal()->getSupportedBraking(&supportedBraking);
+    return HalResult<std::vector<Braking>>::fromStatus(result, supportedBraking);
+}
+
 HalResult<std::vector<CompositePrimitive>> AidlHalWrapper::getSupportedPrimitivesInternal() {
     std::vector<CompositePrimitive> supportedPrimitives;
     auto result = getHal()->getSupportedPrimitives(&supportedPrimitives);
@@ -335,18 +380,36 @@
     return HalResult<std::vector<milliseconds>>::ok(durations);
 }
 
+HalResult<float> AidlHalWrapper::getMinFrequencyInternal() {
+    float minFrequency = 0;
+    auto result = getHal()->getFrequencyMinimum(&minFrequency);
+    return HalResult<float>::fromStatus(result, minFrequency);
+}
+
 HalResult<float> AidlHalWrapper::getResonantFrequencyInternal() {
     float f0 = 0;
     auto result = getHal()->getResonantFrequency(&f0);
     return HalResult<float>::fromStatus(result, f0);
 }
 
+HalResult<float> AidlHalWrapper::getFrequencyResolutionInternal() {
+    float frequencyResolution = 0;
+    auto result = getHal()->getFrequencyResolution(&frequencyResolution);
+    return HalResult<float>::fromStatus(result, frequencyResolution);
+}
+
 HalResult<float> AidlHalWrapper::getQFactorInternal() {
     float qFactor = 0;
     auto result = getHal()->getQFactor(&qFactor);
     return HalResult<float>::fromStatus(result, qFactor);
 }
 
+HalResult<std::vector<float>> AidlHalWrapper::getMaxAmplitudesInternal() {
+    std::vector<float> amplitudes;
+    auto result = getHal()->getBandwidthAmplitudeMap(&amplitudes);
+    return HalResult<std::vector<float>>::fromStatus(result, amplitudes);
+}
+
 sp<Aidl::IVibrator> AidlHalWrapper::getHal() {
     std::lock_guard<std::mutex> lock(mHandleMutex);
     return mHandle;
@@ -412,13 +475,6 @@
 }
 
 template <typename I>
-HalResult<std::chrono::milliseconds> HidlHalWrapper<I>::performComposedEffect(
-        const std::vector<CompositeEffect>&, const std::function<void()>&) {
-    ALOGV("Skipped composed effect because Vibrator HAL AIDL is not available");
-    return HalResult<std::chrono::milliseconds>::unsupported();
-}
-
-template <typename I>
 HalResult<Capabilities> HidlHalWrapper<I>::getCapabilitiesInternal() {
     hardware::Return<bool> result = getHal()->supportsAmplitudeControl();
     Capabilities capabilities =