Vibrator.cpp 49 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327
  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. #include "Vibrator.h"
  17. #include <glob.h>
  18. #include <hardware/hardware.h>
  19. #include <hardware/vibrator.h>
  20. #include <log/log.h>
  21. #include <stdio.h>
  22. #include <utils/Trace.h>
  23. #include <cinttypes>
  24. #include <cmath>
  25. #include <fstream>
  26. #include <iostream>
  27. #include <sstream>
  28. #ifndef ARRAY_SIZE
  29. #define ARRAY_SIZE(x) (sizeof((x)) / sizeof((x)[0]))
  30. #endif
  31. namespace aidl {
  32. namespace android {
  33. namespace hardware {
  34. namespace vibrator {
  35. static constexpr uint8_t FF_CUSTOM_DATA_LEN = 2;
  36. static constexpr uint16_t FF_CUSTOM_DATA_LEN_MAX_COMP = 2044; // (COMPOSE_SIZE_MAX + 1) * 8 + 4
  37. static constexpr uint16_t FF_CUSTOM_DATA_LEN_MAX_PWLE = 2302;
  38. static constexpr uint32_t WAVEFORM_DOUBLE_CLICK_SILENCE_MS = 100;
  39. static constexpr uint32_t WAVEFORM_LONG_VIBRATION_THRESHOLD_MS = 50;
  40. static constexpr uint8_t VOLTAGE_SCALE_MAX = 100;
  41. static constexpr int8_t MAX_COLD_START_LATENCY_MS = 6; // I2C Transaction + DSP Return-From-Standby
  42. static constexpr uint32_t MIN_ON_OFF_INTERVAL_US = 8500; // SVC initialization time
  43. static constexpr int8_t MAX_PAUSE_TIMING_ERROR_MS = 1; // ALERT Irq Handling
  44. static constexpr uint32_t MAX_TIME_MS = UINT16_MAX;
  45. static constexpr auto ASYNC_COMPLETION_TIMEOUT = std::chrono::milliseconds(100);
  46. static constexpr auto POLLING_TIMEOUT = 20;
  47. static constexpr int32_t COMPOSE_DELAY_MAX_MS = 10000;
  48. /* nsections is 8 bits. Need to preserve 1 section for the first delay before the first effect. */
  49. static constexpr int32_t COMPOSE_SIZE_MAX = 254;
  50. static constexpr int32_t COMPOSE_PWLE_SIZE_MAX_DEFAULT = 127;
  51. // Measured resonant frequency, f0_measured, is represented by Q10.14 fixed
  52. // point format on cs40l26 devices. The expression to calculate f0 is:
  53. // f0 = f0_measured / 2^Q14_BIT_SHIFT
  54. // See the LRA Calibration Support documentation for more details.
  55. static constexpr int32_t Q14_BIT_SHIFT = 14;
  56. // Measured Q factor, q_measured, is represented by Q8.16 fixed
  57. // point format on cs40l26 devices. The expression to calculate q is:
  58. // q = q_measured / 2^Q16_BIT_SHIFT
  59. // See the LRA Calibration Support documentation for more details.
  60. static constexpr int32_t Q16_BIT_SHIFT = 16;
  61. static constexpr int32_t COMPOSE_PWLE_PRIMITIVE_DURATION_MAX_MS = 16383;
  62. static constexpr uint32_t WT_LEN_CALCD = 0x00800000;
  63. static constexpr uint8_t PWLE_CHIRP_BIT = 0x8; // Dynamic/static frequency and voltage
  64. static constexpr uint8_t PWLE_BRAKE_BIT = 0x4;
  65. static constexpr uint8_t PWLE_AMP_REG_BIT = 0x2;
  66. static constexpr float PWLE_LEVEL_MIN = 0.0;
  67. static constexpr float PWLE_LEVEL_MAX = 1.0;
  68. static constexpr float CS40L26_PWLE_LEVEL_MIX = -1.0;
  69. static constexpr float CS40L26_PWLE_LEVEL_MAX = 0.9995118;
  70. static constexpr float PWLE_FREQUENCY_RESOLUTION_HZ = 1.00;
  71. static constexpr float PWLE_FREQUENCY_MIN_HZ = 1.00;
  72. static constexpr float PWLE_FREQUENCY_MAX_HZ = 1000.00;
  73. static constexpr float PWLE_BW_MAP_SIZE =
  74. 1 + ((PWLE_FREQUENCY_MAX_HZ - PWLE_FREQUENCY_MIN_HZ) / PWLE_FREQUENCY_RESOLUTION_HZ);
  75. static uint16_t amplitudeToScale(float amplitude, float maximum) {
  76. float ratio = 100; /* Unit: % */
  77. if (maximum != 0)
  78. ratio = amplitude / maximum * 100;
  79. if (maximum == 0 || ratio > 100)
  80. ratio = 100;
  81. return std::round(ratio);
  82. }
  83. enum WaveformBankID : uint8_t {
  84. RAM_WVFRM_BANK,
  85. ROM_WVFRM_BANK,
  86. OWT_WVFRM_BANK,
  87. };
  88. enum WaveformIndex : uint16_t {
  89. /* Physical waveform */
  90. WAVEFORM_LONG_VIBRATION_EFFECT_INDEX = 0,
  91. WAVEFORM_RESERVED_INDEX_1 = 1,
  92. WAVEFORM_CLICK_INDEX = 2,
  93. WAVEFORM_SHORT_VIBRATION_EFFECT_INDEX = 3,
  94. WAVEFORM_THUD_INDEX = 4,
  95. WAVEFORM_SPIN_INDEX = 5,
  96. WAVEFORM_QUICK_RISE_INDEX = 6,
  97. WAVEFORM_SLOW_RISE_INDEX = 7,
  98. WAVEFORM_QUICK_FALL_INDEX = 8,
  99. WAVEFORM_LIGHT_TICK_INDEX = 9,
  100. WAVEFORM_LOW_TICK_INDEX = 10,
  101. WAVEFORM_RESERVED_MFG_1,
  102. WAVEFORM_RESERVED_MFG_2,
  103. WAVEFORM_RESERVED_MFG_3,
  104. WAVEFORM_MAX_PHYSICAL_INDEX,
  105. /* OWT waveform */
  106. WAVEFORM_COMPOSE = WAVEFORM_MAX_PHYSICAL_INDEX,
  107. WAVEFORM_PWLE,
  108. /*
  109. * Refer to <linux/input.h>, the WAVEFORM_MAX_INDEX must not exceed 96.
  110. * #define FF_GAIN 0x60 // 96 in decimal
  111. * #define FF_MAX_EFFECTS FF_GAIN
  112. */
  113. WAVEFORM_MAX_INDEX,
  114. };
  115. std::vector<CompositePrimitive> defaultSupportedPrimitives = {
  116. ndk::enum_range<CompositePrimitive>().begin(), ndk::enum_range<CompositePrimitive>().end()};
  117. enum vibe_state {
  118. VIBE_STATE_STOPPED = 0,
  119. VIBE_STATE_HAPTIC,
  120. VIBE_STATE_ASP,
  121. };
  122. std::mutex mActiveId_mutex; // protects mActiveId
  123. static int min(int x, int y) {
  124. return x < y ? x : y;
  125. }
  126. static int floatToUint16(float input, uint16_t *output, float scale, float min, float max) {
  127. if (input < min || input > max)
  128. return -ERANGE;
  129. *output = roundf(input * scale);
  130. return 0;
  131. }
  132. struct dspmem_chunk {
  133. uint8_t *head;
  134. uint8_t *current;
  135. uint8_t *max;
  136. int bytes;
  137. uint32_t cache;
  138. int cachebits;
  139. };
  140. static dspmem_chunk *dspmem_chunk_create(void *data, int size) {
  141. auto ch = new dspmem_chunk{
  142. .head = reinterpret_cast<uint8_t *>(data),
  143. .current = reinterpret_cast<uint8_t *>(data),
  144. .max = reinterpret_cast<uint8_t *>(data) + size,
  145. };
  146. return ch;
  147. }
  148. static bool dspmem_chunk_end(struct dspmem_chunk *ch) {
  149. return ch->current == ch->max;
  150. }
  151. static int dspmem_chunk_bytes(struct dspmem_chunk *ch) {
  152. return ch->bytes;
  153. }
  154. static int dspmem_chunk_write(struct dspmem_chunk *ch, int nbits, uint32_t val) {
  155. int nwrite, i;
  156. nwrite = min(24 - ch->cachebits, nbits);
  157. ch->cache <<= nwrite;
  158. ch->cache |= val >> (nbits - nwrite);
  159. ch->cachebits += nwrite;
  160. nbits -= nwrite;
  161. if (ch->cachebits == 24) {
  162. if (dspmem_chunk_end(ch))
  163. return -ENOSPC;
  164. ch->cache &= 0xFFFFFF;
  165. for (i = 0; i < sizeof(ch->cache); i++, ch->cache <<= 8)
  166. *ch->current++ = (ch->cache & 0xFF000000) >> 24;
  167. ch->bytes += sizeof(ch->cache);
  168. ch->cachebits = 0;
  169. }
  170. if (nbits)
  171. return dspmem_chunk_write(ch, nbits, val);
  172. return 0;
  173. }
  174. static int dspmem_chunk_flush(struct dspmem_chunk *ch) {
  175. if (!ch->cachebits)
  176. return 0;
  177. return dspmem_chunk_write(ch, 24 - ch->cachebits, 0);
  178. }
  179. Vibrator::Vibrator(std::unique_ptr<HwApi> hwapi, std::unique_ptr<HwCal> hwcal)
  180. : mHwApi(std::move(hwapi)), mHwCal(std::move(hwcal)), mAsyncHandle(std::async([] {})) {
  181. int32_t longFrequencyShift;
  182. std::string caldata{8, '0'};
  183. uint32_t calVer;
  184. const char *inputEventName = std::getenv("INPUT_EVENT_NAME");
  185. const char *inputEventPathName = std::getenv("INPUT_EVENT_PATH");
  186. if ((strstr(inputEventName, "cs40l26") != nullptr) ||
  187. (strstr(inputEventName, "cs40l26_dual_input") != nullptr)) {
  188. glob_t inputEventPaths;
  189. int fd = -1;
  190. int ret;
  191. uint32_t val = 0;
  192. char str[20] = {0x00};
  193. for (uint8_t retry = 0; retry < 10; retry++) {
  194. ret = glob(inputEventPathName, 0, nullptr, &inputEventPaths);
  195. if (ret) {
  196. ALOGE("Fail to get input event paths (%d): %s", errno, strerror(errno));
  197. } else {
  198. for (int i = 0; i < inputEventPaths.gl_pathc; i++) {
  199. fd = TEMP_FAILURE_RETRY(open(inputEventPaths.gl_pathv[i], O_RDWR));
  200. if (fd > 0) {
  201. if (ioctl(fd, EVIOCGBIT(0, sizeof(val)), &val) > 0 &&
  202. (val & (1 << EV_FF)) && ioctl(fd, EVIOCGNAME(sizeof(str)), &str) > 0 &&
  203. strstr(str, inputEventName) != nullptr) {
  204. mInputFd.reset(fd);
  205. ALOGI("Control %s through %s", inputEventName,
  206. inputEventPaths.gl_pathv[i]);
  207. break;
  208. }
  209. close(fd);
  210. }
  211. }
  212. }
  213. if (ret == 0) {
  214. globfree(&inputEventPaths);
  215. }
  216. if (mInputFd.ok()) {
  217. break;
  218. }
  219. sleep(1);
  220. ALOGW("Retry #%d to search in %zu input devices.", retry, inputEventPaths.gl_pathc);
  221. }
  222. if (!mInputFd.ok()) {
  223. ALOGE("Fail to get an input event with name %s", inputEventName);
  224. }
  225. } else {
  226. ALOGE("The input name %s is not cs40l26_input or cs40l26_dual_input", inputEventName);
  227. }
  228. mFfEffects.resize(WAVEFORM_MAX_INDEX);
  229. mEffectDurations.resize(WAVEFORM_MAX_INDEX);
  230. mEffectDurations = {
  231. 1000, 100, 30, 1000, 300, 130, 150, 500, 100, 15, 20, 1000, 1000, 1000,
  232. }; /* 11+3 waveforms. The duration must < UINT16_MAX */
  233. uint8_t effectIndex;
  234. for (effectIndex = 0; effectIndex < WAVEFORM_MAX_INDEX; effectIndex++) {
  235. if (effectIndex < WAVEFORM_MAX_PHYSICAL_INDEX) {
  236. /* Initialize physical waveforms. */
  237. mFfEffects[effectIndex] = {
  238. .type = FF_PERIODIC,
  239. .id = -1,
  240. .replay.length = static_cast<uint16_t>(mEffectDurations[effectIndex]),
  241. .u.periodic.waveform = FF_CUSTOM,
  242. .u.periodic.custom_data = new int16_t[2]{RAM_WVFRM_BANK, effectIndex},
  243. .u.periodic.custom_len = FF_CUSTOM_DATA_LEN,
  244. };
  245. // Bypass the waveform update due to different input name
  246. if ((strstr(inputEventName, "cs40l26") != nullptr) ||
  247. (strstr(inputEventName, "cs40l26_dual_input") != nullptr)) {
  248. if (!mHwApi->setFFEffect(
  249. mInputFd, &mFfEffects[effectIndex],
  250. static_cast<uint16_t>(mFfEffects[effectIndex].replay.length))) {
  251. ALOGE("Failed upload effect %d (%d): %s", effectIndex, errno, strerror(errno));
  252. }
  253. }
  254. if (mFfEffects[effectIndex].id != effectIndex) {
  255. ALOGW("Unexpected effect index: %d -> %d", effectIndex, mFfEffects[effectIndex].id);
  256. }
  257. } else {
  258. /* Initiate placeholders for OWT effects. */
  259. mFfEffects[effectIndex] = {
  260. .type = FF_PERIODIC,
  261. .id = -1,
  262. .replay.length = 0,
  263. .u.periodic.waveform = FF_CUSTOM,
  264. .u.periodic.custom_data = nullptr,
  265. .u.periodic.custom_len = 0,
  266. };
  267. }
  268. }
  269. if (mHwCal->getF0(&caldata)) {
  270. mHwApi->setF0(caldata);
  271. }
  272. if (mHwCal->getRedc(&caldata)) {
  273. mHwApi->setRedc(caldata);
  274. }
  275. if (mHwCal->getQ(&caldata)) {
  276. mHwApi->setQ(caldata);
  277. }
  278. mHwCal->getLongFrequencyShift(&longFrequencyShift);
  279. if (longFrequencyShift > 0) {
  280. mF0Offset = longFrequencyShift * std::pow(2, 14);
  281. } else if (longFrequencyShift < 0) {
  282. mF0Offset = std::pow(2, 24) - std::abs(longFrequencyShift) * std::pow(2, 14);
  283. } else {
  284. mF0Offset = 0;
  285. }
  286. mHwCal->getVersion(&calVer);
  287. if (calVer == 2) {
  288. mHwCal->getTickVolLevels(&mTickEffectVol);
  289. mHwCal->getClickVolLevels(&mClickEffectVol);
  290. mHwCal->getLongVolLevels(&mLongEffectVol);
  291. } else {
  292. ALOGD("Unsupported calibration version: %u!", calVer);
  293. }
  294. mHwApi->setF0CompEnable(mHwCal->isF0CompEnabled());
  295. mHwApi->setRedcCompEnable(mHwCal->isRedcCompEnabled());
  296. mIsUnderExternalControl = false;
  297. mIsChirpEnabled = mHwCal->isChirpEnabled();
  298. mHwCal->getSupportedPrimitives(&mSupportedPrimitivesBits);
  299. if (mSupportedPrimitivesBits > 0) {
  300. for (auto e : defaultSupportedPrimitives) {
  301. if (mSupportedPrimitivesBits & (1 << uint32_t(e))) {
  302. mSupportedPrimitives.emplace_back(e);
  303. }
  304. }
  305. } else {
  306. for (auto e : defaultSupportedPrimitives) {
  307. mSupportedPrimitivesBits |= (1 << uint32_t(e));
  308. }
  309. mSupportedPrimitives = defaultSupportedPrimitives;
  310. }
  311. mHwApi->setMinOnOffInterval(MIN_ON_OFF_INTERVAL_US);
  312. }
  313. ndk::ScopedAStatus Vibrator::getCapabilities(int32_t *_aidl_return) {
  314. ATRACE_NAME("Vibrator::getCapabilities");
  315. int32_t ret = IVibrator::CAP_ON_CALLBACK | IVibrator::CAP_PERFORM_CALLBACK |
  316. IVibrator::CAP_AMPLITUDE_CONTROL | IVibrator::CAP_GET_RESONANT_FREQUENCY |
  317. IVibrator::CAP_GET_Q_FACTOR;
  318. if (hasHapticAlsaDevice()) {
  319. ret |= IVibrator::CAP_EXTERNAL_CONTROL;
  320. } else {
  321. ALOGE("No haptics ALSA device");
  322. }
  323. if (mHwApi->hasOwtFreeSpace()) {
  324. ret |= IVibrator::CAP_COMPOSE_EFFECTS;
  325. if (mIsChirpEnabled) {
  326. ret |= IVibrator::CAP_FREQUENCY_CONTROL | IVibrator::CAP_COMPOSE_PWLE_EFFECTS;
  327. }
  328. }
  329. *_aidl_return = ret;
  330. return ndk::ScopedAStatus::ok();
  331. }
  332. ndk::ScopedAStatus Vibrator::off() {
  333. ATRACE_NAME("Vibrator::off");
  334. bool ret{true};
  335. const std::scoped_lock<std::mutex> lock(mActiveId_mutex);
  336. if (mActiveId >= 0) {
  337. /* Stop the active effect. */
  338. if (!mHwApi->setFFPlay(mInputFd, mActiveId, false)) {
  339. ALOGE("Failed to stop effect %d (%d): %s", mActiveId, errno, strerror(errno));
  340. ret = false;
  341. }
  342. if ((mActiveId >= WAVEFORM_MAX_PHYSICAL_INDEX) &&
  343. (!mHwApi->eraseOwtEffect(mInputFd, mActiveId, &mFfEffects))) {
  344. ALOGE("Failed to clean up the composed effect %d", mActiveId);
  345. ret = false;
  346. }
  347. } else {
  348. ALOGV("Vibrator is already off");
  349. }
  350. mActiveId = -1;
  351. setGlobalAmplitude(false);
  352. if (mF0Offset) {
  353. mHwApi->setF0Offset(0);
  354. }
  355. if (ret) {
  356. return ndk::ScopedAStatus::ok();
  357. } else {
  358. return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
  359. }
  360. }
  361. ndk::ScopedAStatus Vibrator::on(int32_t timeoutMs,
  362. const std::shared_ptr<IVibratorCallback> &callback) {
  363. ATRACE_NAME("Vibrator::on");
  364. if (timeoutMs > MAX_TIME_MS) {
  365. return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
  366. }
  367. const uint16_t index = (timeoutMs < WAVEFORM_LONG_VIBRATION_THRESHOLD_MS)
  368. ? WAVEFORM_SHORT_VIBRATION_EFFECT_INDEX
  369. : WAVEFORM_LONG_VIBRATION_EFFECT_INDEX;
  370. if (MAX_COLD_START_LATENCY_MS <= MAX_TIME_MS - timeoutMs) {
  371. timeoutMs += MAX_COLD_START_LATENCY_MS;
  372. }
  373. setGlobalAmplitude(true);
  374. if (mF0Offset) {
  375. mHwApi->setF0Offset(mF0Offset);
  376. }
  377. return on(timeoutMs, index, nullptr /*ignored*/, callback);
  378. }
  379. ndk::ScopedAStatus Vibrator::perform(Effect effect, EffectStrength strength,
  380. const std::shared_ptr<IVibratorCallback> &callback,
  381. int32_t *_aidl_return) {
  382. ATRACE_NAME("Vibrator::perform");
  383. return performEffect(effect, strength, callback, _aidl_return);
  384. }
  385. ndk::ScopedAStatus Vibrator::getSupportedEffects(std::vector<Effect> *_aidl_return) {
  386. *_aidl_return = {Effect::TEXTURE_TICK, Effect::TICK, Effect::CLICK, Effect::HEAVY_CLICK,
  387. Effect::DOUBLE_CLICK};
  388. return ndk::ScopedAStatus::ok();
  389. }
  390. ndk::ScopedAStatus Vibrator::setAmplitude(float amplitude) {
  391. ATRACE_NAME("Vibrator::setAmplitude");
  392. if (amplitude <= 0.0f || amplitude > 1.0f) {
  393. return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
  394. }
  395. mLongEffectScale = amplitude;
  396. if (!isUnderExternalControl()) {
  397. return setGlobalAmplitude(true);
  398. } else {
  399. return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
  400. }
  401. }
  402. ndk::ScopedAStatus Vibrator::setExternalControl(bool enabled) {
  403. ATRACE_NAME("Vibrator::setExternalControl");
  404. setGlobalAmplitude(enabled);
  405. if (mHasHapticAlsaDevice || mConfigHapticAlsaDeviceDone || hasHapticAlsaDevice()) {
  406. if (!mHwApi->setHapticPcmAmp(&mHapticPcm, enabled, mCard, mDevice)) {
  407. ALOGE("Failed to %s haptic pcm device: %d", (enabled ? "enable" : "disable"), mDevice);
  408. return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
  409. }
  410. } else {
  411. ALOGE("No haptics ALSA device");
  412. return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
  413. }
  414. mIsUnderExternalControl = enabled;
  415. return ndk::ScopedAStatus::ok();
  416. }
  417. ndk::ScopedAStatus Vibrator::getCompositionDelayMax(int32_t *maxDelayMs) {
  418. ATRACE_NAME("Vibrator::getCompositionDelayMax");
  419. *maxDelayMs = COMPOSE_DELAY_MAX_MS;
  420. return ndk::ScopedAStatus::ok();
  421. }
  422. ndk::ScopedAStatus Vibrator::getCompositionSizeMax(int32_t *maxSize) {
  423. ATRACE_NAME("Vibrator::getCompositionSizeMax");
  424. *maxSize = COMPOSE_SIZE_MAX;
  425. return ndk::ScopedAStatus::ok();
  426. }
  427. ndk::ScopedAStatus Vibrator::getSupportedPrimitives(std::vector<CompositePrimitive> *supported) {
  428. *supported = mSupportedPrimitives;
  429. return ndk::ScopedAStatus::ok();
  430. }
  431. ndk::ScopedAStatus Vibrator::getPrimitiveDuration(CompositePrimitive primitive,
  432. int32_t *durationMs) {
  433. ndk::ScopedAStatus status;
  434. uint32_t effectIndex;
  435. if (primitive != CompositePrimitive::NOOP) {
  436. status = getPrimitiveDetails(primitive, &effectIndex);
  437. if (!status.isOk()) {
  438. return status;
  439. }
  440. *durationMs = mEffectDurations[effectIndex];
  441. } else {
  442. *durationMs = 0;
  443. }
  444. return ndk::ScopedAStatus::ok();
  445. }
  446. ndk::ScopedAStatus Vibrator::compose(const std::vector<CompositeEffect> &composite,
  447. const std::shared_ptr<IVibratorCallback> &callback) {
  448. ATRACE_NAME("Vibrator::compose");
  449. uint16_t size;
  450. uint16_t nextEffectDelay;
  451. auto ch = dspmem_chunk_create(new uint8_t[FF_CUSTOM_DATA_LEN_MAX_COMP]{0x00},
  452. FF_CUSTOM_DATA_LEN_MAX_COMP);
  453. if (composite.size() > COMPOSE_SIZE_MAX || composite.empty()) {
  454. return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
  455. }
  456. /* Check if there is a wait before the first effect. */
  457. nextEffectDelay = composite.front().delayMs;
  458. if (nextEffectDelay > COMPOSE_DELAY_MAX_MS || nextEffectDelay < 0) {
  459. return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
  460. } else if (nextEffectDelay > 0) {
  461. size = composite.size() + 1;
  462. } else {
  463. size = composite.size();
  464. }
  465. dspmem_chunk_write(ch, 8, 0); /* Padding */
  466. dspmem_chunk_write(ch, 8, (uint8_t)(0xFF & size)); /* nsections */
  467. dspmem_chunk_write(ch, 8, 0); /* repeat */
  468. uint8_t header_count = dspmem_chunk_bytes(ch);
  469. /* Insert 1 section for a wait before the first effect. */
  470. if (nextEffectDelay) {
  471. dspmem_chunk_write(ch, 32, 0); /* amplitude, index, repeat & flags */
  472. dspmem_chunk_write(ch, 16, (uint16_t)(0xFFFF & nextEffectDelay)); /* delay */
  473. }
  474. for (uint32_t i_curr = 0, i_next = 1; i_curr < composite.size(); i_curr++, i_next++) {
  475. auto &e_curr = composite[i_curr];
  476. uint32_t effectIndex = 0;
  477. uint32_t effectVolLevel = 0;
  478. if (e_curr.scale < 0.0f || e_curr.scale > 1.0f) {
  479. return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
  480. }
  481. if (e_curr.primitive != CompositePrimitive::NOOP) {
  482. ndk::ScopedAStatus status;
  483. status = getPrimitiveDetails(e_curr.primitive, &effectIndex);
  484. if (!status.isOk()) {
  485. return status;
  486. }
  487. effectVolLevel = intensityToVolLevel(e_curr.scale, effectIndex);
  488. }
  489. /* Fetch the next composite effect delay and fill into the current section */
  490. nextEffectDelay = 0;
  491. if (i_next < composite.size()) {
  492. auto &e_next = composite[i_next];
  493. int32_t delay = e_next.delayMs;
  494. if (delay > COMPOSE_DELAY_MAX_MS || delay < 0) {
  495. return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
  496. }
  497. nextEffectDelay = delay;
  498. }
  499. if (effectIndex == 0 && nextEffectDelay == 0) {
  500. return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
  501. }
  502. dspmem_chunk_write(ch, 8, (uint8_t)(0xFF & effectVolLevel)); /* amplitude */
  503. dspmem_chunk_write(ch, 8, (uint8_t)(0xFF & effectIndex)); /* index */
  504. dspmem_chunk_write(ch, 8, 0); /* repeat */
  505. dspmem_chunk_write(ch, 8, 0); /* flags */
  506. dspmem_chunk_write(ch, 16, (uint16_t)(0xFFFF & nextEffectDelay)); /* delay */
  507. }
  508. dspmem_chunk_flush(ch);
  509. if (header_count == dspmem_chunk_bytes(ch)) {
  510. return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
  511. } else {
  512. return performEffect(WAVEFORM_MAX_INDEX /*ignored*/, VOLTAGE_SCALE_MAX /*ignored*/, ch,
  513. callback);
  514. }
  515. }
  516. ndk::ScopedAStatus Vibrator::on(uint32_t timeoutMs, uint32_t effectIndex, dspmem_chunk *ch,
  517. const std::shared_ptr<IVibratorCallback> &callback) {
  518. ndk::ScopedAStatus status = ndk::ScopedAStatus::ok();
  519. if (effectIndex >= FF_MAX_EFFECTS) {
  520. ALOGE("Invalid waveform index %d", effectIndex);
  521. return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
  522. }
  523. if (mAsyncHandle.wait_for(ASYNC_COMPLETION_TIMEOUT) != std::future_status::ready) {
  524. ALOGE("Previous vibration pending: prev: %d, curr: %d", mActiveId, effectIndex);
  525. return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
  526. }
  527. if (ch) {
  528. /* Upload OWT effect. */
  529. if (ch->head == nullptr) {
  530. ALOGE("Invalid OWT bank");
  531. delete ch;
  532. return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
  533. }
  534. bool isPwle = (*reinterpret_cast<uint16_t *>(ch->head) != 0x0000);
  535. effectIndex = isPwle ? WAVEFORM_PWLE : WAVEFORM_COMPOSE;
  536. uint32_t freeBytes;
  537. mHwApi->getOwtFreeSpace(&freeBytes);
  538. if (dspmem_chunk_bytes(ch) > freeBytes) {
  539. ALOGE("Invalid OWT length: Effect %d: %d > %d!", effectIndex, dspmem_chunk_bytes(ch),
  540. freeBytes);
  541. delete ch;
  542. return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
  543. }
  544. int errorStatus;
  545. if (!mHwApi->uploadOwtEffect(mInputFd, ch->head, dspmem_chunk_bytes(ch),
  546. &mFfEffects[effectIndex], &effectIndex, &errorStatus)) {
  547. delete ch;
  548. ALOGE("Invalid uploadOwtEffect");
  549. return ndk::ScopedAStatus::fromExceptionCode(errorStatus);
  550. }
  551. delete ch;
  552. } else if (effectIndex == WAVEFORM_SHORT_VIBRATION_EFFECT_INDEX ||
  553. effectIndex == WAVEFORM_LONG_VIBRATION_EFFECT_INDEX) {
  554. /* Update duration for long/short vibration. */
  555. mFfEffects[effectIndex].replay.length = static_cast<uint16_t>(timeoutMs);
  556. if (!mHwApi->setFFEffect(mInputFd, &mFfEffects[effectIndex],
  557. static_cast<uint16_t>(timeoutMs))) {
  558. ALOGE("Failed to edit effect %d (%d): %s", effectIndex, errno, strerror(errno));
  559. return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
  560. }
  561. }
  562. const std::scoped_lock<std::mutex> lock(mActiveId_mutex);
  563. mActiveId = effectIndex;
  564. /* Play the event now. */
  565. if (!mHwApi->setFFPlay(mInputFd, effectIndex, true)) {
  566. ALOGE("Failed to play effect %d (%d): %s", effectIndex, errno, strerror(errno));
  567. return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
  568. }
  569. mAsyncHandle = std::async(&Vibrator::waitForComplete, this, callback);
  570. return ndk::ScopedAStatus::ok();
  571. }
  572. ndk::ScopedAStatus Vibrator::setEffectAmplitude(float amplitude, float maximum) {
  573. uint16_t scale = amplitudeToScale(amplitude, maximum);
  574. if (!mHwApi->setFFGain(mInputFd, scale)) {
  575. ALOGE("Failed to set the gain to %u (%d): %s", scale, errno, strerror(errno));
  576. return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
  577. }
  578. return ndk::ScopedAStatus::ok();
  579. }
  580. ndk::ScopedAStatus Vibrator::setGlobalAmplitude(bool set) {
  581. uint8_t amplitude = set ? roundf(mLongEffectScale * mLongEffectVol[1]) : VOLTAGE_SCALE_MAX;
  582. if (!set) {
  583. mLongEffectScale = 1.0; // Reset the scale for the later new effect.
  584. }
  585. return setEffectAmplitude(amplitude, VOLTAGE_SCALE_MAX);
  586. }
  587. ndk::ScopedAStatus Vibrator::getSupportedAlwaysOnEffects(std::vector<Effect> * /*_aidl_return*/) {
  588. return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
  589. }
  590. ndk::ScopedAStatus Vibrator::alwaysOnEnable(int32_t /*id*/, Effect /*effect*/,
  591. EffectStrength /*strength*/) {
  592. return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
  593. }
  594. ndk::ScopedAStatus Vibrator::alwaysOnDisable(int32_t /*id*/) {
  595. return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
  596. }
  597. ndk::ScopedAStatus Vibrator::getResonantFrequency(float *resonantFreqHz) {
  598. std::string caldata{8, '0'};
  599. if (!mHwCal->getF0(&caldata)) {
  600. ALOGE("Failed to get resonant frequency (%d): %s", errno, strerror(errno));
  601. return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
  602. }
  603. *resonantFreqHz = static_cast<float>(std::stoul(caldata, nullptr, 16)) / (1 << Q14_BIT_SHIFT);
  604. return ndk::ScopedAStatus::ok();
  605. }
  606. ndk::ScopedAStatus Vibrator::getQFactor(float *qFactor) {
  607. std::string caldata{8, '0'};
  608. if (!mHwCal->getQ(&caldata)) {
  609. ALOGE("Failed to get q factor (%d): %s", errno, strerror(errno));
  610. return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
  611. }
  612. *qFactor = static_cast<float>(std::stoul(caldata, nullptr, 16)) / (1 << Q16_BIT_SHIFT);
  613. return ndk::ScopedAStatus::ok();
  614. }
  615. ndk::ScopedAStatus Vibrator::getFrequencyResolution(float *freqResolutionHz) {
  616. int32_t capabilities;
  617. Vibrator::getCapabilities(&capabilities);
  618. if (capabilities & IVibrator::CAP_FREQUENCY_CONTROL) {
  619. *freqResolutionHz = PWLE_FREQUENCY_RESOLUTION_HZ;
  620. return ndk::ScopedAStatus::ok();
  621. } else {
  622. return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
  623. }
  624. }
  625. ndk::ScopedAStatus Vibrator::getFrequencyMinimum(float *freqMinimumHz) {
  626. int32_t capabilities;
  627. Vibrator::getCapabilities(&capabilities);
  628. if (capabilities & IVibrator::CAP_FREQUENCY_CONTROL) {
  629. *freqMinimumHz = PWLE_FREQUENCY_MIN_HZ;
  630. return ndk::ScopedAStatus::ok();
  631. } else {
  632. return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
  633. }
  634. }
  635. ndk::ScopedAStatus Vibrator::getBandwidthAmplitudeMap(std::vector<float> *_aidl_return) {
  636. // TODO(b/170919640): complete implementation
  637. int32_t capabilities;
  638. Vibrator::getCapabilities(&capabilities);
  639. if (capabilities & IVibrator::CAP_FREQUENCY_CONTROL) {
  640. std::vector<float> bandwidthAmplitudeMap(PWLE_BW_MAP_SIZE, 1.0);
  641. *_aidl_return = bandwidthAmplitudeMap;
  642. return ndk::ScopedAStatus::ok();
  643. } else {
  644. return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
  645. }
  646. }
  647. ndk::ScopedAStatus Vibrator::getPwlePrimitiveDurationMax(int32_t *durationMs) {
  648. int32_t capabilities;
  649. Vibrator::getCapabilities(&capabilities);
  650. if (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS) {
  651. *durationMs = COMPOSE_PWLE_PRIMITIVE_DURATION_MAX_MS;
  652. return ndk::ScopedAStatus::ok();
  653. } else {
  654. return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
  655. }
  656. }
  657. ndk::ScopedAStatus Vibrator::getPwleCompositionSizeMax(int32_t *maxSize) {
  658. int32_t capabilities;
  659. Vibrator::getCapabilities(&capabilities);
  660. if (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS) {
  661. *maxSize = COMPOSE_PWLE_SIZE_MAX_DEFAULT;
  662. return ndk::ScopedAStatus::ok();
  663. } else {
  664. return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
  665. }
  666. }
  667. ndk::ScopedAStatus Vibrator::getSupportedBraking(std::vector<Braking> *supported) {
  668. int32_t capabilities;
  669. Vibrator::getCapabilities(&capabilities);
  670. if (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS) {
  671. *supported = {
  672. Braking::NONE,
  673. };
  674. return ndk::ScopedAStatus::ok();
  675. } else {
  676. return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
  677. }
  678. }
  679. static void resetPreviousEndAmplitudeEndFrequency(float *prevEndAmplitude,
  680. float *prevEndFrequency) {
  681. const float reset = -1.0;
  682. *prevEndAmplitude = reset;
  683. *prevEndFrequency = reset;
  684. }
  685. static void incrementIndex(int *index) {
  686. *index += 1;
  687. }
  688. static void constructPwleSegment(dspmem_chunk *ch, uint16_t delay, uint16_t amplitude,
  689. uint16_t frequency, uint8_t flags, uint32_t vbemfTarget = 0) {
  690. dspmem_chunk_write(ch, 16, delay);
  691. dspmem_chunk_write(ch, 12, amplitude);
  692. dspmem_chunk_write(ch, 12, frequency);
  693. /* feature flags to control the chirp, CLAB braking, back EMF amplitude regulation */
  694. dspmem_chunk_write(ch, 8, (flags | 1) << 4);
  695. if (flags & PWLE_AMP_REG_BIT) {
  696. dspmem_chunk_write(ch, 24, vbemfTarget); /* target back EMF voltage */
  697. }
  698. }
  699. static int constructActiveSegment(dspmem_chunk *ch, int duration, float amplitude, float frequency,
  700. bool chirp) {
  701. uint16_t delay = 0;
  702. uint16_t amp = 0;
  703. uint16_t freq = 0;
  704. uint8_t flags = 0x0;
  705. if ((floatToUint16(duration, &delay, 4, 0.0f, COMPOSE_PWLE_PRIMITIVE_DURATION_MAX_MS) < 0) ||
  706. (floatToUint16(amplitude, &amp, 2048, CS40L26_PWLE_LEVEL_MIX, CS40L26_PWLE_LEVEL_MAX) <
  707. 0) ||
  708. (floatToUint16(frequency, &freq, 4, PWLE_FREQUENCY_MIN_HZ, PWLE_FREQUENCY_MAX_HZ) < 0)) {
  709. ALOGE("Invalid argument: %d, %f, %f", duration, amplitude, frequency);
  710. return -ERANGE;
  711. }
  712. if (chirp) {
  713. flags |= PWLE_CHIRP_BIT;
  714. }
  715. constructPwleSegment(ch, delay, amp, freq, flags, 0 /*ignored*/);
  716. return 0;
  717. }
  718. static int constructBrakingSegment(dspmem_chunk *ch, int duration, Braking brakingType) {
  719. uint16_t delay = 0;
  720. uint16_t freq = 0;
  721. uint8_t flags = 0x00;
  722. if (floatToUint16(duration, &delay, 4, 0.0f, COMPOSE_PWLE_PRIMITIVE_DURATION_MAX_MS) < 0) {
  723. ALOGE("Invalid argument: %d", duration);
  724. return -ERANGE;
  725. }
  726. floatToUint16(PWLE_FREQUENCY_MIN_HZ, &freq, 4, PWLE_FREQUENCY_MIN_HZ, PWLE_FREQUENCY_MAX_HZ);
  727. if (static_cast<std::underlying_type<Braking>::type>(brakingType)) {
  728. flags |= PWLE_BRAKE_BIT;
  729. }
  730. constructPwleSegment(ch, delay, 0 /*ignored*/, freq, flags, 0 /*ignored*/);
  731. return 0;
  732. }
  733. static void updateWLength(dspmem_chunk *ch, uint32_t totalDuration) {
  734. totalDuration *= 8; /* Unit: 0.125 ms (since wlength played @ 8kHz). */
  735. totalDuration |= WT_LEN_CALCD; /* Bit 23 is for WT_LEN_CALCD; Bit 22 is for WT_INDEFINITE. */
  736. *(ch->head + 0) = (totalDuration >> 24) & 0xFF;
  737. *(ch->head + 1) = (totalDuration >> 16) & 0xFF;
  738. *(ch->head + 2) = (totalDuration >> 8) & 0xFF;
  739. *(ch->head + 3) = totalDuration & 0xFF;
  740. }
  741. static void updateNSection(dspmem_chunk *ch, int segmentIdx) {
  742. *(ch->head + 7) |= (0xF0 & segmentIdx) >> 4; /* Bit 4 to 7 */
  743. *(ch->head + 9) |= (0x0F & segmentIdx) << 4; /* Bit 3 to 0 */
  744. }
  745. ndk::ScopedAStatus Vibrator::composePwle(const std::vector<PrimitivePwle> &composite,
  746. const std::shared_ptr<IVibratorCallback> &callback) {
  747. ATRACE_NAME("Vibrator::composePwle");
  748. int32_t capabilities;
  749. Vibrator::getCapabilities(&capabilities);
  750. if ((capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS) == 0) {
  751. return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
  752. }
  753. if (composite.empty() || composite.size() > COMPOSE_PWLE_SIZE_MAX_DEFAULT) {
  754. return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
  755. }
  756. std::vector<Braking> supported;
  757. Vibrator::getSupportedBraking(&supported);
  758. bool isClabSupported =
  759. std::find(supported.begin(), supported.end(), Braking::CLAB) != supported.end();
  760. int segmentIdx = 0;
  761. uint32_t totalDuration = 0;
  762. float prevEndAmplitude;
  763. float prevEndFrequency;
  764. resetPreviousEndAmplitudeEndFrequency(&prevEndAmplitude, &prevEndFrequency);
  765. auto ch = dspmem_chunk_create(new uint8_t[FF_CUSTOM_DATA_LEN_MAX_PWLE]{0x00},
  766. FF_CUSTOM_DATA_LEN_MAX_PWLE);
  767. bool chirp = false;
  768. dspmem_chunk_write(ch, 24, 0x000000); /* Waveform length placeholder */
  769. dspmem_chunk_write(ch, 8, 0); /* Repeat */
  770. dspmem_chunk_write(ch, 12, 0); /* Wait time between repeats */
  771. dspmem_chunk_write(ch, 8, 0x00); /* nsections placeholder */
  772. for (auto &e : composite) {
  773. switch (e.getTag()) {
  774. case PrimitivePwle::active: {
  775. auto active = e.get<PrimitivePwle::active>();
  776. if (active.duration < 0 ||
  777. active.duration > COMPOSE_PWLE_PRIMITIVE_DURATION_MAX_MS) {
  778. return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
  779. }
  780. if (active.startAmplitude < PWLE_LEVEL_MIN ||
  781. active.startAmplitude > PWLE_LEVEL_MAX ||
  782. active.endAmplitude < PWLE_LEVEL_MIN || active.endAmplitude > PWLE_LEVEL_MAX) {
  783. return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
  784. }
  785. if (active.startAmplitude > CS40L26_PWLE_LEVEL_MAX) {
  786. active.startAmplitude = CS40L26_PWLE_LEVEL_MAX;
  787. }
  788. if (active.endAmplitude > CS40L26_PWLE_LEVEL_MAX) {
  789. active.endAmplitude = CS40L26_PWLE_LEVEL_MAX;
  790. }
  791. if (active.startFrequency < PWLE_FREQUENCY_MIN_HZ ||
  792. active.startFrequency > PWLE_FREQUENCY_MAX_HZ ||
  793. active.endFrequency < PWLE_FREQUENCY_MIN_HZ ||
  794. active.endFrequency > PWLE_FREQUENCY_MAX_HZ) {
  795. return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
  796. }
  797. if (!((active.startAmplitude == prevEndAmplitude) &&
  798. (active.startFrequency == prevEndFrequency))) {
  799. if (constructActiveSegment(ch, 0, active.startAmplitude, active.startFrequency,
  800. false) < 0) {
  801. return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
  802. }
  803. incrementIndex(&segmentIdx);
  804. }
  805. if (active.startFrequency != active.endFrequency) {
  806. chirp = true;
  807. }
  808. if (constructActiveSegment(ch, active.duration, active.endAmplitude,
  809. active.endFrequency, chirp) < 0) {
  810. return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
  811. }
  812. incrementIndex(&segmentIdx);
  813. prevEndAmplitude = active.endAmplitude;
  814. prevEndFrequency = active.endFrequency;
  815. totalDuration += active.duration;
  816. chirp = false;
  817. break;
  818. }
  819. case PrimitivePwle::braking: {
  820. auto braking = e.get<PrimitivePwle::braking>();
  821. if (braking.braking > Braking::CLAB) {
  822. return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
  823. } else if (!isClabSupported && (braking.braking == Braking::CLAB)) {
  824. return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
  825. }
  826. if (braking.duration > COMPOSE_PWLE_PRIMITIVE_DURATION_MAX_MS) {
  827. return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
  828. }
  829. if (constructBrakingSegment(ch, 0, braking.braking) < 0) {
  830. return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
  831. }
  832. incrementIndex(&segmentIdx);
  833. if (constructBrakingSegment(ch, braking.duration, braking.braking) < 0) {
  834. return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
  835. }
  836. incrementIndex(&segmentIdx);
  837. resetPreviousEndAmplitudeEndFrequency(&prevEndAmplitude, &prevEndFrequency);
  838. totalDuration += braking.duration;
  839. break;
  840. }
  841. }
  842. if (segmentIdx > COMPOSE_PWLE_SIZE_MAX_DEFAULT) {
  843. ALOGE("Too many PrimitivePwle section!");
  844. return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
  845. }
  846. }
  847. dspmem_chunk_flush(ch);
  848. /* Update wlength */
  849. totalDuration += MAX_COLD_START_LATENCY_MS;
  850. if (totalDuration > 0x7FFFF) {
  851. ALOGE("Total duration is too long (%d)!", totalDuration);
  852. return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
  853. }
  854. updateWLength(ch, totalDuration);
  855. /* Update nsections */
  856. updateNSection(ch, segmentIdx);
  857. return performEffect(WAVEFORM_MAX_INDEX /*ignored*/, VOLTAGE_SCALE_MAX /*ignored*/, ch,
  858. callback);
  859. }
  860. bool Vibrator::isUnderExternalControl() {
  861. return mIsUnderExternalControl;
  862. }
  863. binder_status_t Vibrator::dump(int fd, const char **args, uint32_t numArgs) {
  864. if (fd < 0) {
  865. ALOGE("Called debug() with invalid fd.");
  866. return STATUS_OK;
  867. }
  868. (void)args;
  869. (void)numArgs;
  870. dprintf(fd, "AIDL:\n");
  871. dprintf(fd, " F0 Offset: %" PRIu32 "\n", mF0Offset);
  872. dprintf(fd, " Voltage Levels:\n");
  873. dprintf(fd, " Tick Effect Min: %" PRIu32 " Max: %" PRIu32 "\n", mTickEffectVol[0],
  874. mTickEffectVol[1]);
  875. dprintf(fd, " Click Effect Min: %" PRIu32 " Max: %" PRIu32 "\n", mClickEffectVol[0],
  876. mClickEffectVol[1]);
  877. dprintf(fd, " Long Effect Min: %" PRIu32 " Max: %" PRIu32 "\n", mLongEffectVol[0],
  878. mLongEffectVol[1]);
  879. dprintf(fd, " FF effect:\n");
  880. dprintf(fd, " Physical waveform:\n");
  881. dprintf(fd, "\tId\tIndex\tt ->\tt'\n");
  882. for (uint8_t effectId = 0; effectId < WAVEFORM_MAX_PHYSICAL_INDEX; effectId++) {
  883. dprintf(fd, "\t%d\t%d\t%d\t%d\n", mFfEffects[effectId].id,
  884. mFfEffects[effectId].u.periodic.custom_data[1], mEffectDurations[effectId],
  885. mFfEffects[effectId].replay.length);
  886. }
  887. dprintf(fd, " OWT waveform:\n");
  888. dprintf(fd, "\tId\tBytes\tData\n");
  889. for (uint8_t effectId = WAVEFORM_MAX_PHYSICAL_INDEX; effectId < WAVEFORM_MAX_INDEX;
  890. effectId++) {
  891. uint32_t numBytes = mFfEffects[effectId].u.periodic.custom_len * 2;
  892. std::stringstream ss;
  893. ss << " ";
  894. for (int i = 0; i < numBytes; i++) {
  895. ss << std::uppercase << std::setfill('0') << std::setw(2) << std::hex
  896. << (uint16_t)(*(
  897. reinterpret_cast<uint8_t *>(mFfEffects[effectId].u.periodic.custom_data) +
  898. i))
  899. << " ";
  900. }
  901. dprintf(fd, "\t%d\t%d\t{%s}\n", mFfEffects[effectId].id, numBytes, ss.str().c_str());
  902. }
  903. dprintf(fd, "\n");
  904. dprintf(fd, "\n");
  905. mHwApi->debug(fd);
  906. dprintf(fd, "\n");
  907. mHwCal->debug(fd);
  908. fsync(fd);
  909. return STATUS_OK;
  910. }
  911. bool Vibrator::hasHapticAlsaDevice() {
  912. // We need to call findHapticAlsaDevice once only. Calling in the
  913. // constructor is too early in the boot process and the pcm file contents
  914. // are empty. Hence we make the call here once only right before we need to.
  915. if (!mConfigHapticAlsaDeviceDone) {
  916. if (mHwApi->getHapticAlsaDevice(&mCard, &mDevice)) {
  917. mHasHapticAlsaDevice = true;
  918. mConfigHapticAlsaDeviceDone = true;
  919. } else {
  920. ALOGE("Haptic ALSA device not supported");
  921. }
  922. } else {
  923. ALOGD("Haptic ALSA device configuration done.");
  924. }
  925. return mHasHapticAlsaDevice;
  926. }
  927. ndk::ScopedAStatus Vibrator::getSimpleDetails(Effect effect, EffectStrength strength,
  928. uint32_t *outEffectIndex, uint32_t *outTimeMs,
  929. uint32_t *outVolLevel) {
  930. uint32_t effectIndex;
  931. uint32_t timeMs;
  932. float intensity;
  933. uint32_t volLevel;
  934. switch (strength) {
  935. case EffectStrength::LIGHT:
  936. intensity = 0.5f;
  937. break;
  938. case EffectStrength::MEDIUM:
  939. intensity = 0.7f;
  940. break;
  941. case EffectStrength::STRONG:
  942. intensity = 1.0f;
  943. break;
  944. default:
  945. return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
  946. }
  947. switch (effect) {
  948. case Effect::TEXTURE_TICK:
  949. effectIndex = WAVEFORM_LIGHT_TICK_INDEX;
  950. intensity *= 0.5f;
  951. break;
  952. case Effect::TICK:
  953. effectIndex = WAVEFORM_CLICK_INDEX;
  954. intensity *= 0.5f;
  955. break;
  956. case Effect::CLICK:
  957. effectIndex = WAVEFORM_CLICK_INDEX;
  958. intensity *= 0.7f;
  959. break;
  960. case Effect::HEAVY_CLICK:
  961. effectIndex = WAVEFORM_CLICK_INDEX;
  962. intensity *= 1.0f;
  963. break;
  964. default:
  965. return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
  966. }
  967. volLevel = intensityToVolLevel(intensity, effectIndex);
  968. timeMs = mEffectDurations[effectIndex] + MAX_COLD_START_LATENCY_MS;
  969. *outEffectIndex = effectIndex;
  970. *outTimeMs = timeMs;
  971. *outVolLevel = volLevel;
  972. return ndk::ScopedAStatus::ok();
  973. }
  974. ndk::ScopedAStatus Vibrator::getCompoundDetails(Effect effect, EffectStrength strength,
  975. uint32_t *outTimeMs, dspmem_chunk *outCh) {
  976. ndk::ScopedAStatus status;
  977. uint32_t timeMs = 0;
  978. uint32_t thisEffectIndex;
  979. uint32_t thisTimeMs;
  980. uint32_t thisVolLevel;
  981. switch (effect) {
  982. case Effect::DOUBLE_CLICK:
  983. dspmem_chunk_write(outCh, 8, 0); /* Padding */
  984. dspmem_chunk_write(outCh, 8, 2); /* nsections */
  985. dspmem_chunk_write(outCh, 8, 0); /* repeat */
  986. status = getSimpleDetails(Effect::CLICK, strength, &thisEffectIndex, &thisTimeMs,
  987. &thisVolLevel);
  988. if (!status.isOk()) {
  989. return status;
  990. }
  991. timeMs += thisTimeMs;
  992. dspmem_chunk_write(outCh, 8, (uint8_t)(0xFF & thisVolLevel)); /* amplitude */
  993. dspmem_chunk_write(outCh, 8, (uint8_t)(0xFF & thisEffectIndex)); /* index */
  994. dspmem_chunk_write(outCh, 8, 0); /* repeat */
  995. dspmem_chunk_write(outCh, 8, 0); /* flags */
  996. dspmem_chunk_write(outCh, 16,
  997. (uint16_t)(0xFFFF & WAVEFORM_DOUBLE_CLICK_SILENCE_MS)); /* delay */
  998. timeMs += WAVEFORM_DOUBLE_CLICK_SILENCE_MS + MAX_PAUSE_TIMING_ERROR_MS;
  999. status = getSimpleDetails(Effect::HEAVY_CLICK, strength, &thisEffectIndex, &thisTimeMs,
  1000. &thisVolLevel);
  1001. if (!status.isOk()) {
  1002. return status;
  1003. }
  1004. timeMs += thisTimeMs;
  1005. dspmem_chunk_write(outCh, 8, (uint8_t)(0xFF & thisVolLevel)); /* amplitude */
  1006. dspmem_chunk_write(outCh, 8, (uint8_t)(0xFF & thisEffectIndex)); /* index */
  1007. dspmem_chunk_write(outCh, 8, 0); /* repeat */
  1008. dspmem_chunk_write(outCh, 8, 0); /* flags */
  1009. dspmem_chunk_write(outCh, 16, 0); /* delay */
  1010. dspmem_chunk_flush(outCh);
  1011. break;
  1012. default:
  1013. return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
  1014. }
  1015. *outTimeMs = timeMs;
  1016. return ndk::ScopedAStatus::ok();
  1017. }
  1018. ndk::ScopedAStatus Vibrator::getPrimitiveDetails(CompositePrimitive primitive,
  1019. uint32_t *outEffectIndex) {
  1020. uint32_t effectIndex;
  1021. uint32_t primitiveBit = 1 << int32_t(primitive);
  1022. if ((primitiveBit & mSupportedPrimitivesBits) == 0x0) {
  1023. return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
  1024. }
  1025. switch (primitive) {
  1026. case CompositePrimitive::NOOP:
  1027. return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
  1028. case CompositePrimitive::CLICK:
  1029. effectIndex = WAVEFORM_CLICK_INDEX;
  1030. break;
  1031. case CompositePrimitive::THUD:
  1032. effectIndex = WAVEFORM_THUD_INDEX;
  1033. break;
  1034. case CompositePrimitive::SPIN:
  1035. effectIndex = WAVEFORM_SPIN_INDEX;
  1036. break;
  1037. case CompositePrimitive::QUICK_RISE:
  1038. effectIndex = WAVEFORM_QUICK_RISE_INDEX;
  1039. break;
  1040. case CompositePrimitive::SLOW_RISE:
  1041. effectIndex = WAVEFORM_SLOW_RISE_INDEX;
  1042. break;
  1043. case CompositePrimitive::QUICK_FALL:
  1044. effectIndex = WAVEFORM_QUICK_FALL_INDEX;
  1045. break;
  1046. case CompositePrimitive::LIGHT_TICK:
  1047. effectIndex = WAVEFORM_LIGHT_TICK_INDEX;
  1048. break;
  1049. case CompositePrimitive::LOW_TICK:
  1050. effectIndex = WAVEFORM_LOW_TICK_INDEX;
  1051. break;
  1052. default:
  1053. return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
  1054. }
  1055. *outEffectIndex = effectIndex;
  1056. return ndk::ScopedAStatus::ok();
  1057. }
  1058. ndk::ScopedAStatus Vibrator::performEffect(Effect effect, EffectStrength strength,
  1059. const std::shared_ptr<IVibratorCallback> &callback,
  1060. int32_t *outTimeMs) {
  1061. ndk::ScopedAStatus status;
  1062. uint32_t effectIndex;
  1063. uint32_t timeMs = 0;
  1064. uint32_t volLevel;
  1065. dspmem_chunk *ch = nullptr;
  1066. switch (effect) {
  1067. case Effect::TEXTURE_TICK:
  1068. // fall-through
  1069. case Effect::TICK:
  1070. // fall-through
  1071. case Effect::CLICK:
  1072. // fall-through
  1073. case Effect::HEAVY_CLICK:
  1074. status = getSimpleDetails(effect, strength, &effectIndex, &timeMs, &volLevel);
  1075. break;
  1076. case Effect::DOUBLE_CLICK:
  1077. ch = dspmem_chunk_create(new uint8_t[FF_CUSTOM_DATA_LEN_MAX_COMP]{0x00},
  1078. FF_CUSTOM_DATA_LEN_MAX_COMP);
  1079. status = getCompoundDetails(effect, strength, &timeMs, ch);
  1080. volLevel = VOLTAGE_SCALE_MAX;
  1081. break;
  1082. default:
  1083. status = ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
  1084. break;
  1085. }
  1086. if (!status.isOk()) {
  1087. goto exit;
  1088. }
  1089. status = performEffect(effectIndex, volLevel, ch, callback);
  1090. exit:
  1091. *outTimeMs = timeMs;
  1092. return status;
  1093. }
  1094. ndk::ScopedAStatus Vibrator::performEffect(uint32_t effectIndex, uint32_t volLevel,
  1095. dspmem_chunk *ch,
  1096. const std::shared_ptr<IVibratorCallback> &callback) {
  1097. setEffectAmplitude(volLevel, VOLTAGE_SCALE_MAX);
  1098. return on(MAX_TIME_MS, effectIndex, ch, callback);
  1099. }
  1100. void Vibrator::waitForComplete(std::shared_ptr<IVibratorCallback> &&callback) {
  1101. if (!mHwApi->pollVibeState(VIBE_STATE_HAPTIC, POLLING_TIMEOUT)) {
  1102. ALOGW("Failed to get state \"Haptic\"");
  1103. }
  1104. mHwApi->pollVibeState(VIBE_STATE_STOPPED);
  1105. const std::scoped_lock<std::mutex> lock(mActiveId_mutex);
  1106. if ((mActiveId >= WAVEFORM_MAX_PHYSICAL_INDEX) &&
  1107. (!mHwApi->eraseOwtEffect(mInputFd, mActiveId, &mFfEffects))) {
  1108. ALOGE("Failed to clean up the composed effect %d", mActiveId);
  1109. }
  1110. mActiveId = -1;
  1111. if (callback) {
  1112. auto ret = callback->onComplete();
  1113. if (!ret.isOk()) {
  1114. ALOGE("Failed completion callback: %d", ret.getExceptionCode());
  1115. }
  1116. }
  1117. }
  1118. uint32_t Vibrator::intensityToVolLevel(float intensity, uint32_t effectIndex) {
  1119. uint32_t volLevel;
  1120. auto calc = [](float intst, std::array<uint32_t, 2> v) -> uint32_t {
  1121. return std::lround(intst * (v[1] - v[0])) + v[0];
  1122. };
  1123. switch (effectIndex) {
  1124. case WAVEFORM_LIGHT_TICK_INDEX:
  1125. volLevel = calc(intensity, mTickEffectVol);
  1126. break;
  1127. case WAVEFORM_QUICK_RISE_INDEX:
  1128. // fall-through
  1129. case WAVEFORM_QUICK_FALL_INDEX:
  1130. volLevel = calc(intensity, mLongEffectVol);
  1131. break;
  1132. case WAVEFORM_CLICK_INDEX:
  1133. // fall-through
  1134. case WAVEFORM_THUD_INDEX:
  1135. // fall-through
  1136. case WAVEFORM_SPIN_INDEX:
  1137. // fall-through
  1138. case WAVEFORM_SLOW_RISE_INDEX:
  1139. // fall-through
  1140. default:
  1141. volLevel = calc(intensity, mClickEffectVol);
  1142. break;
  1143. }
  1144. return volLevel;
  1145. }
  1146. } // namespace vibrator
  1147. } // namespace hardware
  1148. } // namespace android
  1149. } // namespace aidl