hdmi: connection: add rpi specific aidl hal

* Needed for AIDL HDMI-CEC HAL to work. Some functions that were in the
  HIDL HDMI-CEC HAL have been moved to separate HDMI connection HAL in the
  AIDL versions. Only returns connection status of HDMI ports on Pi.
  onHotplugEvent is not implemented.
* Use hardware/interfaces/tv/hdmi/connection/aidl/ as reference.
This commit is contained in:
Konsta
2025-03-21 14:55:10 +02:00
parent 667fad95e6
commit f6fe82c411
10 changed files with 262 additions and 1 deletions

View File

@@ -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",
],
}

View File

@@ -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 <android-base/file.h>
#include <android-base/logging.h>
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 = "card0";
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<HdmiPortInfo>* _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<IHdmiConnectionCallback>& 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

View File

@@ -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 <aidl/android/hardware/tv/hdmi/connection/BnHdmiConnection.h>
#include <aidl/android/hardware/tv/hdmi/connection/Result.h>
#include <algorithm>
#include <vector>
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<HdmiPortInfo>* _aidl_return) override;
::ndk::ScopedAStatus isConnected(int32_t portId, bool* _aidl_return) override;
::ndk::ScopedAStatus setCallback(
const std::shared_ptr<IHdmiConnectionCallback>& callback) override;
::ndk::ScopedAStatus setHpdSignal(HpdSignal signal, int32_t portId) override;
::ndk::ScopedAStatus getHpdSignal(int32_t portId, HpdSignal* _aidl_return) override;
private:
std::vector<HdmiPortInfo> mPortInfos;
std::vector<HpdSignal> mHpdSignal;
std::shared_ptr<IHdmiConnectionCallback> mCallback;
};
} // namespace implementation
} // namespace connection
} // namespace hdmi
} // Namespace tv
} // namespace hardware
} // namespace android

View File

@@ -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

View File

@@ -0,0 +1,10 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>android.hardware.tv.hdmi.connection</name>
<version>1</version>
<interface>
<name>IHdmiConnection</name>
<instance>default</instance>
</interface>
</hal>
</manifest>

37
hdmi/connection/main.cpp Normal file
View File

@@ -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 <android-base/logging.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
using android::hardware::tv::hdmi::connection::implementation::HdmiConnection;
int main() {
ABinderProcess_setThreadPoolMaxThreadCount(1);
ABinderProcess_startThreadPool();
std::shared_ptr<HdmiConnection> hdmiAidl = ndk::SharedRefBase::make<HdmiConnection>();
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
}