RDKEMW-17873: HDMI-CEC Polaris HAL Migration#57
Conversation
apatel859
left a comment
There was a problem hiding this comment.
Can you cimpile this code in normal build and vdevice build and see if you face any compilation issue?
876022c to
1c009ec
Compare
|
All contributors have signed the CLA ✍️ ✅ |
02757ea to
ba51587
Compare
There was a problem hiding this comment.
Pull request overview
This PR introduces a HAL abstraction + factory to switch the CCEC driver between a legacy C HAL backend (vHAL) and an Android Binder/AIDL backend (AidlHAL), and updates the build to produce/link the new backend libraries.
Changes:
- Added
HDMICecHalinterface andHDMICecHalFactoryto select AIDL vs legacy backend at runtime. - Implemented
vHAL(legacy C driver wrapper) andAidlHAL(binder/AIDL implementation). - Updated
DriverImplto route all HAL operations through the new interface; updated Makefiles to build/link backend shared libraries.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| ccec/src/Makefile.am | Builds libvHAL.la + libAidlHAL.la and links them into libRCEC.la. |
| ccec/src/Makefile | Builds libvHAL.so + libAidlHAL.so and links them into libRCEC.so; adds binder/AIDL include/link plumbing. |
| ccec/src/factoryImpl/HDMICecHal.h | New abstract HAL interface used by DriverImpl. |
| ccec/src/factoryImpl/HDMICecHalFactory.h | Declares factory for backend selection. |
| ccec/src/factoryImpl/HDMICecHalFactory.cpp | Implements backend selection via binder service discovery. |
| ccec/src/factoryImpl/vHAL.h | Declares legacy backend wrapper. |
| ccec/src/factoryImpl/vHAL.cpp | Implements legacy backend wrapper via HdmiCec* C APIs. |
| ccec/src/factoryImpl/AidlHAL.h | Declares AIDL/binder backend. |
| ccec/src/factoryImpl/AidlHAL.cpp | Implements AIDL/binder backend + poll ACK emulation + frame length filtering. |
| ccec/src/DriverImpl.hpp | Stores std::unique_ptr<HDMICecHal> for the selected backend. |
| ccec/src/DriverImpl.cpp | Uses HDMICecHal for open/close/read/write operations and AIDL-specific behaviors. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
174c2b5 to
1c06faf
Compare
32ad93b to
50d97a2
Compare
fe826af to
0982342
Compare
0982342 to
f4eeb3a
Compare
| if(emulateAckForPollFrames(buf, length)) { | ||
| *result = 0; // HDMI_CEC_IO_SUCCESS | ||
| return 0; | ||
| } |
| android::binder::Status onMessageSent(const std::vector<uint8_t>& message, SendMessageStatus status) override { | ||
| if (mAidlHal) { | ||
| int result = (status == SendMessageStatus::ACK_STATE_0) ? 1 : | ||
| (status == SendMessageStatus::ACK_STATE_1) ? 2 : 3; | ||
| mAidlHal->dispatchTx(result); | ||
| } | ||
| return android::binder::Status::ok(); | ||
| } |
| // Map AIDL SendMessageStatus to HAL error codes | ||
| *result = 0; // HDMI_CEC_IO_SUCCESS | ||
| if (sendStatus == SendMessageStatus::ACK_STATE_0) { | ||
| *result = 1; // HDMI_CEC_IO_SENT_AND_ACKD | ||
| } else if (sendStatus == SendMessageStatus::ACK_STATE_1) { | ||
| *result = 2; // HDMI_CEC_IO_SENT_BUT_NOT_ACKD | ||
| } else if (sendStatus == SendMessageStatus::BUSY){ | ||
| *result = 3; // HDMI_CEC_IO_SENT_FAILED | ||
| throw IOException(); | ||
| } |
| CCEC_LOG(LOG_WARN, | ||
| "DriverImpl::getLogicalAddress no allocated LA from AIDL (statusOk=%d, count=%zu). Trying fallback allocation.\r\n", | ||
| status.isOk() ? 1 : 0, | ||
| addresses.size()); |
| // Macro definitions for internal use | ||
| #define BINDER_VERSION _IOWR('b', 9, struct binder_version) | ||
| #define BINDER_WRITE_READ_V7 _IOWR('b', 1, struct binder_write_read_v7) | ||
| #define BC_TRANSACTION_V7 _IOW('c', 0, struct binder_transaction_data_v7) | ||
|
|
| const size_t binder_map_size = (version.protocol_version == 7) ? BINDER_MMAP_SIZE_V7 : BINDER_MMAP_SIZE_V8; | ||
| void* const mapped_mem = mmap(nullptr, binder_map_size, PROT_READ, MAP_PRIVATE, binder_fd, 0); | ||
| if (mapped_mem == MAP_FAILED) { |
| # Binder libraries - link if they exist | ||
| ifneq ($(wildcard $(BINDER_BUILD_DIR)/libbinder.a),) | ||
| LDFLAGS += -L$(BINDER_BUILD_DIR) -lbinder | ||
| endif | ||
| ifneq ($(wildcard $(BINDER_BUILD_DIR)/libutils.a),) | ||
| LDFLAGS += -L$(BINDER_BUILD_DIR) -lutils | ||
| endif | ||
| ifneq ($(wildcard $(BINDER_BUILD_DIR)/liblog.a),) | ||
| LDFLAGS += -L$(BINDER_BUILD_DIR) -llog | ||
| endif |
| # Calculate AIDL include path relative to workspace | ||
| AIDL_GEN_DIR := $(shell cd ../../.. && pwd)/aidl/rdk-halif-aidl/gen/hdmicec/current | ||
| AIDL_H_DIR := $(AIDL_GEN_DIR)/h | ||
| BINDER_IDL_DIR := $(shell cd ../../.. && pwd)/aidl/rdk-halif-aidl/build-tools/linux_binder_idl | ||
| BINDER_INCLUDE := $(BINDER_IDL_DIR)/android/native/libs/binder/include | ||
| BINDER_NDK_INCLUDE := $(BINDER_IDL_DIR)/android/native/libs/binder/ndk/include_cpp | ||
| BINDER_UTILS_INCLUDE := $(BINDER_IDL_DIR)/android/core/libutils/include | ||
| BINDER_CUTILS_INCLUDE := $(BINDER_IDL_DIR)/android/core/libcutils/include | ||
| BINDER_LOG_INCLUDE := $(BINDER_IDL_DIR)/android/logging/liblog/include | ||
| BINDER_BASE_INCLUDE := $(BINDER_IDL_DIR)/android/libbase/include | ||
| BINDER_BUILD_DIR := $(BINDER_IDL_DIR)/aidl-generator/out |
| DriverImpl::DriverImpl() : status(CLOSED), nativeHandle(0) | ||
| { | ||
| mHal = HDMICecHalFactory::Create(); | ||
| CCEC_LOG( LOG_DEBUG, "Creating DriverImpl done\r\n"); |
93e20d3 to
9e492e8
Compare
| * -------------------------------------------------------------------- */ | ||
| int HDMICecRdkVHAL::txAsync(int handle, const unsigned char *buf, int len) | ||
| { | ||
| CCEC_LOG(LOG_INFO, "HDMICecRdkVHAL::txAsync handle=%d len=%d\r\n", handle, len); |
There was a problem hiding this comment.
We can combine two logs to one for all the APIs
| status.isOk() ? 1 : 0, | ||
| addresses.size()); | ||
| if (mAidlController != nullptr) { | ||
| const std::vector<int32_t> preferred = preferredLogicalAddressesForDeviceType(*logicalAddress); |
There was a problem hiding this comment.
pass correct device type
| CCEC_LOG(LOG_DEBUG, "HDMICecRdkVHAL::getPhysicalAddress handle=%d ret=%d addr=0x%x\r\n", | ||
| ret, (physicalAddress ? *physicalAddress : 0)); |
There was a problem hiding this comment.
Fix Copilot comments
| android::binder::Status onMessageSent(const std::vector<uint8_t>& message, SendMessageStatus status) override { | ||
| if (mAidlHal) { | ||
| int result = (status == SendMessageStatus::ACK_STATE_0) ? 1 : | ||
| (status == SendMessageStatus::ACK_STATE_1) ? 2 : 3; | ||
| mAidlHal->dispatchTx(result); | ||
| } | ||
| return android::binder::Status::ok(); | ||
| } |
| *result = 0; // HDMI_CEC_IO_SUCCESS | ||
| if (sendStatus == SendMessageStatus::ACK_STATE_0) { | ||
| *result = 1; // HDMI_CEC_IO_SENT_AND_ACKD | ||
| } else if (sendStatus == SendMessageStatus::ACK_STATE_1) { | ||
| *result = 2; // HDMI_CEC_IO_SENT_BUT_NOT_ACKD | ||
| } else if (sendStatus == SendMessageStatus::BUSY){ | ||
| *result = 3; // HDMI_CEC_IO_SENT_FAILED | ||
| throw IOException(); | ||
| } |
| if (mAidlController != nullptr) { | ||
| const std::vector<int32_t> preferred = preferredLogicalAddressesForDeviceType(*logicalAddress); | ||
| for (std::vector<int32_t>::const_iterator it = preferred.begin(); it != preferred.end(); ++it) { |
| // Macro definitions for internal use | ||
| #define BINDER_VERSION _IOWR('b', 9, struct binder_version) | ||
| #define BINDER_WRITE_READ_V7 _IOWR('b', 1, struct binder_write_read_v7) | ||
| #define BC_TRANSACTION_V7 _IOW('c', 0, struct binder_transaction_data_v7) |
| CCEC_LOG(LOG_INFO, "[+] Binder protocol version detected: %d\n", version.protocol_version); | ||
|
|
||
| const size_t binder_map_size = (version.protocol_version == 7) ? BINDER_MMAP_SIZE_V7 : BINDER_MMAP_SIZE_V8; | ||
| void* const mapped_mem = mmap(nullptr, binder_map_size, PROT_READ, MAP_PRIVATE, binder_fd, 0); |
| factoryImpl/HDMICecHalFactory.cpp \ | ||
| factoryImpl/HDMICecRdkVHAL.cpp \ | ||
| factoryImpl/HDMICecAidlHAL.cpp \ | ||
| factoryImpl/ServiceManagerCheck.cpp |
| # Binder libraries - link if they exist | ||
| ifneq ($(wildcard $(BINDER_BUILD_DIR)/libbinder.a),) | ||
| LDFLAGS += -L$(BINDER_BUILD_DIR) -lbinder | ||
| endif | ||
| ifneq ($(wildcard $(BINDER_BUILD_DIR)/libutils.a),) | ||
| LDFLAGS += -L$(BINDER_BUILD_DIR) -lutils | ||
| endif | ||
| ifneq ($(wildcard $(BINDER_BUILD_DIR)/liblog.a),) | ||
| LDFLAGS += -L$(BINDER_BUILD_DIR) -llog | ||
| endif |
| DriverImpl::DriverImpl() : status(CLOSED), nativeHandle(0) | ||
| { | ||
| mHal = HDMICecHalFactory::Create(); | ||
| CCEC_LOG( LOG_DEBUG, "Creating DriverImpl done\r\n"); |
| } | ||
|
|
||
| int err = HdmiCecOpen(&nativeHandle); | ||
| int err = mHal->open(&nativeHandle); |
There was a problem hiding this comment.
Add NULL check for mHal wherever it is used
| CCEC_LOG(LOG_DEBUG, "HDMICecRdkVHAL::getPhysicalAddress handle=%d ret=%d addr=0x%x\r\n", | ||
| ret, (physicalAddress ? *physicalAddress : 0)); |
There was a problem hiding this comment.
Fix Copilot comments
| class HalFactoryUtility { | ||
| enum class BackendType { | ||
| UNKNOWN, | ||
| LEGACY, | ||
| AIDL | ||
| }; | ||
|
|
||
| static BackendType mBackendType; | ||
|
|
||
| bool isAidlServiceAvailable(const android::String16 &expectedServiceName) | ||
| { | ||
| CCEC_LOG(LOG_INFO, "isAidlServiceAvailable invoked\r\n"); |
| { | ||
| CCEC_LOG(LOG_INFO, "HDMICecHalFactory::Create invoked\r\n"); | ||
|
|
||
| if (HalFactoryUtility::isAidlServiceAvailable(IHdmiCec::serviceName().c_str())) { |
| const size_t binder_map_size = (version.protocol_version == 7) ? BINDER_MMAP_SIZE_V7 : BINDER_MMAP_SIZE_V8; | ||
| void* const mapped_mem = mmap(nullptr, binder_map_size, PROT_READ, MAP_PRIVATE, binder_fd, 0); | ||
| if (mapped_mem == MAP_FAILED) { | ||
| CCEC_LOG(LOG_ERROR, "[-] Shared address space context instantiation failed\n"); |
| CCEC_LOG(LOG_DEBUG, "HDMICecRdkVHAL::getPhysicalAddress handle=%d ret=%d addr=0x%x\r\n", | ||
| ret, (physicalAddress ? *physicalAddress : 0)); |
| int HDMICecAidlHAL::getPhysicalAddress(int handle, unsigned int *physicalAddress) | ||
| { | ||
| if (physicalAddress != nullptr) { | ||
| *physicalAddress = 0; | ||
| } | ||
|
|
||
| CCEC_LOG( LOG_DEBUG, "HDMICecAidlHAL::getPhysicalAddress completed\r\n"); | ||
|
|
||
| return 0; | ||
| } |
| factoryImpl/HDMICecHalFactory.cpp \ | ||
| factoryImpl/HDMICecRdkVHAL.cpp \ | ||
| factoryImpl/HDMICecAidlHAL.cpp \ | ||
| factoryImpl/ServiceManagerCheck.cpp | ||
|
|
||
| libRCEC_la_LDFLAGS = -lpthread |
| factoryImpl/HDMICecHalFactory.cpp \ | ||
| factoryImpl/HDMICecRdkVHAL.cpp \ | ||
| factoryImpl/HDMICecAidlHAL.cpp \ | ||
| factoryImpl/ServiceManagerCheck.cpp |
| CCEC_LOG(LOG_INFO, "[+] Binder protocol version detected: %d\n", version.protocol_version); | ||
|
|
||
| const size_t binder_map_size = (version.protocol_version == 7) ? BINDER_MMAP_SIZE_V7 : BINDER_MMAP_SIZE_V8; | ||
| void* const mapped_mem = mmap(nullptr, binder_map_size, PROT_READ, MAP_PRIVATE, binder_fd, 0); |
| // Macro definitions for internal use | ||
| #define BINDER_VERSION _IOWR('b', 9, struct binder_version) | ||
| #define BINDER_WRITE_READ_V7 _IOWR('b', 1, struct binder_write_read_v7) | ||
| #define BC_TRANSACTION_V7 _IOW('c', 0, struct binder_transaction_data_v7) |
| bwr.write_size = write_size; | ||
| bwr.write_consumed = 0; | ||
| bwr.write_buffer = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(tx.write_payload.data())); | ||
| bwr.read_size = read_size; | ||
| bwr.read_consumed = 0; | ||
| bwr.read_buffer = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(tx.read_payload.data())); |
| /* Probe with a 2-byte directed frame (GiveDevicePowerStatus) */ | ||
| { | ||
| AutoLock lock_(mAidlMutex); | ||
| std::vector<uint8_t> probe; | ||
| probe.reserve(2); | ||
| probe.push_back(buf ? buf[0] : 0); | ||
| probe.push_back(0x8F); // GiveDevicePowerStatus | ||
|
|
||
| SendMessageStatus probeStatus = SendMessageStatus::BUSY; | ||
| android::binder::Status aidlStatus = mAidlController->sendMessage(probe, &probeStatus); | ||
| if (aidlStatus.isOk() && probeStatus == SendMessageStatus::ACK_STATE_0) { |
| /** | ||
| * @brief Get the physical address of the device. | ||
| * | ||
| * Legacy: calls HdmiCecGetPhysicalAddress(). | ||
| * AIDL: queries the physical address via binder. | ||
| * |
| std::unique_ptr<IHDMICecHal> HDMICecHalFactory::Create() | ||
| { | ||
| CCEC_LOG(LOG_INFO, "HDMICecHalFactory::Create invoked\r\n"); | ||
|
|
||
| try { | ||
| if (HalFactoryUtility::isAidlServiceAvailable(android::String16(IHdmiCec::serviceName().c_str()))) { | ||
| CCEC_LOG(LOG_INFO, "HDMICecHalFactory: Aidl Service is available — using HDMICecAidlHAL\r\n"); | ||
| return std::make_unique<HDMICecAidlHAL>(); | ||
| } |
|
I have read the CLA Document and I hereby sign the CLA. |
No description provided.