Refactor HDMI related AIDL packages

Move CEC, EArc and the old "HDMI" package in to one common hdmi package
as cec, earc and connection.

Test: Build
Bug: 261729059

Change-Id: Ic657713e3a4078125e211bb0d337519a9192aaa1
diff --git a/tv/hdmi/earc/aidl/default/Android.bp b/tv/hdmi/earc/aidl/default/Android.bp
new file mode 100644
index 0000000..5d56c2a
--- /dev/null
+++ b/tv/hdmi/earc/aidl/default/Android.bp
@@ -0,0 +1,58 @@
+// Copyright (C) 2022 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 {
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_binary {
+    name: "android.hardware.tv.hdmi.earc-service",
+    vintf_fragments: ["android.hardware.tv.hdmi.earc-service.xml"],
+    relative_install_path: "hw",
+    vendor: true,
+    cflags: [
+        "-Wall",
+        "-Wextra",
+    ],
+    init_rc: ["android.hardware.tv.hdmi.earc-service.rc"],
+    srcs: [
+        "serviceMock.cpp",
+        "EArcMock.cpp",
+    ],
+    shared_libs: [
+        "libbinder_ndk",
+        "liblog",
+        "libbase",
+        "libutils",
+        "libhardware",
+        "libhidlbase",
+        "android.hardware.tv.hdmi.earc-V1-ndk",
+    ],
+}
+
+cc_fuzz {
+    name: "android.hardware.tv.hdmi.earc-service_fuzzer",
+    defaults: ["service_fuzzer_defaults"],
+    static_libs: [
+        "android.hardware.tv.hdmi.earc-V1-ndk",
+        "liblog",
+    ],
+    srcs: [
+        "fuzzer.cpp",
+        "EArcMock.cpp",
+    ],
+    fuzz_config: {
+        componentid: 826094,
+    },
+}
diff --git a/tv/hdmi/earc/aidl/default/EArcMock.cpp b/tv/hdmi/earc/aidl/default/EArcMock.cpp
new file mode 100644
index 0000000..3578999
--- /dev/null
+++ b/tv/hdmi/earc/aidl/default/EArcMock.cpp
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2022 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 "android.hardware.tv.hdmi.earc"
+#include <android-base/logging.h>
+#include <fcntl.h>
+#include <utils/Log.h>
+
+#include "EArcMock.h"
+
+using ndk::ScopedAStatus;
+
+namespace android {
+namespace hardware {
+namespace tv {
+namespace hdmi {
+namespace earc {
+namespace implementation {
+
+void EArcMock::serviceDied(void* cookie) {
+    ALOGE("EArcMock died");
+    auto eArc = static_cast<EArcMock*>(cookie);
+    eArc->mEArcEnabled = false;
+}
+
+ScopedAStatus EArcMock::setEArcEnabled(bool in_enabled) {
+    mEArcEnabled = in_enabled;
+    if (mEArcEnabled != in_enabled) {
+        return ScopedAStatus::fromServiceSpecificError(
+                static_cast<int32_t>(Result::FAILURE_UNKNOWN));
+    } else {
+        return ScopedAStatus::ok();
+    }
+}
+
+ScopedAStatus EArcMock::isEArcEnabled(bool* _aidl_return) {
+    *_aidl_return = mEArcEnabled;
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus EArcMock::getState(int32_t portId, IEArcStatus* _aidl_return) {
+    // Maintain port connection status and update on hotplug event
+    if (portId <= mTotalPorts && portId >= 1) {
+        *_aidl_return = mPortStatus[portId];
+    } else {
+        return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus EArcMock::getLastReportedAudioCapabilities(int32_t portId,
+                                                         std::vector<uint8_t>* _aidl_return) {
+    if (portId <= mTotalPorts && portId >= 1) {
+        *_aidl_return = mCapabilities[portId];
+    } else {
+        return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus EArcMock::setCallback(const std::shared_ptr<IEArcCallback>& callback) {
+    if (mCallback != nullptr) {
+        mCallback = nullptr;
+    }
+
+    if (callback != nullptr) {
+        mCallback = callback;
+        AIBinder_linkToDeath(this->asBinder().get(), mDeathRecipient.get(), 0 /* cookie */);
+    }
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus EArcMock::reportCapabilities(const std::vector<uint8_t> capabilities,
+                                           int32_t portId) {
+    if (mCallback != nullptr) {
+        mCallback->onCapabilitiesReported(capabilities, portId);
+        return ScopedAStatus::ok();
+    } else {
+        return ScopedAStatus::fromExceptionCode(EX_NULL_POINTER);
+    }
+}
+
+ScopedAStatus EArcMock::changeState(const IEArcStatus status, int32_t portId) {
+    if (mCallback != nullptr) {
+        mCallback->onStateChange(status, portId);
+        return ScopedAStatus::ok();
+    } else {
+        return ScopedAStatus::fromExceptionCode(EX_NULL_POINTER);
+    }
+}
+
+EArcMock::EArcMock() {
+    ALOGE("[halimp_aidl] Opening a virtual eARC HAL for testing and virtual machine.");
+    mCallback = nullptr;
+    mCapabilities.resize(mTotalPorts);
+    mPortStatus.resize(mTotalPorts);
+    mPortStatus[0] = IEArcStatus::STATUS_IDLE;
+    mDeathRecipient = ndk::ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient_new(serviceDied));
+}
+
+}  // namespace implementation
+}  // namespace earc
+}  // namespace hdmi
+}  // namespace tv
+}  // namespace hardware
+}  // namespace android
diff --git a/tv/hdmi/earc/aidl/default/EArcMock.h b/tv/hdmi/earc/aidl/default/EArcMock.h
new file mode 100644
index 0000000..fc4c828
--- /dev/null
+++ b/tv/hdmi/earc/aidl/default/EArcMock.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2022 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 <aidl/android/hardware/tv/hdmi/earc/BnEArc.h>
+#include <aidl/android/hardware/tv/hdmi/earc/Result.h>
+#include <algorithm>
+#include <vector>
+
+using namespace std;
+
+namespace android {
+namespace hardware {
+namespace tv {
+namespace hdmi {
+namespace earc {
+namespace implementation {
+
+using ::aidl::android::hardware::tv::hdmi::earc::BnEArc;
+using ::aidl::android::hardware::tv::hdmi::earc::IEArc;
+using ::aidl::android::hardware::tv::hdmi::earc::IEArcCallback;
+using ::aidl::android::hardware::tv::hdmi::earc::IEArcStatus;
+using ::aidl::android::hardware::tv::hdmi::earc::Result;
+
+struct EArcMock : public BnEArc {
+    EArcMock();
+
+    ::ndk::ScopedAStatus setEArcEnabled(bool in_enabled) override;
+    ::ndk::ScopedAStatus isEArcEnabled(bool* _aidl_return) override;
+    ::ndk::ScopedAStatus setCallback(const std::shared_ptr<IEArcCallback>& in_callback) override;
+    ::ndk::ScopedAStatus getState(int32_t in_portId, IEArcStatus* _aidl_return) override;
+    ::ndk::ScopedAStatus getLastReportedAudioCapabilities(
+            int32_t in_portId, std::vector<uint8_t>* _aidl_return) override;
+    ::ndk::ScopedAStatus reportCapabilities(const std::vector<uint8_t> capabilities,
+                                            int32_t portId);
+    ::ndk::ScopedAStatus changeState(const IEArcStatus status, int32_t portId);
+
+  private:
+    static void* __threadLoop(void* data);
+    void threadLoop();
+
+  private:
+    static void serviceDied(void* cookie);
+    std::shared_ptr<IEArcCallback> mCallback;
+
+    // Variables for the virtual EARC hal impl
+    std::vector<std::vector<uint8_t>> mCapabilities;
+    std::vector<IEArcStatus> mPortStatus;
+    bool mEArcEnabled = true;
+
+    // Port configuration
+    int mTotalPorts = 1;
+
+    // Testing variables
+    pthread_t mThreadId = 0;
+
+    ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
+};
+}  // namespace implementation
+}  // namespace earc
+}  // Namespace hdmi
+}  // Namespace tv
+}  // namespace hardware
+}  // namespace android
diff --git a/tv/hdmi/earc/aidl/default/android.hardware.tv.hdmi.earc-service.rc b/tv/hdmi/earc/aidl/default/android.hardware.tv.hdmi.earc-service.rc
new file mode 100644
index 0000000..53bec04
--- /dev/null
+++ b/tv/hdmi/earc/aidl/default/android.hardware.tv.hdmi.earc-service.rc
@@ -0,0 +1,5 @@
+service vendor.earc-default /vendor/bin/hw/android.hardware.tv.hdmi.earc-service
+    interface aidl android.hardware.tv.hdmi.earc.IEArc/default
+    class hal
+    user system
+    group system
diff --git a/tv/hdmi/earc/aidl/default/android.hardware.tv.hdmi.earc-service.xml b/tv/hdmi/earc/aidl/default/android.hardware.tv.hdmi.earc-service.xml
new file mode 100644
index 0000000..6f8d03d
--- /dev/null
+++ b/tv/hdmi/earc/aidl/default/android.hardware.tv.hdmi.earc-service.xml
@@ -0,0 +1,10 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.tv.hdmi.earc</name>
+        <version>1</version>
+        <interface>
+            <name>IEArc</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+</manifest>
diff --git a/tv/hdmi/earc/aidl/default/fuzzer.cpp b/tv/hdmi/earc/aidl/default/fuzzer.cpp
new file mode 100644
index 0000000..25264ae
--- /dev/null
+++ b/tv/hdmi/earc/aidl/default/fuzzer.cpp
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2022 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 <EArcMock.h>
+#include <fuzzbinder/libbinder_ndk_driver.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+using android::fuzzService;
+using android::hardware::tv::hdmi::earc::implementation::EArcMock;
+using ndk::SharedRefBase;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    auto earcAidl = SharedRefBase::make<EArcMock>();
+
+    fuzzService(earcAidl->asBinder().get(), FuzzedDataProvider(data, size));
+
+    return 0;
+}
diff --git a/tv/hdmi/earc/aidl/default/serviceMock.cpp b/tv/hdmi/earc/aidl/default/serviceMock.cpp
new file mode 100644
index 0000000..0878e76
--- /dev/null
+++ b/tv/hdmi/earc/aidl/default/serviceMock.cpp
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 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 "android.hardware.tv.hdmi.earc-service-shim"
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <hidl/HidlTransportSupport.h>
+#include <utils/Log.h>
+#include "EArcMock.h"
+
+using android::hardware::tv::hdmi::earc::implementation::EArcMock;
+
+int main() {
+    ABinderProcess_setThreadPoolMaxThreadCount(1);
+    ABinderProcess_startThreadPool();
+
+    std::shared_ptr<EArcMock> earcAidl = ndk::SharedRefBase::make<EArcMock>();
+    const std::string instance = std::string() + EArcMock::descriptor + "/default";
+    binder_status_t status =
+            AServiceManager_addService(earcAidl->asBinder().get(), instance.c_str());
+    CHECK_EQ(status, STATUS_OK);
+
+    ABinderProcess_joinThreadPool();
+    return 0;
+}