From 5144dda2f152bbea21da8fa15370e7cd2550c645 Mon Sep 17 00:00:00 2001 From: grandhi_santoshkumar Date: Mon, 6 Jul 2026 12:52:27 +0000 Subject: [PATCH 1/8] RDKEMW-19159: Migrate libds api to thunder. Reason for change: Migrate libds api to thunder. Test Procedure: refer RDKEMW-19159 Risks: High Signed-off-by:gsanto722 --- externals/CMakeLists.txt | 5 + externals/PlayerThunderAccessBase.h | 4 +- externals/rdk/PlayerExternalsRdkInterface.cpp | 165 +++++++++++++++++- externals/rdk/PlayerExternalsRdkInterface.h | 14 ++ externals/rdk/PlayerThunderAccess.cpp | 8 + 5 files changed, 187 insertions(+), 9 deletions(-) diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt index 457439a9..1ce60daf 100644 --- a/externals/CMakeLists.txt +++ b/externals/CMakeLists.txt @@ -135,6 +135,11 @@ if(CMAKE_IARM_MGR) list(APPEND LIB_EXT_DEPENDS -lIARMBus -lds -ldshalcli) endif() +if(CMAKE_DS_THUNDER_PLUGIN) + message("CMAKE_DS_THUNDER_PLUGIN set: libds replaced by Thunder HdcpProfile.1 / DisplaySettings.1 / DisplayInfo.1") + set(LIB_EXT_DEFINES "${LIB_EXT_DEFINES} -DUSE_DS_THUNDER_PLUGIN=1") +endif() + if(CMAKE_PLAYER_RFC_REQUIRED) message("PLAYER RFC set") set(LIB_EXT_DEFINES "${LIB_EXT_DEFINES} -DPLAYER_RFC_ENABLED") diff --git a/externals/PlayerThunderAccessBase.h b/externals/PlayerThunderAccessBase.h index 8916f1de..e9722d17 100644 --- a/externals/PlayerThunderAccessBase.h +++ b/externals/PlayerThunderAccessBase.h @@ -43,7 +43,9 @@ enum PlayerThunderAccessPlugin SECMANAGER, WATERMARK, HDMIINPUT, - COMPOSITEINPUT + COMPOSITEINPUT, + HDCPPROFILE, + DISPLAYINFO }; /* diff --git a/externals/rdk/PlayerExternalsRdkInterface.cpp b/externals/rdk/PlayerExternalsRdkInterface.cpp index 107f202b..8e918dce 100644 --- a/externals/rdk/PlayerExternalsRdkInterface.cpp +++ b/externals/rdk/PlayerExternalsRdkInterface.cpp @@ -29,6 +29,10 @@ #include "PlayerExternalsInterface.h" #include +#ifdef USE_DS_THUNDER_PLUGIN +#include "PlayerThunderAccess.h" +#endif + #include #define DISPLAY_WIDTH_UNKNOWN -1 /**< Parsing failed for getResolution().getName(); */ @@ -126,7 +130,9 @@ void PlayerExternalsRdkInterface::Initialize() MW_PRE_LOGGER_LOG("Done getting interface \n"); SetHDMIStatus(); -#ifdef USE_DS_EVENT_SUPPORTED +#ifdef USE_DS_THUNDER_PLUGIN + RegisterThunderEventHandlers(); +#elif defined(USE_DS_EVENT_SUPPORTED) RegisterDsClientEventHandler(); #endif @@ -203,7 +209,9 @@ void PlayerExternalsRdkInterface::OnResolutionPreChange(int width, int height) PlayerExternalsRdkInterface::~PlayerExternalsRdkInterface() { -#ifdef USE_DS_EVENT_SUPPORTED +#ifdef USE_DS_THUNDER_PLUGIN + RemoveThunderEventHandlers(); +#elif defined(USE_DS_EVENT_SUPPORTED) RemoveDsClientEventHandlers(); #endif m_pDeviceInterfaceBase = nullptr; @@ -228,6 +236,65 @@ void PlayerExternalsRdkInterface::SetResolution(int width, int height) */ void PlayerExternalsRdkInterface::SetHDMIStatus() { +#ifdef USE_DS_THUNDER_PLUGIN + /* + * Thunder path: replaces all libds (device::Manager / VideoOutputPort) calls. + * CSV mapping: + * getHDCPCurrentProtocol -> HdcpProfile.1 getHDCPStatus -> currentHDCPVersion + * getHDCPReceiverProtocol -> HdcpProfile.1 getHDCPStatus -> receiverHDCPVersion + * isContentProtected -> HdcpProfile.1 getHDCPStatus -> isHDCPEnabled + * isDisplayConnected -> HdcpProfile.1 getHDCPStatus -> isConnected + * getPixelResolution -> DisplayInfo.1 displayinfo -> width / height + */ + bool isConnected = false; + bool isHDCPEnabled = false; + dsHdcpProtocolVersion_t hdcpCurrentProtocol = dsHDCP_VERSION_1X; + + /* --- Query HDCP status via HdcpProfile.1 --- */ + if (m_hdcpProfileThunder) { + JsonObject param, result; + if (m_hdcpProfileThunder->InvokeJSONRPC("getHDCPStatus", param, result)) { + isConnected = result["isConnected"].Boolean(); + isHDCPEnabled = result["isHDCPEnabled"].Boolean(); + std::string currentVer = result["currentHDCPVersion"].String(); + hdcpCurrentProtocol = (currentVer == "2.2") ? dsHDCP_VERSION_2X : dsHDCP_VERSION_1X; + MW_LOG_WARN("SetHDMIStatus: connected=%d enabled=%d currentHDCPVersion=%s\n", + isConnected, isHDCPEnabled, currentVer.c_str()); + } else { + MW_LOG_WARN("SetHDMIStatus: getHDCPStatus JSONRPC failed\n"); + } + } else { + MW_LOG_WARN("SetHDMIStatus: HdcpProfile Thunder object not initialised\n"); + } + + /* --- Query pixel resolution via DisplayInfo.1 --- */ + if (isConnected && m_displayInfoThunder) { + JsonObject param, result; + if (m_displayInfoThunder->InvokeJSONRPC("displayinfo", param, result)) { + int w = static_cast(result["width"].Number()); + int h = static_cast(result["height"].Number()); + MW_LOG_WARN("SetHDMIStatus: resolution %dx%d\n", w, h); + SetResolution(w, h); + } else { + MW_LOG_WARN("SetHDMIStatus: displayinfo JSONRPC failed\n"); + } + } else if (!isConnected) { + SetResolution(DISPLAY_RESOLUTION_NA, DISPLAY_RESOLUTION_NA); + } + + m_isHDCPEnabled = isHDCPEnabled; + if (m_isHDCPEnabled) { + m_hdcpCurrentProtocol = hdcpCurrentProtocol; + MW_LOG_WARN(" detected HDCP version %s\n", m_hdcpCurrentProtocol == dsHDCP_VERSION_2X ? "2.x" : "1.4"); + } else { + MW_LOG_WARN("HDCP is not enabled\n"); + } + if (!isConnected) { + m_hdcpCurrentProtocol = dsHDCP_VERSION_1X; + MW_LOG_WARN(" GetHDCPVersion: Did not detect HDCP version defaulting to 1.4 (%d)\n", m_hdcpCurrentProtocol); + } + +#else bool isConnected = false; bool isHDCPCompliant = false; bool isHDCPEnabled = true; @@ -235,12 +302,9 @@ void PlayerExternalsRdkInterface::SetHDMIStatus() dsHdcpProtocolVersion_t hdcpReceiverProtocol = dsHDCP_VERSION_MAX; dsHdcpProtocolVersion_t hdcpCurrentProtocol = dsHDCP_VERSION_MAX; - - - try { //Get the HDMI port - device::Manager::Initialize(); + device::Manager::Initialize(); std::string strVideoPort = device::Host::getInstance().getDefaultVideoPortName(); ::device::VideoOutputPort &vPort = ::device::Host::getInstance().getVideoOutputPort(strVideoPort); isConnected = vPort.isDisplayConnected(); @@ -299,7 +363,7 @@ void PlayerExternalsRdkInterface::SetHDMIStatus() SetResolution(DISPLAY_RESOLUTION_NA,DISPLAY_RESOLUTION_NA); } - device::Manager::DeInitialize(); + device::Manager::DeInitialize(); } catch (const std::exception& e) { MW_LOG_WARN("DeviceSettings exception caught: %s\n", e.what()); @@ -327,11 +391,96 @@ void PlayerExternalsRdkInterface::SetHDMIStatus() m_hdcpCurrentProtocol = dsHDCP_VERSION_1X; MW_LOG_WARN(" GetHDCPVersion: Did not detect HDCP version defaulting to 1.4 (%d)\n", m_hdcpCurrentProtocol); } - +#endif return; } +#ifdef USE_DS_THUNDER_PLUGIN +/** + * @brief Create Thunder plugin objects and subscribe to HDMI/HDCP/resolution events. + * CSV mapping: + * IARM_BUS_DSMGR_EVENT_HDCP_STATUS -> HdcpProfile.1 onDisplayConnectionChanged + * IARM_BUS_DSMGR_EVENT_HDMI_HOTPLUG -> DisplaySettings.1 connectedVideoDisplaysUpdated + * IARM_BUS_DSMGR_EVENT_RES_POSTCHANGE -> DisplaySettings.1 resolutionChanged + * IARM_BUS_DSMGR_EVENT_RES_PRECHANGE -> DisplaySettings.1 resolutionPreChange + */ +void PlayerExternalsRdkInterface::RegisterThunderEventHandlers() +{ + /* ---- HdcpProfile.1 ---- */ + m_hdcpProfileThunder = std::make_unique(PlayerThunderAccessPlugin::HDCPPROFILE); + m_hdcpProfileThunder->ActivatePlugin(); + + /* onDisplayConnectionChanged: replaces IARM_BUS_DSMGR_EVENT_HDCP_STATUS */ + m_hdcpProfileThunder->SubscribeEvent( + "onDisplayConnectionChanged", + [](const WPEFramework::Core::JSON::VariantContainer& params) { + MW_LOG_WARN("[Thunder] onDisplayConnectionChanged received\n"); + auto pInstance = PlayerExternalsRdkInterface::GetPlayerExternalsRdkInterfaceInstance(); + if (pInstance) { + pInstance->SetHDMIStatus(); + } + }); + + /* ---- DisplaySettings.1 ---- */ + m_dsThunder = std::make_unique(PlayerThunderAccessPlugin::DS); + m_dsThunder->ActivatePlugin(); + + /* connectedVideoDisplaysUpdated: replaces IARM_BUS_DSMGR_EVENT_HDMI_HOTPLUG */ + m_dsThunder->SubscribeEvent( + "connectedVideoDisplaysUpdated", + [](const WPEFramework::Core::JSON::VariantContainer& params) { + MW_LOG_WARN("[Thunder] connectedVideoDisplaysUpdated received\n"); + auto pInstance = PlayerExternalsRdkInterface::GetPlayerExternalsRdkInterfaceInstance(); + if (pInstance) { + pInstance->SetHDMIStatus(); + } + }); + + /* resolutionChanged: replaces IARM_BUS_DSMGR_EVENT_RES_POSTCHANGE */ + m_dsThunder->SubscribeEvent( + "resolutionChanged", + [](const WPEFramework::Core::JSON::VariantContainer& params) { + MW_LOG_WARN("[Thunder] resolutionChanged received\n"); + auto pInstance = PlayerExternalsRdkInterface::GetPlayerExternalsRdkInterfaceInstance(); + if (pInstance) { + pInstance->SetHDMIStatus(); + } + }); + + /* resolutionPreChange: replaces IARM_BUS_DSMGR_EVENT_RES_PRECHANGE */ + m_dsThunder->SubscribeEvent( + "resolutionPreChange", + [](const WPEFramework::Core::JSON::VariantContainer& params) { + MW_LOG_WARN("[Thunder] resolutionPreChange received\n"); + }); + + /* ---- DisplayInfo.1 ---- */ + m_displayInfoThunder = std::make_unique(PlayerThunderAccessPlugin::DISPLAYINFO); + m_displayInfoThunder->ActivatePlugin(); +} + +/** + * @brief Unsubscribe Thunder events and release plugin objects. + */ +void PlayerExternalsRdkInterface::RemoveThunderEventHandlers() +{ + if (m_hdcpProfileThunder) { + m_hdcpProfileThunder->UnSubscribeEvent("onDisplayConnectionChanged"); + m_hdcpProfileThunder.reset(); + } + if (m_dsThunder) { + m_dsThunder->UnSubscribeEvent("connectedVideoDisplaysUpdated"); + m_dsThunder->UnSubscribeEvent("resolutionChanged"); + m_dsThunder->UnSubscribeEvent("resolutionPreChange"); + m_dsThunder.reset(); + } + if (m_displayInfoThunder) { + m_displayInfoThunder.reset(); + } +} +#endif /* USE_DS_THUNDER_PLUGIN */ + void PlayerExternalsRdkInterface::setHdcpProtocol(dsHdcpProtocolVersion_t t_protocol) { m_hdcpCurrentProtocol = t_protocol; diff --git a/externals/rdk/PlayerExternalsRdkInterface.h b/externals/rdk/PlayerExternalsRdkInterface.h index 2f35e7bc..d683e672 100644 --- a/externals/rdk/PlayerExternalsRdkInterface.h +++ b/externals/rdk/PlayerExternalsRdkInterface.h @@ -24,6 +24,8 @@ #ifndef PLAYER_IARM_RDK_INTERFACE_H #define PLAYER_IARM_RDK_INTERFACE_H + +#ifndef USE_DS_THUNDER_PLUGIN #include "manager.hpp" #include "host.hpp" #include "videoResolution.hpp" @@ -33,6 +35,10 @@ #include "dsDisplay.h" #include "audioOutputPort.hpp" #include "dsAudio.h" +#else +#include "PlayerThunderAccess.h" +#include +#endif #include #include "PlayerExternalsInterfaceBase.h" @@ -88,6 +94,14 @@ class PlayerExternalsRdkInterface : public PlayerExternalsInterfaceBase /**< Callback function for fake tune operations */ std::function m_doFakeTuneCallback = nullptr; +#ifdef USE_DS_THUNDER_PLUGIN + std::unique_ptr m_hdcpProfileThunder; + std::unique_ptr m_dsThunder; + std::unique_ptr m_displayInfoThunder; + void RegisterThunderEventHandlers(); + void RemoveThunderEventHandlers(); +#endif + PlayerExternalsRdkInterface(); public: diff --git a/externals/rdk/PlayerThunderAccess.cpp b/externals/rdk/PlayerThunderAccess.cpp index 286ac37c..43eb2d95 100644 --- a/externals/rdk/PlayerThunderAccess.cpp +++ b/externals/rdk/PlayerThunderAccess.cpp @@ -52,6 +52,8 @@ using namespace WPEFramework; #define WATERMARK_PLUGIN_CALLSIGN "org.rdk.Watermark.1" #define HDMIINPUT_CALLSIGN "org.rdk.HdmiInput.1" #define COMPOSITEINPUT_CALLSIGN "org.rdk.CompositeInput.1" +#define HDCPPROFILE_CALLSIGN "org.rdk.HdcpProfile.1" +#define DISPLAYINFO_CALLSIGN "DisplayInfo.1" /** * @brief Structure to save the Thunder security token details @@ -110,6 +112,12 @@ PlayerThunderAccess::PlayerThunderAccess(PlayerThunderAccessPlugin callsign) case PlayerThunderAccessPlugin::COMPOSITEINPUT : pluginCallsign = COMPOSITEINPUT_CALLSIGN; break; + case PlayerThunderAccessPlugin::HDCPPROFILE : + pluginCallsign = HDCPPROFILE_CALLSIGN; + break; + case PlayerThunderAccessPlugin::DISPLAYINFO : + pluginCallsign = DISPLAYINFO_CALLSIGN; + break; default: MW_LOG_ERR("Undefined plugin tried to initialize: %d", (int)callsign); pluginCallsign = ""; From 4ef7c7cb3ab1e887a02da5d350f6d1f581c9e17d Mon Sep 17 00:00:00 2001 From: grandhi_santoshkumar Date: Mon, 6 Jul 2026 15:17:03 +0000 Subject: [PATCH 2/8] fixbuild issue --- externals/rdk/PlayerExternalsRdkInterface.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/externals/rdk/PlayerExternalsRdkInterface.h b/externals/rdk/PlayerExternalsRdkInterface.h index d683e672..12527c77 100644 --- a/externals/rdk/PlayerExternalsRdkInterface.h +++ b/externals/rdk/PlayerExternalsRdkInterface.h @@ -38,6 +38,10 @@ #else #include "PlayerThunderAccess.h" #include +// Compatibility aliases: libds types not available when using Thunder +typedef int dsHdcpProtocolVersion_t; +#define dsHDCP_VERSION_1X 14 +#define dsHDCP_VERSION_2X 22 #endif #include From 454d41ecd8ac6e1ca12449e9b14c7e823239f824 Mon Sep 17 00:00:00 2001 From: grandhi_santoshkumar Date: Tue, 7 Jul 2026 10:03:24 +0000 Subject: [PATCH 3/8] fix build issue --- externals/rdk/IIarm/DeviceIARMInterface.cpp | 15 ++++++++++----- externals/rdk/PlayerThunderAccess.h | 19 ++++++++++--------- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/externals/rdk/IIarm/DeviceIARMInterface.cpp b/externals/rdk/IIarm/DeviceIARMInterface.cpp index 234e6a06..8a423712 100644 --- a/externals/rdk/IIarm/DeviceIARMInterface.cpp +++ b/externals/rdk/IIarm/DeviceIARMInterface.cpp @@ -89,7 +89,7 @@ typedef struct _IARM_BUS_NetSrvMgr_Iface_EventData_t { std::shared_ptr s_pDeviceIARMInterface = nullptr; -#ifndef USE_DS_EVENT_SUPPORTED +#if !defined(USE_DS_EVENT_SUPPORTED) && !defined(USE_DS_THUNDER_PLUGIN) static void HDMIEventHandler(const char *owner, IARM_EventId_t eventId, void *data, size_t len); static void ResolutionHandler(const char *owner, IARM_EventId_t eventId, void *data, size_t len); #endif @@ -259,6 +259,7 @@ static void IARM_PowerChangeHandler (const PowerController_PowerState_t currentS void DeviceIARMInterface::IARMInit() { +#ifndef USE_DS_THUNDER_PLUGIN //char processName[20] = {0}; IARM_Result_t result; MW_PRE_LOGGER_LOG("IARM Interface Init started in Player\n"); @@ -292,12 +293,12 @@ void DeviceIARMInterface::IARMInit() } MW_PRE_LOGGER_LOG("IARM Interface Init completed in Player\n"); - +#endif /* USE_DS_THUNDER_PLUGIN */ } void DeviceIARMInterface::RegisterDsMgrEventHandler() { -#ifndef USE_DS_EVENT_SUPPORTED +#if !defined(USE_DS_EVENT_SUPPORTED) && !defined(USE_DS_THUNDER_PLUGIN) IARM_Bus_RegisterEventHandler(IARM_BUS_DSMGR_NAME,IARM_BUS_DSMGR_EVENT_HDMI_HOTPLUG, HDMIEventHandler); IARM_Bus_RegisterEventHandler(IARM_BUS_DSMGR_NAME,IARM_BUS_DSMGR_EVENT_HDCP_STATUS, HDMIEventHandler); IARM_Bus_RegisterEventHandler(IARM_BUS_DSMGR_NAME,IARM_BUS_DSMGR_EVENT_RES_POSTCHANGE, ResolutionHandler); @@ -306,16 +307,19 @@ void DeviceIARMInterface::RegisterDsMgrEventHandler() void DeviceIARMInterface::RemoveEventHandlers() { -#ifndef USE_DS_EVENT_SUPPORTED +#if !defined(USE_DS_EVENT_SUPPORTED) && !defined(USE_DS_THUNDER_PLUGIN) IARM_Bus_RemoveEventHandler(IARM_BUS_DSMGR_NAME,IARM_BUS_DSMGR_EVENT_HDMI_HOTPLUG, HDMIEventHandler); IARM_Bus_RemoveEventHandler(IARM_BUS_DSMGR_NAME,IARM_BUS_DSMGR_EVENT_HDCP_STATUS, HDMIEventHandler); IARM_Bus_RemoveEventHandler(IARM_BUS_DSMGR_NAME,IARM_BUS_DSMGR_EVENT_RES_POSTCHANGE, ResolutionHandler); #endif +#ifndef USE_DS_THUNDER_PLUGIN IARM_Bus_RemoveEventHandler("NET_SRV_MGR", IARM_BUS_NETWORK_MANAGER_EVENT_INTERFACE_IPADDRESS, getActiveInterfaceEventHandler); +#endif } void DeviceIARMInterface::RegisterNtwMgrEventHandler() { +#ifndef USE_DS_THUNDER_PLUGIN std::shared_ptr pInstance = PlayerExternalsRdkInterface::GetPlayerExternalsRdkInterfaceInstance(); bool wifiStatus = false; @@ -336,6 +340,7 @@ void DeviceIARMInterface::RegisterNtwMgrEventHandler() } IARM_Bus_RegisterEventHandler("NET_SRV_MGR", IARM_BUS_NETWORK_MANAGER_EVENT_INTERFACE_IPADDRESS, getActiveInterfaceEventHandler); pInstance->SetActiveInterface(wifiStatus); +#endif /* USE_DS_THUNDER_PLUGIN */ } char * DeviceIARMInterface::GetTR181Config(const char * paramName, size_t & iConfigLen) @@ -407,7 +412,7 @@ static void getActiveInterfaceEventHandler (const char *owner, IARM_EventId_t ev } -#ifndef USE_DS_EVENT_SUPPORTED +#if !defined(USE_DS_EVENT_SUPPORTED) && !defined(USE_DS_THUNDER_PLUGIN) /** * @brief IARM event handler for HDCP and HDMI hot plug events */ diff --git a/externals/rdk/PlayerThunderAccess.h b/externals/rdk/PlayerThunderAccess.h index 427d2f5c..6d6e75e5 100644 --- a/externals/rdk/PlayerThunderAccess.h +++ b/externals/rdk/PlayerThunderAccess.h @@ -28,6 +28,7 @@ #include "Module.h" #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Weffc++" +#pragma GCC diagnostic ignored "-Wmacro-redefined" #include #include #pragma GCC diagnostic pop @@ -79,6 +80,15 @@ class PlayerThunderAccess : public PlayerThunderAccessBase */ bool ActivatePlugin() override; + /** + * @fn SubscribeEvent + * @note Subscribe event data for the specific plugin + * @param eventName,functionHandler Event name, Event handler + * @retval true on success + * @retval false on failure + */ + bool SubscribeEvent (string eventName, std::function functionHandler); + /** * @fn UnSubscribeEvent * @note unSubscribe event data for the specific plugin @@ -397,15 +407,6 @@ class PlayerThunderAccess : public PlayerThunderAccessBase */ bool GetResolutionFromDS_VIDEOIN(int & widthFromDS, int & heightFromDS); - /** - * @fn SubscribeEvent - * @note Subscribe event data for the specific plugin - * @param eventName,functionHandler Event name, Event handler - * @retval true on success - * @retval false on failure - */ - bool SubscribeEvent (string eventName, std::function functionHandler); - /** * @fn GetAudioTrackInternal * From 397057aa2ac7287c6c7f40af5d10895f7abc172e Mon Sep 17 00:00:00 2001 From: grandhi_santoshkumar Date: Tue, 7 Jul 2026 14:14:14 +0000 Subject: [PATCH 4/8] fix linking issue from aamp --- externals/CMakeLists.txt | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt index 1ce60daf..3bb50b14 100644 --- a/externals/CMakeLists.txt +++ b/externals/CMakeLists.txt @@ -132,12 +132,31 @@ if(CMAKE_IARM_MGR) set(EXT_SOURCES "${EXT_SOURCES}" rdk/IIarm/DeviceIARMInterface.cpp) set(EXT_SOURCES "${EXT_SOURCES}" rdk/IFirebolt/DeviceFireboltInterface.cpp) set(EXT_SOURCES "${EXT_SOURCES}" IFirebolt/FireboltInterface.cpp) - list(APPEND LIB_EXT_DEPENDS -lIARMBus -lds -ldshalcli) + if(CMAKE_DS_THUNDER_PLUGIN) + # Thunder path: libds (-lds -ldshalcli) replaced by Thunder plugins; keep only IARM bus + list(APPEND LIB_EXT_DEPENDS -lIARMBus) + else() + list(APPEND LIB_EXT_DEPENDS -lIARMBus -lds -ldshalcli) + endif() endif() if(CMAKE_DS_THUNDER_PLUGIN) message("CMAKE_DS_THUNDER_PLUGIN set: libds replaced by Thunder HdcpProfile.1 / DisplaySettings.1 / DisplayInfo.1") set(LIB_EXT_DEFINES "${LIB_EXT_DEFINES} -DUSE_DS_THUNDER_PLUGIN=1") + # PlayerThunderAccess.cpp is required; ensure it is compiled even if CMAKE_WPEFRAMEWORK_REQUIRED was not set + if(NOT CMAKE_WPEFRAMEWORK_REQUIRED) + message("CMAKE_DS_THUNDER_PLUGIN: auto-enabling WPEFramework for PlayerThunderAccess") + list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/") + set(LIB_EXT_DEFINES "${LIB_EXT_DEFINES} -DUSE_CPP_THUNDER_PLUGIN_ACCESS") + set(THUNDER_INTERFACE_SRCS ${THUNDER_INTERFACE_SRCS} rdk/PlayerThunderAccess.cpp Module.cpp) + find_package(WPEFramework REQUIRED) + if(WPEFRAMEWORK_FOUND) + include_directories(SYSTEM ${WPEFRAMEWORK_INCLUDE_DIRS}) + list(APPEND LIB_EXT_DEPENDS ${WPEFRAMEWORK_LIBRARIES}) + else() + message(FATAL_ERROR "CMAKE_DS_THUNDER_PLUGIN requires WPEFramework but it was not found") + endif() + endif() endif() if(CMAKE_PLAYER_RFC_REQUIRED) From 7a6d1e525da4b1a8f2183b89c3154fbc3b74b1a2 Mon Sep 17 00:00:00 2001 From: grandhi_santoshkumar Date: Wed, 8 Jul 2026 15:04:46 +0000 Subject: [PATCH 5/8] change IP for JSON as like Netflix --- externals/rdk/PlayerThunderAccess.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/externals/rdk/PlayerThunderAccess.cpp b/externals/rdk/PlayerThunderAccess.cpp index 43eb2d95..5722aaf5 100644 --- a/externals/rdk/PlayerThunderAccess.cpp +++ b/externals/rdk/PlayerThunderAccess.cpp @@ -35,7 +35,7 @@ using namespace std; using namespace WPEFramework; -#define SERVER_DETAILS "127.0.0.1:9998" +#define SERVER_DETAILS "100.64.11.1:9998" #define MAX_LENGTH 1024 #define APP_ID "MainPlayer" From 883de4692f606255bf03edd4a580886c2899d518 Mon Sep 17 00:00:00 2001 From: grandhi_santoshkumar Date: Thu, 9 Jul 2026 10:21:12 +0000 Subject: [PATCH 6/8] added debug logs in player interface code --- externals/rdk/PlayerExternalsRdkInterface.cpp | 110 +++++++++++++----- externals/rdk/PlayerThunderAccess.cpp | 12 +- 2 files changed, 91 insertions(+), 31 deletions(-) diff --git a/externals/rdk/PlayerExternalsRdkInterface.cpp b/externals/rdk/PlayerExternalsRdkInterface.cpp index 8e918dce..33c41a18 100644 --- a/externals/rdk/PlayerExternalsRdkInterface.cpp +++ b/externals/rdk/PlayerExternalsRdkInterface.cpp @@ -250,48 +250,82 @@ void PlayerExternalsRdkInterface::SetHDMIStatus() bool isHDCPEnabled = false; dsHdcpProtocolVersion_t hdcpCurrentProtocol = dsHDCP_VERSION_1X; + MW_LOG_WARN("[DS-Thunder] SetHDMIStatus() called\n"); + /* --- Query HDCP status via HdcpProfile.1 --- */ if (m_hdcpProfileThunder) { JsonObject param, result; - if (m_hdcpProfileThunder->InvokeJSONRPC("getHDCPStatus", param, result)) { - isConnected = result["isConnected"].Boolean(); - isHDCPEnabled = result["isHDCPEnabled"].Boolean(); - std::string currentVer = result["currentHDCPVersion"].String(); - hdcpCurrentProtocol = (currentVer == "2.2") ? dsHDCP_VERSION_2X : dsHDCP_VERSION_1X; - MW_LOG_WARN("SetHDMIStatus: connected=%d enabled=%d currentHDCPVersion=%s\n", - isConnected, isHDCPEnabled, currentVer.c_str()); + std::string rawResponse; + MW_LOG_WARN("[DS-Thunder] Calling HdcpProfile.1::getHDCPStatus\n"); + bool rpcRet = m_hdcpProfileThunder->InvokeJSONRPC("getHDCPStatus", param, result); + result.ToString(rawResponse); + MW_LOG_WARN("[DS-Thunder] getHDCPStatus rpcRet=%d rawResponse=%s\n", rpcRet, rawResponse.c_str()); + if (rpcRet) { + /* Response is nested: { "HDCPStatus": { "isConnected":..., ... }, "success":true } */ + if (result.HasLabel("HDCPStatus")) { + JsonObject hdcpStatus = result["HDCPStatus"].Object(); + std::string hdcpStatusStr; + hdcpStatus.ToString(hdcpStatusStr); + MW_LOG_WARN("[DS-Thunder] HDCPStatus object=%s\n", hdcpStatusStr.c_str()); + isConnected = hdcpStatus["isConnected"].Boolean(); + isHDCPEnabled = hdcpStatus["isHDCPEnabled"].Boolean(); + std::string currentVer = hdcpStatus["currentHDCPVersion"].String(); + hdcpCurrentProtocol = (currentVer == "2.2") ? dsHDCP_VERSION_2X : dsHDCP_VERSION_1X; + MW_LOG_WARN("[DS-Thunder] getHDCPStatus: isConnected=%d isHDCPEnabled=%d currentHDCPVersion=%s\n", + isConnected, isHDCPEnabled, currentVer.c_str()); + } else { + MW_LOG_WARN("[DS-Thunder] getHDCPStatus: 'HDCPStatus' key missing in response — falling back to flat read\n"); + /* Fallback: try flat fields (old API) */ + isConnected = result["isConnected"].Boolean(); + isHDCPEnabled = result["isHDCPEnabled"].Boolean(); + std::string currentVer = result["currentHDCPVersion"].String(); + hdcpCurrentProtocol = (currentVer == "2.2") ? dsHDCP_VERSION_2X : dsHDCP_VERSION_1X; + MW_LOG_WARN("[DS-Thunder] fallback flat: isConnected=%d isHDCPEnabled=%d currentHDCPVersion=%s\n", + isConnected, isHDCPEnabled, currentVer.c_str()); + } } else { - MW_LOG_WARN("SetHDMIStatus: getHDCPStatus JSONRPC failed\n"); + MW_LOG_WARN("[DS-Thunder] getHDCPStatus JSONRPC call failed (rpcRet=false)\n"); } } else { - MW_LOG_WARN("SetHDMIStatus: HdcpProfile Thunder object not initialised\n"); + MW_LOG_WARN("[DS-Thunder] m_hdcpProfileThunder is NULL — was RegisterThunderEventHandlers() called?\n"); } /* --- Query pixel resolution via DisplayInfo.1 --- */ if (isConnected && m_displayInfoThunder) { JsonObject param, result; - if (m_displayInfoThunder->InvokeJSONRPC("displayinfo", param, result)) { - int w = static_cast(result["width"].Number()); - int h = static_cast(result["height"].Number()); - MW_LOG_WARN("SetHDMIStatus: resolution %dx%d\n", w, h); + std::string rawResponse; + MW_LOG_WARN("[DS-Thunder] Calling DisplayInfo.1::displayinfo (property)\n"); + /* Note: displayinfo is a WPEFramework *property* — it has no "success" field. + * InvokeJSONRPC may return false even on success; read result fields directly. */ + bool rpcRet = m_displayInfoThunder->InvokeJSONRPC("displayinfo", param, result); + result.ToString(rawResponse); + MW_LOG_WARN("[DS-Thunder] displayinfo rpcRet=%d rawResponse=%s\n", rpcRet, rawResponse.c_str()); + /* Read width/height regardless of rpcRet — property has no "success" key */ + int w = static_cast(result["width"].Number()); + int h = static_cast(result["height"].Number()); + MW_LOG_WARN("[DS-Thunder] displayinfo: width=%d height=%d\n", w, h); + if (w > 0 && h > 0) { SetResolution(w, h); } else { - MW_LOG_WARN("SetHDMIStatus: displayinfo JSONRPC failed\n"); + MW_LOG_WARN("[DS-Thunder] displayinfo: invalid resolution w=%d h=%d — keeping current\n", w, h); } } else if (!isConnected) { + MW_LOG_WARN("[DS-Thunder] Display not connected — setting resolution to NA\n"); SetResolution(DISPLAY_RESOLUTION_NA, DISPLAY_RESOLUTION_NA); + } else { + MW_LOG_WARN("[DS-Thunder] m_displayInfoThunder is NULL\n"); } m_isHDCPEnabled = isHDCPEnabled; if (m_isHDCPEnabled) { m_hdcpCurrentProtocol = hdcpCurrentProtocol; - MW_LOG_WARN(" detected HDCP version %s\n", m_hdcpCurrentProtocol == dsHDCP_VERSION_2X ? "2.x" : "1.4"); + MW_LOG_WARN("[DS-Thunder] HDCP version detected: %s\n", m_hdcpCurrentProtocol == dsHDCP_VERSION_2X ? "2.x" : "1.4"); } else { - MW_LOG_WARN("HDCP is not enabled\n"); + MW_LOG_WARN("[DS-Thunder] HDCP is not enabled\n"); } if (!isConnected) { m_hdcpCurrentProtocol = dsHDCP_VERSION_1X; - MW_LOG_WARN(" GetHDCPVersion: Did not detect HDCP version defaulting to 1.4 (%d)\n", m_hdcpCurrentProtocol); + MW_LOG_WARN("[DS-Thunder] GetHDCPVersion: Display not connected — defaulting to HDCP 1.4 (%d)\n", m_hdcpCurrentProtocol); } #else @@ -407,57 +441,77 @@ void PlayerExternalsRdkInterface::SetHDMIStatus() */ void PlayerExternalsRdkInterface::RegisterThunderEventHandlers() { + MW_LOG_WARN("[DS-Thunder] RegisterThunderEventHandlers() start\n"); + /* ---- HdcpProfile.1 ---- */ + MW_LOG_WARN("[DS-Thunder] Creating PlayerThunderAccess for HDCPPROFILE (org.rdk.HdcpProfile.1)\n"); m_hdcpProfileThunder = std::make_unique(PlayerThunderAccessPlugin::HDCPPROFILE); - m_hdcpProfileThunder->ActivatePlugin(); + bool activateRet = m_hdcpProfileThunder->ActivatePlugin(); + MW_LOG_WARN("[DS-Thunder] HdcpProfile.1 ActivatePlugin() ret=%d\n", activateRet); /* onDisplayConnectionChanged: replaces IARM_BUS_DSMGR_EVENT_HDCP_STATUS */ - m_hdcpProfileThunder->SubscribeEvent( + bool subRet = m_hdcpProfileThunder->SubscribeEvent( "onDisplayConnectionChanged", [](const WPEFramework::Core::JSON::VariantContainer& params) { - MW_LOG_WARN("[Thunder] onDisplayConnectionChanged received\n"); + std::string paramsStr; + params.ToString(paramsStr); + MW_LOG_WARN("[DS-Thunder] onDisplayConnectionChanged event received params=%s\n", paramsStr.c_str()); auto pInstance = PlayerExternalsRdkInterface::GetPlayerExternalsRdkInterfaceInstance(); if (pInstance) { pInstance->SetHDMIStatus(); } }); + MW_LOG_WARN("[DS-Thunder] HdcpProfile.1 SubscribeEvent(onDisplayConnectionChanged) ret=%d\n", subRet); /* ---- DisplaySettings.1 ---- */ + MW_LOG_WARN("[DS-Thunder] Creating PlayerThunderAccess for DS (org.rdk.DisplaySettings.1)\n"); m_dsThunder = std::make_unique(PlayerThunderAccessPlugin::DS); - m_dsThunder->ActivatePlugin(); + activateRet = m_dsThunder->ActivatePlugin(); + MW_LOG_WARN("[DS-Thunder] DisplaySettings.1 ActivatePlugin() ret=%d\n", activateRet); /* connectedVideoDisplaysUpdated: replaces IARM_BUS_DSMGR_EVENT_HDMI_HOTPLUG */ - m_dsThunder->SubscribeEvent( + subRet = m_dsThunder->SubscribeEvent( "connectedVideoDisplaysUpdated", [](const WPEFramework::Core::JSON::VariantContainer& params) { - MW_LOG_WARN("[Thunder] connectedVideoDisplaysUpdated received\n"); + std::string paramsStr; + params.ToString(paramsStr); + MW_LOG_WARN("[DS-Thunder] connectedVideoDisplaysUpdated event received params=%s\n", paramsStr.c_str()); auto pInstance = PlayerExternalsRdkInterface::GetPlayerExternalsRdkInterfaceInstance(); if (pInstance) { pInstance->SetHDMIStatus(); } }); + MW_LOG_WARN("[DS-Thunder] DisplaySettings.1 SubscribeEvent(connectedVideoDisplaysUpdated) ret=%d\n", subRet); /* resolutionChanged: replaces IARM_BUS_DSMGR_EVENT_RES_POSTCHANGE */ - m_dsThunder->SubscribeEvent( + subRet = m_dsThunder->SubscribeEvent( "resolutionChanged", [](const WPEFramework::Core::JSON::VariantContainer& params) { - MW_LOG_WARN("[Thunder] resolutionChanged received\n"); + std::string paramsStr; + params.ToString(paramsStr); + MW_LOG_WARN("[DS-Thunder] resolutionChanged event received params=%s\n", paramsStr.c_str()); auto pInstance = PlayerExternalsRdkInterface::GetPlayerExternalsRdkInterfaceInstance(); if (pInstance) { pInstance->SetHDMIStatus(); } }); + MW_LOG_WARN("[DS-Thunder] DisplaySettings.1 SubscribeEvent(resolutionChanged) ret=%d\n", subRet); /* resolutionPreChange: replaces IARM_BUS_DSMGR_EVENT_RES_PRECHANGE */ - m_dsThunder->SubscribeEvent( + subRet = m_dsThunder->SubscribeEvent( "resolutionPreChange", [](const WPEFramework::Core::JSON::VariantContainer& params) { - MW_LOG_WARN("[Thunder] resolutionPreChange received\n"); + MW_LOG_WARN("[DS-Thunder] resolutionPreChange event received\n"); }); + MW_LOG_WARN("[DS-Thunder] DisplaySettings.1 SubscribeEvent(resolutionPreChange) ret=%d\n", subRet); /* ---- DisplayInfo.1 ---- */ + MW_LOG_WARN("[DS-Thunder] Creating PlayerThunderAccess for DISPLAYINFO (DisplayInfo.1)\n"); m_displayInfoThunder = std::make_unique(PlayerThunderAccessPlugin::DISPLAYINFO); - m_displayInfoThunder->ActivatePlugin(); + activateRet = m_displayInfoThunder->ActivatePlugin(); + MW_LOG_WARN("[DS-Thunder] DisplayInfo.1 ActivatePlugin() ret=%d\n", activateRet); + + MW_LOG_WARN("[DS-Thunder] RegisterThunderEventHandlers() done\n"); } /** diff --git a/externals/rdk/PlayerThunderAccess.cpp b/externals/rdk/PlayerThunderAccess.cpp index 5722aaf5..fc7c78bc 100644 --- a/externals/rdk/PlayerThunderAccess.cpp +++ b/externals/rdk/PlayerThunderAccess.cpp @@ -126,20 +126,26 @@ PlayerThunderAccess::PlayerThunderAccess(PlayerThunderAccessPlugin callsign) uint32_t status = Core::ERROR_NONE; + MW_LOG_WARN("[ThunderAccess] Connecting to Thunder server=%s callsign=%s", SERVER_DETAILS, pluginCallsign.c_str()); + Core::SystemInfo::SetEnvironment(_T("THUNDER_ACCESS"), (_T(SERVER_DETAILS))); string sToken = ""; #ifdef DISABLE_SECURITY_TOKEN gPlayerSecurityData.securityToken = "token=" + sToken; gPlayerSecurityData.tokenQueried = true; + MW_LOG_WARN("[ThunderAccess] Security token DISABLED"); #else if(!gPlayerSecurityData.tokenQueried) { unsigned char buffer[MAX_LENGTH] = {0}; gPlayerSecurityData.tokenStatus = GetSecurityToken(MAX_LENGTH,buffer); if(gPlayerSecurityData.tokenStatus > 0){ - // LOG_INFO( "[ThunderAccess] : GetSecurityToken success"); sToken = (char*)buffer; gPlayerSecurityData.securityToken = "token=" + sToken; + MW_LOG_WARN("[ThunderAccess] Security token obtained (len=%d)", gPlayerSecurityData.tokenStatus); + } + else { + MW_LOG_WARN("[ThunderAccess] GetSecurityToken failed status=%d — proceeding without token", gPlayerSecurityData.tokenStatus); } gPlayerSecurityData.tokenQueried = true; } @@ -157,7 +163,7 @@ PlayerThunderAccess::PlayerThunderAccess(PlayerThunderAccessPlugin callsign) if (NULL == controllerObject) { MW_LOG_WARN( "[ThunderAccess] Controller object creation failed"); } else { - MW_LOG_INFO( "[ThunderAccess] Controller object creation success"); + MW_LOG_INFO( "[ThunderAccess] Controller object creation success (server=%s)", SERVER_DETAILS); } } @@ -170,7 +176,7 @@ PlayerThunderAccess::PlayerThunderAccess(PlayerThunderAccessPlugin callsign) if (NULL == remoteObject) { MW_LOG_WARN( "[ThunderAccess] %s Client initialization failed", pluginCallsign.c_str()); } else { - MW_LOG_INFO( "[ThunderAccess] %s Client initialization success", pluginCallsign.c_str()); + MW_LOG_INFO( "[ThunderAccess] %s Client initialization success (server=%s)", pluginCallsign.c_str(), SERVER_DETAILS); } } From a612d661f0b057d952ec61b64aeb5ddc48ac7742 Mon Sep 17 00:00:00 2001 From: grandhi_santoshkumar Date: Thu, 9 Jul 2026 15:54:31 +0000 Subject: [PATCH 7/8] fix thunder api fail --- externals/CMakeLists.txt | 2 +- externals/PlayerThunderAccessBase.h | 3 +- .../ThunderAccessPlayer.cpp | 50 ++++--- externals/rdk/PlayerExternalsRdkInterface.cpp | 139 ++++++++++++------ externals/rdk/PlayerExternalsRdkInterface.h | 13 +- externals/rdk/PlayerThunderAccess.cpp | 4 - externals/rdk/PlayerThunderAccess.h | 1 - 7 files changed, 136 insertions(+), 76 deletions(-) diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt index 3bb50b14..e1b098a5 100644 --- a/externals/CMakeLists.txt +++ b/externals/CMakeLists.txt @@ -141,7 +141,7 @@ if(CMAKE_IARM_MGR) endif() if(CMAKE_DS_THUNDER_PLUGIN) - message("CMAKE_DS_THUNDER_PLUGIN set: libds replaced by Thunder HdcpProfile.1 / DisplaySettings.1 / DisplayInfo.1") + message("CMAKE_DS_THUNDER_PLUGIN set: libds replaced by Thunder HdcpProfile.1 / DisplaySettings.1") set(LIB_EXT_DEFINES "${LIB_EXT_DEFINES} -DUSE_DS_THUNDER_PLUGIN=1") # PlayerThunderAccess.cpp is required; ensure it is compiled even if CMAKE_WPEFRAMEWORK_REQUIRED was not set if(NOT CMAKE_WPEFRAMEWORK_REQUIRED) diff --git a/externals/PlayerThunderAccessBase.h b/externals/PlayerThunderAccessBase.h index e9722d17..090b0ac0 100644 --- a/externals/PlayerThunderAccessBase.h +++ b/externals/PlayerThunderAccessBase.h @@ -44,8 +44,7 @@ enum PlayerThunderAccessPlugin WATERMARK, HDMIINPUT, COMPOSITEINPUT, - HDCPPROFILE, - DISPLAYINFO + HDCPPROFILE }; /* diff --git a/externals/contentsecuritymanager/ThunderAccessPlayer.cpp b/externals/contentsecuritymanager/ThunderAccessPlayer.cpp index 6ab170f8..12253dc4 100755 --- a/externals/contentsecuritymanager/ThunderAccessPlayer.cpp +++ b/externals/contentsecuritymanager/ThunderAccessPlayer.cpp @@ -64,7 +64,7 @@ ThunderAccessPlayer::ThunderAccessPlayer(std::string callsign) ,controllerObject(NULL) ,pluginCallsign(callsign) { - MW_LOG_INFO( "[ThunderAccessPlayer]Inside"); + MW_LOG_WARN( "[GSK-TAP-CTOR] callsign=%s server=%s", callsign.c_str(), SERVER_DETAILS); uint32_t status = Core::ERROR_NONE; Core::SystemInfo::SetEnvironment(_T("THUNDER_ACCESS"), (_T(SERVER_DETAILS))); @@ -72,19 +72,22 @@ ThunderAccessPlayer::ThunderAccessPlayer(std::string callsign) #ifdef DISABLE_SECURITY_TOKEN gSecurityPlayerData.securityToken = "token=" + sToken; gSecurityPlayerData.tokenQueried = true; + MW_LOG_WARN( "[GSK-TAP-TOKEN] security token DISABLED"); #else if(!gSecurityPlayerData.tokenQueried) { unsigned char buffer[MAX_LENGTH] = {0}; gSecurityPlayerData.tokenStatus = GetSecurityToken(MAX_LENGTH,buffer); if(gSecurityPlayerData.tokenStatus > 0){ - MW_LOG_INFO( "[ThunderAccessPlayer] : GetSecurityToken success"); sToken = (char*)buffer; gSecurityPlayerData.securityToken = "token=" + sToken; + MW_LOG_WARN( "[GSK-TAP-TOKEN] GetSecurityToken success len=%d", gSecurityPlayerData.tokenStatus); + } else { + MW_LOG_WARN( "[GSK-TAP-TOKEN] GetSecurityToken failed status=%d proceeding without token", gSecurityPlayerData.tokenStatus); } gSecurityPlayerData.tokenQueried = true; - - //MW_LOG_WARN( "[ThunderAccessPlayer] securityToken : %s tokenStatus : %d tokenQueried : %s", gSecurityPlayerData.securityToken.c_str(), gSecurityPlayerData.tokenStatus, ((gSecurityPlayerData.tokenQueried)?"true":"false")); + } else { + MW_LOG_INFO( "[GSK-TAP-TOKEN] reusing cached token tokenStatus=%d", gSecurityPlayerData.tokenStatus); } #endif if (NULL == controllerObject) { @@ -97,9 +100,9 @@ ThunderAccessPlayer::ThunderAccessPlayer(std::string callsign) } if (NULL == controllerObject) { - MW_LOG_WARN( "[ThunderAccessPlayer] Controller object creation failed"); + MW_LOG_WARN( "[GSK-TAP-CTRL] controller object creation FAILED"); } else { - MW_LOG_INFO( "[ThunderAccessPlayer] Controller object creation success"); + MW_LOG_WARN( "[GSK-TAP-CTRL] controller object created OK server=%s", SERVER_DETAILS); } } @@ -110,9 +113,9 @@ ThunderAccessPlayer::ThunderAccessPlayer(std::string callsign) remoteObject = new JSONRPC::LinkType(_T(pluginCallsign), _T("")); } if (NULL == remoteObject) { - MW_LOG_WARN( "[ThunderAccessPlayer] %s Client initialization failed", pluginCallsign.c_str()); + MW_LOG_WARN( "[GSK-TAP-REMOTE] %s remote object creation FAILED", pluginCallsign.c_str()); } else { - MW_LOG_INFO( "[ThunderAccessPlayer] %s Client initialization success", pluginCallsign.c_str()); + MW_LOG_WARN( "[GSK-TAP-REMOTE] %s remote object created OK server=%s", pluginCallsign.c_str(), SERVER_DETAILS); } } @@ -138,18 +141,19 @@ bool ThunderAccessPlayer::ActivatePlugin() if (NULL != controllerObject) { controlParam["callsign"] = pluginCallsign; + MW_LOG_WARN( "[GSK-TAP-ACTIVATE] sending activate callsign=%s", pluginCallsign.c_str()); status = controllerObject->Invoke(THUNDER_RPC_TIMEOUT, _T("activate"), controlParam, result); if (Core::ERROR_NONE == status){ result.ToString(response); - MW_LOG_INFO( "[ThunderAccessPlayer] %s plugin Activated. Response : %s ", pluginCallsign.c_str(), response.c_str()); + MW_LOG_WARN( "[GSK-TAP-ACTIVATE] %s activated OK response=%s", pluginCallsign.c_str(), response.c_str()); } else { - MW_LOG_WARN( "[ThunderAccessPlayer] %s plugin Activation failed with error status : %u ", pluginCallsign.c_str(), status); + MW_LOG_WARN( "[GSK-TAP-ACTIVATE] %s activation FAILED errorStatus=%u", pluginCallsign.c_str(), status); ret = false; } } else { - MW_LOG_WARN( "[ThunderAccessPlayer] Controller Object NULL "); + MW_LOG_WARN( "[GSK-TAP-ACTIVATE] controller object is NULL cannot activate %s", pluginCallsign.c_str()); ret = false; } return ret; @@ -163,16 +167,17 @@ bool ThunderAccessPlayer::SubscribeEvent (string eventName, std::functionSubscribe(THUNDER_RPC_TIMEOUT, _T(eventName), functionHandler); if (Core::ERROR_NONE == status) { - MW_LOG_INFO( "[ThunderAccessPlayer] Subscribed to : %s", eventName.c_str()); + MW_LOG_WARN( "[GSK-TAP-SUBSCRIBE] %s::%s subscribed OK", pluginCallsign.c_str(), eventName.c_str()); } else { - MW_LOG_WARN( "[ThunderAccessPlayer] Subscription failed for : %s with error status %u", eventName.c_str(), status); + MW_LOG_WARN( "[GSK-TAP-SUBSCRIBE] %s::%s subscription FAILED errorStatus=%u", pluginCallsign.c_str(), eventName.c_str(), status); ret = false; } } else { - MW_LOG_WARN( "[ThunderAccessPlayer] remoteObject not created for the plugin!"); + MW_LOG_WARN( "[GSK-TAP-SUBSCRIBE] remoteObject is NULL for %s cannot subscribe to %s", pluginCallsign.c_str(), eventName.c_str()); ret = false; } return ret; @@ -186,11 +191,12 @@ bool ThunderAccessPlayer::SubscribeEvent (string eventName, std::functionUnsubscribe(THUNDER_RPC_TIMEOUT, _T(eventName)); - MW_LOG_INFO( "[ThunderAccessPlayer] UnSubscribed : %s event", eventName.c_str()); + MW_LOG_WARN( "[GSK-TAP-UNSUBSCRIBE] %s::%s unsubscribed OK", pluginCallsign.c_str(), eventName.c_str()); } else { - MW_LOG_WARN( "[ThunderAccessPlayer] remoteObject not created for the plugin!"); + MW_LOG_WARN( "[GSK-TAP-UNSUBSCRIBE] remoteObject is NULL for %s cannot unsubscribe %s", pluginCallsign.c_str(), eventName.c_str()); ret = false; } return ret; @@ -206,26 +212,26 @@ bool ThunderAccessPlayer::InvokeJSONRPC(std::string method, const JsonObject &pa std::string response; uint32_t status = Core::ERROR_NONE; + MW_LOG_WARN( "[GSK-TAP-INVOKE] callsign=%s method=%s", pluginCallsign.c_str(), method.c_str()); if(NULL == remoteObject) { - MW_LOG_WARN( "[ThunderAccessPlayer] client not initialized! "); + MW_LOG_WARN( "[GSK-TAP-INVOKE] remoteObject is NULL for %s cannot invoke %s", pluginCallsign.c_str(), method.c_str()); return false; } JsonObject result_internal; status = remoteObject->Invoke(waitTime, _T(method), param, result_internal); + result_internal.ToString(response); if (Core::ERROR_NONE == status) { if (result_internal["success"].Boolean()) { - result_internal.ToString(response); - MW_LOG_TRACE( "[ThunderAccessPlayer] %s success! Response : %s", method.c_str() , response.c_str()); + MW_LOG_WARN( "[GSK-TAP-INVOKE] %s::%s SUCCESS response=%s", pluginCallsign.c_str(), method.c_str(), response.c_str()); } else { - result_internal.ToString(response); - MW_LOG_WARN( "[ThunderAccessPlayer] %s call failed! Response : %s", method.c_str() , response.c_str()); + MW_LOG_WARN( "[GSK-TAP-INVOKE] %s::%s FAILED (no success field) response=%s", pluginCallsign.c_str(), method.c_str(), response.c_str()); ret = false; } } else { - MW_LOG_WARN( "[ThunderAccessPlayer] %s : invoke failed with error status %u", method.c_str(), status); + MW_LOG_WARN( "[GSK-TAP-INVOKE] %s::%s invoke FAILED errorStatus=%u response=%s", pluginCallsign.c_str(), method.c_str(), status, response.c_str()); ret = false; } diff --git a/externals/rdk/PlayerExternalsRdkInterface.cpp b/externals/rdk/PlayerExternalsRdkInterface.cpp index 33c41a18..22cb6338 100644 --- a/externals/rdk/PlayerExternalsRdkInterface.cpp +++ b/externals/rdk/PlayerExternalsRdkInterface.cpp @@ -129,11 +129,16 @@ void PlayerExternalsRdkInterface::Initialize() MW_PRE_LOGGER_LOG("Done getting interface \n"); - SetHDMIStatus(); #ifdef USE_DS_THUNDER_PLUGIN + /* Register event handlers first so Thunder objects exist before SetHDMIStatus() is called */ RegisterThunderEventHandlers(); -#elif defined(USE_DS_EVENT_SUPPORTED) + /* Post the initial HDMI status query through the worker thread */ + PostHDMIStatusUpdate(); +#else + SetHDMIStatus(); +# ifdef USE_DS_EVENT_SUPPORTED RegisterDsClientEventHandler(); +# endif #endif MW_PRE_LOGGER_LOG("Initializing completed \n"); @@ -244,7 +249,7 @@ void PlayerExternalsRdkInterface::SetHDMIStatus() * getHDCPReceiverProtocol -> HdcpProfile.1 getHDCPStatus -> receiverHDCPVersion * isContentProtected -> HdcpProfile.1 getHDCPStatus -> isHDCPEnabled * isDisplayConnected -> HdcpProfile.1 getHDCPStatus -> isConnected - * getPixelResolution -> DisplayInfo.1 displayinfo -> width / height + * getPixelResolution -> DisplaySettings.1 getCurrentResolution -> w / h */ bool isConnected = false; bool isHDCPEnabled = false; @@ -290,30 +295,33 @@ void PlayerExternalsRdkInterface::SetHDMIStatus() MW_LOG_WARN("[DS-Thunder] m_hdcpProfileThunder is NULL — was RegisterThunderEventHandlers() called?\n"); } - /* --- Query pixel resolution via DisplayInfo.1 --- */ - if (isConnected && m_displayInfoThunder) { + /* --- Query pixel resolution via DisplaySettings.1::getCurrentResolution --- */ + if (isConnected && m_dsThunder) { JsonObject param, result; std::string rawResponse; - MW_LOG_WARN("[DS-Thunder] Calling DisplayInfo.1::displayinfo (property)\n"); - /* Note: displayinfo is a WPEFramework *property* — it has no "success" field. - * InvokeJSONRPC may return false even on success; read result fields directly. */ - bool rpcRet = m_displayInfoThunder->InvokeJSONRPC("displayinfo", param, result); + MW_LOG_WARN("[DS-Thunder] Calling DisplaySettings.1::getCurrentResolution\n"); + bool rpcRet = m_dsThunder->InvokeJSONRPC("getCurrentResolution", param, result); result.ToString(rawResponse); - MW_LOG_WARN("[DS-Thunder] displayinfo rpcRet=%d rawResponse=%s\n", rpcRet, rawResponse.c_str()); - /* Read width/height regardless of rpcRet — property has no "success" key */ - int w = static_cast(result["width"].Number()); - int h = static_cast(result["height"].Number()); - MW_LOG_WARN("[DS-Thunder] displayinfo: width=%d height=%d\n", w, h); - if (w > 0 && h > 0) { - SetResolution(w, h); + MW_LOG_WARN("[DS-Thunder] getCurrentResolution rpcRet=%d rawResponse=%s\n", rpcRet, rawResponse.c_str()); + if (rpcRet && result["success"].Boolean()) { + int w = static_cast(result["w"].Number()); + int h = static_cast(result["h"].Number()); + MW_LOG_WARN("[DS-Thunder] getCurrentResolution: resolution=%s w=%d h=%d\n", + result["resolution"].String().c_str(), w, h); + if (w > 0 && h > 0) { + SetResolution(w, h); + } else { + MW_LOG_WARN("[DS-Thunder] getCurrentResolution: invalid resolution w=%d h=%d — keeping current\n", w, h); + } } else { - MW_LOG_WARN("[DS-Thunder] displayinfo: invalid resolution w=%d h=%d — keeping current\n", w, h); + MW_LOG_WARN("[DS-Thunder] getCurrentResolution failed rpcRet=%d success=%d\n", + rpcRet, result["success"].Boolean()); } } else if (!isConnected) { MW_LOG_WARN("[DS-Thunder] Display not connected — setting resolution to NA\n"); SetResolution(DISPLAY_RESOLUTION_NA, DISPLAY_RESOLUTION_NA); } else { - MW_LOG_WARN("[DS-Thunder] m_displayInfoThunder is NULL\n"); + MW_LOG_WARN("[DS-Thunder] m_dsThunder is NULL\n"); } m_isHDCPEnabled = isHDCPEnabled; @@ -431,6 +439,46 @@ void PlayerExternalsRdkInterface::SetHDMIStatus() } #ifdef USE_DS_THUNDER_PLUGIN +/** + * @brief Signal the worker thread that an HDMI status update is needed. + * Safe to call from Thunder event callbacks (returns immediately). + * Multiple concurrent calls are coalesced — the worker runs SetHDMIStatus() + * exactly once per burst of events. + */ +void PlayerExternalsRdkInterface::PostHDMIStatusUpdate() +{ + { + std::lock_guard lk(m_eventMutex); + m_eventPending = true; + } + m_eventCv.notify_one(); + MW_LOG_WARN("[DS-Thunder] PostHDMIStatusUpdate: event queued\n"); +} + +/** + * @brief Worker thread body. + * Waits for a pending update, then calls SetHDMIStatus() once. + * Coalesces rapid back-to-back events into a single call. + */ +void PlayerExternalsRdkInterface::EventWorkerLoop() +{ + MW_LOG_WARN("[DS-Thunder] EventWorkerLoop: thread started\n"); + while (true) { + std::unique_lock lk(m_eventMutex); + m_eventCv.wait(lk, [this] { + return m_eventPending.load() || m_eventWorkerStop.load(); + }); + if (m_eventWorkerStop.load()) { + MW_LOG_WARN("[DS-Thunder] EventWorkerLoop: stop requested — exiting\n"); + break; + } + m_eventPending = false; + lk.unlock(); /* unlock before JSONRPC calls */ + MW_LOG_WARN("[DS-Thunder] EventWorkerLoop: calling SetHDMIStatus()\n"); + SetHDMIStatus(); + } +} + /** * @brief Create Thunder plugin objects and subscribe to HDMI/HDCP/resolution events. * CSV mapping: @@ -443,6 +491,12 @@ void PlayerExternalsRdkInterface::RegisterThunderEventHandlers() { MW_LOG_WARN("[DS-Thunder] RegisterThunderEventHandlers() start\n"); + /* Start the worker thread that serialises SetHDMIStatus() calls */ + m_eventWorkerStop = false; + m_eventPending = false; + m_eventWorkerThread = std::thread(&PlayerExternalsRdkInterface::EventWorkerLoop, this); + MW_LOG_WARN("[DS-Thunder] EventWorkerLoop thread started\n"); + /* ---- HdcpProfile.1 ---- */ MW_LOG_WARN("[DS-Thunder] Creating PlayerThunderAccess for HDCPPROFILE (org.rdk.HdcpProfile.1)\n"); m_hdcpProfileThunder = std::make_unique(PlayerThunderAccessPlugin::HDCPPROFILE); @@ -450,16 +504,15 @@ void PlayerExternalsRdkInterface::RegisterThunderEventHandlers() MW_LOG_WARN("[DS-Thunder] HdcpProfile.1 ActivatePlugin() ret=%d\n", activateRet); /* onDisplayConnectionChanged: replaces IARM_BUS_DSMGR_EVENT_HDCP_STATUS */ + /* NOTE: Thunder does not allow InvokeJSONRPC from within a callback. + * Spawn a detached thread so the callback returns immediately. */ bool subRet = m_hdcpProfileThunder->SubscribeEvent( "onDisplayConnectionChanged", - [](const WPEFramework::Core::JSON::VariantContainer& params) { + [this](const WPEFramework::Core::JSON::VariantContainer& params) { std::string paramsStr; params.ToString(paramsStr); - MW_LOG_WARN("[DS-Thunder] onDisplayConnectionChanged event received params=%s\n", paramsStr.c_str()); - auto pInstance = PlayerExternalsRdkInterface::GetPlayerExternalsRdkInterfaceInstance(); - if (pInstance) { - pInstance->SetHDMIStatus(); - } + MW_LOG_WARN("[DS-Thunder] onDisplayConnectionChanged received params=%s\n", paramsStr.c_str()); + PostHDMIStatusUpdate(); }); MW_LOG_WARN("[DS-Thunder] HdcpProfile.1 SubscribeEvent(onDisplayConnectionChanged) ret=%d\n", subRet); @@ -472,28 +525,22 @@ void PlayerExternalsRdkInterface::RegisterThunderEventHandlers() /* connectedVideoDisplaysUpdated: replaces IARM_BUS_DSMGR_EVENT_HDMI_HOTPLUG */ subRet = m_dsThunder->SubscribeEvent( "connectedVideoDisplaysUpdated", - [](const WPEFramework::Core::JSON::VariantContainer& params) { + [this](const WPEFramework::Core::JSON::VariantContainer& params) { std::string paramsStr; params.ToString(paramsStr); - MW_LOG_WARN("[DS-Thunder] connectedVideoDisplaysUpdated event received params=%s\n", paramsStr.c_str()); - auto pInstance = PlayerExternalsRdkInterface::GetPlayerExternalsRdkInterfaceInstance(); - if (pInstance) { - pInstance->SetHDMIStatus(); - } + MW_LOG_WARN("[DS-Thunder] connectedVideoDisplaysUpdated received params=%s\n", paramsStr.c_str()); + PostHDMIStatusUpdate(); }); MW_LOG_WARN("[DS-Thunder] DisplaySettings.1 SubscribeEvent(connectedVideoDisplaysUpdated) ret=%d\n", subRet); /* resolutionChanged: replaces IARM_BUS_DSMGR_EVENT_RES_POSTCHANGE */ subRet = m_dsThunder->SubscribeEvent( "resolutionChanged", - [](const WPEFramework::Core::JSON::VariantContainer& params) { + [this](const WPEFramework::Core::JSON::VariantContainer& params) { std::string paramsStr; params.ToString(paramsStr); - MW_LOG_WARN("[DS-Thunder] resolutionChanged event received params=%s\n", paramsStr.c_str()); - auto pInstance = PlayerExternalsRdkInterface::GetPlayerExternalsRdkInterfaceInstance(); - if (pInstance) { - pInstance->SetHDMIStatus(); - } + MW_LOG_WARN("[DS-Thunder] resolutionChanged received params=%s\n", paramsStr.c_str()); + PostHDMIStatusUpdate(); }); MW_LOG_WARN("[DS-Thunder] DisplaySettings.1 SubscribeEvent(resolutionChanged) ret=%d\n", subRet); @@ -505,12 +552,6 @@ void PlayerExternalsRdkInterface::RegisterThunderEventHandlers() }); MW_LOG_WARN("[DS-Thunder] DisplaySettings.1 SubscribeEvent(resolutionPreChange) ret=%d\n", subRet); - /* ---- DisplayInfo.1 ---- */ - MW_LOG_WARN("[DS-Thunder] Creating PlayerThunderAccess for DISPLAYINFO (DisplayInfo.1)\n"); - m_displayInfoThunder = std::make_unique(PlayerThunderAccessPlugin::DISPLAYINFO); - activateRet = m_displayInfoThunder->ActivatePlugin(); - MW_LOG_WARN("[DS-Thunder] DisplayInfo.1 ActivatePlugin() ret=%d\n", activateRet); - MW_LOG_WARN("[DS-Thunder] RegisterThunderEventHandlers() done\n"); } @@ -519,6 +560,17 @@ void PlayerExternalsRdkInterface::RegisterThunderEventHandlers() */ void PlayerExternalsRdkInterface::RemoveThunderEventHandlers() { + /* Stop worker thread before unsubscribing */ + { + std::lock_guard lk(m_eventMutex); + m_eventWorkerStop = true; + } + m_eventCv.notify_one(); + if (m_eventWorkerThread.joinable()) { + m_eventWorkerThread.join(); + MW_LOG_WARN("[DS-Thunder] EventWorkerLoop thread joined\n"); + } + if (m_hdcpProfileThunder) { m_hdcpProfileThunder->UnSubscribeEvent("onDisplayConnectionChanged"); m_hdcpProfileThunder.reset(); @@ -529,9 +581,6 @@ void PlayerExternalsRdkInterface::RemoveThunderEventHandlers() m_dsThunder->UnSubscribeEvent("resolutionPreChange"); m_dsThunder.reset(); } - if (m_displayInfoThunder) { - m_displayInfoThunder.reset(); - } } #endif /* USE_DS_THUNDER_PLUGIN */ diff --git a/externals/rdk/PlayerExternalsRdkInterface.h b/externals/rdk/PlayerExternalsRdkInterface.h index 12527c77..27809851 100644 --- a/externals/rdk/PlayerExternalsRdkInterface.h +++ b/externals/rdk/PlayerExternalsRdkInterface.h @@ -38,6 +38,10 @@ #else #include "PlayerThunderAccess.h" #include +#include +#include +#include +#include // Compatibility aliases: libds types not available when using Thunder typedef int dsHdcpProtocolVersion_t; #define dsHDCP_VERSION_1X 14 @@ -101,9 +105,16 @@ class PlayerExternalsRdkInterface : public PlayerExternalsInterfaceBase #ifdef USE_DS_THUNDER_PLUGIN std::unique_ptr m_hdcpProfileThunder; std::unique_ptr m_dsThunder; - std::unique_ptr m_displayInfoThunder; void RegisterThunderEventHandlers(); void RemoveThunderEventHandlers(); + /* Worker thread: serialises and coalesces HDMI-status update requests */ + void PostHDMIStatusUpdate(); + void EventWorkerLoop(); + std::thread m_eventWorkerThread; + std::mutex m_eventMutex; + std::condition_variable m_eventCv; + std::atomic m_eventPending{false}; + std::atomic m_eventWorkerStop{false}; #endif PlayerExternalsRdkInterface(); diff --git a/externals/rdk/PlayerThunderAccess.cpp b/externals/rdk/PlayerThunderAccess.cpp index fc7c78bc..c14e63b8 100644 --- a/externals/rdk/PlayerThunderAccess.cpp +++ b/externals/rdk/PlayerThunderAccess.cpp @@ -53,7 +53,6 @@ using namespace WPEFramework; #define HDMIINPUT_CALLSIGN "org.rdk.HdmiInput.1" #define COMPOSITEINPUT_CALLSIGN "org.rdk.CompositeInput.1" #define HDCPPROFILE_CALLSIGN "org.rdk.HdcpProfile.1" -#define DISPLAYINFO_CALLSIGN "DisplayInfo.1" /** * @brief Structure to save the Thunder security token details @@ -115,9 +114,6 @@ PlayerThunderAccess::PlayerThunderAccess(PlayerThunderAccessPlugin callsign) case PlayerThunderAccessPlugin::HDCPPROFILE : pluginCallsign = HDCPPROFILE_CALLSIGN; break; - case PlayerThunderAccessPlugin::DISPLAYINFO : - pluginCallsign = DISPLAYINFO_CALLSIGN; - break; default: MW_LOG_ERR("Undefined plugin tried to initialize: %d", (int)callsign); pluginCallsign = ""; diff --git a/externals/rdk/PlayerThunderAccess.h b/externals/rdk/PlayerThunderAccess.h index 6d6e75e5..cba5c4c5 100644 --- a/externals/rdk/PlayerThunderAccess.h +++ b/externals/rdk/PlayerThunderAccess.h @@ -28,7 +28,6 @@ #include "Module.h" #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wmacro-redefined" #include #include #pragma GCC diagnostic pop From 819802890ccec0004447167c04515694ba9f09d5 Mon Sep 17 00:00:00 2001 From: grandhi_santoshkumar Date: Fri, 10 Jul 2026 08:04:20 +0000 Subject: [PATCH 8/8] - Firebolt mode: Firebolt events -> worker thread -> Thunder JSONRPC SetHDMIStatus() - IARM mode: Thunder events -> worker thread -> Thunder JSONRPC SetHDMIStatus() - No libds/IARM API calls in either path --- .../rdk/IFirebolt/DeviceFireboltInterface.cpp | 21 ++- externals/rdk/PlayerExternalsRdkInterface.cpp | 145 +++++++++++------- externals/rdk/PlayerExternalsRdkInterface.h | 7 +- 3 files changed, 115 insertions(+), 58 deletions(-) diff --git a/externals/rdk/IFirebolt/DeviceFireboltInterface.cpp b/externals/rdk/IFirebolt/DeviceFireboltInterface.cpp index 2f08631b..c3ee01bd 100644 --- a/externals/rdk/IFirebolt/DeviceFireboltInterface.cpp +++ b/externals/rdk/IFirebolt/DeviceFireboltInterface.cpp @@ -229,6 +229,14 @@ static void HDCPEventHandlerFirebolt(const Firebolt::Device::HDCPVersionMap& t_H { std::shared_ptr pInstance = PlayerExternalsRdkInterface::GetPlayerExternalsRdkInterfaceInstance(); +#ifdef USE_DS_THUNDER_PLUGIN + /* When the Thunder plugin path is active, HDCP version and connection state + * are read authoritatively from HdcpProfile.1::getHDCPStatus inside + * SetHDMIStatus(). Route through the coalescing worker thread so that + * concurrent Firebolt callbacks don't race on the Thunder RPC object. */ + MW_LOG_WARN("[DS-Thunder] HDCPEventHandlerFirebolt: routing to PostHDMIStatusUpdate\n"); + pInstance->PostHDMIStatusUpdate(); +#else if(t_HDCPVersionMap.hdcp2_2) { pInstance->setHdcpProtocol(dsHDCP_VERSION_2X); @@ -245,7 +253,7 @@ static void HDCPEventHandlerFirebolt(const Firebolt::Device::HDCPVersionMap& t_H } pInstance->SetHDMIStatus(); - +#endif } /** @@ -253,6 +261,15 @@ static void HDCPEventHandlerFirebolt(const Firebolt::Device::HDCPVersionMap& t_H */ static void ResolutionHandlerFirebolt(const std::string& t_res) { +#ifdef USE_DS_THUNDER_PLUGIN + /* When the Thunder plugin path is active, resolution is fetched from + * DisplaySettings.1::getCurrentResolution inside SetHDMIStatus(). Route + * through the coalescing worker thread so this event is handled in order + * with HDCP events. */ + MW_LOG_WARN("[DS-Thunder] ResolutionHandlerFirebolt: routing to PostHDMIStatusUpdate\n"); + std::shared_ptr pInstance = PlayerExternalsRdkInterface::GetPlayerExternalsRdkInterfaceInstance(); + pInstance->PostHDMIStatusUpdate(); +#else int width = 1280; int height = 720; @@ -272,5 +289,5 @@ static void ResolutionHandlerFirebolt(const std::string& t_res) { MW_LOG_ERR("Failed to get current resolution"); } - +#endif } diff --git a/externals/rdk/PlayerExternalsRdkInterface.cpp b/externals/rdk/PlayerExternalsRdkInterface.cpp index 22cb6338..3172bddb 100644 --- a/externals/rdk/PlayerExternalsRdkInterface.cpp +++ b/externals/rdk/PlayerExternalsRdkInterface.cpp @@ -480,18 +480,34 @@ void PlayerExternalsRdkInterface::EventWorkerLoop() } /** - * @brief Create Thunder plugin objects and subscribe to HDMI/HDCP/resolution events. - * CSV mapping: - * IARM_BUS_DSMGR_EVENT_HDCP_STATUS -> HdcpProfile.1 onDisplayConnectionChanged - * IARM_BUS_DSMGR_EVENT_HDMI_HOTPLUG -> DisplaySettings.1 connectedVideoDisplaysUpdated - * IARM_BUS_DSMGR_EVENT_RES_POSTCHANGE -> DisplaySettings.1 resolutionChanged - * IARM_BUS_DSMGR_EVENT_RES_PRECHANGE -> DisplaySettings.1 resolutionPreChange + * @brief Create Thunder plugin objects and, in IARM mode, subscribe to Thunder + * HDMI/HDCP/resolution events. + * + * Event-source split: + * IARM mode : Thunder events are the source. + * Callbacks route through PostHDMIStatusUpdate() so that + * InvokeJSONRPC is never called from inside a Thunder callback. + * CSV mapping: + * IARM_BUS_DSMGR_EVENT_HDCP_STATUS -> HdcpProfile.1 onDisplayConnectionChanged + * IARM_BUS_DSMGR_EVENT_HDMI_HOTPLUG -> DisplaySettings.1 connectedVideoDisplaysUpdated + * IARM_BUS_DSMGR_EVENT_RES_POSTCHANGE -> DisplaySettings.1 resolutionChanged + * IARM_BUS_DSMGR_EVENT_RES_PRECHANGE -> DisplaySettings.1 resolutionPreChange + * Firebolt mode: Firebolt SDK delivers events via subscribeOnHdcpChanged / + * subscribeOnVideoResolutionChanged in DeviceFireboltInterface. + * Those handlers call PostHDMIStatusUpdate() directly. + * No Thunder subscriptions needed here. + * + * The Thunder plugin objects (m_hdcpProfileThunder, m_dsThunder) are created in + * both modes and used solely for the data queries inside SetHDMIStatus() + * (getHDCPStatus and getCurrentResolution). */ void PlayerExternalsRdkInterface::RegisterThunderEventHandlers() { MW_LOG_WARN("[DS-Thunder] RegisterThunderEventHandlers() start\n"); - /* Start the worker thread that serialises SetHDMIStatus() calls */ + /* Start the worker thread that serialises SetHDMIStatus() calls. + * Needed in both modes: Thunder callbacks must not call InvokeJSONRPC + * directly, and Firebolt callbacks may arrive concurrently. */ m_eventWorkerStop = false; m_eventPending = false; m_eventWorkerThread = std::thread(&PlayerExternalsRdkInterface::EventWorkerLoop, this); @@ -503,64 +519,74 @@ void PlayerExternalsRdkInterface::RegisterThunderEventHandlers() bool activateRet = m_hdcpProfileThunder->ActivatePlugin(); MW_LOG_WARN("[DS-Thunder] HdcpProfile.1 ActivatePlugin() ret=%d\n", activateRet); - /* onDisplayConnectionChanged: replaces IARM_BUS_DSMGR_EVENT_HDCP_STATUS */ - /* NOTE: Thunder does not allow InvokeJSONRPC from within a callback. - * Spawn a detached thread so the callback returns immediately. */ - bool subRet = m_hdcpProfileThunder->SubscribeEvent( - "onDisplayConnectionChanged", - [this](const WPEFramework::Core::JSON::VariantContainer& params) { - std::string paramsStr; - params.ToString(paramsStr); - MW_LOG_WARN("[DS-Thunder] onDisplayConnectionChanged received params=%s\n", paramsStr.c_str()); - PostHDMIStatusUpdate(); - }); - MW_LOG_WARN("[DS-Thunder] HdcpProfile.1 SubscribeEvent(onDisplayConnectionChanged) ret=%d\n", subRet); - /* ---- DisplaySettings.1 ---- */ MW_LOG_WARN("[DS-Thunder] Creating PlayerThunderAccess for DS (org.rdk.DisplaySettings.1)\n"); m_dsThunder = std::make_unique(PlayerThunderAccessPlugin::DS); activateRet = m_dsThunder->ActivatePlugin(); MW_LOG_WARN("[DS-Thunder] DisplaySettings.1 ActivatePlugin() ret=%d\n", activateRet); - /* connectedVideoDisplaysUpdated: replaces IARM_BUS_DSMGR_EVENT_HDMI_HOTPLUG */ - subRet = m_dsThunder->SubscribeEvent( - "connectedVideoDisplaysUpdated", - [this](const WPEFramework::Core::JSON::VariantContainer& params) { - std::string paramsStr; - params.ToString(paramsStr); - MW_LOG_WARN("[DS-Thunder] connectedVideoDisplaysUpdated received params=%s\n", paramsStr.c_str()); - PostHDMIStatusUpdate(); - }); - MW_LOG_WARN("[DS-Thunder] DisplaySettings.1 SubscribeEvent(connectedVideoDisplaysUpdated) ret=%d\n", subRet); - - /* resolutionChanged: replaces IARM_BUS_DSMGR_EVENT_RES_POSTCHANGE */ - subRet = m_dsThunder->SubscribeEvent( - "resolutionChanged", - [this](const WPEFramework::Core::JSON::VariantContainer& params) { - std::string paramsStr; - params.ToString(paramsStr); - MW_LOG_WARN("[DS-Thunder] resolutionChanged received params=%s\n", paramsStr.c_str()); - PostHDMIStatusUpdate(); - }); - MW_LOG_WARN("[DS-Thunder] DisplaySettings.1 SubscribeEvent(resolutionChanged) ret=%d\n", subRet); - - /* resolutionPreChange: replaces IARM_BUS_DSMGR_EVENT_RES_PRECHANGE */ - subRet = m_dsThunder->SubscribeEvent( - "resolutionPreChange", - [](const WPEFramework::Core::JSON::VariantContainer& params) { - MW_LOG_WARN("[DS-Thunder] resolutionPreChange event received\n"); - }); - MW_LOG_WARN("[DS-Thunder] DisplaySettings.1 SubscribeEvent(resolutionPreChange) ret=%d\n", subRet); + /* ---- Thunder event subscriptions (IARM mode only) ---- */ + if (m_initialized == InitState::IARM) + { + MW_LOG_WARN("[DS-Thunder] IARM mode: subscribing to Thunder events\n"); + + /* onDisplayConnectionChanged: replaces IARM_BUS_DSMGR_EVENT_HDCP_STATUS */ + bool subRet = m_hdcpProfileThunder->SubscribeEvent( + "onDisplayConnectionChanged", + [this](const WPEFramework::Core::JSON::VariantContainer& params) { + std::string paramsStr; + params.ToString(paramsStr); + MW_LOG_WARN("[DS-Thunder] onDisplayConnectionChanged received params=%s\n", paramsStr.c_str()); + PostHDMIStatusUpdate(); + }); + MW_LOG_WARN("[DS-Thunder] HdcpProfile.1 SubscribeEvent(onDisplayConnectionChanged) ret=%d\n", subRet); + + /* connectedVideoDisplaysUpdated: replaces IARM_BUS_DSMGR_EVENT_HDMI_HOTPLUG */ + subRet = m_dsThunder->SubscribeEvent( + "connectedVideoDisplaysUpdated", + [this](const WPEFramework::Core::JSON::VariantContainer& params) { + std::string paramsStr; + params.ToString(paramsStr); + MW_LOG_WARN("[DS-Thunder] connectedVideoDisplaysUpdated received params=%s\n", paramsStr.c_str()); + PostHDMIStatusUpdate(); + }); + MW_LOG_WARN("[DS-Thunder] DisplaySettings.1 SubscribeEvent(connectedVideoDisplaysUpdated) ret=%d\n", subRet); + + /* resolutionChanged: replaces IARM_BUS_DSMGR_EVENT_RES_POSTCHANGE */ + subRet = m_dsThunder->SubscribeEvent( + "resolutionChanged", + [this](const WPEFramework::Core::JSON::VariantContainer& params) { + std::string paramsStr; + params.ToString(paramsStr); + MW_LOG_WARN("[DS-Thunder] resolutionChanged received params=%s\n", paramsStr.c_str()); + PostHDMIStatusUpdate(); + }); + MW_LOG_WARN("[DS-Thunder] DisplaySettings.1 SubscribeEvent(resolutionChanged) ret=%d\n", subRet); + + /* resolutionPreChange: replaces IARM_BUS_DSMGR_EVENT_RES_PRECHANGE (log only) */ + subRet = m_dsThunder->SubscribeEvent( + "resolutionPreChange", + [](const WPEFramework::Core::JSON::VariantContainer& params) { + MW_LOG_WARN("[DS-Thunder] resolutionPreChange event received\n"); + }); + MW_LOG_WARN("[DS-Thunder] DisplaySettings.1 SubscribeEvent(resolutionPreChange) ret=%d\n", subRet); + } + else + { + MW_LOG_WARN("[DS-Thunder] Firebolt mode: Thunder event subscriptions skipped " + "(events delivered by Firebolt SDK -> PostHDMIStatusUpdate)\n"); + } MW_LOG_WARN("[DS-Thunder] RegisterThunderEventHandlers() done\n"); } /** - * @brief Unsubscribe Thunder events and release plugin objects. + * @brief Stop the worker thread, unsubscribe Thunder events (IARM mode only), + * and release plugin objects. */ void PlayerExternalsRdkInterface::RemoveThunderEventHandlers() { - /* Stop worker thread before unsubscribing */ + /* Stop worker thread first so no further SetHDMIStatus() calls are made */ { std::lock_guard lk(m_eventMutex); m_eventWorkerStop = true; @@ -571,14 +597,23 @@ void PlayerExternalsRdkInterface::RemoveThunderEventHandlers() MW_LOG_WARN("[DS-Thunder] EventWorkerLoop thread joined\n"); } + /* Unsubscribe Thunder events — only if they were registered (IARM mode) */ + if (m_initialized == InitState::IARM) + { + if (m_hdcpProfileThunder) { + m_hdcpProfileThunder->UnSubscribeEvent("onDisplayConnectionChanged"); + } + if (m_dsThunder) { + m_dsThunder->UnSubscribeEvent("connectedVideoDisplaysUpdated"); + m_dsThunder->UnSubscribeEvent("resolutionChanged"); + m_dsThunder->UnSubscribeEvent("resolutionPreChange"); + } + } + if (m_hdcpProfileThunder) { - m_hdcpProfileThunder->UnSubscribeEvent("onDisplayConnectionChanged"); m_hdcpProfileThunder.reset(); } if (m_dsThunder) { - m_dsThunder->UnSubscribeEvent("connectedVideoDisplaysUpdated"); - m_dsThunder->UnSubscribeEvent("resolutionChanged"); - m_dsThunder->UnSubscribeEvent("resolutionPreChange"); m_dsThunder.reset(); } } diff --git a/externals/rdk/PlayerExternalsRdkInterface.h b/externals/rdk/PlayerExternalsRdkInterface.h index 27809851..7b99e33e 100644 --- a/externals/rdk/PlayerExternalsRdkInterface.h +++ b/externals/rdk/PlayerExternalsRdkInterface.h @@ -108,7 +108,6 @@ class PlayerExternalsRdkInterface : public PlayerExternalsInterfaceBase void RegisterThunderEventHandlers(); void RemoveThunderEventHandlers(); /* Worker thread: serialises and coalesces HDMI-status update requests */ - void PostHDMIStatusUpdate(); void EventWorkerLoop(); std::thread m_eventWorkerThread; std::mutex m_eventMutex; @@ -152,6 +151,12 @@ class PlayerExternalsRdkInterface : public PlayerExternalsInterfaceBase */ void SetResolution(int width, int height); +#ifdef USE_DS_THUNDER_PLUGIN + /* Post a pending HDMI-status update to the coalescing worker thread. + * Safe to call from any Firebolt event callback thread. */ + void PostHDMIStatusUpdate(); +#endif + // Singleton for object creation /**