diff --git a/libwvdrmengine/cdm/core/include/cdm_engine.h b/libwvdrmengine/cdm/core/include/cdm_engine.h index fff903bc..6d084716 100644 --- a/libwvdrmengine/cdm/core/include/cdm_engine.h +++ b/libwvdrmengine/cdm/core/include/cdm_engine.h @@ -3,8 +3,11 @@ #ifndef WVCDM_CORE_CDM_ENGINE_H_ #define WVCDM_CORE_CDM_ENGINE_H_ +#include + #include "cdm_session.h" #include "certificate_provisioning.h" +#include "crypto_session.h" #include "initialization_data.h" #include "oemcrypto_adapter.h" #include "scoped_ptr.h" @@ -117,6 +120,8 @@ class CdmEngine { void OnKeyReleaseEvent(const CdmKeySetId& key_set_id); + std::string MapHdcpVersion(CryptoSession::OemCryptoHdcpVersion version); + // instance variables CdmSessionMap sessions_; CdmReleaseKeySetMap release_key_sets_; diff --git a/libwvdrmengine/cdm/core/include/wv_cdm_constants.h b/libwvdrmengine/cdm/core/include/wv_cdm_constants.h index 876ad623..0c67de5f 100644 --- a/libwvdrmengine/cdm/core/include/wv_cdm_constants.h +++ b/libwvdrmengine/cdm/core/include/wv_cdm_constants.h @@ -43,6 +43,12 @@ static const std::string QUERY_KEY_SYSTEM_ID = "SystemID"; // system id static const std::string QUERY_KEY_PROVISIONING_ID = "ProvisioningID"; // provisioning unique id +static const std::string QUERY_KEY_CURRENT_HDCP_LEVEL = "HdcpLevel"; + // current HDCP level +static const std::string QUERY_KEY_MAX_HDCP_LEVEL = "MaxHdcpLevel"; + // maximum supported HDCP level +static const std::string QUERY_KEY_USAGE_SUPPORT = "UsageSupport"; + // whether usage reporting is supported static const std::string QUERY_VALUE_TRUE = "True"; static const std::string QUERY_VALUE_FALSE = "False"; @@ -52,6 +58,12 @@ static const std::string QUERY_VALUE_SECURITY_LEVEL_L1 = "L1"; static const std::string QUERY_VALUE_SECURITY_LEVEL_L2 = "L2"; static const std::string QUERY_VALUE_SECURITY_LEVEL_L3 = "L3"; static const std::string QUERY_VALUE_SECURITY_LEVEL_UNKNOWN = "Unknown"; +static const std::string QUERY_VALUE_DISCONNECTED = "Disconnected"; +static const std::string QUERY_VALUE_UNPROTECTED = "Unprotected"; +static const std::string QUERY_VALUE_HDCP_V1 = "HDCP-1.x"; +static const std::string QUERY_VALUE_HDCP_V2_0 = "HDCP-2.0"; +static const std::string QUERY_VALUE_HDCP_V2_1 = "HDCP-2.1"; +static const std::string QUERY_VALUE_HDCP_V2_2 = "HDCP-2.2"; static const std::string ISO_BMFF_VIDEO_MIME_TYPE = "video/mp4"; static const std::string ISO_BMFF_AUDIO_MIME_TYPE = "audio/mp4"; diff --git a/libwvdrmengine/cdm/core/src/cdm_engine.cpp b/libwvdrmengine/cdm/core/src/cdm_engine.cpp index 9a2bdbd7..bde19b07 100644 --- a/libwvdrmengine/cdm/core/src/cdm_engine.cpp +++ b/libwvdrmengine/cdm/core/src/cdm_engine.cpp @@ -402,6 +402,21 @@ CdmResponseType CdmEngine::QueryStatus(CdmQueryMap* key_info) { (*key_info)[QUERY_KEY_PROVISIONING_ID] = provisioning_id; } + CryptoSession::OemCryptoHdcpVersion current_hdcp; + CryptoSession::OemCryptoHdcpVersion max_hdcp; + success = crypto_session.GetHdcpCapabilities(¤t_hdcp, &max_hdcp); + if (success) { + (*key_info)[QUERY_KEY_CURRENT_HDCP_LEVEL] = MapHdcpVersion(current_hdcp); + (*key_info)[QUERY_KEY_MAX_HDCP_LEVEL] = MapHdcpVersion(max_hdcp); + } + + bool supports_usage_reporting; + success = crypto_session.UsageInformationSupport(&supports_usage_reporting); + if (success) { + (*key_info)[QUERY_KEY_USAGE_SUPPORT] = + supports_usage_reporting ? QUERY_VALUE_TRUE : QUERY_VALUE_FALSE; + } + return NO_ERROR; } @@ -743,4 +758,23 @@ void CdmEngine::OnKeyReleaseEvent(const CdmKeySetId& key_set_id) { } } +std::string CdmEngine::MapHdcpVersion( + CryptoSession::OemCryptoHdcpVersion version) { + switch (version) { + case CryptoSession::kOemCryptoNoHdcpDeviceAttached: + return QUERY_VALUE_DISCONNECTED; + case CryptoSession::kOemCryptoHdcpNotSupported: + return QUERY_VALUE_UNPROTECTED; + case CryptoSession::kOemCryptoHdcpVersion1: + return QUERY_VALUE_HDCP_V1; + case CryptoSession::kOemCryptoHdcpVersion2: + return QUERY_VALUE_HDCP_V2_0; + case CryptoSession::kOemCryptoHdcpVersion2_1: + return QUERY_VALUE_HDCP_V2_1; + case CryptoSession::kOemCryptoHdcpVersion2_2: + return QUERY_VALUE_HDCP_V2_2; + } + return ""; +} + } // namespace wvcdm diff --git a/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp b/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp index a205a87b..d42b5f10 100644 --- a/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp +++ b/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp @@ -464,6 +464,39 @@ status_t WVDrmPlugin::getPropertyString(const String8& name, } else { value = kDisable; } + } else if (name == "hdcpLevel") { + CdmQueryMap status; + CdmResponseType res = mCDM->QueryStatus(&status); + if (res != wvcdm::NO_ERROR) { + ALOGE("Error querying CDM status: %u", res); + return mapCdmResponseType(res); + } else if (!status.count(QUERY_KEY_CURRENT_HDCP_LEVEL)) { + ALOGE("CDM did not report a current HDCP level"); + return kErrorCDMGeneric; + } + value = status[QUERY_KEY_CURRENT_HDCP_LEVEL].c_str(); + } else if (name == "maxHdcpLevel") { + CdmQueryMap status; + CdmResponseType res = mCDM->QueryStatus(&status); + if (res != wvcdm::NO_ERROR) { + ALOGE("Error querying CDM status: %u", res); + return mapCdmResponseType(res); + } else if (!status.count(QUERY_KEY_MAX_HDCP_LEVEL)) { + ALOGE("CDM did not report a maximum HDCP level"); + return kErrorCDMGeneric; + } + value = status[QUERY_KEY_MAX_HDCP_LEVEL].c_str(); + } else if (name == "usageReportingSupport") { + CdmQueryMap status; + CdmResponseType res = mCDM->QueryStatus(&status); + if (res != wvcdm::NO_ERROR) { + ALOGE("Error querying CDM status: %u", res); + return mapCdmResponseType(res); + } else if (!status.count(QUERY_KEY_USAGE_SUPPORT)) { + ALOGE("CDM did not report whether it supports usage reporting"); + return kErrorCDMGeneric; + } + value = status[QUERY_KEY_USAGE_SUPPORT].c_str(); } else { ALOGE("App requested unknown string property %s", name.string()); return android::ERROR_DRM_CANNOT_HANDLE;