diff --git a/Android.mk b/Android.mk deleted file mode 100644 index cce17b4..0000000 --- a/Android.mk +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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/common/Android.bp b/common/Android.bp new file mode 100644 index 0000000..acc9d1e --- /dev/null +++ b/common/Android.bp @@ -0,0 +1,50 @@ +// +// 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. + +cc_library_static { + name: "libhdcpcommon", + + cppflags: [ + "-DANDROID", + "-DANDROID_VERSION=800", + "-DLOG_TAG=\"HDCPCOMMON\"", + ] + ["-DLOG_CONSOLE"] + ["-Wno-error"], // LOG_CONSOLE will print ALOGI, ALOGE, ALOGW in Android. Enable on debug build + + include_dirs: [ + "hardware/intel/external/media/hdcp/sdk", + "hardware/intel/external/media/hdcp/common", + ], + + shared_libs: [ + "libutils", + "liblog", + ], + + srcs: [ + "clientsock.cpp", + "gensock.cpp", + "servsock.cpp", + "socketdata.cpp", + ], + + proprietary: true, + +} diff --git a/common/Android.mk b/common/Android.mk deleted file mode 100644 index cfb5385..0000000 --- a/common/Android.mk +++ /dev/null @@ -1,73 +0,0 @@ -# -# 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) - -LOCAL_CPPFLAGS := \ - -DANDROID \ - -DANDROID_VERSION=800 \ - -DLOG_TAG=\"HDCPCOMMON\" - -# 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_CPPFLAG += \ - -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-error - -LOCAL_C_INCLUDES += \ - $(LOCAL_PATH)/../sdk \ - $(LOCAL_PATH)/../common \ - -LOCAL_SHARED_LIBRARIES := \ - libutils \ - liblog \ - -LOCAL_SRC_FILES := \ - clientsock.cpp \ - gensock.cpp \ - servsock.cpp \ - socketdata.cpp \ - -LOCAL_MODULE := libhdcpcommon -LOCAL_PROPRIETARY_MODULE := true - -include $(BUILD_STATIC_LIBRARY) diff --git a/daemon/Android.bp b/daemon/Android.bp new file mode 100644 index 0000000..7ded302 --- /dev/null +++ b/daemon/Android.bp @@ -0,0 +1,63 @@ +// +// 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. + +cc_binary { + name: "hdcpd", + + cppflags: [ + "-DANDROID", + "-DUSES_HDCP_HWCOMPOSER", + "-DANDROID_VERSION=800", + "-DLOG_TAG=\"HDCPD\"", + ] + ["-DLOG_CONSOLE"] + [ // LOG_CONSOLE will print ALOGI, ALOGE, ALOGW in Android. Enable on debug build + "-Wno-unused-parameter", + "-Wno-error", + ], + + shared_libs: [ + "libutils", + "libbinder", + "liblog", + "libcrypto", + "libdrm", + "libssl", + "libhwcservice", + ], + + static_libs: ["libhdcpcommon"], + + srcs: [ + "main.cpp", + "daemon.cpp", + "port.cpp", + //"srm.cpp", + "portmanager.cpp", + "portmanager_android.cpp", + ], + + include_dirs: ["."] + [ + "hardware/intel/external/media/hdcp/sdk", + "hardware/intel/external/media/hdcp/common", + ], + + proprietary: true, + +} diff --git a/daemon/Android.mk b/daemon/Android.mk deleted file mode 100755 index 0bcc0ac..0000000 --- a/daemon/Android.mk +++ /dev/null @@ -1,84 +0,0 @@ -# -# 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) - -LOCAL_CPPFLAGS := \ - -DANDROID \ - -DANDROID_VERSION=800 \ - -DLOG_TAG=\"HDCPD\" - -# 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_CPPFLAG += \ - -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_SHARED_LIBRARIES := \ - libutils \ - libbinder \ - liblog \ - libcrypto \ - libdrm \ - libssl - -LOCAL_STATIC_LIBRARIES := \ - libhdcpcommon \ - -LOCAL_SRC_FILES := \ - main.cpp \ - daemon.cpp \ - port.cpp \ - srm.cpp \ - portmanager.cpp \ - portmanager_android.cpp - -LOCAL_C_INCLUDES := \ - $(LOCAL_PATH) \ - $(LOCAL_PATH)/../sdk \ - $(LOCAL_PATH)/../common - -LOCAL_MODULE := hdcpd -LOCAL_PROPRIETARY_MODULE := true - -include $(BUILD_EXECUTABLE) diff --git a/daemon/daemon.cpp b/daemon/daemon.cpp index e8804ad..68b7b78 100644 --- a/daemon/daemon.cpp +++ b/daemon/daemon.cpp @@ -178,7 +178,7 @@ void HdcpDaemon::DispatchCommand( sendResponse = false; } break; - +#if HDCP_SRM case HDCP_API_SENDSRMDATA: HDCP_NORMALMESSAGE("Daemon received 'SendSrmData' request"); SendSRMData(data, appId); @@ -188,7 +188,7 @@ void HdcpDaemon::DispatchCommand( HDCP_NORMALMESSAGE("Daemon received 'GetSrmVersion' request"); GetSRMVersion(data); break; - +#endif case HDCP_API_CONFIG: HDCP_NORMALMESSAGE("Daemon received 'Config' request"); Config(data); @@ -500,6 +500,7 @@ void HdcpDaemon::GetKsvList(SocketData& data, uint32_t appId) HDCP_FUNCTION_EXIT(SUCCESS); } +#if HDCP_SRM void HdcpDaemon::SendSRMData(SocketData& data, uint32_t appId) { HDCP_FUNCTION_ENTER; @@ -590,18 +591,19 @@ void HdcpDaemon::GetSRMVersion(SocketData& data) HDCP_FUNCTION_EXIT(SUCCESS); } +#endif void HdcpDaemon::Config(SocketData& data) { HDCP_FUNCTION_ENTER; - +#if HDCP_SRM int32_t sts = SrmConfig(data.Config.disableSrmStorage); if (SUCCESS != sts) { data.Status = HDCP_STATUS_ERROR_INTERNAL; return; } - +#endif data.Status = HDCP_STATUS_SUCCESSFUL; HDCP_FUNCTION_EXIT(SUCCESS); diff --git a/daemon/daemon.h b/daemon/daemon.h index f67fbda..eba8bb4 100644 --- a/daemon/daemon.h +++ b/daemon/daemon.h @@ -37,6 +37,7 @@ #include "socketdata.h" #define APP_ID_INTERNAL 0 +#define HDCP_SRM 0 #ifdef ANDROID #define HDCP_PIDFILE "/data/hdcp/hdcpd.pid" diff --git a/daemon/main.cpp b/daemon/main.cpp index 6f36df1..ea0b670 100644 --- a/daemon/main.cpp +++ b/daemon/main.cpp @@ -156,6 +156,7 @@ int32_t InitializeWithMinimalPrivileges() int32_t ret = 1; HdcpDaemon daemon; +#if HDCP_SRM ret = SrmInit(); if (SUCCESS != ret) { @@ -163,7 +164,7 @@ int32_t InitializeWithMinimalPrivileges() HDCP_ASSERTMESSAGE("SrmInit failed, destroying the daemon."); goto out; } - +#endif ret = PortManagerInit(daemon); if (SUCCESS != ret) { @@ -193,7 +194,9 @@ int32_t InitializeWithMinimalPrivileges() out: PortManagerRelease(); +#if HDCP_SRM SrmRelease(); +#endif HDCP_FUNCTION_EXIT(ret); return ret; diff --git a/daemon/portmanager.cpp b/daemon/portmanager.cpp index 1234af6..5f300b2 100755 --- a/daemon/portmanager.cpp +++ b/daemon/portmanager.cpp @@ -494,11 +494,14 @@ PortManager::PortManager(HdcpDaemon& daemonSocket) : // Set default state m_IsValid = false; - m_DrmFd = drmOpen("i915", nullptr); + m_DrmFd = drmOpen("virtio_gpu", nullptr); if (m_DrmFd < 0) { - HDCP_ASSERTMESSAGE("Failed to open i915 device!"); - return; + m_DrmFd = drmOpen("i915", nullptr); + if (m_DrmFd < 0) { + HDCP_ASSERTMESSAGE("Failed to open i915 device!"); + return; + } } if (SUCCESS != InitDrmObjects()) @@ -721,6 +724,7 @@ int32_t PortManager::EnablePort( { HDCP_FUNCTION_ENTER; + HDCP_NORMALMESSAGE("level %d", level); DrmObject *drmObject = GetDrmObjectByPortId(portId); if (nullptr == drmObject || DRM_MODE_DISCONNECTED == drmObject->GetConnection()) @@ -731,6 +735,7 @@ int32_t PortManager::EnablePort( bool type1Capable = (UINT32_MAX != drmObject->GetPropertyId(CP_CONTENT_TYPE)); + HDCP_NORMALMESSAGE("type1Capable %d", type1Capable); if (!type1Capable) { @@ -749,6 +754,7 @@ int32_t PortManager::EnablePort( // if level == 2, then content type == 1 means enabled, // content type == 0 means upgrade to type 1. uint8_t currCpType = drmObject->GetCpType(); + HDCP_NORMALMESSAGE("currCpType %d", currCpType); if (CP_TYPE_INVALID != currCpType && (uint32_t)(level - 1) <= currCpType) { drmObject->AddRefAppId(appId); @@ -767,6 +773,7 @@ int32_t PortManager::EnablePort( default : break; } + HDCP_NORMALMESSAGE("cpType %d", cpType); // Set CP_Content_Type property, try at most AUTH_NUM_RETRY times ret = SetPortProperty( drmObject->GetDrmId(), @@ -787,6 +794,7 @@ int32_t PortManager::EnablePort( // The port hasn't been enabled so far // Set Content Protection property, try at most AUTH_NUM_RETRY times uint8_t cpValue = CP_DESIRED; + HDCP_NORMALMESSAGE("cpValue %d", cpValue); ret = SetPortProperty( drmObject->GetDrmId(), drmObject->GetPropertyId(CONTENT_PROTECTION), @@ -1417,7 +1425,10 @@ int32_t PortManagerHWComposer::SetPortProperty( { HDCP_FUNCTION_ENTER; + HDCP_NORMALMESSAGE("PortManagerHWComposer::SetPortProperty"); int32_t ret = EINVAL; + uint8_t propValue = 0; + static uint8_t typeValue = 0; DrmObject *drmObject = GetDrmObjectByDrmId(drmId); if (nullptr == drmObject) @@ -1432,11 +1443,14 @@ int32_t PortManagerHWComposer::SetPortProperty( return ENOENT; } - uint8_t propValue = *value; + propValue = *value; + if (propId == drmObject->GetPropertyId(CP_CONTENT_TYPE)) + typeValue = *value; android::ProcessState::initWithDriver(BINDER_IPC); -#ifdef USES_IA_HWCOMPOSER +#ifdef USES_HDCP_HWCOMPOSER + HDCP_NORMALMESSAGE("PortManagerHWComposer::SetPortProperty hwcService_Connect"); // Connect to HWC service HWCSHANDLE hwcs = HwcService_Connect(); if (nullptr == hwcs) @@ -1457,12 +1471,13 @@ int32_t PortManagerHWComposer::SetPortProperty( { HDCP_NORMALMESSAGE("Set content protection property (on) via HWC"); ret = HwcService_Video_EnableHDCPSession_ForDisplay(hwcs, drmId, - (EHwcsContentType)propValue); + (EHwcsContentType)typeValue); } else if (propId == drmObject->GetPropertyId(CP_CONTENT_TYPE)) { // This is only for HDCP2.2 HDCP_NORMALMESSAGE("Set content type property via HWC"); + HDCP_NORMALMESSAGE("Set content type property via HWC, propVlue = %d", propValue); ret = HwcService_Video_EnableHDCPSession_ForDisplay(hwcs, drmId, (EHwcsContentType)propValue); } diff --git a/daemon/portmanager.h b/daemon/portmanager.h index 8160111..6828f4f 100755 --- a/daemon/portmanager.h +++ b/daemon/portmanager.h @@ -37,7 +37,7 @@ #ifdef ANDROID -#ifdef USES_IA_HWCOMPOSER +#ifdef USES_HDCP_HWCOMPOSER #include #endif @@ -45,7 +45,7 @@ #include #include -#ifdef USES_IA_HWCOMPOSER +#ifdef USES_HDCP_HWCOMPOSER #include #endif diff --git a/daemon/portmanager_android.cpp b/daemon/portmanager_android.cpp index d4fa2a5..279b1dd 100755 --- a/daemon/portmanager_android.cpp +++ b/daemon/portmanager_android.cpp @@ -31,7 +31,7 @@ #include "portmanager.h" #include "portmanager_android.h" -#ifdef USES_IA_HWCOMPOSER +#ifdef USES_HDCP_HWCOMPOSER #include #endif @@ -39,7 +39,7 @@ #include #include -#ifdef USES_IA_HWCOMPOSER +#ifdef USES_HDCP_HWCOMPOSER #include #endif @@ -78,11 +78,13 @@ drmObject->GetPropertyId(CONTENT_PROTECTION)) { *cpValue = properties->prop_values[i]; + HDCP_ASSERTMESSAGE("Get properties cpvalue %d", *cpValue); } else if (properties->props[i] == drmObject->GetPropertyId(CP_CONTENT_TYPE)) { *cpType = properties->prop_values[i]; + HDCP_ASSERTMESSAGE("Get properties cpType %d", *cpType); } } @@ -110,6 +112,7 @@ int32_t setPortProperty_hwcservice(int32_t m_DrmFd, // If the size isn't sizeof(uint8_t), it means SRM data, need create blob // then set the blob id by drmModeConnectorSetProperty + HDCP_ASSERTMESSAGE("setPortProperty_hwcservice"); int ret = EINVAL; uint32_t propValue; if (sizeof(uint8_t) != size) @@ -128,7 +131,7 @@ int32_t setPortProperty_hwcservice(int32_t m_DrmFd, android::ProcessState::initWithDriver("/dev/vndbinder"); -#ifdef USES_IA_HWCOMPOSER +#ifdef USES_HDCP_HWCOMPOSER // Connect to HWC service HWCSHANDLE hwcs = HwcService_Connect(); if (hwcs == NULL) { @@ -153,16 +156,16 @@ int32_t setPortProperty_hwcservice(int32_t m_DrmFd, for (uint32_t i = 0; i < numRetry; ++i) { -#ifdef USES_IA_HWCOMPOSER +#ifdef USES_HDCP_HWCOMPOSER if(propId == drmObject->GetPropertyId(CONTENT_PROTECTION)) { - HDCP_ASSERTMESSAGE("Attempting HDCP Enable"); + HDCP_ASSERTMESSAGE("Attempting HDCP Enable, value =%d, propValue =%d", value, propValue); ret = HwcService_Video_EnableHDCPSession_ForDisplay( hwcs, drmId, (EHwcsContentType)propValue); } else if(propId == drmObject->GetPropertyId(CP_CONTENT_TYPE)) { //This is only for HDCP2.2 - HDCP_ASSERTMESSAGE("Attempting HDCP Enable Type 1"); + HDCP_ASSERTMESSAGE("Attempting HDCP Enable, value =%d, propValue =%d", value, propValue); ret = HwcService_Video_EnableHDCPSession_ForDisplay( hwcs, drmId, (EHwcsContentType)propValue); } else if(propId == drmObject->GetPropertyId(CP_SRM)) @@ -172,6 +175,7 @@ int32_t setPortProperty_hwcservice(int32_t m_DrmFd, (const int8_t *)&value, size); } else { + HDCP_ASSERTMESSAGE("Hwc disconnect"); HwcService_Disconnect(hwcs); hwcs = NULL; ret = EINVAL; @@ -206,7 +210,7 @@ int32_t setPortProperty_hwcservice(int32_t m_DrmFd, if (SUCCESS != ret) { -#ifdef USES_IA_HWCOMPOSER +#ifdef USES_HDCP_HWCOMPOSER HwcService_Disconnect(hwcs); #endif HDCP_ASSERTMESSAGE("Failed to Enable HDCP"); @@ -214,7 +218,7 @@ int32_t setPortProperty_hwcservice(int32_t m_DrmFd, return EBUSY; } -#ifdef USES_IA_HWCOMPOSER +#ifdef USES_HDCP_HWCOMPOSER HwcService_Disconnect(hwcs); #endif HDCP_FUNCTION_EXIT(SUCCESS); diff --git a/sdk/Android.bp b/sdk/Android.bp new file mode 100644 index 0000000..e067772 --- /dev/null +++ b/sdk/Android.bp @@ -0,0 +1,68 @@ +// +// 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. + +cc_library_shared { + name: "libhdcpsdk", + + // For ALOGV and enter/exit log, set ENABLE_DEBUG=1 during compilation e.g. mm ENABLE_DEBUG=1 -j32 + cppflags: [ + "-DANDROID", + "-DANDROID_VERSION=800", + "-DLOG_TAG=\"HDCPSDK\"", + ] + ["-DLOG_CONSOLE"] + [ // LOG_CONSOLE will print ALOGI, ALOGE, ALOGW in Android. Enable on debug build + // ifeq ($(ENABLE_DEBUG),1) + "-DHDCP_USE_VERBOSE_LOGGING", + + // ANDROIDMK TRANSLATION ERROR: endif from unsupported conditional + "-DHDCP_USE_FUNCTION_LOGGING", + // endif + "-DHDCP_USE_LINK_FUNCTION_LOGGING", + + // ANDROIDMK TRANSLATION ERROR: unsupported conditional + ] + [ // ifeq ($(ENABLE_DEBUG),1) + "-Wno-unused-parameter", + "-Wno-error", + ], + + include_dirs: [ + "hardware/intel/external/media/hdcp/sdk", + "hardware/intel/external/media/hdcp/daemon", + "hardware/intel/external/media/hdcp/common", + ], + + srcs: [ + "hdcpapi.cpp", + "sessionmanager.cpp", + "session.cpp", + ], + + shared_libs: [ + "libutils", + "liblog", + ], + + static_libs: ["libhdcpcommon"], + + export_include_dirs: [""], + + proprietary: true, + +} diff --git a/sdk/Android.mk b/test/hdcpTestUtility/Android.mk similarity index 88% rename from sdk/Android.mk rename to test/hdcpTestUtility/Android.mk index ac11b3a..6974df1 100644 --- a/sdk/Android.mk +++ b/test/hdcpTestUtility/Android.mk @@ -26,7 +26,7 @@ include $(CLEAR_VARS) LOCAL_CPPFLAGS += \ -DANDROID \ -DANDROID_VERSION=800 \ - -DLOG_TAG=\"HDCPSDK\" + -DLOG_TAG=\"HDCPTESTUTILITY\" # LOG_CONSOLE will print ALOGI, ALOGE, ALOGW in Android. Enable on debug build ifeq ($(TARGET_BUILD_VARIANT),userdebug) @@ -55,26 +55,21 @@ LOCAL_CPPFLAGS += \ -Wno-error LOCAL_C_INCLUDES += \ - $(LOCAL_PATH)/../sdk \ - $(LOCAL_PATH)/../daemon \ - $(LOCAL_PATH)/../common \ + $(LOCAL_PATH)/../../sdk \ + $(LOCAL_PATH)/../../test/hdcpTestUtility \ LOCAL_SRC_FILES := \ - hdcpapi.cpp \ - sessionmanager.cpp \ - session.cpp \ + hdcpTestUtility.cpp \ LOCAL_SHARED_LIBRARIES := \ libutils \ liblog \ - -LOCAL_STATIC_LIBRARIES := \ - libhdcpcommon \ + libhdcpsdk \ LOCAL_EXPORT_C_INCLUDE_DIRS = \ $(LOCAL_PATH)/ -LOCAL_MODULE := libhdcpsdk +LOCAL_MODULE := hdcpTestUtility LOCAL_PROPRIETARY_MODULE := true -include $(BUILD_SHARED_LIBRARY) +include $(BUILD_EXECUTABLE) 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__