From 7ef308ad4ac49db9bbe048aa411613452db62b08 Mon Sep 17 00:00:00 2001 From: Demon Date: Wed, 20 Sep 2017 09:08:07 +0000 Subject: [PATCH] hidl: Convert IR HAL into a native binderized HAL Change-Id: I8ddae1ba36d5a9cc16f0937189ff250eff3e7935 --- consumerir/Android.mk | 25 --- consumerir/consumerir.c | 168 ------------------ hidl/consumerir/Android.bp | 32 ++++ hidl/consumerir/ConsumerIr.cpp | 102 +++++++++++ hidl/consumerir/ConsumerIr.h | 48 +++++ .../android.hardware.ir@1.0-service.xiaomi.rc | 4 + hidl/consumerir/service.cpp | 48 +++++ 7 files changed, 234 insertions(+), 193 deletions(-) delete mode 100644 consumerir/Android.mk delete mode 100644 consumerir/consumerir.c create mode 100644 hidl/consumerir/Android.bp create mode 100644 hidl/consumerir/ConsumerIr.cpp create mode 100644 hidl/consumerir/ConsumerIr.h create mode 100644 hidl/consumerir/android.hardware.ir@1.0-service.xiaomi.rc create mode 100644 hidl/consumerir/service.cpp diff --git a/consumerir/Android.mk b/consumerir/Android.mk deleted file mode 100644 index b51a5d9..0000000 --- a/consumerir/Android.mk +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2013 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. - -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) - -LOCAL_MODULE := consumerir.$(TARGET_BOARD_PLATFORM) -LOCAL_MODULE_RELATIVE_PATH := hw -LOCAL_SRC_FILES := consumerir.c -LOCAL_SHARED_LIBRARIES := liblog libcutils -LOCAL_MODULE_TAGS := optional - -include $(BUILD_SHARED_LIBRARY) diff --git a/consumerir/consumerir.c b/consumerir/consumerir.c deleted file mode 100644 index 5f7834a..0000000 --- a/consumerir/consumerir.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (C) 2013 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 "ConsumerIrLirc" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) - -static const consumerir_freq_range_t consumerir_freqs[] = { - {.min = 30000, .max = 60000}, -}; - -static int open_lircdev(void) -{ - char value[PROPERTY_VALUE_MAX] = {'\0'}; - property_get("ro.lirc.dev", value, "/dev/lirc0"); - int fd = open(value, O_RDWR); - if (fd < 0) { - ALOGE("failed to open %s error %d", value, fd); - return fd; - } - - return fd; -} - -static int consumerir_transmit(struct consumerir_device *dev __unused, - int carrier_freq, const int pattern[], int pattern_len) -{ - int total_time = 0; - long i; - int fd; - int rc; - char value[PROPERTY_VALUE_MAX] = {'\0'}; - int duty_cycle; - - fd = open_lircdev(); - if (fd < 0) { - return fd; - } - - rc = ioctl(fd, LIRC_SET_SEND_CARRIER, &carrier_freq); - if (rc < 0) { - ALOGE("failed to set carrier %d error %d", carrier_freq, rc); - goto out_close; - } - - property_get("ro.lirc.duty_cycle", value, "33"); - duty_cycle = atoi(value); - rc = ioctl(fd, LIRC_SET_SEND_DUTY_CYCLE, &duty_cycle); - if (rc < 0) { - ALOGE("failed to set duty cycle %d error %d", duty_cycle, rc); - goto out_close; - } - - if (pattern_len&1) { - rc = write(fd, pattern, sizeof(*pattern)*pattern_len); - } - else { - rc = write(fd, pattern, sizeof(*pattern)*(pattern_len-1)); - usleep(pattern[pattern_len-1]); - } - if (rc < 0) { - ALOGE("failed to write pattern %d error %d", pattern_len, rc); - goto out_close; - } - - rc = 0; - -out_close: - close(fd); - - return rc; -} - -static int consumerir_get_num_carrier_freqs(struct consumerir_device *dev __unused) -{ - return ARRAY_SIZE(consumerir_freqs); -} - -static int consumerir_get_carrier_freqs(struct consumerir_device *dev __unused, - size_t len, consumerir_freq_range_t *ranges) -{ - size_t to_copy = ARRAY_SIZE(consumerir_freqs); - - to_copy = len < to_copy ? len : to_copy; - memcpy(ranges, consumerir_freqs, to_copy * sizeof(consumerir_freq_range_t)); - return to_copy; -} - -static int consumerir_close(hw_device_t *dev) -{ - free(dev); - return 0; -} - -/* - * Generic device handling - */ -static int consumerir_open(const hw_module_t* module, const char* name, - hw_device_t** device) -{ - if (strcmp(name, CONSUMERIR_TRANSMITTER) != 0) { - return -EINVAL; - } - if (device == NULL) { - ALOGE("NULL device on open"); - return -EINVAL; - } - - int lircfd = open_lircdev(); - if (lircfd < 0) { - return lircfd; - } - close(lircfd); - - consumerir_device_t *dev = malloc(sizeof(consumerir_device_t)); - memset(dev, 0, sizeof(consumerir_device_t)); - - dev->common.tag = HARDWARE_DEVICE_TAG; - dev->common.version = 0; - dev->common.module = (struct hw_module_t*) module; - dev->common.close = consumerir_close; - - dev->transmit = consumerir_transmit; - dev->get_num_carrier_freqs = consumerir_get_num_carrier_freqs; - dev->get_carrier_freqs = consumerir_get_carrier_freqs; - - *device = (hw_device_t*) dev; - return 0; -} - -static struct hw_module_methods_t consumerir_module_methods = { - .open = consumerir_open, -}; - -consumerir_module_t HAL_MODULE_INFO_SYM = { - .common = { - .tag = HARDWARE_MODULE_TAG, - .module_api_version = CONSUMERIR_MODULE_API_VERSION_1_0, - .hal_api_version = HARDWARE_HAL_API_VERSION, - .id = CONSUMERIR_HARDWARE_MODULE_ID, - .name = "LIRC IR HAL", - .author = "Xiaomi Corporation", - .methods = &consumerir_module_methods, - }, -}; diff --git a/hidl/consumerir/Android.bp b/hidl/consumerir/Android.bp new file mode 100644 index 0000000..df525c8 --- /dev/null +++ b/hidl/consumerir/Android.bp @@ -0,0 +1,32 @@ +// +// Copyright (C) 2017-2018 The LineageOS 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.ir@1.0-service.xiaomi", + relative_install_path: "hw", + defaults: ["hidl_defaults"], + init_rc: ["android.hardware.ir@1.0-service.xiaomi.rc"], + srcs: ["service.cpp", "ConsumerIr.cpp"], + shared_libs: [ + "android.hardware.ir@1.0", + "libbase", + "libhardware", + "libhidlbase", + "libhidltransport", + "libhwbinder", + "libutils", + ], + proprietary: true, +} diff --git a/hidl/consumerir/ConsumerIr.cpp b/hidl/consumerir/ConsumerIr.cpp new file mode 100644 index 0000000..752db75 --- /dev/null +++ b/hidl/consumerir/ConsumerIr.cpp @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2017-2018 The LineageOS 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 "ConsumerIrService" + +#include +#include + +#include + +#include "ConsumerIr.h" + +namespace android { +namespace hardware { +namespace ir { +namespace V1_0 { +namespace implementation { + +#define LIRC_DEV_PATH "/dev/lirc0" + +static const int dutyCycle = 33; + +static hidl_vec rangeVec{ + {.min = 30000, .max = 60000}, +}; + +static int openLircDev() { + int fd = open(LIRC_DEV_PATH, O_RDWR); + + if (fd < 0) { + LOG(ERROR) << "failed to open " << LIRC_DEV_PATH << ", error " << fd; + } + + return fd; +} + +// Methods from ::android::hardware::ir::V1_0::IConsumerIr follow. +Return ConsumerIr::transmit(int32_t carrierFreq, const hidl_vec& pattern) { + size_t entries = pattern.size(); + int rc; + int lircFd; + + lircFd = openLircDev(); + if (lircFd < 0) { + return lircFd; + } + + rc = ioctl(lircFd, LIRC_SET_SEND_CARRIER, &carrierFreq); + if (rc < 0) { + LOG(ERROR) << "failed to set carrier " << carrierFreq << ", error: " << errno; + goto out_close; + } + + rc = ioctl(lircFd, LIRC_SET_SEND_DUTY_CYCLE, &dutyCycle); + if (rc < 0) { + LOG(ERROR) << "failed to set duty cycle " << dutyCycle << ", error: " << errno; + goto out_close; + } + + if ((entries & 1) != 0) { + rc = write(lircFd, pattern.data(), sizeof(int32_t) * entries); + } else { + rc = write(lircFd, pattern.data(), sizeof(int32_t) * (entries - 1)); + usleep(pattern[entries - 1]); + } + + if (rc < 0) { + LOG(ERROR) << "failed to write pattern " << pattern.size() << ", error: " << errno; + goto out_close; + } + + rc = 0; + +out_close: + close(lircFd); + + return rc == 0; +} + +Return ConsumerIr::getCarrierFreqs(getCarrierFreqs_cb _hidl_cb) { + _hidl_cb(true, rangeVec); + return Void(); +} + +} // namespace implementation +} // namespace V1_0 +} // namespace ir +} // namespace hardware +} // namespace android diff --git a/hidl/consumerir/ConsumerIr.h b/hidl/consumerir/ConsumerIr.h new file mode 100644 index 0000000..ad0c751 --- /dev/null +++ b/hidl/consumerir/ConsumerIr.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2017-2018 The LineageOS 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_IR_V1_0_IR_H +#define ANDROID_HARDWARE_IR_V1_0_IR_H + +#include +#include +#include + +namespace android { +namespace hardware { +namespace ir { +namespace V1_0 { +namespace implementation { + +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::hardware::hidl_vec; +using ::android::hardware::ir::V1_0::ConsumerIrFreqRange; +using ::android::hardware::ir::V1_0::IConsumerIr; + +class ConsumerIr : public IConsumerIr { + // Methods from ::android::hardware::ir::V1_0::IConsumerIr follow. + Return transmit(int32_t carrierFreq, const hidl_vec& pattern) override; + Return getCarrierFreqs(getCarrierFreqs_cb _hidl_cb) override; +}; + +} // namespace implementation +} // namespace V1_0 +} // namespace ir +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_IR_V1_0_IR_H diff --git a/hidl/consumerir/android.hardware.ir@1.0-service.xiaomi.rc b/hidl/consumerir/android.hardware.ir@1.0-service.xiaomi.rc new file mode 100644 index 0000000..03bd661 --- /dev/null +++ b/hidl/consumerir/android.hardware.ir@1.0-service.xiaomi.rc @@ -0,0 +1,4 @@ +service ir-hal-1-0 /vendor/bin/hw/android.hardware.ir@1.0-service.xiaomi + class hal + user system + group system diff --git a/hidl/consumerir/service.cpp b/hidl/consumerir/service.cpp new file mode 100644 index 0000000..a668503 --- /dev/null +++ b/hidl/consumerir/service.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2017-2018 The LineageOS 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.ir@1.0-service.xiaomi" + +#include +#include + +#include "ConsumerIr.h" + +// libhwbinder: +using android::hardware::configureRpcThreadpool; +using android::hardware::joinRpcThreadpool; + +// Generated HIDL files +using android::hardware::ir::V1_0::IConsumerIr; +using android::hardware::ir::V1_0::implementation::ConsumerIr; + +int main() { + android::sp service = new ConsumerIr(); + + configureRpcThreadpool(1, true /*callerWillJoin*/); + + android::status_t status = service->registerAsService(); + if (status != android::OK) { + LOG(ERROR) << "Cannot register ConsumerIr HAL service"; + return 1; + } + + LOG(INFO) << "ConsumerIr HAL Ready."; + joinRpcThreadpool(); + // Under normal cases, execution will not reach this line. + LOG(ERROR) << "ConsumerIr HAL failed to join thread pool."; + return 1; +}