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 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. 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 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 66 Return<bool> Vibrator::supportsAmplitudeControl() { 67 return true; 68 } 69 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 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