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);