diff --git a/device-redfin.mk b/device-redfin.mk
index 2a6d20a..90c8b94 100644
--- a/device-redfin.mk
+++ b/device-redfin.mk
@@ -115,6 +115,20 @@ PRODUCT_PACKAGES += \
PRODUCT_PACKAGES += \
android.hardware.vibrator@1.3-service.redfin
+# DRV2624 Haptics Waveform
+PRODUCT_COPY_FILES += \
+ device/google/redfin/vibrator/drv2624/drv2624.bin:$(TARGET_COPY_OUT_VENDOR)/firmware/drv2624.bin
+
+# Vibrator HAL
+PRODUCT_PRODUCT_PROPERTIES +=\
+ ro.vibrator.hal.config.dynamic=1 \
+ ro.vibrator.hal.click.duration=8 \
+ ro.vibrator.hal.tick.duration=8 \
+ ro.vibrator.hal.heavyclick.duration=8 \
+ ro.vibrator.hal.long.voltage=161 \
+ ro.vibrator.hal.long.frequency.shift=0 \
+ ro.vibrator.hal.steady.shape=1
+
# Dumpstate HAL
PRODUCT_PACKAGES += \
android.hardware.dumpstate@1.0-service.redfin
diff --git a/init.insmod.redfin.cfg b/init.insmod.redfin.cfg
index f57ad6c..ad77b2d 100644
--- a/init.insmod.redfin.cfg
+++ b/init.insmod.redfin.cfg
@@ -5,7 +5,7 @@
#############################################
# Load kernel modules
-modprobe|adsp_loader_dlkm.ko apr_dlkm.ko atomic64_test.ko bolero_cdc_dlkm.ko br_netfilter.ko hdmi_dlkm.ko lcd.ko lkdtm.ko llcc_perfmon.ko locktorture.ko machine_dlkm.ko mbhc_dlkm.ko native_dlkm.ko pinctrl_lpi_dlkm.ko platform_dlkm.ko q6_dlkm.ko q6_notifier_dlkm.ko q6_pdr_dlkm.ko rcutorture.ko rx_macro_dlkm.ko snd_event_dlkm.ko stub_dlkm.ko swr_ctrl_dlkm.ko swr_dlkm.ko test_user_copy.ko torture.ko tx_macro_dlkm.ko usf_dlkm.ko va_macro_dlkm.ko wcd938x_dlkm.ko wcd938x_slave_dlkm.ko wcd9xxx_dlkm.ko wcd_core_dlkm.ko wlan.ko wsa881x_dlkm.ko wsa_macro_dlkm.ko heatmap.ko sec_touch.ko
+modprobe|adsp_loader_dlkm.ko apr_dlkm.ko atomic64_test.ko bolero_cdc_dlkm.ko br_netfilter.ko hdmi_dlkm.ko lcd.ko lkdtm.ko llcc_perfmon.ko locktorture.ko machine_dlkm.ko mbhc_dlkm.ko native_dlkm.ko pinctrl_lpi_dlkm.ko platform_dlkm.ko q6_dlkm.ko q6_notifier_dlkm.ko q6_pdr_dlkm.ko rcutorture.ko rx_macro_dlkm.ko snd_event_dlkm.ko stub_dlkm.ko swr_ctrl_dlkm.ko swr_dlkm.ko test_user_copy.ko torture.ko tx_macro_dlkm.ko usf_dlkm.ko va_macro_dlkm.ko wcd938x_dlkm.ko wcd938x_slave_dlkm.ko wcd9xxx_dlkm.ko wcd_core_dlkm.ko wlan.ko wsa881x_dlkm.ko wsa_macro_dlkm.ko heatmap.ko sec_touch.ko drv2624.ko
# All modules loaded
setprop|vendor.all.modules.ready
diff --git a/vibrator/Android.bp b/vibrator/Android.bp
index d2dd9c0..c19ddbd 100644
--- a/vibrator/Android.bp
+++ b/vibrator/Android.bp
@@ -1,5 +1,5 @@
//
-// Copyright (C) 2017 The Android Open Source Project
+// Copyright (C) 2019 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -14,67 +14,18 @@
// limitations under the License.
cc_defaults {
- name: "android.hardware.vibrator@1.3-defaults.redfin",
+ name: "PixelVibratorDefaultsRedfin",
defaults: ["hidl_defaults"],
relative_install_path: "hw",
+ static_libs: [
+ "PixelVibratorCommonRedfin",
+ ],
shared_libs: [
+ "libbase",
"libhidlbase",
"libcutils",
"liblog",
"libutils",
"libhardware",
- "android.hardware.vibrator@1.0",
- "android.hardware.vibrator@1.1",
- "android.hardware.vibrator@1.2",
- "android.hardware.vibrator@1.3",
- ],
- proprietary: true,
-}
-
-cc_library {
- name: "android.hardware.vibrator@1.3-impl.redfin",
- defaults: ["android.hardware.vibrator@1.3-defaults.redfin"],
- srcs: [
- "Hardware.cpp",
- "Vibrator.cpp",
],
}
-
-cc_binary {
- name: "android.hardware.vibrator@1.3-service.redfin",
- defaults: ["android.hardware.vibrator@1.3-defaults.redfin"],
- init_rc: ["android.hardware.vibrator@1.3-service.redfin.rc"],
- vintf_fragments: ["android.hardware.vibrator@1.3-service.redfin.xml"],
- srcs: ["service.cpp"],
- static_libs: ["android.hardware.vibrator@1.3-impl.redfin"],
-}
-
-cc_test {
- name: "PtsVibratorHalRedfinTestSuite",
- defaults: ["android.hardware.vibrator@1.3-defaults.redfin"],
- srcs: [
- "tests/main.cpp",
- "tests/test-hwapi.cpp",
- "tests/test-hwcal.cpp",
- "tests/test-vibrator.cpp",
- ],
- static_libs: [
- "android.hardware.vibrator@1.3-impl.redfin",
- "libgmock",
- ],
- shared_libs: [
- "libbase",
- ],
- test_suites: [
- "general-tests",
- "pts",
- ],
- multilib: {
- lib32: {
- suffix: "32",
- },
- lib64: {
- suffix: "64",
- },
- },
-}
diff --git a/vibrator/AndroidTest.xml b/vibrator/AndroidTest.xml
deleted file mode 100644
index a6ddf6d..0000000
--- a/vibrator/AndroidTest.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/vibrator/Hardware.cpp b/vibrator/Hardware.cpp
deleted file mode 100644
index 6f1d01d..0000000
--- a/vibrator/Hardware.cpp
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "android.hardware.vibrator@1.3-service.redfin"
-
-#include "Hardware.h"
-
-#include
-
-#include
-
-namespace android {
-namespace hardware {
-namespace vibrator {
-namespace V1_3 {
-namespace implementation {
-
-template
-static void fileFromEnv(const char *env, T *outStream, std::string *outName = nullptr) {
- auto file = std::getenv(env);
- auto mode = std::is_base_of_v ? std::ios_base::out : std::ios_base::in;
-
- if (file == nullptr) {
- ALOGE("Failed get env %s", env);
- return;
- }
-
- if (outName != nullptr) {
- *outName = std::string(file);
- }
-
- // Force 'in' mode to prevent file creation
- outStream->open(file, mode | std::ios_base::in);
- if (!*outStream) {
- ALOGE("Failed to open %s:%s (%d): %s", env, file, errno, strerror(errno));
- }
-}
-
-static auto pathsFromEnv(const char *env) {
- std::map ret;
- auto value = std::getenv(env);
-
- if (value == nullptr) {
- return ret;
- }
-
- std::istringstream paths{value};
- std::string path;
-
- while (paths >> path) {
- ret[path].open(path);
- }
-
- return ret;
-}
-
-static std::string trim(const std::string &str, const std::string &whitespace = " \t") {
- const auto str_begin = str.find_first_not_of(whitespace);
- if (str_begin == std::string::npos) {
- return "";
- }
-
- const auto str_end = str.find_last_not_of(whitespace);
- const auto str_range = str_end - str_begin + 1;
-
- return str.substr(str_begin, str_range);
-}
-
-template
-static Enable_If_Iterable unpack(std::istream &stream, T *value) {
- for (auto &entry : *value) {
- stream >> entry;
- }
-}
-
-template
-static Enable_If_Iterable unpack(std::istream &stream, T *value) {
- stream >> *value;
-}
-
-HwApi::HwApi() {
- // ostreams below are required
- fileFromEnv("F0_FILEPATH", &mF0, &mNames[&mF0]);
- fileFromEnv("REDC_FILEPATH", &mRedc, &mNames[&mRedc]);
- fileFromEnv("Q_FILEPATH", &mQ, &mNames[&mQ]);
- fileFromEnv("ACTIVATE_PATH", &mActivate, &mNames[&mActivate]);
- fileFromEnv("DURATION_PATH", &mDuration, &mNames[&mDuration]);
- fileFromEnv("STATE_PATH", &mState, &mNames[&mState]);
- fileFromEnv("EFFECT_DURATION_PATH", &mEffectDuration, &mNames[&mEffectDuration]);
- fileFromEnv("EFFECT_INDEX_PATH", &mEffectIndex, &mNames[&mEffectIndex]);
- fileFromEnv("EFFECT_QUEUE_PATH", &mEffectQueue, &mNames[&mEffectQueue]);
- fileFromEnv("EFFECT_SCALE_PATH", &mEffectScale, &mNames[&mEffectScale]);
- fileFromEnv("GLOBAL_SCALE_PATH", &mGlobalScale, &mNames[&mGlobalScale]);
- fileFromEnv("ASP_ENABLE_PATH", &mAspEnable, &mNames[&mAspEnable]);
- fileFromEnv("GPIO_FALL_INDEX", &mGpioFallIndex, &mNames[&mGpioFallIndex]);
- fileFromEnv("GPIO_FALL_SCALE", &mGpioFallScale, &mNames[&mGpioFallScale]);
- fileFromEnv("GPIO_RISE_INDEX", &mGpioRiseIndex, &mNames[&mGpioRiseIndex]);
- fileFromEnv("GPIO_RISE_SCALE", &mGpioRiseScale, &mNames[&mGpioRiseScale]);
-}
-
-template
-bool HwApi::has(T &stream) {
- return !!stream;
-}
-
-template
-bool HwApi::get(T *value, U &stream) {
- bool ret;
- stream.seekg(0);
- stream >> *value;
- if (!(ret = !!stream)) {
- ALOGE("Failed to read %s (%d): %s", mNames[&stream].c_str(), errno, strerror(errno));
- }
- stream.clear();
- return ret;
-}
-
-template
-bool HwApi::set(const T &value, U &stream) {
- bool ret;
- stream << value << std::endl;
- if (!(ret = !!stream)) {
- ALOGE("Failed to write %s (%d): %s", mNames[&stream].c_str(), errno, strerror(errno));
- stream.clear();
- }
- return ret;
-}
-
-void HwApi::debug(int fd) {
- dprintf(fd, "Kernel:\n");
-
- for (auto &entry : pathsFromEnv("HWAPI_DEBUG_PATHS")) {
- auto &path = entry.first;
- auto &stream = entry.second;
- std::string line;
-
- dprintf(fd, " %s:\n", path.c_str());
- while (std::getline(stream, line)) {
- dprintf(fd, " %s\n", line.c_str());
- }
- }
-}
-
-HwCal::HwCal() {
- std::ifstream calfile;
-
- fileFromEnv("CALIBRATION_FILEPATH", &calfile);
-
- for (std::string line; std::getline(calfile, line);) {
- if (line.empty() || line[0] == '#') {
- continue;
- }
- std::istringstream is_line(line);
- std::string key, value;
- if (std::getline(is_line, key, ':') && std::getline(is_line, value)) {
- mCalData[trim(key)] = trim(value);
- }
- }
-}
-
-template
-bool HwCal::get(const char *key, T *value) {
- auto it = mCalData.find(key);
- if (it == mCalData.end()) {
- ALOGE("Missing %s config!", key);
- return false;
- }
- std::stringstream stream{it->second};
- unpack(stream, value);
- if (!stream || !stream.eof()) {
- ALOGE("Invalid %s config!", key);
- return false;
- }
- return true;
-}
-
-void HwCal::debug(int fd) {
- std::ifstream stream;
- std::string path;
- std::string line;
-
- dprintf(fd, "Persist:\n");
-
- fileFromEnv("CALIBRATION_FILEPATH", &stream, &path);
-
- dprintf(fd, " %s:\n", path.c_str());
- while (std::getline(stream, line)) {
- dprintf(fd, " %s\n", line.c_str());
- }
-}
-
-} // namespace implementation
-} // namespace V1_3
-} // namespace vibrator
-} // namespace hardware
-} // namespace android
diff --git a/vibrator/Hardware.h b/vibrator/Hardware.h
deleted file mode 100644
index 4b65f24..0000000
--- a/vibrator/Hardware.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#ifndef ANDROID_HARDWARE_VIBRATOR_HARDWARE_H
-#define ANDROID_HARDWARE_VIBRATOR_HARDWARE_H
-
-#include "Vibrator.h"
-#include "utils.h"
-
-namespace android {
-namespace hardware {
-namespace vibrator {
-namespace V1_3 {
-namespace implementation {
-
-class HwApi : public Vibrator::HwApi {
- public:
- HwApi();
- bool setF0(uint32_t value) override { return set(value, mF0); }
- bool setRedc(uint32_t value) override { return set(value, mRedc); }
- bool setQ(uint32_t value) override { return set(value, mQ); }
- bool setActivate(bool value) override { return set(value, mActivate); }
- bool setDuration(uint32_t value) override { return set(value, mDuration); }
- bool getEffectDuration(uint32_t *value) override { return get(value, mEffectDuration); }
- bool setEffectIndex(uint32_t value) override { return set(value, mEffectIndex); }
- bool setEffectQueue(std::string value) override { return set(value, mEffectQueue); }
- bool hasEffectScale() override { return has(mEffectScale); }
- bool setEffectScale(uint32_t value) override { return set(value, mEffectScale); }
- bool setGlobalScale(uint32_t value) override { return set(value, mGlobalScale); }
- bool setState(bool value) override { return set(value, mState); }
- bool hasAspEnable() override { return has(mAspEnable); }
- bool getAspEnable(bool *value) override { return get(value, mAspEnable); }
- bool setAspEnable(bool value) override { return set(value, mAspEnable); }
- bool setGpioFallIndex(uint32_t value) override { return set(value, mGpioFallIndex); }
- bool setGpioFallScale(uint32_t value) override { return set(value, mGpioFallScale); }
- bool setGpioRiseIndex(uint32_t value) override { return set(value, mGpioRiseIndex); }
- bool setGpioRiseScale(uint32_t value) override { return set(value, mGpioRiseScale); }
- void debug(int fd) override;
-
- private:
- template
- bool has(T &stream);
- template
- bool get(T *value, U &stream);
- template
- bool set(const T &value, U &stream);
-
- private:
- std::map mNames;
- std::ofstream mF0;
- std::ofstream mRedc;
- std::ofstream mQ;
- std::ofstream mActivate;
- std::ofstream mDuration;
- std::ifstream mEffectDuration;
- std::ofstream mEffectIndex;
- std::ofstream mEffectQueue;
- std::ofstream mEffectScale;
- std::ofstream mGlobalScale;
- std::ofstream mState;
- std::fstream mAspEnable;
- std::ofstream mGpioFallIndex;
- std::ofstream mGpioFallScale;
- std::ofstream mGpioRiseIndex;
- std::ofstream mGpioRiseScale;
-};
-
-class HwCal : public Vibrator::HwCal {
- private:
- static constexpr char F0_CONFIG[] = "f0_measured";
- static constexpr char REDC_CONFIG[] = "redc_measured";
- static constexpr char Q_CONFIG[] = "q_measured";
- static constexpr char Q_INDEX[] = "q_index";
- static constexpr char VOLTAGES_CONFIG[] = "v_levels";
-
- static constexpr uint32_t Q_FLOAT_TO_FIXED = 1 << 16;
- static constexpr float Q_INDEX_TO_FLOAT = 1.5f;
- static constexpr uint32_t Q_INDEX_TO_FIXED = Q_INDEX_TO_FLOAT * Q_FLOAT_TO_FIXED;
- static constexpr uint32_t Q_INDEX_OFFSET = 2.0f * Q_FLOAT_TO_FIXED;
-
- static constexpr uint32_t Q_DEFAULT = 15.5 * Q_FLOAT_TO_FIXED;
- static constexpr std::array V_LEVELS_DEFAULT = {60, 70, 80, 90, 100, 76};
-
- public:
- HwCal();
- bool getF0(uint32_t *value) override { return get(F0_CONFIG, value); }
- bool getRedc(uint32_t *value) override { return get(REDC_CONFIG, value); }
- bool getQ(uint32_t *value) override {
- if (get(Q_CONFIG, value)) {
- return true;
- }
- if (get(Q_INDEX, value)) {
- *value = *value * Q_INDEX_TO_FIXED + Q_INDEX_OFFSET;
- return true;
- }
- *value = Q_DEFAULT;
- return true;
- }
- bool getVolLevels(std::array *value) override {
- if (get(VOLTAGES_CONFIG, value)) {
- return true;
- }
- *value = V_LEVELS_DEFAULT;
- return true;
- }
- void debug(int fd) override;
-
- private:
- template
- bool get(const char *key, T *value);
-
- private:
- std::map mCalData;
-};
-
-} // namespace implementation
-} // namespace V1_3
-} // namespace vibrator
-} // namespace hardware
-} // namespace android
-
-#endif // ANDROID_HARDWARE_VIBRATOR_HARDWARE_H
diff --git a/vibrator/Vibrator.cpp b/vibrator/Vibrator.cpp
deleted file mode 100644
index 8bce7cc..0000000
--- a/vibrator/Vibrator.cpp
+++ /dev/null
@@ -1,415 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "android.hardware.vibrator@1.3-service.redfin"
-
-#include
-
-#include
-#include
-#include
-
-#include "Vibrator.h"
-
-#include
-#include
-#include
-#include
-
-#ifndef ARRAY_SIZE
-#define ARRAY_SIZE(x) (sizeof((x)) / sizeof((x)[0]))
-#endif
-
-namespace android {
-namespace hardware {
-namespace vibrator {
-namespace V1_3 {
-namespace implementation {
-
-using Status = ::android::hardware::vibrator::V1_0::Status;
-using EffectStrength = ::android::hardware::vibrator::V1_0::EffectStrength;
-
-static constexpr uint32_t WAVEFORM_SIMPLE_EFFECT_INDEX = 2;
-
-static constexpr uint32_t WAVEFORM_TEXTURE_TICK_EFFECT_LEVEL = 0;
-
-static constexpr uint32_t WAVEFORM_TICK_EFFECT_LEVEL = 1;
-
-static constexpr uint32_t WAVEFORM_CLICK_EFFECT_LEVEL = 2;
-
-static constexpr uint32_t WAVEFORM_HEAVY_CLICK_EFFECT_LEVEL = 3;
-
-static constexpr uint32_t WAVEFORM_DOUBLE_CLICK_SILENCE_MS = 100;
-
-static constexpr uint32_t WAVEFORM_LONG_VIBRATION_EFFECT_INDEX = 0;
-
-static constexpr uint32_t WAVEFORM_TRIGGER_QUEUE_INDEX = 65534;
-
-static constexpr uint32_t VOLTAGE_GLOBAL_SCALE_LEVEL = 5;
-static constexpr uint8_t VOLTAGE_SCALE_MAX = 100;
-
-static constexpr int8_t MAX_COLD_START_LATENCY_MS = 6; // I2C Transaction + DSP Return-From-Standby
-static constexpr int8_t MAX_PAUSE_TIMING_ERROR_MS = 1; // ALERT Irq Handling
-
-static constexpr float AMP_ATTENUATE_STEP_SIZE = 0.125f;
-static constexpr float EFFECT_FREQUENCY_KHZ = 48.0f;
-
-static uint8_t amplitudeToScale(uint8_t amplitude, uint8_t maximum) {
- return std::round((-20 * std::log10(amplitude / static_cast(maximum))) /
- (AMP_ATTENUATE_STEP_SIZE));
-}
-
-Vibrator::Vibrator(std::unique_ptr hwapi, std::unique_ptr hwcal)
- : mHwApi(std::move(hwapi)), mHwCal(std::move(hwcal)) {
- uint32_t caldata;
- uint32_t effectDuration;
-
- if (!mHwApi->setState(true)) {
- ALOGE("Failed to set state (%d): %s", errno, strerror(errno));
- }
-
- if (mHwCal->getF0(&caldata)) {
- mHwApi->setF0(caldata);
- }
- if (mHwCal->getRedc(&caldata)) {
- mHwApi->setRedc(caldata);
- }
- if (mHwCal->getQ(&caldata)) {
- mHwApi->setQ(caldata);
- }
- mHwCal->getVolLevels(&mVolLevels);
-
- mHwApi->setEffectIndex(WAVEFORM_SIMPLE_EFFECT_INDEX);
- mHwApi->getEffectDuration(&effectDuration);
-
- mSimpleEffectDuration = std::ceil(effectDuration / EFFECT_FREQUENCY_KHZ);
-
- const uint32_t scaleFall =
- amplitudeToScale(mVolLevels[WAVEFORM_CLICK_EFFECT_LEVEL], VOLTAGE_SCALE_MAX);
- const uint32_t scaleRise =
- amplitudeToScale(mVolLevels[WAVEFORM_HEAVY_CLICK_EFFECT_LEVEL], VOLTAGE_SCALE_MAX);
-
- mHwApi->setGpioFallIndex(WAVEFORM_SIMPLE_EFFECT_INDEX);
- mHwApi->setGpioFallScale(scaleFall);
- mHwApi->setGpioRiseIndex(WAVEFORM_SIMPLE_EFFECT_INDEX);
- mHwApi->setGpioRiseScale(scaleRise);
-}
-
-Return Vibrator::on(uint32_t timeoutMs, uint32_t effectIndex) {
- mHwApi->setEffectIndex(effectIndex);
- mHwApi->setDuration(timeoutMs);
- mHwApi->setActivate(1);
-
- return Status::OK;
-}
-
-// Methods from ::android::hardware::vibrator::V1_1::IVibrator follow.
-Return Vibrator::on(uint32_t timeoutMs) {
- if (MAX_COLD_START_LATENCY_MS <= UINT32_MAX - timeoutMs) {
- timeoutMs += MAX_COLD_START_LATENCY_MS;
- }
- setGlobalAmplitude(true);
- return on(timeoutMs, WAVEFORM_LONG_VIBRATION_EFFECT_INDEX);
-}
-
-Return Vibrator::off() {
- setGlobalAmplitude(false);
- if (!mHwApi->setActivate(0)) {
- ALOGE("Failed to turn vibrator off (%d): %s", errno, strerror(errno));
- return Status::UNKNOWN_ERROR;
- }
- return Status::OK;
-}
-
-Return Vibrator::supportsAmplitudeControl() {
- return !isUnderExternalControl() && mHwApi->hasEffectScale();
-}
-
-Return Vibrator::setAmplitude(uint8_t amplitude) {
- if (!amplitude) {
- return Status::BAD_VALUE;
- }
-
- if (!isUnderExternalControl()) {
- return setEffectAmplitude(amplitude, UINT8_MAX);
- } else {
- return Status::UNSUPPORTED_OPERATION;
- }
-}
-
-Return Vibrator::setEffectAmplitude(uint8_t amplitude, uint8_t maximum) {
- int32_t scale = amplitudeToScale(amplitude, maximum);
-
- if (!mHwApi->setEffectScale(scale)) {
- ALOGE("Failed to set effect amplitude (%d): %s", errno, strerror(errno));
- return Status::UNKNOWN_ERROR;
- }
-
- return Status::OK;
-}
-
-Return Vibrator::setGlobalAmplitude(bool set) {
- uint8_t amplitude = set ? mVolLevels[VOLTAGE_GLOBAL_SCALE_LEVEL] : VOLTAGE_SCALE_MAX;
- int32_t scale = amplitudeToScale(amplitude, VOLTAGE_SCALE_MAX);
-
- if (!mHwApi->setGlobalScale(scale)) {
- ALOGE("Failed to set global amplitude (%d): %s", errno, strerror(errno));
- return Status::UNKNOWN_ERROR;
- }
-
- return Status::OK;
-}
-
-// Methods from ::android::hardware::vibrator::V1_3::IVibrator follow.
-
-Return Vibrator::supportsExternalControl() {
- return (mHwApi->hasAspEnable() ? true : false);
-}
-
-Return Vibrator::setExternalControl(bool enabled) {
- setGlobalAmplitude(enabled);
-
- if (!mHwApi->setAspEnable(enabled)) {
- ALOGE("Failed to set external control (%d): %s", errno, strerror(errno));
- return Status::UNKNOWN_ERROR;
- }
- return Status::OK;
-}
-
-bool Vibrator::isUnderExternalControl() {
- bool isAspEnabled;
- mHwApi->getAspEnable(&isAspEnabled);
- return isAspEnabled;
-}
-
-// Methods from ::android.hidl.base::V1_0::IBase follow.
-
-Return Vibrator::debug(const hidl_handle &handle,
- const hidl_vec & /* options */) {
- if (handle == nullptr || handle->numFds < 1 || handle->data[0] < 0) {
- ALOGE("Called debug() with invalid fd.");
- return Void();
- }
-
- int fd = handle->data[0];
-
- dprintf(fd, "HIDL:\n");
-
- dprintf(fd, " Voltage Levels:");
- for (auto v : mVolLevels) {
- dprintf(fd, " %" PRIu32, v);
- }
- dprintf(fd, "\n");
-
- dprintf(fd, " Effect Duration: %" PRIu32 "\n", mSimpleEffectDuration);
-
- dprintf(fd, "\n");
-
- mHwApi->debug(fd);
-
- dprintf(fd, "\n");
-
- mHwCal->debug(fd);
-
- fsync(fd);
- return Void();
-}
-
-template
-Return Vibrator::performWrapper(T effect, EffectStrength strength, perform_cb _hidl_cb) {
- auto validRange = hidl_enum_range();
- if (effect < *validRange.begin() || effect > *std::prev(validRange.end())) {
- _hidl_cb(Status::UNSUPPORTED_OPERATION, 0);
- return Void();
- }
- return performEffect(static_cast(effect), strength, _hidl_cb);
-}
-
-Return Vibrator::perform(V1_0::Effect effect, EffectStrength strength, perform_cb _hidl_cb) {
- return performWrapper(effect, strength, _hidl_cb);
-}
-
-Return Vibrator::perform_1_1(V1_1::Effect_1_1 effect, EffectStrength strength,
- perform_cb _hidl_cb) {
- return performWrapper(effect, strength, _hidl_cb);
-}
-
-Return Vibrator::perform_1_2(V1_2::Effect effect, EffectStrength strength,
- perform_cb _hidl_cb) {
- return performWrapper(effect, strength, _hidl_cb);
-}
-
-Return Vibrator::perform_1_3(Effect effect, EffectStrength strength, perform_cb _hidl_cb) {
- return performWrapper(effect, strength, _hidl_cb);
-}
-
-Return Vibrator::getSimpleDetails(Effect effect, EffectStrength strength,
- uint32_t *outTimeMs, uint32_t *outVolLevel) {
- uint32_t timeMs;
- uint32_t volLevel;
- uint32_t volIndex;
- int8_t volOffset;
-
- switch (strength) {
- case EffectStrength::LIGHT:
- volOffset = -1;
- break;
- case EffectStrength::MEDIUM:
- volOffset = 0;
- break;
- case EffectStrength::STRONG:
- volOffset = 1;
- break;
- default:
- return Status::UNSUPPORTED_OPERATION;
- }
-
- switch (effect) {
- case Effect::TEXTURE_TICK:
- volIndex = WAVEFORM_TEXTURE_TICK_EFFECT_LEVEL;
- volOffset = 0;
- break;
- case Effect::TICK:
- volIndex = WAVEFORM_TICK_EFFECT_LEVEL;
- volOffset = 0;
- break;
- case Effect::CLICK:
- volIndex = WAVEFORM_CLICK_EFFECT_LEVEL;
- break;
- case Effect::HEAVY_CLICK:
- volIndex = WAVEFORM_HEAVY_CLICK_EFFECT_LEVEL;
- break;
- default:
- return Status::UNSUPPORTED_OPERATION;
- }
-
- volLevel = mVolLevels[volIndex + volOffset];
- timeMs = mSimpleEffectDuration + MAX_COLD_START_LATENCY_MS;
-
- *outTimeMs = timeMs;
- *outVolLevel = volLevel;
-
- return Status::OK;
-}
-
-Return Vibrator::getCompoundDetails(Effect effect, EffectStrength strength,
- uint32_t *outTimeMs, uint32_t * /*outVolLevel*/,
- std::string *outEffectQueue) {
- Status status;
- uint32_t timeMs;
- std::ostringstream effectBuilder;
- uint32_t thisTimeMs;
- uint32_t thisVolLevel;
-
- switch (effect) {
- case Effect::DOUBLE_CLICK:
- timeMs = 0;
-
- status = getSimpleDetails(Effect::CLICK, strength, &thisTimeMs, &thisVolLevel);
- if (status != Status::OK) {
- return status;
- }
- effectBuilder << WAVEFORM_SIMPLE_EFFECT_INDEX << "." << thisVolLevel;
- timeMs += thisTimeMs;
-
- effectBuilder << ",";
-
- effectBuilder << WAVEFORM_DOUBLE_CLICK_SILENCE_MS;
- timeMs += WAVEFORM_DOUBLE_CLICK_SILENCE_MS + MAX_PAUSE_TIMING_ERROR_MS;
-
- effectBuilder << ",";
-
- status = getSimpleDetails(Effect::HEAVY_CLICK, strength, &thisTimeMs, &thisVolLevel);
- if (status != Status::OK) {
- return status;
- }
- effectBuilder << WAVEFORM_SIMPLE_EFFECT_INDEX << "." << thisVolLevel;
- timeMs += thisTimeMs;
-
- break;
- default:
- return Status::UNSUPPORTED_OPERATION;
- }
-
- *outTimeMs = timeMs;
- *outEffectQueue = effectBuilder.str();
-
- return Status::OK;
-}
-
-Return Vibrator::setEffectQueue(const std::string &effectQueue) {
- if (!mHwApi->setEffectQueue(effectQueue)) {
- ALOGE("Failed to write \"%s\" to effect queue (%d): %s", effectQueue.c_str(), errno,
- strerror(errno));
- return Status::UNKNOWN_ERROR;
- }
-
- return Status::OK;
-}
-
-Return Vibrator::performEffect(Effect effect, EffectStrength strength, perform_cb _hidl_cb) {
- Status status = Status::OK;
- uint32_t timeMs = 0;
- uint32_t effectIndex;
- uint32_t volLevel;
- std::string effectQueue;
-
- switch (effect) {
- case Effect::TEXTURE_TICK:
- // fall-through
- case Effect::TICK:
- // fall-through
- case Effect::CLICK:
- // fall-through
- case Effect::HEAVY_CLICK:
- status = getSimpleDetails(effect, strength, &timeMs, &volLevel);
- break;
- case Effect::DOUBLE_CLICK:
- status = getCompoundDetails(effect, strength, &timeMs, &volLevel, &effectQueue);
- break;
- default:
- status = Status::UNSUPPORTED_OPERATION;
- break;
- }
- if (status != Status::OK) {
- goto exit;
- }
-
- if (!effectQueue.empty()) {
- status = setEffectQueue(effectQueue);
- if (status != Status::OK) {
- goto exit;
- }
- effectIndex = WAVEFORM_TRIGGER_QUEUE_INDEX;
- } else {
- setEffectAmplitude(volLevel, VOLTAGE_SCALE_MAX);
- effectIndex = WAVEFORM_SIMPLE_EFFECT_INDEX;
- }
-
- on(timeMs, effectIndex);
-
-exit:
-
- _hidl_cb(status, timeMs);
-
- return Void();
-}
-
-} // namespace implementation
-} // namespace V1_3
-} // namespace vibrator
-} // namespace hardware
-} // namespace android
diff --git a/vibrator/Vibrator.h b/vibrator/Vibrator.h
deleted file mode 100644
index b204dae..0000000
--- a/vibrator/Vibrator.h
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#ifndef ANDROID_HARDWARE_VIBRATOR_V1_3_VIBRATOR_H
-#define ANDROID_HARDWARE_VIBRATOR_V1_3_VIBRATOR_H
-
-#include
-#include
-
-#include
-
-namespace android {
-namespace hardware {
-namespace vibrator {
-namespace V1_3 {
-namespace implementation {
-
-class Vibrator : public IVibrator {
- public:
- // APIs for interfacing with the kernel driver.
- class HwApi {
- public:
- virtual ~HwApi() = default;
- // Stores the LRA resonant frequency to be used for PWLE playback
- // and click compensation.
- virtual bool setF0(uint32_t value) = 0;
- // Stores the LRA series resistance to be used for click
- // compensation.
- virtual bool setRedc(uint32_t value) = 0;
- // Stores the LRA Q factor to be used for Q-dependent waveform
- // selection.
- virtual bool setQ(uint32_t value) = 0;
- // Activates/deactivates the vibrator for durations specified by
- // setDuration().
- virtual bool setActivate(bool value) = 0;
- // Specifies the vibration duration in milliseconds.
- virtual bool setDuration(uint32_t value) = 0;
- // Reports the duration of the waveform selected by
- // setEffectIndex(), measured in 48-kHz periods.
- virtual bool getEffectDuration(uint32_t *value) = 0;
- // Selects the waveform associated with vibration calls from
- // the Android vibrator HAL.
- virtual bool setEffectIndex(uint32_t value) = 0;
- // Specifies an array of waveforms, delays, and repetition markers to
- // generate complex waveforms.
- virtual bool setEffectQueue(std::string value) = 0;
- // Reports whether setEffectScale() is supported.
- virtual bool hasEffectScale() = 0;
- // Indicates the number of 0.125-dB steps of attenuation to apply to
- // waveforms triggered in response to vibration calls from the
- // Android vibrator HAL.
- virtual bool setEffectScale(uint32_t value) = 0;
- // Indicates the number of 0.125-dB steps of attenuation to apply to
- // any output waveform (additive to all other set*Scale()
- // controls).
- virtual bool setGlobalScale(uint32_t value) = 0;
- // Specifies the active state of the vibrator
- // (true = enabled, false= disabled).
- virtual bool setState(bool value) = 0;
- // Reports whether getAspEnable()/setAspEnable() is supported.
- virtual bool hasAspEnable() = 0;
- // Enables/disables ASP playback.
- virtual bool getAspEnable(bool *value) = 0;
- // Reports enabled/disabled state of ASP playback.
- virtual bool setAspEnable(bool value) = 0;
- // Selects the waveform associated with a GPIO1 falling edge.
- virtual bool setGpioFallIndex(uint32_t value) = 0;
- // Indicates the number of 0.125-dB steps of attenuation to apply to
- // waveforms triggered in response to a GPIO1 falling edge.
- virtual bool setGpioFallScale(uint32_t value) = 0;
- // Selects the waveform associated with a GPIO1 rising edge.
- virtual bool setGpioRiseIndex(uint32_t value) = 0;
- // Indicates the number of 0.125-dB steps of attenuation to apply to
- // waveforms triggered in response to a GPIO1 rising edge.
- virtual bool setGpioRiseScale(uint32_t value) = 0;
- // Emit diagnostic information to the given file.
- virtual void debug(int fd) = 0;
- };
-
- // APIs for obtaining calibration/configuration data from persistent memory.
- class HwCal {
- public:
- virtual ~HwCal() = default;
- // Obtains the LRA resonant frequency to be used for PWLE playback
- // and click compensation.
- virtual bool getF0(uint32_t *value) = 0;
- // Obtains the LRA series resistance to be used for click
- // compensation.
- virtual bool getRedc(uint32_t *value) = 0;
- // Obtains the LRA Q factor to be used for Q-dependent waveform
- // selection.
- virtual bool getQ(uint32_t *value) = 0;
- // Obtains the discreet voltage levels to be applied for the various
- // waveforms, in units of 1%.
- virtual bool getVolLevels(std::array *value) = 0;
- // Emit diagnostic information to the given file.
- virtual void debug(int fd) = 0;
- };
-
- public:
- Vibrator(std::unique_ptr hwapi, std::unique_ptr hwcal);
-
- // Methods from ::android::hardware::vibrator::V1_0::IVibrator follow.
- using Status = ::android::hardware::vibrator::V1_0::Status;
- Return on(uint32_t timeoutMs) override;
- Return off() override;
- Return supportsAmplitudeControl() override;
- Return setAmplitude(uint8_t amplitude) override;
-
- // Methods from ::android::hardware::vibrator::V1_3::IVibrator follow.
- Return supportsExternalControl() override;
- Return setExternalControl(bool enabled) override;
-
- using EffectStrength = ::android::hardware::vibrator::V1_0::EffectStrength;
- Return perform(V1_0::Effect effect, EffectStrength strength,
- perform_cb _hidl_cb) override;
- Return perform_1_1(V1_1::Effect_1_1 effect, EffectStrength strength,
- perform_cb _hidl_cb) override;
- Return perform_1_2(V1_2::Effect effect, EffectStrength strength,
- perform_cb _hidl_cb) override;
- Return perform_1_3(Effect effect, EffectStrength strength, perform_cb _hidl_cb) override;
-
- // Methods from ::android.hidl.base::V1_0::IBase follow.
- Return debug(const hidl_handle &handle, const hidl_vec &options) override;
-
- private:
- Return on(uint32_t timeoutMs, uint32_t effectIndex);
- template
- Return performWrapper(T effect, EffectStrength strength, perform_cb _hidl_cb);
- // set 'amplitude' based on an arbitrary scale determined by 'maximum'
- Return setEffectAmplitude(uint8_t amplitude, uint8_t maximum);
- Return setGlobalAmplitude(bool set);
- // 'simple' effects are those precompiled and loaded into the controller
- Return getSimpleDetails(Effect effect, EffectStrength strength, uint32_t *outTimeMs,
- uint32_t *outVolLevel);
- // 'compound' effects are those composed by stringing multiple 'simple' effects
- Return getCompoundDetails(Effect effect, EffectStrength strength, uint32_t *outTimeMs,
- uint32_t *outVolLevel, std::string *outEffectQueue);
- Return setEffectQueue(const std::string &effectQueue);
- Return performEffect(Effect effect, EffectStrength strength, perform_cb _hidl_cb);
- bool isUnderExternalControl();
- std::unique_ptr mHwApi;
- std::unique_ptr mHwCal;
- std::array mVolLevels;
- uint32_t mSimpleEffectDuration;
-};
-
-} // namespace implementation
-} // namespace V1_3
-} // namespace vibrator
-} // namespace hardware
-} // namespace android
-
-#endif // ANDROID_HARDWARE_VIBRATOR_V1_3_VIBRATOR_H
diff --git a/vibrator/android.hardware.vibrator@1.3-service.redfin.rc b/vibrator/android.hardware.vibrator@1.3-service.redfin.rc
deleted file mode 100644
index a609ab0..0000000
--- a/vibrator/android.hardware.vibrator@1.3-service.redfin.rc
+++ /dev/null
@@ -1,38 +0,0 @@
-service vendor.vibrator-1-3 /vendor/bin/hw/android.hardware.vibrator@1.3-service.redfin
- class hal
- user system
- group system
-
- setenv CALIBRATION_FILEPATH /mnt/vendor/persist/haptics/cs40l25a.cal
-
- setenv F0_FILEPATH /sys/class/leds/vibrator/device/f0_stored
- setenv REDC_FILEPATH /sys/class/leds/vibrator/device/redc_stored
- setenv Q_FILEPATH /sys/class/leds/vibrator/device/q_stored
- setenv ACTIVATE_PATH /sys/class/leds/vibrator/activate
- setenv DURATION_PATH /sys/class/leds/vibrator/duration
- setenv STATE_PATH /sys/class/leds/vibrator/state
- setenv EFFECT_DURATION_PATH /sys/class/leds/vibrator/device/cp_trigger_duration
- setenv EFFECT_INDEX_PATH /sys/class/leds/vibrator/device/cp_trigger_index
- setenv EFFECT_QUEUE_PATH /sys/class/leds/vibrator/device/cp_trigger_queue
- setenv EFFECT_SCALE_PATH /sys/class/leds/vibrator/device/cp_dig_scale
- setenv GLOBAL_SCALE_PATH /sys/class/leds/vibrator/device/dig_scale
- setenv ASP_ENABLE_PATH /sys/class/leds/vibrator/device/asp_enable
- setenv GPIO_FALL_INDEX /sys/class/leds/vibrator/device/gpio1_fall_index
- setenv GPIO_FALL_SCALE /sys/class/leds/vibrator/device/gpio1_fall_dig_scale
- setenv GPIO_RISE_INDEX /sys/class/leds/vibrator/device/gpio1_rise_index
- setenv GPIO_RISE_SCALE /sys/class/leds/vibrator/device/gpio1_rise_dig_scale
-
- setenv HWAPI_DEBUG_PATHS "
- /sys/class/leds/vibrator/device/asp_enable
- /sys/class/leds/vibrator/device/f0_stored
- /sys/class/leds/vibrator/device/fw_rev
- /sys/class/leds/vibrator/device/gpio1_fall_dig_scale
- /sys/class/leds/vibrator/device/gpio1_fall_index
- /sys/class/leds/vibrator/device/gpio1_rise_dig_scale
- /sys/class/leds/vibrator/device/gpio1_rise_index
- /sys/class/leds/vibrator/device/heartbeat
- /sys/class/leds/vibrator/device/num_waves
- /sys/class/leds/vibrator/device/q_stored
- /sys/class/leds/vibrator/device/redc_stored
- /sys/class/leds/vibrator/state
- "
diff --git a/vibrator/common/Android.bp b/vibrator/common/Android.bp
new file mode 100644
index 0000000..477aa05
--- /dev/null
+++ b/vibrator/common/Android.bp
@@ -0,0 +1,33 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_library {
+ name: "PixelVibratorCommonRedfin",
+ srcs: [
+ "HardwareBase.cpp",
+ ],
+ shared_libs: [
+ "libbase",
+ "libcutils",
+ "liblog",
+ "libutils",
+ ],
+ cflags: [
+ "-DATRACE_TAG=(ATRACE_TAG_VIBRATOR | ATRACE_TAG_HAL)",
+ "-DLOG_TAG=\"android.hardware.vibrator@1.x-common\"",
+ ],
+ export_include_dirs: ["."],
+ vendor_available: true,
+}
diff --git a/vibrator/common/HardwareBase.cpp b/vibrator/common/HardwareBase.cpp
new file mode 100644
index 0000000..f868b6a
--- /dev/null
+++ b/vibrator/common/HardwareBase.cpp
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "HardwareBase.h"
+
+#include
+#include
+
+#include
+#include
+
+#include "utils.h"
+
+namespace android {
+namespace hardware {
+namespace vibrator {
+namespace common {
+namespace implementation {
+
+HwApiBase::HwApiBase() {
+ mPathPrefix = std::getenv("HWAPI_PATH_PREFIX") ?: "";
+ if (mPathPrefix.empty()) {
+ ALOGE("Failed get HWAPI path prefix!");
+ }
+}
+
+bool HwApiBase::has(const std::ios &stream) {
+ return !!stream;
+}
+
+void HwApiBase::debug(int fd) {
+ dprintf(fd, "Kernel:\n");
+
+ for (auto &entry : utils::pathsFromEnv("HWAPI_DEBUG_PATHS", mPathPrefix)) {
+ auto &path = entry.first;
+ auto &stream = entry.second;
+ std::string line;
+
+ dprintf(fd, " %s:\n", path.c_str());
+ while (std::getline(stream, line)) {
+ dprintf(fd, " %s\n", line.c_str());
+ }
+ }
+
+ mRecordsMutex.lock();
+ dprintf(fd, " Records:\n");
+ for (auto &r : mRecords) {
+ if (r == nullptr) {
+ continue;
+ }
+ dprintf(fd, " %s\n", r->toString(mNames).c_str());
+ }
+ mRecordsMutex.unlock();
+}
+
+HwCalBase::HwCalBase() {
+ std::ifstream calfile;
+ auto propertyPrefix = std::getenv("PROPERTY_PREFIX");
+
+ if (propertyPrefix != NULL) {
+ mPropertyPrefix = std::string(propertyPrefix);
+ } else {
+ ALOGE("Failed get property prefix!");
+ }
+
+ utils::fileFromEnv("CALIBRATION_FILEPATH", &calfile);
+
+ for (std::string line; std::getline(calfile, line);) {
+ if (line.empty() || line[0] == '#') {
+ continue;
+ }
+ std::istringstream is_line(line);
+ std::string key, value;
+ if (std::getline(is_line, key, ':') && std::getline(is_line, value)) {
+ mCalData[utils::trim(key)] = utils::trim(value);
+ }
+ }
+}
+
+void HwCalBase::debug(int fd) {
+ std::ifstream stream;
+ std::string path;
+ std::string line;
+ struct context {
+ HwCalBase *obj;
+ int fd;
+ } context{this, fd};
+
+ dprintf(fd, "Properties:\n");
+
+ property_list(
+ [](const char *key, const char *value, void *cookie) {
+ struct context *context = static_cast(cookie);
+ HwCalBase *obj = context->obj;
+ int fd = context->fd;
+ const std::string expect{obj->mPropertyPrefix};
+ const std::string actual{key, std::min(strlen(key), expect.size())};
+ if (actual == expect) {
+ dprintf(fd, " %s:\n", key);
+ dprintf(fd, " %s\n", value);
+ }
+ },
+ &context);
+
+ dprintf(fd, "\n");
+
+ dprintf(fd, "Persist:\n");
+
+ utils::fileFromEnv("CALIBRATION_FILEPATH", &stream, &path);
+
+ dprintf(fd, " %s:\n", path.c_str());
+ while (std::getline(stream, line)) {
+ dprintf(fd, " %s\n", line.c_str());
+ }
+}
+
+} // namespace implementation
+} // namespace common
+} // namespace vibrator
+} // namespace hardware
+} // namespace android
diff --git a/vibrator/common/HardwareBase.h b/vibrator/common/HardwareBase.h
new file mode 100644
index 0000000..46aa839
--- /dev/null
+++ b/vibrator/common/HardwareBase.h
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ANDROID_HARDWARE_VIBRATOR_HARDWARE_BASE_H
+#define ANDROID_HARDWARE_VIBRATOR_HARDWARE_BASE_H
+
+#include
+#include
+#include
+#include
+
+#include
+#include