1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #pragma once 17 18 #include <aidl/android/hardware/vibrator/BnVibrator.h> 19 #include <android-base/unique_fd.h> 20 #include <linux/input.h> 21 #include <tinyalsa/asoundlib.h> 22 23 #include <array> 24 #include <fstream> 25 #include <future> 26 #include <ctime> 27 #include <chrono> 28 29 namespace aidl { 30 namespace android { 31 namespace hardware { 32 namespace vibrator { 33 34 class Vibrator : public BnVibrator { 35 public: 36 // APIs for interfacing with the kernel driver. 37 class HwApi { 38 public: 39 virtual ~HwApi() = default; 40 // Stores the LRA resonant frequency to be used for PWLE playback 41 // and click compensation. 42 virtual bool setF0(std::string value) = 0; 43 // Stores the frequency offset for long vibrations. 44 virtual bool setF0Offset(uint32_t value) = 0; 45 // Stores the LRA series resistance to be used for click 46 // compensation. 47 virtual bool setRedc(std::string value) = 0; 48 // Stores the LRA Q factor to be used for Q-dependent waveform 49 // selection. 50 virtual bool setQ(std::string value) = 0; 51 // Reports the number of effect waveforms loaded in firmware. 52 virtual bool getEffectCount(uint32_t *value) = 0; 53 // Blocks until timeout or vibrator reaches desired state 54 // (2 = ASP enabled, 1 = haptic enabled, 0 = disabled). 55 virtual bool pollVibeState(uint32_t value, int32_t timeoutMs = -1) = 0; 56 // Reports whether getOwtFreeSpace() is supported. 57 virtual bool hasOwtFreeSpace() = 0; 58 // Reports the available OWT bytes. 59 virtual bool getOwtFreeSpace(uint32_t *value) = 0; 60 // Enables/Disables F0 compensation enable status 61 virtual bool setF0CompEnable(bool value) = 0; 62 // Enables/Disables Redc compensation enable status 63 virtual bool setRedcCompEnable(bool value) = 0; 64 // Stores the minumun delay time between playback and stop effects. 65 virtual bool setMinOnOffInterval(uint32_t value) = 0; 66 // Gets the scaling factor for contextual haptic events. 67 virtual uint32_t getContextScale() = 0; 68 // Gets the enable status for contextual haptic events. 69 virtual bool getContextEnable() = 0; 70 // Gets the settling time for contextual haptic events. 71 // This will allow the device to stay face up for the duration given, 72 // even if InMotion events were detected. 73 virtual uint32_t getContextSettlingTime() = 0; 74 // Gets the cooldown time for contextual haptic events. 75 // This is used to avoid changing the scale of close playback events. 76 virtual uint32_t getContextCooldownTime() = 0; 77 // Checks the enable status for contextual haptics fade feature. When enabled 78 // this feature will cause the scaling factor to fade back up to max over 79 // the setting time set, instead of instantaneously changing it back to max. 80 virtual bool getContextFadeEnable() = 0; 81 // Indicates the number of 0.125-dB steps of attenuation to apply to 82 // waveforms triggered in response to vibration calls from the 83 // Android vibrator HAL. 84 virtual bool setFFGain(int fd, uint16_t value) = 0; 85 // Create/modify custom effects for all physical waveforms. 86 virtual bool setFFEffect(int fd, struct ff_effect *effect, uint16_t timeoutMs) = 0; 87 // Activates/deactivates the effect index after setFFGain() and setFFEffect(). 88 virtual bool setFFPlay(int fd, int8_t index, bool value) = 0; 89 // Get the Alsa device for the audio coupled haptics effect 90 virtual bool getHapticAlsaDevice(int *card, int *device) = 0; 91 // Set haptics PCM amplifier before triggering audio haptics feature 92 virtual bool setHapticPcmAmp(struct pcm **haptic_pcm, bool enable, int card, 93 int device) = 0; 94 // Set OWT waveform for compose or compose PWLE request 95 virtual bool uploadOwtEffect(int fd, uint8_t *owtData, uint32_t numBytes, 96 struct ff_effect *effect, uint32_t *outEffectIndex, 97 int *status) = 0; 98 // Erase OWT waveform 99 virtual bool eraseOwtEffect(int fd, int8_t effectIndex, std::vector<ff_effect> *effect) = 0; 100 // Emit diagnostic information to the given file. 101 virtual void debug(int fd) = 0; 102 }; 103 104 // APIs for obtaining calibration/configuration data from persistent memory. 105 class HwCal { 106 public: 107 virtual ~HwCal() = default; 108 // Obtain the calibration version 109 virtual bool getVersion(uint32_t *value) = 0; 110 // Obtains the LRA resonant frequency to be used for PWLE playback 111 // and click compensation. 112 virtual bool getF0(std::string *value) = 0; 113 // Obtains the LRA series resistance to be used for click 114 // compensation. 115 virtual bool getRedc(std::string *value) = 0; 116 // Obtains the LRA Q factor to be used for Q-dependent waveform 117 // selection. 118 virtual bool getQ(std::string *value) = 0; 119 // Obtains frequency shift for long vibrations. 120 virtual bool getLongFrequencyShift(int32_t *value) = 0; 121 // Obtains the v0/v1(min/max) voltage levels to be applied for 122 // tick/click/long in units of 1%. 123 virtual bool getTickVolLevels(std::array<uint32_t, 2> *value) = 0; 124 virtual bool getClickVolLevels(std::array<uint32_t, 2> *value) = 0; 125 virtual bool getLongVolLevels(std::array<uint32_t, 2> *value) = 0; 126 // Checks if the chirp feature is enabled. 127 virtual bool isChirpEnabled() = 0; 128 // Obtains the supported primitive effects. 129 virtual bool getSupportedPrimitives(uint32_t *value) = 0; 130 // Checks if the f0 compensation feature needs to be enabled. 131 virtual bool isF0CompEnabled() = 0; 132 // Checks if the redc compensation feature needs to be enabled. 133 virtual bool isRedcCompEnabled() = 0; 134 // Emit diagnostic information to the given file. 135 virtual void debug(int fd) = 0; 136 }; 137 138 public: 139 Vibrator(std::unique_ptr<HwApi> hwapi, std::unique_ptr<HwCal> hwcal); 140 141 ndk::ScopedAStatus getCapabilities(int32_t *_aidl_return) override; 142 ndk::ScopedAStatus off() override; 143 ndk::ScopedAStatus on(int32_t timeoutMs, 144 const std::shared_ptr<IVibratorCallback> &callback) override; 145 ndk::ScopedAStatus perform(Effect effect, EffectStrength strength, 146 const std::shared_ptr<IVibratorCallback> &callback, 147 int32_t *_aidl_return) override; 148 ndk::ScopedAStatus getSupportedEffects(std::vector<Effect> *_aidl_return) override; 149 ndk::ScopedAStatus setAmplitude(float amplitude) override; 150 ndk::ScopedAStatus setExternalControl(bool enabled) override; 151 ndk::ScopedAStatus getCompositionDelayMax(int32_t *maxDelayMs); 152 ndk::ScopedAStatus getCompositionSizeMax(int32_t *maxSize); 153 ndk::ScopedAStatus getSupportedPrimitives(std::vector<CompositePrimitive> *supported) override; 154 ndk::ScopedAStatus getPrimitiveDuration(CompositePrimitive primitive, 155 int32_t *durationMs) override; 156 ndk::ScopedAStatus compose(const std::vector<CompositeEffect> &composite, 157 const std::shared_ptr<IVibratorCallback> &callback) override; 158 ndk::ScopedAStatus getSupportedAlwaysOnEffects(std::vector<Effect> *_aidl_return) override; 159 ndk::ScopedAStatus alwaysOnEnable(int32_t id, Effect effect, EffectStrength strength) override; 160 ndk::ScopedAStatus alwaysOnDisable(int32_t id) override; 161 ndk::ScopedAStatus getResonantFrequency(float *resonantFreqHz) override; 162 ndk::ScopedAStatus getQFactor(float *qFactor) override; 163 ndk::ScopedAStatus getFrequencyResolution(float *freqResolutionHz) override; 164 ndk::ScopedAStatus getFrequencyMinimum(float *freqMinimumHz) override; 165 ndk::ScopedAStatus getBandwidthAmplitudeMap(std::vector<float> *_aidl_return) override; 166 ndk::ScopedAStatus getPwlePrimitiveDurationMax(int32_t *durationMs) override; 167 ndk::ScopedAStatus getPwleCompositionSizeMax(int32_t *maxSize) override; 168 ndk::ScopedAStatus getSupportedBraking(std::vector<Braking> *supported) override; 169 ndk::ScopedAStatus composePwle(const std::vector<PrimitivePwle> &composite, 170 const std::shared_ptr<IVibratorCallback> &callback) override; 171 172 binder_status_t dump(int fd, const char **args, uint32_t numArgs) override; 173 174 private: 175 ndk::ScopedAStatus on(uint32_t timeoutMs, uint32_t effectIndex, struct dspmem_chunk *ch, 176 const std::shared_ptr<IVibratorCallback> &callback); 177 // set 'amplitude' based on an arbitrary scale determined by 'maximum' 178 ndk::ScopedAStatus setEffectAmplitude(float amplitude, float maximum, bool scalable); 179 ndk::ScopedAStatus setGlobalAmplitude(bool set); 180 // 'simple' effects are those precompiled and loaded into the controller 181 ndk::ScopedAStatus getSimpleDetails(Effect effect, EffectStrength strength, 182 uint32_t *outEffectIndex, uint32_t *outTimeMs, 183 uint32_t *outVolLevel); 184 // 'compound' effects are those composed by stringing multiple 'simple' effects 185 ndk::ScopedAStatus getCompoundDetails(Effect effect, EffectStrength strength, 186 uint32_t *outTimeMs, struct dspmem_chunk *outCh); 187 ndk::ScopedAStatus getPrimitiveDetails(CompositePrimitive primitive, uint32_t *outEffectIndex); 188 ndk::ScopedAStatus performEffect(Effect effect, EffectStrength strength, 189 const std::shared_ptr<IVibratorCallback> &callback, 190 int32_t *outTimeMs); 191 ndk::ScopedAStatus performEffect(uint32_t effectIndex, uint32_t volLevel, 192 struct dspmem_chunk *ch, 193 const std::shared_ptr<IVibratorCallback> &callback); 194 ndk::ScopedAStatus setPwle(const std::string &pwleQueue); 195 bool isUnderExternalControl(); 196 void waitForComplete(std::shared_ptr<IVibratorCallback> &&callback); 197 uint32_t intensityToVolLevel(float intensity, uint32_t effectIndex); 198 bool findHapticAlsaDevice(int *card, int *device); 199 bool hasHapticAlsaDevice(); 200 bool enableHapticPcmAmp(struct pcm **haptic_pcm, bool enable, int card, int device); 201 uint16_t amplitudeToScale(float amplitude, float maximum, bool scalable); 202 void updateContext(); 203 204 std::unique_ptr<HwApi> mHwApi; 205 std::unique_ptr<HwCal> mHwCal; 206 uint32_t mF0Offset; 207 std::array<uint32_t, 2> mTickEffectVol; 208 std::array<uint32_t, 2> mClickEffectVol; 209 std::array<uint32_t, 2> mLongEffectVol; 210 std::vector<ff_effect> mFfEffects; 211 std::vector<uint32_t> mEffectDurations; 212 std::future<void> mAsyncHandle; 213 ::android::base::unique_fd mInputFd; 214 int8_t mActiveId{-1}; 215 struct pcm *mHapticPcm; 216 int mCard; 217 int mDevice; 218 bool mHasHapticAlsaDevice{false}; 219 bool mIsUnderExternalControl; 220 float mLongEffectScale = 1.0; 221 bool mIsChirpEnabled; 222 uint32_t mScaleTime; 223 bool mFadeEnable; 224 uint32_t mScalingFactor; 225 uint32_t mScaleCooldown; 226 bool mContextEnable; 227 uint32_t mSupportedPrimitivesBits = 0x0; 228 std::vector<CompositePrimitive> mSupportedPrimitives; 229 bool mConfigHapticAlsaDeviceDone{false}; 230 }; 231 232 } // namespace vibrator 233 } // namespace hardware 234 } // namespace android 235 } // namespace aidl 236