diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml index 8a7804f3f3..fcff6bcbd4 100644 --- a/compatibility_matrices/compatibility_matrix.current.xml +++ b/compatibility_matrices/compatibility_matrix.current.xml @@ -299,9 +299,9 @@ default - + android.hardware.ir - 1.0 + 1 IConsumerIr default diff --git a/ir/aidl/Android.bp b/ir/aidl/Android.bp new file mode 100644 index 0000000000..8741157dcd --- /dev/null +++ b/ir/aidl/Android.bp @@ -0,0 +1,35 @@ +// 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. + +aidl_interface { + name: "android.hardware.ir", + vendor_available: true, + srcs: ["android/hardware/ir/*.aidl"], + stability: "vintf", + backend: { + cpp: { + enabled: false, + }, + java: { + sdk_version: "module_current", + }, + ndk: { + separate_platform_variant: false, + vndk: { + // TODO(b/206116595) enable this + enabled: false, + }, + }, + }, +} diff --git a/ir/aidl/aidl_api/android.hardware.ir/current/android/hardware/ir/ConsumerIrFreqRange.aidl b/ir/aidl/aidl_api/android.hardware.ir/current/android/hardware/ir/ConsumerIrFreqRange.aidl new file mode 100644 index 0000000000..4a0d286938 --- /dev/null +++ b/ir/aidl/aidl_api/android.hardware.ir/current/android/hardware/ir/ConsumerIrFreqRange.aidl @@ -0,0 +1,39 @@ +/* + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.ir; +@VintfStability +parcelable ConsumerIrFreqRange { + int minHz; + int maxHz; +} diff --git a/ir/aidl/aidl_api/android.hardware.ir/current/android/hardware/ir/IConsumerIr.aidl b/ir/aidl/aidl_api/android.hardware.ir/current/android/hardware/ir/IConsumerIr.aidl new file mode 100644 index 0000000000..056a8b1235 --- /dev/null +++ b/ir/aidl/aidl_api/android.hardware.ir/current/android/hardware/ir/IConsumerIr.aidl @@ -0,0 +1,39 @@ +/* + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.ir; +@VintfStability +interface IConsumerIr { + android.hardware.ir.ConsumerIrFreqRange[] getCarrierFreqs(); + void transmit(in int carrierFreq, in int[] pattern); +} diff --git a/ir/aidl/android/hardware/ir/ConsumerIrFreqRange.aidl b/ir/aidl/android/hardware/ir/ConsumerIrFreqRange.aidl new file mode 100644 index 0000000000..ab0276ae54 --- /dev/null +++ b/ir/aidl/android/hardware/ir/ConsumerIrFreqRange.aidl @@ -0,0 +1,23 @@ +/* + * 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. + */ + +package android.hardware.ir; + +@VintfStability +parcelable ConsumerIrFreqRange { + int minHz; + int maxHz; +} diff --git a/ir/aidl/android/hardware/ir/IConsumerIr.aidl b/ir/aidl/android/hardware/ir/IConsumerIr.aidl new file mode 100644 index 0000000000..d14fa566bc --- /dev/null +++ b/ir/aidl/android/hardware/ir/IConsumerIr.aidl @@ -0,0 +1,45 @@ +/* + * 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. + */ + +package android.hardware.ir; + +import android.hardware.ir.ConsumerIrFreqRange; + +@VintfStability +interface IConsumerIr { + /** + * Enumerates which frequencies the IR transmitter supports. + * + * Status OK (EX_NONE) on success. + * + * @return - an array of all supported frequency ranges. + */ + ConsumerIrFreqRange[] getCarrierFreqs(); + + /** + * Sends an IR pattern at a given frequency in HZ. + * + * The pattern is alternating series of carrier on and off periods measured in + * microseconds. The carrier should be turned off at the end of a transmit + * even if there are and odd number of entries in the pattern array. + * + * This call must return when the transmit is complete or encounters an error. + * + * Status OK (EX_NONE) on success. + * EX_UNSUPPORTED_OPERATION when the frequency is not supported. + */ + void transmit(in int carrierFreq, in int[] pattern); +} diff --git a/ir/aidl/default/Android.bp b/ir/aidl/default/Android.bp new file mode 100644 index 0000000000..6519664dec --- /dev/null +++ b/ir/aidl/default/Android.bp @@ -0,0 +1,33 @@ +// 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. + +// Example binder service of the ir HAL. +cc_binary { + name: "android.hardware.ir-service.example", + relative_install_path: "hw", + init_rc: ["android.hardware.ir-service.example.rc"], + vendor: true, + vintf_fragments: ["android.hardware.ir-service.example.xml"], + + shared_libs: [ + "libbase", + "libbinder_ndk", + "libcutils", + "liblog", + "libutils", + "android.hardware.ir-V1-ndk", + ], + + srcs: ["main.cpp"], +} diff --git a/ir/aidl/default/android.hardware.ir-service.example.rc b/ir/aidl/default/android.hardware.ir-service.example.rc new file mode 100644 index 0000000000..56def64a90 --- /dev/null +++ b/ir/aidl/default/android.hardware.ir-service.example.rc @@ -0,0 +1,4 @@ +service vendor.ir-default /vendor/bin/hw/android.hardware.ir-service.example + class hal + user nobody + group nobody diff --git a/ir/aidl/default/android.hardware.ir-service.example.xml b/ir/aidl/default/android.hardware.ir-service.example.xml new file mode 100644 index 0000000000..1a63520f34 --- /dev/null +++ b/ir/aidl/default/android.hardware.ir-service.example.xml @@ -0,0 +1,7 @@ + + + android.hardware.ir + 1 + IConsumerIr/default + + diff --git a/ir/aidl/default/main.cpp b/ir/aidl/default/main.cpp new file mode 100644 index 0000000000..764aeaf641 --- /dev/null +++ b/ir/aidl/default/main.cpp @@ -0,0 +1,77 @@ +/* + * 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 + +namespace aidl::android::hardware::ir { + +const std::vector kSupportedFreqs = { + {2000, 4000}, + {10000, 30000}, +}; + +class ConsumerIr : public BnConsumerIr { + ::ndk::ScopedAStatus getCarrierFreqs(std::vector* _aidl_return) override; + ::ndk::ScopedAStatus transmit(int32_t in_carrierFreq, + const std::vector& in_pattern) override; +}; + +::ndk::ScopedAStatus ConsumerIr::getCarrierFreqs(std::vector* _aidl_return) { + *_aidl_return = kSupportedFreqs; + return ::ndk::ScopedAStatus::ok(); +} + +bool isSupportedFreq(int32_t freq) { + for (const auto& range : kSupportedFreqs) { + if (freq >= range.minHz && freq <= range.maxHz) return true; + } + return false; +} + +::ndk::ScopedAStatus ConsumerIr::transmit(int32_t in_carrierFreq, + const std::vector& in_pattern) { + if (isSupportedFreq(in_carrierFreq)) { + // trasmit the pattern, each integer is number of microseconds in an + // alternating on/off state. + usleep(std::accumulate(in_pattern.begin(), in_pattern.end(), 0)); + return ::ndk::ScopedAStatus::ok(); + } else { + // unsupported operation + return ::ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); + } + return ::ndk::ScopedAStatus::ok(); +} + +} // 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 +} diff --git a/ir/aidl/vts/Android.bp b/ir/aidl/vts/Android.bp new file mode 100644 index 0000000000..c2491b8922 --- /dev/null +++ b/ir/aidl/vts/Android.bp @@ -0,0 +1,43 @@ +// +// 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. +// + +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + +cc_test { + name: "VtsHalIrTargetTest", + defaults: [ + "VtsHalTargetTestDefaults", + "use_libaidlvintf_gtest_helper_static", + ], + srcs: ["VtsHalIrTargetTest.cpp"], + shared_libs: [ + "libbinder_ndk", + ], + static_libs: [ + "android.hardware.ir-V1-ndk", + ], + test_suites: [ + "general-tests", + "vts", + ], +} diff --git a/ir/aidl/vts/VtsHalIrTargetTest.cpp b/ir/aidl/vts/VtsHalIrTargetTest.cpp new file mode 100644 index 0000000000..3527625ae6 --- /dev/null +++ b/ir/aidl/vts/VtsHalIrTargetTest.cpp @@ -0,0 +1,77 @@ +/* + * 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. + */ + +#define LOG_TAG "ir_aidl_hal_test" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using ::aidl::android::hardware::ir::ConsumerIrFreqRange; +using ::aidl::android::hardware::ir::IConsumerIr; +using ::ndk::SpAIBinder; + +class ConsumerIrTest : public ::testing::TestWithParam { + public: + virtual void SetUp() override { + mIr = IConsumerIr::fromBinder( + SpAIBinder(AServiceManager_waitForService(GetParam().c_str()))); + ASSERT_NE(mIr, nullptr); + } + + std::shared_ptr mIr; +}; + +// Test transmit() for the min and max frequency of every available range +TEST_P(ConsumerIrTest, TransmitTest) { + std::vector ranges; + const auto& ret = mIr->getCarrierFreqs(&ranges); + ASSERT_TRUE(ret.isOk()); + + if (ranges.size() > 0) { + uint32_t len = 16; + std::vector vec; + vec.resize(len); + std::fill(vec.begin(), vec.end(), 1000); + for (auto range = ranges.begin(); range != ranges.end(); range++) { + EXPECT_TRUE(mIr->transmit(range->minHz, vec).isOk()); + EXPECT_TRUE(mIr->transmit(range->maxHz, vec).isOk()); + } + } +} + +// Test transmit() when called with invalid frequencies +TEST_P(ConsumerIrTest, BadFreqTest) { + uint32_t len = 16; + std::vector vec; + vec.resize(len); + std::fill(vec.begin(), vec.end(), 1); + const auto& res = mIr->transmit(-1, vec); + EXPECT_FALSE(res.isOk()); + EXPECT_EQ(res.getExceptionCode(), EX_UNSUPPORTED_OPERATION); +} + +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ConsumerIrTest); +INSTANTIATE_TEST_SUITE_P( + PerInstance, ConsumerIrTest, + testing::ValuesIn(android::getAidlHalInstanceNames(IConsumerIr::descriptor)), + ::android::PrintInstanceNameToString);