Merge "Added support for additional HDCP levels." into udc-dev

This commit is contained in:
Alex Dale
2023-04-01 00:56:04 +00:00
committed by Android (Google) Code Review
7 changed files with 91 additions and 51 deletions

View File

@@ -415,8 +415,6 @@ class CdmEngine {
void OnKeyReleaseEvent(const CdmKeySetId& key_set_id);
std::string MapHdcpVersion(CryptoSession::HdcpCapability version);
void CloseExpiredReleaseSessions();
// Returns "true" if |okp_provisioner_| should be checked.

View File

@@ -155,12 +155,12 @@ class LicenseKeyStatus {
void SetConstraints(const ConstraintList& constraints);
bool is_content_key_;
CdmKeyStatus key_status_;
bool meets_constraints_;
bool meets_security_level_constraints_;
bool is_content_key_ = false;
CdmKeyStatus key_status_ = kKeyStatusInternalError;
bool meets_constraints_ = true;
bool meets_security_level_constraints_ = true;
CdmKeyAllowedUsage allowed_usage_;
CryptoSession::HdcpCapability default_hdcp_level_;
CryptoSession::HdcpCapability default_hdcp_level_ = HDCP_NONE;
ConstraintList constraints_;
CORE_DISALLOW_COPY_AND_ASSIGN(LicenseKeyStatus);

View File

@@ -142,6 +142,11 @@ 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 QUERY_VALUE_HDCP_V2_3 = "HDCP-2.3";
static const std::string QUERY_VALUE_HDCP_V1_0 = "HDCP-1.0";
static const std::string QUERY_VALUE_HDCP_V1_1 = "HDCP-1.1";
static const std::string QUERY_VALUE_HDCP_V1_2 = "HDCP-1.2";
static const std::string QUERY_VALUE_HDCP_V1_3 = "HDCP-1.3";
static const std::string QUERY_VALUE_HDCP_V1_4 = "HDCP-1.4";
static const std::string QUERY_VALUE_HDCP_LEVEL_UNKNOWN = "HDCP-LevelUnknown";
static const std::string QUERY_VALUE_DRM_CERTIFICATE = "DrmCertificate";
static const std::string QUERY_VALUE_KEYBOX = "Keybox";

View File

@@ -33,6 +33,37 @@ namespace wvcdm {
namespace {
const uint64_t kReleaseSessionTimeToLive = 60; // seconds
const uint32_t kUpdateUsageInformationPeriod = 60; // seconds
std::string MapHdcpVersion(CryptoSession::HdcpCapability version) {
switch (version) {
case HDCP_NONE:
return QUERY_VALUE_HDCP_NONE;
case HDCP_V1:
return QUERY_VALUE_HDCP_V1;
case HDCP_V2:
return QUERY_VALUE_HDCP_V2_0;
case HDCP_V2_1:
return QUERY_VALUE_HDCP_V2_1;
case HDCP_V2_2:
return QUERY_VALUE_HDCP_V2_2;
case HDCP_V2_3:
return QUERY_VALUE_HDCP_V2_3;
// V17 and forward.
case HDCP_V1_0:
return QUERY_VALUE_HDCP_V1_0;
case HDCP_V1_1:
return QUERY_VALUE_HDCP_V1_1;
case HDCP_V1_2:
return QUERY_VALUE_HDCP_V1_2;
case HDCP_V1_3:
return QUERY_VALUE_HDCP_V1_3;
case HDCP_V1_4:
return QUERY_VALUE_HDCP_V1_4;
case HDCP_NO_DIGITAL_OUTPUT:
return QUERY_VALUE_HDCP_NO_DIGITAL_OUTPUT;
}
return QUERY_VALUE_HDCP_LEVEL_UNKNOWN;
}
} // namespace
class UsagePropertySet : public CdmClientPropertySet {
@@ -2190,27 +2221,6 @@ CdmResponseType CdmEngine::SetPlaybackId(const CdmSessionId& session_id,
return CdmResponseType(NO_ERROR);
}
std::string CdmEngine::MapHdcpVersion(CryptoSession::HdcpCapability version) {
switch (version) {
case HDCP_NONE:
return QUERY_VALUE_HDCP_NONE;
case HDCP_V1:
return QUERY_VALUE_HDCP_V1;
case HDCP_V2:
return QUERY_VALUE_HDCP_V2_0;
case HDCP_V2_1:
return QUERY_VALUE_HDCP_V2_1;
case HDCP_V2_2:
return QUERY_VALUE_HDCP_V2_2;
case HDCP_V2_3:
return QUERY_VALUE_HDCP_V2_3;
case HDCP_NO_DIGITAL_OUTPUT:
return QUERY_VALUE_HDCP_NO_DIGITAL_OUTPUT;
default:
return QUERY_VALUE_HDCP_LEVEL_UNKNOWN;
}
}
void CdmEngine::CloseExpiredReleaseSessions() {
const int64_t current_time = clock_.GetCurrentTime();
std::set<CdmSessionId> close_session_set;

View File

@@ -2103,9 +2103,8 @@ CdmResponseType CryptoSession::GetHdcpCapabilities(
RETURN_IF_NULL(current, PARAMETER_NULL);
RETURN_IF_NULL(max, PARAMETER_NULL);
OEMCryptoResult status;
WithOecReadLock("GetHdcpCapabilities", [&] {
status = OEMCrypto_GetHDCPCapability(security_level, current, max);
const OEMCryptoResult status = WithOecReadLock("GetHdcpCapabilities", [&] {
return OEMCrypto_GetHDCPCapability(security_level, current, max);
});
if (OEMCrypto_SUCCESS == status) {

View File

@@ -9,6 +9,7 @@
#include "log.h"
#include "wv_cdm_constants.h"
namespace wvcdm {
namespace {
// License protocol aliases
using KeyContainer = ::video_widevine::License::KeyContainer;
@@ -19,7 +20,7 @@ using ConstraintList =
// Map the HDCP protection associated with a key in the license to
// an equivalent OEMCrypto HDCP protection level
wvcdm::CryptoSession::HdcpCapability ProtobufHdcpToOemCryptoHdcp(
CryptoSession::HdcpCapability ProtobufHdcpToOemCryptoHdcp(
const OutputProtection::HDCP& input) {
switch (input) {
case OutputProtection::HDCP_NONE:
@@ -36,11 +37,46 @@ wvcdm::CryptoSession::HdcpCapability ProtobufHdcpToOemCryptoHdcp(
return HDCP_V2_3;
case OutputProtection::HDCP_NO_DIGITAL_OUTPUT:
return HDCP_NO_DIGITAL_OUTPUT;
default:
LOGE("Unknown HDCP Level, returning HDCP_NO_DIGITAL_OUTPUT: input = %d",
static_cast<int>(input));
return HDCP_NO_DIGITAL_OUTPUT;
}
LOGW("Unknown HDCP Level, returning HDCP_NO_DIGITAL_OUTPUT: input = %d",
static_cast<int>(input));
return HDCP_NO_DIGITAL_OUTPUT;
}
bool MeetsHdcpRequirements(const CryptoSession::HdcpCapability& required,
const CryptoSession::HdcpCapability& provided) {
if (provided == HDCP_NO_DIGITAL_OUTPUT) return true; // Always met.
switch (required) {
case HDCP_NONE:
return true; // Always met.
case HDCP_V1: // Means v1.x
// Can be any HDCP level other than NONE.
return provided != HDCP_NONE;
case HDCP_V2: // Means v2.0
case HDCP_V2_1:
case HDCP_V2_2:
case HDCP_V2_3:
// Must be equal to or higher than the required v2.x version.
return provided >= required && provided <= HDCP_V2_3;
case HDCP_V1_0:
case HDCP_V1_1:
case HDCP_V1_2:
case HDCP_V1_3:
case HDCP_V1_4:
// Must be equal to or higher than the required v1.x version,
// be exactly v1.x, or within the 2.x range. OEMCrypto may
// behave differently.
return (provided == HDCP_V1) ||
(provided >= required && provided <= HDCP_V1_4) ||
(provided >= HDCP_V2 && provided <= HDCP_V2_3);
case HDCP_NO_DIGITAL_OUTPUT:
// If |provided| was HDCP_NO_DIGITAL_OUTPUT, it would have been caught
// at the top of this function.
return false;
}
LOGE("Unknown required HDCP level: required = %d, provided = %d",
static_cast<int>(required), static_cast<int>(provided));
return false;
}
// Returns the constraint from a set of constraints that matches the
@@ -63,8 +99,6 @@ VideoResolutionConstraint* GetConstraintForRes(
} // namespace
namespace wvcdm {
bool LicenseKeys::IsContentKey(const std::string& key_id) {
if (key_statuses_.count(key_id) > 0) {
return key_statuses_[key_id]->IsContentKey();
@@ -199,12 +233,7 @@ void LicenseKeys::SetEntitledKeys(
}
LicenseKeyStatus::LicenseKeyStatus(const KeyContainer& key,
const CdmSecurityLevel security_level)
: is_content_key_(false),
key_status_(kKeyStatusInternalError),
meets_constraints_(true),
meets_security_level_constraints_(true),
default_hdcp_level_(HDCP_NONE) {
const CdmSecurityLevel security_level) {
allowed_usage_.Clear();
constraints_.Clear();
@@ -370,15 +399,14 @@ void LicenseKeyStatus::ApplyConstraints(
}
}
CryptoSession::HdcpCapability desired_hdcp_level;
CryptoSession::HdcpCapability desired_hdcp_level = default_hdcp_level_;
if (current_constraint && current_constraint->has_required_protection()) {
desired_hdcp_level = ProtobufHdcpToOemCryptoHdcp(
current_constraint->required_protection().hdcp());
} else {
desired_hdcp_level = default_hdcp_level_;
}
meets_constraints_ = (new_hdcp_level >= desired_hdcp_level);
meets_constraints_ =
MeetsHdcpRequirements(desired_hdcp_level, new_hdcp_level);
}
void LicenseKeyStatus::SetConstraints(const ConstraintList& constraints) {

View File

@@ -72,9 +72,9 @@ void PolicyEngine::CheckDeviceHdcpStatusOnTimer(int64_t current_time) {
void PolicyEngine::CheckDeviceHdcpStatus() {
if (!license_keys_->Empty()) {
CryptoSession::HdcpCapability current_hdcp_level;
CryptoSession::HdcpCapability ignored;
CdmResponseType status =
CryptoSession::HdcpCapability current_hdcp_level = HDCP_NONE;
CryptoSession::HdcpCapability ignored = HDCP_NONE;
const CdmResponseType status =
crypto_session_->GetHdcpCapabilities(&current_hdcp_level, &ignored);
if (status != NO_ERROR) {
current_hdcp_level = HDCP_NONE;