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
24 #include "Vibrator.h"
25
26 #include <cinttypes>
27 #include <cmath>
28 #include <iostream>
29 #include <fstream>
30
31
32 namespace android {
33 namespace hardware {
34 namespace vibrator {
35 namespace V1_0 {
36 namespace implementation {
37
38 static constexpr int MAX_VOLTAGE = 3596;
39 static constexpr int MIN_VOLTAGE = 116;
40
41 static constexpr uint32_t CLICK_TIMING_MS = 20;
42
Vibrator(std::ofstream && enable,std::ofstream && amplitude)43 Vibrator::Vibrator(std::ofstream&& enable, std::ofstream&& amplitude) :
44 mEnable(std::move(enable)),
45 mAmplitude(std::move(amplitude)) {}
46
47 // Methods from ::android::hardware::vibrator::V1_0::IVibrator follow.
on(uint32_t timeout_ms)48 Return<Status> Vibrator::on(uint32_t timeout_ms) {
49 mEnable << timeout_ms << std::endl;
50 if (!mEnable) {
51 ALOGE("Failed to turn vibrator on (%d): %s", errno, strerror(errno));
52 return Status::UNKNOWN_ERROR;
53 }
54 return Status::OK;
55 }
56
off()57 Return<Status> Vibrator::off() {
58 mEnable << 0 << std::endl;
59 if (!mEnable) {
60 ALOGE("Failed to turn vibrator off (%d): %s", errno, strerror(errno));
61 return Status::UNKNOWN_ERROR;
62 }
63 return Status::OK;
64 }
65
supportsAmplitudeControl()66 Return<bool> Vibrator::supportsAmplitudeControl() {
67 return true;
68 }
69
setAmplitude(uint8_t amplitude)70 Return<Status> Vibrator::setAmplitude(uint8_t amplitude) {
71 if (amplitude == 0) {
72 return Status::BAD_VALUE;
73 }
74 // Scale the voltage such that an amplitude of 1 is MIN_VOLTAGE, an amplitude of 255 is
75 // MAX_VOLTAGE, and there are equal steps for every value in between.
76 long voltage =
77 std::lround((amplitude - 1) / 254.0 * (MAX_VOLTAGE - MIN_VOLTAGE) + MIN_VOLTAGE);
78 ALOGE("Setting amplitude to: %ld", voltage);
79 mAmplitude << voltage << std::endl;
80 if (!mAmplitude) {
81 ALOGE("Failed to set amplitude (%d): %s", errno, strerror(errno));
82 return Status::UNKNOWN_ERROR;
83 }
84 return Status::OK;
85 }
86
perform(Effect effect,EffectStrength strength,perform_cb _hidl_cb)87 Return<void> Vibrator::perform(Effect effect, EffectStrength strength, perform_cb _hidl_cb) {
88 if (effect == Effect::CLICK) {
89 uint8_t amplitude;
90 switch (strength) {
91 case EffectStrength::LIGHT:
92 amplitude = 36;
93 break;
94 case EffectStrength::MEDIUM:
95 amplitude = 128;
96 break;
97 case EffectStrength::STRONG:
98 amplitude = 255;
99 break;
100 default:
101 _hidl_cb(Status::UNSUPPORTED_OPERATION, 0);
102 return Void();
103 }
104 on(CLICK_TIMING_MS);
105 setAmplitude(amplitude);
106 _hidl_cb(Status::OK, CLICK_TIMING_MS);
107 } else {
108 _hidl_cb(Status::UNSUPPORTED_OPERATION, 0);
109 }
110 return Void();
111 }
112
113 } // namespace implementation
114 } // namespace V1_0
115 } // namespace vibrator
116 } // namespace hardware
117 } // namespace android
118