From a271b57c99fae8111f6468f50b0555bb46f9d464 Mon Sep 17 00:00:00 2001 From: Sebastiano Barezzi Date: Sun, 18 Aug 2024 22:48:40 +0200 Subject: [PATCH] Rewrite IR HAL in AIDL Change-Id: Ie27056c065766ab802ee337ced921876726de5cb --- aidl/ir/Android.bp | 21 +++++ aidl/ir/ConsumerIr.cpp | 91 +++++++++++++++++++ aidl/ir/ConsumerIr.h | 27 ++++++ aidl/ir/android.hardware.ir-service.xiaomi.rc | 14 +++ .../ir/android.hardware.ir-service.xiaomi.xml | 11 +++ aidl/ir/service.cpp | 24 +++++ 6 files changed, 188 insertions(+) create mode 100644 aidl/ir/Android.bp create mode 100644 aidl/ir/ConsumerIr.cpp create mode 100644 aidl/ir/ConsumerIr.h create mode 100644 aidl/ir/android.hardware.ir-service.xiaomi.rc create mode 100644 aidl/ir/android.hardware.ir-service.xiaomi.xml create mode 100644 aidl/ir/service.cpp diff --git a/aidl/ir/Android.bp b/aidl/ir/Android.bp new file mode 100644 index 0000000..3cba7d7 --- /dev/null +++ b/aidl/ir/Android.bp @@ -0,0 +1,21 @@ +// +// SPDX-FileCopyrightText: 2024 The LineageOS Project +// SPDX-License-Identifier: Apache-2.0 +// + +cc_binary { + name: "android.hardware.ir-service.xiaomi", + relative_install_path: "hw", + vendor: true, + init_rc: ["android.hardware.ir-service.xiaomi.rc"], + vintf_fragments: ["android.hardware.ir-service.xiaomi.xml"], + srcs: [ + "ConsumerIr.cpp", + "service.cpp", + ], + shared_libs: [ + "libbase", + "libbinder_ndk", + "android.hardware.ir-V1-ndk", + ], +} diff --git a/aidl/ir/ConsumerIr.cpp b/aidl/ir/ConsumerIr.cpp new file mode 100644 index 0000000..8418c8c --- /dev/null +++ b/aidl/ir/ConsumerIr.cpp @@ -0,0 +1,91 @@ +/* + * SPDX-FileCopyrightText: 2017-2024 The LineageOS Project + * SPDX-License-Identifier: Apache-2.0 + */ + +#define LOG_TAG "ConsumerIr" + +#include "ConsumerIr.h" + +#include +#include +#include +#include + +using std::vector; + +namespace aidl { +namespace android { +namespace hardware { +namespace ir { + +static const std::string kIrDevice = "/dev/lirc0"; + +static const int kDutyCycle = 33; + +static vector kRangeVec{ + {.minHz = 30000, .maxHz = 60000}, +}; + +::ndk::ScopedAStatus ConsumerIr::getCarrierFreqs(vector* _aidl_return) { + *_aidl_return = kRangeVec; + + return ::ndk::ScopedAStatus::ok(); +} + +::ndk::ScopedAStatus ConsumerIr::transmit(int32_t carrierFreqHz, const vector& pattern) { + size_t entries = pattern.size(); + + if (entries == 0) { + return ::ndk::ScopedAStatus::ok(); + } + + int fd = open(kIrDevice.c_str(), O_RDWR); + if (fd < 0) { + LOG(ERROR) << "Failed to open " << kIrDevice << ", error " << fd; + + return ::ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); + } + + int rc = ioctl(fd, LIRC_SET_SEND_CARRIER, &carrierFreqHz); + if (rc < 0) { + LOG(ERROR) << "Failed to set carrier " << carrierFreqHz << ", error: " << errno; + + close(fd); + + return ::ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); + } + + rc = ioctl(fd, LIRC_SET_SEND_DUTY_CYCLE, &kDutyCycle); + if (rc < 0) { + LOG(ERROR) << "Failed to set duty cycle " << kDutyCycle << ", error: " << errno; + + close(fd); + + return ::ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); + } + + if ((entries & 1) != 0) { + rc = write(fd, pattern.data(), entries * sizeof(int32_t)); + } else { + rc = write(fd, pattern.data(), (entries - 1) * sizeof(int32_t)); + usleep(pattern[entries - 1]); + } + + if (rc < 0) { + LOG(ERROR) << "Failed to write pattern, " << entries << " entries, error: " << errno; + + close(fd); + + return ::ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); + } + + close(fd); + + return ::ndk::ScopedAStatus::ok(); +} + +} // namespace ir +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/aidl/ir/ConsumerIr.h b/aidl/ir/ConsumerIr.h new file mode 100644 index 0000000..61f8bb0 --- /dev/null +++ b/aidl/ir/ConsumerIr.h @@ -0,0 +1,27 @@ +/* + * SPDX-FileCopyrightText: 2024 The LineageOS Project + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include + +namespace aidl { +namespace android { +namespace hardware { +namespace ir { + +class ConsumerIr : public BnConsumerIr { + public: + ::ndk::ScopedAStatus getCarrierFreqs( + ::std::vector<::aidl::android::hardware::ir::ConsumerIrFreqRange>* _aidl_return) + override; + ::ndk::ScopedAStatus transmit(int32_t carrierFreqHz, + const ::std::vector& pattern) override; +}; + +} // namespace ir +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/aidl/ir/android.hardware.ir-service.xiaomi.rc b/aidl/ir/android.hardware.ir-service.xiaomi.rc new file mode 100644 index 0000000..3cbc77d --- /dev/null +++ b/aidl/ir/android.hardware.ir-service.xiaomi.rc @@ -0,0 +1,14 @@ +# +# SPDX-FileCopyrightText: 2024 The LineageOS Project +# SPDX-License-Identifier: Apache-2.0 +# + +on early-boot + # IR device + chown system system /dev/lirc0 + +service vendor.ir-default /vendor/bin/hw/android.hardware.ir-service.xiaomi + class hal + user system + group system + shutdown critical diff --git a/aidl/ir/android.hardware.ir-service.xiaomi.xml b/aidl/ir/android.hardware.ir-service.xiaomi.xml new file mode 100644 index 0000000..760539e --- /dev/null +++ b/aidl/ir/android.hardware.ir-service.xiaomi.xml @@ -0,0 +1,11 @@ + + + + android.hardware.ir + 1 + IConsumerIr/default + + diff --git a/aidl/ir/service.cpp b/aidl/ir/service.cpp new file mode 100644 index 0000000..02e69ef --- /dev/null +++ b/aidl/ir/service.cpp @@ -0,0 +1,24 @@ +/* + * SPDX-FileCopyrightText: 2024 The LineageOS Project + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "ConsumerIr.h" + +#include +#include +#include + +using aidl::android::hardware::ir::ConsumerIr; + +int main() { + ABinderProcess_setThreadPoolMaxThreadCount(0); + std::shared_ptr hal = ::ndk::SharedRefBase::make(); + + const std::string instance = std::string(ConsumerIr::descriptor) + "/default"; + binder_status_t status = AServiceManager_addService(hal->asBinder().get(), instance.c_str()); + CHECK_EQ(status, STATUS_OK); + + ABinderProcess_joinThreadPool(); + return EXIT_FAILURE; // should not reach +}