1 /*
2 * Copyright (C) 2017 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 #define LOG_TAG "VibratorService"
18
19 #include <log/log.h>
20
21 #include <hardware/hardware.h>
22 #include <hardware/vibrator.h>
23 #include <cutils/properties.h>
24
25 #include "Vibrator.h"
26
27 #include <cinttypes>
28 #include <cmath>
29 #include <iostream>
30 #include <fstream>
31
32
33 namespace android {
34 namespace hardware {
35 namespace vibrator {
36 namespace V1_2 {
37 namespace implementation {
38
39 using Status = ::android::hardware::vibrator::V1_0::Status;
40 using EffectStrength = ::android::hardware::vibrator::V1_0::EffectStrength;
41
42 static constexpr uint32_t WAVEFORM_TICK_EFFECT_INDEX = 2;
43 static constexpr uint32_t WAVEFORM_TICK_EFFECT_MS = 9;
44
45 static constexpr uint32_t WAVEFORM_CLICK_EFFECT_INDEX = 3;
46 static constexpr uint32_t WAVEFORM_CLICK_EFFECT_MS = 9;
47
48 static constexpr uint32_t WAVEFORM_HEAVY_CLICK_EFFECT_INDEX = 4;
49 static constexpr uint32_t WAVEFORM_HEAVY_CLICK_EFFECT_MS = 9;
50 static constexpr uint32_t WAVEFORM_STRONG_HEAVY_CLICK_EFFECT_MS = 12;
51
52 static constexpr uint32_t WAVEFORM_DOUBLE_CLICK_EFFECT_INDEX = 7;
53 static constexpr uint32_t WAVEFORM_DOUBLE_CLICK_EFFECT_MS = 130;
54
55 static constexpr uint32_t WAVEFORM_RINGTONE_EFFECT_INDEX = 65534;
56 static constexpr uint32_t WAVEFORM_RINGTONE_EFFECT_MS = 30000;
57
58 // The_big_adventure - RINGTONE_1
59 static constexpr char WAVEFORM_RINGTONE1_EFFECT_QUEUE[] = "160, 11.100, 1600, 1!";
60
61 // Copycat - RINGTONE_2
62 static constexpr char WAVEFORM_RINGTONE2_EFFECT_QUEUE[] = "260, 12.100, 660, 2!";
63
64 // Crackle - RINGTONE_3
65 static constexpr char WAVEFORM_RINGTONE3_EFFECT_QUEUE[] = "404, 13.100, 1440, 5!";
66
67 // Flutterby - RINGTONE_4
68 static constexpr char WAVEFORM_RINGTONE4_EFFECT_QUEUE[] = "140, 14.100, 6!";
69
70 // Hotline - RINGTONE_5
71 static constexpr char WAVEFORM_RINGTONE5_EFFECT_QUEUE[] = "140, 15.100, 4!";
72
73 // Leaps_and_bounds - RINGTONE_6
74 static constexpr char WAVEFORM_RINGTONE6_EFFECT_QUEUE[] = "140, 16.100, 1!";
75
76 // Lollipop - RINGTONE_7
77 static constexpr char WAVEFORM_RINGTONE7_EFFECT_QUEUE[] = "140, 17.100, 624, 1!";
78
79 // Lost_and_found - RINGTONE_8
80 static constexpr char WAVEFORM_RINGTONE8_EFFECT_QUEUE[] = "140, 18.100, 1020,496, 1!";
81
82 // Mash_up - RINGTONE_9
83 static constexpr char WAVEFORM_RINGTONE9_EFFECT_QUEUE[] = "140, 19.100, 8, 3!";
84
85 // Monkey_around - RINGTONE_10
86 static constexpr char WAVEFORM_RINGTONE10_EFFECT_QUEUE[] = "20.100, 23.100, 23.80, 23.60, 892, 4!";
87
88 // Schools_out - RINGTONE_11
89 static constexpr char WAVEFORM_RINGTONE11_EFFECT_QUEUE[] = "21.60, 21.80, 21.100, 1020, 564, 6!";
90
91 // Zen_too - RINGTONE_12
92 static constexpr char WAVEFORM_RINGTONE12_EFFECT_QUEUE[] = "140, 22.100, 972, 1!";
93
94 static constexpr float AMP_ATTENUATE_STEP_SIZE = 0.125f;
95
96 static constexpr int8_t MAX_TRIGGER_LATENCY_MS = 6;
97
amplitudeToScale(uint8_t amplitude,uint8_t maximum)98 static uint8_t amplitudeToScale(uint8_t amplitude, uint8_t maximum) {
99 return std::round((-20 * std::log10(amplitude / static_cast<float>(maximum))) /
100 (AMP_ATTENUATE_STEP_SIZE));
101 }
102
Vibrator(std::ofstream && activate,std::ofstream && duration,std::ofstream && effect,std::ofstream && queue,std::ofstream && scale)103 Vibrator::Vibrator(std::ofstream&& activate, std::ofstream&& duration, std::ofstream&& effect,
104 std::ofstream&& queue, std::ofstream&& scale) :
105 mActivate(std::move(activate)),
106 mDuration(std::move(duration)),
107 mEffectIndex(std::move(effect)),
108 mEffectQueue(std::move(queue)),
109 mScale(std::move(scale))
110 {}
111
on(uint32_t timeoutMs,uint32_t effectIndex)112 Return<Status> Vibrator::on(uint32_t timeoutMs, uint32_t effectIndex) {
113 mEffectIndex << effectIndex << std::endl;
114 mDuration << (timeoutMs + MAX_TRIGGER_LATENCY_MS) << std::endl;
115 mActivate << 1 << std::endl;
116
117 return Status::OK;
118 }
119
120
121 // Methods from ::android::hardware::vibrator::V1_1::IVibrator follow.
on(uint32_t timeoutMs)122 Return<Status> Vibrator::on(uint32_t timeoutMs) {
123 return on(timeoutMs, 0);
124 }
125
off()126 Return<Status> Vibrator::off() {
127 mActivate << 0 << std::endl;
128 if (!mActivate) {
129 ALOGE("Failed to turn vibrator off (%d): %s", errno, strerror(errno));
130 return Status::UNKNOWN_ERROR;
131 }
132 return Status::OK;
133 }
134
supportsAmplitudeControl()135 Return<bool> Vibrator::supportsAmplitudeControl() {
136 return (mScale ? true : false);
137 }
138
setAmplitude(uint8_t amplitude)139 Return<Status> Vibrator::setAmplitude(uint8_t amplitude) {
140
141 if (!amplitude) {
142 return Status::BAD_VALUE;
143 }
144
145 int32_t scale = amplitudeToScale(amplitude, UINT8_MAX);
146
147 mScale << scale << std::endl;
148 if (!mScale) {
149 ALOGE("Failed to set amplitude (%d): %s", errno, strerror(errno));
150 return Status::UNKNOWN_ERROR;
151 }
152
153 return Status::OK;
154 }
155
perform(V1_0::Effect effect,EffectStrength strength,perform_cb _hidl_cb)156 Return<void> Vibrator::perform(V1_0::Effect effect, EffectStrength strength,
157 perform_cb _hidl_cb) {
158 return performWrapper(effect, strength, _hidl_cb);
159 }
160
perform_1_1(V1_1::Effect_1_1 effect,EffectStrength strength,perform_cb _hidl_cb)161 Return<void> Vibrator::perform_1_1(V1_1::Effect_1_1 effect, EffectStrength strength,
162 perform_cb _hidl_cb) {
163 return performWrapper(effect, strength, _hidl_cb);
164 }
165
perform_1_2(Effect effect,EffectStrength strength,perform_cb _hidl_cb)166 Return<void> Vibrator::perform_1_2(Effect effect, EffectStrength strength,
167 perform_cb _hidl_cb) {
168 return performWrapper(effect, strength, _hidl_cb);
169 }
170
171 template <typename T>
performWrapper(T effect,EffectStrength strength,perform_cb _hidl_cb)172 Return<void> Vibrator::performWrapper(T effect, EffectStrength strength, perform_cb _hidl_cb) {
173 auto validRange = hidl_enum_range<T>();
174 if (effect < *validRange.begin() || effect > *std::prev(validRange.end())) {
175 _hidl_cb(Status::UNSUPPORTED_OPERATION, 0);
176 return Void();
177 }
178 return performEffect(static_cast<Effect>(effect), strength, _hidl_cb);
179 }
180
performEffect(Effect effect,EffectStrength strength,perform_cb _hidl_cb)181 Return<void> Vibrator::performEffect(Effect effect, EffectStrength strength,
182 perform_cb _hidl_cb) {
183 Status status = Status::OK;
184 uint32_t timeMs;
185 uint32_t effectIndex;
186
187 switch (effect) {
188 case Effect::TICK:
189 effectIndex = WAVEFORM_TICK_EFFECT_INDEX;
190 timeMs = WAVEFORM_TICK_EFFECT_MS;
191 break;
192 case Effect::CLICK:
193 effectIndex = WAVEFORM_CLICK_EFFECT_INDEX;
194 timeMs = WAVEFORM_CLICK_EFFECT_MS;
195 break;
196 case Effect::HEAVY_CLICK:
197 effectIndex = WAVEFORM_HEAVY_CLICK_EFFECT_INDEX;
198 if (strength == EffectStrength::STRONG) {
199 timeMs = WAVEFORM_STRONG_HEAVY_CLICK_EFFECT_MS;
200 } else {
201 timeMs = WAVEFORM_HEAVY_CLICK_EFFECT_MS;
202 }
203 break;
204 case Effect::DOUBLE_CLICK:
205 effectIndex = WAVEFORM_DOUBLE_CLICK_EFFECT_INDEX;
206 timeMs = WAVEFORM_DOUBLE_CLICK_EFFECT_MS;
207 break;
208 case Effect::RINGTONE_1:
209 mEffectQueue << WAVEFORM_RINGTONE1_EFFECT_QUEUE << std::endl;
210 break;
211 case Effect::RINGTONE_2:
212 mEffectQueue << WAVEFORM_RINGTONE2_EFFECT_QUEUE << std::endl;
213 break;
214 case Effect::RINGTONE_3:
215 mEffectQueue << WAVEFORM_RINGTONE3_EFFECT_QUEUE << std::endl;
216 break;
217 case Effect::RINGTONE_4:
218 mEffectQueue << WAVEFORM_RINGTONE4_EFFECT_QUEUE << std::endl;
219 break;
220 case Effect::RINGTONE_5:
221 mEffectQueue << WAVEFORM_RINGTONE5_EFFECT_QUEUE << std::endl;
222 break;
223 case Effect::RINGTONE_6:
224 mEffectQueue << WAVEFORM_RINGTONE6_EFFECT_QUEUE << std::endl;
225 break;
226 case Effect::RINGTONE_7:
227 mEffectQueue << WAVEFORM_RINGTONE7_EFFECT_QUEUE << std::endl;
228 break;
229 case Effect::RINGTONE_8:
230 mEffectQueue << WAVEFORM_RINGTONE8_EFFECT_QUEUE << std::endl;
231 break;
232 case Effect::RINGTONE_9:
233 mEffectQueue << WAVEFORM_RINGTONE9_EFFECT_QUEUE << std::endl;
234 break;
235 case Effect::RINGTONE_10:
236 mEffectQueue << WAVEFORM_RINGTONE10_EFFECT_QUEUE << std::endl;
237 break;
238 case Effect::RINGTONE_11:
239 mEffectQueue << WAVEFORM_RINGTONE11_EFFECT_QUEUE << std::endl;
240 break;
241 case Effect::RINGTONE_12:
242 mEffectQueue << WAVEFORM_RINGTONE12_EFFECT_QUEUE << std::endl;
243 break;
244 default:
245 _hidl_cb(Status::UNSUPPORTED_OPERATION, 0);
246 return Void();
247 }
248
249 // EffectStrength needs to be handled differently for ringtone effects
250 if (effect >= Effect::RINGTONE_1 && effect <= Effect::RINGTONE_15) {
251 effectIndex = WAVEFORM_RINGTONE_EFFECT_INDEX;
252 timeMs = WAVEFORM_RINGTONE_EFFECT_MS;
253 switch (strength) {
254 case EffectStrength::LIGHT:
255 setAmplitude(UINT8_MAX / 3);
256 break;
257 case EffectStrength::MEDIUM:
258 setAmplitude(UINT8_MAX / 2);
259 break;
260 case EffectStrength::STRONG:
261 setAmplitude(UINT8_MAX);
262 break;
263 default:
264 _hidl_cb(Status::UNSUPPORTED_OPERATION, 0);
265 return Void();
266 }
267 } else {
268 switch (strength) {
269 case EffectStrength::LIGHT:
270 effectIndex -= 1;
271 break;
272 case EffectStrength::MEDIUM:
273 break;
274 case EffectStrength::STRONG:
275 effectIndex += 1;
276 break;
277 default:
278 _hidl_cb(Status::UNSUPPORTED_OPERATION, 0);
279 return Void();
280 }
281 timeMs += MAX_TRIGGER_LATENCY_MS; // Add expected cold-start latency
282 setAmplitude(UINT8_MAX); // Always set full-scale for non-ringtone constants
283 }
284
285 on(timeMs, effectIndex);
286 _hidl_cb(status, timeMs);
287
288 return Void();
289 }
290
291
292 } // namespace implementation
293 } // namespace V1_2
294 } // namespace vibrator
295 } // namespace hardware
296 } // namespace android
297