diff --git a/.github/workflows/L1-tests.yml b/.github/workflows/L1-tests.yml index cc031231..97b85eb7 100755 --- a/.github/workflows/L1-tests.yml +++ b/.github/workflows/L1-tests.yml @@ -14,7 +14,7 @@ on: env: BUILD_TYPE: Debug THUNDER_REF: "R4.4.1" - INTERFACES_REF: "develop" + INTERFACES_REF: "feature/RDKEMW-1008-COM-RPC_support" AUTOMATICS_UNAME: ${{ secrets.AUTOMATICS_UNAME}} AUTOMATICS_PASSCODE: ${{ secrets. AUTOMATICS_PASSCODE}} @@ -123,7 +123,7 @@ jobs: with: repository: rdkcentral/entservices-testframework path: entservices-testframework - ref: develop + ref: feature/RDKEMW-1008-COM-RPC_support token: ${{ secrets.RDKCM_RDKE }} - name: Checkout entservices-inputoutput @@ -138,7 +138,7 @@ jobs: with: repository: rdkcentral/entservices-inputoutput path: entservices-inputoutput - ref: develop + ref: feature/RDKEMW-1008-COM-RPC_support - name: Checkout googletest if: steps.cache.outputs.cache-hit != 'true' diff --git a/.github/workflows/L2-tests.yml b/.github/workflows/L2-tests.yml index 34cdc6d6..c3e8d15a 100755 --- a/.github/workflows/L2-tests.yml +++ b/.github/workflows/L2-tests.yml @@ -14,7 +14,7 @@ on: env: BUILD_TYPE: Debug THUNDER_REF: "R4.4.1" - INTERFACES_REF: "develop" + INTERFACES_REF: "feature/RDKEMW-1008-COM-RPC_support" AUTOMATICS_UNAME: ${{ secrets.AUTOMATICS_UNAME}} AUTOMATICS_PASSCODE: ${{ secrets. AUTOMATICS_PASSCODE}} diff --git a/AVInput/AVInput.conf.in b/AVInput/AVInput.conf.in index 556edab0..b9c5b95c 100644 --- a/AVInput/AVInput.conf.in +++ b/AVInput/AVInput.conf.in @@ -2,3 +2,11 @@ precondition = ["Platform"] callsign = "org.rdk.AVInput" autostart = "false" startuporder = "@PLUGIN_AVINPUT_STARTUPORDER@" + +configuration = JSON() +rootobject = JSON() + +rootobject.add("mode", "@PLUGIN_AVINPUT_MODE@") +rootobject.add("locator", "lib@PLUGIN_IMPLEMENTATION@.so") + +configuration.add("root", rootobject) diff --git a/AVInput/AVInput.config b/AVInput/AVInput.config index e7226db5..c2b8cafd 100644 --- a/AVInput/AVInput.config +++ b/AVInput/AVInput.config @@ -1,7 +1,16 @@ set (autostart false) set (preconditions Platform) -set (callsign org.rdk.AVInput) +set (callsign "org.rdk.AVInput") if(PLUGIN_AVINPUT_STARTUPORDER) set (startuporder ${PLUGIN_AVINPUT_STARTUPORDER}) endif() + +map() + key(root) + map() + kv(mode ${PLUGIN_AVINPUT_MODE}) + kv(locator lib${PLUGIN_IMPLEMENTATION}.so) + end() +end() +ans(configuration) diff --git a/AVInput/AVInput.cpp b/AVInput/AVInput.cpp index c7586702..e00cf4aa 100644 --- a/AVInput/AVInput.cpp +++ b/AVInput/AVInput.cpp @@ -1,21 +1,21 @@ /** -* If not stated otherwise in this file or this component's LICENSE -* file the following copyright and licenses apply: -* -* Copyright 2020 RDK Management -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -**/ + * If not stated otherwise in this file or this component's LICENSE + * file the following copyright and licenses apply: + * + * Copyright 2025 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ #include "AVInput.h" #include "dsMgr.h" @@ -23,72 +23,15 @@ #include "compositeIn.hpp" #include "UtilsJsonRpc.h" -#include "UtilsIarm.h" -#include "host.hpp" - -#include "exception.hpp" -#include -#include #define API_VERSION_NUMBER_MAJOR 1 #define API_VERSION_NUMBER_MINOR 7 #define API_VERSION_NUMBER_PATCH 1 -#define HDMI 0 -#define COMPOSITE 1 -#define AV_HOT_PLUG_EVENT_CONNECTED 0 -#define AV_HOT_PLUG_EVENT_DISCONNECTED 1 -#define AVINPUT_METHOD_NUMBER_OF_INPUTS "numberOfInputs" +// Explicitly implementing getInputDevices method instead of autogenerating via IAVInput.h +// because it requires optional parameters which are not supported in Thunder 4.x. This can +// be refactored after migrating to 5.x. #define AVINPUT_METHOD_GET_INPUT_DEVICES "getInputDevices" -#define AVINPUT_METHOD_WRITE_EDID "writeEDID" -#define AVINPUT_METHOD_READ_EDID "readEDID" -#define AVINPUT_METHOD_READ_RAWSPD "getRawSPD" -#define AVINPUT_METHOD_READ_SPD "getSPD" -#define AVINPUT_METHOD_SET_EDID_VERSION "setEdidVersion" -#define AVINPUT_METHOD_GET_EDID_VERSION "getEdidVersion" -#define AVINPUT_METHOD_SET_EDID_ALLM_SUPPORT "setEdid2AllmSupport" -#define AVINPUT_METHOD_GET_EDID_ALLM_SUPPORT "getEdid2AllmSupport" -#define AVINPUT_METHOD_SET_VRR_SUPPORT "setVRRSupport" -#define AVINPUT_METHOD_GET_VRR_SUPPORT "getVRRSupport" -#define AVINPUT_METHOD_GET_VRR_FRAME_RATE "getVRRFrameRate" -#define AVINPUT_METHOD_GET_HDMI_COMPATIBILITY_VERSION "getHdmiVersion" -#define AVINPUT_METHOD_SET_MIXER_LEVELS "setMixerLevels" -#define AVINPUT_METHOD_START_INPUT "startInput" -#define AVINPUT_METHOD_STOP_INPUT "stopInput" -#define AVINPUT_METHOD_SCALE_INPUT "setVideoRectangle" -#define AVINPUT_METHOD_CURRENT_VIDEO_MODE "currentVideoMode" -#define AVINPUT_METHOD_CONTENT_PROTECTED "contentProtected" -#define AVINPUT_METHOD_SUPPORTED_GAME_FEATURES "getSupportedGameFeatures" -#define AVINPUT_METHOD_GAME_FEATURE_STATUS "getGameFeatureStatus" - -#define AVINPUT_EVENT_ON_DEVICES_CHANGED "onDevicesChanged" -#define AVINPUT_EVENT_ON_SIGNAL_CHANGED "onSignalChanged" -#define AVINPUT_EVENT_ON_STATUS_CHANGED "onInputStatusChanged" -#define AVINPUT_EVENT_ON_VIDEO_MODE_UPDATED "videoStreamInfoUpdate" -#define AVINPUT_EVENT_ON_GAME_FEATURE_STATUS_CHANGED "gameFeatureStatusUpdate" -#define AVINPUT_EVENT_ON_AVI_CONTENT_TYPE_CHANGED "aviContentTypeUpdate" - -#define STR_ALLM "ALLM" -#define VRR_TYPE_HDMI "VRR-HDMI" -#define VRR_TYPE_FREESYNC "VRR-FREESYNC" -#define VRR_TYPE_FREESYNC_PREMIUM "VRR-FREESYNC-PREMIUM" -#define VRR_TYPE_FREESYNC_PREMIUM_PRO "VRR-FREESYNC-PREMIUM-PRO" - -static bool isAudioBalanceSet = false; -static int planeType = 0; - -using namespace std; -int getTypeOfInput(string sType) -{ - int iType = -1; - if (strcmp (sType.c_str(), "HDMI") == 0) - iType = HDMI; - else if (strcmp (sType.c_str(), "COMPOSITE") ==0) - iType = COMPOSITE; - else - throw "Invalide type of INPUT, please specify HDMI/COMPOSITE"; - return iType; -} namespace WPEFramework { namespace { @@ -101,1696 +44,215 @@ namespace { // Terminations {}, // Controls - {} - ); + {}); } namespace Plugin { -SERVICE_REGISTRATION(AVInput, API_VERSION_NUMBER_MAJOR, API_VERSION_NUMBER_MINOR, API_VERSION_NUMBER_PATCH); - -AVInput* AVInput::_instance = nullptr; - -AVInput::AVInput() - : PluginHost::JSONRPC() -{ - RegisterAll(); -} - -AVInput::~AVInput() -{ - UnregisterAll(); -} - -const string AVInput::Initialize(PluginHost::IShell * /* service */) -{ - AVInput::_instance = this; - InitializeIARM(); - - return (string()); -} - -void AVInput::Deinitialize(PluginHost::IShell * /* service */) -{ - DeinitializeIARM(); - AVInput::_instance = nullptr; -} - -string AVInput::Information() const -{ - return (string()); -} - -void AVInput::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, - dsAVEventHandler)); - IARM_CHECK(IARM_Bus_RegisterEventHandler( - IARM_BUS_DSMGR_NAME, - IARM_BUS_DSMGR_EVENT_HDMI_IN_SIGNAL_STATUS, - dsAVSignalStatusEventHandler)); - IARM_CHECK(IARM_Bus_RegisterEventHandler( - IARM_BUS_DSMGR_NAME, - IARM_BUS_DSMGR_EVENT_HDMI_IN_STATUS, - dsAVStatusEventHandler)); - IARM_CHECK(IARM_Bus_RegisterEventHandler( - IARM_BUS_DSMGR_NAME, - IARM_BUS_DSMGR_EVENT_HDMI_IN_VIDEO_MODE_UPDATE, - dsAVVideoModeEventHandler)); - IARM_CHECK(IARM_Bus_RegisterEventHandler( - IARM_BUS_DSMGR_NAME, - IARM_BUS_DSMGR_EVENT_HDMI_IN_ALLM_STATUS, - dsAVGameFeatureStatusEventHandler)); - IARM_CHECK(IARM_Bus_RegisterEventHandler( - IARM_BUS_DSMGR_NAME, - IARM_BUS_DSMGR_EVENT_HDMI_IN_VRR_STATUS, - dsAVGameFeatureStatusEventHandler)); - IARM_CHECK(IARM_Bus_RegisterEventHandler( - IARM_BUS_DSMGR_NAME, - IARM_BUS_DSMGR_EVENT_COMPOSITE_IN_HOTPLUG, - dsAVEventHandler)); - IARM_CHECK(IARM_Bus_RegisterEventHandler( - IARM_BUS_DSMGR_NAME, - IARM_BUS_DSMGR_EVENT_COMPOSITE_IN_SIGNAL_STATUS, - dsAVSignalStatusEventHandler)); - IARM_CHECK(IARM_Bus_RegisterEventHandler( - IARM_BUS_DSMGR_NAME, - IARM_BUS_DSMGR_EVENT_COMPOSITE_IN_STATUS, - dsAVStatusEventHandler)); - IARM_CHECK(IARM_Bus_RegisterEventHandler( - IARM_BUS_DSMGR_NAME, - IARM_BUS_DSMGR_EVENT_COMPOSITE_IN_VIDEO_MODE_UPDATE, - dsAVVideoModeEventHandler)); - IARM_CHECK(IARM_Bus_RegisterEventHandler( - IARM_BUS_DSMGR_NAME, - IARM_BUS_DSMGR_EVENT_HDMI_IN_AVI_CONTENT_TYPE, - dsAviContentTypeEventHandler)); - } -} - -void AVInput::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, dsAVEventHandler)); - IARM_CHECK(IARM_Bus_RemoveEventHandler( - IARM_BUS_DSMGR_NAME, - IARM_BUS_DSMGR_EVENT_HDMI_IN_SIGNAL_STATUS, dsAVSignalStatusEventHandler)); - IARM_CHECK(IARM_Bus_RemoveEventHandler( - IARM_BUS_DSMGR_NAME, - IARM_BUS_DSMGR_EVENT_HDMI_IN_STATUS, dsAVStatusEventHandler)); - IARM_CHECK(IARM_Bus_RemoveEventHandler( - IARM_BUS_DSMGR_NAME, - IARM_BUS_DSMGR_EVENT_HDMI_IN_VIDEO_MODE_UPDATE, dsAVVideoModeEventHandler)); - IARM_CHECK(IARM_Bus_RemoveEventHandler( - IARM_BUS_DSMGR_NAME, - IARM_BUS_DSMGR_EVENT_HDMI_IN_ALLM_STATUS, dsAVGameFeatureStatusEventHandler)); - IARM_CHECK(IARM_Bus_RemoveEventHandler( - IARM_BUS_DSMGR_NAME, - IARM_BUS_DSMGR_EVENT_HDMI_IN_VRR_STATUS, dsAVGameFeatureStatusEventHandler)); - IARM_CHECK(IARM_Bus_RemoveEventHandler( - IARM_BUS_DSMGR_NAME, - IARM_BUS_DSMGR_EVENT_COMPOSITE_IN_HOTPLUG, dsAVEventHandler)); - IARM_CHECK(IARM_Bus_RemoveEventHandler( - IARM_BUS_DSMGR_NAME, - IARM_BUS_DSMGR_EVENT_COMPOSITE_IN_SIGNAL_STATUS, dsAVSignalStatusEventHandler)); - IARM_CHECK(IARM_Bus_RemoveEventHandler( - IARM_BUS_DSMGR_NAME, - IARM_BUS_DSMGR_EVENT_COMPOSITE_IN_STATUS, dsAVStatusEventHandler)); - IARM_CHECK(IARM_Bus_RemoveEventHandler( - IARM_BUS_DSMGR_NAME, - IARM_BUS_DSMGR_EVENT_COMPOSITE_IN_VIDEO_MODE_UPDATE, dsAVVideoModeEventHandler)); - IARM_CHECK(IARM_Bus_RemoveEventHandler( - IARM_BUS_DSMGR_NAME, - IARM_BUS_DSMGR_EVENT_HDMI_IN_AVI_CONTENT_TYPE, dsAviContentTypeEventHandler)); - } -} - -void AVInput::RegisterAll() -{ - Register(_T(AVINPUT_METHOD_NUMBER_OF_INPUTS), &AVInput::endpoint_numberOfInputs, this); - Register(_T(AVINPUT_METHOD_CURRENT_VIDEO_MODE), &AVInput::endpoint_currentVideoMode, this); - Register(_T(AVINPUT_METHOD_CONTENT_PROTECTED), &AVInput::endpoint_contentProtected, this); - Register(_T(AVINPUT_METHOD_GET_INPUT_DEVICES), &AVInput::getInputDevicesWrapper, this); - Register(_T(AVINPUT_METHOD_WRITE_EDID), &AVInput::writeEDIDWrapper, this); - Register(_T(AVINPUT_METHOD_READ_EDID), &AVInput::readEDIDWrapper, this); - Register(_T(AVINPUT_METHOD_READ_RAWSPD), &AVInput::getRawSPDWrapper, this); - Register(_T(AVINPUT_METHOD_READ_SPD), &AVInput::getSPDWrapper, this); - Register(_T(AVINPUT_METHOD_SET_EDID_VERSION), &AVInput::setEdidVersionWrapper, this); - Register(_T(AVINPUT_METHOD_GET_EDID_VERSION), &AVInput::getEdidVersionWrapper, this); - Register(_T(AVINPUT_METHOD_SET_MIXER_LEVELS), &AVInput::setMixerLevels, this); - Register(_T(AVINPUT_METHOD_SET_EDID_ALLM_SUPPORT), &AVInput::setEdid2AllmSupportWrapper, this); - Register(_T(AVINPUT_METHOD_GET_EDID_ALLM_SUPPORT), &AVInput::getEdid2AllmSupportWrapper, this); - Register(_T(AVINPUT_METHOD_SET_VRR_SUPPORT), &AVInput::setVRRSupportWrapper, this); - Register(_T(AVINPUT_METHOD_GET_VRR_SUPPORT), &AVInput::getVRRSupportWrapper, this); - Register(_T(AVINPUT_METHOD_GET_VRR_FRAME_RATE), &AVInput::getVRRFrameRateWrapper, this); - Register(_T(AVINPUT_METHOD_GET_HDMI_COMPATIBILITY_VERSION), &AVInput::getHdmiVersionWrapper, this); - Register(_T(AVINPUT_METHOD_START_INPUT), &AVInput::startInput, this); - Register(_T(AVINPUT_METHOD_STOP_INPUT), &AVInput::stopInput, this); - Register(_T(AVINPUT_METHOD_SCALE_INPUT), &AVInput::setVideoRectangleWrapper, this); - Register(_T(AVINPUT_METHOD_SUPPORTED_GAME_FEATURES), &AVInput::getSupportedGameFeatures, this); - Register(_T(AVINPUT_METHOD_GAME_FEATURE_STATUS), &AVInput::getGameFeatureStatusWrapper, this); - m_primVolume = DEFAULT_PRIM_VOL_LEVEL; - m_inputVolume = DEFAULT_INPUT_VOL_LEVEL; - m_currentVrrType = dsVRR_NONE; -} - -void AVInput::UnregisterAll() -{ - Unregister(_T(AVINPUT_METHOD_NUMBER_OF_INPUTS)); - Unregister(_T(AVINPUT_METHOD_CURRENT_VIDEO_MODE)); - Unregister(_T(AVINPUT_METHOD_CONTENT_PROTECTED)); - Unregister(_T(AVINPUT_METHOD_GET_INPUT_DEVICES)); - Unregister(_T(AVINPUT_METHOD_WRITE_EDID)); - Unregister(_T(AVINPUT_METHOD_READ_EDID)); - Unregister(_T(AVINPUT_METHOD_READ_RAWSPD)); - Unregister(_T(AVINPUT_METHOD_READ_SPD)); - Unregister(_T(AVINPUT_METHOD_SET_VRR_SUPPORT)); - Unregister(_T(AVINPUT_METHOD_GET_VRR_SUPPORT)); - Unregister(_T(AVINPUT_METHOD_GET_VRR_FRAME_RATE)); - Unregister(_T(AVINPUT_METHOD_SET_EDID_VERSION)); - Unregister(_T(AVINPUT_METHOD_GET_EDID_VERSION)); - Unregister(_T(AVINPUT_METHOD_START_INPUT)); - Unregister(_T(AVINPUT_METHOD_STOP_INPUT)); - Unregister(_T(AVINPUT_METHOD_SCALE_INPUT)); - Unregister(_T(AVINPUT_METHOD_SUPPORTED_GAME_FEATURES)); - Unregister(_T(AVINPUT_METHOD_GAME_FEATURE_STATUS)); -} - -void setResponseArray(JsonObject& response, const char* key, const vector& items) -{ - JsonArray arr; - for(auto& i : items) arr.Add(JsonValue(i)); - - response[key] = arr; - - string json; - response.ToString(json); - LOGINFO("%s: result json %s\n", __FUNCTION__, json.c_str()); -} - -uint32_t AVInput::endpoint_numberOfInputs(const JsonObject ¶meters, JsonObject &response) -{ - LOGINFOMETHOD(); - - bool success = false; - - auto result = numberOfInputs(success); - if (success) { - response[_T("numberOfInputs")] = result; - } - - returnResponse(success); -} - -uint32_t AVInput::endpoint_currentVideoMode(const JsonObject ¶meters, JsonObject &response) -{ - LOGINFOMETHOD(); - - bool success = false; - - auto result = currentVideoMode(success); - if (success) { - response[_T("currentVideoMode")] = result; - } - - returnResponse(success); -} - -uint32_t AVInput::endpoint_contentProtected(const JsonObject ¶meters, JsonObject &response) -{ - LOGINFOMETHOD(); - - // "Ths is the way it's done in Service Manager" - response[_T("isContentProtected")] = true; - - returnResponse(true); -} - -int AVInput::numberOfInputs(bool &success) -{ - int result = 0; + SERVICE_REGISTRATION(AVInput, API_VERSION_NUMBER_MAJOR, API_VERSION_NUMBER_MINOR, API_VERSION_NUMBER_PATCH); - try { - result = device::HdmiInput::getInstance().getNumberOfInputs(); - success = true; - } - catch (...) { - LOGERR("Exception caught"); - success = false; - } - - return result; -} - -string AVInput::currentVideoMode(bool &success) -{ - string result; - - try { - result = device::HdmiInput::getInstance().getCurrentVideoMode(); - success = true; - } - catch (...) { - LOGERR("Exception caught"); - success = false; - } - - return result; -} - - -uint32_t AVInput::startInput(const JsonObject& parameters, JsonObject& response) -{ - LOGINFOMETHOD(); - - string sPortId = parameters["portId"].String(); - string sType = parameters["typeOfInput"].String(); - bool audioMix = parameters["requestAudioMix"].Boolean(); - int portId = 0; - int iType = 0; - planeType = 0; //planeType = 0 - primary, 1 - secondary video plane type - bool topMostPlane = parameters["topMost"].Boolean(); - LOGINFO("topMost value in thunder: %d\n",topMostPlane); - if (parameters.HasLabel("portId") && parameters.HasLabel("typeOfInput")) + AVInput::AVInput() + : _service(nullptr) + , _connectionId(0) + , _avInput(nullptr) + , _avInputNotification(this) { - try { - portId = stoi(sPortId); - iType = getTypeOfInput (sType); - if (parameters.HasLabel("plane")){ - string sPlaneType = parameters["plane"].String(); - planeType = stoi(sPlaneType); - if(!(planeType == 0 || planeType == 1))// planeType has to be primary(0) or secondary(1) - { - LOGWARN("planeType is invalid\n"); - returnResponse(false); - } - } - }catch (...) { - LOGWARN("Invalid Arguments"); - returnResponse(false); - } - } - else { - LOGWARN("Required parameters are not passed"); - returnResponse(false); + Register(_T(AVINPUT_METHOD_GET_INPUT_DEVICES), &AVInput::getInputDevicesWrapper, this); + SYSLOG(Logging::Startup, (_T("AVInput Constructor"))); } - try + AVInput::~AVInput() { - if (iType == HDMI) { - device::HdmiInput::getInstance().selectPort(portId,audioMix,planeType,topMostPlane); - } - else if(iType == COMPOSITE) { - device::CompositeInput::getInstance().selectPort(portId); - } - } - catch (const device::Exception& err) { - LOG_DEVICE_EXCEPTION1(std::to_string(portId)); - returnResponse(false); + Unregister(_T(AVINPUT_METHOD_GET_INPUT_DEVICES)); + SYSLOG(Logging::Shutdown, (string(_T("AVInput Destructor")))); } - returnResponse(true); -} - -uint32_t AVInput::stopInput(const JsonObject& parameters, JsonObject& response) -{ - LOGINFOMETHOD(); - - string sType = parameters["typeOfInput"].String(); - int iType = 0; - if (parameters.HasLabel("typeOfInput")) - try { - iType = getTypeOfInput (sType); - }catch (...) { - LOGWARN("Invalid Arguments"); - returnResponse(false); - } - else { - LOGWARN("Required parameters are not passed"); - returnResponse(false); - } - - try + const string AVInput::Initialize(PluginHost::IShell* service) { - planeType = -1; - if (isAudioBalanceSet){ - device::Host::getInstance().setAudioMixerLevels(dsAUDIO_INPUT_PRIMARY,MAX_PRIM_VOL_LEVEL); - device::Host::getInstance().setAudioMixerLevels(dsAUDIO_INPUT_SYSTEM,DEFAULT_INPUT_VOL_LEVEL); - isAudioBalanceSet = false; - } - if (iType == HDMI) { - device::HdmiInput::getInstance().selectPort(-1); - } - else if (iType == COMPOSITE) { - device::CompositeInput::getInstance().selectPort(-1); - } - } - catch (const device::Exception& err) { - LOGWARN("AVInputService::stopInput Failed"); - returnResponse(false); - } - returnResponse(true); -} + string message = ""; -uint32_t AVInput::setVideoRectangleWrapper(const JsonObject& parameters, JsonObject& response) -{ - LOGINFOMETHOD(); + ASSERT(nullptr != service); + ASSERT(nullptr == _service); + ASSERT(nullptr == _avInput); + ASSERT(0 == _connectionId); - bool result = true; - if (!parameters.HasLabel("x") && !parameters.HasLabel("y")) { - result = false; - LOGWARN("please specif coordinates (x,y)"); - } + SYSLOG(Logging::Startup, (_T("AVInput::Initialize: PID=%u"), getpid())); - if (!parameters.HasLabel("w") && !parameters.HasLabel("h")) { - result = false; - LOGWARN("please specify window width and height (w,h)"); - } + _service = service; + _service->AddRef(); + _service->Register(&_avInputNotification); - if (!parameters.HasLabel("typeOfInput")) { - result = false; - LOGWARN("please specify type of input HDMI/COMPOSITE"); - } + _avInput = service->Root(_connectionId, 5000, _T("AVInputImplementation")); - if (result) { - int x = 0; - int y = 0; - int w = 0; - int h = 0; - int t = 0; - string sType; + if (nullptr != _avInput) { - try { - if (parameters.HasLabel("x")) { - x = parameters["x"].Number(); - } - if (parameters.HasLabel("y")) { - y = parameters["y"].Number(); - } - if (parameters.HasLabel("w")) { - w = parameters["w"].Number(); - } - if (parameters.HasLabel("h")) { - h = parameters["h"].Number(); - } - if (parameters.HasLabel("typeOfInput")) { - sType = parameters["typeOfInput"].String(); - t = getTypeOfInput (sType); - } - } - catch (...) { - LOGWARN("Invalid Arguments"); - returnResponse(false); - } + // Register for notifications + _avInput->Register(_avInputNotification.baseInterface()); + _avInput->Register(_avInputNotification.baseInterface()); + _avInput->Register(_avInputNotification.baseInterface()); + _avInput->Register(_avInputNotification.baseInterface()); + _avInput->Register(_avInputNotification.baseInterface()); + _avInput->Register(_avInputNotification.baseInterface()); - result = setVideoRectangle(x, y, w, h, t); - if (false == result) { - LOGWARN("AVInputService::setVideoRectangle Failed"); - returnResponse(false); + // Invoking Plugin API register to wpeframework + Exchange::JAVInput::Register(*this, _avInput); + } else { + SYSLOG(Logging::Startup, (_T("AVInput::Initialize: Failed to initialize AVInput plugin"))); + message = _T("AVInput plugin could not be initialized"); } - returnResponse(true); - } - returnResponse(false); -} -bool AVInput::setVideoRectangle(int x, int y, int width, int height, int type) -{ - bool ret = true; - - try - { - if (type == HDMI) { - device::HdmiInput::getInstance().scaleVideo(x, y, width, height); - } - else { - device::CompositeInput::getInstance().scaleVideo(x, y, width, height); - } + return message; } - catch (const device::Exception& err) { - ret = false; - } - - return ret; -} -uint32_t AVInput::getInputDevicesWrapper(const JsonObject& parameters, JsonObject& response) -{ - LOGINFOMETHOD(); - - if (parameters.HasLabel("typeOfInput")) { - string sType = parameters["typeOfInput"].String(); - int iType = 0; - try { - iType = getTypeOfInput (sType); - }catch (...) { - LOGWARN("Invalid Arguments"); - returnResponse(false); - } - response["devices"] = getInputDevices(iType); - } - else { - JsonArray listHdmi = getInputDevices(HDMI); - JsonArray listComposite = getInputDevices(COMPOSITE); - for (int i = 0; i < listComposite.Length(); i++) { - listHdmi.Add(listComposite.Get(i)); - } - response["devices"] = listHdmi; - } - returnResponse(true); -} - -uint32_t AVInput::writeEDIDWrapper(const JsonObject& parameters, JsonObject& response) -{ - LOGINFOMETHOD(); - - string sPortId = parameters["portId"].String(); - int portId = 0; - std::string message; - - if (parameters.HasLabel("portId") && parameters.HasLabel("message")) { - portId = stoi(sPortId); - message = parameters["message"].String(); - } - else { - LOGWARN("Required parameters are not passed"); - returnResponse(false); - } - - writeEDID(portId, message); - returnResponse(true); -} - -uint32_t AVInput::readEDIDWrapper(const JsonObject& parameters, JsonObject& response) -{ - LOGINFOMETHOD(); - - string sPortId = parameters["portId"].String(); - int portId = 0; - try { - portId = stoi(sPortId); - }catch (...) { - LOGWARN("Invalid Arguments"); - returnResponse(false); - } - - string edid = readEDID (portId); - if (edid.empty()) { - returnResponse(false); - } - else { - response["EDID"] = edid; - returnResponse(true); - } -} - -JsonArray AVInput::getInputDevices(int iType) -{ - JsonArray list; - try + void AVInput::Deinitialize(PluginHost::IShell* service) { - int num = 0; - if (iType == HDMI) { - num = device::HdmiInput::getInstance().getNumberOfInputs(); - } - else if (iType == COMPOSITE) { - num = device::CompositeInput::getInstance().getNumberOfInputs(); - } - if (num > 0) { - int i = 0; - for (i = 0; i < num; i++) { - //Input ID is aleays 0-indexed, continuous number starting 0 - JsonObject hash; - hash["id"] = i; - std::stringstream locator; - if (iType == HDMI) { - locator << "hdmiin://localhost/deviceid/" << i; - hash["connected"] = device::HdmiInput::getInstance().isPortConnected(i); - } - else if (iType == COMPOSITE) { - locator << "cvbsin://localhost/deviceid/" << i; - hash["connected"] = device::CompositeInput::getInstance().isPortConnected(i); + ASSERT(_service == service); + + SYSLOG(Logging::Shutdown, (string(_T("AVInput::Deinitialize")))); + + // Make sure the Activated and Deactivated are no longer called before we start cleaning up. + _service->Unregister(&_avInputNotification); + + if (nullptr != _avInput) { + + _avInput->Unregister(_avInputNotification.baseInterface()); + _avInput->Unregister(_avInputNotification.baseInterface()); + _avInput->Unregister(_avInputNotification.baseInterface()); + _avInput->Unregister(_avInputNotification.baseInterface()); + _avInput->Unregister(_avInputNotification.baseInterface()); + _avInput->Unregister(_avInputNotification.baseInterface()); + + Exchange::JAVInput::Unregister(*this); + + // Stop processing: + RPC::IRemoteConnection* connection = service->RemoteConnection(_connectionId); + VARIABLE_IS_NOT_USED uint32_t result = _avInput->Release(); + + _avInput = nullptr; + + // It should have been the last reference we are releasing, + // so it should endup in a DESTRUCTION_SUCCEEDED, if not we + // are leaking... + ASSERT(result == Core::ERROR_DESTRUCTION_SUCCEEDED); + + // If this was running in a (container) process... + if (nullptr != connection) { + // Lets trigger the cleanup sequence for + // out-of-process code. Which will guard + // that unwilling processes, get shot if + // not stopped friendly :-) + try { + connection->Terminate(); + // Log success if needed + LOGWARN("Connection terminated successfully."); + } catch (const std::exception& e) { + std::string errorMessage = "Failed to terminate connection: "; + errorMessage += e.what(); + LOGWARN("%s", errorMessage.c_str()); } - hash["locator"] = locator.str(); - LOGWARN("AVInputService::getInputDevices id %d, locator=[%s], connected=[%d]", i, hash["locator"].String().c_str(), hash["connected"].Boolean()); - list.Add(hash); - } - } - } - catch (const std::exception &e) { - LOGWARN("AVInputService::getInputDevices Failed"); - } - return list; -} - -void AVInput::writeEDID(int portId, std::string message) -{ -} - -std::string AVInput::readEDID(int iPort) -{ - vector edidVec({'u','n','k','n','o','w','n' }); - string edidbase64 = ""; - try { - vector edidVec2; - device::HdmiInput::getInstance().getEDIDBytesInfo (iPort, edidVec2); - edidVec = edidVec2;//edidVec must be "unknown" unless we successfully get to this line - //convert to base64 - uint16_t size = min(edidVec.size(), (size_t)numeric_limits::max()); - - LOGWARN("AVInput::readEDID size:%d edidVec.size:%zu", size, edidVec.size()); - if(edidVec.size() > (size_t)numeric_limits::max()) { - LOGERR("Size too large to use ToString base64 wpe api"); - return edidbase64; + connection->Release(); + } } - Core::ToString((uint8_t*)&edidVec[0], size, true, edidbase64); - } - catch (const device::Exception& err) { - LOG_DEVICE_EXCEPTION1(std::to_string(iPort)); - } - return edidbase64; -} - -/** - * @brief This function is used to translate HDMI/COMPOSITE input hotplug to - * deviceChanged event. - * - * @param[in] input Number of input port integer. - * @param[in] connection status of input port integer. - */ -void AVInput::AVInputHotplug( int input , int connect, int type) -{ - LOGWARN("AVInputHotplug [%d, %d, %d]", input, connect, type); - - JsonObject params; - params["devices"] = getInputDevices(type); - sendNotify(AVINPUT_EVENT_ON_DEVICES_CHANGED, params); -} - -/** - * @brief This function is used to translate HDMI/COMPOSITE input signal change to - * signalChanged event. - * - * @param[in] port HDMI/COMPOSITE In port id. - * @param[in] signalStatus signal status of HDMI/COMPOSITE In port. - */ -void AVInput::AVInputSignalChange( int port , int signalStatus, int type) -{ - LOGWARN("AVInputSignalStatus [%d, %d, %d]", port, signalStatus, type); - - JsonObject params; - params["id"] = port; - std::stringstream locator; - if (type == HDMI) { - locator << "hdmiin://localhost/deviceid/" << port; - } - else { - locator << "cvbsin://localhost/deviceid/" << port; - } - params["locator"] = locator.str(); - /* values of dsHdmiInSignalStatus_t and dsCompInSignalStatus_t are same - Hence used only HDMI macro for case statement */ - switch (signalStatus) { - case dsHDMI_IN_SIGNAL_STATUS_NOSIGNAL: - params["signalStatus"] = "noSignal"; - break; - - case dsHDMI_IN_SIGNAL_STATUS_UNSTABLE: - params["signalStatus"] = "unstableSignal"; - break; - - case dsHDMI_IN_SIGNAL_STATUS_NOTSUPPORTED: - params["signalStatus"] = "notSupportedSignal"; - break; - - case dsHDMI_IN_SIGNAL_STATUS_STABLE: - params["signalStatus"] = "stableSignal"; - break; - - default: - params["signalStatus"] = "none"; - break; - } - sendNotify(AVINPUT_EVENT_ON_SIGNAL_CHANGED, params); -} -/** - * @brief This function is used to translate HDMI/COMPOSITE input status change to - * inputStatusChanged event. - * - * @param[in] port HDMI/COMPOSITE In port id. - * @param[bool] isPresented HDMI/COMPOSITE In presentation started/stopped. - */ -void AVInput::AVInputStatusChange( int port , bool isPresented, int type) -{ - LOGWARN("avInputStatus [%d, %d, %d]", port, isPresented, type); - - JsonObject params; - params["id"] = port; - std::stringstream locator; - if (type == HDMI) { - locator << "hdmiin://localhost/deviceid/" << port; - } - else if (type == COMPOSITE) { - locator << "cvbsin://localhost/deviceid/" << port; - } - params["locator"] = locator.str(); - - if(isPresented) { - params["status"] = "started"; - } - else { - params["status"] = "stopped"; + _connectionId = 0; + _service->Release(); + _service = nullptr; + SYSLOG(Logging::Shutdown, (string(_T("AVInput de-initialised")))); } - params["plane"] = planeType; - sendNotify(AVINPUT_EVENT_ON_STATUS_CHANGED, params); -} - -/** - * @brief This function is used to translate HDMI input video mode change to - * videoStreamInfoUpdate event. - * - * @param[in] port HDMI In port id. - * @param[dsVideoPortResolution_t] video resolution data - */ -void AVInput::AVInputVideoModeUpdate( int port , dsVideoPortResolution_t resolution, int type) -{ - LOGWARN("AVInputVideoModeUpdate [%d]", port); - - JsonObject params; - params["id"] = port; - std::stringstream locator; - if(type == HDMI){ - - locator << "hdmiin://localhost/deviceid/" << port; - switch(resolution.pixelResolution) { - case dsVIDEO_PIXELRES_720x480: - params["width"] = 720; - params["height"] = 480; - break; - - case dsVIDEO_PIXELRES_720x576: - params["width"] = 720; - params["height"] = 576; - break; - - case dsVIDEO_PIXELRES_1280x720: - params["width"] = 1280; - params["height"] = 720; - break; - - case dsVIDEO_PIXELRES_1920x1080: - params["width"] = 1920; - params["height"] = 1080; - break; - - case dsVIDEO_PIXELRES_3840x2160: - params["width"] = 3840; - params["height"] = 2160; - break; - - case dsVIDEO_PIXELRES_4096x2160: - params["width"] = 4096; - params["height"] = 2160; - break; - - default: - params["width"] = 1920; - params["height"] = 1080; - break; - } - params["progressive"] = (!resolution.interlaced); - } - else if(type == COMPOSITE) + JsonArray AVInput::getInputDevices(int iType) { - locator << "cvbsin://localhost/deviceid/" << port; - switch(resolution.pixelResolution) { - case dsVIDEO_PIXELRES_720x480: - params["width"] = 720; - params["height"] = 480; - break; - case dsVIDEO_PIXELRES_720x576: - params["width"] = 720; - params["height"] = 576; - break; - default: - params["width"] = 720; - params["height"] = 576; - break; - } - - params["progressive"] = false; - } - - params["locator"] = locator.str(); - switch(resolution.frameRate) { - case dsVIDEO_FRAMERATE_24: - params["frameRateN"] = 24000; - params["frameRateD"] = 1000; - break; - - case dsVIDEO_FRAMERATE_25: - params["frameRateN"] = 25000; - params["frameRateD"] = 1000; - break; - - case dsVIDEO_FRAMERATE_30: - params["frameRateN"] = 30000; - params["frameRateD"] = 1000; - break; - - case dsVIDEO_FRAMERATE_50: - params["frameRateN"] = 50000; - params["frameRateD"] = 1000; - break; - - case dsVIDEO_FRAMERATE_60: - params["frameRateN"] = 60000; - params["frameRateD"] = 1000; - break; - - case dsVIDEO_FRAMERATE_23dot98: - params["frameRateN"] = 24000; - params["frameRateD"] = 1001; - break; - - case dsVIDEO_FRAMERATE_29dot97: - params["frameRateN"] = 30000; - params["frameRateD"] = 1001; - break; - - case dsVIDEO_FRAMERATE_59dot94: - params["frameRateN"] = 60000; - params["frameRateD"] = 1001; - break; - case dsVIDEO_FRAMERATE_100: - params["frameRateN"] = 100000; - params["frameRateD"] = 1000; - break; - case dsVIDEO_FRAMERATE_119dot88: - params["frameRateN"] = 120000; - params["frameRateD"] = 1001; - break; - case dsVIDEO_FRAMERATE_120: - params["frameRateN"] = 120000; - params["frameRateD"] = 1000; - break; - case dsVIDEO_FRAMERATE_200: - params["frameRateN"] = 200000; - params["frameRateD"] = 1000; - break; - case dsVIDEO_FRAMERATE_239dot76: - params["frameRateN"] = 240000; - params["frameRateD"] = 1001; - break; - case dsVIDEO_FRAMERATE_240: - params["frameRateN"] = 240000; - params["frameRateD"] = 100; - break; - default: - params["frameRateN"] = 60000; - params["frameRateD"] = 1000; - break; - } - - sendNotify(AVINPUT_EVENT_ON_VIDEO_MODE_UPDATED, params); -} - -void AVInput::dsAviContentTypeEventHandler(const char *owner, IARM_EventId_t eventId, void *data, size_t len) -{ - if(!AVInput::_instance) - return; - - if (IARM_BUS_DSMGR_EVENT_HDMI_IN_AVI_CONTENT_TYPE == eventId) - { - IARM_Bus_DSMgr_EventData_t *eventData = (IARM_Bus_DSMgr_EventData_t *)data; - int hdmi_in_port = eventData->data.hdmi_in_content_type.port; - int avi_content_type = eventData->data.hdmi_in_content_type.aviContentType; - LOGINFO("Received IARM_BUS_DSMGR_EVENT_HDMI_IN_AVI_CONTENT_TYPE event port: %d, Content Type : %d", hdmi_in_port,avi_content_type); - - AVInput::_instance->hdmiInputAviContentTypeChange(hdmi_in_port, avi_content_type); - } -} - -void AVInput::hdmiInputAviContentTypeChange( int port , int content_type) -{ - JsonObject params; - params["id"] = port; - params["aviContentType"] = content_type; - sendNotify(AVINPUT_EVENT_ON_AVI_CONTENT_TYPE_CHANGED, params); -} - -void AVInput::dsAVEventHandler(const char *owner, IARM_EventId_t eventId, void *data, size_t len) -{ - if(!AVInput::_instance) - return; - - IARM_Bus_DSMgr_EventData_t *eventData = (IARM_Bus_DSMgr_EventData_t *)data; - if (IARM_BUS_DSMGR_EVENT_HDMI_IN_HOTPLUG == eventId) { - int hdmiin_hotplug_port = eventData->data.hdmi_in_connect.port; - int hdmiin_hotplug_conn = eventData->data.hdmi_in_connect.isPortConnected; - LOGWARN("Received IARM_BUS_DSMGR_EVENT_HDMI_IN_HOTPLUG event data:%d", hdmiin_hotplug_port); - AVInput::_instance->AVInputHotplug(hdmiin_hotplug_port, hdmiin_hotplug_conn ? AV_HOT_PLUG_EVENT_CONNECTED : AV_HOT_PLUG_EVENT_DISCONNECTED, HDMI); - } - else if (IARM_BUS_DSMGR_EVENT_COMPOSITE_IN_HOTPLUG == eventId) { - int compositein_hotplug_port = eventData->data.composite_in_connect.port; - int compositein_hotplug_conn = eventData->data.composite_in_connect.isPortConnected; - LOGWARN("Received IARM_BUS_DSMGR_EVENT_COMPOSITE_IN_HOTPLUG event data:%d", compositein_hotplug_port); - AVInput::_instance->AVInputHotplug(compositein_hotplug_port, compositein_hotplug_conn ? AV_HOT_PLUG_EVENT_CONNECTED : AV_HOT_PLUG_EVENT_DISCONNECTED, COMPOSITE); - } -} - -void AVInput::dsAVSignalStatusEventHandler(const char *owner, IARM_EventId_t eventId, void *data, size_t len) -{ - if(!AVInput::_instance) - return; - IARM_Bus_DSMgr_EventData_t *eventData = (IARM_Bus_DSMgr_EventData_t *)data; - if (IARM_BUS_DSMGR_EVENT_HDMI_IN_SIGNAL_STATUS == eventId) { - int hdmi_in_port = eventData->data.hdmi_in_sig_status.port; - int hdmi_in_signal_status = eventData->data.hdmi_in_sig_status.status; - LOGWARN("Received IARM_BUS_DSMGR_EVENT_HDMI_IN_SIGNAL_STATUS event port: %d, signal status: %d", hdmi_in_port,hdmi_in_signal_status); - AVInput::_instance->AVInputSignalChange(hdmi_in_port, hdmi_in_signal_status, HDMI); - } - else if (IARM_BUS_DSMGR_EVENT_COMPOSITE_IN_SIGNAL_STATUS == eventId) { - int composite_in_port = eventData->data.composite_in_sig_status.port; - int composite_in_signal_status = eventData->data.composite_in_sig_status.status; - LOGWARN("Received IARM_BUS_DSMGR_EVENT_COMPOSITE_IN_SIGNAL_STATUS event port: %d, signal status: %d", composite_in_port,composite_in_signal_status); - AVInput::_instance->AVInputSignalChange(composite_in_port, composite_in_signal_status, COMPOSITE); - } -} - -void AVInput::dsAVStatusEventHandler(const char *owner, IARM_EventId_t eventId, void *data, size_t len) -{ - if(!AVInput::_instance) - return; - IARM_Bus_DSMgr_EventData_t *eventData = (IARM_Bus_DSMgr_EventData_t *)data; - if (IARM_BUS_DSMGR_EVENT_HDMI_IN_STATUS == eventId) { - int hdmi_in_port = eventData->data.hdmi_in_status.port; - bool hdmi_in_status = eventData->data.hdmi_in_status.isPresented; - LOGWARN("Received IARM_BUS_DSMGR_EVENT_HDMI_IN_STATUS event port: %d, started: %d", hdmi_in_port,hdmi_in_status); - AVInput::_instance->AVInputStatusChange(hdmi_in_port, hdmi_in_status, HDMI); - } - else if (IARM_BUS_DSMGR_EVENT_COMPOSITE_IN_STATUS == eventId) { - int composite_in_port = eventData->data.composite_in_status.port; - bool composite_in_status = eventData->data.composite_in_status.isPresented; - LOGWARN("Received IARM_BUS_DSMGR_EVENT_COMPOSITE_IN_STATUS event port: %d, started: %d", composite_in_port,composite_in_status); - AVInput::_instance->AVInputStatusChange(composite_in_port, composite_in_status, COMPOSITE); - } -} - -void AVInput::dsAVVideoModeEventHandler(const char *owner, IARM_EventId_t eventId, void *data, size_t len) -{ - if(!AVInput::_instance) - return; - - if (IARM_BUS_DSMGR_EVENT_HDMI_IN_VIDEO_MODE_UPDATE == eventId) { - IARM_Bus_DSMgr_EventData_t *eventData = (IARM_Bus_DSMgr_EventData_t *)data; - int hdmi_in_port = eventData->data.hdmi_in_video_mode.port; - dsVideoPortResolution_t resolution = {}; - resolution.pixelResolution = eventData->data.hdmi_in_video_mode.resolution.pixelResolution; - resolution.interlaced = eventData->data.hdmi_in_video_mode.resolution.interlaced; - resolution.frameRate = eventData->data.hdmi_in_video_mode.resolution.frameRate; - LOGWARN("Received IARM_BUS_DSMGR_EVENT_HDMI_IN_VIDEO_MODE_UPDATE event port: %d, pixelResolution: %d, interlaced : %d, frameRate: %d \n", hdmi_in_port,resolution.pixelResolution, resolution.interlaced, resolution.frameRate); - AVInput::_instance->AVInputVideoModeUpdate(hdmi_in_port, resolution,HDMI); - } - else if (IARM_BUS_DSMGR_EVENT_COMPOSITE_IN_VIDEO_MODE_UPDATE == eventId) { - IARM_Bus_DSMgr_EventData_t *eventData = (IARM_Bus_DSMgr_EventData_t *)data; - int composite_in_port = eventData->data.composite_in_video_mode.port; - dsVideoPortResolution_t resolution = {}; - resolution.pixelResolution = eventData->data.composite_in_video_mode.resolution.pixelResolution; - resolution.interlaced = eventData->data.composite_in_video_mode.resolution.interlaced; - resolution.frameRate = eventData->data.composite_in_video_mode.resolution.frameRate; - LOGWARN("Received IARM_BUS_DSMGR_EVENT_COMPOSITE_IN_VIDEO_MODE_UPDATE event port: %d, pixelResolution: %d, interlaced : %d, frameRate: %d \n", composite_in_port,resolution.pixelResolution, resolution.interlaced, resolution.frameRate); - AVInput::_instance->AVInputVideoModeUpdate(composite_in_port, resolution,COMPOSITE); - } -} - -void AVInput::dsAVGameFeatureStatusEventHandler(const char *owner, IARM_EventId_t eventId, void *data, size_t len) -{ - if(!AVInput::_instance) - return; - - if (IARM_BUS_DSMGR_EVENT_HDMI_IN_ALLM_STATUS == eventId) - { - IARM_Bus_DSMgr_EventData_t *eventData = (IARM_Bus_DSMgr_EventData_t *)data; - int hdmi_in_port = eventData->data.hdmi_in_allm_mode.port; - bool allm_mode = eventData->data.hdmi_in_allm_mode.allm_mode; - LOGWARN("Received IARM_BUS_DSMGR_EVENT_HDMI_IN_ALLM_STATUS event port: %d, ALLM Mode: %d", hdmi_in_port,allm_mode); - - AVInput::_instance->AVInputALLMChange(hdmi_in_port, allm_mode); - } - if (IARM_BUS_DSMGR_EVENT_HDMI_IN_VRR_STATUS == eventId) - { - IARM_Bus_DSMgr_EventData_t *eventData = (IARM_Bus_DSMgr_EventData_t *)data; - int hdmi_in_port = eventData->data.hdmi_in_vrr_mode.port; - dsVRRType_t new_vrrType = eventData->data.hdmi_in_vrr_mode.vrr_type; - LOGWARN("Received IARM_BUS_DSMGR_EVENT_HDMI_IN_VRR_STATUS event port: %d, VRR Type: %d", hdmi_in_port,new_vrrType); - - if(new_vrrType == dsVRR_NONE) + JsonArray list; + try { - if(AVInput::_instance->m_currentVrrType != dsVRR_NONE){ - AVInput::_instance->AVInputVRRChange(hdmi_in_port, AVInput::_instance->m_currentVrrType, false); + int num = 0; + if (iType == INPUT_TYPE_INT_HDMI) { + num = device::HdmiInput::getInstance().getNumberOfInputs(); + } + else if (iType == INPUT_TYPE_INT_COMPOSITE) { + num = device::CompositeInput::getInstance().getNumberOfInputs(); + } + if (num > 0) { + int i = 0; + for (i = 0; i < num; i++) { + //Input ID is aleays 0-indexed, continuous number starting 0 + JsonObject hash; + hash["id"] = i; + std::stringstream locator; + if (iType == INPUT_TYPE_INT_HDMI) { + locator << "hdmiin://localhost/deviceid/" << i; + hash["connected"] = device::HdmiInput::getInstance().isPortConnected(i); + } + else if (iType == INPUT_TYPE_INT_COMPOSITE) { + locator << "cvbsin://localhost/deviceid/" << i; + hash["connected"] = device::CompositeInput::getInstance().isPortConnected(i); + } + hash["locator"] = locator.str(); + LOGWARN("AVInputService::getInputDevices id %d, locator=[%s], connected=[%d]", i, hash["locator"].String().c_str(), hash["connected"].Boolean()); + list.Add(hash); } + } } - else - { - if(AVInput::_instance->m_currentVrrType != dsVRR_NONE){ - AVInput::_instance->AVInputVRRChange(hdmi_in_port, AVInput::_instance->m_currentVrrType, false); - } - AVInput::_instance->AVInputVRRChange(hdmi_in_port, new_vrrType, true); - } - AVInput::_instance->m_currentVrrType = new_vrrType; - } -} - -void AVInput::AVInputALLMChange( int port , bool allm_mode) -{ - JsonObject params; - params["id"] = port; - params["gameFeature"] = STR_ALLM; - params["mode"] = allm_mode; - - sendNotify(AVINPUT_EVENT_ON_GAME_FEATURE_STATUS_CHANGED, params); -} - -void AVInput::AVInputVRRChange( int port , dsVRRType_t vrr_type, bool vrr_mode) -{ - JsonObject params; - switch(vrr_type) - { - case dsVRR_HDMI_VRR: - params["id"] = port; - params["gameFeature"] = VRR_TYPE_HDMI; - params["mode"] = vrr_mode; - break; - case dsVRR_AMD_FREESYNC: - params["id"] = port; - params["gameFeature"] = VRR_TYPE_FREESYNC; - params["mode"] = vrr_mode; - break; - case dsVRR_AMD_FREESYNC_PREMIUM: - params["id"] = port; - params["gameFeature"] = VRR_TYPE_FREESYNC_PREMIUM; - params["mode"] = vrr_mode; - break; - case dsVRR_AMD_FREESYNC_PREMIUM_PRO: - params["id"] = port; - params["gameFeature"] = VRR_TYPE_FREESYNC_PREMIUM_PRO; - params["mode"] = vrr_mode; - break; - default: - break; - } - sendNotify(AVINPUT_EVENT_ON_GAME_FEATURE_STATUS_CHANGED, params); -} - -uint32_t AVInput::getSupportedGameFeatures(const JsonObject& parameters, JsonObject& response) -{ - LOGINFOMETHOD(); - vector supportedFeatures; - try - { - device::HdmiInput::getInstance().getSupportedGameFeatures (supportedFeatures); - for (size_t i = 0; i < supportedFeatures.size(); i++) - { - LOGINFO("Supported Game Feature [%zu]: %s\n",i,supportedFeatures.at(i).c_str()); - } - } - catch (const device::Exception& err) - { - LOG_DEVICE_EXCEPTION0(); - } - - if (supportedFeatures.empty()) { - returnResponse(false); - } - else { - setResponseArray(response, "supportedGameFeatures", supportedFeatures); - returnResponse(true); - } -} - -uint32_t AVInput::getGameFeatureStatusWrapper(const JsonObject& parameters, JsonObject& response) -{ - string sGameFeature = ""; - string sPortId = parameters["portId"].String(); - int portId = 0; - - LOGINFOMETHOD(); - if (parameters.HasLabel("portId") && parameters.HasLabel("gameFeature")) - { - try { - portId = stoi(sPortId); - sGameFeature = parameters["gameFeature"].String(); - }catch (...) { - LOGWARN("Invalid Arguments"); - returnResponse(false); + catch (const std::exception &e) { + LOGWARN("AVInputService::getInputDevices Failed"); } + return list; } - else { - LOGWARN("Required parameters are not passed"); - returnResponse(false); - } - - if (strcmp (sGameFeature.c_str(), STR_ALLM) == 0) - { - bool allm = getALLMStatus(portId); - LOGWARN("AVInput::getGameFeatureStatusWrapper ALLM MODE:%d", allm); - response["mode"] = allm; - } - else if(strcmp (sGameFeature.c_str(), VRR_TYPE_HDMI) == 0) - { - bool hdmi_vrr = false; - dsHdmiInVrrStatus_t vrrStatus; - getVRRStatus(portId, &vrrStatus); - if(vrrStatus.vrrType == dsVRR_HDMI_VRR) - hdmi_vrr = true; - LOGWARN("AVInput::getGameFeatureStatusWrapper HDMI VRR MODE:%d", hdmi_vrr); - response["mode"] = hdmi_vrr; - } - else if(strcmp (sGameFeature.c_str(), VRR_TYPE_FREESYNC) == 0) - { - bool freesync = false; - dsHdmiInVrrStatus_t vrrStatus; - getVRRStatus(portId, &vrrStatus); - if(vrrStatus.vrrType == dsVRR_AMD_FREESYNC) - freesync = true; - LOGWARN("AVInput::getGameFeatureStatusWrapper FREESYNC MODE:%d", freesync); - response["mode"] = freesync; - } - else if(strcmp (sGameFeature.c_str(), VRR_TYPE_FREESYNC_PREMIUM) == 0) - { - bool freesync_premium = false; - dsHdmiInVrrStatus_t vrrStatus; - getVRRStatus(portId, &vrrStatus); - if(vrrStatus.vrrType == dsVRR_AMD_FREESYNC_PREMIUM) - freesync_premium = true; - LOGWARN("AVInput::getGameFeatureStatusWrapper FREESYNC PREMIUM MODE:%d", freesync_premium); - response["mode"] = freesync_premium; - } - else if(strcmp (sGameFeature.c_str(), VRR_TYPE_FREESYNC_PREMIUM_PRO) == 0) - { - bool freesync_premium_pro = false; - dsHdmiInVrrStatus_t vrrStatus; - getVRRStatus(portId, &vrrStatus); - if(vrrStatus.vrrType == dsVRR_AMD_FREESYNC_PREMIUM_PRO) - freesync_premium_pro = true; - LOGWARN("AVInput::getGameFeatureStatusWrapper FREESYNC PREMIUM PRO MODE:%d", freesync_premium_pro); - response["mode"] = freesync_premium_pro; - } - else - { - LOGWARN("AVInput::getGameFeatureStatusWrapper Mode is not supported. Supported mode: ALLM, VRR-HDMI, VRR-FREESYNC-PREMIUM"); - returnResponse(false); - } - returnResponse(true); -} - -bool AVInput::getALLMStatus(int iPort) -{ - bool allm = false; - try + uint32_t AVInput::getInputDevicesWrapper(const JsonObject& parameters, JsonObject& response) { - device::HdmiInput::getInstance().getHdmiALLMStatus (iPort, &allm); - LOGWARN("AVInput::getALLMStatus ALLM MODE: %d", allm); - } - catch (const device::Exception& err) - { - LOG_DEVICE_EXCEPTION1(std::to_string(iPort)); - } - return allm; -} - -bool AVInput::getVRRStatus(int iPort, dsHdmiInVrrStatus_t *vrrStatus) -{ - bool ret = true; - try - { - device::HdmiInput::getInstance().getVRRStatus (iPort, vrrStatus); - LOGWARN("AVInput::getVRRStatus VRR TYPE: %d, VRR FRAMERATE: %f", vrrStatus->vrrType,vrrStatus->vrrAmdfreesyncFramerate_Hz); - } - catch (const device::Exception& err) - { - LOG_DEVICE_EXCEPTION1(std::to_string(iPort)); - ret = false; - } - return ret; -} - -uint32_t AVInput::getRawSPDWrapper(const JsonObject& parameters, JsonObject& response) -{ - LOGINFOMETHOD(); + LOGINFOMETHOD(); - string sPortId = parameters["portId"].String(); - int portId = 0; - if (parameters.HasLabel("portId")) - { - try { - portId = stoi(sPortId); - }catch (...) { - LOGWARN("Invalid Arguments"); - returnResponse(false); + if (parameters.HasLabel("typeOfInput")) { + string sType = parameters["typeOfInput"].String(); + int iType = 0; + try { + iType = AVInputUtils::getTypeOfInput(sType); + }catch (...) { + LOGWARN("Invalid Arguments"); + returnResponse(false); + } + response["devices"] = getInputDevices(iType); } - } - else { - LOGWARN("Required parameters are not passed"); - returnResponse(false); - } - - string spdInfo = getRawSPD (portId); - response["HDMISPD"] = spdInfo; - if (spdInfo.empty()) { - returnResponse(false); - } - else { - returnResponse(true); - } -} - -uint32_t AVInput::getSPDWrapper(const JsonObject& parameters, JsonObject& response) -{ - LOGINFOMETHOD(); - - string sPortId = parameters["portId"].String(); - int portId = 0; - if (parameters.HasLabel("portId")) - { - try { - portId = stoi(sPortId); - }catch (...) { - LOGWARN("Invalid Arguments"); - returnResponse(false); + else { + JsonArray listHdmi = getInputDevices(INPUT_TYPE_INT_HDMI); + JsonArray listComposite = getInputDevices(INPUT_TYPE_INT_COMPOSITE); + for (int i = 0; i < listComposite.Length(); i++) { + listHdmi.Add(listComposite.Get(i)); + } + response["devices"] = listHdmi; } - } - else { - LOGWARN("Required parameters are not passed"); - returnResponse(false); - } - - string spdInfo = getSPD (portId); - response["HDMISPD"] = spdInfo; - if (spdInfo.empty()) { - returnResponse(false); - } - else { returnResponse(true); } -} - -std::string AVInput::getRawSPD(int iPort) -{ - LOGINFO("AVInput::getSPDInfo"); - vector spdVect({'u','n','k','n','o','w','n' }); - std::string spdbase64 = ""; - try { - LOGWARN("AVInput::getSPDInfo"); - vector spdVect2; - device::HdmiInput::getInstance().getHDMISPDInfo(iPort, spdVect2); - spdVect = spdVect2;//edidVec must be "unknown" unless we successfully get to this line - - //convert to base64 - uint16_t size = min(spdVect.size(), (size_t)numeric_limits::max()); - - LOGWARN("AVInput::getSPD size:%d spdVec.size:%zu", size, spdVect.size()); - - if(spdVect.size() > (size_t)numeric_limits::max()) { - LOGERR("Size too large to use ToString base64 wpe api"); - return spdbase64; - } - - LOGINFO("------------getSPD: "); - for (size_t itr =0; itr < spdVect.size(); itr++) { - LOGINFO("%02X ", spdVect[itr]); - } - Core::ToString((uint8_t*)&spdVect[0], size, false, spdbase64); - } - catch (const device::Exception& err) { - LOG_DEVICE_EXCEPTION1(std::to_string(iPort)); - } - return spdbase64; -} - -std::string AVInput::getSPD(int iPort) -{ - LOGINFO("AVInput::getSPDInfo"); - vector spdVect({'u','n','k','n','o','w','n' }); - std::string spdbase64 = ""; - try { - LOGWARN("AVInput::getSPDInfo"); - vector spdVect2; - device::HdmiInput::getInstance().getHDMISPDInfo(iPort, spdVect2); - spdVect = spdVect2;//edidVec must be "unknown" unless we successfully get to this line - - //convert to base64 - uint16_t size = min(spdVect.size(), (size_t)numeric_limits::max()); - - LOGWARN("AVInput::getSPD size:%d spdVec.size:%zu", size, spdVect.size()); - - if(spdVect.size() > (size_t)numeric_limits::max()) { - LOGERR("Size too large to use ToString base64 wpe api"); - return spdbase64; - } - - LOGINFO("------------getSPD: "); - for (size_t itr =0; itr < spdVect.size(); itr++) { - LOGINFO("%02X ", spdVect[itr]); - } - if (spdVect.size() > 0) { - struct dsSpd_infoframe_st pre; - memcpy(&pre,spdVect.data(),sizeof(struct dsSpd_infoframe_st)); - char str[200] = {0}; - snprintf(str, sizeof(str), "Packet Type:%02X,Version:%u,Length:%u,vendor name:%s,product des:%s,source info:%02X", - pre.pkttype,pre.version,pre.length,pre.vendor_name,pre.product_des,pre.source_info); - spdbase64 = str; - } - } - catch (const device::Exception& err) { - LOG_DEVICE_EXCEPTION1(std::to_string(iPort)); + string AVInput::Information() const + { + return (string()); } - return spdbase64; -} - -uint32_t AVInput::setMixerLevels(const JsonObject& parameters, JsonObject& response) -{ - returnIfParamNotFound(parameters, "primaryVolume"); - returnIfParamNotFound(parameters, "inputVolume"); - - int primVol = 0, inputVol = 0; - try { - primVol = parameters["primaryVolume"].Number(); - inputVol = parameters["inputVolume"].Number() ; - } catch(...) { - LOGERR("Incompatible params passed !!!\n"); - response["success"] = false; - returnResponse(false); - } - - if( (primVol >=0) && (inputVol >=0) ) { - m_primVolume = primVol; - m_inputVolume = inputVol; - } - else { - LOGERR("Incompatible params passed !!!\n"); - response["success"] = false; - returnResponse(false); - } - if(m_primVolume > MAX_PRIM_VOL_LEVEL) { - LOGWARN("Primary Volume greater than limit. Set to MAX_PRIM_VOL_LEVEL(100) !!!\n"); - m_primVolume = MAX_PRIM_VOL_LEVEL; - } - if(m_inputVolume > DEFAULT_INPUT_VOL_LEVEL) { - LOGWARN("INPUT Volume greater than limit. Set to DEFAULT_INPUT_VOL_LEVEL(100) !!!\n"); - m_inputVolume = DEFAULT_INPUT_VOL_LEVEL; - } - - LOGINFO("GLOBAL primary Volume=%d input Volume=%d \n",m_primVolume , m_inputVolume ); - - try{ - - device::Host::getInstance().setAudioMixerLevels(dsAUDIO_INPUT_PRIMARY,primVol); - device::Host::getInstance().setAudioMixerLevels(dsAUDIO_INPUT_SYSTEM,inputVol); - } - catch(...){ - LOGWARN("Not setting SoC volume !!!\n"); - returnResponse(false); - } - isAudioBalanceSet = true; - returnResponse(true); -} - -int setEdid2AllmSupport(int portId, bool allmSupport) -{ - bool ret = true; - try - { - device::HdmiInput::getInstance().setEdid2AllmSupport (portId, allmSupport); - LOGWARN("AVInput - allmsupport:%d", allmSupport); - } - catch (const device::Exception& err) - { - LOG_DEVICE_EXCEPTION1(std::to_string(portId)); - ret = false; - } -return ret; -} - -uint32_t AVInput::setEdid2AllmSupportWrapper(const JsonObject& parameters, JsonObject& response) -{ - LOGINFOMETHOD(); - - returnIfParamNotFound(parameters, "portId"); - returnIfParamNotFound(parameters, "allmSupport"); - - int portId = 0; - string sPortId = parameters["portId"].String(); - bool allmSupport = parameters["allmSupport"].Boolean(); - - try { - portId = stoi(sPortId); - }catch (const std::exception& err) { - LOGWARN("sPortId invalid paramater: %s ", sPortId.c_str()); - returnResponse(false); - } - - bool result = setEdid2AllmSupport(portId, allmSupport); - if(result == true) - { - returnResponse(true); - } - else - { - returnResponse(false); - } - -} - -bool getEdid2AllmSupport(int portId,bool *allmSupportValue) -{ - bool ret = true; - try - { - device::HdmiInput::getInstance().getEdid2AllmSupport (portId, allmSupportValue); - LOGINFO("AVInput - getEdid2AllmSupport:%d", *allmSupportValue); - } - catch (const device::Exception& err) - { - LOG_DEVICE_EXCEPTION1(std::to_string(portId)); - ret = false; - } - return ret; -} - -uint32_t AVInput::getEdid2AllmSupportWrapper(const JsonObject& parameters, JsonObject& response) -{ - LOGINFOMETHOD(); - string sPortId = parameters["portId"].String(); - - int portId = 0; - bool allmSupport = true; - returnIfParamNotFound(parameters, "portId"); - - try { - portId = stoi(sPortId); - }catch (const std::exception& err) { - LOGWARN("sPortId invalid paramater: %s ", sPortId.c_str()); - returnResponse(false); - } - - bool result = getEdid2AllmSupport(portId, &allmSupport); - if(result == true) - { - response["allmSupport"] = allmSupport; - returnResponse(true); - } - else - { - returnResponse(false); - } -} - -bool AVInput::getVRRSupport(int portId,bool *vrrSupportValue) -{ - bool ret = true; - try - { - device::HdmiInput::getInstance().getVRRSupport (portId, vrrSupportValue); - LOGINFO("AVInput - getVRRSupport:%d", *vrrSupportValue); - } - catch (const device::Exception& err) - { - LOG_DEVICE_EXCEPTION1(std::to_string(portId)); - ret = false; - } - return ret; -} - -uint32_t AVInput::getVRRSupportWrapper(const JsonObject& parameters, JsonObject& response) -{ - LOGINFOMETHOD(); - returnIfParamNotFound(parameters, "portId"); - string sPortId = parameters["portId"].String(); - - int portId = 0; - bool vrrSupport = true; - - try { - portId = stoi(sPortId); - }catch (const std::exception& err) { - LOGWARN("sPortId invalid paramater: %s ", sPortId.c_str()); - returnResponse(false); - } - - bool result = getVRRSupport(portId, &vrrSupport); - if(result == true) - { - response["vrrSupport"] = vrrSupport; - returnResponse(true); - } - else - { - returnResponse(false); - } -} - -bool AVInput::setVRRSupport(int portId, bool vrrSupport) -{ - bool ret = true; - try - { - device::HdmiInput::getInstance().setVRRSupport (portId, vrrSupport); - LOGWARN("AVInput - vrrSupport:%d", vrrSupport); - } - catch (const device::Exception& err) - { - LOG_DEVICE_EXCEPTION1(std::to_string(portId)); - ret = false; - } - return ret; - -} - -uint32_t AVInput::setVRRSupportWrapper(const JsonObject& parameters, JsonObject& response) -{ - LOGINFOMETHOD(); - - returnIfParamNotFound(parameters, "portId"); - returnIfParamNotFound(parameters, "vrrSupport"); - - int portId = 0; - string sPortId = parameters["portId"].String(); - bool vrrSupport = parameters["vrrSupport"].Boolean(); - - try { - portId = stoi(sPortId); - }catch (const std::exception& err) { - LOGWARN("sPortId invalid paramater: %s ", sPortId.c_str()); - returnResponse(false); - } - bool result = setVRRSupport(portId, vrrSupport); - if(result == true) - { - returnResponse(true); - } - else - { - returnResponse(false); - } -} - -uint32_t AVInput::getVRRFrameRateWrapper(const JsonObject& parameters, JsonObject& response) -{ - LOGINFOMETHOD(); - returnIfParamNotFound(parameters, "portId"); - string sPortId = parameters["portId"].String(); - - int portId = 0; - dsHdmiInVrrStatus_t vrrStatus; - vrrStatus.vrrAmdfreesyncFramerate_Hz = 0; - - try { - portId = stoi(sPortId); - }catch (const std::exception& err) { - LOGWARN("sPortId invalid paramater: %s ", sPortId.c_str()); - returnResponse(false); - } - - bool result = getVRRStatus(portId, &vrrStatus); - if(result == true) - { - response["currentVRRVideoFrameRate"] = vrrStatus.vrrAmdfreesyncFramerate_Hz; - returnResponse(true); - } - else - { - returnResponse(false); - } -} - -uint32_t AVInput::setEdidVersionWrapper(const JsonObject& parameters, JsonObject& response) -{ - LOGINFOMETHOD(); - string sPortId = parameters["portId"].String(); - int portId = 0; - string sVersion = ""; - if (parameters.HasLabel("portId") && parameters.HasLabel("edidVersion")) + void AVInput::Deactivated(RPC::IRemoteConnection* connection) { - try { - portId = stoi(sPortId); - sVersion = parameters["edidVersion"].String(); - }catch (...) { - LOGWARN("Invalid Arguments"); - returnResponse(false); + if (connection->Id() == _connectionId) { + ASSERT(nullptr != _service); + Core::IWorkerPool::Instance().Submit(PluginHost::IShell::Job::Create(_service, PluginHost::IShell::DEACTIVATED, PluginHost::IShell::FAILURE)); } } - else { - LOGWARN("Required parameters are not passed"); - returnResponse(false); - } - - int edidVer = -1; - if (strcmp (sVersion.c_str(), "HDMI1.4") == 0) { - edidVer = HDMI_EDID_VER_14; - } - else if (strcmp (sVersion.c_str(), "HDMI2.0") == 0) { - edidVer = HDMI_EDID_VER_20; - } - - if (edidVer < 0) { - returnResponse(false); - } - bool result = setEdidVersion (portId, edidVer); - if (result == false) { - returnResponse(false); - } - else { - returnResponse(true); - } -} - -uint32_t AVInput::getHdmiVersionWrapper(const JsonObject& parameters, JsonObject& response) -{ - LOGINFOMETHOD(); - returnIfParamNotFound(parameters, "portId"); - string sPortId = parameters["portId"].String(); - int portId = 0; - - try { - portId = stoi(sPortId); - }catch (const std::exception& err) { - LOGWARN("sPortId invalid paramater: %s ", sPortId.c_str()); - returnResponse(false); - } - - dsHdmiMaxCapabilityVersion_t hdmiCapVersion = HDMI_COMPATIBILITY_VERSION_14; - - try { - device::HdmiInput::getInstance().getHdmiVersion(portId, &(hdmiCapVersion)); - LOGWARN("AVInput::getHdmiVersion Hdmi Version:%d", hdmiCapVersion); - } - catch (const device::Exception& err) { - LOG_DEVICE_EXCEPTION1(std::to_string(portId)); - returnResponse(false); - } - - switch ((int)hdmiCapVersion){ - case HDMI_COMPATIBILITY_VERSION_14: - response["HdmiCapabilityVersion"] = "1.4"; - break; - case HDMI_COMPATIBILITY_VERSION_20: - response["HdmiCapabilityVersion"] = "2.0"; - break; - case HDMI_COMPATIBILITY_VERSION_21: - response["HdmiCapabilityVersion"] = "2.1"; - break; - } - - - if(hdmiCapVersion == HDMI_COMPATIBILITY_VERSION_MAX) + void AVInput::Notification::OnDevicesChanged(Exchange::IAVInput::IInputDeviceIterator* const devices) + { + Core::JSON::ArrayType deviceArray; + if (devices != nullptr) { - returnResponse(false); - }else{ - returnResponse(true); - } -} + Exchange::IAVInput::InputDevice resultItem{}; -int AVInput::setEdidVersion(int iPort, int iEdidVer) -{ - bool ret = true; - try { - device::HdmiInput::getInstance().setEdidVersion (iPort, iEdidVer); - LOGWARN("AVInput::setEdidVersion EDID Version:%d", iEdidVer); - } - catch (const device::Exception& err) { - LOG_DEVICE_EXCEPTION1(std::to_string(iPort)); - ret = false; - } - return ret; -} + while (devices->Next(resultItem) == true) { deviceArray.Add() = resultItem; } -uint32_t AVInput::getEdidVersionWrapper(const JsonObject& parameters, JsonObject& response) -{ - string sPortId = parameters["portId"].String(); - int portId = 0; - - LOGINFOMETHOD(); - if (parameters.HasLabel("portId")) - { - try { - portId = stoi(sPortId); - } - catch (...) { - LOGWARN("Invalid Arguments"); - returnResponse(false); + Core::JSON::Container eventPayload; + eventPayload.Add(_T("deviceArray"), &deviceArray); + _parent.Notify(_T("onDevicesChanged"), eventPayload); } } - else { - LOGWARN("Required parameters are not passed"); - returnResponse(false); - } - - int edidVer = getEdidVersion (portId); - switch (edidVer) { - case HDMI_EDID_VER_14: - response["edidVersion"] = "HDMI1.4"; - break; - case HDMI_EDID_VER_20: - response["edidVersion"] = "HDMI2.0"; - break; - } - - if (edidVer < 0) { - returnResponse(false); - } - else { - returnResponse(true); - } -} - -int AVInput::getEdidVersion(int iPort) -{ - int edidVersion = -1; - - try { - device::HdmiInput::getInstance().getEdidVersion (iPort, &edidVersion); - LOGWARN("AVInput::getEdidVersion EDID Version:%d", edidVersion); - } - catch (const device::Exception& err) { - LOG_DEVICE_EXCEPTION1(std::to_string(iPort)); - } - return edidVersion; -} } // namespace Plugin } // namespace WPEFramework diff --git a/AVInput/AVInput.h b/AVInput/AVInput.h index b6c86142..b917f56b 100644 --- a/AVInput/AVInput.h +++ b/AVInput/AVInput.h @@ -2,7 +2,7 @@ * If not stated otherwise in this file or this component's LICENSE * file the following copyright and licenses apply: * - * Copyright 2020 RDK Management + * Copyright 2025 RDK Management * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,113 +20,148 @@ #pragma once #include "Module.h" -#include "libIBus.h" -#include "dsTypes.h" -#define DEFAULT_PRIM_VOL_LEVEL 25 -#define MAX_PRIM_VOL_LEVEL 100 -#define DEFAULT_INPUT_VOL_LEVEL 100 +#include +#include +#include +#include +#include "AVInputJsonData.h" +#include "AVInputUtils.h" + +#include "UtilsLogging.h" +#include "tracing/Logging.h" namespace WPEFramework { namespace Plugin { - -class AVInput: public PluginHost::IPlugin, public PluginHost::JSONRPC -{ -private: - AVInput(const AVInput &) = delete; - AVInput &operator=(const AVInput &) = delete; - -public: - AVInput(); - virtual ~AVInput(); - - BEGIN_INTERFACE_MAP(AVInput) - INTERFACE_ENTRY(PluginHost::IPlugin) - INTERFACE_ENTRY(PluginHost::IDispatcher) - END_INTERFACE_MAP - - int m_primVolume; - int m_inputVolume; //Player Volume - - dsVRRType_t m_currentVrrType; -public: - // IPlugin methods - // ------------------------------------------------------------------------------------------------------- - virtual const string Initialize(PluginHost::IShell *service) override; - virtual void Deinitialize(PluginHost::IShell *service) override; - virtual string Information() const override; - -protected: - void InitializeIARM(); - void DeinitializeIARM(); - - void RegisterAll(); - void UnregisterAll(); - - uint32_t endpoint_numberOfInputs(const JsonObject ¶meters, JsonObject &response); - uint32_t endpoint_currentVideoMode(const JsonObject ¶meters, JsonObject &response); - uint32_t endpoint_contentProtected(const JsonObject ¶meters, JsonObject &response); - -private: - static int numberOfInputs(bool &success); - static string currentVideoMode(bool &success); - - //Begin methods - uint32_t getInputDevicesWrapper(const JsonObject& parameters, JsonObject& response); - uint32_t writeEDIDWrapper(const JsonObject& parameters, JsonObject& response); - uint32_t readEDIDWrapper(const JsonObject& parameters, JsonObject& response); - uint32_t getRawSPDWrapper(const JsonObject& parameters, JsonObject& response); - uint32_t getSPDWrapper(const JsonObject& parameters, JsonObject& response); - uint32_t setEdidVersionWrapper(const JsonObject& parameters, JsonObject& response); - uint32_t getEdidVersionWrapper(const JsonObject& parameters, JsonObject& response); - uint32_t setEdid2AllmSupportWrapper(const JsonObject& parameters, JsonObject& response); - uint32_t getEdid2AllmSupportWrapper(const JsonObject& parameters, JsonObject& response); - uint32_t setVRRSupportWrapper(const JsonObject& parameters, JsonObject& response); - uint32_t getVRRSupportWrapper(const JsonObject& parameters, JsonObject& response); - uint32_t getVRRFrameRateWrapper(const JsonObject& parameters, JsonObject& response); - uint32_t startInput(const JsonObject& parameters, JsonObject& response); - uint32_t stopInput(const JsonObject& parameters, JsonObject& response); - uint32_t setVideoRectangleWrapper(const JsonObject& parameters, JsonObject& response); - uint32_t getSupportedGameFeatures(const JsonObject& parameters, JsonObject& response); - uint32_t getGameFeatureStatusWrapper(const JsonObject& parameters, JsonObject& response); - uint32_t setMixerLevels(const JsonObject& parameters, JsonObject& response); - uint32_t getHdmiVersionWrapper(const JsonObject& parameters, JsonObject& response); - //End methods - - JsonArray getInputDevices(int iType); - void writeEDID(int deviceId, std::string message); - std::string readEDID(int iPort); - std::string getRawSPD(int iPort); - std::string getSPD(int iPort); - int setEdidVersion(int iPort, int iEdidVer); - int getEdidVersion(int iPort); - bool setVRRSupport(int portId, bool vrrSupport); - bool getVRRSupport(int portId, bool *vrrSupportValue); - bool setVideoRectangle(int x, int y, int width, int height, int type); - bool getALLMStatus(int iPort); - bool getVRRStatus(int iPort, dsHdmiInVrrStatus_t *vrrStatus); - - void AVInputHotplug(int input , int connect, int type); - void AVInputVRRChange( int port , dsVRRType_t vrr_type, bool vrr_mode); - static void dsAVEventHandler(const char *owner, IARM_EventId_t eventId, void *data, size_t len); - - void AVInputSignalChange( int port , int signalStatus, int type); - static void dsAVSignalStatusEventHandler(const char *owner, IARM_EventId_t eventId, void *data, size_t len); - - void AVInputStatusChange( int port , bool isPresented, int type); - static void dsAVStatusEventHandler(const char *owner, IARM_EventId_t eventId, void *data, size_t len); - - void AVInputVideoModeUpdate( int port , dsVideoPortResolution_t resolution,int type); - static void dsAVVideoModeEventHandler(const char *owner, IARM_EventId_t eventId, void *data, size_t len); - - void AVInputALLMChange( int port , bool allmMode); - static void dsAVGameFeatureStatusEventHandler(const char *owner, IARM_EventId_t eventId, void *data, size_t len); - - void hdmiInputAviContentTypeChange(int port, int content_type); - static void dsAviContentTypeEventHandler(const char *owner, IARM_EventId_t eventId, void *data, size_t len); -public: - static AVInput* _instance; -}; - + + class AVInput : public PluginHost::IPlugin, public PluginHost::JSONRPC { + + public: + + AVInput(const AVInput&) = delete; + AVInput& operator=(const AVInput&) = delete; + + AVInput(); + virtual ~AVInput(); + + BEGIN_INTERFACE_MAP(AVInput) + INTERFACE_ENTRY(PluginHost::IPlugin) + INTERFACE_ENTRY(PluginHost::IDispatcher) + INTERFACE_AGGREGATE(Exchange::IAVInput, _avInput) + END_INTERFACE_MAP + + // IPlugin methods + // ------------------------------------------------------------------------------------------------------- + const string Initialize(PluginHost::IShell* service) override; + void Deinitialize(PluginHost::IShell* service) override; + string Information() const override; + + protected: + + void RegisterAll(); + void UnregisterAll(); + + private: + + PluginHost::IShell* _service {}; + uint32_t _connectionId {}; + Exchange::IAVInput* _avInput {}; + + class Notification : public RPC::IRemoteConnection::INotification, + public Exchange::IAVInput::IDevicesChangedNotification, + public Exchange::IAVInput::ISignalChangedNotification, + public Exchange::IAVInput::IInputStatusChangedNotification, + public Exchange::IAVInput::IVideoStreamInfoUpdateNotification, + public Exchange::IAVInput::IGameFeatureStatusUpdateNotification, + public Exchange::IAVInput::IHdmiContentTypeUpdateNotification { + + public: + + explicit Notification(AVInput* parent) + : _parent(*parent) + { + ASSERT(parent != nullptr); + } + + virtual ~Notification() + { + } + + template + T* baseInterface() + { + static_assert(std::is_base_of(), "base type mismatch"); + return static_cast(this); + } + + BEGIN_INTERFACE_MAP(Notification) + INTERFACE_ENTRY(Exchange::IAVInput::IDevicesChangedNotification) + INTERFACE_ENTRY(Exchange::IAVInput::ISignalChangedNotification) + INTERFACE_ENTRY(Exchange::IAVInput::IInputStatusChangedNotification) + INTERFACE_ENTRY(Exchange::IAVInput::IVideoStreamInfoUpdateNotification) + INTERFACE_ENTRY(Exchange::IAVInput::IGameFeatureStatusUpdateNotification) + INTERFACE_ENTRY(Exchange::IAVInput::IHdmiContentTypeUpdateNotification) + INTERFACE_ENTRY(RPC::IRemoteConnection::INotification) + END_INTERFACE_MAP + + void Activated(RPC::IRemoteConnection*) override + { + } + + void Deactivated(RPC::IRemoteConnection* connection) override + { + _parent.Deactivated(connection); + } + + void OnDevicesChanged(Exchange::IAVInput::IInputDeviceIterator* const devices) override; + + void OnSignalChanged(const int id, const string& locator, const string& signalStatus) override + { + LOGINFO("OnSignalChanged: id %d, locator %s, status %s\n", id, locator.c_str(), signalStatus.c_str()); + Exchange::JAVInput::Event::OnSignalChanged(_parent, id, locator, signalStatus); + } + + void OnInputStatusChanged(const int id, const string& locator, const string& status, const int plane) override + { + LOGINFO("OnInputStatusChanged: id %d, locator %s, status %s, plane %d\n", id, locator.c_str(), status.c_str(), plane); + Exchange::JAVInput::Event::OnInputStatusChanged(_parent, id, locator, status, plane); + } + + void VideoStreamInfoUpdate(const int id, const string& locator, const int width, const int height, const bool progressive, const int frameRateN, const int frameRateD) override + { + LOGINFO("VideoStreamInfoUpdate: id %d, width %d, height %d, frameRateN %d, frameRateD %d, progressive %d, locator %s\n", + id, width, height, frameRateN, frameRateD, progressive, locator.c_str()); + Exchange::JAVInput::Event::VideoStreamInfoUpdate(_parent, id, locator, width, height, progressive, frameRateN, frameRateD); + } + + void GameFeatureStatusUpdate(const int id, const string& gameFeature, const bool mode) override + { + LOGINFO("GameFeatureStatusUpdate: id %d, gameFeature %s, mode %d\n", + id, gameFeature.c_str(), static_cast(mode)); + Exchange::JAVInput::Event::GameFeatureStatusUpdate(_parent, id, gameFeature, mode); + } + + void HdmiContentTypeUpdate(const int id, const int aviContentType) override + { + LOGINFO("HdmiContentTypeUpdate: id %d, contentType %d\n", id, aviContentType); + Exchange::JAVInput::Event::HdmiContentTypeUpdate(_parent, id, aviContentType); + } + + private: + AVInput& _parent; + + Notification() = delete; + Notification(const Notification&) = delete; + Notification& operator=(const Notification&) = delete; + }; + + Core::Sink _avInputNotification; + + void Deactivated(RPC::IRemoteConnection* connection); + + JsonArray getInputDevices(int iType); + uint32_t getInputDevicesWrapper(const JsonObject& parameters, JsonObject& response); + + }; // AVInput } // namespace Plugin } // namespace WPEFramework diff --git a/AVInput/AVInputImplementation.cpp b/AVInput/AVInputImplementation.cpp new file mode 100644 index 00000000..db6824f8 --- /dev/null +++ b/AVInput/AVInputImplementation.cpp @@ -0,0 +1,1573 @@ +/** + * If not stated otherwise in this file or this component's LICENSE + * file the following copyright and licenses apply: + * + * Copyright 2025 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +#include "AVInputImplementation.h" +#include +#include +#include + +#include "UtilsJsonRpc.h" + +#define STR_ALLM "ALLM" +#define VRR_TYPE_HDMI "VRR-HDMI" +#define VRR_TYPE_FREESYNC "VRR-FREESYNC" +#define VRR_TYPE_FREESYNC_PREMIUM "VRR-FREESYNC-PREMIUM" +#define VRR_TYPE_FREESYNC_PREMIUM_PRO "VRR-FREESYNC-PREMIUM-PRO" + +#define AV_HOT_PLUG_EVENT_CONNECTED 0 +#define AV_HOT_PLUG_EVENT_DISCONNECTED 1 + +static bool isAudioBalanceSet = false; +static int planeType = 0; + +using namespace std; + +namespace WPEFramework { +namespace Plugin { + SERVICE_REGISTRATION(AVInputImplementation, 1, 0); + AVInputImplementation* AVInputImplementation::_instance = nullptr; + + AVInputImplementation::AVInputImplementation() + : _adminLock() + , _service(nullptr) + { + LOGINFO("Create AVInputImplementation Instance"); + AVInputImplementation::_instance = this; + InitializeIARM(); + } + + AVInputImplementation::~AVInputImplementation() + { + DeinitializeIARM(); + AVInputImplementation::_instance = nullptr; + _service = nullptr; + } + + void AVInputImplementation::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, + dsAVEventHandler)); + IARM_CHECK(IARM_Bus_RegisterEventHandler( + IARM_BUS_DSMGR_NAME, + IARM_BUS_DSMGR_EVENT_HDMI_IN_SIGNAL_STATUS, + dsAVSignalStatusEventHandler)); + IARM_CHECK(IARM_Bus_RegisterEventHandler( + IARM_BUS_DSMGR_NAME, + IARM_BUS_DSMGR_EVENT_HDMI_IN_STATUS, + dsAVStatusEventHandler)); + IARM_CHECK(IARM_Bus_RegisterEventHandler( + IARM_BUS_DSMGR_NAME, + IARM_BUS_DSMGR_EVENT_HDMI_IN_VIDEO_MODE_UPDATE, + dsAVVideoModeEventHandler)); + IARM_CHECK(IARM_Bus_RegisterEventHandler( + IARM_BUS_DSMGR_NAME, + IARM_BUS_DSMGR_EVENT_HDMI_IN_ALLM_STATUS, + dsAVGameFeatureStatusEventHandler)); + IARM_CHECK(IARM_Bus_RegisterEventHandler( + IARM_BUS_DSMGR_NAME, + IARM_BUS_DSMGR_EVENT_HDMI_IN_VRR_STATUS, + dsAVGameFeatureStatusEventHandler)); + IARM_CHECK(IARM_Bus_RegisterEventHandler( + IARM_BUS_DSMGR_NAME, + IARM_BUS_DSMGR_EVENT_COMPOSITE_IN_HOTPLUG, + dsAVEventHandler)); + IARM_CHECK(IARM_Bus_RegisterEventHandler( + IARM_BUS_DSMGR_NAME, + IARM_BUS_DSMGR_EVENT_COMPOSITE_IN_SIGNAL_STATUS, + dsAVSignalStatusEventHandler)); + IARM_CHECK(IARM_Bus_RegisterEventHandler( + IARM_BUS_DSMGR_NAME, + IARM_BUS_DSMGR_EVENT_COMPOSITE_IN_STATUS, + dsAVStatusEventHandler)); + IARM_CHECK(IARM_Bus_RegisterEventHandler( + IARM_BUS_DSMGR_NAME, + IARM_BUS_DSMGR_EVENT_COMPOSITE_IN_VIDEO_MODE_UPDATE, + dsAVVideoModeEventHandler)); + IARM_CHECK(IARM_Bus_RegisterEventHandler( + IARM_BUS_DSMGR_NAME, + IARM_BUS_DSMGR_EVENT_HDMI_IN_AVI_CONTENT_TYPE, + dsAviContentTypeEventHandler)); + } + } + + void AVInputImplementation::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, dsAVEventHandler)); + IARM_CHECK(IARM_Bus_RemoveEventHandler( + IARM_BUS_DSMGR_NAME, + IARM_BUS_DSMGR_EVENT_HDMI_IN_SIGNAL_STATUS, dsAVSignalStatusEventHandler)); + IARM_CHECK(IARM_Bus_RemoveEventHandler( + IARM_BUS_DSMGR_NAME, + IARM_BUS_DSMGR_EVENT_HDMI_IN_STATUS, dsAVStatusEventHandler)); + IARM_CHECK(IARM_Bus_RemoveEventHandler( + IARM_BUS_DSMGR_NAME, + IARM_BUS_DSMGR_EVENT_HDMI_IN_VIDEO_MODE_UPDATE, dsAVVideoModeEventHandler)); + IARM_CHECK(IARM_Bus_RemoveEventHandler( + IARM_BUS_DSMGR_NAME, + IARM_BUS_DSMGR_EVENT_HDMI_IN_ALLM_STATUS, dsAVGameFeatureStatusEventHandler)); + IARM_CHECK(IARM_Bus_RemoveEventHandler( + IARM_BUS_DSMGR_NAME, + IARM_BUS_DSMGR_EVENT_HDMI_IN_VRR_STATUS, dsAVGameFeatureStatusEventHandler)); + IARM_CHECK(IARM_Bus_RemoveEventHandler( + IARM_BUS_DSMGR_NAME, + IARM_BUS_DSMGR_EVENT_COMPOSITE_IN_HOTPLUG, dsAVEventHandler)); + IARM_CHECK(IARM_Bus_RemoveEventHandler( + IARM_BUS_DSMGR_NAME, + IARM_BUS_DSMGR_EVENT_COMPOSITE_IN_SIGNAL_STATUS, dsAVSignalStatusEventHandler)); + IARM_CHECK(IARM_Bus_RemoveEventHandler( + IARM_BUS_DSMGR_NAME, + IARM_BUS_DSMGR_EVENT_COMPOSITE_IN_STATUS, dsAVStatusEventHandler)); + IARM_CHECK(IARM_Bus_RemoveEventHandler( + IARM_BUS_DSMGR_NAME, + IARM_BUS_DSMGR_EVENT_COMPOSITE_IN_VIDEO_MODE_UPDATE, dsAVVideoModeEventHandler)); + IARM_CHECK(IARM_Bus_RemoveEventHandler( + IARM_BUS_DSMGR_NAME, + IARM_BUS_DSMGR_EVENT_HDMI_IN_AVI_CONTENT_TYPE, dsAviContentTypeEventHandler)); + } + } + + void AVInputImplementation::dsAviContentTypeEventHandler(const char* owner, IARM_EventId_t eventId, void* data, size_t len) + { + if (!AVInputImplementation::_instance) + return; + + if (IARM_BUS_DSMGR_EVENT_HDMI_IN_AVI_CONTENT_TYPE == eventId) { + IARM_Bus_DSMgr_EventData_t* eventData = (IARM_Bus_DSMgr_EventData_t*)data; + int hdmi_in_port = eventData->data.hdmi_in_content_type.port; + int avi_content_type = eventData->data.hdmi_in_content_type.aviContentType; + LOGINFO("Received IARM_BUS_DSMGR_EVENT_HDMI_IN_AVI_CONTENT_TYPE event port: %d, Content Type : %d", hdmi_in_port, avi_content_type); + + AVInputImplementation::_instance->hdmiInputAviContentTypeChange(hdmi_in_port, avi_content_type); + } + } + + void AVInputImplementation::dsAVEventHandler(const char* owner, IARM_EventId_t eventId, void* data, size_t len) + { + if (!AVInputImplementation::_instance) + return; + + IARM_Bus_DSMgr_EventData_t* eventData = (IARM_Bus_DSMgr_EventData_t*)data; + if (IARM_BUS_DSMGR_EVENT_HDMI_IN_HOTPLUG == eventId) { + int hdmiin_hotplug_port = eventData->data.hdmi_in_connect.port; + int hdmiin_hotplug_conn = eventData->data.hdmi_in_connect.isPortConnected; + LOGWARN("Received IARM_BUS_DSMGR_EVENT_HDMI_IN_HOTPLUG event data:%d", hdmiin_hotplug_port); + AVInputImplementation::_instance->AVInputHotplug(hdmiin_hotplug_port, hdmiin_hotplug_conn ? AV_HOT_PLUG_EVENT_CONNECTED : AV_HOT_PLUG_EVENT_DISCONNECTED, INPUT_TYPE_INT_HDMI); + } else if (IARM_BUS_DSMGR_EVENT_COMPOSITE_IN_HOTPLUG == eventId) { + int compositein_hotplug_port = eventData->data.composite_in_connect.port; + int compositein_hotplug_conn = eventData->data.composite_in_connect.isPortConnected; + LOGWARN("Received IARM_BUS_DSMGR_EVENT_COMPOSITE_IN_HOTPLUG event data:%d", compositein_hotplug_port); + AVInputImplementation::_instance->AVInputHotplug(compositein_hotplug_port, compositein_hotplug_conn ? AV_HOT_PLUG_EVENT_CONNECTED : AV_HOT_PLUG_EVENT_DISCONNECTED, INPUT_TYPE_INT_COMPOSITE); + } + } + + void AVInputImplementation::dsAVSignalStatusEventHandler(const char* owner, IARM_EventId_t eventId, void* data, size_t len) + { + if (!AVInputImplementation::_instance) + return; + IARM_Bus_DSMgr_EventData_t* eventData = (IARM_Bus_DSMgr_EventData_t*)data; + if (IARM_BUS_DSMGR_EVENT_HDMI_IN_SIGNAL_STATUS == eventId) { + int hdmi_in_port = eventData->data.hdmi_in_sig_status.port; + int hdmi_in_signal_status = eventData->data.hdmi_in_sig_status.status; + LOGWARN("Received IARM_BUS_DSMGR_EVENT_HDMI_IN_SIGNAL_STATUS event port: %d, signal status: %d", hdmi_in_port, hdmi_in_signal_status); + AVInputImplementation::_instance->AVInputSignalChange(hdmi_in_port, hdmi_in_signal_status, INPUT_TYPE_INT_HDMI); + } else if (IARM_BUS_DSMGR_EVENT_COMPOSITE_IN_SIGNAL_STATUS == eventId) { + int composite_in_port = eventData->data.composite_in_sig_status.port; + int composite_in_signal_status = eventData->data.composite_in_sig_status.status; + LOGWARN("Received IARM_BUS_DSMGR_EVENT_COMPOSITE_IN_SIGNAL_STATUS event port: %d, signal status: %d", composite_in_port, composite_in_signal_status); + AVInputImplementation::_instance->AVInputSignalChange(composite_in_port, composite_in_signal_status, INPUT_TYPE_INT_COMPOSITE); + } + } + + void AVInputImplementation::dsAVStatusEventHandler(const char* owner, IARM_EventId_t eventId, void* data, size_t len) + { + if (!AVInputImplementation::_instance) + return; + IARM_Bus_DSMgr_EventData_t* eventData = (IARM_Bus_DSMgr_EventData_t*)data; + if (IARM_BUS_DSMGR_EVENT_HDMI_IN_STATUS == eventId) { + int hdmi_in_port = eventData->data.hdmi_in_status.port; + bool hdmi_in_status = eventData->data.hdmi_in_status.isPresented; + LOGWARN("Received IARM_BUS_DSMGR_EVENT_HDMI_IN_STATUS event port: %d, started: %d", hdmi_in_port, hdmi_in_status); + AVInputImplementation::_instance->AVInputStatusChange(hdmi_in_port, hdmi_in_status, INPUT_TYPE_INT_HDMI); + } else if (IARM_BUS_DSMGR_EVENT_COMPOSITE_IN_STATUS == eventId) { + int composite_in_port = eventData->data.composite_in_status.port; + bool composite_in_status = eventData->data.composite_in_status.isPresented; + LOGWARN("Received IARM_BUS_DSMGR_EVENT_COMPOSITE_IN_STATUS event port: %d, started: %d", composite_in_port, composite_in_status); + AVInputImplementation::_instance->AVInputStatusChange(composite_in_port, composite_in_status, INPUT_TYPE_INT_COMPOSITE); + } + } + + void AVInputImplementation::dsAVVideoModeEventHandler(const char* owner, IARM_EventId_t eventId, void* data, size_t len) + { + if (!AVInputImplementation::_instance) + return; + + if (IARM_BUS_DSMGR_EVENT_HDMI_IN_VIDEO_MODE_UPDATE == eventId) { + IARM_Bus_DSMgr_EventData_t* eventData = (IARM_Bus_DSMgr_EventData_t*)data; + int hdmi_in_port = eventData->data.hdmi_in_video_mode.port; + dsVideoPortResolution_t resolution = {}; + resolution.pixelResolution = eventData->data.hdmi_in_video_mode.resolution.pixelResolution; + resolution.interlaced = eventData->data.hdmi_in_video_mode.resolution.interlaced; + resolution.frameRate = eventData->data.hdmi_in_video_mode.resolution.frameRate; + LOGWARN("Received IARM_BUS_DSMGR_EVENT_HDMI_IN_VIDEO_MODE_UPDATE event port: %d, pixelResolution: %d, interlaced : %d, frameRate: %d \n", hdmi_in_port, resolution.pixelResolution, resolution.interlaced, resolution.frameRate); + AVInputImplementation::_instance->AVInputVideoModeUpdate(hdmi_in_port, resolution, INPUT_TYPE_INT_HDMI); + } else if (IARM_BUS_DSMGR_EVENT_COMPOSITE_IN_VIDEO_MODE_UPDATE == eventId) { + IARM_Bus_DSMgr_EventData_t* eventData = (IARM_Bus_DSMgr_EventData_t*)data; + int composite_in_port = eventData->data.composite_in_video_mode.port; + dsVideoPortResolution_t resolution = {}; + resolution.pixelResolution = eventData->data.composite_in_video_mode.resolution.pixelResolution; + resolution.interlaced = eventData->data.composite_in_video_mode.resolution.interlaced; + resolution.frameRate = eventData->data.composite_in_video_mode.resolution.frameRate; + LOGWARN("Received IARM_BUS_DSMGR_EVENT_COMPOSITE_IN_VIDEO_MODE_UPDATE event port: %d, pixelResolution: %d, interlaced : %d, frameRate: %d \n", composite_in_port, resolution.pixelResolution, resolution.interlaced, resolution.frameRate); + AVInputImplementation::_instance->AVInputVideoModeUpdate(composite_in_port, resolution, INPUT_TYPE_INT_COMPOSITE); + } + } + + void AVInputImplementation::dsAVGameFeatureStatusEventHandler(const char* owner, IARM_EventId_t eventId, void* data, size_t len) + { + if (!AVInputImplementation::_instance) + return; + + if (IARM_BUS_DSMGR_EVENT_HDMI_IN_ALLM_STATUS == eventId) { + IARM_Bus_DSMgr_EventData_t* eventData = (IARM_Bus_DSMgr_EventData_t*)data; + int hdmi_in_port = eventData->data.hdmi_in_allm_mode.port; + bool allm_mode = eventData->data.hdmi_in_allm_mode.allm_mode; + LOGWARN("Received IARM_BUS_DSMGR_EVENT_HDMI_IN_ALLM_STATUS event port: %d, ALLM Mode: %d", hdmi_in_port, allm_mode); + + AVInputImplementation::_instance->AVInputALLMChange(hdmi_in_port, allm_mode); + } + if (IARM_BUS_DSMGR_EVENT_HDMI_IN_VRR_STATUS == eventId) { + IARM_Bus_DSMgr_EventData_t* eventData = (IARM_Bus_DSMgr_EventData_t*)data; + int hdmi_in_port = eventData->data.hdmi_in_vrr_mode.port; + dsVRRType_t new_vrrType = eventData->data.hdmi_in_vrr_mode.vrr_type; + LOGWARN("Received IARM_BUS_DSMGR_EVENT_HDMI_IN_VRR_STATUS event port: %d, VRR Type: %d", hdmi_in_port, new_vrrType); + + if (new_vrrType == dsVRR_NONE) { + if (AVInputImplementation::_instance->m_currentVrrType != dsVRR_NONE) { + AVInputImplementation::_instance->AVInputVRRChange(hdmi_in_port, AVInputImplementation::_instance->m_currentVrrType, false); + } + } else { + if (AVInputImplementation::_instance->m_currentVrrType != dsVRR_NONE) { + AVInputImplementation::_instance->AVInputVRRChange(hdmi_in_port, AVInputImplementation::_instance->m_currentVrrType, false); + } + AVInputImplementation::_instance->AVInputVRRChange(hdmi_in_port, new_vrrType, true); + } + AVInputImplementation::_instance->m_currentVrrType = new_vrrType; + } + } + + template + Core::hresult AVInputImplementation::Register(std::list& list, T* notification) + { + uint32_t status = Core::ERROR_GENERAL; + + ASSERT(nullptr != notification); + _adminLock.Lock(); + + // Make sure we can't register the same notification callback multiple times + if (std::find(list.begin(), list.end(), notification) == list.end()) { + list.push_back(notification); + notification->AddRef(); + status = Core::ERROR_NONE; + } + + _adminLock.Unlock(); + return status; + } + + template + Core::hresult AVInputImplementation::Unregister(std::list& list, T* notification) + { + uint32_t status = Core::ERROR_GENERAL; + + ASSERT(nullptr != notification); + _adminLock.Lock(); + + // Make sure we can't unregister the same notification callback multiple times + auto itr = std::find(list.begin(), list.end(), notification); + if (itr != list.end()) { + (*itr)->Release(); + list.erase(itr); + status = Core::ERROR_NONE; + } + + _adminLock.Unlock(); + return status; + } + + Core::hresult AVInputImplementation::Register(Exchange::IAVInput::IDevicesChangedNotification* notification) + { + Core::hresult errorCode = Register(_devicesChangedNotifications, notification); + LOGINFO("IDevicesChangedNotification %p, errorCode: %u", notification, errorCode); + return errorCode; + } + + Core::hresult AVInputImplementation::Unregister(Exchange::IAVInput::IDevicesChangedNotification* notification) + { + Core::hresult errorCode = Unregister(_devicesChangedNotifications, notification); + LOGINFO("IDevicesChangedNotification %p, errorCode: %u", notification, errorCode); + return errorCode; + } + + Core::hresult AVInputImplementation::Register(Exchange::IAVInput::ISignalChangedNotification* notification) + { + Core::hresult errorCode = Register(_signalChangedNotifications, notification); + LOGINFO("ISignalChangedNotification %p, errorCode: %u", notification, errorCode); + return errorCode; + } + + Core::hresult AVInputImplementation::Unregister(Exchange::IAVInput::ISignalChangedNotification* notification) + { + Core::hresult errorCode = Unregister(_signalChangedNotifications, notification); + LOGINFO("ISignalChangedNotification %p, errorCode: %u", notification, errorCode); + return errorCode; + } + + Core::hresult AVInputImplementation::Register(Exchange::IAVInput::IInputStatusChangedNotification* notification) + { + Core::hresult errorCode = Register(_inputStatusChangedNotifications, notification); + LOGINFO("IInputStatusChangedNotification %p, errorCode: %u", notification, errorCode); + return errorCode; + } + + Core::hresult AVInputImplementation::Unregister(Exchange::IAVInput::IInputStatusChangedNotification* notification) + { + Core::hresult errorCode = Unregister(_inputStatusChangedNotifications, notification); + LOGINFO("IInputStatusChangedNotification %p, errorCode: %u", notification, errorCode); + return errorCode; + } + + Core::hresult AVInputImplementation::Register(Exchange::IAVInput::IVideoStreamInfoUpdateNotification* notification) + { + Core::hresult errorCode = Register(_videoStreamInfoUpdateNotifications, notification); + LOGINFO("IVideoStreamInfoUpdateNotification %p, errorCode: %u", notification, errorCode); + return errorCode; + } + + Core::hresult AVInputImplementation::Unregister(Exchange::IAVInput::IVideoStreamInfoUpdateNotification* notification) + { + Core::hresult errorCode = Unregister(_videoStreamInfoUpdateNotifications, notification); + LOGINFO("IVideoStreamInfoUpdateNotification %p, errorCode: %u", notification, errorCode); + return errorCode; + } + + Core::hresult AVInputImplementation::Register(Exchange::IAVInput::IGameFeatureStatusUpdateNotification* notification) + { + Core::hresult errorCode = Register(_gameFeatureStatusUpdateNotifications, notification); + LOGINFO("IGameFeatureStatusUpdateNotification %p, errorCode: %u", notification, errorCode); + return errorCode; + } + + Core::hresult AVInputImplementation::Unregister(Exchange::IAVInput::IGameFeatureStatusUpdateNotification* notification) + { + Core::hresult errorCode = Unregister(_gameFeatureStatusUpdateNotifications, notification); + LOGINFO("IGameFeatureStatusUpdateNotification %p, errorCode: %u", notification, errorCode); + return errorCode; + } + + Core::hresult AVInputImplementation::Register(Exchange::IAVInput::IHdmiContentTypeUpdateNotification* notification) + { + Core::hresult errorCode = Register(_hdmiContentTypeUpdateNotifications, notification); + LOGINFO("IHdmiContentTypeUpdateNotification %p, errorCode: %u", notification, errorCode); + return errorCode; + } + + Core::hresult AVInputImplementation::Unregister(Exchange::IAVInput::IHdmiContentTypeUpdateNotification* notification) + { + Core::hresult errorCode = Unregister(_hdmiContentTypeUpdateNotifications, notification); + LOGINFO("IHdmiContentTypeUpdateNotification %p, errorCode: %u", notification, errorCode); + return errorCode; + } + + void AVInputImplementation::dispatchEvent(Event event, const ParamsType params) + { + Core::IWorkerPool::Instance().Submit(Job::Create(this, event, params)); + } + + void AVInputImplementation::Dispatch(Event event, const ParamsType params) + { + using namespace WPEFramework::Exchange; + + _adminLock.Lock(); + + switch (event) { + case ON_AVINPUT_DEVICES_CHANGED: { + + if (auto* const devices = boost::get(¶ms)) { + LOGINFO("ON_AVINPUT_DEVICES_CHANGED"); + + std::list::const_iterator index(_devicesChangedNotifications.begin()); + + while (index != _devicesChangedNotifications.end()) { + (*index)->OnDevicesChanged(*devices); + ++index; + } + } + break; + } + case ON_AVINPUT_SIGNAL_CHANGED: { + + if (const auto* tupleValue = boost::get>(¶ms)) { + int id = std::get<0>(*tupleValue); + string locator = std::get<1>(*tupleValue); + string signalStatus = std::get<2>(*tupleValue); + + std::list::const_iterator index(_signalChangedNotifications.begin()); + + while (index != _signalChangedNotifications.end()) { + (*index)->OnSignalChanged(id, locator, signalStatus); + ++index; + } + } + break; + } + case ON_AVINPUT_STATUS_CHANGED: { + + if (const auto* tupleValue = boost::get>(¶ms)) { + int id = std::get<0>(*tupleValue); + string locator = std::get<1>(*tupleValue); + string status = std::get<2>(*tupleValue); + int plane = std::get<3>(*tupleValue); + + std::list::const_iterator index(_inputStatusChangedNotifications.begin()); + + while (index != _inputStatusChangedNotifications.end()) { + (*index)->OnInputStatusChanged(id, locator, status, plane); + ++index; + } + } + break; + } + case ON_AVINPUT_VIDEO_STREAM_INFO_UPDATE: { + if (const auto* tupleValue = boost::get>(¶ms)) { + int id = std::get<0>(*tupleValue); + string locator = std::get<1>(*tupleValue); + int width = std::get<2>(*tupleValue); + int height = std::get<3>(*tupleValue); + bool progressive = std::get<4>(*tupleValue); + int frameRateN = std::get<5>(*tupleValue); + int frameRateD = std::get<6>(*tupleValue); + + std::list::const_iterator index(_videoStreamInfoUpdateNotifications.begin()); + + while (index != _videoStreamInfoUpdateNotifications.end()) { + (*index)->VideoStreamInfoUpdate(id, locator, width, height, progressive, frameRateN, frameRateD); + ++index; + } + } + break; + } + case ON_AVINPUT_GAME_FEATURE_STATUS_UPDATE: { + if (const auto* tupleValue = boost::get>(¶ms)) { + int id = std::get<0>(*tupleValue); + string gameFeature = std::get<1>(*tupleValue); + bool mode = std::get<2>(*tupleValue); + + std::list::const_iterator index(_gameFeatureStatusUpdateNotifications.begin()); + + while (index != _gameFeatureStatusUpdateNotifications.end()) { + (*index)->GameFeatureStatusUpdate(id, gameFeature, mode); + ++index; + } + } + break; + } + case ON_AVINPUT_AVI_CONTENT_TYPE_UPDATE: { + if (const auto* tupleValue = boost::get>(¶ms)) { + int id = std::get<0>(*tupleValue); + int aviContentType = std::get<1>(*tupleValue); + + std::list::const_iterator index(_hdmiContentTypeUpdateNotifications.begin()); + + while (index != _hdmiContentTypeUpdateNotifications.end()) { + (*index)->HdmiContentTypeUpdate(id, aviContentType); + ++index; + } + } + break; + } + + default: { + LOGWARN("Event[%u] not handled", event); + break; + } + } + _adminLock.Unlock(); + } + + Core::hresult AVInputImplementation::ContentProtected(bool& isContentProtected, bool& success) + { + // "This is the way it's done in Service Manager" + isContentProtected = true; + success = true; + return Core::ERROR_NONE; + } + + Core::hresult AVInputImplementation::NumberOfInputs(uint32_t& numberOfInputs, bool& success) + { + try { + numberOfInputs = device::HdmiInput::getInstance().getNumberOfInputs(); + } catch (...) { + LOGERR("Exception caught"); + success = false; + return Core::ERROR_GENERAL; + } + + success = true; + return Core::ERROR_NONE; + } + + Core::hresult AVInputImplementation::CurrentVideoMode(string& currentVideoMode, bool& success) + { + try { + currentVideoMode = device::HdmiInput::getInstance().getCurrentVideoMode(); + } catch (...) { + LOGERR("Exception caught"); + success = false; + return Core::ERROR_GENERAL; + } + + success = true; + return Core::ERROR_NONE; + } + + Core::hresult AVInputImplementation::StartInput(const string& portId, const string& typeOfInput, const bool requestAudioMix, const int plane, const bool topMost, SuccessResult& successResult) + { + int id; + + try { + id = stoi(portId); + } catch (const std::exception& err) { + LOGERR("StartInput: Invalid paramater: portId: %s ", portId.c_str()); + successResult.success = false; + return Core::ERROR_GENERAL; + } + + try { + switch(AVInputUtils::getTypeOfInput(typeOfInput)) { + case INPUT_TYPE_INT_HDMI: { + device::HdmiInput::getInstance().selectPort(id, requestAudioMix, plane, topMost); + break; + } + case INPUT_TYPE_INT_COMPOSITE: { + device::CompositeInput::getInstance().selectPort(id); + } + default: { + LOGWARN("Invalid input type passed to StartInput"); + successResult.success = false; + return Core::ERROR_GENERAL; + } + } + } catch(...) { + successResult.success = false; + return Core::ERROR_GENERAL; + } + + successResult.success = true; + return Core::ERROR_NONE; + } + + Core::hresult AVInputImplementation::StopInput(const string& typeOfInput, SuccessResult& successResult) + { + Core::hresult ret = Core::ERROR_NONE; + successResult.success = true; + + try { + planeType = -1; + if (isAudioBalanceSet) { + device::Host::getInstance().setAudioMixerLevels(dsAUDIO_INPUT_PRIMARY, MAX_PRIM_VOL_LEVEL); + device::Host::getInstance().setAudioMixerLevels(dsAUDIO_INPUT_SYSTEM, DEFAULT_INPUT_VOL_LEVEL); + isAudioBalanceSet = false; + } + + switch(AVInputUtils::getTypeOfInput(typeOfInput)) { + case INPUT_TYPE_INT_HDMI: { + device::HdmiInput::getInstance().selectPort(-1); + break; + } + case INPUT_TYPE_INT_COMPOSITE: { + device::CompositeInput::getInstance().selectPort(-1); + } + default: { + LOGWARN("Invalid input type passed to StopInput"); + successResult.success = false; + return Core::ERROR_GENERAL; + } + } + } catch (const device::Exception& err) { + LOGWARN("AVInputImplementation::StopInput Failed"); + successResult.success = false; + ret = Core::ERROR_GENERAL; + } + + return ret; + } + + Core::hresult AVInputImplementation::SetVideoRectangle(const uint16_t x, const uint16_t y, const uint16_t w, const uint16_t h, const string& typeOfInput, SuccessResult& successResult) + { + try { + switch(AVInputUtils::getTypeOfInput(typeOfInput)) { + case INPUT_TYPE_INT_HDMI: { + device::HdmiInput::getInstance().scaleVideo(x, y, w, h); + break; + } + case INPUT_TYPE_INT_COMPOSITE: { + device::CompositeInput::getInstance().scaleVideo(x, y, w, h); + } + default: { + successResult.success = false; + return Core::ERROR_GENERAL; + } + } + } catch(...) { + successResult.success = false; + return Core::ERROR_GENERAL; + } + + successResult.success = true; + return Core::ERROR_NONE; + } + + Core::hresult AVInputImplementation::getInputDevices(const string& typeOfInput, std::list &inputDeviceList) + { + int num = 0; + bool isHdmi = true; + + try { + switch(AVInputUtils::getTypeOfInput(typeOfInput)) { + case INPUT_TYPE_INT_HDMI: { + num = device::HdmiInput::getInstance().getNumberOfInputs(); + break; + } + case INPUT_TYPE_INT_COMPOSITE: { + num = device::CompositeInput::getInstance().getNumberOfInputs(); + isHdmi = false; + } + default: { + LOGERR("getInputDevices: Invalid input type"); + return Core::ERROR_GENERAL; + } + } + + if (num > 0) { + int i = 0; + for (i = 0; i < num; i++) { + // Input ID is aleays 0-indexed, continuous number starting 0 + WPEFramework::Exchange::IAVInput::InputDevice inputDevice; + + inputDevice.id = i; + std::stringstream locator; + if (isHdmi) { + locator << "hdmiin://localhost/deviceid/" << i; + inputDevice.connected = device::HdmiInput::getInstance().isPortConnected(i); + } else { + locator << "cvbsin://localhost/deviceid/" << i; + inputDevice.connected = device::CompositeInput::getInstance().isPortConnected(i); + } + inputDevice.locator = locator.str(); + LOGINFO("getInputDevices id %d, locator=[%s], connected=[%d]", i, inputDevice.locator.c_str(), inputDevice.connected); + inputDeviceList.push_back(inputDevice); + } + } + } catch (const std::exception& e) { + LOGERR("AVInputService::getInputDevices Failed"); + return Core::ERROR_GENERAL; + } + + return Core::ERROR_NONE; + } + + Core::hresult AVInputImplementation::GetInputDevices(const string& typeOfInput, IInputDeviceIterator*& devices, bool& success) + { + Core::hresult result; + std::list inputDeviceList; + success = false; + + try { + switch(AVInputUtils::getTypeOfInput(typeOfInput)) { + case INPUT_TYPE_INT_ALL: { + result = getInputDevices(INPUT_TYPE_HDMI, inputDeviceList); + if(result == Core::ERROR_NONE) { + result = getInputDevices(INPUT_TYPE_COMPOSITE, inputDeviceList); + } + break; + } + case INPUT_TYPE_INT_HDMI: + case INPUT_TYPE_INT_COMPOSITE: { + result = getInputDevices(typeOfInput, inputDeviceList); + } + default: { + LOGERR("GetInputDevices: Invalid input type"); + return Core::ERROR_GENERAL; + } + } + } catch(...) { + return Core::ERROR_GENERAL; + } + + if(Core::ERROR_NONE == result) { + devices = Core::Service>::Create(inputDeviceList); + success = true; + } + + return result; + } + + Core::hresult AVInputImplementation::WriteEDID(const string& portId, const string& message, SuccessResult& successResult) + { + try { + stoi(portId); + } catch (const std::exception& err) { + LOGERR("WriteEDID: Invalid paramater: portId: %s ", portId.c_str()); + successResult.success = false; + return Core::ERROR_GENERAL; + } + + // TODO: This wasn't implemented in the original code, do we want to implement it? + successResult.success = true; + return Core::ERROR_NONE; + } + + Core::hresult AVInputImplementation::ReadEDID(const string& portId, string& EDID, bool& success) + { + int id; + + try { + id = stoi(portId); + } catch (const std::exception& err) { + LOGERR("ReadEDID: Invalid paramater: portId: %s ", portId.c_str()); + success = false; + return Core::ERROR_GENERAL; + } + + vector edidVec({ 'u', 'n', 'k', 'n', 'o', 'w', 'n' }); + + try { + vector edidVec2; + device::HdmiInput::getInstance().getEDIDBytesInfo(id, edidVec2); + edidVec = edidVec2; // edidVec must be "unknown" unless we successfully get to this line + + // convert to base64 + uint16_t size = min(edidVec.size(), (size_t)numeric_limits::max()); + + if(0 == size) { + success = false; + return Core::ERROR_GENERAL; + } + + LOGWARN("AVInputImplementation::readEDID size:%d edidVec.size:%zu", size, edidVec.size()); + if (edidVec.size() > (size_t)numeric_limits::max()) { + LOGERR("Size too large to use ToString base64 wpe api"); + success = false; + return Core::ERROR_GENERAL; + } + Core::ToString((uint8_t*)&edidVec[0], size, true, EDID); + } catch (const device::Exception& err) { + LOG_DEVICE_EXCEPTION1(std::to_string(id)); + success = false; + return Core::ERROR_GENERAL; + } + + success = true; + return Core::ERROR_NONE; + } + + /** + * @brief This function is used to translate HDMI/COMPOSITE input hotplug to + * deviceChanged event. + * + * @param[in] input Number of input port integer. + * @param[in] connection status of input port integer. + */ + void AVInputImplementation::AVInputHotplug(int input, int connect, int type) + { + LOGWARN("AVInputHotplug [%d, %d, %d]", input, connect, type); + + IInputDeviceIterator* devices; + bool success; + + string typeOfInput; + + try { + typeOfInput = AVInputUtils::getTypeOfInput(type); + } catch(...) { + LOGERR("AVInputHotplug: Invalid input type"); + return; + } + + Core::hresult result = GetInputDevices(typeOfInput, devices, success); + if (Core::ERROR_NONE != result) { + LOGERR("AVInputHotplug [%d, %d, %d]: Failed to get devices", input, connect, type); + return; + } + + ParamsType params = devices; + dispatchEvent(ON_AVINPUT_DEVICES_CHANGED, params); + } + + /** + * @brief This function is used to translate HDMI/COMPOSITE input signal change to + * signalChanged event. + * + * @param[in] port HDMI/COMPOSITE In port id. + * @param[in] signalStatus signal status of HDMI/COMPOSITE In port. + * @param[in] type HDMI/COMPOSITE In type. + */ + void AVInputImplementation::AVInputSignalChange(int port, int signalStatus, int type) + { + LOGWARN("AVInputSignalStatus [%d, %d, %d]", port, signalStatus, type); + + string signalStatusStr; + + std::stringstream locator; + if (type == INPUT_TYPE_INT_HDMI) { + locator << "hdmiin://localhost/deviceid/" << port; + } else { + locator << "cvbsin://localhost/deviceid/" << port; + } + + /* values of dsHdmiInSignalStatus_t and dsCompInSignalStatus_t are same + Hence used only HDMI macro for case statement */ + switch (signalStatus) { + case dsHDMI_IN_SIGNAL_STATUS_NOSIGNAL: + signalStatusStr = "noSignal"; + break; + + case dsHDMI_IN_SIGNAL_STATUS_UNSTABLE: + signalStatusStr = "unstableSignal"; + break; + + case dsHDMI_IN_SIGNAL_STATUS_NOTSUPPORTED: + signalStatusStr = "notSupportedSignal"; + break; + + case dsHDMI_IN_SIGNAL_STATUS_STABLE: + signalStatusStr = "stableSignal"; + break; + + default: + signalStatusStr = "none"; + break; + } + + ParamsType params = std::make_tuple(port, locator.str(), signalStatusStr); + dispatchEvent(ON_AVINPUT_SIGNAL_CHANGED, params); + } + + /** + * @brief This function is used to translate HDMI/COMPOSITE input status change to + * inputStatusChanged event. + * + * @param[in] port HDMI/COMPOSITE In port id. + * @param[in] isPresented HDMI/COMPOSITE In presentation started/stopped. + * @param[in] type HDMI/COMPOSITE In type. + */ + void AVInputImplementation::AVInputStatusChange(int port, bool isPresented, int type) + { + LOGWARN("avInputStatus [%d, %d, %d]", port, isPresented, type); + + std::stringstream locator; + + if (type == INPUT_TYPE_INT_HDMI) { + locator << "hdmiin://localhost/deviceid/" << port; + } else if (type == INPUT_TYPE_INT_COMPOSITE) { + locator << "cvbsin://localhost/deviceid/" << port; + } + + string status = isPresented ? "started" : "stopped"; + ParamsType params = std::make_tuple(port, locator.str(), status, planeType); + dispatchEvent(ON_AVINPUT_STATUS_CHANGED, params); + } + + /** + * @brief This function is used to translate HDMI input video mode change to + * videoStreamInfoUpdate event. + * + * @param[in] port HDMI In port id. + * @param[in] resolution resolution of HDMI In port. + * @param[in] type HDMI/COMPOSITE In type. + */ + void AVInputImplementation::AVInputVideoModeUpdate(int port, dsVideoPortResolution_t resolution, int type) + { + int width; + int height; + bool progressive; + int frameRateN; + int frameRateD; + + std::stringstream locator; + + LOGWARN("AVInputVideoModeUpdate [%d]", port); + + if (type == INPUT_TYPE_INT_HDMI) { + locator << "hdmiin://localhost/deviceid/" << port; + + switch (resolution.pixelResolution) { + + case dsVIDEO_PIXELRES_720x480: + width = 720; + height = 480; + break; + + case dsVIDEO_PIXELRES_720x576: + width = 720; + height = 576; + break; + + case dsVIDEO_PIXELRES_1280x720: + width = 1280; + height = 720; + break; + + case dsVIDEO_PIXELRES_1920x1080: + width = 1920; + height = 1080; + break; + + case dsVIDEO_PIXELRES_3840x2160: + width = 3840; + height = 2160; + break; + + case dsVIDEO_PIXELRES_4096x2160: + width = 4096; + height = 2160; + break; + + default: + width = 1920; + height = 1080; + break; + } + + progressive = (!resolution.interlaced); + + } else if (type == INPUT_TYPE_INT_COMPOSITE) { + locator << "cvbsin://localhost/deviceid/" << port; + + switch (resolution.pixelResolution) { + case dsVIDEO_PIXELRES_720x480: + width = 720; + height = 480; + break; + + case dsVIDEO_PIXELRES_720x576: + width = 720; + height = 576; + break; + + default: + width = 720; + height = 576; + break; + } + + progressive = false; + } + + switch (resolution.frameRate) { + case dsVIDEO_FRAMERATE_24: + frameRateN = 24000; + frameRateD = 1000; + break; + + case dsVIDEO_FRAMERATE_25: + frameRateN = 25000; + frameRateD = 1000; + break; + + case dsVIDEO_FRAMERATE_30: + frameRateN = 30000; + frameRateD = 1000; + break; + + case dsVIDEO_FRAMERATE_50: + frameRateN = 50000; + frameRateD = 1000; + break; + + case dsVIDEO_FRAMERATE_60: + frameRateN = 60000; + frameRateD = 1000; + break; + + case dsVIDEO_FRAMERATE_23dot98: + frameRateN = 24000; + frameRateD = 1001; + break; + + case dsVIDEO_FRAMERATE_29dot97: + frameRateN = 30000; + frameRateD = 1001; + break; + + case dsVIDEO_FRAMERATE_59dot94: + frameRateN = 60000; + frameRateD = 1001; + break; + + case dsVIDEO_FRAMERATE_100: + frameRateN = 100000; + frameRateD = 1000; + break; + + case dsVIDEO_FRAMERATE_119dot88: + frameRateN = 120000; + frameRateD = 1001; + break; + + case dsVIDEO_FRAMERATE_120: + frameRateN = 120000; + frameRateD = 1000; + break; + + case dsVIDEO_FRAMERATE_200: + frameRateN = 200000; + frameRateD = 1000; + break; + + case dsVIDEO_FRAMERATE_239dot76: + frameRateN = 240000; + frameRateD = 1001; + break; + + case dsVIDEO_FRAMERATE_240: + frameRateN = 240000; + frameRateD = 1000; + break; + + default: + frameRateN = 60000; + frameRateD = 1000; + break; + } + + ParamsType params = std::make_tuple(port, locator.str(), width, height, progressive, frameRateN, frameRateD); + dispatchEvent(ON_AVINPUT_VIDEO_STREAM_INFO_UPDATE, params); + } + + + void AVInputImplementation::hdmiInputAviContentTypeChange(int port, int content_type) + { + ParamsType params = std::make_tuple(port, content_type); + dispatchEvent(ON_AVINPUT_AVI_CONTENT_TYPE_UPDATE, params); + } + + void AVInputImplementation::AVInputALLMChange(int port, bool allm_mode) + { + ParamsType params = std::make_tuple(port, STR_ALLM, allm_mode); + dispatchEvent(ON_AVINPUT_GAME_FEATURE_STATUS_UPDATE, params); + } + + void AVInputImplementation::AVInputVRRChange(int port, dsVRRType_t vrr_type, bool vrr_mode) + { + string gameFeature; + + switch (vrr_type) { + case dsVRR_HDMI_VRR: + gameFeature = VRR_TYPE_HDMI; + break; + case dsVRR_AMD_FREESYNC: + gameFeature = VRR_TYPE_FREESYNC; + break; + case dsVRR_AMD_FREESYNC_PREMIUM: + gameFeature = VRR_TYPE_FREESYNC_PREMIUM; + break; + case dsVRR_AMD_FREESYNC_PREMIUM_PRO: + gameFeature = VRR_TYPE_FREESYNC_PREMIUM_PRO; + break; + default: + break; + } + + ParamsType params = std::make_tuple(port, gameFeature, vrr_mode); + dispatchEvent(ON_AVINPUT_GAME_FEATURE_STATUS_UPDATE, params); + } + + Core::hresult AVInputImplementation::GetSupportedGameFeatures(IStringIterator*& features, bool& success) + { + Core::hresult result = Core::ERROR_NONE; + success = true; + features = nullptr; + std::vector supportedFeatures; + try { + device::HdmiInput::getInstance().getSupportedGameFeatures(supportedFeatures); + } catch (const device::Exception& err) { + LOG_DEVICE_EXCEPTION0(); + success = false; + result = Core::ERROR_GENERAL; + } + + if (!supportedFeatures.empty() && result == Core::ERROR_NONE) { + features = Core::Service>::Create(supportedFeatures); + } else { + success = false; + } + + return result; + } + + Core::hresult AVInputImplementation::GetGameFeatureStatus(const string& portId, const string& gameFeature, bool& mode, bool& success) + { + int id; + + try { + id = stoi(portId); + } catch (const std::exception& err) { + LOGERR("GetGameFeatureStatus: Invalid paramater: portId: %s ", portId.c_str()); + success = false; + return Core::ERROR_GENERAL; + } + + if (gameFeature == STR_ALLM) { + mode = getALLMStatus(id); + } else if (gameFeature == VRR_TYPE_HDMI) { + dsHdmiInVrrStatus_t vrrStatus; + getVRRStatus(id, &vrrStatus); + mode = (vrrStatus.vrrType == dsVRR_HDMI_VRR); + } else if (gameFeature == VRR_TYPE_FREESYNC) { + dsHdmiInVrrStatus_t vrrStatus; + getVRRStatus(id, &vrrStatus); + mode = (vrrStatus.vrrType == dsVRR_AMD_FREESYNC); + } else if (gameFeature == VRR_TYPE_FREESYNC_PREMIUM) { + dsHdmiInVrrStatus_t vrrStatus; + getVRRStatus(id, &vrrStatus); + mode = (vrrStatus.vrrType == dsVRR_AMD_FREESYNC_PREMIUM); + } else if (gameFeature == VRR_TYPE_FREESYNC_PREMIUM_PRO) { + dsHdmiInVrrStatus_t vrrStatus; + getVRRStatus(id, &vrrStatus); + mode = (vrrStatus.vrrType == dsVRR_AMD_FREESYNC_PREMIUM_PRO); + } else { + LOGWARN("AVInputImplementation::GetGameFeatureStatus Unsupported feature: %s", gameFeature.c_str()); + success = false; + return Core::ERROR_GENERAL; + } + + success = true; + return Core::ERROR_NONE; + } + + bool AVInputImplementation::getALLMStatus(int iPort) + { + bool allm = false; + + try { + device::HdmiInput::getInstance().getHdmiALLMStatus(iPort, &allm); + LOGWARN("AVInputImplementation::getALLMStatus ALLM MODE: %d", allm); + } catch (const device::Exception& err) { + LOG_DEVICE_EXCEPTION1(std::to_string(iPort)); + } + return allm; + } + + bool AVInputImplementation::getVRRStatus(int iPort, dsHdmiInVrrStatus_t* vrrStatus) + { + bool ret = true; + try { + device::HdmiInput::getInstance().getVRRStatus(iPort, vrrStatus); + LOGWARN("AVInputImplementation::getVRRStatus VRR TYPE: %d, VRR FRAMERATE: %f", vrrStatus->vrrType, vrrStatus->vrrAmdfreesyncFramerate_Hz); + } catch (const device::Exception& err) { + LOG_DEVICE_EXCEPTION1(std::to_string(iPort)); + ret = false; + } + return ret; + } + + Core::hresult AVInputImplementation::GetVRRFrameRate(const string& portId, double& currentVRRVideoFrameRate, bool& success) + { + int id; + + try { + id = stoi(portId); + } catch (const std::exception& err) { + LOGERR("GetVRRFrameRate: Invalid paramater: portId: %s ", portId.c_str()); + success = false; + return Core::ERROR_GENERAL; + } + + dsHdmiInVrrStatus_t vrrStatus; + vrrStatus.vrrAmdfreesyncFramerate_Hz = 0; + + success = getVRRStatus(id, &vrrStatus); + if(success == true) + { + currentVRRVideoFrameRate = vrrStatus.vrrAmdfreesyncFramerate_Hz; + } + + return success ? Core::ERROR_NONE : Core::ERROR_GENERAL; + } + + Core::hresult AVInputImplementation::GetRawSPD(const string& portId, string& HDMISPD, bool& success) + { + LOGINFO("AVInputImplementation::GetRawSPD"); + + int id; + + try { + id = stoi(portId); + } catch (const std::exception& err) { + LOGERR("GetRawSPD: Invalid paramater: portId: %s ", portId.c_str()); + success = false; + return Core::ERROR_GENERAL; + } + + vector spdVect({ 'u', 'n', 'k', 'n', 'o', 'w', 'n' }); + HDMISPD.clear(); + try { + LOGWARN("AVInputImplementation::getSPDInfo"); + vector spdVect2; + device::HdmiInput::getInstance().getHDMISPDInfo(id, spdVect2); + spdVect = spdVect2; // spdVect must be "unknown" unless we successfully get to this line + + // convert to base64 + uint16_t size = min(spdVect.size(), (size_t)numeric_limits::max()); + + LOGWARN("AVInputImplementation::getSPD size:%d spdVec.size:%zu", size, spdVect.size()); + + if (spdVect.size() > (size_t)numeric_limits::max()) { + LOGERR("Size too large to use ToString base64 wpe api"); + success = false; + return Core::ERROR_GENERAL; + } + + LOGINFO("------------getSPD: "); + for (size_t itr = 0; itr < spdVect.size(); itr++) { + LOGINFO("%02X ", spdVect[itr]); + } + Core::ToString((uint8_t*)&spdVect[0], size, false, HDMISPD); + } catch (const device::Exception& err) { + LOG_DEVICE_EXCEPTION1(std::to_string(id)); + success = false; + return Core::ERROR_GENERAL; + } + + success = true; + return Core::ERROR_NONE; + } + + Core::hresult AVInputImplementation::GetSPD(const string& portId, string& HDMISPD, bool& success) + { + int id; + + try { + id = stoi(portId); + } catch (const std::exception& err) { + LOGERR("GetSPD: Invalid paramater: portId: %s ", portId.c_str()); + success = false; + return Core::ERROR_GENERAL; + } + + vector spdVect({ 'u', 'n', 'k', 'n', 'o', 'w', 'n' }); + + LOGINFO("AVInputImplementation::GetSPD"); + + try { + vector spdVect2; + device::HdmiInput::getInstance().getHDMISPDInfo(id, spdVect2); + spdVect = spdVect2; // edidVec must be "unknown" unless we successfully get to this line + + // convert to base64 + uint16_t size = min(spdVect.size(), (size_t)numeric_limits::max()); + + LOGWARN("AVInputImplementation::GetSPD size:%d spdVec.size:%zu", size, spdVect.size()); + + if (spdVect.size() > (size_t)numeric_limits::max()) { + LOGERR("Size too large to use ToString base64 wpe api"); + success = false; + return Core::ERROR_GENERAL; + } + + LOGINFO("------------getSPD: "); + for (size_t itr = 0; itr < spdVect.size(); itr++) { + LOGINFO("%02X ", spdVect[itr]); + } + + if (spdVect.size() > 0) { + struct dsSpd_infoframe_st pre; + memcpy(&pre, spdVect.data(), sizeof(struct dsSpd_infoframe_st)); + + char str[200] = { 0 }; + snprintf(str, sizeof(str), "Packet Type:%02X,Version:%u,Length:%u,vendor name:%s,product des:%s,source info:%02X", + pre.pkttype, pre.version, pre.length, pre.vendor_name, pre.product_des, pre.source_info); + HDMISPD = str; + } + } catch (const device::Exception& err) { + LOG_DEVICE_EXCEPTION1(std::to_string(id)); + success = false; + return Core::ERROR_GENERAL; + } + + success = true; + return Core::ERROR_NONE; + } + + Core::hresult AVInputImplementation::SetMixerLevels(const int primaryVolume, const int inputVolume, SuccessResult& successResult) + { + try { + device::Host::getInstance().setAudioMixerLevels(dsAUDIO_INPUT_PRIMARY, primaryVolume); + device::Host::getInstance().setAudioMixerLevels(dsAUDIO_INPUT_SYSTEM, inputVolume); + } catch (...) { + LOGWARN("Not setting SoC volume !!!\n"); + successResult.success = false; + return Core::ERROR_GENERAL; + } + + isAudioBalanceSet = true; + successResult.success = true; + return Core::ERROR_NONE; + } + + Core::hresult AVInputImplementation::SetEdid2AllmSupport(const string& portId, const bool allmSupport, SuccessResult& successResult) + { + int id; + + try { + id = stoi(portId); + } catch (const std::exception& err) { + LOGERR("SetEdid2AllmSupport: Invalid paramater: portId: %s ", portId.c_str()); + successResult.success = false; + return Core::ERROR_GENERAL; + } + + try { + device::HdmiInput::getInstance().setEdid2AllmSupport(id, allmSupport); + LOGWARN("AVInput - allmsupport:%d", allmSupport); + } catch (const device::Exception& err) { + LOG_DEVICE_EXCEPTION1(std::to_string(id)); + successResult.success = false; + return Core::ERROR_GENERAL; + } + + successResult.success = true; + return Core::ERROR_NONE; + } + + Core::hresult AVInputImplementation::GetEdid2AllmSupport(const string& portId, bool& allmSupport, bool& success) + { + int id; + + try { + id = stoi(portId); + } catch (const std::exception& err) { + LOGERR("GetEdid2AllmSupport: Invalid paramater: portId: %s ", portId.c_str()); + success = false; + return Core::ERROR_GENERAL; + } + + allmSupport = true; + + try { + device::HdmiInput::getInstance().getEdid2AllmSupport(id, &allmSupport); + LOGINFO("AVInput - getEdid2AllmSupport:%d", allmSupport); + } catch (const device::Exception& err) { + LOG_DEVICE_EXCEPTION1(std::to_string(id)); + success = false; + return Core::ERROR_GENERAL; + } + + success = true; + return Core::ERROR_NONE; + } + + Core::hresult AVInputImplementation::GetVRRSupport(const string& portId, bool& vrrSupport, bool& success) + { + int id; + + try { + id = stoi(portId); + } catch (const std::exception& err) { + LOGERR("GetVRRSupport: Invalid paramater: portId: %s ", portId.c_str()); + success = false; + return Core::ERROR_GENERAL; + } + + vrrSupport = true; + + try { + device::HdmiInput::getInstance().getVRRSupport(id, &vrrSupport); + LOGINFO("AVInput - getVRRSupport:%d", vrrSupport); + } catch (const device::Exception& err) { + LOG_DEVICE_EXCEPTION1(std::to_string(id)); + success = false; + return Core::ERROR_GENERAL; + } + + success = true; + return Core::ERROR_NONE; + } + + Core::hresult AVInputImplementation::SetVRRSupport(const string& portId, const bool vrrSupport, SuccessResult& successResult) + { + int id; + + try { + id = stoi(portId); + } catch (const std::exception& err) { + LOGERR("SetVRRSupport: Invalid paramater: portId: %s ", portId.c_str()); + successResult.success = false; + return Core::ERROR_GENERAL; + } + + try { + device::HdmiInput::getInstance().setVRRSupport(id, vrrSupport); + LOGWARN("AVInput - vrrSupport:%d", vrrSupport); + } catch (const device::Exception& err) { + LOG_DEVICE_EXCEPTION1(std::to_string(id)); + successResult.success = false; + return Core::ERROR_GENERAL; + } + + successResult.success = true; + return Core::ERROR_NONE; + } + + Core::hresult AVInputImplementation::GetHdmiVersion(const string& portId, string& HdmiCapabilityVersion, bool& success) + { + int id; + + try { + id = stoi(portId); + } catch (const std::exception& err) { + LOGERR("GetHdmiVersion: Invalid paramater: portId: %s ", portId.c_str()); + success = false; + return Core::ERROR_GENERAL; + } + + dsHdmiMaxCapabilityVersion_t hdmiCapVersion = HDMI_COMPATIBILITY_VERSION_14; + + try { + device::HdmiInput::getInstance().getHdmiVersion(id, &hdmiCapVersion); + LOGWARN("AVInputImplementation::GetHdmiVersion Hdmi Version:%d", hdmiCapVersion); + } catch (const device::Exception& err) { + LOG_DEVICE_EXCEPTION1(std::to_string(id)); + success = false; + return Core::ERROR_GENERAL; + } + + switch ((int)hdmiCapVersion) { + case HDMI_COMPATIBILITY_VERSION_14: + HdmiCapabilityVersion = "1.4"; + success = true; + break; + case HDMI_COMPATIBILITY_VERSION_20: + HdmiCapabilityVersion = "2.0"; + success = true; + break; + case HDMI_COMPATIBILITY_VERSION_21: + HdmiCapabilityVersion = "2.1"; + success = true; + break; + default: + success = false; + return Core::ERROR_NONE; + } + + if (hdmiCapVersion == HDMI_COMPATIBILITY_VERSION_MAX) { + success = false; + return Core::ERROR_GENERAL; + } + + return Core::ERROR_NONE; + } + + Core::hresult AVInputImplementation::SetEdidVersion(const string& portId, const string& edidVersion, SuccessResult& successResult) + { + int id; + + try { + id = stoi(portId); + } catch (const std::exception& err) { + LOGERR("SetEdidVersion: Invalid paramater: portId: %s ", portId.c_str()); + successResult.success = false; + return Core::ERROR_GENERAL; + } + + int edidVer = -1; + + if (strcmp(edidVersion.c_str(), "HDMI1.4") == 0) { + edidVer = HDMI_EDID_VER_14; + } else if (strcmp(edidVersion.c_str(), "HDMI2.0") == 0) { + edidVer = HDMI_EDID_VER_20; + } else { + LOGERR("Invalid EDID Version: %s", edidVersion.c_str()); + successResult.success = false; + return Core::ERROR_GENERAL; + } + + try { + device::HdmiInput::getInstance().setEdidVersion(id, edidVer); + LOGWARN("AVInputImplementation::setEdidVersion EDID Version: %s", edidVersion.c_str()); + } catch (const device::Exception& err) { + LOG_DEVICE_EXCEPTION1(std::to_string(id)); + successResult.success = false; + return Core::ERROR_GENERAL; + } + + successResult.success = true; + return Core::ERROR_NONE; + } + + Core::hresult AVInputImplementation::GetEdidVersion(const string& portId, string& edidVersion, bool& success) + { + int id; + + try { + id = stoi(portId); + } catch (const std::exception& err) { + LOGERR("GetEdidVersion: Invalid paramater: portId: %s ", portId.c_str()); + success = false; + return Core::ERROR_GENERAL; + } + + int version = -1; + + try { + device::HdmiInput::getInstance().getEdidVersion(id, &version); + LOGWARN("AVInputImplementation::getEdidVersion EDID Version:%d", version); + } catch (const device::Exception& err) { + LOG_DEVICE_EXCEPTION1(std::to_string(id)); + success = false; + return Core::ERROR_GENERAL; + } + + switch (version) { + case HDMI_EDID_VER_14: + edidVersion = "HDMI1.4"; + break; + case HDMI_EDID_VER_20: + edidVersion = "HDMI2.0"; + break; + default: + success = false; + return Core::ERROR_GENERAL; + } + + success = true; + return Core::ERROR_NONE; + } + +} // namespace Plugin +} // namespace WPEFramework diff --git a/AVInput/AVInputImplementation.h b/AVInput/AVInputImplementation.h new file mode 100644 index 00000000..a33d3f86 --- /dev/null +++ b/AVInput/AVInputImplementation.h @@ -0,0 +1,222 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2025 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.Fv + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "Module.h" + +#include "UtilsIarm.h" +#include "UtilsJsonRpc.h" +#include "dsMgr.h" + +#include "compositeIn.hpp" +#include "exception.hpp" +#include "hdmiIn.hpp" +#include "host.hpp" + +#include +#include + +#include +#include + +#include +#include +#include + +#include "AVInputUtils.h" + +#define DEFAULT_PRIM_VOL_LEVEL 25 +#define MAX_PRIM_VOL_LEVEL 100 +#define DEFAULT_INPUT_VOL_LEVEL 100 + +using ParamsType = boost::variant< + WPEFramework::Exchange::IAVInput::IInputDeviceIterator* const, // OnDevicesChanged + std::tuple, // OnSignalChanged + std::tuple, // OnInputStatusChanged + std::tuple, // VideoStreamInfoUpdate + std::tuple, // GameFeatureStatusUpdate + std::tuple // HdmiContentTypeUpdate +>; + +namespace WPEFramework { +namespace Plugin { + + class AVInputImplementation : public Exchange::IAVInput { + + public: + + static AVInputImplementation* _instance; + dsVRRType_t m_currentVrrType; + friend class Job; + + // We do not allow this plugin to be copied !! + AVInputImplementation(); + ~AVInputImplementation() override; + + // We do not allow this plugin to be copied !! + AVInputImplementation(const AVInputImplementation&) = delete; + AVInputImplementation& operator=(const AVInputImplementation&) = delete; + + BEGIN_INTERFACE_MAP(AVInputImplementation) + INTERFACE_ENTRY(Exchange::IAVInput) + END_INTERFACE_MAP + + enum Event { + ON_AVINPUT_DEVICES_CHANGED, + ON_AVINPUT_SIGNAL_CHANGED, + ON_AVINPUT_STATUS_CHANGED, + ON_AVINPUT_VIDEO_STREAM_INFO_UPDATE, + ON_AVINPUT_GAME_FEATURE_STATUS_UPDATE, + ON_AVINPUT_AVI_CONTENT_TYPE_UPDATE + }; + + class EXTERNAL Job : public Core::IDispatch { + + public: + + Job() = delete; + Job(const Job&) = delete; + Job& operator=(const Job&) = delete; + ~Job() + { + if (_avInputImplementation != nullptr) { + _avInputImplementation->Release(); + } + } + + static Core::ProxyType Create(AVInputImplementation* avInputImplementation, Event event, ParamsType params) + { +#ifndef USE_THUNDER_R4 + return (Core::proxy_cast(Core::ProxyType::Create(avInputImplementation, event, params))); +#else + return (Core::ProxyType(Core::ProxyType::Create(avInputImplementation, event, params))); +#endif + } + + virtual void Dispatch() + { + _avInputImplementation->Dispatch(_event, _params); + } + + protected: + + Job(AVInputImplementation* avInputImplementation, Event event, ParamsType& params) + : _avInputImplementation(avInputImplementation) + , _event(event) + , _params(params) + { + if (_avInputImplementation != nullptr) { + _avInputImplementation->AddRef(); + } + } + + private: + + AVInputImplementation* _avInputImplementation; + const Event _event; + ParamsType _params; + }; + + virtual Core::hresult Register(Exchange::IAVInput::IDevicesChangedNotification* notification) override; + virtual Core::hresult Unregister(Exchange::IAVInput::IDevicesChangedNotification* notification) override; + virtual Core::hresult Register(Exchange::IAVInput::ISignalChangedNotification* notification) override; + virtual Core::hresult Unregister(Exchange::IAVInput::ISignalChangedNotification* notification) override; + virtual Core::hresult Register(Exchange::IAVInput::IInputStatusChangedNotification* notification) override; + virtual Core::hresult Unregister(Exchange::IAVInput::IInputStatusChangedNotification* notification) override; + virtual Core::hresult Register(Exchange::IAVInput::IVideoStreamInfoUpdateNotification* notification) override; + virtual Core::hresult Unregister(Exchange::IAVInput::IVideoStreamInfoUpdateNotification* notification) override; + virtual Core::hresult Register(Exchange::IAVInput::IGameFeatureStatusUpdateNotification* notification) override; + virtual Core::hresult Unregister(Exchange::IAVInput::IGameFeatureStatusUpdateNotification* notification) override; + virtual Core::hresult Register(Exchange::IAVInput::IHdmiContentTypeUpdateNotification* notification) override; + virtual Core::hresult Unregister(Exchange::IAVInput::IHdmiContentTypeUpdateNotification* notification) override; + + Core::hresult NumberOfInputs(uint32_t& numberOfInputs, bool& success) override; + Core::hresult GetInputDevices(const string& typeOfInput, Exchange::IAVInput::IInputDeviceIterator*& devices, bool& success); + Core::hresult WriteEDID(const string& portId, const string& message, SuccessResult& successResult) override; + Core::hresult ReadEDID(const string& portId, string& EDID, bool& success) override; + Core::hresult GetRawSPD(const string& portId, string& HDMISPD, bool& success) override; + Core::hresult GetSPD(const string& portId, string& HDMISPD, bool& success) override; + Core::hresult SetEdidVersion(const string& portId, const string& edidVersion, SuccessResult& successResult) override; + Core::hresult GetEdidVersion(const string& portId, string& edidVersion, bool& success) override; + Core::hresult SetEdid2AllmSupport(const string& portId, const bool allmSupport, SuccessResult& successResult) override; + Core::hresult GetEdid2AllmSupport(const string& portId, bool& allmSupport, bool& success) override; + Core::hresult SetVRRSupport(const string& portId, const bool vrrSupport, SuccessResult& successResult) override; + Core::hresult GetVRRSupport(const string& portId, bool& vrrSupport, bool& success) override; + Core::hresult GetHdmiVersion(const string& portId, string& HdmiCapabilityVersion, bool& success) override; + Core::hresult SetMixerLevels(const int primaryVolume, const int inputVolume, SuccessResult& successResult) override; + Core::hresult StartInput(const string& portId, const string& typeOfInput, const bool requestAudioMix, const int plane, const bool topMost, SuccessResult& successResult) override; + Core::hresult StopInput(const string& typeOfInput, SuccessResult& successResult) override; + Core::hresult SetVideoRectangle(const uint16_t x, const uint16_t y, const uint16_t w, const uint16_t h, const string& typeOfInput, SuccessResult& successResult) override; + Core::hresult CurrentVideoMode(string& currentVideoMode, bool& success) override; + Core::hresult ContentProtected(bool& isContentProtected, bool& success) override; + Core::hresult GetSupportedGameFeatures(IStringIterator*& features, bool& success) override; + Core::hresult GetGameFeatureStatus(const string& portId, const string& gameFeature, bool& mode, bool& success) override; + Core::hresult GetVRRFrameRate(const string& portId, double& currentVRRVideoFrameRate, bool& success) override; + + Core::hresult getInputDevices(const string& typeOfInput, std::list& inputDeviceList); + void AVInputHotplug(int input, int connect, int type); + void AVInputSignalChange(int port, int signalStatus, int type); + void AVInputStatusChange(int port, bool isPresented, int type); + void AVInputVideoModeUpdate(int port, dsVideoPortResolution_t resolution, int type); + void hdmiInputAviContentTypeChange(int port, int content_type); + void AVInputALLMChange(int port, bool allm_mode); + void AVInputVRRChange(int port, dsVRRType_t vrr_type, bool vrr_mode); + + private: + + mutable Core::CriticalSection _adminLock; + PluginHost::IShell* _service; + + template + uint32_t Register(std::list& list, T* notification); + template + uint32_t Unregister(std::list& list, T* notification); + + std::list _devicesChangedNotifications; + std::list _signalChangedNotifications; + std::list _inputStatusChangedNotifications; + std::list _videoStreamInfoUpdateNotifications; + std::list _gameFeatureStatusUpdateNotifications; + std::list _hdmiContentTypeUpdateNotifications; + + int m_primVolume; + int m_inputVolume; // Player Volume + + void InitializeIARM(); + void DeinitializeIARM(); + + void dispatchEvent(Event, const ParamsType params); + void Dispatch(Event event, const ParamsType params); + + static string currentVideoMode(bool& success); + + bool getALLMStatus(int iPort); + bool getVRRStatus(int iPort, dsHdmiInVrrStatus_t* vrrStatus); + std::string GetRawSPD(int iPort); + + static void dsAVEventHandler(const char* owner, IARM_EventId_t eventId, void* data, size_t len); + static void dsAVSignalStatusEventHandler(const char* owner, IARM_EventId_t eventId, void* data, size_t len); + static void dsAVStatusEventHandler(const char* owner, IARM_EventId_t eventId, void* data, size_t len); + static void dsAVVideoModeEventHandler(const char* owner, IARM_EventId_t eventId, void* data, size_t len); + static void dsAVGameFeatureStatusEventHandler(const char* owner, IARM_EventId_t eventId, void* data, size_t len); + static void dsAviContentTypeEventHandler(const char* owner, IARM_EventId_t eventId, void* data, size_t len); + }; +} // namespace Plugin +} // namespace WPEFramework diff --git a/AVInput/AVInputJsonData.h b/AVInput/AVInputJsonData.h new file mode 100644 index 00000000..32fd0dc8 --- /dev/null +++ b/AVInput/AVInputJsonData.h @@ -0,0 +1,104 @@ +/** + * If not stated otherwise in this file or this component's LICENSE + * file the following copyright and licenses apply: + * + * Copyright 2025 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +#pragma once +#include +#include +#include + +// The following is extracted from JsonData_AVInput.h, as Thunder 4.x doesn't support iterators in events. +// Because of this AVInput handles the event and converts the iterator to a JSON array string. When we move to 5.x we can +// remove this class and use the iterator directly in the event. + +namespace WPEFramework +{ + namespace Plugin + { + class InputDeviceJson : public Core::JSON::Container { + public: + InputDeviceJson() + : Core::JSON::Container() + { + _Init(); + } + + InputDeviceJson(const InputDeviceJson& _other) + : Core::JSON::Container() + , Id(_other.Id) + , Locator(_other.Locator) + , Connected(_other.Connected) + { + _Init(); + } + + InputDeviceJson& operator=(const InputDeviceJson& _rhs) + { + Id = _rhs.Id; + Locator = _rhs.Locator; + Connected = _rhs.Connected; + return (*this); + } + + InputDeviceJson(const Exchange::IAVInput::InputDevice& _other) + : Core::JSON::Container() + { + Id = _other.id; + Locator = _other.locator; + Connected = _other.connected; + _Init(); + } + + InputDeviceJson& operator=(const Exchange::IAVInput::InputDevice& _rhs) + { + Id = _rhs.id; + Locator = _rhs.locator; + Connected = _rhs.connected; + return (*this); + } + + operator Exchange::IAVInput::InputDevice() const + { + Exchange::IAVInput::InputDevice _value{}; + _value.id = Id; + _value.locator = Locator; + _value.connected = Connected; + return (_value); + } + + bool IsValid() const + { + return (true); + } + + private: + void _Init() + { + Add(_T("id"), &Id); + Add(_T("locator"), &Locator); + Add(_T("connected"), &Connected); + } + + public: + Core::JSON::DecSInt32 Id; // id + Core::JSON::String Locator; // locator + Core::JSON::Boolean Connected; // connected + + }; // class InputDeviceJson + } // namespace Plugin +} // namespace WPEFramework diff --git a/AVInput/AVInputUtils.cpp b/AVInput/AVInputUtils.cpp new file mode 100644 index 00000000..9d5ddf9f --- /dev/null +++ b/AVInput/AVInputUtils.cpp @@ -0,0 +1,47 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2025 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.Fv + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + #include "AVInputUtils.h" + +int getTypeOfInput(const std::string& sType) { + if (strcmp(sType.c_str(), INPUT_TYPE_STRING_HDMI) == 0) + return INPUT_TYPE_INT_HDMI; + else if (strcmp(sType.c_str(), INPUT_TYPE_STRING_COMPOSITE) == 0) + return INPUT_TYPE_INT_COMPOSITE; + else if (strcmp(sType.c_str(), INPUT_TYPE_STRING_ALL) == 0) + return INPUT_TYPE_INT_ALL; + else throw "Invalid type of INPUT, please specify HDMI/COMPOSITE/ALL"; +} + +std::string& getTypeOfInput(const int type) { + switch(type) { + case INPUT_TYPE_INT_HDMI: + return INPUT_TYPE_STRING_HDMI; + break; + case INPUT_TYPE_INT_COMPOSITE: + return INPUT_TYPE_STRING_COMPOSITE; + break; + case INPUT_TYPE_INT_ALL: + return INPUT_TYPE_STRING_ALL; + break; + default: + throw "Invalid input type"; + } +} + diff --git a/AVInput/AVInputUtils.h b/AVInput/AVInputUtils.h new file mode 100644 index 00000000..515485f3 --- /dev/null +++ b/AVInput/AVInputUtils.h @@ -0,0 +1,37 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2025 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.Fv + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#define INPUT_TYPE_STRING_ALL "ALL" +#define INPUT_TYPE_STRING_HDMI "HDMI" +#define INPUT_TYPE_STRING_COMPOSITE "COMPOSITE" + +#define INPUT_TYPE_INT_ALL -1 +#define INPUT_TYPE_INT_HDMI 0 +#define INPUT_TYPE_INT_COMPOSITE 1 + +class AVInputUtils { +public: + static int getTypeOfInput(const std::string& type); + static std::string& getTypeOfInput(const int type); + +private: + AVInputUtils() = delete; +}; diff --git a/AVInput/CMakeLists.txt b/AVInput/CMakeLists.txt index 2df53ee4..63c14e42 100644 --- a/AVInput/CMakeLists.txt +++ b/AVInput/CMakeLists.txt @@ -17,8 +17,13 @@ set(PLUGIN_NAME AVInput) set(MODULE_NAME ${NAMESPACE}${PLUGIN_NAME}) +set(PLUGIN_IMPLEMENTATION ${MODULE_NAME}Implementation) + +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") find_package(${NAMESPACE}Plugins REQUIRED) +find_package(${NAMESPACE}Definitions REQUIRED) +find_package(CompileSettingsDebug CONFIG REQUIRED) if (USE_THUNDER_R4) find_package(${NAMESPACE}COM REQUIRED) @@ -28,47 +33,63 @@ endif (USE_THUNDER_R4) set(PLUGIN_AVINPUT_STARTUPORDER "" CACHE STRING "To configure startup order of AVInput plugin") -add_library(${MODULE_NAME} SHARED - AVInput.cpp - Module.cpp - ) +add_library(${MODULE_NAME} SHARED AVInput.cpp Module.cpp) set_target_properties(${MODULE_NAME} PROPERTIES CXX_STANDARD 11 CXX_STANDARD_REQUIRED YES) -if (RDK_SERVICE_L2_TEST) - find_library(TESTMOCKLIB_LIBRARIES NAMES TestMocklib) - if (TESTMOCKLIB_LIBRARIES) - message ("linking mock libraries ${TESTMOCKLIB_LIBRARIES} library") - target_link_libraries(${MODULE_NAME} PRIVATE ${TESTMOCKLIB_LIBRARIES}) - else (TESTMOCKLIB_LIBRARIES) - message ("Require ${TESTMOCKLIB_LIBRARIES} library") - endif (TESTMOCKLIB_LIBRARIES) -endif (RDK_SERVICES_L2_TEST) - target_compile_definitions(${MODULE_NAME} PRIVATE MODULE_NAME=Plugin_${PLUGIN_NAME}) -target_include_directories(${MODULE_NAME} PRIVATE ../helpers) - -if (USE_THUNDER_R4) -target_link_libraries(${MODULE_NAME} PRIVATE ${NAMESPACE}COM::${NAMESPACE}COM) -else () -target_link_libraries(${MODULE_NAME} PRIVATE ${NAMESPACE}Protocols::${NAMESPACE}Protocols) -endif (USE_THUNDER_R4) - find_package(DS) find_package(IARMBus) +target_include_directories(${MODULE_NAME} PRIVATE ../helpers) target_include_directories(${MODULE_NAME} PRIVATE ${DS_INCLUDE_DIRS}) target_include_directories(${MODULE_NAME} PRIVATE ${IARMBUS_INCLUDE_DIRS}) -target_include_directories(${MODULE_NAME} PRIVATE ../helpers) set_source_files_properties(AVInput.cpp PROPERTIES COMPILE_FLAGS "-fexceptions") -target_link_libraries(${MODULE_NAME} PUBLIC ${NAMESPACE}Plugins::${NAMESPACE}Plugins ${IARMBUS_LIBRARIES} ${DS_LIBRARIES} ) +target_link_libraries(${MODULE_NAME} + PRIVATE + CompileSettingsDebug::CompileSettingsDebug + ${NAMESPACE}Plugins::${NAMESPACE}Plugins + ${NAMESPACE}Definitions::${NAMESPACE}Definitions) install(TARGETS ${MODULE_NAME} DESTINATION lib/${STORAGE_DIRECTORY}/plugins) + +add_library(${PLUGIN_IMPLEMENTATION} SHARED AVInputImplementation.cpp Module.cpp) + +set_target_properties(${PLUGIN_IMPLEMENTATION} PROPERTIES + CXX_STANDARD 11 + CXX_STANDARD_REQUIRED YES) + +if (USE_THUNDER_R4) +target_link_libraries(${PLUGIN_IMPLEMENTATION} PRIVATE ${NAMESPACE}COM::${NAMESPACE}COM) +else () +target_link_libraries(${PLUGIN_IMPLEMENTATION} PRIVATE ${NAMESPACE}Protocols::${NAMESPACE}Protocols) +endif (USE_THUNDER_R4) + +if (RDK_SERVICE_L2_TEST) + find_library(TESTMOCKLIB_LIBRARIES NAMES TestMocklib) + if (TESTMOCKLIB_LIBRARIES) + message ("linking mock libraries ${TESTMOCKLIB_LIBRARIES} library") + target_link_libraries(${PLUGIN_IMPLEMENTATION} PRIVATE ${TESTMOCKLIB_LIBRARIES}) + else (TESTMOCKLIB_LIBRARIES) + message ("Require ${TESTMOCKLIB_LIBRARIES} library") + endif (TESTMOCKLIB_LIBRARIES) +endif (RDK_SERVICES_L2_TEST) + +target_include_directories(${PLUGIN_IMPLEMENTATION} PRIVATE ${DS_INCLUDE_DIRS}) +target_include_directories(${PLUGIN_IMPLEMENTATION} PRIVATE ${IARMBUS_INCLUDE_DIRS}) +target_include_directories(${PLUGIN_IMPLEMENTATION} PRIVATE ../helpers) + +target_link_libraries(${PLUGIN_IMPLEMENTATION} PUBLIC ${NAMESPACE}Plugins::${NAMESPACE}Plugins ${IARMBUS_LIBRARIES} ${DS_LIBRARIES} ) + +target_link_libraries(${MODULE_NAME} PUBLIC ${IARMBUS_LIBRARIES} ${DS_LIBRARIES} ) + +install(TARGETS ${PLUGIN_IMPLEMENTATION} + DESTINATION lib/${STORAGE_DIRECTORY}/plugins) write_config(${PLUGIN_NAME}) diff --git a/Tests/L1Tests/CMakeLists.txt b/Tests/L1Tests/CMakeLists.txt index 3d6639c9..c58d4613 100755 --- a/Tests/L1Tests/CMakeLists.txt +++ b/Tests/L1Tests/CMakeLists.txt @@ -106,7 +106,6 @@ set (HDCPPROFILE_INC ${CMAKE_SOURCE_DIR}/../entservices-inputoutput/HdcpProfile set (HDCPPROFILE_LIBS ${NAMESPACE}HdcpProfile ${NAMESPACE}HdcpProfileImplementation) add_plugin_test_ex(PLUGIN_HDCPPROFILE tests/test_HdcpProfile.cpp "${HDCPPROFILE_INC}" "${HDCPPROFILE_LIBS}") - # PLUGIN_HDMICEC2 add_plugin_test_ex(PLUGIN_HDMICEC2 tests/test_HdmiCec2.cpp "../../HdmiCec_2" "${NAMESPACE}HdmiCec_2") @@ -121,7 +120,8 @@ add_plugin_test_ex(PLUGIN_HDMICECSOURCE tests/test_HdmiCecSource.cpp "${HDMICECS # PLUGIN_AVINPUT set (AVINPUT_INC ${CMAKE_SOURCE_DIR}/../entservices-inputoutput/AVInput ${CMAKE_SOURCE_DIR}/../entservices-inputoutput/helpers) -add_plugin_test_ex(PLUGIN_AVINPUT tests/test_AVInput.cpp "${AVINPUT_INC}" "${NAMESPACE}AVInput") +set (AVINPUT_LIBS ${NAMESPACE}AVInput ${NAMESPACE}AVInputImplementation) +add_plugin_test_ex(PLUGIN_AVINPUT tests/test_AVInput.cpp "${AVINPUT_INC}" "${AVINPUT_LIBS}") add_library(${MODULE_NAME} SHARED ${TEST_SRC}) diff --git a/Tests/L1Tests/tests/test_AVInput.cpp b/Tests/L1Tests/tests/test_AVInput.cpp index 0d0be6bd..e4b436af 100644 --- a/Tests/L1Tests/tests/test_AVInput.cpp +++ b/Tests/L1Tests/tests/test_AVInput.cpp @@ -18,6 +18,8 @@ **/ #include +#include "COMLinkMock.h" +#include #include "AVInput.h" @@ -29,6 +31,9 @@ #include "ServiceMock.h" #include "ThunderPortability.h" +#include "AVInputImplementation.h" +#include "AVInputMock.h" + using namespace WPEFramework; using ::testing::NiceMock; @@ -36,19 +41,88 @@ using ::testing::NiceMock; class AVInputTest : public ::testing::Test { protected: Core::ProxyType plugin; + Core::ProxyType AVInputImpl; + + NiceMock service; + NiceMock comLinkMock; + Core::JSONRPC::Handler& handler; DECL_CORE_JSONRPC_CONX connection; string response; + AVInputMock* p_avInputMock = nullptr; + + IarmBusImplMock* p_iarmBusImplMock = nullptr; + AVInputTest() : plugin(Core::ProxyType::Create()) , handler(*(plugin)) , INIT_CONX(1, 0) { + p_avInputMock = new NiceMock; + + #ifdef USE_THUNDER_R4 + ON_CALL(comLinkMock, Instantiate(::testing::_, ::testing::_, ::testing::_)) + .WillByDefault(::testing::Invoke( + [&](const RPC::Object& object, const uint32_t waitTime, uint32_t& connectionId) { + AVInputImpl = Core::ProxyType::Create(); + return &AVInputImpl; + })); + #else + ON_CALL(comLinkMock, Instantiate(::testing::_, ::testing::_, ::testing::_, ::testing::_, ::testing::_)) + .WillByDefault(::testing::Return(AVInputImpl)); + #endif + + p_iarmBusImplMock = new NiceMock ; + IarmBus::setImpl(p_iarmBusImplMock); + + plugin->Initialize(&service); + + } + virtual ~AVInputTest() + { + plugin->Deinitialize(&service); + + IarmBus::setImpl(nullptr); + if (p_iarmBusImplMock != nullptr) { + delete p_iarmBusImplMock; + p_iarmBusImplMock = nullptr; + } } - virtual ~AVInputTest() = default; }; +TEST_F(AVInputTest, RegisteredMethods) +{ + EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("numberOfInputs"))); + EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("currentVideoMode"))); + EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("contentProtected"))); + EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("setEdid2AllmSupport"))); + EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("getEdid2AllmSupport"))); + EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("setVRRSupport"))); + EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("getVRRSupport"))); + EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("getVRRFrameRate"))); + EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("getInputDevices"))); + EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("writeEDID"))); + EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("readEDID"))); + EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("getRawSPD"))); + EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("getSPD"))); + EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("setEdidVersion"))); + EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("getEdidVersion"))); + EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("getHdmiVersion"))); + EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("setMixerLevels"))); + EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("startInput"))); + EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("stopInput"))); + EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("setVideoRectangle"))); + EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("getSupportedGameFeatures"))); + EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("getGameFeatureStatus"))); +} + +TEST_F(AVInputTest, contentProtected) +{ + EXPECT_EQ(Core::ERROR_NONE, handler.Invoke(connection, _T("contentProtected"), _T("{}"), response)); + EXPECT_EQ(response, string("{\"isContentProtected\":true,\"success\":true}")); +} + class AVInputDsTest : public AVInputTest { protected: HdmiInputImplMock* p_hdmiInputImplMock = nullptr; @@ -96,20 +170,93 @@ class AVInputDsTest : public AVInputTest { } }; +TEST_F(AVInputDsTest, numberOfInputs) +{ + ON_CALL(*p_hdmiInputImplMock, getNumberOfInputs()) + .WillByDefault(::testing::Return(1)); + + EXPECT_EQ(Core::ERROR_NONE, handler.Invoke(connection, _T("numberOfInputs"), _T("{}"), response)); + EXPECT_EQ(response, string("{\"numberOfInputs\":1,\"success\":true}")); +} + +TEST_F(AVInputDsTest, currentVideoMode) +{ + ON_CALL(*p_hdmiInputImplMock, getCurrentVideoMode()) + .WillByDefault(::testing::Return(string("unknown"))); + + EXPECT_EQ(Core::ERROR_NONE, handler.Invoke(connection, _T("currentVideoMode"), _T("{}"), response)); + EXPECT_EQ(response, string("{\"currentVideoMode\":\"unknown\",\"success\":true}")); +} + +TEST_F(AVInputDsTest, getEdid2AllmSupport) +{ + EXPECT_EQ(Core::ERROR_NONE, handler.Invoke(connection, _T("getEdid2AllmSupport"), _T("{\"portId\": \"0\",\"allmSupport\":true}"), response)); + EXPECT_EQ(response, string("{\"allmSupport\":true,\"success\":true}")); +} + +TEST_F(AVInputDsTest, getEdid2AllmSupport_ErrorCase) +{ + EXPECT_EQ(Core::ERROR_GENERAL, handler.Invoke(connection, _T("getEdid2AllmSupport"), _T("{\"portId\": \"test\",\"allmSupport\":true}"), response)); + EXPECT_EQ(response, string("")); +} + +TEST_F(AVInputDsTest, setEdid2AllmSupport) +{ + EXPECT_EQ(Core::ERROR_NONE, handler.Invoke(connection, _T("setEdid2AllmSupport"), _T("{\"portId\": \"0\",\"allmSupport\":true}"), response)); + EXPECT_EQ(response, string("{\"success\":true}")); +} + +TEST_F(AVInputDsTest, setEdid2AllmSupport_ErrorCase) +{ + EXPECT_EQ(Core::ERROR_GENERAL, handler.Invoke(connection, _T("setEdid2AllmSupport"), _T("{\"portId\": \"test\",\"allmSupport\":true}"), response)); + EXPECT_EQ(response, string("")); +} + +TEST_F(AVInputDsTest, getVRRSupport) +{ + EXPECT_EQ(Core::ERROR_NONE, handler.Invoke(connection, _T("getVRRSupport"), _T("{\"portId\": \"0\",\"vrrSupport\":true}"), response)); + EXPECT_EQ(response, string("{\"vrrSupport\":true,\"success\":true}")); +} + +TEST_F(AVInputDsTest, getVRRSupport_ErrorCase) +{ + EXPECT_EQ(Core::ERROR_GENERAL, handler.Invoke(connection, _T("getVRRSupport"), _T("{\"portId\": \"test\",\"vrrSupport\":true}"), response)); + EXPECT_EQ(response, string("")); +} + +TEST_F(AVInputDsTest, setVRRSupport) +{ + EXPECT_EQ(Core::ERROR_NONE, handler.Invoke(connection, _T("setVRRSupport"), _T("{\"portId\": \"0\",\"vrrSupport\":true}"), response)); + EXPECT_EQ(response, string("{\"success\":true}")); +} + +TEST_F(AVInputDsTest, setVRRSupport_ErrorCase) +{ + EXPECT_EQ(Core::ERROR_GENERAL, handler.Invoke(connection, _T("setVRRSupport"), _T("{\"portId\": \"test\",\"vrrSupport\":true}"), response)); + EXPECT_EQ(response, string("")); +} + +TEST_F(AVInputDsTest, getVRRFrameRate) +{ + EXPECT_EQ(Core::ERROR_NONE, handler.Invoke(connection, _T("getVRRFrameRate"), _T("{\"portId\": \"0\"}"), response)); + EXPECT_EQ(response, string("{\"currentVRRVideoFrameRate\":0,\"success\":true}")); +} + +TEST_F(AVInputDsTest, getVRRFrameRate_ErrorCase) +{ + EXPECT_EQ(Core::ERROR_GENERAL, handler.Invoke(connection, _T("getVRRFrameRate"), _T("{\"portId\": \"test\"}"), response)); + EXPECT_EQ(response, string("")); +} + class AVInputInit : public AVInputDsTest { protected: - IarmBusImplMock* p_iarmBusImplMock = nullptr; NiceMock factoriesImplementation; PLUGINHOST_DISPATCHER* dispatcher; - NiceMock service; Core::JSONRPC::Message message; AVInputInit() : AVInputDsTest() { - p_iarmBusImplMock = new NiceMock; - IarmBus::setImpl(p_iarmBusImplMock); - ON_CALL(*p_iarmBusImplMock, IARM_Bus_RegisterEventHandler(::testing::_, ::testing::_, ::testing::_)) .WillByDefault(::testing::Invoke( [&](const char* ownerName, IARM_EventId_t eventId, IARM_EventHandler_t handler) { @@ -159,7 +306,6 @@ class AVInputInit : public AVInputDsTest { } return IARM_RESULT_SUCCESS; })); - EXPECT_EQ(string(""), plugin->Initialize(&service)); PluginHost::IFactories::Assign(&factoriesImplementation); dispatcher = static_cast( @@ -172,43 +318,9 @@ class AVInputInit : public AVInputDsTest { dispatcher->Deactivate(); dispatcher->Release(); PluginHost::IFactories::Assign(nullptr); - - plugin->Deinitialize(&service); - - IarmBus::setImpl(nullptr); - if (p_iarmBusImplMock != nullptr) { - delete p_iarmBusImplMock; - p_iarmBusImplMock = nullptr; - } } }; -TEST_F(AVInputTest, RegisteredMethods) -{ - EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("numberOfInputs"))); - EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("currentVideoMode"))); - EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("contentProtected"))); - EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("setEdid2AllmSupport"))); - EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("getEdid2AllmSupport"))); - EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("setVRRSupport"))); - EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("getVRRSupport"))); - EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("getVRRFrameRate"))); - EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("getInputDevices"))); - EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("writeEDID"))); - EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("readEDID"))); - EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("getRawSPD"))); - EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("getSPD"))); - EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("setEdidVersion"))); - EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("getEdidVersion"))); - EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("getHdmiVersion"))); - EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("setMixerLevels"))); - EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("startInput"))); - EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("stopInput"))); - EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("setVideoRectangle"))); - EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("getSupportedGameFeatures"))); - EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("getGameFeatureStatus"))); -} - TEST_F(AVInputInit, getInputDevices) { EXPECT_CALL(*p_hdmiInputImplMock, getNumberOfInputs()) @@ -1875,87 +1987,3 @@ TEST_F(AVInputInit, aviContentTypeUpdate_HDMI) EVENT_UNSUBSCRIBE(0, _T("aviContentTypeUpdate"), _T("org.rdk.AVInput"), message); } - -TEST_F(AVInputTest, contentProtected) -{ - EXPECT_EQ(Core::ERROR_NONE, handler.Invoke(connection, _T("contentProtected"), _T("{}"), response)); - EXPECT_EQ(response, string("{\"isContentProtected\":true,\"success\":true}")); -} - -TEST_F(AVInputDsTest, numberOfInputs) -{ - ON_CALL(*p_hdmiInputImplMock, getNumberOfInputs()) - .WillByDefault(::testing::Return(1)); - - EXPECT_EQ(Core::ERROR_NONE, handler.Invoke(connection, _T("numberOfInputs"), _T("{}"), response)); - EXPECT_EQ(response, string("{\"numberOfInputs\":1,\"success\":true}")); -} - -TEST_F(AVInputDsTest, currentVideoMode) -{ - ON_CALL(*p_hdmiInputImplMock, getCurrentVideoMode()) - .WillByDefault(::testing::Return(string("unknown"))); - - EXPECT_EQ(Core::ERROR_NONE, handler.Invoke(connection, _T("currentVideoMode"), _T("{}"), response)); - EXPECT_EQ(response, string("{\"currentVideoMode\":\"unknown\",\"success\":true}")); -} - -TEST_F(AVInputDsTest, getEdid2AllmSupport) -{ - EXPECT_EQ(Core::ERROR_NONE, handler.Invoke(connection, _T("getEdid2AllmSupport"), _T("{\"portId\": \"0\",\"allmSupport\":true}"), response)); - EXPECT_EQ(response, string("{\"allmSupport\":true,\"success\":true}")); -} - -TEST_F(AVInputDsTest, getEdid2AllmSupport_ErrorCase) -{ - EXPECT_EQ(Core::ERROR_GENERAL, handler.Invoke(connection, _T("getEdid2AllmSupport"), _T("{\"portId\": \"test\",\"allmSupport\":true}"), response)); - EXPECT_EQ(response, string("")); -} - -TEST_F(AVInputDsTest, setEdid2AllmSupport) -{ - EXPECT_EQ(Core::ERROR_NONE, handler.Invoke(connection, _T("setEdid2AllmSupport"), _T("{\"portId\": \"0\",\"allmSupport\":true}"), response)); - EXPECT_EQ(response, string("{\"success\":true}")); -} - -TEST_F(AVInputDsTest, setEdid2AllmSupport_ErrorCase) -{ - EXPECT_EQ(Core::ERROR_GENERAL, handler.Invoke(connection, _T("setEdid2AllmSupport"), _T("{\"portId\": \"test\",\"allmSupport\":true}"), response)); - EXPECT_EQ(response, string("")); -} - -TEST_F(AVInputDsTest, getVRRSupport) -{ - EXPECT_EQ(Core::ERROR_NONE, handler.Invoke(connection, _T("getVRRSupport"), _T("{\"portId\": \"0\",\"vrrSupport\":true}"), response)); - EXPECT_EQ(response, string("{\"vrrSupport\":true,\"success\":true}")); -} - -TEST_F(AVInputDsTest, getVRRSupport_ErrorCase) -{ - EXPECT_EQ(Core::ERROR_GENERAL, handler.Invoke(connection, _T("getVRRSupport"), _T("{\"portId\": \"test\",\"vrrSupport\":true}"), response)); - EXPECT_EQ(response, string("")); -} - -TEST_F(AVInputDsTest, setVRRSupport) -{ - EXPECT_EQ(Core::ERROR_NONE, handler.Invoke(connection, _T("setVRRSupport"), _T("{\"portId\": \"0\",\"vrrSupport\":true}"), response)); - EXPECT_EQ(response, string("{\"success\":true}")); -} - -TEST_F(AVInputDsTest, setVRRSupport_ErrorCase) -{ - EXPECT_EQ(Core::ERROR_GENERAL, handler.Invoke(connection, _T("setVRRSupport"), _T("{\"portId\": \"test\",\"vrrSupport\":true}"), response)); - EXPECT_EQ(response, string("")); -} - -TEST_F(AVInputDsTest, getVRRFrameRate) -{ - EXPECT_EQ(Core::ERROR_NONE, handler.Invoke(connection, _T("getVRRFrameRate"), _T("{\"portId\": \"0\"}"), response)); - EXPECT_EQ(response, string("{\"currentVRRVideoFrameRate\":0,\"success\":true}")); -} - -TEST_F(AVInputDsTest, getVRRFrameRate_ErrorCase) -{ - EXPECT_EQ(Core::ERROR_GENERAL, handler.Invoke(connection, _T("getVRRFrameRate"), _T("{\"portId\": \"test\"}"), response)); - EXPECT_EQ(response, string("")); -}