/* * Copyright (C) 2021 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 #include #include #include #include #include #include #include #include using ::aidl::android::hardware::ir::ConsumerIrFreqRange; namespace aidl::android::hardware::ir { class ConsumerIr : public BnConsumerIr { public: ConsumerIr(); private: ::ndk::ScopedAStatus getCarrierFreqs(std::vector* _aidl_return) override; ::ndk::ScopedAStatus transmit(int32_t in_carrierFreqHz, const std::vector& in_pattern) override; consumerir_device_t *mDevice = nullptr; }; ConsumerIr::ConsumerIr() { const hw_module_t *hw_module = NULL; int ret = hw_get_module(CONSUMERIR_HARDWARE_MODULE_ID, &hw_module); if (ret != 0) { ALOGE("hw_get_module %s failed: %d", CONSUMERIR_HARDWARE_MODULE_ID, ret); return; } ret = hw_module->methods->open(hw_module, CONSUMERIR_TRANSMITTER, (hw_device_t **) &mDevice); if (ret < 0) { // note - may want to make this a fatal error - otherwise the service will crash when it's used ALOGE("Can't open consumer IR transmitter, error: %d", ret); // in case it's modified mDevice = nullptr; } } ::ndk::ScopedAStatus ConsumerIr::getCarrierFreqs(std::vector* _aidl_return) { int32_t len = mDevice->get_num_carrier_freqs(mDevice); if (len < 0) { (*_aidl_return).clear(); return ::ndk::ScopedAStatus::ok(); } consumerir_freq_range_t *rangeAr = new consumerir_freq_range_t[len]; bool success = (mDevice->get_carrier_freqs(mDevice, len, rangeAr) >= 0); if (!success) { (*_aidl_return).clear(); return ::ndk::ScopedAStatus::ok(); } (*_aidl_return).resize(len); for (int32_t i = 0; i < len; i++) { (*_aidl_return)[i].minHz = static_cast(rangeAr[i].min); (*_aidl_return)[i].maxHz = static_cast(rangeAr[i].max); } return ::ndk::ScopedAStatus::ok(); } ::ndk::ScopedAStatus ConsumerIr::transmit(int32_t in_carrierFreqHz, const std::vector& in_pattern) { if (in_carrierFreqHz > 0) { mDevice->transmit(mDevice, in_carrierFreqHz, in_pattern.data(), in_pattern.size()); return ::ndk::ScopedAStatus::ok(); } else { return ::ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); } } } // namespace aidl::android::hardware::ir using aidl::android::hardware::ir::ConsumerIr; int main() { auto binder = ::ndk::SharedRefBase::make(); const std::string name = std::string() + ConsumerIr::descriptor + "/default"; CHECK_EQ(STATUS_OK, AServiceManager_addService(binder->asBinder().get(), name.c_str())) << "Failed to register " << name; ABinderProcess_setThreadPoolMaxThreadCount(0); ABinderProcess_joinThreadPool(); return EXIT_FAILURE; // should not reached }