diff --git a/device.mk b/device.mk index 17acd00..94fc498 100644 --- a/device.mk +++ b/device.mk @@ -138,7 +138,8 @@ PRODUCT_COPY_FILES += \ # CEC PRODUCT_PACKAGES += \ - android.hardware.tv.hdmi.cec-service.rpi + android.hardware.tv.hdmi.cec-service.rpi \ + android.hardware.tv.hdmi.connection-service.rpi PRODUCT_COPY_FILES += \ frameworks/native/data/etc/android.hardware.hdmi.cec.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.hdmi.cec.xml diff --git a/hdmi/connection/Android.bp b/hdmi/connection/Android.bp new file mode 100644 index 0000000..9b2a684 --- /dev/null +++ b/hdmi/connection/Android.bp @@ -0,0 +1,22 @@ +// Copyright (C) 2022 The Android Open Source Project +// Copyright (C) 2025 KonstaKANG +// +// SPDX-License-Identifier: Apache-2.0 + +cc_binary { + name: "android.hardware.tv.hdmi.connection-service.rpi", + relative_install_path: "hw", + init_rc: ["android.hardware.tv.hdmi.connection-service.rpi.rc"], + vintf_fragments: ["android.hardware.tv.hdmi.connection-service.rpi.xml"], + vendor: true, + srcs: [ + "HdmiConnection.cpp", + "main.cpp", + ], + shared_libs: [ + "android.hardware.tv.hdmi.connection-V1-ndk", + "libbase", + "libbinder_ndk", + "liblog", + ], +} diff --git a/hdmi/connection/HdmiConnection.cpp b/hdmi/connection/HdmiConnection.cpp new file mode 100644 index 0000000..c152edb --- /dev/null +++ b/hdmi/connection/HdmiConnection.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * Copyright (C) 2025 KonstaKANG + * + * 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.connection-service.rpi" + +#include "HdmiConnection.h" + +#include +#include + +using android::base::ReadFileToString; +using ndk::ScopedAStatus; +using std::string; + +namespace android { +namespace hardware { +namespace tv { +namespace hdmi { +namespace connection { +namespace implementation { + +static const string drmCard = "card1"; + +HdmiConnection::HdmiConnection() { + mCallback = nullptr; + + for (int i = 0; i < 2; i++) { + mPortInfos.push_back( + {.type = HdmiPortType::OUTPUT, + .portId = i, + .cecSupported = true, + .arcSupported = false, + .eArcSupported = false, + .physicalAddress = 0xFFFF}); + mHpdSignal.push_back(HpdSignal::HDMI_HPD_PHYSICAL); + } +} + +HdmiConnection::~HdmiConnection() { + if (mCallback != nullptr) { + mCallback = nullptr; + } +} + +ScopedAStatus HdmiConnection::getPortInfo(std::vector* _aidl_return) { + *_aidl_return = mPortInfos; + return ScopedAStatus::ok(); +} + +ScopedAStatus HdmiConnection::isConnected(int32_t portId, bool* _aidl_return) { + if (portId != 0 && portId != 1) { + *_aidl_return = false; + return ScopedAStatus::ok(); + } + + bool connected = false; + string hdmiStatusPath = "/sys/class/drm/" + drmCard + "-HDMI-A-" + to_string(portId + 1) + "/status"; + if (!access(hdmiStatusPath.c_str(), R_OK)) { + string connectedValue; + if (ReadFileToString(hdmiStatusPath, &connectedValue)) { + connected = !connectedValue.compare("connected\n"); + } + } + LOG(INFO) << "portId: " << portId << ", connected: " << connected; + + *_aidl_return = connected; + return ScopedAStatus::ok(); +} + +ScopedAStatus HdmiConnection::setCallback(const std::shared_ptr& callback) { + if (mCallback != nullptr) { + mCallback = nullptr; + } + + if (callback != nullptr) { + mCallback = callback; + } + + return ScopedAStatus::ok(); +} + +ScopedAStatus HdmiConnection::setHpdSignal(HpdSignal signal, int32_t portId) { + if (portId != 0 && portId != 1) { + return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + + mHpdSignal.at(portId) = signal; + return ScopedAStatus::ok(); +} + +ScopedAStatus HdmiConnection::getHpdSignal(int32_t portId, HpdSignal* _aidl_return) { + if (portId != 0 && portId != 1) { + return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + } + + *_aidl_return = mHpdSignal.at(portId); + return ScopedAStatus::ok(); +} + +} // namespace implementation +} // namespace connection +} // namespace hdmi +} // namespace tv +} // namespace hardware +} // namespace android diff --git a/hdmi/connection/HdmiConnection.h b/hdmi/connection/HdmiConnection.h new file mode 100644 index 0000000..716b9da --- /dev/null +++ b/hdmi/connection/HdmiConnection.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * Copyright (C) 2025 KonstaKANG + * + * 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 + +using namespace std; + +namespace android { +namespace hardware { +namespace tv { +namespace hdmi { +namespace connection { +namespace implementation { + +using ::aidl::android::hardware::tv::hdmi::connection::BnHdmiConnection; +using ::aidl::android::hardware::tv::hdmi::connection::HdmiPortInfo; +using ::aidl::android::hardware::tv::hdmi::connection::HdmiPortType; +using ::aidl::android::hardware::tv::hdmi::connection::HpdSignal; +using ::aidl::android::hardware::tv::hdmi::connection::IHdmiConnection; +using ::aidl::android::hardware::tv::hdmi::connection::IHdmiConnectionCallback; +using ::aidl::android::hardware::tv::hdmi::connection::Result; + +struct HdmiConnection : public BnHdmiConnection { + HdmiConnection(); + ~HdmiConnection(); + ::ndk::ScopedAStatus getPortInfo(std::vector* _aidl_return) override; + ::ndk::ScopedAStatus isConnected(int32_t portId, bool* _aidl_return) override; + ::ndk::ScopedAStatus setCallback( + const std::shared_ptr& callback) override; + ::ndk::ScopedAStatus setHpdSignal(HpdSignal signal, int32_t portId) override; + ::ndk::ScopedAStatus getHpdSignal(int32_t portId, HpdSignal* _aidl_return) override; + + private: + std::vector mPortInfos; + std::vector mHpdSignal; + + std::shared_ptr mCallback; +}; + +} // namespace implementation +} // namespace connection +} // namespace hdmi +} // Namespace tv +} // namespace hardware +} // namespace android diff --git a/hdmi/connection/android.hardware.tv.hdmi.connection-service.rpi.rc b/hdmi/connection/android.hardware.tv.hdmi.connection-service.rpi.rc new file mode 100644 index 0000000..7087f19 --- /dev/null +++ b/hdmi/connection/android.hardware.tv.hdmi.connection-service.rpi.rc @@ -0,0 +1,5 @@ +service vendor.hdmi-default /vendor/bin/hw/android.hardware.tv.hdmi.connection-service.rpi + interface aidl android.hardware.tv.hdmi.connection.IHdmiConnection/default + class hal + user system + group system diff --git a/hdmi/connection/android.hardware.tv.hdmi.connection-service.rpi.xml b/hdmi/connection/android.hardware.tv.hdmi.connection-service.rpi.xml new file mode 100644 index 0000000..144fef1 --- /dev/null +++ b/hdmi/connection/android.hardware.tv.hdmi.connection-service.rpi.xml @@ -0,0 +1,10 @@ + + + android.hardware.tv.hdmi.connection + 1 + + IHdmiConnection + default + + + diff --git a/hdmi/connection/main.cpp b/hdmi/connection/main.cpp new file mode 100644 index 0000000..2b1f991 --- /dev/null +++ b/hdmi/connection/main.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * Copyright (C) 2025 KonstaKANG + * + * 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 "HdmiConnection.h" + +#include +#include +#include + +using android::hardware::tv::hdmi::connection::implementation::HdmiConnection; + +int main() { + ABinderProcess_setThreadPoolMaxThreadCount(1); + ABinderProcess_startThreadPool(); + + std::shared_ptr hdmiAidl = ndk::SharedRefBase::make(); + const std::string instance = std::string() + HdmiConnection::descriptor + "/default"; + binder_status_t status = AServiceManager_addService(hdmiAidl->asBinder().get(), instance.c_str()); + CHECK_EQ(status, STATUS_OK); + + ABinderProcess_joinThreadPool(); + return EXIT_FAILURE; // should not reach +} diff --git a/sepolicy/file.te b/sepolicy/file.te index 3afd706..8c3f935 100644 --- a/sepolicy/file.te +++ b/sepolicy/file.te @@ -1 +1,2 @@ type mediadrm_vendor_data_file, file_type, data_file_type; +type sysfs_hdmi, file_type, sysfs_type; diff --git a/sepolicy/file_contexts b/sepolicy/file_contexts index 8b5df6f..7e09201 100644 --- a/sepolicy/file_contexts +++ b/sepolicy/file_contexts @@ -4,7 +4,10 @@ # CEC /dev/cec0 u:object_r:cec_device:s0 /dev/cec1 u:object_r:cec_device:s0 +/sys/devices/platform/axi/axi:gpu/drm/card1/card1-HDMI-A-1/status u:object_r:sysfs_hdmi:s0 +/sys/devices/platform/axi/axi:gpu/drm/card1/card1-HDMI-A-2/status u:object_r:sysfs_hdmi:s0 /vendor/bin/hw/android\.hardware\.tv\.hdmi\.cec-service\.rpi u:object_r:hal_tv_hdmi_cec_default_exec:s0 +/vendor/bin/hw/android\.hardware\.tv\.hdmi\.connection-service\.rpi u:object_r:hal_tv_hdmi_connection_default_exec:s0 # DRM /data/vendor/mediadrm(/.*)? u:object_r:mediadrm_vendor_data_file:s0 diff --git a/sepolicy/hal_tv_hdmi_connection_default.te b/sepolicy/hal_tv_hdmi_connection_default.te new file mode 100644 index 0000000..d016287 --- /dev/null +++ b/sepolicy/hal_tv_hdmi_connection_default.te @@ -0,0 +1 @@ +allow hal_tv_hdmi_connection_default sysfs_hdmi:file r_file_perms;