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/stringprintf.h>
20 #include <android-base/unique_fd.h>
21 #include <linux/input.h>
22 #include <tinyalsa/asoundlib.h>
23 
24 #include <array>
25 #include <chrono>
26 #include <ctime>
27 #include <fstream>
28 #include <future>
29 
30 #include "CapoDetector.h"
31 
32 using CapoDetector = android::chre::CapoDetector;
33 
34 namespace aidl {
35 namespace android {
36 namespace hardware {
37 namespace vibrator {
38 
39 using ::android::base::StringPrintf;
40 
41 class Vibrator : public BnVibrator {
42   public:
43     // APIs for interfacing with the kernel driver.
44     class HwApi {
45       public:
46         virtual ~HwApi() = default;
47         // Stores the LRA resonant frequency to be used for PWLE playback
48         // and click compensation.
49         virtual bool setF0(std::string value) = 0;
50         // Stores the frequency offset for long vibrations.
51         virtual bool setF0Offset(uint32_t value) = 0;
52         // Stores the LRA series resistance to be used for click
53         // compensation.
54         virtual bool setRedc(std::string value) = 0;
55         // Stores the LRA Q factor to be used for Q-dependent waveform
56         // selection.
57         virtual bool setQ(std::string value) = 0;
58         // Reports the number of effect waveforms loaded in firmware.
59         virtual bool getEffectCount(uint32_t *value) = 0;
60         // Blocks until timeout or vibrator reaches desired state
61         // (2 = ASP enabled, 1 = haptic enabled, 0 = disabled).
62         virtual bool pollVibeState(uint32_t value, int32_t timeoutMs = -1) = 0;
63         // Reports whether getOwtFreeSpace() is supported.
64         virtual bool hasOwtFreeSpace() = 0;
65         // Reports the available OWT bytes.
66         virtual bool getOwtFreeSpace(uint32_t *value) = 0;
67         // Enables/Disables F0 compensation enable status
68         virtual bool setF0CompEnable(bool value) = 0;
69         // Enables/Disables Redc compensation enable status
70         virtual bool setRedcCompEnable(bool value) = 0;
71         // Stores the minumun delay time between playback and stop effects.
72         virtual bool setMinOnOffInterval(uint32_t value) = 0;
73         // Determine the /dev and /sys paths for input force-feedback control.
74         virtual bool initFF() = 0;
75         // Gets the scaling factor for contextual haptic events.
76         virtual uint32_t getContextScale() = 0;
77         // Gets the enable status for contextual haptic events.
78         virtual bool getContextEnable() = 0;
79         // Gets the settling time for contextual haptic events.
80         // This will allow the device to stay face up for the duration given,
81         // even if InMotion events were detected.
82         virtual uint32_t getContextSettlingTime() = 0;
83         // Gets the cooldown time for contextual haptic events.
84         // This is used to avoid changing the scale of close playback events.
85         virtual uint32_t getContextCooldownTime() = 0;
86         // Checks the enable status for contextual haptics fade feature.  When enabled
87         // this feature will cause the scaling factor to fade back up to max over
88         // the setting time set, instead of instantaneously changing it back to max.
89         virtual bool getContextFadeEnable() = 0;
90         // Indicates the number of 0.125-dB steps of attenuation to apply to
91         // waveforms triggered in response to vibration calls from the
92         // Android vibrator HAL.
93         virtual bool setFFGain(uint16_t value) = 0;
94         // Create/modify custom effects for all physical waveforms.
95         virtual bool setFFEffect(struct ff_effect *effect, uint16_t timeoutMs) = 0;
96         // Activates/deactivates the effect index after setFFGain() and setFFEffect().
97         virtual bool setFFPlay(int8_t index, bool value) = 0;
98         // Get the Alsa device for the audio coupled haptics effect
99         virtual bool getHapticAlsaDevice(int *card, int *device) = 0;
100         // Set haptics PCM amplifier before triggering audio haptics feature
101         virtual bool setHapticPcmAmp(struct pcm **haptic_pcm, bool enable, int card,
102                                      int device) = 0;
103         // Checks to see if the passthrough i2s haptics feature is supported by
104         // the target device.
105         virtual bool isPassthroughI2sHapticSupported() = 0;
106         // Set OWT waveform for compose or compose PWLE request
107         virtual bool uploadOwtEffect(const uint8_t *owtData, const uint32_t numBytes,
108                                      struct ff_effect *effect, uint32_t *outEffectIndex,
109                                      int *status) = 0;
110         // Erase OWT waveform
111         virtual bool eraseOwtEffect(int8_t effectIndex, std::vector<ff_effect> *effect) = 0;
112         // Checks to see if DBC (Dynamic Boost Control) feature is supported
113         // by the target device.
114         virtual bool isDbcSupported() = 0;
115         // Configures and enables the DBC feature and all associated parameters
116         virtual bool enableDbc() = 0;
117         // Emit diagnostic information to the given file.
118         virtual void debug(int fd) = 0;
119     };
120 
121     // APIs for obtaining calibration/configuration data from persistent memory.
122     class HwCal {
123       public:
124         virtual ~HwCal() = default;
125         // Obtain the calibration version
126         virtual bool getVersion(uint32_t *value) = 0;
127         // Obtains the LRA resonant frequency to be used for PWLE playback
128         // and click compensation.
129         virtual bool getF0(std::string *value) = 0;
130         // Obtains the LRA series resistance to be used for click
131         // compensation.
132         virtual bool getRedc(std::string *value) = 0;
133         // Obtains the LRA Q factor to be used for Q-dependent waveform
134         // selection.
135         virtual bool getQ(std::string *value) = 0;
136         // Obtains frequency shift for long vibrations.
137         virtual bool getLongFrequencyShift(int32_t *value) = 0;
138         // Obtains device mass for calculating the bandwidth amplitude map
139         virtual bool getDeviceMass(float *value) = 0;
140         // Obtains loc coeff for calculating the bandwidth amplitude map
141         virtual bool getLocCoeff(float *value) = 0;
142         // Obtains the v0/v1(min/max) voltage levels to be applied for
143         // tick/click/long in units of 1%.
144         virtual bool getTickVolLevels(std::array<uint32_t, 2> *value) = 0;
145         virtual bool getClickVolLevels(std::array<uint32_t, 2> *value) = 0;
146         virtual bool getLongVolLevels(std::array<uint32_t, 2> *value) = 0;
147         // Checks if the chirp feature is enabled.
148         virtual bool isChirpEnabled() = 0;
149         // Obtains the supported primitive effects.
150         virtual bool getSupportedPrimitives(uint32_t *value) = 0;
151         // Checks if the f0 compensation feature needs to be enabled.
152         virtual bool isF0CompEnabled() = 0;
153         // Checks if the redc compensation feature needs to be enabled.
154         virtual bool isRedcCompEnabled() = 0;
155         // Emit diagnostic information to the given file.
156         virtual void debug(int fd) = 0;
157     };
158 
159     // APIs for logging data to statistics backend
160     class StatsApi {
161       public:
162         virtual ~StatsApi() = default;
163         // Increment count for effect
164         virtual bool logPrimitive(uint16_t effectIndex) = 0;
165         // Increment count for long/short waveform and duration bucket
166         virtual bool logWaveform(uint16_t effectIndex, int32_t duration) = 0;
167         // Increment count for error
168         virtual bool logError(uint16_t errorIndex) = 0;
169         // Start new latency measurement
170         virtual bool logLatencyStart(uint16_t latencyIndex) = 0;
171         // Finish latency measurement and update latency statistics with result
172         virtual bool logLatencyEnd() = 0;
173         // Emit diagnostic information to the given file.
174         virtual void debug(int fd) = 0;
175     };
176 
177   public:
178     Vibrator(std::unique_ptr<HwApi> hwapi, std::unique_ptr<HwCal> hwcal,
179              std::unique_ptr<StatsApi> statsapi);
180 
181     ndk::ScopedAStatus getCapabilities(int32_t *_aidl_return) override;
182     ndk::ScopedAStatus off() override;
183     ndk::ScopedAStatus on(int32_t timeoutMs,
184                           const std::shared_ptr<IVibratorCallback> &callback) override;
185     ndk::ScopedAStatus perform(Effect effect, EffectStrength strength,
186                                const std::shared_ptr<IVibratorCallback> &callback,
187                                int32_t *_aidl_return) override;
188     ndk::ScopedAStatus getSupportedEffects(std::vector<Effect> *_aidl_return) override;
189     ndk::ScopedAStatus setAmplitude(float amplitude) override;
190     ndk::ScopedAStatus setExternalControl(bool enabled) override;
191     ndk::ScopedAStatus getCompositionDelayMax(int32_t *maxDelayMs);
192     ndk::ScopedAStatus getCompositionSizeMax(int32_t *maxSize);
193     ndk::ScopedAStatus getSupportedPrimitives(std::vector<CompositePrimitive> *supported) override;
194     ndk::ScopedAStatus getPrimitiveDuration(CompositePrimitive primitive,
195                                             int32_t *durationMs) override;
196     ndk::ScopedAStatus compose(const std::vector<CompositeEffect> &composite,
197                                const std::shared_ptr<IVibratorCallback> &callback) override;
198     ndk::ScopedAStatus getSupportedAlwaysOnEffects(std::vector<Effect> *_aidl_return) override;
199     ndk::ScopedAStatus alwaysOnEnable(int32_t id, Effect effect, EffectStrength strength) override;
200     ndk::ScopedAStatus alwaysOnDisable(int32_t id) override;
201     ndk::ScopedAStatus getResonantFrequency(float *resonantFreqHz) override;
202     ndk::ScopedAStatus getQFactor(float *qFactor) override;
203     ndk::ScopedAStatus getFrequencyResolution(float *freqResolutionHz) override;
204     ndk::ScopedAStatus getFrequencyMinimum(float *freqMinimumHz) override;
205     ndk::ScopedAStatus getBandwidthAmplitudeMap(std::vector<float> *_aidl_return) override;
206     ndk::ScopedAStatus getPwlePrimitiveDurationMax(int32_t *durationMs) override;
207     ndk::ScopedAStatus getPwleCompositionSizeMax(int32_t *maxSize) override;
208     ndk::ScopedAStatus getSupportedBraking(std::vector<Braking> *supported) override;
209     ndk::ScopedAStatus composePwle(const std::vector<PrimitivePwle> &composite,
210                                    const std::shared_ptr<IVibratorCallback> &callback) override;
211 
212     binder_status_t dump(int fd, const char **args, uint32_t numArgs) override;
213 
214   private:
215     ndk::ScopedAStatus on(uint32_t timeoutMs, uint32_t effectIndex, const class DspMemChunk *ch,
216                           const std::shared_ptr<IVibratorCallback> &callback);
217     // set 'amplitude' based on an arbitrary scale determined by 'maximum'
218     ndk::ScopedAStatus setEffectAmplitude(float amplitude, float maximum, bool scalable);
219     // 'simple' effects are those precompiled and loaded into the controller
220     ndk::ScopedAStatus getSimpleDetails(Effect effect, EffectStrength strength,
221                                         uint32_t *outEffectIndex, uint32_t *outTimeMs,
222                                         uint32_t *outVolLevel);
223     // 'compound' effects are those composed by stringing multiple 'simple' effects
224     ndk::ScopedAStatus getCompoundDetails(Effect effect, EffectStrength strength,
225                                           uint32_t *outTimeMs, class DspMemChunk *outCh);
226     ndk::ScopedAStatus getPrimitiveDetails(CompositePrimitive primitive, uint32_t *outEffectIndex);
227     ndk::ScopedAStatus performEffect(Effect effect, EffectStrength strength,
228                                      const std::shared_ptr<IVibratorCallback> &callback,
229                                      int32_t *outTimeMs);
230     ndk::ScopedAStatus performEffect(uint32_t effectIndex, uint32_t volLevel,
231                                      const class DspMemChunk *ch,
232                                      const std::shared_ptr<IVibratorCallback> &callback);
233     ndk::ScopedAStatus setPwle(const std::string &pwleQueue);
234     bool isUnderExternalControl();
235     void waitForComplete(std::shared_ptr<IVibratorCallback> &&callback);
236     uint32_t intensityToVolLevel(float intensity, uint32_t effectIndex);
237     bool findHapticAlsaDevice(int *card, int *device);
238     bool hasHapticAlsaDevice();
239     bool enableHapticPcmAmp(struct pcm **haptic_pcm, bool enable, int card, int device);
240     void createPwleMaxLevelLimitMap();
241     void createBandwidthAmplitudeMap();
242     uint16_t amplitudeToScale(float amplitude, float maximum, bool scalable);
243     void updateContext();
244 
245     std::unique_ptr<HwApi> mHwApi;
246     std::unique_ptr<HwCal> mHwCal;
247     std::unique_ptr<StatsApi> mStatsApi;
248     uint32_t mF0Offset;
249     std::array<uint32_t, 2> mTickEffectVol;
250     std::array<uint32_t, 2> mClickEffectVol;
251     std::array<uint32_t, 2> mLongEffectVol;
252     std::vector<ff_effect> mFfEffects;
253     std::vector<uint32_t> mEffectDurations;
254     std::vector<std::vector<int16_t>> mEffectCustomData;
255     std::future<void> mAsyncHandle;
256     int8_t mActiveId{-1};
257     struct pcm *mHapticPcm;
258     int mCard;
259     int mDevice;
260     bool mHasHapticAlsaDevice{false};
261     bool mHasPassthroughHapticDevice;
262     bool mIsUnderExternalControl;
263     float mGlobalAmplitude = 1.0;
264     bool mIsChirpEnabled;
265     uint32_t mSupportedPrimitivesBits = 0x0;
266     float mRedc{0};
267     float mResonantFrequency{0};
268     std::vector<CompositePrimitive> mSupportedPrimitives;
269     bool mConfigHapticAlsaDeviceDone{false};
270     std::vector<float> mBandwidthAmplitudeMap{};
271     bool mCreateBandwidthAmplitudeMapDone{false};
272     uint32_t mScaleTime;
273     bool mFadeEnable;
274     uint32_t mScalingFactor;
275     uint32_t mScaleCooldown;
276     bool mContextEnable;
277     bool mContextEnabledPreviously{false};
278     uint32_t mLastEffectPlayedTime = 0;
279     float mLastPlayedScale = 0;
280     sp<CapoDetector> mContextListener;
281     enum hal_state {
282         IDLE,
283         PREPARING,
284         ISSUED,
285         PLAYING,
286         STOPPED,
287         RESTORED,
288     };
289     hal_state halState = IDLE;
290 };
291 
292 }  // namespace vibrator
293 }  // namespace hardware
294 }  // namespace android
295 }  // namespace aidl
296