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 
17 #include "Vibrator.h"
18 
19 #include <glob.h>
20 #include <hardware/hardware.h>
21 #include <hardware/vibrator.h>
22 #include <log/log.h>
23 #include <stdio.h>
24 #include <utils/Trace.h>
25 
26 #include <cinttypes>
27 #include <cmath>
28 #include <fstream>
29 #include <iostream>
30 #include <memory>
31 #include <optional>
32 #include <sstream>
33 
34 #ifndef ARRAY_SIZE
35 #define ARRAY_SIZE(x) (sizeof((x)) / sizeof((x)[0]))
36 #endif
37 
38 #ifdef LOG_TAG
39 #undef LOG_TAG
40 #define LOG_TAG std::getenv("HAPTIC_NAME")
41 #endif
42 
43 namespace aidl {
44 namespace android {
45 namespace hardware {
46 namespace vibrator {
47 static constexpr uint16_t FF_CUSTOM_DATA_LEN_MAX_COMP = 2044;  // (COMPOSE_SIZE_MAX + 1) * 8 + 4
48 static constexpr uint16_t FF_CUSTOM_DATA_LEN_MAX_PWLE = 2302;
49 
50 static constexpr uint32_t WAVEFORM_DOUBLE_CLICK_SILENCE_MS = 100;
51 
52 static constexpr uint32_t WAVEFORM_LONG_VIBRATION_THRESHOLD_MS = 50;
53 
54 static constexpr uint8_t VOLTAGE_SCALE_MAX = 100;
55 
56 static constexpr int8_t MAX_COLD_START_LATENCY_MS = 6;  // I2C Transaction + DSP Return-From-Standby
57 static constexpr int8_t MAX_PAUSE_TIMING_ERROR_MS = 1;  // ALERT Irq Handling
58 static constexpr uint32_t MAX_TIME_MS = UINT16_MAX;
59 
60 static constexpr auto ASYNC_COMPLETION_TIMEOUT = std::chrono::milliseconds(100);
61 static constexpr auto POLLING_TIMEOUT = 20;
62 static constexpr int32_t COMPOSE_DELAY_MAX_MS = 10000;
63 
64 /* nsections is 8 bits. Need to preserve 1 section for the first delay before the first effect. */
65 static constexpr int32_t COMPOSE_SIZE_MAX = 254;
66 static constexpr int32_t COMPOSE_PWLE_SIZE_MAX_DEFAULT = 127;
67 
68 // Measured resonant frequency, f0_measured, is represented by Q10.14 fixed
69 // point format on cs40l26 devices. The expression to calculate f0 is:
70 //   f0 = f0_measured / 2^Q14_BIT_SHIFT
71 // See the LRA Calibration Support documentation for more details.
72 static constexpr int32_t Q14_BIT_SHIFT = 14;
73 
74 // Measured Q factor, q_measured, is represented by Q8.16 fixed
75 // point format on cs40l26 devices. The expression to calculate q is:
76 //   q = q_measured / 2^Q16_BIT_SHIFT
77 // See the LRA Calibration Support documentation for more details.
78 static constexpr int32_t Q16_BIT_SHIFT = 16;
79 
80 static constexpr int32_t COMPOSE_PWLE_PRIMITIVE_DURATION_MAX_MS = 16383;
81 
82 static constexpr uint32_t WT_LEN_CALCD = 0x00800000;
83 static constexpr uint8_t PWLE_CHIRP_BIT = 0x8;  // Dynamic/static frequency and voltage
84 static constexpr uint8_t PWLE_BRAKE_BIT = 0x4;
85 static constexpr uint8_t PWLE_AMP_REG_BIT = 0x2;
86 
87 static constexpr float PWLE_LEVEL_MIN = 0.0;
88 static constexpr float PWLE_LEVEL_MAX = 1.0;
89 static constexpr float CS40L26_PWLE_LEVEL_MIN = -1.0;
90 static constexpr float CS40L26_PWLE_LEVEL_MAX = 0.9995118;
91 static constexpr float PWLE_FREQUENCY_RESOLUTION_HZ = 1.00;
92 static constexpr float PWLE_FREQUENCY_MIN_HZ = 1.00;
93 static constexpr float PWLE_FREQUENCY_MAX_HZ = 1000.00;
94 static constexpr float PWLE_BW_MAP_SIZE =
95         1 + ((PWLE_FREQUENCY_MAX_HZ - PWLE_FREQUENCY_MIN_HZ) / PWLE_FREQUENCY_RESOLUTION_HZ);
96 
97 /*
98  * [15] Edge, 0:Falling, 1:Rising
99  * [14:12] GPI_NUM, 1:GPI1 (with CS40L26A, 1 is the only supported GPI)
100  * [8] BANK, 0:RAM, 1:R0M
101  * [7] USE_BUZZGEN, 0:Not buzzgen, 1:buzzgen
102  * [6:0] WAVEFORM_INDEX
103  * 0x9100 = 1001 0001 0000 0000: Rising + GPI1 + RAM + Not buzzgen
104  */
105 static constexpr uint16_t GPIO_TRIGGER_CONFIG = 0x9100;
106 
amplitudeToScale(float amplitude,float maximum)107 static uint16_t amplitudeToScale(float amplitude, float maximum) {
108     float ratio = 100; /* Unit: % */
109     if (maximum != 0)
110         ratio = amplitude / maximum * 100;
111 
112     if (maximum == 0 || ratio > 100)
113         ratio = 100;
114 
115     return std::round(ratio);
116 }
117 
118 enum WaveformBankID : uint8_t {
119     RAM_WVFRM_BANK,
120     ROM_WVFRM_BANK,
121     OWT_WVFRM_BANK,
122 };
123 
124 enum WaveformIndex : uint16_t {
125     /* Physical waveform */
126     WAVEFORM_LONG_VIBRATION_EFFECT_INDEX = 0,
127     WAVEFORM_RESERVED_INDEX_1 = 1,
128     WAVEFORM_CLICK_INDEX = 2,
129     WAVEFORM_SHORT_VIBRATION_EFFECT_INDEX = 3,
130     WAVEFORM_THUD_INDEX = 4,
131     WAVEFORM_SPIN_INDEX = 5,
132     WAVEFORM_QUICK_RISE_INDEX = 6,
133     WAVEFORM_SLOW_RISE_INDEX = 7,
134     WAVEFORM_QUICK_FALL_INDEX = 8,
135     WAVEFORM_LIGHT_TICK_INDEX = 9,
136     WAVEFORM_LOW_TICK_INDEX = 10,
137     WAVEFORM_RESERVED_MFG_1,
138     WAVEFORM_RESERVED_MFG_2,
139     WAVEFORM_RESERVED_MFG_3,
140     WAVEFORM_MAX_PHYSICAL_INDEX,
141     /* OWT waveform */
142     WAVEFORM_COMPOSE = WAVEFORM_MAX_PHYSICAL_INDEX,
143     WAVEFORM_PWLE,
144     /*
145      * Refer to <linux/input.h>, the WAVEFORM_MAX_INDEX must not exceed 96.
146      * #define FF_GAIN		0x60  // 96 in decimal
147      * #define FF_MAX_EFFECTS	FF_GAIN
148      */
149     WAVEFORM_MAX_INDEX,
150 };
151 
152 std::vector<CompositePrimitive> defaultSupportedPrimitives = {
153         ndk::enum_range<CompositePrimitive>().begin(), ndk::enum_range<CompositePrimitive>().end()};
154 
155 enum vibe_state {
156     VIBE_STATE_STOPPED = 0,
157     VIBE_STATE_HAPTIC,
158     VIBE_STATE_ASP,
159 };
160 
161 class DspMemChunk {
162   private:
163     std::unique_ptr<uint8_t[]> head;
164     size_t bytes = 0;
165     uint8_t waveformType;
166     uint8_t *_current;
167     const uint8_t *_max;
168     uint32_t _cache = 0;
169     int _cachebits = 0;
170 
isEnd() const171     bool isEnd() const { return _current == _max; }
min(int x,int y)172     int min(int x, int y) { return x < y ? x : y; }
173 
write(int nbits,uint32_t val)174     int write(int nbits, uint32_t val) {
175         int nwrite, i;
176 
177         nwrite = min(24 - _cachebits, nbits);
178         _cache <<= nwrite;
179         _cache |= val >> (nbits - nwrite);
180         _cachebits += nwrite;
181         nbits -= nwrite;
182 
183         if (_cachebits == 24) {
184             if (isEnd())
185                 return -ENOSPC;
186 
187             _cache &= 0xFFFFFF;
188             for (i = 0; i < sizeof(_cache); i++, _cache <<= 8)
189                 *_current++ = (_cache & 0xFF000000) >> 24;
190 
191             bytes += sizeof(_cache);
192             _cachebits = 0;
193         }
194 
195         if (nbits)
196             return write(nbits, val);
197 
198         return 0;
199     }
200 
fToU16(float input,uint16_t * output,float scale,float min,float max)201    int fToU16(float input, uint16_t *output, float scale, float min, float max) {
202         if (input < min || input > max)
203             return -ERANGE;
204 
205         *output = roundf(input * scale);
206         return 0;
207     }
208 
constructPwleSegment(uint16_t delay,uint16_t amplitude,uint16_t frequency,uint8_t flags,uint32_t vbemfTarget=0)209     void constructPwleSegment(uint16_t delay, uint16_t amplitude, uint16_t frequency, uint8_t flags,
210                               uint32_t vbemfTarget = 0) {
211         write(16, delay);
212         write(12, amplitude);
213         write(12, frequency);
214         /* feature flags to control the chirp, CLAB braking, back EMF amplitude regulation */
215         write(8, (flags | 1) << 4);
216         if (flags & PWLE_AMP_REG_BIT) {
217             write(24, vbemfTarget); /* target back EMF voltage */
218         }
219     }
220 
221   public:
front() const222     uint8_t *front() const { return head.get(); }
type() const223     uint8_t type() const { return waveformType; }
size() const224     size_t size() const { return bytes; }
225 
DspMemChunk(uint8_t type,size_t size)226     DspMemChunk(uint8_t type, size_t size) : head(new uint8_t[size]{0x00}) {
227         waveformType = type;
228         _current = head.get();
229         _max = _current + size;
230 
231         if (waveformType == WAVEFORM_COMPOSE) {
232             write(8, 0); /* Padding */
233             write(8, 0); /* nsections placeholder */
234             write(8, 0); /* repeat */
235         } else if (waveformType == WAVEFORM_PWLE) {
236             write(24, 0); /* Waveform length placeholder */
237             write(8, 0);  /* Repeat */
238             write(12, 0); /* Wait time between repeats */
239             write(8, 0);  /* nsections placeholder */
240         } else {
241             ALOGE("%s: Invalid type: %u", __func__, waveformType);
242         }
243     }
244 
flush()245     int flush() {
246         if (!_cachebits)
247             return 0;
248 
249         return write(24 - _cachebits, 0);
250     }
251 
constructComposeSegment(uint32_t effectVolLevel,uint32_t effectIndex,uint8_t repeat,uint8_t flags,uint16_t nextEffectDelay)252     int constructComposeSegment(uint32_t effectVolLevel, uint32_t effectIndex, uint8_t repeat,
253                                 uint8_t flags, uint16_t nextEffectDelay) {
254         if (waveformType != WAVEFORM_COMPOSE) {
255             ALOGE("%s: Invalid type: %d", __func__, waveformType);
256             return -EDOM;
257         }
258         if (effectVolLevel > 100 || effectIndex > WAVEFORM_MAX_PHYSICAL_INDEX) {
259             ALOGE("%s: Invalid argument: %u, %u", __func__, effectVolLevel, effectIndex);
260             return -EINVAL;
261         }
262         write(8, effectVolLevel);   /* amplitude */
263         write(8, effectIndex);      /* index */
264         write(8, repeat);           /* repeat */
265         write(8, flags);            /* flags */
266         write(16, nextEffectDelay); /* delay */
267         return 0;
268     }
269 
constructActiveSegment(int duration,float amplitude,float frequency,bool chirp)270     int constructActiveSegment(int duration, float amplitude, float frequency, bool chirp) {
271         uint16_t delay = 0;
272         uint16_t amp = 0;
273         uint16_t freq = 0;
274         uint8_t flags = 0x0;
275         if (waveformType != WAVEFORM_PWLE) {
276             ALOGE("%s: Invalid type: %d", __func__, waveformType);
277             return -EDOM;
278         }
279         if ((fToU16(duration, &delay, 4, 0.0f, COMPOSE_PWLE_PRIMITIVE_DURATION_MAX_MS) < 0) ||
280             (fToU16(amplitude, &amp, 2048, CS40L26_PWLE_LEVEL_MIN, CS40L26_PWLE_LEVEL_MAX) < 0) ||
281             (fToU16(frequency, &freq, 4, PWLE_FREQUENCY_MIN_HZ, PWLE_FREQUENCY_MAX_HZ) < 0)) {
282             ALOGE("%s: Invalid argument: %d, %f, %f", __func__, duration, amplitude, frequency);
283             return -ERANGE;
284         }
285         if (chirp) {
286             flags |= PWLE_CHIRP_BIT;
287         }
288         constructPwleSegment(delay, amp, freq, flags, 0 /*ignored*/);
289         return 0;
290     }
291 
constructBrakingSegment(int duration,Braking brakingType)292     int constructBrakingSegment(int duration, Braking brakingType) {
293         uint16_t delay = 0;
294         uint16_t freq = 0;
295         uint8_t flags = 0x00;
296         if (waveformType != WAVEFORM_PWLE) {
297             ALOGE("%s: Invalid type: %d", __func__, waveformType);
298             return -EDOM;
299         }
300         if (fToU16(duration, &delay, 4, 0.0f, COMPOSE_PWLE_PRIMITIVE_DURATION_MAX_MS) < 0) {
301             ALOGE("%s: Invalid argument: %d", __func__, duration);
302             return -ERANGE;
303         }
304         fToU16(PWLE_FREQUENCY_MIN_HZ, &freq, 4, PWLE_FREQUENCY_MIN_HZ, PWLE_FREQUENCY_MAX_HZ);
305         if (static_cast<std::underlying_type<Braking>::type>(brakingType)) {
306             flags |= PWLE_BRAKE_BIT;
307         }
308 
309         constructPwleSegment(delay, 0 /*ignored*/, freq, flags, 0 /*ignored*/);
310         return 0;
311     }
312 
updateWLength(uint32_t totalDuration)313     int updateWLength(uint32_t totalDuration) {
314         uint8_t *f = front();
315         if (f == nullptr) {
316             ALOGE("%s: head does not exist!", __func__);
317             return -ENOMEM;
318         }
319         if (waveformType != WAVEFORM_PWLE) {
320             ALOGE("%s: Invalid type: %d", __func__, waveformType);
321             return -EDOM;
322         }
323         if (totalDuration > 0x7FFFF) {
324             ALOGE("%s: Invalid argument: %u", __func__, totalDuration);
325             return -EINVAL;
326         }
327         totalDuration *= 8; /* Unit: 0.125 ms (since wlength played @ 8kHz). */
328         totalDuration |=
329                 WT_LEN_CALCD; /* Bit 23 is for WT_LEN_CALCD; Bit 22 is for WT_INDEFINITE. */
330         *(f + 0) = (totalDuration >> 24) & 0xFF;
331         *(f + 1) = (totalDuration >> 16) & 0xFF;
332         *(f + 2) = (totalDuration >> 8) & 0xFF;
333         *(f + 3) = totalDuration & 0xFF;
334         return 0;
335     }
336 
updateNSection(int segmentIdx)337     int updateNSection(int segmentIdx) {
338         uint8_t *f = front();
339         if (f == nullptr) {
340             ALOGE("%s: head does not exist!", __func__);
341             return -ENOMEM;
342         }
343 
344         if (waveformType == WAVEFORM_COMPOSE) {
345             if (segmentIdx > COMPOSE_SIZE_MAX + 1 /*1st effect may have a delay*/) {
346                 ALOGE("%s: Invalid argument: %d", __func__, segmentIdx);
347                 return -EINVAL;
348             }
349             *(f + 2) = (0xFF & segmentIdx);
350         } else if (waveformType == WAVEFORM_PWLE) {
351             if (segmentIdx > COMPOSE_PWLE_SIZE_MAX_DEFAULT) {
352                 ALOGE("%s: Invalid argument: %d", __func__, segmentIdx);
353                 return -EINVAL;
354             }
355             *(f + 7) |= (0xF0 & segmentIdx) >> 4; /* Bit 4 to 7 */
356             *(f + 9) |= (0x0F & segmentIdx) << 4; /* Bit 3 to 0 */
357         } else {
358             ALOGE("%s: Invalid type: %d", __func__, waveformType);
359             return -EDOM;
360         }
361 
362         return 0;
363     }
364 };
365 
Vibrator(std::unique_ptr<HwApi> hwApiDefault,std::unique_ptr<HwCal> hwCalDefault,std::unique_ptr<HwApi> hwApiDual,std::unique_ptr<HwCal> hwCalDual,std::unique_ptr<HwGPIO> hwgpio)366 Vibrator::Vibrator(std::unique_ptr<HwApi> hwApiDefault, std::unique_ptr<HwCal> hwCalDefault,
367                    std::unique_ptr<HwApi> hwApiDual, std::unique_ptr<HwCal> hwCalDual,
368                    std::unique_ptr<HwGPIO> hwgpio)
369     : mHwApiDef(std::move(hwApiDefault)),
370       mHwCalDef(std::move(hwCalDefault)),
371       mHwApiDual(std::move(hwApiDual)),
372       mHwCalDual(std::move(hwCalDual)),
373       mHwGPIO(std::move(hwgpio)),
374       mAsyncHandle(std::async([] {})) {
375     int32_t longFrequencyShift;
376     std::string caldata{8, '0'};
377     uint32_t calVer;
378 
379     // ==================Single actuators and dual actuators checking =============================
380     if ((mHwApiDual != nullptr) && (mHwCalDual != nullptr))
381         mIsDual = true;
382 
383     // ==================INPUT Devices== Base =================
384     const char *inputEventName = std::getenv("INPUT_EVENT_NAME");
385     const char *inputEventPathName = std::getenv("INPUT_EVENT_PATH");
386     if ((strstr(inputEventName, "cs40l26") != nullptr) ||
387         (strstr(inputEventName, "cs40l26_dual_input") != nullptr)) {
388         glob_t inputEventPaths;
389         int fd = -1;
390         int ret;
391         uint32_t val = 0;
392         char str[20] = {0x00};
393         for (uint8_t retry = 0; retry < 10; retry++) {
394             ret = glob(inputEventPathName, 0, nullptr, &inputEventPaths);
395             if (ret) {
396                 ALOGE("Failed to get input event paths (%d): %s", errno, strerror(errno));
397             } else {
398                 for (int i = 0; i < inputEventPaths.gl_pathc; i++) {
399                     fd = TEMP_FAILURE_RETRY(open(inputEventPaths.gl_pathv[i], O_RDWR));
400                     if (fd > 0) {
401                         if (ioctl(fd, EVIOCGBIT(0, sizeof(val)), &val) > 0 &&
402                             (val & (1 << EV_FF)) && ioctl(fd, EVIOCGNAME(sizeof(str)), &str) > 0 &&
403                             strstr(str, inputEventName) != nullptr) {
404                             mInputFd.reset(fd);
405                             ALOGI("Control %s through %s", inputEventName,
406                                   inputEventPaths.gl_pathv[i]);
407                             break;
408                         }
409                         close(fd);
410                     }
411                 }
412             }
413 
414             if (ret == 0) {
415                 globfree(&inputEventPaths);
416             }
417             if (mInputFd.ok()) {
418                 break;
419             }
420 
421             sleep(1);
422             ALOGW("Retry #%d to search in %zu input devices.", retry, inputEventPaths.gl_pathc);
423         }
424 
425         if (!mInputFd.ok()) {
426             ALOGE("Failed to get an input event with name %s", inputEventName);
427         }
428     } else {
429         ALOGE("The input name %s is not cs40l26_input or cs40l26_dual_input", inputEventName);
430     }
431 
432     // ==================INPUT Devices== Flip =================
433     if (mIsDual) {
434         const char *inputEventNameDual = std::getenv("INPUT_EVENT_NAME_DUAL");
435         if ((strstr(inputEventNameDual, "cs40l26_dual_input") != nullptr)) {
436             glob_t inputEventPaths;
437             int fd = -1;
438             int ret;
439             uint32_t val = 0;
440             char str[20] = {0x00};
441             for (uint8_t retry = 0; retry < 10; retry++) {
442                 ret = glob(inputEventPathName, 0, nullptr, &inputEventPaths);
443                 if (ret) {
444                     ALOGE("Failed to get flip's input event paths (%d): %s", errno,
445                           strerror(errno));
446                 } else {
447                     for (int i = 0; i < inputEventPaths.gl_pathc; i++) {
448                         fd = TEMP_FAILURE_RETRY(open(inputEventPaths.gl_pathv[i], O_RDWR));
449                         if (fd > 0) {
450                             if (ioctl(fd, EVIOCGBIT(0, sizeof(val)), &val) > 0 &&
451                                 (val & (1 << EV_FF)) &&
452                                 ioctl(fd, EVIOCGNAME(sizeof(str)), &str) > 0 &&
453                                 strstr(str, inputEventNameDual) != nullptr) {
454                                 mInputFdDual.reset(fd);
455                                 ALOGI("Control %s through %s", inputEventNameDual,
456                                       inputEventPaths.gl_pathv[i]);
457                                 break;
458                             }
459                             close(fd);
460                         }
461                     }
462                 }
463 
464                 if (ret == 0) {
465                     globfree(&inputEventPaths);
466                 }
467                 if (mInputFdDual.ok()) {
468                     break;
469                 }
470 
471                 sleep(1);
472                 ALOGW("Retry #%d to search in %zu input devices.", retry, inputEventPaths.gl_pathc);
473             }
474 
475             if (!mInputFdDual.ok()) {
476                 ALOGE("Failed to get an input event with name %s", inputEventNameDual);
477             }
478             ALOGE("HWAPI: %s", std::getenv("HWAPI_PATH_PREFIX"));
479         } else {
480             ALOGE("The input name %s is not cs40l26_dual_input", inputEventNameDual);
481         }
482     }
483     // ====================HAL internal effect table== Base ==================================
484 
485     mFfEffects.resize(WAVEFORM_MAX_INDEX);
486     mEffectDurations.resize(WAVEFORM_MAX_INDEX);
487     mEffectDurations = {
488             1000, 100, 12, 1000, 300, 130, 150, 500, 100, 5, 12, 1000, 1000, 1000,
489     }; /* 11+3 waveforms. The duration must < UINT16_MAX */
490     mEffectCustomData.reserve(WAVEFORM_MAX_INDEX);
491 
492     uint8_t effectIndex;
493     uint16_t numBytes = 0;
494     for (effectIndex = 0; effectIndex < WAVEFORM_MAX_INDEX; effectIndex++) {
495         if (effectIndex < WAVEFORM_MAX_PHYSICAL_INDEX) {
496             /* Initialize physical waveforms. */
497             mEffectCustomData.push_back({RAM_WVFRM_BANK, effectIndex});
498             mFfEffects[effectIndex] = {
499                     .type = FF_PERIODIC,
500                     .id = -1,
501                     // Length == 0 to allow firmware control of the duration
502                     .replay.length = 0,
503                     .u.periodic.waveform = FF_CUSTOM,
504                     .u.periodic.custom_data = mEffectCustomData[effectIndex].data(),
505                     .u.periodic.custom_len =
506                             static_cast<uint32_t>(mEffectCustomData[effectIndex].size()),
507             };
508             // Bypass the waveform update due to different input name
509             if ((strstr(inputEventName, "cs40l26") != nullptr) ||
510                 (strstr(inputEventName, "cs40l26_dual_input") != nullptr)) {
511                 // Let the firmware control the playback duration to avoid
512                 // cutting any effect that is played short
513                 if (!mHwApiDef->setFFEffect(
514                             mInputFd, &mFfEffects[effectIndex],
515                             mEffectDurations[effectIndex])) {
516                     ALOGE("Failed upload effect %d (%d): %s", effectIndex, errno, strerror(errno));
517                 }
518             }
519             if (mFfEffects[effectIndex].id != effectIndex) {
520                 ALOGW("Unexpected effect index: %d -> %d", effectIndex, mFfEffects[effectIndex].id);
521             }
522         } else {
523             /* Initiate placeholders for OWT effects. */
524             numBytes = effectIndex == WAVEFORM_COMPOSE ? FF_CUSTOM_DATA_LEN_MAX_COMP
525                                                        : FF_CUSTOM_DATA_LEN_MAX_PWLE;
526             std::vector<int16_t> tempVec(numBytes, 0);
527             mEffectCustomData.push_back(std::move(tempVec));
528             mFfEffects[effectIndex] = {
529                     .type = FF_PERIODIC,
530                     .id = -1,
531                     .replay.length = 0,
532                     .u.periodic.waveform = FF_CUSTOM,
533                     .u.periodic.custom_data = mEffectCustomData[effectIndex].data(),
534                     .u.periodic.custom_len = 0,
535             };
536         }
537     }
538 
539     // ====================HAL internal effect table== Flip ==================================
540     if (mIsDual) {
541         mFfEffectsDual.resize(WAVEFORM_MAX_INDEX);
542         mEffectCustomDataDual.reserve(WAVEFORM_MAX_INDEX);
543 
544         for (effectIndex = 0; effectIndex < WAVEFORM_MAX_INDEX; effectIndex++) {
545             if (effectIndex < WAVEFORM_MAX_PHYSICAL_INDEX) {
546                 /* Initialize physical waveforms. */
547                 mEffectCustomDataDual.push_back({RAM_WVFRM_BANK, effectIndex});
548                 mFfEffectsDual[effectIndex] = {
549                         .type = FF_PERIODIC,
550                         .id = -1,
551                         // Length == 0 to allow firmware control of the duration
552                         .replay.length = 0,
553                         .u.periodic.waveform = FF_CUSTOM,
554                         .u.periodic.custom_data = mEffectCustomDataDual[effectIndex].data(),
555                         .u.periodic.custom_len =
556                                 static_cast<uint32_t>(mEffectCustomDataDual[effectIndex].size()),
557                 };
558                 // Bypass the waveform update due to different input name
559                 if ((strstr(inputEventName, "cs40l26") != nullptr) ||
560                     (strstr(inputEventName, "cs40l26_dual_input") != nullptr)) {
561                     // Let the firmware control the playback duration to avoid
562                     // cutting any effect that is played short
563                     if (!mHwApiDual->setFFEffect(
564                                 mInputFdDual, &mFfEffectsDual[effectIndex],
565                                 mEffectDurations[effectIndex])) {
566                         ALOGE("Failed upload flip's effect %d (%d): %s", effectIndex, errno,
567                               strerror(errno));
568                     }
569                 }
570                 if (mFfEffectsDual[effectIndex].id != effectIndex) {
571                     ALOGW("Unexpected effect index: %d -> %d", effectIndex,
572                           mFfEffectsDual[effectIndex].id);
573                 }
574             } else {
575                 /* Initiate placeholders for OWT effects. */
576                 numBytes = effectIndex == WAVEFORM_COMPOSE ? FF_CUSTOM_DATA_LEN_MAX_COMP
577                                                        : FF_CUSTOM_DATA_LEN_MAX_PWLE;
578                 std::vector<int16_t> tempVec(numBytes, 0);
579                 mEffectCustomDataDual.push_back(std::move(tempVec));
580                 mFfEffectsDual[effectIndex] = {
581                         .type = FF_PERIODIC,
582                         .id = -1,
583                         .replay.length = 0,
584                         .u.periodic.waveform = FF_CUSTOM,
585                         .u.periodic.custom_data = mEffectCustomDataDual[effectIndex].data(),
586                         .u.periodic.custom_len = 0,
587                 };
588             }
589         }
590     }
591     // ==============Calibration data checking======================================
592 
593     if (mHwCalDef->getF0(&caldata)) {
594         mHwApiDef->setF0(caldata);
595     }
596     if (mHwCalDef->getRedc(&caldata)) {
597         mHwApiDef->setRedc(caldata);
598     }
599     if (mHwCalDef->getQ(&caldata)) {
600         mHwApiDef->setQ(caldata);
601     }
602 
603     if (mHwCalDef->getF0SyncOffset(&mF0Offset)) {
604         ALOGD("Vibrator::Vibrator: F0 offset calculated from both base and flip calibration data: "
605               "%u",
606               mF0Offset);
607     } else {
608         mHwCalDef->getLongFrequencyShift(&longFrequencyShift);
609         if (longFrequencyShift > 0) {
610             mF0Offset = longFrequencyShift * std::pow(2, 14);
611         } else if (longFrequencyShift < 0) {
612             mF0Offset = std::pow(2, 24) - std::abs(longFrequencyShift) * std::pow(2, 14);
613         } else {
614             mF0Offset = 0;
615         }
616         ALOGD("Vibrator::Vibrator: F0 offset calculated from long shift frequency: %u", mF0Offset);
617     }
618 
619     if (mIsDual) {
620         if (mHwCalDual->getF0(&caldata)) {
621             mHwApiDual->setF0(caldata);
622         }
623         if (mHwCalDual->getRedc(&caldata)) {
624             mHwApiDual->setRedc(caldata);
625         }
626         if (mHwCalDual->getQ(&caldata)) {
627             mHwApiDual->setQ(caldata);
628         }
629 
630         if (mHwCalDual->getF0SyncOffset(&mF0OffsetDual)) {
631             ALOGD("Vibrator::Vibrator: Dual: F0 offset calculated from both base and flip "
632                   "calibration data: "
633                   "%u",
634                   mF0OffsetDual);
635         }
636     }
637 
638     mHwCalDef->getVersion(&calVer);
639     if (calVer == 2) {
640         mHwCalDef->getTickVolLevels(&(mTickEffectVol));
641         mHwCalDef->getClickVolLevels(&(mClickEffectVol));
642         mHwCalDef->getLongVolLevels(&(mLongEffectVol));
643     } else {
644         ALOGW("Unsupported calibration version! Using the default calibration value");
645         mHwCalDef->getTickVolLevels(&(mTickEffectVol));
646         mHwCalDef->getClickVolLevels(&(mClickEffectVol));
647         mHwCalDef->getLongVolLevels(&(mLongEffectVol));
648     }
649 
650     // ================Project specific setting to driver===============================
651 
652     mHwApiDef->setF0CompEnable(mHwCalDef->isF0CompEnabled());
653     mHwApiDef->setRedcCompEnable(mHwCalDef->isRedcCompEnabled());
654     mHwApiDef->setMinOnOffInterval(MIN_ON_OFF_INTERVAL_US);
655     if (mIsDual) {
656         mHwApiDual->setF0CompEnable(mHwCalDual->isF0CompEnabled());
657         mHwApiDual->setRedcCompEnable(mHwCalDual->isRedcCompEnabled());
658         mHwApiDual->setMinOnOffInterval(MIN_ON_OFF_INTERVAL_US);
659     }
660     // ===============Audio coupled haptics bool init ========
661     mIsUnderExternalControl = false;
662 
663     // =============== Compose PWLE check =====================================
664     mIsChirpEnabled = mHwCalDef->isChirpEnabled();
665 
666     mHwCalDef->getSupportedPrimitives(&mSupportedPrimitivesBits);
667     if (mSupportedPrimitivesBits > 0) {
668         for (auto e : defaultSupportedPrimitives) {
669             if (mSupportedPrimitivesBits & (1 << uint32_t(e))) {
670                 mSupportedPrimitives.emplace_back(e);
671             }
672         }
673     } else {
674         for (auto e : defaultSupportedPrimitives) {
675             mSupportedPrimitivesBits |= (1 << uint32_t(e));
676         }
677         mSupportedPrimitives = defaultSupportedPrimitives;
678     }
679 
680     mPrimitiveMaxScale = {1.0f, 0.95f, 0.75f, 0.9f, 1.0f, 1.0f, 1.0f, 0.75f, 0.75f};
681     mPrimitiveMinScale = {0.0f, 0.01f, 0.11f, 0.23f, 0.0f, 0.25f, 0.02f, 0.03f, 0.16f};
682 
683     // ====== Get GPIO status and init it ================
684     mGPIOStatus = mHwGPIO->getGPIO();
685     if (!mGPIOStatus || !mHwGPIO->initGPIO()) {
686         ALOGE("Vibrator: GPIO initialization process error");
687     }
688 }
689 
getCapabilities(int32_t * _aidl_return)690 ndk::ScopedAStatus Vibrator::getCapabilities(int32_t *_aidl_return) {
691     ATRACE_NAME("Vibrator::getCapabilities");
692 
693     int32_t ret = IVibrator::CAP_ON_CALLBACK | IVibrator::CAP_PERFORM_CALLBACK |
694                   IVibrator::CAP_AMPLITUDE_CONTROL | IVibrator::CAP_GET_RESONANT_FREQUENCY |
695                   IVibrator::CAP_GET_Q_FACTOR;
696     if (hasHapticAlsaDevice()) {
697         ret |= IVibrator::CAP_EXTERNAL_CONTROL;
698     } else {
699         ALOGE("No haptics ALSA device");
700     }
701     if (mHwApiDef->hasOwtFreeSpace()) {
702         ret |= IVibrator::CAP_COMPOSE_EFFECTS;
703         if (mIsChirpEnabled) {
704             ret |= IVibrator::CAP_FREQUENCY_CONTROL | IVibrator::CAP_COMPOSE_PWLE_EFFECTS;
705         }
706     }
707     *_aidl_return = ret;
708     return ndk::ScopedAStatus::ok();
709 }
710 
off()711 ndk::ScopedAStatus Vibrator::off() {
712     ATRACE_NAME("Vibrator::off");
713     bool ret{true};
714     const std::scoped_lock<std::mutex> lock(mActiveId_mutex);
715 
716     if (mActiveId >= 0) {
717         ALOGD("Off: Stop the active effect: %d", mActiveId);
718         /* Stop the active effect. */
719         if (!mHwApiDef->setFFPlay(mInputFd, mActiveId, false)) {
720             ALOGE("Off: Failed to stop effect %d (%d): %s", mActiveId, errno, strerror(errno));
721             ret = false;
722         }
723         if (mIsDual && (!mHwApiDual->setFFPlay(mInputFdDual, mActiveId, false))) {
724             ALOGE("Off: Failed to stop flip's effect %d (%d): %s", mActiveId, errno,
725                   strerror(errno));
726             ret = false;
727         }
728 
729         if (!mHwGPIO->setGPIOOutput(false)) {
730             ALOGE("Off: Failed to reset GPIO(%d): %s", errno, strerror(errno));
731             return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
732         }
733     } else {
734         ALOGD("Off: Vibrator is already off");
735     }
736 
737     setGlobalAmplitude(false);
738     if (mF0Offset) {
739         mHwApiDef->setF0Offset(0);
740         if (mIsDual && mF0OffsetDual) {
741             mHwApiDual->setF0Offset(0);
742         }
743     }
744 
745     if (ret) {
746         ALOGD("Off: Done.");
747         mActiveId = -1;
748         return ndk::ScopedAStatus::ok();
749     } else {
750         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
751     }
752 }
753 
on(int32_t timeoutMs,const std::shared_ptr<IVibratorCallback> & callback)754 ndk::ScopedAStatus Vibrator::on(int32_t timeoutMs,
755                                 const std::shared_ptr<IVibratorCallback> &callback) {
756     ATRACE_NAME("Vibrator::on");
757     ALOGD("Vibrator::on");
758 
759     if (timeoutMs > MAX_TIME_MS) {
760         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
761     }
762     const uint16_t index = (timeoutMs < WAVEFORM_LONG_VIBRATION_THRESHOLD_MS)
763                                    ? WAVEFORM_SHORT_VIBRATION_EFFECT_INDEX
764                                    : WAVEFORM_LONG_VIBRATION_EFFECT_INDEX;
765     if (MAX_COLD_START_LATENCY_MS <= MAX_TIME_MS - timeoutMs) {
766         timeoutMs += MAX_COLD_START_LATENCY_MS;
767     }
768     setGlobalAmplitude(true);
769     if (mF0Offset) {
770         mHwApiDef->setF0Offset(mF0Offset);
771         if (mIsDual && mF0OffsetDual) {
772             mHwApiDual->setF0Offset(mF0OffsetDual);
773         }
774     }
775     return on(timeoutMs, index, nullptr /*ignored*/, callback);
776 }
777 
perform(Effect effect,EffectStrength strength,const std::shared_ptr<IVibratorCallback> & callback,int32_t * _aidl_return)778 ndk::ScopedAStatus Vibrator::perform(Effect effect, EffectStrength strength,
779                                      const std::shared_ptr<IVibratorCallback> &callback,
780                                      int32_t *_aidl_return) {
781     ATRACE_NAME("Vibrator::perform");
782     ALOGD("Vibrator::perform");
783     return performEffect(effect, strength, callback, _aidl_return);
784 }
785 
getSupportedEffects(std::vector<Effect> * _aidl_return)786 ndk::ScopedAStatus Vibrator::getSupportedEffects(std::vector<Effect> *_aidl_return) {
787     *_aidl_return = {Effect::TEXTURE_TICK, Effect::TICK, Effect::CLICK, Effect::HEAVY_CLICK,
788                      Effect::DOUBLE_CLICK};
789     return ndk::ScopedAStatus::ok();
790 }
791 
setAmplitude(float amplitude)792 ndk::ScopedAStatus Vibrator::setAmplitude(float amplitude) {
793     ATRACE_NAME("Vibrator::setAmplitude");
794 
795     if (amplitude <= 0.0f || amplitude > 1.0f) {
796         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
797     }
798 
799     mLongEffectScale = amplitude;
800     if (!isUnderExternalControl()) {
801         return setGlobalAmplitude(true);
802     } else {
803         return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
804     }
805 }
806 
setExternalControl(bool enabled)807 ndk::ScopedAStatus Vibrator::setExternalControl(bool enabled) {
808     ATRACE_NAME("Vibrator::setExternalControl");
809 
810     setGlobalAmplitude(enabled);
811 
812     if (mHasHapticAlsaDevice || mConfigHapticAlsaDeviceDone || hasHapticAlsaDevice()) {
813         if (!mHwApiDef->setHapticPcmAmp(&mHapticPcm, enabled, mCard, mDevice)) {
814             ALOGE("Failed to %s haptic pcm device: %d", (enabled ? "enable" : "disable"), mDevice);
815             return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
816         }
817     } else {
818         ALOGE("No haptics ALSA device");
819         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
820     }
821 
822     mIsUnderExternalControl = enabled;
823     return ndk::ScopedAStatus::ok();
824 }
825 
getCompositionDelayMax(int32_t * maxDelayMs)826 ndk::ScopedAStatus Vibrator::getCompositionDelayMax(int32_t *maxDelayMs) {
827     ATRACE_NAME("Vibrator::getCompositionDelayMax");
828     *maxDelayMs = COMPOSE_DELAY_MAX_MS;
829     return ndk::ScopedAStatus::ok();
830 }
831 
getCompositionSizeMax(int32_t * maxSize)832 ndk::ScopedAStatus Vibrator::getCompositionSizeMax(int32_t *maxSize) {
833     ATRACE_NAME("Vibrator::getCompositionSizeMax");
834     *maxSize = COMPOSE_SIZE_MAX;
835     return ndk::ScopedAStatus::ok();
836 }
837 
getSupportedPrimitives(std::vector<CompositePrimitive> * supported)838 ndk::ScopedAStatus Vibrator::getSupportedPrimitives(std::vector<CompositePrimitive> *supported) {
839     *supported = mSupportedPrimitives;
840     return ndk::ScopedAStatus::ok();
841 }
842 
getPrimitiveDuration(CompositePrimitive primitive,int32_t * durationMs)843 ndk::ScopedAStatus Vibrator::getPrimitiveDuration(CompositePrimitive primitive,
844                                                   int32_t *durationMs) {
845     ndk::ScopedAStatus status;
846     uint32_t effectIndex;
847     if (primitive != CompositePrimitive::NOOP) {
848         status = getPrimitiveDetails(primitive, &effectIndex);
849         if (!status.isOk()) {
850             return status;
851         }
852 
853         *durationMs = mEffectDurations[effectIndex];
854     } else {
855         *durationMs = 0;
856     }
857     return ndk::ScopedAStatus::ok();
858 }
859 
compose(const std::vector<CompositeEffect> & composite,const std::shared_ptr<IVibratorCallback> & callback)860 ndk::ScopedAStatus Vibrator::compose(const std::vector<CompositeEffect> &composite,
861                                      const std::shared_ptr<IVibratorCallback> &callback) {
862     ATRACE_NAME("Vibrator::compose");
863     ALOGD("Vibrator::compose");
864     uint16_t size;
865     uint16_t nextEffectDelay;
866     uint16_t totalDuration = 0;
867 
868     if (composite.size() > COMPOSE_SIZE_MAX || composite.empty()) {
869         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
870     }
871 
872     /* Check if there is a wait before the first effect. */
873     nextEffectDelay = composite.front().delayMs;
874     totalDuration += nextEffectDelay;
875     if (nextEffectDelay > COMPOSE_DELAY_MAX_MS || nextEffectDelay < 0) {
876         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
877     } else if (nextEffectDelay > 0) {
878         size = composite.size() + 1;
879     } else {
880         size = composite.size();
881     }
882 
883     DspMemChunk ch(WAVEFORM_COMPOSE, FF_CUSTOM_DATA_LEN_MAX_COMP);
884     const uint8_t header_count = ch.size();
885 
886     /* Insert 1 section for a wait before the first effect. */
887     if (nextEffectDelay) {
888         ch.constructComposeSegment(0 /*amplitude*/, 0 /*index*/, 0 /*repeat*/, 0 /*flags*/,
889                                    nextEffectDelay /*delay*/);
890     }
891 
892     for (uint32_t i_curr = 0, i_next = 1; i_curr < composite.size(); i_curr++, i_next++) {
893         auto &e_curr = composite[i_curr];
894         uint32_t effectIndex = 0;
895         uint32_t effectVolLevel = 0;
896         float effectScale = e_curr.scale;
897         if (effectScale < 0.0f || effectScale > 1.0f) {
898             return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
899         }
900 
901         if (e_curr.primitive != CompositePrimitive::NOOP) {
902             ndk::ScopedAStatus status;
903             status = getPrimitiveDetails(e_curr.primitive, &effectIndex);
904             if (!status.isOk()) {
905                 return status;
906             }
907             // Add a max and min threshold to prevent the device crash(overcurrent) or no
908             // feeling
909             if (effectScale > mPrimitiveMaxScale[static_cast<uint32_t>(e_curr.primitive)]) {
910                 effectScale = mPrimitiveMaxScale[static_cast<uint32_t>(e_curr.primitive)];
911             }
912             if (effectScale < mPrimitiveMinScale[static_cast<uint32_t>(e_curr.primitive)]) {
913                 effectScale = mPrimitiveMinScale[static_cast<uint32_t>(e_curr.primitive)];
914             }
915             effectVolLevel = intensityToVolLevel(effectScale, effectIndex);
916             totalDuration += mEffectDurations[effectIndex];
917         }
918 
919         /* Fetch the next composite effect delay and fill into the current section */
920         nextEffectDelay = 0;
921         if (i_next < composite.size()) {
922             auto &e_next = composite[i_next];
923             int32_t delay = e_next.delayMs;
924 
925             if (delay > COMPOSE_DELAY_MAX_MS || delay < 0) {
926                 return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
927             }
928             nextEffectDelay = delay;
929             totalDuration += delay;
930         }
931 
932         if (effectIndex == 0 && nextEffectDelay == 0) {
933             return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
934         }
935 
936         ch.constructComposeSegment(effectVolLevel, effectIndex, 0 /*repeat*/, 0 /*flags*/,
937                                    nextEffectDelay /*delay*/);
938     }
939 
940     ch.flush();
941     if (ch.updateNSection(size) < 0) {
942         ALOGE("%s: Failed to update the section count", __func__);
943         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
944     }
945     if (header_count == ch.size()) {
946         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
947     } else {
948         // Composition duration should be 0 to allow firmware to play the whole effect
949         mFfEffects[WAVEFORM_COMPOSE].replay.length = 0;
950         if (mIsDual) {
951             mFfEffectsDual[WAVEFORM_COMPOSE].replay.length = 0;
952         }
953         return performEffect(WAVEFORM_MAX_INDEX /*ignored*/, VOLTAGE_SCALE_MAX /*ignored*/, &ch,
954                              callback);
955     }
956 }
957 
on(uint32_t timeoutMs,uint32_t effectIndex,const DspMemChunk * ch,const std::shared_ptr<IVibratorCallback> & callback)958 ndk::ScopedAStatus Vibrator::on(uint32_t timeoutMs, uint32_t effectIndex, const DspMemChunk *ch,
959                                 const std::shared_ptr<IVibratorCallback> &callback) {
960     ndk::ScopedAStatus status = ndk::ScopedAStatus::ok();
961 
962     if (effectIndex >= FF_MAX_EFFECTS) {
963         ALOGE("Invalid waveform index %d", effectIndex);
964         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
965     }
966     if (mAsyncHandle.wait_for(ASYNC_COMPLETION_TIMEOUT) != std::future_status::ready) {
967         ALOGE("Previous vibration pending: prev: %d, curr: %d", mActiveId, effectIndex);
968         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
969     }
970 
971     if (ch) {
972         /* Upload OWT effect. */
973         if (ch->front() == nullptr) {
974             ALOGE("Invalid OWT bank");
975             return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
976         }
977 
978         if (ch->type() != WAVEFORM_PWLE && ch->type() != WAVEFORM_COMPOSE) {
979             ALOGE("Invalid OWT type");
980             return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
981         }
982         effectIndex = ch->type();
983 
984         uint32_t freeBytes;
985         mHwApiDef->getOwtFreeSpace(&freeBytes);
986         if (ch->size() > freeBytes) {
987             ALOGE("Invalid OWT length: Effect %d: %zu > %d!", effectIndex, ch->size(), freeBytes);
988             return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
989         }
990         if (mIsDual) {
991             mHwApiDual->getOwtFreeSpace(&freeBytes);
992             if (ch-> size() > freeBytes) {
993                 ALOGE("Invalid OWT length in flip: Effect %d: %d > %d!", effectIndex,
994                       ch-> size(), freeBytes);
995                 return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
996             }
997         }
998 
999         int errorStatus;
1000         if (mGPIOStatus && mIsDual) {
1001             mFfEffects[effectIndex].trigger.button = GPIO_TRIGGER_CONFIG | effectIndex;
1002             mFfEffectsDual[effectIndex].trigger.button = GPIO_TRIGGER_CONFIG | effectIndex;
1003         } else {
1004             ALOGD("Not dual haptics HAL and GPIO status fail");
1005         }
1006 
1007         if (!mHwApiDef->uploadOwtEffect(mInputFd, ch->front(), ch->size(), &mFfEffects[effectIndex],
1008                                         &effectIndex, &errorStatus)) {
1009             ALOGE("Invalid uploadOwtEffect");
1010             return ndk::ScopedAStatus::fromExceptionCode(errorStatus);
1011         }
1012         if (mIsDual && !mHwApiDual->uploadOwtEffect(mInputFdDual, ch->front(), ch->size(),
1013                                                     &mFfEffectsDual[effectIndex], &effectIndex,
1014                                                     &errorStatus)) {
1015             ALOGE("Invalid uploadOwtEffect in flip");
1016             return ndk::ScopedAStatus::fromExceptionCode(errorStatus);
1017         }
1018 
1019     } else if (effectIndex == WAVEFORM_SHORT_VIBRATION_EFFECT_INDEX ||
1020                effectIndex == WAVEFORM_LONG_VIBRATION_EFFECT_INDEX) {
1021         /* Update duration for long/short vibration. */
1022         mFfEffects[effectIndex].replay.length = static_cast<uint16_t>(timeoutMs);
1023         if (mGPIOStatus && mIsDual) {
1024             mFfEffects[effectIndex].trigger.button = GPIO_TRIGGER_CONFIG | effectIndex;
1025             mFfEffectsDual[effectIndex].trigger.button = GPIO_TRIGGER_CONFIG | effectIndex;
1026         } else {
1027             ALOGD("Not dual haptics HAL and GPIO status fail");
1028         }
1029         if (!mHwApiDef->setFFEffect(mInputFd, &mFfEffects[effectIndex],
1030                                     static_cast<uint16_t>(timeoutMs))) {
1031             ALOGE("Failed to edit effect %d (%d): %s", effectIndex, errno, strerror(errno));
1032             return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
1033         }
1034         if (mIsDual) {
1035             mFfEffectsDual[effectIndex].replay.length = static_cast<uint16_t>(timeoutMs);
1036             if (!mHwApiDual->setFFEffect(mInputFdDual, &mFfEffectsDual[effectIndex],
1037                                          static_cast<uint16_t>(timeoutMs))) {
1038                 ALOGE("Failed to edit flip's effect %d (%d): %s", effectIndex, errno,
1039                       strerror(errno));
1040                 return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
1041             }
1042         }
1043     }
1044 
1045     {
1046         const std::scoped_lock<std::mutex> lock(mActiveId_mutex);
1047         /* Play the event now. */
1048         mActiveId = effectIndex;
1049         if (!mGPIOStatus) {
1050             ALOGE("GetVibrator: GPIO status error");
1051             // Do playcode to play effect
1052             if (!mHwApiDef->setFFPlay(mInputFd, effectIndex, true)) {
1053                 ALOGE("Failed to play effect %d (%d): %s", effectIndex, errno, strerror(errno));
1054                 mActiveId = -1;
1055                 return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
1056             }
1057             if (mIsDual && !mHwApiDual->setFFPlay(mInputFdDual, effectIndex, true)) {
1058                 ALOGE("Failed to play flip's effect %d (%d): %s", effectIndex, errno,
1059                       strerror(errno));
1060                 mActiveId = -1;
1061                 return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
1062             }
1063         } else {
1064             // Using GPIO to play effect
1065             if ((effectIndex == WAVEFORM_CLICK_INDEX || effectIndex == WAVEFORM_LIGHT_TICK_INDEX)) {
1066                 mFfEffects[effectIndex].trigger.button = GPIO_TRIGGER_CONFIG | effectIndex;
1067                 if (!mHwApiDef->setFFEffect(mInputFd, &mFfEffects[effectIndex],
1068                                             mFfEffects[effectIndex].replay.length)) {
1069                     ALOGE("Failed to edit effect %d (%d): %s", effectIndex, errno, strerror(errno));
1070                     return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
1071                 }
1072                 if (mIsDual) {
1073                     mFfEffectsDual[effectIndex].trigger.button = GPIO_TRIGGER_CONFIG | effectIndex;
1074                     if (!mHwApiDual->setFFEffect(mInputFdDual, &mFfEffectsDual[effectIndex],
1075                                                  mFfEffectsDual[effectIndex].replay.length)) {
1076                         ALOGE("Failed to edit flip's effect %d (%d): %s", effectIndex, errno,
1077                               strerror(errno));
1078                         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
1079                     }
1080                 }
1081             }
1082             if (!mHwGPIO->setGPIOOutput(true)) {
1083                 ALOGE("Failed to trigger effect %d (%d) by GPIO: %s", effectIndex, errno,
1084                       strerror(errno));
1085                 return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
1086             }
1087         }
1088     }
1089 
1090     mAsyncHandle = std::async(&Vibrator::waitForComplete, this, callback);
1091     ALOGD("Vibrator::on, set done.");
1092     return ndk::ScopedAStatus::ok();
1093 }
1094 
setEffectAmplitude(float amplitude,float maximum)1095 ndk::ScopedAStatus Vibrator::setEffectAmplitude(float amplitude, float maximum) {
1096     uint16_t scale = amplitudeToScale(amplitude, maximum);
1097     if (!mHwApiDef->setFFGain(mInputFd, scale)) {
1098         ALOGE("Failed to set the gain to %u (%d): %s", scale, errno, strerror(errno));
1099         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
1100     }
1101     if (mIsDual) {
1102         if (!mHwApiDual->setFFGain(mInputFdDual, scale)) {
1103             ALOGE("Failed to set flip's gain to %u (%d): %s", scale, errno, strerror(errno));
1104             return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
1105         }
1106     }
1107     return ndk::ScopedAStatus::ok();
1108 }
1109 
setGlobalAmplitude(bool set)1110 ndk::ScopedAStatus Vibrator::setGlobalAmplitude(bool set) {
1111     uint8_t amplitude = set ? roundf(mLongEffectScale * mLongEffectVol[1]) : VOLTAGE_SCALE_MAX;
1112     if (!set) {
1113         mLongEffectScale = 1.0;  // Reset the scale for the later new effect.
1114     }
1115 
1116     return setEffectAmplitude(amplitude, VOLTAGE_SCALE_MAX);
1117 }
1118 
getSupportedAlwaysOnEffects(std::vector<Effect> *)1119 ndk::ScopedAStatus Vibrator::getSupportedAlwaysOnEffects(std::vector<Effect> * /*_aidl_return*/) {
1120     return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
1121 }
1122 
alwaysOnEnable(int32_t,Effect,EffectStrength)1123 ndk::ScopedAStatus Vibrator::alwaysOnEnable(int32_t /*id*/, Effect /*effect*/,
1124                                             EffectStrength /*strength*/) {
1125     return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
1126 }
alwaysOnDisable(int32_t)1127 ndk::ScopedAStatus Vibrator::alwaysOnDisable(int32_t /*id*/) {
1128     return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
1129 }
1130 
getResonantFrequency(float * resonantFreqHz)1131 ndk::ScopedAStatus Vibrator::getResonantFrequency(float *resonantFreqHz) {
1132     std::string caldata{8, '0'};
1133     if (!mHwCalDef->getF0(&caldata)) {
1134         ALOGE("Failed to get resonant frequency (%d): %s", errno, strerror(errno));
1135         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
1136     }
1137     *resonantFreqHz = static_cast<float>(std::stoul(caldata, nullptr, 16)) / (1 << Q14_BIT_SHIFT);
1138 
1139     return ndk::ScopedAStatus::ok();
1140 }
1141 
getQFactor(float * qFactor)1142 ndk::ScopedAStatus Vibrator::getQFactor(float *qFactor) {
1143     std::string caldata{8, '0'};
1144     if (!mHwCalDef->getQ(&caldata)) {
1145         ALOGE("Failed to get q factor (%d): %s", errno, strerror(errno));
1146         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
1147     }
1148     *qFactor = static_cast<float>(std::stoul(caldata, nullptr, 16)) / (1 << Q16_BIT_SHIFT);
1149 
1150     return ndk::ScopedAStatus::ok();
1151 }
1152 
getFrequencyResolution(float * freqResolutionHz)1153 ndk::ScopedAStatus Vibrator::getFrequencyResolution(float *freqResolutionHz) {
1154     int32_t capabilities;
1155     Vibrator::getCapabilities(&capabilities);
1156     if (capabilities & IVibrator::CAP_FREQUENCY_CONTROL) {
1157         *freqResolutionHz = PWLE_FREQUENCY_RESOLUTION_HZ;
1158         return ndk::ScopedAStatus::ok();
1159     } else {
1160         return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
1161     }
1162 }
1163 
getFrequencyMinimum(float * freqMinimumHz)1164 ndk::ScopedAStatus Vibrator::getFrequencyMinimum(float *freqMinimumHz) {
1165     int32_t capabilities;
1166     Vibrator::getCapabilities(&capabilities);
1167     if (capabilities & IVibrator::CAP_FREQUENCY_CONTROL) {
1168         *freqMinimumHz = PWLE_FREQUENCY_MIN_HZ;
1169         return ndk::ScopedAStatus::ok();
1170     } else {
1171         return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
1172     }
1173 }
1174 
getBandwidthAmplitudeMap(std::vector<float> * _aidl_return)1175 ndk::ScopedAStatus Vibrator::getBandwidthAmplitudeMap(std::vector<float> *_aidl_return) {
1176     // TODO(b/170919640): complete implementation
1177     int32_t capabilities;
1178     Vibrator::getCapabilities(&capabilities);
1179     if (capabilities & IVibrator::CAP_FREQUENCY_CONTROL) {
1180         std::vector<float> bandwidthAmplitudeMap(PWLE_BW_MAP_SIZE, 1.0);
1181         *_aidl_return = bandwidthAmplitudeMap;
1182         return ndk::ScopedAStatus::ok();
1183     } else {
1184         return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
1185     }
1186 }
1187 
getPwlePrimitiveDurationMax(int32_t * durationMs)1188 ndk::ScopedAStatus Vibrator::getPwlePrimitiveDurationMax(int32_t *durationMs) {
1189     int32_t capabilities;
1190     Vibrator::getCapabilities(&capabilities);
1191     if (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS) {
1192         *durationMs = COMPOSE_PWLE_PRIMITIVE_DURATION_MAX_MS;
1193         return ndk::ScopedAStatus::ok();
1194     } else {
1195         return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
1196     }
1197 }
1198 
getPwleCompositionSizeMax(int32_t * maxSize)1199 ndk::ScopedAStatus Vibrator::getPwleCompositionSizeMax(int32_t *maxSize) {
1200     int32_t capabilities;
1201     Vibrator::getCapabilities(&capabilities);
1202     if (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS) {
1203         *maxSize = COMPOSE_PWLE_SIZE_MAX_DEFAULT;
1204         return ndk::ScopedAStatus::ok();
1205     } else {
1206         return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
1207     }
1208 }
1209 
getSupportedBraking(std::vector<Braking> * supported)1210 ndk::ScopedAStatus Vibrator::getSupportedBraking(std::vector<Braking> *supported) {
1211     int32_t capabilities;
1212     Vibrator::getCapabilities(&capabilities);
1213     if (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS) {
1214         *supported = {
1215                 Braking::NONE,
1216         };
1217         return ndk::ScopedAStatus::ok();
1218     } else {
1219         return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
1220     }
1221 }
1222 
resetPreviousEndAmplitudeEndFrequency(float * prevEndAmplitude,float * prevEndFrequency)1223 static void resetPreviousEndAmplitudeEndFrequency(float *prevEndAmplitude,
1224                                                   float *prevEndFrequency) {
1225     const float reset = -1.0;
1226     *prevEndAmplitude = reset;
1227     *prevEndFrequency = reset;
1228 }
1229 
incrementIndex(int * index)1230 static void incrementIndex(int *index) {
1231     *index += 1;
1232 }
1233 
composePwle(const std::vector<PrimitivePwle> & composite,const std::shared_ptr<IVibratorCallback> & callback)1234 ndk::ScopedAStatus Vibrator::composePwle(const std::vector<PrimitivePwle> &composite,
1235                                          const std::shared_ptr<IVibratorCallback> &callback) {
1236     ATRACE_NAME("Vibrator::composePwle");
1237     int32_t capabilities;
1238 
1239     Vibrator::getCapabilities(&capabilities);
1240     if ((capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS) == 0) {
1241         return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
1242     }
1243 
1244     if (composite.empty() || composite.size() > COMPOSE_PWLE_SIZE_MAX_DEFAULT) {
1245         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
1246     }
1247 
1248     std::vector<Braking> supported;
1249     Vibrator::getSupportedBraking(&supported);
1250     bool isClabSupported =
1251             std::find(supported.begin(), supported.end(), Braking::CLAB) != supported.end();
1252 
1253     int segmentIdx = 0;
1254     uint32_t totalDuration = 0;
1255     float prevEndAmplitude;
1256     float prevEndFrequency;
1257     resetPreviousEndAmplitudeEndFrequency(&prevEndAmplitude, &prevEndFrequency);
1258     DspMemChunk ch(WAVEFORM_PWLE, FF_CUSTOM_DATA_LEN_MAX_PWLE);
1259     bool chirp = false;
1260 
1261     for (auto &e : composite) {
1262         switch (e.getTag()) {
1263             case PrimitivePwle::active: {
1264                 auto active = e.get<PrimitivePwle::active>();
1265                 if (active.duration < 0 ||
1266                     active.duration > COMPOSE_PWLE_PRIMITIVE_DURATION_MAX_MS) {
1267                     return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
1268                 }
1269                 if (active.startAmplitude < PWLE_LEVEL_MIN ||
1270                     active.startAmplitude > PWLE_LEVEL_MAX ||
1271                     active.endAmplitude < PWLE_LEVEL_MIN || active.endAmplitude > PWLE_LEVEL_MAX) {
1272                     return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
1273                 }
1274                 if (active.startAmplitude > CS40L26_PWLE_LEVEL_MAX) {
1275                     active.startAmplitude = CS40L26_PWLE_LEVEL_MAX;
1276                 }
1277                 if (active.endAmplitude > CS40L26_PWLE_LEVEL_MAX) {
1278                     active.endAmplitude = CS40L26_PWLE_LEVEL_MAX;
1279                 }
1280 
1281                 if (active.startFrequency < PWLE_FREQUENCY_MIN_HZ ||
1282                     active.startFrequency > PWLE_FREQUENCY_MAX_HZ ||
1283                     active.endFrequency < PWLE_FREQUENCY_MIN_HZ ||
1284                     active.endFrequency > PWLE_FREQUENCY_MAX_HZ) {
1285                     return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
1286                 }
1287 
1288                 if (!((active.startAmplitude == prevEndAmplitude) &&
1289                       (active.startFrequency == prevEndFrequency))) {
1290                     if (ch.constructActiveSegment(0, active.startAmplitude, active.startFrequency,
1291                                                   false) < 0) {
1292                         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
1293                     }
1294                     incrementIndex(&segmentIdx);
1295                 }
1296 
1297                 if (active.startFrequency != active.endFrequency) {
1298                     chirp = true;
1299                 }
1300                 if (ch.constructActiveSegment(active.duration, active.endAmplitude,
1301                                               active.endFrequency, chirp) < 0) {
1302                     return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
1303                 }
1304                 incrementIndex(&segmentIdx);
1305 
1306                 prevEndAmplitude = active.endAmplitude;
1307                 prevEndFrequency = active.endFrequency;
1308                 totalDuration += active.duration;
1309                 chirp = false;
1310                 break;
1311             }
1312             case PrimitivePwle::braking: {
1313                 auto braking = e.get<PrimitivePwle::braking>();
1314                 if (braking.braking > Braking::CLAB) {
1315                     return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
1316                 } else if (!isClabSupported && (braking.braking == Braking::CLAB)) {
1317                     return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
1318                 }
1319 
1320                 if (braking.duration > COMPOSE_PWLE_PRIMITIVE_DURATION_MAX_MS) {
1321                     return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
1322                 }
1323 
1324                 if (ch.constructBrakingSegment(0, braking.braking) < 0) {
1325                     return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
1326                 }
1327                 incrementIndex(&segmentIdx);
1328 
1329                 if (ch.constructBrakingSegment(braking.duration, braking.braking) < 0) {
1330                     return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
1331                 }
1332                 incrementIndex(&segmentIdx);
1333 
1334                 resetPreviousEndAmplitudeEndFrequency(&prevEndAmplitude, &prevEndFrequency);
1335                 totalDuration += braking.duration;
1336                 break;
1337             }
1338         }
1339 
1340         if (segmentIdx > COMPOSE_PWLE_SIZE_MAX_DEFAULT) {
1341             ALOGE("Too many PrimitivePwle section!");
1342             return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
1343         }
1344     }
1345     ch.flush();
1346 
1347     /* Update wlength */
1348     totalDuration += MAX_COLD_START_LATENCY_MS;
1349     if (totalDuration > 0x7FFFF) {
1350         ALOGE("Total duration is too long (%d)!", totalDuration);
1351         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
1352     }
1353 
1354     if (ch.updateWLength(totalDuration) < 0) {
1355         ALOGE("%s: Failed to update the waveform length length", __func__);
1356         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
1357     }
1358 
1359     /* Update nsections */
1360     if (ch.updateNSection(segmentIdx) < 0) {
1361         ALOGE("%s: Failed to update the section count", __func__);
1362         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
1363     }
1364 
1365     return performEffect(WAVEFORM_MAX_INDEX /*ignored*/, VOLTAGE_SCALE_MAX /*ignored*/, &ch,
1366                          callback);
1367 }
1368 
isUnderExternalControl()1369 bool Vibrator::isUnderExternalControl() {
1370     return mIsUnderExternalControl;
1371 }
1372 
1373 // BnCInterface APIs
1374 
dump(int fd,const char ** args,uint32_t numArgs)1375 binder_status_t Vibrator::dump(int fd, const char **args, uint32_t numArgs) {
1376     if (fd < 0) {
1377         ALOGE("Called debug() with invalid fd.");
1378         return STATUS_OK;
1379     }
1380 
1381     (void)args;
1382     (void)numArgs;
1383 
1384     dprintf(fd, "AIDL:\n");
1385 
1386     dprintf(fd, "  F0 Offset: base: %" PRIu32 " flip: %" PRIu32 "\n", mF0Offset, mF0OffsetDual);
1387 
1388     dprintf(fd, "  Voltage Levels:\n");
1389     dprintf(fd, "     Tick Effect Min: %" PRIu32 " Max: %" PRIu32 "\n", mTickEffectVol[0],
1390             mTickEffectVol[1]);
1391     dprintf(fd, "     Click Effect Min: %" PRIu32 " Max: %" PRIu32 "\n", mClickEffectVol[0],
1392             mClickEffectVol[1]);
1393     dprintf(fd, "     Long Effect Min: %" PRIu32 " Max: %" PRIu32 "\n", mLongEffectVol[0],
1394             mLongEffectVol[1]);
1395 
1396     dprintf(fd, "  FF effect:\n");
1397     dprintf(fd, "    Physical waveform:\n");
1398     dprintf(fd, "==== Base ====\n\tId\tIndex\tt   ->\tt'\ttrigger button\n");
1399     uint8_t effectId;
1400     for (effectId = 0; effectId < WAVEFORM_MAX_PHYSICAL_INDEX; effectId++) {
1401         dprintf(fd, "\t%d\t%d\t%d\t%d\t%X\n", mFfEffects[effectId].id,
1402                 mFfEffects[effectId].u.periodic.custom_data[1], mEffectDurations[effectId],
1403                 mFfEffects[effectId].replay.length, mFfEffects[effectId].trigger.button);
1404     }
1405     if (mIsDual) {
1406         dprintf(fd, "==== Flip ====\n\tId\tIndex\tt   ->\tt'\ttrigger button\n");
1407         for (effectId = 0; effectId < WAVEFORM_MAX_PHYSICAL_INDEX; effectId++) {
1408             dprintf(fd, "\t%d\t%d\t%d\t%d\t%X\n", mFfEffectsDual[effectId].id,
1409                     mFfEffectsDual[effectId].u.periodic.custom_data[1], mEffectDurations[effectId],
1410                     mFfEffectsDual[effectId].replay.length,
1411                     mFfEffectsDual[effectId].trigger.button);
1412         }
1413     }
1414 
1415     dprintf(fd, "Base: OWT waveform:\n");
1416     dprintf(fd, "\tId\tBytes\tData\tt\ttrigger button\n");
1417     for (effectId = WAVEFORM_MAX_PHYSICAL_INDEX; effectId < WAVEFORM_MAX_INDEX; effectId++) {
1418         uint32_t numBytes = mFfEffects[effectId].u.periodic.custom_len * 2;
1419         std::stringstream ss;
1420         ss << " ";
1421         for (int i = 0; i < numBytes; i++) {
1422             ss << std::uppercase << std::setfill('0') << std::setw(2) << std::hex
1423                << (uint16_t)(*(
1424                           reinterpret_cast<uint8_t *>(mFfEffects[effectId].u.periodic.custom_data) +
1425                           i))
1426                << " ";
1427         }
1428         dprintf(fd, "\t%d\t%d\t{%s}\t%u\t%X\n", mFfEffects[effectId].id, numBytes, ss.str().c_str(),
1429                 mFfEffectsDual[effectId].replay.length, mFfEffects[effectId].trigger.button);
1430     }
1431     if (mIsDual) {
1432         dprintf(fd, "Flip: OWT waveform:\n");
1433         dprintf(fd, "\tId\tBytes\tData\tt\ttrigger button\n");
1434         for (effectId = WAVEFORM_MAX_PHYSICAL_INDEX; effectId < WAVEFORM_MAX_INDEX; effectId++) {
1435             uint32_t numBytes = mFfEffectsDual[effectId].u.periodic.custom_len * 2;
1436             std::stringstream ss;
1437             ss << " ";
1438             for (int i = 0; i < numBytes; i++) {
1439                 ss << std::uppercase << std::setfill('0') << std::setw(2) << std::hex
1440                    << (uint16_t)(*(reinterpret_cast<uint8_t *>(
1441                                            mFfEffectsDual[effectId].u.periodic.custom_data) +
1442                                    i))
1443                    << " ";
1444             }
1445             dprintf(fd, "\t%d\t%d\t{%s}\t%u\t%X\n", mFfEffectsDual[effectId].id, numBytes,
1446                     ss.str().c_str(), mFfEffectsDual[effectId].replay.length,
1447                     mFfEffectsDual[effectId].trigger.button);
1448         }
1449     }
1450     dprintf(fd, "\n");
1451     dprintf(fd, "\n");
1452 
1453     mHwApiDef->debug(fd);
1454 
1455     dprintf(fd, "\n");
1456 
1457     mHwCalDef->debug(fd);
1458 
1459     if (mIsDual) {
1460         mHwApiDual->debug(fd);
1461         dprintf(fd, "\n");
1462         mHwCalDual->debug(fd);
1463     }
1464 
1465     fsync(fd);
1466     return STATUS_OK;
1467 }
1468 
hasHapticAlsaDevice()1469 bool Vibrator::hasHapticAlsaDevice() {
1470     // We need to call findHapticAlsaDevice once only. Calling in the
1471     // constructor is too early in the boot process and the pcm file contents
1472     // are empty. Hence we make the call here once only right before we need to.
1473     if (!mConfigHapticAlsaDeviceDone) {
1474         if (mHwApiDef->getHapticAlsaDevice(&mCard, &mDevice)) {
1475             mHasHapticAlsaDevice = true;
1476             mConfigHapticAlsaDeviceDone = true;
1477         } else {
1478             ALOGE("Haptic ALSA device not supported");
1479         }
1480     } else {
1481         ALOGD("Haptic ALSA device configuration done.");
1482     }
1483     return mHasHapticAlsaDevice;
1484 }
1485 
getSimpleDetails(Effect effect,EffectStrength strength,uint32_t * outEffectIndex,uint32_t * outTimeMs,uint32_t * outVolLevel)1486 ndk::ScopedAStatus Vibrator::getSimpleDetails(Effect effect, EffectStrength strength,
1487                                               uint32_t *outEffectIndex, uint32_t *outTimeMs,
1488                                               uint32_t *outVolLevel) {
1489     uint32_t effectIndex;
1490     uint32_t timeMs;
1491     float intensity;
1492     uint32_t volLevel;
1493     switch (strength) {
1494         case EffectStrength::LIGHT:
1495             intensity = 0.5f;
1496             break;
1497         case EffectStrength::MEDIUM:
1498             intensity = 0.7f;
1499             break;
1500         case EffectStrength::STRONG:
1501             intensity = 1.0f;
1502             break;
1503         default:
1504             return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
1505     }
1506 
1507     switch (effect) {
1508         case Effect::TEXTURE_TICK:
1509             effectIndex = WAVEFORM_LIGHT_TICK_INDEX;
1510             intensity *= 0.5f;
1511             break;
1512         case Effect::TICK:
1513             effectIndex = WAVEFORM_CLICK_INDEX;
1514             intensity *= 0.5f;
1515             break;
1516         case Effect::CLICK:
1517             effectIndex = WAVEFORM_CLICK_INDEX;
1518             intensity *= 0.7f;
1519             break;
1520         case Effect::HEAVY_CLICK:
1521             effectIndex = WAVEFORM_CLICK_INDEX;
1522             intensity *= 1.0f;
1523             // WAVEFORM_CLICK_INDEX is 2, but the primitive CLICK index is 1.
1524             if (intensity > mPrimitiveMaxScale[WAVEFORM_CLICK_INDEX - 1]) {
1525                 intensity = mPrimitiveMaxScale[WAVEFORM_CLICK_INDEX - 1];
1526             }
1527             break;
1528         default:
1529             return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
1530     }
1531 
1532     volLevel = intensityToVolLevel(intensity, effectIndex);
1533     timeMs = mEffectDurations[effectIndex] + MAX_COLD_START_LATENCY_MS;
1534 
1535     *outEffectIndex = effectIndex;
1536     *outTimeMs = timeMs;
1537     *outVolLevel = volLevel;
1538     return ndk::ScopedAStatus::ok();
1539 }
1540 
getCompoundDetails(Effect effect,EffectStrength strength,uint32_t * outTimeMs,DspMemChunk * outCh)1541 ndk::ScopedAStatus Vibrator::getCompoundDetails(Effect effect, EffectStrength strength,
1542                                                 uint32_t *outTimeMs, DspMemChunk *outCh) {
1543     ndk::ScopedAStatus status;
1544     uint32_t timeMs = 0;
1545     uint32_t thisEffectIndex;
1546     uint32_t thisTimeMs;
1547     uint32_t thisVolLevel;
1548     switch (effect) {
1549         case Effect::DOUBLE_CLICK:
1550             status = getSimpleDetails(Effect::CLICK, strength, &thisEffectIndex, &thisTimeMs,
1551                                       &thisVolLevel);
1552             if (!status.isOk()) {
1553                 return status;
1554             }
1555             timeMs += thisTimeMs;
1556             outCh->constructComposeSegment(thisVolLevel, thisEffectIndex, 0 /*repeat*/, 0 /*flags*/,
1557                                            WAVEFORM_DOUBLE_CLICK_SILENCE_MS);
1558 
1559             timeMs += WAVEFORM_DOUBLE_CLICK_SILENCE_MS + MAX_PAUSE_TIMING_ERROR_MS;
1560 
1561             status = getSimpleDetails(Effect::HEAVY_CLICK, strength, &thisEffectIndex, &thisTimeMs,
1562                                       &thisVolLevel);
1563             if (!status.isOk()) {
1564                 return status;
1565             }
1566             timeMs += thisTimeMs;
1567 
1568             outCh->constructComposeSegment(thisVolLevel, thisEffectIndex, 0 /*repeat*/, 0 /*flags*/,
1569                                            0 /*delay*/);
1570             outCh->flush();
1571             if (outCh->updateNSection(2) < 0) {
1572                 ALOGE("%s: Failed to update the section count", __func__);
1573                 return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
1574             }
1575 
1576             break;
1577         default:
1578             return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
1579     }
1580 
1581     *outTimeMs = timeMs;
1582     // Compositions should have 0 duration
1583     mFfEffects[WAVEFORM_COMPOSE].replay.length = 0;
1584     if (mIsDual) {
1585         mFfEffectsDual[WAVEFORM_COMPOSE].replay.length = 0;
1586     }
1587 
1588     return ndk::ScopedAStatus::ok();
1589 }
1590 
getPrimitiveDetails(CompositePrimitive primitive,uint32_t * outEffectIndex)1591 ndk::ScopedAStatus Vibrator::getPrimitiveDetails(CompositePrimitive primitive,
1592                                                  uint32_t *outEffectIndex) {
1593     uint32_t effectIndex;
1594     uint32_t primitiveBit = 1 << int32_t(primitive);
1595     if ((primitiveBit & mSupportedPrimitivesBits) == 0x0) {
1596         return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
1597     }
1598 
1599     switch (primitive) {
1600         case CompositePrimitive::NOOP:
1601             return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
1602         case CompositePrimitive::CLICK:
1603             effectIndex = WAVEFORM_CLICK_INDEX;
1604             break;
1605         case CompositePrimitive::THUD:
1606             effectIndex = WAVEFORM_THUD_INDEX;
1607             break;
1608         case CompositePrimitive::SPIN:
1609             effectIndex = WAVEFORM_SPIN_INDEX;
1610             break;
1611         case CompositePrimitive::QUICK_RISE:
1612             effectIndex = WAVEFORM_QUICK_RISE_INDEX;
1613             break;
1614         case CompositePrimitive::SLOW_RISE:
1615             effectIndex = WAVEFORM_SLOW_RISE_INDEX;
1616             break;
1617         case CompositePrimitive::QUICK_FALL:
1618             effectIndex = WAVEFORM_QUICK_FALL_INDEX;
1619             break;
1620         case CompositePrimitive::LIGHT_TICK:
1621             effectIndex = WAVEFORM_LIGHT_TICK_INDEX;
1622             break;
1623         case CompositePrimitive::LOW_TICK:
1624             effectIndex = WAVEFORM_LOW_TICK_INDEX;
1625             break;
1626         default:
1627             return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
1628     }
1629 
1630     *outEffectIndex = effectIndex;
1631 
1632     return ndk::ScopedAStatus::ok();
1633 }
1634 
performEffect(Effect effect,EffectStrength strength,const std::shared_ptr<IVibratorCallback> & callback,int32_t * outTimeMs)1635 ndk::ScopedAStatus Vibrator::performEffect(Effect effect, EffectStrength strength,
1636                                            const std::shared_ptr<IVibratorCallback> &callback,
1637                                            int32_t *outTimeMs) {
1638     ndk::ScopedAStatus status;
1639     uint32_t effectIndex;
1640     uint32_t timeMs = 0;
1641     uint32_t volLevel;
1642     std::optional<DspMemChunk> maybeCh;
1643     switch (effect) {
1644         case Effect::TEXTURE_TICK:
1645             // fall-through
1646         case Effect::TICK:
1647             // fall-through
1648         case Effect::CLICK:
1649             // fall-through
1650         case Effect::HEAVY_CLICK:
1651             status = getSimpleDetails(effect, strength, &effectIndex, &timeMs, &volLevel);
1652             break;
1653         case Effect::DOUBLE_CLICK:
1654             maybeCh.emplace(WAVEFORM_COMPOSE, FF_CUSTOM_DATA_LEN_MAX_COMP);
1655             status = getCompoundDetails(effect, strength, &timeMs, &*maybeCh);
1656             volLevel = VOLTAGE_SCALE_MAX;
1657             break;
1658         default:
1659             status = ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
1660             break;
1661     }
1662     if (status.isOk()) {
1663         DspMemChunk *ch = maybeCh ? &*maybeCh : nullptr;
1664         status = performEffect(effectIndex, volLevel, ch, callback);
1665     }
1666 
1667     *outTimeMs = timeMs;
1668     return status;
1669 }
1670 
performEffect(uint32_t effectIndex,uint32_t volLevel,const DspMemChunk * ch,const std::shared_ptr<IVibratorCallback> & callback)1671 ndk::ScopedAStatus Vibrator::performEffect(uint32_t effectIndex, uint32_t volLevel,
1672                                            const DspMemChunk *ch,
1673                                            const std::shared_ptr<IVibratorCallback> &callback) {
1674     setEffectAmplitude(volLevel, VOLTAGE_SCALE_MAX);
1675 
1676     return on(MAX_TIME_MS, effectIndex, ch, callback);
1677 }
1678 
waitForComplete(std::shared_ptr<IVibratorCallback> && callback)1679 void Vibrator::waitForComplete(std::shared_ptr<IVibratorCallback> &&callback) {
1680     ALOGD("waitForComplete: Callback status in waitForComplete(): callBack: %d",
1681           (callback != nullptr));
1682 
1683     // Bypass checking flip part's haptic state
1684     if (!mHwApiDef->pollVibeState(VIBE_STATE_HAPTIC, POLLING_TIMEOUT)) {
1685         ALOGD("Failed to get state \"Haptic\"");
1686     }
1687 
1688     mHwApiDef->pollVibeState(VIBE_STATE_STOPPED);
1689     // Check flip's state after base was done
1690     if (mIsDual) {
1691         mHwApiDual->pollVibeState(VIBE_STATE_STOPPED);
1692     }
1693     ALOGD("waitForComplete: get STOP");
1694     {
1695         const std::scoped_lock<std::mutex> lock(mActiveId_mutex);
1696         if (mActiveId >= WAVEFORM_MAX_PHYSICAL_INDEX) {
1697             if (!mHwApiDef->eraseOwtEffect(mInputFd, mActiveId, &mFfEffects)) {
1698                 ALOGE("Failed to clean up the composed effect %d", mActiveId);
1699             }
1700             if (mIsDual &&
1701                 (!mHwApiDual->eraseOwtEffect(mInputFdDual, mActiveId, &mFfEffectsDual))) {
1702                 ALOGE("Failed to clean up flip's composed effect %d", mActiveId);
1703             }
1704         } else {
1705             ALOGD("waitForComplete: Vibrator is already off");
1706         }
1707         mActiveId = -1;
1708         if (mGPIOStatus && !mHwGPIO->setGPIOOutput(false)) {
1709             ALOGE("waitForComplete: Failed to reset GPIO(%d): %s", errno, strerror(errno));
1710         }
1711         // Do waveform number checking
1712         uint32_t effectCount = WAVEFORM_MAX_PHYSICAL_INDEX;
1713         mHwApiDef->getEffectCount(&effectCount);
1714         if (effectCount > WAVEFORM_MAX_PHYSICAL_INDEX) {
1715             // Forcibly clean all OWT waveforms
1716             if (!mHwApiDef->eraseOwtEffect(mInputFd, WAVEFORM_MAX_INDEX, &mFfEffects)) {
1717                 ALOGE("Failed to clean up all base's composed effect");
1718             }
1719         }
1720 
1721         if (mIsDual) {
1722             // Forcibly clean all OWT waveforms
1723             effectCount = WAVEFORM_MAX_PHYSICAL_INDEX;
1724             mHwApiDual->getEffectCount(&effectCount);
1725             if ((effectCount > WAVEFORM_MAX_PHYSICAL_INDEX) &&
1726                 (!mHwApiDual->eraseOwtEffect(mInputFdDual, WAVEFORM_MAX_INDEX, &mFfEffectsDual))) {
1727                 ALOGE("Failed to clean up all flip's composed effect");
1728             }
1729         }
1730     }
1731 
1732     if (callback) {
1733         auto ret = callback->onComplete();
1734         if (!ret.isOk()) {
1735             ALOGE("Failed completion callback: %d", ret.getExceptionCode());
1736         }
1737     }
1738     ALOGD("waitForComplete: Done.");
1739 }
1740 
intensityToVolLevel(float intensity,uint32_t effectIndex)1741 uint32_t Vibrator::intensityToVolLevel(float intensity, uint32_t effectIndex) {
1742     uint32_t volLevel;
1743     auto calc = [](float intst, std::array<uint32_t, 2> v) -> uint32_t {
1744         return std::lround(intst * (v[1] - v[0])) + v[0];
1745     };
1746 
1747     switch (effectIndex) {
1748         case WAVEFORM_LIGHT_TICK_INDEX:
1749             volLevel = calc(intensity, mTickEffectVol);
1750             break;
1751         case WAVEFORM_QUICK_RISE_INDEX:
1752             // fall-through
1753         case WAVEFORM_QUICK_FALL_INDEX:
1754             volLevel = calc(intensity, mLongEffectVol);
1755             break;
1756         case WAVEFORM_CLICK_INDEX:
1757             // fall-through
1758         case WAVEFORM_THUD_INDEX:
1759             // fall-through
1760         case WAVEFORM_SPIN_INDEX:
1761             // fall-through
1762         case WAVEFORM_SLOW_RISE_INDEX:
1763             // fall-through
1764         default:
1765             volLevel = calc(intensity, mClickEffectVol);
1766             break;
1767     }
1768     return volLevel;
1769 }
1770 
1771 }  // namespace vibrator
1772 }  // namespace hardware
1773 }  // namespace android
1774 }  // namespace aidl
1775