diff --git a/.github/workflows/L1-tests.yml b/.github/workflows/L1-tests.yml index cc031231..d0866540 100755 --- a/.github/workflows/L1-tests.yml +++ b/.github/workflows/L1-tests.yml @@ -123,7 +123,7 @@ jobs: with: repository: rdkcentral/entservices-testframework path: entservices-testframework - ref: develop + ref: feature/RDKEMW-6167-PR token: ${{ secrets.RDKCM_RDKE }} - name: Checkout entservices-inputoutput @@ -460,10 +460,10 @@ jobs: -DDS_FOUND=ON -DHAS_FRONT_PANEL=ON -DRDK_SERVICES_L1_TEST=ON - -DPLUGIN_AVINPUT=ON - -DPLUGIN_HDCPPROFILE=ON + -DPLUGIN_AVINPUT=OFF + -DPLUGIN_HDCPPROFILE=OFF -DPLUGIN_HDMICECSOURCE=ON - -DPLUGIN_HDMICECSINK=ON + -DPLUGIN_HDMICECSINK=OFF -DUSE_THUNDER_R4=ON -DHIDE_NON_EXTERNAL_SYMBOLS=OFF && diff --git a/AVOutput/AVOutputTVHelper.cpp b/AVOutput/AVOutputTVHelper.cpp index 6fbcbab0..5c5e5b3e 100644 --- a/AVOutput/AVOutputTVHelper.cpp +++ b/AVOutput/AVOutputTVHelper.cpp @@ -1209,6 +1209,13 @@ namespace Plugin { LOGERR("Backlight Sync to cache Failed !!!\n"); } + if( !updateAVoutputTVParam("sync","LowLatencyState",info,PQ_PARAM_LOWLATENCY_STATE,level) ) { + LOGINFO("LowLatencyState Successfully Synced to Drive Cache\n"); + } + else { + LOGERR("LowLatencyState Sync to cache Failed !!!\n"); + } + syncCMSParams(); //sync CMS syncWBParams(); diff --git a/AVOutput/CHANGELOG.md b/AVOutput/CHANGELOG.md index cf722532..7daed548 100644 --- a/AVOutput/CHANGELOG.md +++ b/AVOutput/CHANGELOG.md @@ -14,6 +14,11 @@ All notable changes to this RDK Service will be documented in this file. * Changes in CHANGELOG should be updated when commits are added to the main or release branches. There should be one CHANGELOG entry per JIRA Ticket. This is not enforced on sprint branches since there could be multiple changes for the same JIRA ticket during development. +<<<<<<< HEAD +## [1.1.4] - 2025-09-08 +### Fixed +- Sync low latency for AVOutput initialization + ## [1.1.3] - 2025-08-08 ### Fixed - Fixed getDolbyVisionMode() for non DV content diff --git a/CHANGELOG.md b/CHANGELOG.md index db5bc7b0..867461dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,9 +4,25 @@ All notable changes to this project will be documented in this file. Dates are d Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). +#### [1.4.7](https://github.com/rdkcentral/entservices-inputoutput/compare/1.4.6...1.4.7) + +- RDKEMW-7712: Sync low latency for AVOutput initialization (#6338) [`#249`](https://github.com/rdkcentral/entservices-inputoutput/pull/249) +- Merge tag '1.4.6' into develop [`bef0aa3`](https://github.com/rdkcentral/entservices-inputoutput/commit/bef0aa3bf2638d0223008f10babecde595d850df) + +#### [1.4.6](https://github.com/rdkcentral/entservices-inputoutput/compare/1.4.5...1.4.6) + +> 4 September 2025 + +- Feature/rdkemw 7169 [`#245`](https://github.com/rdkcentral/entservices-inputoutput/pull/245) +- 1.4.6 release changelog updates [`7a0d569`](https://github.com/rdkcentral/entservices-inputoutput/commit/7a0d569f253b8a08926e959509e329159aa2d509) +- Merge tag '1.4.5' into develop [`7268514`](https://github.com/rdkcentral/entservices-inputoutput/commit/7268514652bf9f0cda3f3a6433a0f0720bf9d63c) + #### [1.4.5](https://github.com/rdkcentral/entservices-inputoutput/compare/1.4.4...1.4.5) +> 3 September 2025 + - RDKEMW-7169 - Gtest Add missing empty files [`#241`](https://github.com/rdkcentral/entservices-inputoutput/pull/241) +- 1.4.5 release changelog updates [`4354afa`](https://github.com/rdkcentral/entservices-inputoutput/commit/4354afac08c4671cbed356d81a2ed2f612139464) - Merge tag '1.4.4' into develop [`0fabfaf`](https://github.com/rdkcentral/entservices-inputoutput/commit/0fabfaf0816dda67077fd7fe59e074a962e644ef) #### [1.4.4](https://github.com/rdkcentral/entservices-inputoutput/compare/1.4.3...1.4.4) diff --git a/HdmiCecSink/HdmiCecSink.cpp b/HdmiCecSink/HdmiCecSink.cpp index a1ac6a75..931b107d 100644 --- a/HdmiCecSink/HdmiCecSink.cpp +++ b/HdmiCecSink/HdmiCecSink.cpp @@ -25,8 +25,6 @@ #include "host.hpp" #include "UtilsgetRFCConfig.h" -#include "dsMgr.h" -#include "dsRpc.h" #include "dsDisplay.h" #include "videoOutputPort.hpp" #include "manager.hpp" @@ -36,6 +34,9 @@ #include "UtilsJsonRpc.h" #include "UtilssyncPersistFile.h" #include "UtilsSearchRDKProfile.h" +#include "exception.hpp" +#include "hdmiIn.hpp" +#include "dsError.h" #define HDMICECSINK_METHOD_SET_ENABLED "setEnabled" #define HDMICECSINK_METHOD_GET_ENABLED "getEnabled" @@ -692,213 +693,219 @@ namespace WPEFramework } const std::string HdmiCecSink::Initialize(PluginHost::IShell *service) { - InitializePowerManager(service); - profileType = searchRdkProfile(); - - if (profileType == STB || profileType == NOT_FOUND) - { - LOGINFO("Invalid profile type for TV \n"); - return (std::string("Not supported")); - } - - HdmiCecSink::_instance = this; - smConnection=NULL; - cecEnableStatus = false; - HdmiCecSink::_instance->m_numberOfDevices = 0; - m_logicalAddressAllocated = LogicalAddress::UNREGISTERED; - m_currentActiveSource = -1; - m_isHdmiInConnected = false; - hdmiCecAudioDeviceConnected = false; - m_isAudioStatusInfoUpdated = false; - m_audioStatusRequestedCount = 0; - m_audioStatusReceived = false; - m_audioStatusTimerStarted = false; - m_audioDevicePowerStatusRequested = false; - m_pollNextState = POLL_THREAD_STATE_NONE; - m_pollThreadState = POLL_THREAD_STATE_NONE; - m_video_latency = DEFAULT_VIDEO_LATENCY; - m_latency_flags = DEFAULT_LATENCY_FLAGS ; - m_audio_output_delay = DEFAULT_AUDIO_OUTPUT_DELAY; - - Register(HDMICECSINK_METHOD_SET_ENABLED, &HdmiCecSink::setEnabledWrapper, this); - Register(HDMICECSINK_METHOD_GET_ENABLED, &HdmiCecSink::getEnabledWrapper, this); - Register(HDMICECSINK_METHOD_SET_OSD_NAME, &HdmiCecSink::setOSDNameWrapper, this); - Register(HDMICECSINK_METHOD_GET_OSD_NAME, &HdmiCecSink::getOSDNameWrapper, this); - Register(HDMICECSINK_METHOD_SET_VENDOR_ID, &HdmiCecSink::setVendorIdWrapper, this); - Register(HDMICECSINK_METHOD_GET_VENDOR_ID, &HdmiCecSink::getVendorIdWrapper, this); - Register(HDMICECSINK_METHOD_PRINT_DEVICE_LIST, &HdmiCecSink::printDeviceListWrapper, this); - Register(HDMICECSINK_METHOD_SET_ACTIVE_PATH, &HdmiCecSink::setActivePathWrapper, this); - Register(HDMICECSINK_METHOD_SET_ROUTING_CHANGE, &HdmiCecSink::setRoutingChangeWrapper, this); - Register(HDMICECSINK_METHOD_GET_DEVICE_LIST, &HdmiCecSink::getDeviceListWrapper, this); - Register(HDMICECSINK_METHOD_GET_ACTIVE_SOURCE, &HdmiCecSink::getActiveSourceWrapper, this); - Register(HDMICECSINK_METHOD_SET_ACTIVE_SOURCE, &HdmiCecSink::setActiveSourceWrapper, this); - Register(HDMICECSINK_METHOD_GET_ACTIVE_ROUTE, &HdmiCecSink::getActiveRouteWrapper, this); - Register(HDMICECSINK_METHOD_REQUEST_ACTIVE_SOURCE, &HdmiCecSink::requestActiveSourceWrapper, this); - Register(HDMICECSINK_METHOD_SETUP_ARC, &HdmiCecSink::setArcEnableDisableWrapper, this); - Register(HDMICECSINK_METHOD_SET_MENU_LANGUAGE, &HdmiCecSink::setMenuLanguageWrapper, this); - Register(HDMICECSINK_METHOD_REQUEST_SHORT_AUDIO_DESCRIPTOR, &HdmiCecSink::requestShortAudioDescriptorWrapper, this); - Register(HDMICECSINK_METHOD_SEND_STANDBY_MESSAGE, &HdmiCecSink::sendStandbyMessageWrapper, this); - Register(HDMICECSINK_METHOD_SEND_AUDIO_DEVICE_POWER_ON, &HdmiCecSink::sendAudioDevicePowerOnMsgWrapper, this); - Register(HDMICECSINK_METHOD_SEND_KEY_PRESS,&HdmiCecSink::sendRemoteKeyPressWrapper,this); - Register(HDMICECSINK_METHOD_SEND_USER_CONTROL_PRESSED,&HdmiCecSink::sendUserControlPressedWrapper,this); - Register(HDMICECSINK_METHOD_SEND_USER_CONTROL_RELEASED,&HdmiCecSink::sendUserControlReleasedWrapper,this); - Register(HDMICECSINK_METHOD_SEND_GIVE_AUDIO_STATUS,&HdmiCecSink::sendGiveAudioStatusWrapper,this); - Register(HDMICECSINK_METHOD_GET_AUDIO_DEVICE_CONNECTED_STATUS,&HdmiCecSink::getAudioDeviceConnectedStatusWrapper,this); - Register(HDMICECSINK_METHOD_REQUEST_AUDIO_DEVICE_POWER_STATUS,&HdmiCecSink::requestAudioDevicePowerStatusWrapper,this); - Register(HDMICECSINK_METHOD_SET_LATENCY_INFO, &HdmiCecSink::setLatencyInfoWrapper, this); - logicalAddressDeviceType = "None"; - logicalAddress = 0xFF; - // load persistence setting - loadSettings(); - - int err; - dsHdmiInGetNumberOfInputsParam_t hdmiInput; - InitializeIARM(); - m_sendKeyEventThreadExit = false; - m_sendKeyEventThread = std::thread(threadSendKeyEvent); + string msg = ""; - m_currentArcRoutingState = ARC_STATE_ARC_TERMINATED; - m_semSignaltoArcRoutingThread.acquire(); - m_arcRoutingThread = std::thread(threadArcRouting); - - m_audioStatusDetectionTimer.connect( std::bind( &HdmiCecSink::audioStatusTimerFunction, this ) ); - m_audioStatusDetectionTimer.setSingleShot(true); - m_arcStartStopTimer.connect( std::bind( &HdmiCecSink::arcStartStopTimerFunction, this ) ); - m_arcStartStopTimer.setSingleShot(true); - // get power state: - Core::hresult res = Core::ERROR_GENERAL; - PowerState pwrStateCur = WPEFramework::Exchange::IPowerManager::POWER_STATE_UNKNOWN; - PowerState pwrStatePrev = WPEFramework::Exchange::IPowerManager::POWER_STATE_UNKNOWN; - - ASSERT (_powerManagerPlugin); - if (_powerManagerPlugin) { - res = _powerManagerPlugin->GetPowerState(pwrStateCur, pwrStatePrev); - if (Core::ERROR_NONE == res) { - powerState = (pwrStateCur == WPEFramework::Exchange::IPowerManager::POWER_STATE_ON) ? DEVICE_POWER_STATE_ON : DEVICE_POWER_STATE_OFF; - LOGINFO("Current state is PowerManagerPlugin: (%d) powerState :%d \n", pwrStateCur, powerState); - } - } - - err = IARM_Bus_Call(IARM_BUS_DSMGR_NAME, - IARM_BUS_DSMGR_API_dsHdmiInGetNumberOfInputs, - (void *)&hdmiInput, - sizeof(hdmiInput)); + try + { + device::Manager::Initialize(); + LOGINFO("HdmiCecSink plugin device::Manager::Initialize success"); + } + catch(const device::Exception& err) + { + LOGINFO("HdmiCecSink plugin device::Manager::Initialize failed"); + LOG_DEVICE_EXCEPTION0(); + } - if (err == IARM_RESULT_SUCCESS && hdmiInput.result == dsERR_NONE) + if (0 == msg.length()) { - LOGINFO("Number of Inputs [%d] \n", hdmiInput.numHdmiInputs ); - m_numofHdmiInput = hdmiInput.numHdmiInputs; - }else{ - LOGINFO("Not able to get Numebr of inputs so defaulting to 3 \n"); - m_numofHdmiInput = 3; - } + InitializePowerManager(service); + profileType = searchRdkProfile(); - LOGINFO("initalize inputs \n"); + if (profileType == STB || profileType == NOT_FOUND) + { + LOGINFO("Invalid profile type for TV \n"); + return (std::string("Not supported")); + } + + HdmiCecSink::_instance = this; + smConnection=NULL; + cecEnableStatus = false; + HdmiCecSink::_instance->m_numberOfDevices = 0; + m_logicalAddressAllocated = LogicalAddress::UNREGISTERED; + m_currentActiveSource = -1; + m_isHdmiInConnected = false; + hdmiCecAudioDeviceConnected = false; + m_isAudioStatusInfoUpdated = false; + m_audioStatusRequestedCount = 0; + m_audioStatusReceived = false; + m_audioStatusTimerStarted = false; + m_audioDevicePowerStatusRequested = false; + m_pollNextState = POLL_THREAD_STATE_NONE; + m_pollThreadState = POLL_THREAD_STATE_NONE; + m_video_latency = DEFAULT_VIDEO_LATENCY; + m_latency_flags = DEFAULT_LATENCY_FLAGS ; + m_audio_output_delay = DEFAULT_AUDIO_OUTPUT_DELAY; + + Register(HDMICECSINK_METHOD_SET_ENABLED, &HdmiCecSink::setEnabledWrapper, this); + Register(HDMICECSINK_METHOD_GET_ENABLED, &HdmiCecSink::getEnabledWrapper, this); + Register(HDMICECSINK_METHOD_SET_OSD_NAME, &HdmiCecSink::setOSDNameWrapper, this); + Register(HDMICECSINK_METHOD_GET_OSD_NAME, &HdmiCecSink::getOSDNameWrapper, this); + Register(HDMICECSINK_METHOD_SET_VENDOR_ID, &HdmiCecSink::setVendorIdWrapper, this); + Register(HDMICECSINK_METHOD_GET_VENDOR_ID, &HdmiCecSink::getVendorIdWrapper, this); + Register(HDMICECSINK_METHOD_PRINT_DEVICE_LIST, &HdmiCecSink::printDeviceListWrapper, this); + Register(HDMICECSINK_METHOD_SET_ACTIVE_PATH, &HdmiCecSink::setActivePathWrapper, this); + Register(HDMICECSINK_METHOD_SET_ROUTING_CHANGE, &HdmiCecSink::setRoutingChangeWrapper, this); + Register(HDMICECSINK_METHOD_GET_DEVICE_LIST, &HdmiCecSink::getDeviceListWrapper, this); + Register(HDMICECSINK_METHOD_GET_ACTIVE_SOURCE, &HdmiCecSink::getActiveSourceWrapper, this); + Register(HDMICECSINK_METHOD_SET_ACTIVE_SOURCE, &HdmiCecSink::setActiveSourceWrapper, this); + Register(HDMICECSINK_METHOD_GET_ACTIVE_ROUTE, &HdmiCecSink::getActiveRouteWrapper, this); + Register(HDMICECSINK_METHOD_REQUEST_ACTIVE_SOURCE, &HdmiCecSink::requestActiveSourceWrapper, this); + Register(HDMICECSINK_METHOD_SETUP_ARC, &HdmiCecSink::setArcEnableDisableWrapper, this); + Register(HDMICECSINK_METHOD_SET_MENU_LANGUAGE, &HdmiCecSink::setMenuLanguageWrapper, this); + Register(HDMICECSINK_METHOD_REQUEST_SHORT_AUDIO_DESCRIPTOR, &HdmiCecSink::requestShortAudioDescriptorWrapper, this); + Register(HDMICECSINK_METHOD_SEND_STANDBY_MESSAGE, &HdmiCecSink::sendStandbyMessageWrapper, this); + Register(HDMICECSINK_METHOD_SEND_AUDIO_DEVICE_POWER_ON, &HdmiCecSink::sendAudioDevicePowerOnMsgWrapper, this); + Register(HDMICECSINK_METHOD_SEND_KEY_PRESS,&HdmiCecSink::sendRemoteKeyPressWrapper,this); + Register(HDMICECSINK_METHOD_SEND_USER_CONTROL_PRESSED,&HdmiCecSink::sendUserControlPressedWrapper,this); + Register(HDMICECSINK_METHOD_SEND_USER_CONTROL_RELEASED,&HdmiCecSink::sendUserControlReleasedWrapper,this); + Register(HDMICECSINK_METHOD_SEND_GIVE_AUDIO_STATUS,&HdmiCecSink::sendGiveAudioStatusWrapper,this); + Register(HDMICECSINK_METHOD_GET_AUDIO_DEVICE_CONNECTED_STATUS,&HdmiCecSink::getAudioDeviceConnectedStatusWrapper,this); + Register(HDMICECSINK_METHOD_REQUEST_AUDIO_DEVICE_POWER_STATUS,&HdmiCecSink::requestAudioDevicePowerStatusWrapper,this); + Register(HDMICECSINK_METHOD_SET_LATENCY_INFO, &HdmiCecSink::setLatencyInfoWrapper, this); + logicalAddressDeviceType = "None"; + logicalAddress = 0xFF; + // load persistence setting + loadSettings(); + device::Host::getInstance().Register(baseInterface(), "WPE::CecSink"); + m_sendKeyEventThreadExit = false; + m_sendKeyEventThread = std::thread(threadSendKeyEvent); + + m_currentArcRoutingState = ARC_STATE_ARC_TERMINATED; + m_semSignaltoArcRoutingThread.acquire(); + m_arcRoutingThread = std::thread(threadArcRouting); + + m_audioStatusDetectionTimer.connect( std::bind( &HdmiCecSink::audioStatusTimerFunction, this ) ); + m_audioStatusDetectionTimer.setSingleShot(true); + m_arcStartStopTimer.connect( std::bind( &HdmiCecSink::arcStartStopTimerFunction, this ) ); + m_arcStartStopTimer.setSingleShot(true); + // get power state: + Core::hresult res = Core::ERROR_GENERAL; + PowerState pwrStateCur = WPEFramework::Exchange::IPowerManager::POWER_STATE_UNKNOWN; + PowerState pwrStatePrev = WPEFramework::Exchange::IPowerManager::POWER_STATE_UNKNOWN; + + ASSERT (_powerManagerPlugin); + if (_powerManagerPlugin) { + res = _powerManagerPlugin->GetPowerState(pwrStateCur, pwrStatePrev); + if (Core::ERROR_NONE == res) { + powerState = (pwrStateCur == WPEFramework::Exchange::IPowerManager::POWER_STATE_ON) ? DEVICE_POWER_STATE_ON : DEVICE_POWER_STATE_OFF; + LOGINFO("Current state is PowerManagerPlugin: (%d) powerState :%d \n", pwrStateCur, powerState); + } + } - for (int i = 0; i < m_numofHdmiInput; i++){ - HdmiPortMap hdmiPort((uint8_t)i); - LOGINFO(" Add to vector [%d] \n", i); - hdmiInputs.push_back(hdmiPort); - } + try + { + m_numofHdmiInput = device::HdmiInput::getInstance().getNumberOfInputs(); + LOGINFO("HdmiCecSink plugin m_numofHdmiInput %d", m_numofHdmiInput); + } + catch(const device::Exception& err) + { + LOGINFO("HdmiCecSink plugin device::HdmiInput::getInstance().getNumberOfInputs failed"); + m_numofHdmiInput = 3; + LOG_DEVICE_EXCEPTION0(); + } + + LOGINFO("initalize inputs \n"); + + for (int i = 0; i < m_numofHdmiInput; i++){ + HdmiPortMap hdmiPort((uint8_t)i); + LOGINFO(" Add to vector [%d] \n", i); + hdmiInputs.push_back(hdmiPort); + } - LOGINFO("Check the HDMI State \n"); + LOGINFO("Check the HDMI State \n"); - CheckHdmiInState(); - if (cecSettingEnabled) - { - try + CheckHdmiInState(); + if (cecSettingEnabled) { - CECEnable(); - } - catch(...) - { - LOGWARN("Exception while enabling CEC settings .\r\n"); + try + { + CECEnable(); + } + catch(...) + { + LOGWARN("Exception while enabling CEC settings .\r\n"); + } } - } - getCecVersion(); - LOGINFO(" HdmiCecSink plugin Initialize completed \n"); + getCecVersion(); + } + + LOGINFO(" HdmiCecSink plugin Initialize completed \n"); return (std::string()); } void HdmiCecSink::Deinitialize(PluginHost::IShell* /* service */) { - if(_powerManagerPlugin) - { - _powerManagerPlugin->Unregister(_pwrMgrNotification.baseInterface()); - _powerManagerPlugin.Reset(); - } - _registeredEventHandlers = false; + if(_powerManagerPlugin) + { + _powerManagerPlugin->Unregister(_pwrMgrNotification.baseInterface()); + _powerManagerPlugin.Reset(); + } + _registeredEventHandlers = false; - profileType = searchRdkProfile(); + profileType = searchRdkProfile(); - if (profileType == STB || profileType == NOT_FOUND) - { - LOGINFO("Invalid profile type for TV \n"); - return ; - } + if (profileType == STB || profileType == NOT_FOUND) + { + LOGINFO("Invalid profile type for TV \n"); + return ; + } - CECDisable(); - m_currentArcRoutingState = ARC_STATE_ARC_EXIT; + CECDisable(); + m_currentArcRoutingState = ARC_STATE_ARC_EXIT; - m_semSignaltoArcRoutingThread.release(); + m_semSignaltoArcRoutingThread.release(); - try - { - if (m_arcRoutingThread.joinable()) - m_arcRoutingThread.join(); - } - catch(const std::system_error& e) - { - LOGERR("system_error exception in thread join %s", e.what()); - } - catch(const std::exception& e) - { - LOGERR("exception in thread join %s", e.what()); - } + try + { + if (m_arcRoutingThread.joinable()) + m_arcRoutingThread.join(); + } + catch(const std::system_error& e) + { + LOGERR("system_error exception in thread join %s", e.what()); + } + catch(const std::exception& e) + { + LOGERR("exception in thread join %s", e.what()); + } - { - m_sendKeyEventThreadExit = true; - std::unique_lock lk(m_sendKeyEventMutex); - m_sendKeyEventThreadRun = true; - m_sendKeyCV.notify_one(); - } + { + m_sendKeyEventThreadExit = true; + std::unique_lock lk(m_sendKeyEventMutex); + m_sendKeyEventThreadRun = true; + m_sendKeyCV.notify_one(); + } - try - { - if (m_sendKeyEventThread.joinable()) - m_sendKeyEventThread.join(); - } - catch(const std::system_error& e) - { - LOGERR("system_error exception in thread join %s", e.what()); - } - catch(const std::exception& e) - { - LOGERR("exception in thread join %s", e.what()); - } + try + { + if (m_sendKeyEventThread.joinable()) + m_sendKeyEventThread.join(); + } + catch(const std::system_error& e) + { + LOGERR("system_error exception in thread join %s", e.what()); + } + catch(const std::exception& e) + { + LOGERR("exception in thread join %s", e.what()); + } - HdmiCecSink::_instance = nullptr; - DeinitializeIARM(); - LOGWARN(" HdmiCecSink Deinitialize() Done"); - } + HdmiCecSink::_instance = nullptr; + device::Host::getInstance().UnRegister(baseInterface()); - const void HdmiCecSink::InitializeIARM() - { - if (Utils::IARM::init()) - { - IARM_Result_t res; - IARM_CHECK( IARM_Bus_RegisterEventHandler(IARM_BUS_DSMGR_NAME,IARM_BUS_DSMGR_EVENT_HDMI_IN_HOTPLUG, dsHdmiEventHandler) ); - } - } + try + { + device::Manager::DeInitialize(); + LOGINFO("HdmiCecSink plugin device::Manager::DeInitialize success"); + } + catch(const device::Exception& err) + { + LOGINFO("HdmiCecSink plugin device::Manager::DeInitialize failed"); + LOG_DEVICE_EXCEPTION0(); + } - void HdmiCecSink::DeinitializeIARM() - { - if (Utils::IARM::isConnected()) - { - IARM_Result_t res; - IARM_CHECK( IARM_Bus_RemoveEventHandler(IARM_BUS_DSMGR_NAME,IARM_BUS_DSMGR_EVENT_HDMI_IN_HOTPLUG, dsHdmiEventHandler) ); - } + LOGWARN(" HdmiCecSink Deinitialize() Done"); } void HdmiCecSink::InitializePowerManager(PluginHost::IShell *service) @@ -920,20 +927,14 @@ namespace WPEFramework } } - void HdmiCecSink::dsHdmiEventHandler(const char *owner, IARM_EventId_t eventId, void *data, size_t len) - { + void HdmiCecSink::OnHdmiInEventHotPlug(dsHdmiInPort_t port, bool isConnected) + { if(!HdmiCecSink::_instance) return; - if (IARM_BUS_DSMGR_EVENT_HDMI_IN_HOTPLUG == eventId) - { - IARM_Bus_DSMgr_EventData_t *eventData = (IARM_Bus_DSMgr_EventData_t *)data; - bool isHdmiConnected = eventData->data.hdmi_in_connect.isPortConnected; - dsHdmiInPort_t portId = eventData->data.hdmi_in_connect.port; - LOGINFO("Received IARM_BUS_DSMGR_EVENT_HDMI_IN_HOTPLUG event port: %d data:%d \r\n",portId, isHdmiConnected); - HdmiCecSink::_instance->onHdmiHotPlug(portId,isHdmiConnected); - } - } + LOGINFO("Received HdmiCecSink::OnHdmiInEventHotPlug event port: %d isConnected: %d \r\n", port, isConnected); + HdmiCecSink::_instance->onHdmiHotPlug((int) port, isConnected); + } void HdmiCecSink::onPowerModeChanged(const PowerState currentState, const PowerState newState) { @@ -2058,29 +2059,19 @@ namespace WPEFramework void HdmiCecSink::CheckHdmiInState() { - int err; bool isAnyPortConnected = false; - dsHdmiInGetStatusParam_t params; - err = IARM_Bus_Call(IARM_BUS_DSMGR_NAME, - IARM_BUS_DSMGR_API_dsHdmiInGetStatus, - (void *)¶ms, - sizeof(params)); - - if(err == IARM_RESULT_SUCCESS && params.result == dsERR_NONE ) + for( int i = 0; i < m_numofHdmiInput; i++ ) { - for( int i = 0; i < m_numofHdmiInput; i++ ) - { - LOGINFO("Is HDMI In Port [%d] connected [%d] \n",i, params.status.isPortConnected[i]); - if ( params.status.isPortConnected[i] ) - { - isAnyPortConnected = true; - } + LOGINFO("update Port Status [%d] \n", i); + hdmiInputs[i].update(device::HdmiInput::getInstance().isPortConnected(i)); - LOGINFO("update Port Status [%d] \n", i); - hdmiInputs[i].update(params.status.isPortConnected[i]); - } - } + LOGINFO("Is HDMI In Port [%d] connected [%d] \n",i, hdmiInputs[i].m_isConnected); + if ( hdmiInputs[i].m_isConnected ) + { + isAnyPortConnected = true; + } + } if ( isAnyPortConnected ) { m_isHdmiInConnected = true; @@ -3542,30 +3533,26 @@ namespace WPEFramework } - void HdmiCecSink::getHdmiArcPortID() - { - int err; - dsGetHDMIARCPortIdParam_t param; - unsigned int retryCount = 1; - do { - usleep(50000); // Sleep for 50ms before retrying - param.portId = -1; // Initialize to an invalid port ID - err = IARM_Bus_Call(IARM_BUS_DSMGR_NAME, - (char *)IARM_BUS_DSMGR_API_dsGetHDMIARCPortId, - (void *)¶m, - sizeof(param)); - if (IARM_RESULT_SUCCESS == err) - { - LOGINFO("HDMI ARC port ID HdmiArcPortID[%d] on retry count[%d]", param.portId, retryCount); - HdmiArcPortID = param.portId; - break; - } - else - { - LOGWARN("IARM_Bus_Call failed with error[%d], retry count[%d]", err, retryCount); - } - } while(retryCount++ <= 6); - } + void HdmiCecSink::getHdmiArcPortID() + { + int portId; + unsigned int retryCount = 1; + do { + usleep(50000); // Sleep for 50ms before retrying + portId = -1; + dsError_t error = device::HdmiInput::getInstance().getHDMIARCPortId(portId); + if (dsERR_NONE == error) + { + LOGINFO("HDMI ARC port ID HdmiArcPortID[%d] on retry count[%d]", portId, retryCount); + HdmiArcPortID = portId; + break; + } + else + { + LOGWARN("getHDMIARCPortId failed for retry count[%d]", retryCount); + } + } while(retryCount++ <= 6); + } void HdmiCecSink::getCecVersion() { diff --git a/HdmiCecSink/HdmiCecSink.h b/HdmiCecSink/HdmiCecSink.h index 2bc6d7c6..fff9ba1d 100644 --- a/HdmiCecSink/HdmiCecSink.h +++ b/HdmiCecSink/HdmiCecSink.h @@ -41,6 +41,8 @@ #include "UtilsLogging.h" #include #include "PowerManagerInterface.h" +#include "host.hpp" + using namespace WPEFramework; using PowerState = WPEFramework::Exchange::IPowerManager::PowerState; @@ -482,7 +484,7 @@ namespace WPEFramework { // As the registration/unregistration of notifications is realized by the class PluginHost::JSONRPC, // this class exposes a public method called, Notify(), using this methods, all subscribed clients // will receive a JSONRPC message as a notification, in case this method is called. - class HdmiCecSink : public PluginHost::IPlugin, public PluginHost::JSONRPC { + class HdmiCecSink : public PluginHost::IPlugin, public PluginHost::JSONRPC, public device::Host::IHdmiInEvents { enum { POLL_THREAD_STATE_NONE, @@ -530,6 +532,7 @@ namespace WPEFramework { virtual const string Initialize(PluginHost::IShell* shell) override; virtual void Deinitialize(PluginHost::IShell* service) override; virtual string Information() const override { return {}; } + virtual void OnHdmiInEventHotPlug(dsHdmiInPort_t port, bool isConnected) override; static HdmiCecSink* _instance; CECDeviceParams deviceList[16]; std::vector hdmiInputs; @@ -586,6 +589,13 @@ namespace WPEFramework { END_INTERFACE_MAP private: + template + T* baseInterface() + { + static_assert(std::is_base_of(), "base type mismatch"); + return static_cast(this); + } + class PowerManagerNotification : public Exchange::IPowerManager::IModeChangedNotification { private: PowerManagerNotification(const PowerManagerNotification&) = delete; diff --git a/HdmiCecSource/HdmiCecSourceImplementation.cpp b/HdmiCecSource/HdmiCecSourceImplementation.cpp index 4a4e3e64..09f0e957 100644 --- a/HdmiCecSource/HdmiCecSourceImplementation.cpp +++ b/HdmiCecSource/HdmiCecSourceImplementation.cpp @@ -25,7 +25,6 @@ #include "ccec/MessageEncoder.hpp" #include "host.hpp" -#include "dsMgr.h" #include "dsDisplay.h" #include "videoOutputPort.hpp" #include "manager.hpp" @@ -389,8 +388,7 @@ namespace WPEFramework _powerManagerPlugin.Reset(); } _registeredEventHandlers = false; - - DeinitializeIARM(); + device::Host::getInstance().UnRegister(baseInterface()); } Core::hresult HdmiCecSourceImplementation::Configure(PluginHost::IShell* service) @@ -409,7 +407,6 @@ namespace WPEFramework logicalAddress = 0xFF; //CEC plugin functionalities will only work if CECmgr is available. If plugin Initialize failure upper layer will call dtor directly. - InitializeIARM(); InitializePowerManager(service); // load persistence setting @@ -418,6 +415,8 @@ namespace WPEFramework { //TODO(MROLLINS) this is probably per process so we either need to be running in our own process or be carefull no other plugin is calling it device::Manager::Initialize(); + device::Host::getInstance().Register(baseInterface(), "WPE::CecSource"); + std::string strVideoPort = device::Host::getInstance().getDefaultVideoPortName(); device::VideoOutputPort vPort = device::Host::getInstance().getVideoOutputPort(strVideoPort.c_str()); if (vPort.isDisplayConnected()) @@ -731,20 +730,6 @@ namespace WPEFramework registerEventHandlers(); } - const void HdmiCecSourceImplementation::InitializeIARM() - { - IARM_Result_t res; - IARM_CHECK( IARM_Bus_RegisterEventHandler(IARM_BUS_DSMGR_NAME,IARM_BUS_DSMGR_EVENT_HDMI_HOTPLUG, dsHdmiEventHandler) ); - } - - void HdmiCecSourceImplementation::DeinitializeIARM() - { - if (Utils::IARM::isConnected()) - { - IARM_Result_t res; - IARM_CHECK( IARM_Bus_RemoveEventHandler(IARM_BUS_DSMGR_NAME,IARM_BUS_DSMGR_EVENT_HDMI_HOTPLUG,dsHdmiEventHandler) ); - } - } void HdmiCecSourceImplementation::threadHotPlugEventHandler(int data) { LOGINFO("entry threadHotPlugEventHandler \r\n"); @@ -759,25 +744,21 @@ namespace WPEFramework LOGINFO("Exit threadHotPlugEventHandler \r\n"); } - void HdmiCecSourceImplementation::dsHdmiEventHandler(const char *owner, IARM_EventId_t eventId, void *data, size_t len) + void HdmiCecSourceImplementation::OnDisplayHDMIHotPlug(dsDisplayEvent_t displayEvent) { - if(!HdmiCecSourceImplementation::_instance || !_instance->cecEnableStatus) - { - LOGINFO("Return from dsHdmiEventHandler due HdmiCecSourceImplementation::_instance:%p cecEnableStatus:%d \r\n", HdmiCecSourceImplementation::_instance, _instance->cecEnableStatus); - return; - } + LOGINFO("HdmiCecSourceImplementation::OnDisplayHDMIHotPlug : displayEvent = %d ", displayEvent); + + if(!HdmiCecSourceImplementation::_instance || !_instance->cecEnableStatus) + { + LOGINFO("HdmiCecSourceImplementation::OnDisplayHDMIHotPlug failed _instance:%p cecEnableStatus:%d \r\n", HdmiCecSourceImplementation::_instance, _instance->cecEnableStatus); + return; + } + + int hdmi_hotplug_event = (int) displayEvent; + LOGINFO("Received IARM_BUS_DSMGR_EVENT_HDMI_HOTPLUG event data:%d \r\n", hdmi_hotplug_event); + std::thread worker(threadHotPlugEventHandler,hdmi_hotplug_event); + worker.detach(); - if (owner && !strcmp(owner, IARM_BUS_DSMGR_NAME) && (IARM_BUS_DSMGR_EVENT_HDMI_HOTPLUG == eventId)) - { - IARM_Bus_DSMgr_EventData_t *eventData = (IARM_Bus_DSMgr_EventData_t *)data; - if(eventData) - { - int hdmi_hotplug_event = eventData->data.hdmi_hpd.event; - LOGINFO("Received IARM_BUS_DSMGR_EVENT_HDMI_HOTPLUG event data:%d \r\n", hdmi_hotplug_event); - std::thread worker(threadHotPlugEventHandler,hdmi_hotplug_event); - worker.detach(); - } - } } void HdmiCecSourceImplementation::onPowerModeChanged(const PowerState currentState, const PowerState newState) diff --git a/HdmiCecSource/HdmiCecSourceImplementation.h b/HdmiCecSource/HdmiCecSourceImplementation.h index 4a0abbd7..3f7ff6a4 100644 --- a/HdmiCecSource/HdmiCecSourceImplementation.h +++ b/HdmiCecSource/HdmiCecSourceImplementation.h @@ -42,6 +42,8 @@ #include #include "PowerManagerInterface.h" #include +#include "host.hpp" + using namespace WPEFramework; using PowerState = WPEFramework::Exchange::IPowerManager::PowerState; @@ -170,7 +172,7 @@ namespace WPEFramework { // As the registration/unregistration of notifications is realized by the class PluginHost::JSONRPC, // this class exposes a public method called, Notify(), using this methods, all subscribed clients // will receive a JSONRPC message as a notification, in case this method is called. - class HdmiCecSourceImplementation : public Exchange::IHdmiCecSource { + class HdmiCecSourceImplementation : public Exchange::IHdmiCecSource, public device::Host::IDisplayDeviceEvents { enum { VOLUME_UP = 0x41, VOLUME_DOWN = 0x42, @@ -196,6 +198,7 @@ namespace WPEFramework { public: HdmiCecSourceImplementation(); virtual ~HdmiCecSourceImplementation(); + virtual void OnDisplayHDMIHotPlug(dsDisplayEvent_t displayEvent) override; void onPowerModeChanged(const PowerState currentState, const PowerState newState); void registerEventHandlers(); static HdmiCecSourceImplementation* _instance; @@ -226,6 +229,13 @@ namespace WPEFramework { private: + template + T* baseInterface() + { + static_assert(std::is_base_of(), "base type mismatch"); + return static_cast(this); + } + class PowerManagerNotification : public Exchange::IPowerManager::IModeChangedNotification { private: PowerManagerNotification(const PowerManagerNotification&) = delete; diff --git a/Tests/L1Tests/tests/test_HdmiCecSource.cpp b/Tests/L1Tests/tests/test_HdmiCecSource.cpp index 3ae56adb..abd9ba87 100755 --- a/Tests/L1Tests/tests/test_HdmiCecSource.cpp +++ b/Tests/L1Tests/tests/test_HdmiCecSource.cpp @@ -342,29 +342,9 @@ class HdmiCecSourceTest : public ::testing::Test { .WillByDefault(::testing::Return()); ON_CALL(*p_connectionImplMock, addFrameListener(::testing::_)) .WillByDefault(::testing::Return()); - ON_CALL(*p_iarmBusImplMock, IARM_Bus_RegisterEventHandler(::testing::_, ::testing::_, ::testing::_)) - .WillByDefault(::testing::Invoke( - [&](const char* ownerName, IARM_EventId_t eventId, IARM_EventHandler_t handler) { - if ((string(IARM_BUS_CECMGR_NAME) == string(ownerName)) && (eventId == IARM_BUS_CECMGR_EVENT_DAEMON_INITIALIZED)) { - EXPECT_TRUE(handler != nullptr); - cecMgrEventHandler = handler; - } - if ((string(IARM_BUS_CECMGR_NAME) == string(ownerName)) && (eventId == IARM_BUS_CECMGR_EVENT_STATUS_UPDATED)) { - EXPECT_TRUE(handler != nullptr); - cecMgrEventHandler = handler; - } - if ((string(IARM_BUS_DSMGR_NAME) == string(ownerName)) && (eventId == IARM_BUS_DSMGR_EVENT_HDMI_HOTPLUG)) { - EXPECT_TRUE(handler != nullptr); - dsHdmiEventHandler = handler; - } - if ((string(IARM_BUS_PWRMGR_NAME) == string(ownerName)) && (eventId == IARM_BUS_PWRMGR_EVENT_MODECHANGED)) { - EXPECT_TRUE(handler != nullptr); - pwrMgrEventHandler = handler; - } - - return IARM_RESULT_SUCCESS; - })); - + EXPECT_CALL(*p_managerImplMock, Initialize()) + .Times(::testing::AnyNumber()) + .WillRepeatedly(::testing::Return()); } virtual ~HdmiCecSourceTest() override { @@ -1408,18 +1388,14 @@ TEST_F(HdmiCecSourceInitializedEventTest, hdmiEventHandler) iCounter ++; } - ASSERT_TRUE(dsHdmiEventHandler != nullptr); EXPECT_CALL(*p_hostImplMock, getDefaultVideoPortName()) .Times(1) .WillOnce(::testing::Return("TEST")); - - IARM_Bus_DSMgr_EventData_t eventData; - eventData.data.hdmi_hpd.event = 0; - EVENT_SUBSCRIBE(0, _T("onHdmiHotPlug"), _T("client.events.onHdmiHotPlug"), message); - dsHdmiEventHandler(IARM_BUS_DSMGR_NAME, IARM_BUS_DSMGR_EVENT_HDMI_HOTPLUG, &eventData , 0); + //plugin->OnDisplayHDMIHotPlug(dsDISPLAY_EVENT_CONNECTED); + Plugin::HdmiCecSourceImplementation::_instance->OnDisplayHDMIHotPlug(dsDISPLAY_EVENT_CONNECTED); EVENT_UNSUBSCRIBE(0, _T("onHdmiHotPlug"), _T("client.events.onHdmiHotPlug"), message); } diff --git a/build_dependencies.sh b/build_dependencies.sh index d75c69d3..2ba9a85d 100644 --- a/build_dependencies.sh +++ b/build_dependencies.sh @@ -163,8 +163,6 @@ touch telemetry_busmessage_sender.h touch maintenanceMGR.h touch pkg.h touch edid-parser.hpp -touch drm.h -touch drm_mode.h touch secure_wrapper.h touch wpa_ctrl.h touch btmgr.h diff --git a/cov_build.sh b/cov_build.sh index bde2bce8..66632fce 100644 --- a/cov_build.sh +++ b/cov_build.sh @@ -37,6 +37,7 @@ cmake -G Ninja -S "$GITHUB_WORKSPACE" -B build/entservices-inputoutput \ -I ${GITHUB_WORKSPACE}/entservices-testframework/Tests/mocks \ -I ${GITHUB_WORKSPACE}/entservices-testframework/Tests/mocks/thunder \ -I ${GITHUB_WORKSPACE}/entservices-testframework/Tests/mocks/devicesettings \ +-I /usr/include/libdrm \ -include ${GITHUB_WORKSPACE}/entservices-testframework/Tests/mocks/devicesettings.h \ -include ${GITHUB_WORKSPACE}/entservices-testframework/Tests/mocks/Iarm.h \ -include ${GITHUB_WORKSPACE}/entservices-testframework/Tests/mocks/Rfc.h \