From 0b2910ce0c774352cd6b1f43940d8db576a0c3db Mon Sep 17 00:00:00 2001 From: Andy CrossGate Yan Date: Tue, 22 Jun 2021 13:38:31 +0000 Subject: [PATCH] Add Meizu 18 vibrator support Thanks to: - @phhusson for guidance - Google for marlin HAL as reference in implementing 1.0 - @xingrz for Meizu 16th HAL as reference in implementing 1.3 Change-Id: Iecf12cd814e8773abfd78a19f98e31125a73761a --- base.mk | 3 + framework_manifest.xml | 10 ++ hal/meizu-vibrator/Android.bp | 31 ++++ hal/meizu-vibrator/Vibrator.cpp | 140 ++++++++++++++++++ hal/meizu-vibrator/Vibrator.h | 60 ++++++++ ...oid.hardware.vibrator@1.3-service.meizu.rc | 4 + hal/meizu-vibrator/service.cpp | 72 +++++++++ sepolicy/file_contexts | 1 + sepolicy/hal.te | 11 ++ 9 files changed, 332 insertions(+) create mode 100644 hal/meizu-vibrator/Android.bp create mode 100644 hal/meizu-vibrator/Vibrator.cpp create mode 100644 hal/meizu-vibrator/Vibrator.h create mode 100644 hal/meizu-vibrator/android.hardware.vibrator@1.3-service.meizu.rc create mode 100644 hal/meizu-vibrator/service.cpp diff --git a/base.mk b/base.mk index 5d16dbe..f7d7618 100644 --- a/base.mk +++ b/base.mk @@ -207,3 +207,6 @@ PRODUCT_SYSTEM_DEFAULT_PROPERTIES += \ # AOSP overlays PRODUCT_PACKAGES += \ NavigationBarMode2ButtonOverlay + +PRODUCT_PACKAGES += \ + android.hardware.vibrator@1.3-service.meizu diff --git a/framework_manifest.xml b/framework_manifest.xml index cb37b49..1b45b4a 100644 --- a/framework_manifest.xml +++ b/framework_manifest.xml @@ -19,5 +19,15 @@ default + + + android.hardware.vibrator + hwbinder + 1.3 + + IVibrator + default + + diff --git a/hal/meizu-vibrator/Android.bp b/hal/meizu-vibrator/Android.bp new file mode 100644 index 0000000..4e3c1b9 --- /dev/null +++ b/hal/meizu-vibrator/Android.bp @@ -0,0 +1,31 @@ +// +// 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. +cc_binary { + name: "android.hardware.vibrator@1.3-service.meizu", + relative_install_path: "hw", + init_rc: ["android.hardware.vibrator@1.3-service.meizu.rc"], + srcs: ["service.cpp", "Vibrator.cpp"], + cflags: ["-Wall", "-Werror"], + shared_libs: [ + "libhidlbase", + "liblog", + "libutils", + "libhardware", + "android.hardware.vibrator@1.0", + "android.hardware.vibrator@1.1", + "android.hardware.vibrator@1.2", + "android.hardware.vibrator@1.3", + ], +} diff --git a/hal/meizu-vibrator/Vibrator.cpp b/hal/meizu-vibrator/Vibrator.cpp new file mode 100644 index 0000000..8f12987 --- /dev/null +++ b/hal/meizu-vibrator/Vibrator.cpp @@ -0,0 +1,140 @@ +/* + * 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 "VibratorService" + +#include + +#include +#include + +#include "Vibrator.h" + +#include +#include +#include +#include +#include +#include + +namespace android { +namespace hardware { +namespace vibrator { +namespace V1_3 { +namespace implementation { + +Vibrator::Vibrator(std::ofstream&& timeoutAndAmplitude, std::ofstream&& waveNumber, std::ofstream&& effectTrigger) : + mTimeoutAndAmplitude(std::move(timeoutAndAmplitude)), + mWaveNumber(std::move(waveNumber)), + mEffectTrigger(std::move(effectTrigger)) {} + +Return Vibrator::on(uint32_t timeout_ms) { + // Wave number 12 for vibrations slightly stronger than stock (13) + mWaveNumber << 12 << std::endl; + mTimeoutAndAmplitude << timeout_ms << std::endl; + if (!mTimeoutAndAmplitude) { + ALOGE("Failed to turn vibrator on (%d): %s", errno, strerror(errno)); + return Status::UNKNOWN_ERROR; + } + return Status::OK; +} + +Return Vibrator::off() { + mTimeoutAndAmplitude << 0 << std::endl; + if (!mTimeoutAndAmplitude) { + ALOGE("Failed to turn vibrator off (%d): %s", errno, strerror(errno)); + return Status::UNKNOWN_ERROR; + } + return Status::OK; +} + +Return Vibrator::supportsAmplitudeControl() { + return false; +} + +Return Vibrator::setAmplitude(uint8_t) { + return Status::UNSUPPORTED_OPERATION; +} + +Return Vibrator::perform(V1_0::Effect effect, EffectStrength strength, perform_cb _hidl_cb) { + return perform(effect, strength, _hidl_cb); +} + +Return Vibrator::perform_1_1(V1_1::Effect_1_1 effect, EffectStrength strength, perform_cb _hidl_cb) { + return perform(effect, strength, _hidl_cb); +} + +Return Vibrator::perform_1_2(V1_2::Effect effect, EffectStrength strength, perform_cb _hidl_cb) { + return perform(effect, strength, _hidl_cb); +} + +Return Vibrator::perform_1_3(Effect effect, EffectStrength strength, perform_cb _hidl_cb) { + return perform(effect, strength, _hidl_cb); +} + +Return Vibrator::supportsExternalControl() { + return false; +} + +Return Vibrator::setExternalControl(bool) { + return Status::UNSUPPORTED_OPERATION; +} + +Return Vibrator::perform(Effect effect, EffectStrength, perform_cb _hidl_cb) { + uint32_t id; + switch (effect) { + case Effect::CLICK: + id = 31008; + break; + case Effect::DOUBLE_CLICK: + id = 31003; + break; + case Effect::TICK: + case Effect::TEXTURE_TICK: + id = 21000; + break; + case Effect::THUD: + id = 30900; + break; + case Effect::POP: + id = 22520; + break; + case Effect::HEAVY_CLICK: + id = 30900; + break; + default: + _hidl_cb(Status::UNSUPPORTED_OPERATION, 0); + return Void(); + } + mEffectTrigger << id << std::endl; + _hidl_cb(Status::OK, 200); + return Void(); +} + +template Return Vibrator::perform(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 perform(static_cast(effect), strength, _hidl_cb); +} + +} // namespace implementation +} // namespace V1_3 +} // namespace vibrator +} // namespace hardware +} // namespace android diff --git a/hal/meizu-vibrator/Vibrator.h b/hal/meizu-vibrator/Vibrator.h new file mode 100644 index 0000000..df901aa --- /dev/null +++ b/hal/meizu-vibrator/Vibrator.h @@ -0,0 +1,60 @@ +/* + * 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 { + +using android::hardware::vibrator::V1_0::EffectStrength; +using android::hardware::vibrator::V1_0::Status; + +class Vibrator : public IVibrator { +public: + Vibrator(std::ofstream&& timeoutAndAmplitude, std::ofstream&& waveNumber, std::ofstream&& effectTrigger); + Return on(uint32_t timeoutMs) override; + Return off() override; + Return supportsAmplitudeControl() override; + Return setAmplitude(uint8_t amplitude) override; + 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; + Return supportsExternalControl() override; + Return setExternalControl(bool enabled) override; + +private: + Return perform(Effect effect, EffectStrength strength, perform_cb _hidl_cb); + template Return perform(T effect, EffectStrength strength, perform_cb _hidl_cb); + std::ofstream mTimeoutAndAmplitude; + std::ofstream mWaveNumber; + std::ofstream mEffectTrigger; +}; +} // namespace implementation +} // namespace V1_3 +} // namespace vibrator +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_VIBRATOR_V1_3_VIBRATOR_H diff --git a/hal/meizu-vibrator/android.hardware.vibrator@1.3-service.meizu.rc b/hal/meizu-vibrator/android.hardware.vibrator@1.3-service.meizu.rc new file mode 100644 index 0000000..ddf39c4 --- /dev/null +++ b/hal/meizu-vibrator/android.hardware.vibrator@1.3-service.meizu.rc @@ -0,0 +1,4 @@ +service vibrator.meizu /system/bin/hw/android.hardware.vibrator@1.3-service.meizu + class late_start + user system + group system diff --git a/hal/meizu-vibrator/service.cpp b/hal/meizu-vibrator/service.cpp new file mode 100644 index 0000000..1405dfb --- /dev/null +++ b/hal/meizu-vibrator/service.cpp @@ -0,0 +1,72 @@ +/* + * 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.meizu" + +#include +#include +#include +#include +#include + +#include "Vibrator.h" + +using android::hardware::configureRpcThreadpool; +using android::hardware::joinRpcThreadpool; +using android::hardware::vibrator::V1_3::IVibrator; +using android::hardware::vibrator::V1_3::implementation::Vibrator; +using namespace android; + +static const char *CONTROL_PATH_TIMEOUT = "/sys/class/timed_output/vibrator/enable"; +static const char *PATH_WAVE_NUMBER = "/sys/class/meizu/motor/waveform"; +static const char *CONTROL_PATH_EFFECT = "/sys/class/meizu/motor/on_off"; + +status_t registerVibratorService() { + std::ofstream timeoutAndAmplitude{CONTROL_PATH_TIMEOUT}; + if (!timeoutAndAmplitude) { + int error = errno; + ALOGE("Failed to open %s (%d): %s", CONTROL_PATH_TIMEOUT, error, strerror(error)); + return -error; + } + + std::ofstream waveNumber{PATH_WAVE_NUMBER}; + if (!waveNumber) { + int error = errno; + ALOGE("Failed to open %s (%d): %s", PATH_WAVE_NUMBER, error, strerror(error)); + return -error; + } + + std::ofstream effectTrigger{CONTROL_PATH_EFFECT}; + if (!effectTrigger) { + int error = errno; + ALOGE("Failed to open %s (%d): %s", CONTROL_PATH_EFFECT, error, strerror(error)); + return -error; + } + + sp vibrator = new Vibrator(std::move(timeoutAndAmplitude), std::move(waveNumber), std::move(effectTrigger)); + (void) vibrator->registerAsService(); // suppress unused-result warning + return OK; +} + +int main() { + configureRpcThreadpool(1, true); + status_t status = registerVibratorService(); + + if (status != OK) { + return status; + } + + joinRpcThreadpool(); +} diff --git a/sepolicy/file_contexts b/sepolicy/file_contexts index 7ab5e91..2b59077 100644 --- a/sepolicy/file_contexts +++ b/sepolicy/file_contexts @@ -12,6 +12,7 @@ /dev/dsm u:object_r:dmd_device:s0 /system/bin/hw/android.hardware.biometrics.fingerprint@2.1-service.oppo.compat u:object_r:hal_fingerprint_oppo_compat_exec:s0 +/system/bin/hw/android.hardware.vibrator@1.3-service.meizu u:object_r:hal_vibrator_default_exec:s0 /efs u:object_r:efs_file:s0 diff --git a/sepolicy/hal.te b/sepolicy/hal.te index cb44422..280ae2d 100644 --- a/sepolicy/hal.te +++ b/sepolicy/hal.te @@ -8,3 +8,14 @@ init_daemon_domain(hal_fingerprint_oppo_compat) type hal_fingerprint_oppo, domain; allow hal_fingerprint_oppo vendor_default_prop:property_service { set }; + +type vib_strength_sysfs, fs_type, sysfs_type; + +type hal_vibrator_default, domain; +hal_server_domain(hal_vibrator_default, hal_vibrator) + +type hal_vibrator_default_exec, exec_type, vendor_file_type, file_type; +init_daemon_domain(hal_vibrator_default) + +allow hal_vibrator_default vib_strength_sysfs:dir rw_dir_perms; +allow hal_vibrator_default vib_strength_sysfs:file rw_file_perms; -- 2.25.1