From 9cece6dd44569a9083de2dc4ad2148478eee1ce0 Mon Sep 17 00:00:00 2001 From: "Jia, Lin A" Date: Sun, 28 Apr 2024 23:48:02 +0800 Subject: [PATCH] Enable media hdcp --- daemon/Android.mk | 3 +- test/Android.mk | 23 ++ test/CMakeLists.txt | 22 ++ test/hdcpTestUtility/Android.mk | 75 +++++ test/hdcpTestUtility/CMakeLists.txt | 30 ++ test/hdcpTestUtility/hdcpTestUtility.cpp | 339 +++++++++++++++++++++++ test/hdcpTestUtility/hdcpTestUtility.h | 135 +++++++++ 7 files changed, 626 insertions(+), 1 deletion(-) create mode 100644 test/Android.mk create mode 100644 test/CMakeLists.txt create mode 100644 test/hdcpTestUtility/Android.mk create mode 100644 test/hdcpTestUtility/CMakeLists.txt create mode 100644 test/hdcpTestUtility/hdcpTestUtility.cpp create mode 100644 test/hdcpTestUtility/hdcpTestUtility.h diff --git a/daemon/Android.mk b/daemon/Android.mk index 0bcc0ac..563fb66 100755 --- a/daemon/Android.mk +++ b/daemon/Android.mk @@ -60,7 +60,8 @@ LOCAL_SHARED_LIBRARIES := \ liblog \ libcrypto \ libdrm \ - libssl + libssl \ + libhwcservice LOCAL_STATIC_LIBRARIES := \ libhdcpcommon \ diff --git a/test/Android.mk b/test/Android.mk new file mode 100644 index 0000000..cce17b4 --- /dev/null +++ b/test/Android.mk @@ -0,0 +1,23 @@ +# +# Copyright (c) 2009-2018, Intel Corporation +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. + +# Recursively call sub-folder Android.mk +include $(call all-subdir-makefiles) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000..5d7e633 --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,22 @@ +# Copyright (c) 2020, Intel Corporation +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. + + +add_subdirectory(hdcpTestUtility) diff --git a/test/hdcpTestUtility/Android.mk b/test/hdcpTestUtility/Android.mk new file mode 100644 index 0000000..18d0901 --- /dev/null +++ b/test/hdcpTestUtility/Android.mk @@ -0,0 +1,75 @@ +# +# Copyright (c) 2009-2018, Intel Corporation +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. + +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +# For ALOGV and enter/exit log, set ENABLE_DEBUG=1 during compilation e.g. mm ENABLE_DEBUG=1 -j32 +LOCAL_CPPFLAGS += \ + -DANDROID \ + -DANDROID_VERSION=800 \ + -DLOG_TAG=\"HDCPTESTUTILITY\" + +# LOG_CONSOLE will print ALOGI, ALOGE, ALOGW in Android. Enable on debug build +ifeq ($(TARGET_BUILD_VARIANT),userdebug) +LOCAL_CPPFLAGS += -DLOG_CONSOLE +endif + +# For ALOGV and function enter/exit log, set ENABLE_DEBUG=1 during compilation e.g. mm ENABLE_DEBUG=1 -j32 +ifeq ($(ENABLE_DEBUG),1) +LOCAL_CPPFLAGS += \ + -DHDCP_USE_VERBOSE_LOGGING \ + -DHDCP_USE_FUNCTION_LOGGING \ + -DHDCP_USE_LINK_FUNCTION_LOGGING +endif + +ifeq ($(ENABLE_DEBUG),1) + LOCAL_CPPFLAG += \ + -DLOG_CONSOLE \ + -DHDCP_USE_VERBOSE_LOGGING \ + -DHDCP_USE_FUNCTION_LOGGING \ + -DHDCP_USE_LINK_FUNCTION_LOGGING +endif + +#WA +LOCAL_CPPFLAGS += \ + -Wno-unused-parameter \ + -Wno-error + +LOCAL_C_INCLUDES += \ + $(LOCAL_PATH)/../../sdk \ + $(LOCAL_PATH)/../../test/hdcpTestUtility \ + +LOCAL_SRC_FILES := \ + hdcpTestUtility.cpp \ + +LOCAL_SHARED_LIBRARIES := \ + libutils \ + liblog \ + libhdcpsdk \ + +LOCAL_EXPORT_C_INCLUDE_DIRS = \ + $(LOCAL_PATH)/ + +LOCAL_MODULE := hdcpTestUtility +LOCAL_PROPRIETARY_MODULE := true + +include $(BUILD_SHARED_LIBRARY) diff --git a/test/hdcpTestUtility/CMakeLists.txt b/test/hdcpTestUtility/CMakeLists.txt new file mode 100644 index 0000000..5f5ca37 --- /dev/null +++ b/test/hdcpTestUtility/CMakeLists.txt @@ -0,0 +1,30 @@ +# Copyright (c) 2020, Intel Corporation +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. + +project(hdcpTestUtility CXX) + +get_filename_component(HDCP_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../.." REALPATH) +include_directories(${HDCP_DIR}/sdk) + +add_executable(${PROJECT_NAME} hdcpTestUtility.cpp) + +target_compile_options(${PROJECT_NAME} PRIVATE ${HDCP_CXX_FLAGS}) + +target_link_libraries(${PROJECT_NAME} hdcpsdk) diff --git a/test/hdcpTestUtility/hdcpTestUtility.cpp b/test/hdcpTestUtility/hdcpTestUtility.cpp new file mode 100644 index 0000000..5d7ebf5 --- /dev/null +++ b/test/hdcpTestUtility/hdcpTestUtility.cpp @@ -0,0 +1,339 @@ +/* +* Copyright (c) 2020, Intel Corporation +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +*/ +//! +//! \file hdcpTestUtility.cpp +//! \brief +//! + +#include +#include +#include "hdcpTestUtility.h" + +HdcpTestUtility::HdcpTestUtility() +{ + m_PortList = {}; + m_HDCPHandle = 0; +} + +void HdcpTestUtility::StatusChange( + uint32_t HDCPHandle, + uint32_t PortId, + PORT_EVENT PortEvent, + Context ctx) +{ + if (nullptr == ctx) + { + printf("hdcp context pointer is null\n"); + return; + } + + printf("Enter status change\n"); + switch (PortEvent) + { + case PORT_EVENT_PLUG_IN: + printf("Plug out on port %d\n", PortId); + break; + case PORT_EVENT_PLUG_OUT: + printf("Plug in on port %d\n", PortId); + break; + case PORT_EVENT_LINK_LOST: + printf("Link lost on port %d\n", PortId); + break; + default: + printf("No event on port %d\n", PortId); + break; + } +} + +HDCP_STATUS HdcpTestUtility::HdcpDestroy(void) +{ + HDCP_STATUS ret = HDCP_STATUS_ERROR_INTERNAL; + ret = HDCPDestroy(m_HDCPHandle); + return ret; +} + +HDCP_STATUS HdcpTestUtility::HdcpEnumerateDisplay(void) +{ + HDCP_STATUS ret = HDCP_STATUS_ERROR_INTERNAL; + + // enumerate display + ret = HDCPEnumerateDisplay(m_HDCPHandle, &m_PortList); + if (HDCP_STATUS_SUCCESSFUL == ret) + { + if (NUM_PHYSICAL_PORTS_MAX < m_PortList.PortCount) + { + printf("Port count is larger than max number of ports\n"); + ret = HDCP_STATUS_ERROR_INTERNAL; + } + else if (0 == m_PortList.PortCount) + { + printf("No external display connected, please connect it!\n"); + ret = HDCP_STATUS_ERROR_NO_DISPLAY; + } + else + { + for (uint32_t i = 0; i < NUM_PHYSICAL_PORTS_MAX; ++i) + { + if (m_PortList.Ports[i].status & PORT_STATUS_CONNECTED) + { + const char *c = (m_PortList.Ports[i].status & + PORT_STATUS_REPEATER_ATTACHED) + ? "repeater!" + : "receiver!"; + printf("Display through port %d is connected as a %s\n", + m_PortList.Ports[i].Id, + c); + } + } + } + } + else + { + printf("Failed to enumerate display(error %d)\n", ret); + } + return ret; +} + +HDCP_STATUS HdcpTestUtility::SetHdcpLevel(HDCP_LEVEL hdcpLevel) +{ + HDCP_STATUS ret = HDCP_STATUS_ERROR_INTERNAL; + const char *c = hdcpLevel ? "enable HDCP" : "disable HDCP"; + + // Set HDCP level on all connected displays + for (uint32_t i = 0; i < NUM_PHYSICAL_PORTS_MAX; ++i) + { + if (m_PortList.Ports[i].status & PORT_STATUS_CONNECTED) + { + ret = HDCPSetProtectionLevel( + m_HDCPHandle, + m_PortList.Ports[i].Id, + hdcpLevel); + + if (HDCP_STATUS_SUCCESSFUL != ret) + { + printf("Failed to %s(error = %d) on port %d\n", + c, + ret, + m_PortList.Ports[i].Id); + break; + } + } + } + if (HDCP_STATUS_SUCCESSFUL == ret) + { + printf("Succeed to %s\n", c); + } + return ret; +} + +HDCP_STATUS HdcpTestUtility::HdcpGetStatus(PORT_STATUS sts) +{ + HDCP_STATUS ret = HDCP_STATUS_ERROR_INTERNAL; + PORT_STATUS portSts = PORT_STATUS_DISCONNECTED; + + for (uint32_t i = 0; i < NUM_PHYSICAL_PORTS_MAX; i++) + { + if (m_PortList.Ports[i].status & PORT_STATUS_CONNECTED) + { + ret = HDCPGetStatus(m_HDCPHandle, m_PortList.Ports[i].Id, &portSts); + + // check port status + if (HDCP_STATUS_SUCCESSFUL == ret) + { + if (sts == portSts) + { + printf("Port %d: status %s is expected\n", + m_PortList.Ports[i].Id, + Status2String(portSts).c_str()); + } + else + { + ret = HDCP_STATUS_ERROR_INTERNAL; + printf("Port %d: status %s is not expected(%s)\n", + m_PortList.Ports[i].Id, + Status2String(portSts).c_str(), + Status2String(sts).c_str()); + break; + } + } + else + { + printf("Port %d: failed to get status(error: %d)\n", + m_PortList.Ports[i].Id, + ret); + ret = HDCP_STATUS_ERROR_INTERNAL; + break; + } + } + } + return ret; +} + +HDCP_STATUS HdcpTestUtility::HdcpCreate(void) +{ + HDCP_STATUS ret = HDCPCreate(&m_HDCPHandle, HdcpTestUtility::StatusChange, this); + if (HDCP_STATUS_SUCCESSFUL != ret) + { + printf("HDCP context creation failed(error: %d)\n", ret); + } + else + { + printf("HDCP context creation passed\n"); + } + return ret; +} + +std::string HdcpTestUtility::Status2String(const PORT_STATUS Status) +{ + auto it = PortStatusMap.find(Status); + if (it != PortStatusMap.end()) + { + return it->second; + } + else + { + return "UNKNOWN"; + } +} + +/** +* @Parse command. +* @param argc[in] option count +* @param argv[in] command +* @return true if valid cmd, otherwise is false. +*/ +bool ParseCmdOption(int argc, char **argv) +{ + bool ret = true; + + if (MIN_OPTION_COUNT != argc && MAX_OPTION_COUNT != argc) + { + printf("Unrecognised option\n%s", USAGE); + return false; + } + + std::string sOption(argv[1]); + std::transform(sOption.begin(), sOption.end(), sOption.begin(), ::tolower); + if (MIN_OPTION_COUNT == argc) + { + if (!sOption.compare("--hdcp") || !sOption.compare("-h")) + { + printf("%s\n", USAGE); + } + else + { + printf("Unrecognised option\n%s", USAGE); + ret = false; + } + } + else + { + std::string sArg(argv[2]); + std::transform(sArg.begin(), sArg.end(), sArg.begin(), ::tolower); + if (!sOption.compare("--test") && + (!sArg.compare("hdcp") || + !sArg.compare("hdcptype1"))) + { + ret = true; + } + else + { + printf("Unrecognised option\n%s", USAGE); + ret = false; + } + } + return ret; +} + +int32_t main(int argc, char *argv[]) +{ + HDCP_STATUS ret = HDCP_STATUS_ERROR_INTERNAL; + + // parse input parameter + if (!ParseCmdOption(argc, argv)) + { + return 1; + } + + //run hdcp test with specified hdcp level + if (MAX_OPTION_COUNT == argc) + { + std::string sArg(argv[2]); + std::transform(sArg.begin(), sArg.end(), sArg.begin(), ::tolower); + do + { + //1-create HDCP context + HdcpTestUtilityPtr pHDCP = std::make_shared(); + if (!pHDCP) + { + printf("HdcpTestUtility construction failed\n"); + break; + } + if (pHDCP->HdcpCreate()) + { + printf("Please ensure hdcp service launched before test\n"); + break; + } + + //2-enumerate display + ret = pHDCP->HdcpEnumerateDisplay(); + if (HDCP_STATUS_SUCCESSFUL != ret) + { + pHDCP->HdcpDestroy(); + break; + } + + //3-set hdcp level + HDCP_LEVEL hdcplevel = + sArg.compare("hdcp") ? HDCP_LEVEL2 : HDCP_LEVEL1; + PORT_STATUS portSts = + sArg.compare("hdcp") ? TYPE1_ENABLE : TYPE0_ENABLE; + ret = pHDCP->SetHdcpLevel(hdcplevel); + if (HDCP_STATUS_SUCCESSFUL == ret) + { + //4-check port status is expected + ret = pHDCP->HdcpGetStatus(portSts); + } + + //5-disable HDCP + if (HDCP_STATUS_SUCCESSFUL == ret) + { + ret = pHDCP->SetHdcpLevel(HDCP_LEVEL0); + if (HDCP_STATUS_SUCCESSFUL == ret) + { + ret = pHDCP->HdcpGetStatus(PORT_STATUS_CONNECTED); + } + } + + //6-destroy hdcp context + pHDCP->HdcpDestroy(); + } while (false); + if (HDCP_STATUS_ERROR_NO_DISPLAY != ret) + { + if (HDCP_STATUS_SUCCESSFUL != ret) + printf("HDCP %s test failed!\n", sArg.c_str()); + else + printf("HDCP %s test passed!\n", sArg.c_str()); + } + } + return ret; +} diff --git a/test/hdcpTestUtility/hdcpTestUtility.h b/test/hdcpTestUtility/hdcpTestUtility.h new file mode 100644 index 0000000..f726a55 --- /dev/null +++ b/test/hdcpTestUtility/hdcpTestUtility.h @@ -0,0 +1,135 @@ +/* +* Copyright (c) 2020, Intel Corporation +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +*/ +//! +//! \file hdcpTestUtility.h +//! \brief +//! + +#ifndef __HDCP_TEST_UTILITY_H__ +#define __HDCP_TEST_UTILITY_H__ + +#include +#include +#include + +#include "hdcpapi.h" +#include "hdcpdef.h" + +#define TYPE0_ENABLE (PORT_STATUS_HDCP_TYPE0_ENABLED | PORT_STATUS_CONNECTED) +#define TYPE1_ENABLE (PORT_STATUS_HDCP_TYPE1_ENABLED | PORT_STATUS_CONNECTED) + +// hdcpTestUtility usage +#define USAGE \ + "\nUsage: hdcp_test_utility [OPTIONS]\n\ + --test [hdcp|hdcptype1]\n\ + hdcp: turn HDCP on with port maxmum supported HDCP version \n\ + hdcptype1: turn on HDCP2.2 and apply stream type restriction\n\ + --help | -h\n" + +#define MAX_OPTION_COUNT 3 +#define MIN_OPTION_COUNT 2 + +// PORT_STATUS map +static const std::mapPortStatusMap = +{ + {PORT_STATUS_CONNECTED, "Disabled/Connected"}, + {TYPE0_ENABLE, "Type0Enabled"}, + {TYPE1_ENABLE, "Type1Enabled"}, + {PORT_STATUS_REPEATER_ATTACHED, "RepeaterAttached"}, + {PORT_STATUS_DISCONNECTED, "Invalid/Disconnected"}, +}; + +class HdcpTestUtility +{ +public: + //////////////////////////////////////////////////////////////////////////// + /// \brief Construct the HdcpTestUtility object + /// \return Nothing + //////////////////////////////////////////////////////////////////////////// + HdcpTestUtility(); + + //////////////////////////////////////////////////////////////////////////// + /// \brief Destroy the HdcpTestUtility object + /// \return Nothing + //////////////////////////////////////////////////////////////////////////// + ~HdcpTestUtility(){}; + + //////////////////////////////////////////////////////////////////////////// + /// \brief Destroy a HDCP context + /// \return HDCP_STATUS_SUCCESSFUL if successful, error codes on failure + //////////////////////////////////////////////////////////////////////////// + HDCP_STATUS HdcpDestroy(void); + + //////////////////////////////////////////////////////////////////////////// + /// \brief Enumerate all ports connected to external display panel + /// \return HDCP_STATUS_SUCCESSFUL if successful, error codes on failure + //////////////////////////////////////////////////////////////////////////// + HDCP_STATUS HdcpEnumerateDisplay(void); + + //////////////////////////////////////////////////////////////////////////// + /// \brief Callback function for port events + /// \param[in] HdcpHandle + /// \param[in] PortId which receive the link status event + /// \param[in] PortEvent + /// \param[in] hdcp context pointer + /// \return Nothing + //////////////////////////////////////////////////////////////////////////// + static void StatusChange( + uint32_t HDCPHandle, + uint32_t PortId, + PORT_EVENT PortEvent, + Context Ctx); + + //////////////////////////////////////////////////////////////////////////// + /// \brief Set HDCP protection protocol + /// \param[in] hdcpLevel + /// \return HDCP_STATUS_SUCCESSFUL if successful, error codes on failure + //////////////////////////////////////////////////////////////////////////// + HDCP_STATUS SetHdcpLevel(HDCP_LEVEL hdcpLevel); + + //////////////////////////////////////////////////////////////////////////// + /// \brief Get HDCP status + /// \param[out] sts receives the port status + /// \return HDCP_STATUS_SUCCESSFUL if successful, error codes on failure + //////////////////////////////////////////////////////////////////////////// + HDCP_STATUS HdcpGetStatus(PORT_STATUS sts); + + //////////////////////////////////////////////////////////////////////////// + /// \brief Create HDCP context + /// \return HDCP_STATUS_SUCCESSFUL if successful, error codes on failure + //////////////////////////////////////////////////////////////////////////// + HDCP_STATUS HdcpCreate(void); + + //////////////////////////////////////////////////////////////////////////// + /// \brief Convert PORT_STATUS to string + /// \param[in] Status + /// \return string mapped to the input STATUS + //////////////////////////////////////////////////////////////////////////// + std::string Status2String(const PORT_STATUS Status); + +private: + PortList m_PortList; + uint32_t m_HDCPHandle; +}; + +typedef std::shared_ptr HdcpTestUtilityPtr; +#endif //__HDCP_TEST_UTILITY_H__