Clean up other core CDM logs.
[ Merge of http://go/wvgerrit/122613 ] Further log clean up in the core CDM code. - Changed several INFO logs to DEBUG and VERBOSE - Added more identifiers to the DEBUG logs to help match resource associations - Added more enum-to-string functions - Unknown enum values will be formatted to contain their numeric value Key areas improved are the UsageTableHeader and CdmSession. Bug: 183576879 Test: CE CDM unittests Change-Id: I2d11e714d419e0736d3e2f7a7668e8d36d7ef449
This commit is contained in:
@@ -66,6 +66,12 @@ class DeviceFiles {
|
||||
kLicenseNotPresent = kResponseTypeBase + 16,
|
||||
};
|
||||
|
||||
// Converts the different enum types to a human readable C-string for
|
||||
// logging.
|
||||
static const char* CertificateStateToString(CertificateState state);
|
||||
static const char* CertificateTypeToString(CertificateType type);
|
||||
static const char* ResponseTypeToString(ResponseType type);
|
||||
|
||||
// CdmLicenseData represents all of the data that is stored in CDM
|
||||
// license file. License data is uniquely keyed using |key_set_id|.
|
||||
struct CdmLicenseData {
|
||||
|
||||
@@ -798,9 +798,18 @@ class Key;
|
||||
// logging. Query strings values are used if available for the enum.
|
||||
// These functions will fail silently to avoid double logging.
|
||||
const char* CdmCertificateTypeToString(CdmCertificateType type);
|
||||
const char* CdmClientTokenTypeToString(CdmClientTokenType type);
|
||||
const char* CdmLicenseTypeToString(CdmLicenseType license_type);
|
||||
const char* CdmOfflineLicenseStateToString(
|
||||
CdmOfflineLicenseState license_state);
|
||||
const char* CdmSecurityLevelToString(CdmSecurityLevel security_level);
|
||||
const char* CdmUsageEntryStorageTypeToString(CdmUsageEntryStorageType type);
|
||||
const char* SecurityLevelToString(SecurityLevel security_level);
|
||||
// Converts a generic, unknown enum value to a string representation
|
||||
// containing its numeric value.
|
||||
// The pointer returned from this function is thread_local.
|
||||
const char* UnknownEnumValueToString(int value);
|
||||
|
||||
// Both IdToString() and IdPtrToString() functions are used to convert
|
||||
// session IDs, key set IDs or other CDM specific identifiers to a
|
||||
// loggable format.
|
||||
@@ -808,7 +817,6 @@ const char* IdToString(const std::string& id);
|
||||
// Some CDM API function allow for optional string parameters to be
|
||||
// provided as string pointers.
|
||||
const char* IdPtrToString(const std::string* id);
|
||||
|
||||
} // namespace wvcdm
|
||||
|
||||
#endif // WVCDM_CORE_WV_CDM_TYPES_H_
|
||||
|
||||
@@ -275,8 +275,9 @@ CdmResponseType CdmSession::RestoreOfflineSession(const CdmKeySetId& key_set_id,
|
||||
|
||||
if (!file_handle_->RetrieveLicense(key_set_id, &license_data,
|
||||
&sub_error_code)) {
|
||||
LOGE("Failed to retrieve license: sub_error_code = %d, key_set_id = %s",
|
||||
static_cast<int>(sub_error_code), key_set_id.c_str());
|
||||
LOGE("Failed to retrieve license: sub_error_code = %s, key_set_id = %s",
|
||||
DeviceFiles::ResponseTypeToString(sub_error_code),
|
||||
IdToString(key_set_id));
|
||||
SetErrorDetail(error_detail, sub_error_code);
|
||||
return sub_error_code == DeviceFiles::kFileNotFound ? KEYSET_ID_NOT_FOUND_4
|
||||
: GET_LICENSE_ERROR;
|
||||
@@ -308,8 +309,9 @@ CdmResponseType CdmSession::RestoreOfflineSession(const CdmKeySetId& key_set_id,
|
||||
// retry.
|
||||
if (!(license_type == kLicenseTypeRelease ||
|
||||
license_data.state == kLicenseStateActive)) {
|
||||
LOGE("Invalid offline license state: state = %d, license_type = %d",
|
||||
static_cast<int>(license_data.state), static_cast<int>(license_type));
|
||||
LOGE("Invalid offline license state: state = %s, license_type = %s",
|
||||
CdmOfflineLicenseStateToString(license_data.state),
|
||||
CdmLicenseTypeToString(license_type));
|
||||
return GET_RELEASED_LICENSE_ERROR;
|
||||
}
|
||||
|
||||
@@ -502,7 +504,8 @@ CdmResponseType CdmSession::GenerateKeyRequestInternal(
|
||||
|
||||
if (is_release_) {
|
||||
return GenerateReleaseRequest(key_request);
|
||||
} else if (license_received_) {
|
||||
}
|
||||
if (license_received_) {
|
||||
// A call to GenerateKeyRequest after the initial license has been received
|
||||
// is either a renewal/release request or a key rotation event
|
||||
if (init_data.contains_entitled_keys()) {
|
||||
@@ -510,41 +513,40 @@ CdmResponseType CdmSession::GenerateKeyRequestInternal(
|
||||
key_request->type = kKeyRequestTypeNone;
|
||||
key_request->url.clear();
|
||||
return license_parser_->HandleEmbeddedKeyData(init_data);
|
||||
} else {
|
||||
return GenerateRenewalRequest(key_request);
|
||||
}
|
||||
} else {
|
||||
key_request->type = kKeyRequestTypeInitial;
|
||||
|
||||
if (!init_data.is_supported()) {
|
||||
LOGW("Unsupported init data type: %s", init_data.type().c_str());
|
||||
return UNSUPPORTED_INIT_DATA;
|
||||
}
|
||||
if (init_data.IsEmpty() && !license_parser_->HasInitData()) {
|
||||
LOGW("Init data absent");
|
||||
return INIT_DATA_NOT_FOUND;
|
||||
}
|
||||
if (is_offline_ && key_set_id_.empty()) {
|
||||
LOGE("Unable to generate key set ID");
|
||||
return KEY_REQUEST_ERROR_1;
|
||||
}
|
||||
|
||||
CdmResponseType status = LoadPrivateKey();
|
||||
if (status != NO_ERROR) return status;
|
||||
|
||||
app_parameters_ = app_parameters;
|
||||
status = license_parser_->PrepareKeyRequest(
|
||||
init_data, drm_certificate_, license_type, app_parameters,
|
||||
&key_request->message, &key_request->url);
|
||||
if (status != KEY_MESSAGE) return status;
|
||||
|
||||
key_request_ = key_request->message;
|
||||
if (is_offline_) {
|
||||
offline_init_data_ = init_data.data();
|
||||
offline_release_server_url_ = key_request->url;
|
||||
}
|
||||
return KEY_MESSAGE;
|
||||
return GenerateRenewalRequest(key_request);
|
||||
}
|
||||
// Otherwise, initialize license request.
|
||||
key_request->type = kKeyRequestTypeInitial;
|
||||
|
||||
if (!init_data.is_supported()) {
|
||||
LOGW("Unsupported init data type: %s", init_data.type().c_str());
|
||||
return UNSUPPORTED_INIT_DATA;
|
||||
}
|
||||
if (init_data.IsEmpty() && !license_parser_->HasInitData()) {
|
||||
LOGW("Init data absent");
|
||||
return INIT_DATA_NOT_FOUND;
|
||||
}
|
||||
if (is_offline_ && key_set_id_.empty()) {
|
||||
LOGE("Key set ID not set");
|
||||
return KEY_REQUEST_ERROR_1;
|
||||
}
|
||||
// Attempt to load provisioned private key if available.
|
||||
CdmResponseType status = LoadPrivateKey();
|
||||
if (status != NO_ERROR) return status;
|
||||
|
||||
app_parameters_ = app_parameters;
|
||||
status = license_parser_->PrepareKeyRequest(
|
||||
init_data, drm_certificate_, license_type, app_parameters,
|
||||
&key_request->message, &key_request->url);
|
||||
if (status != KEY_MESSAGE) return status;
|
||||
|
||||
key_request_ = key_request->message;
|
||||
if (is_offline_) {
|
||||
offline_init_data_ = init_data.data();
|
||||
offline_release_server_url_ = key_request->url;
|
||||
}
|
||||
return KEY_MESSAGE;
|
||||
}
|
||||
|
||||
// This thin wrapper allows us to update metrics.
|
||||
@@ -562,80 +564,78 @@ CdmResponseType CdmSession::AddKeyInternal(const CdmKeyResponse& key_response) {
|
||||
}
|
||||
|
||||
if (is_release_) {
|
||||
CdmResponseType sts = ReleaseKey(key_response);
|
||||
const CdmResponseType sts = ReleaseKey(key_response);
|
||||
return (sts == NO_ERROR) ? KEY_ADDED : sts;
|
||||
} else if (license_received_) { // renewal
|
||||
}
|
||||
if (license_received_) { // renewal
|
||||
return RenewKey(key_response);
|
||||
} else {
|
||||
// If usage table header+entries are supported, preprocess the license
|
||||
// to see if it has a provider session token. If so a new entry needs
|
||||
// to be created.
|
||||
CdmResponseType sts;
|
||||
std::string provider_session_token;
|
||||
if (supports_usage_info()) {
|
||||
if (license_parser_->ExtractProviderSessionToken(
|
||||
key_response, &provider_session_token) &&
|
||||
!provider_session_token.empty()) {
|
||||
std::string app_id;
|
||||
GetApplicationId(&app_id);
|
||||
sts = usage_table_header_->AddEntry(
|
||||
crypto_session_.get(), is_offline_, key_set_id_,
|
||||
DeviceFiles::GetUsageInfoFileName(app_id), key_response,
|
||||
&usage_entry_number_);
|
||||
crypto_metrics_->usage_table_header_add_entry_.Increment(sts);
|
||||
if (sts != NO_ERROR) return sts;
|
||||
}
|
||||
}
|
||||
sts = license_parser_->HandleKeyResponse(/* is restore */ false,
|
||||
key_response);
|
||||
|
||||
// Update the license sdk and service versions.
|
||||
const VersionInfo& version_info = license_parser_->GetServiceVersion();
|
||||
metrics_->license_sdk_version_.Record(version_info.license_sdk_version());
|
||||
metrics_->license_sdk_version_.Record(
|
||||
version_info.license_service_version());
|
||||
|
||||
// Update or invalidate entry if usage table header+entries are supported
|
||||
if (!provider_session_token.empty() && supports_usage_info()) {
|
||||
if (sts != KEY_ADDED) {
|
||||
const CdmResponseType invalidate_sts =
|
||||
usage_table_header_->InvalidateEntry(
|
||||
usage_entry_number_, true, file_handle_.get(), crypto_metrics_);
|
||||
crypto_metrics_->usage_table_header_delete_entry_.Increment(
|
||||
invalidate_sts);
|
||||
if (invalidate_sts != NO_ERROR) {
|
||||
LOGW("Invalidate usage entry failed: status = %d",
|
||||
static_cast<int>(invalidate_sts));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sts != KEY_ADDED) return (sts == KEY_ERROR) ? ADD_KEY_ERROR : sts;
|
||||
|
||||
license_received_ = true;
|
||||
key_response_ = key_response;
|
||||
|
||||
LOGV("Key added: provider_session_token = %s (size = %zu)",
|
||||
license_parser_->provider_session_token().c_str(),
|
||||
license_parser_->provider_session_token().size());
|
||||
|
||||
if ((is_offline_ || has_provider_session_token()) && !is_temporary_) {
|
||||
if (has_provider_session_token() && supports_usage_info()) {
|
||||
usage_table_header_->UpdateEntry(usage_entry_number_,
|
||||
crypto_session_.get(), &usage_entry_);
|
||||
}
|
||||
|
||||
if (!is_offline_)
|
||||
usage_provider_session_token_ =
|
||||
license_parser_->provider_session_token();
|
||||
|
||||
sts = StoreLicense();
|
||||
}
|
||||
// If usage table header+entries are supported, preprocess the license
|
||||
// to see if it has a provider session token. If so a new entry needs
|
||||
// to be created.
|
||||
CdmResponseType sts;
|
||||
std::string provider_session_token;
|
||||
if (supports_usage_info()) {
|
||||
if (license_parser_->ExtractProviderSessionToken(key_response,
|
||||
&provider_session_token) &&
|
||||
!provider_session_token.empty()) {
|
||||
std::string app_id;
|
||||
GetApplicationId(&app_id);
|
||||
sts = usage_table_header_->AddEntry(
|
||||
crypto_session_.get(), is_offline_, key_set_id_,
|
||||
DeviceFiles::GetUsageInfoFileName(app_id), key_response,
|
||||
&usage_entry_number_);
|
||||
crypto_metrics_->usage_table_header_add_entry_.Increment(sts);
|
||||
if (sts != NO_ERROR) return sts;
|
||||
}
|
||||
has_license_been_loaded_ = true;
|
||||
|
||||
return KEY_ADDED;
|
||||
}
|
||||
sts =
|
||||
license_parser_->HandleKeyResponse(/* is restore */ false, key_response);
|
||||
|
||||
// Update the license sdk and service versions.
|
||||
const VersionInfo& version_info = license_parser_->GetServiceVersion();
|
||||
metrics_->license_sdk_version_.Record(version_info.license_sdk_version());
|
||||
metrics_->license_sdk_version_.Record(version_info.license_service_version());
|
||||
|
||||
// Update or invalidate entry if usage table header+entries are supported
|
||||
if (!provider_session_token.empty() && supports_usage_info()) {
|
||||
if (sts != KEY_ADDED) {
|
||||
const CdmResponseType invalidate_sts =
|
||||
usage_table_header_->InvalidateEntry(
|
||||
usage_entry_number_, true, file_handle_.get(), crypto_metrics_);
|
||||
crypto_metrics_->usage_table_header_delete_entry_.Increment(
|
||||
invalidate_sts);
|
||||
if (invalidate_sts != NO_ERROR) {
|
||||
LOGW("Invalidate usage entry failed: status = %d",
|
||||
static_cast<int>(invalidate_sts));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sts != KEY_ADDED) return (sts == KEY_ERROR) ? ADD_KEY_ERROR : sts;
|
||||
|
||||
license_received_ = true;
|
||||
key_response_ = key_response;
|
||||
|
||||
LOGV("Key added: provider_session_token = %s (size = %zu)",
|
||||
IdToString(license_parser_->provider_session_token()),
|
||||
license_parser_->provider_session_token().size());
|
||||
|
||||
if ((is_offline_ || has_provider_session_token()) && !is_temporary_) {
|
||||
if (has_provider_session_token() && supports_usage_info()) {
|
||||
usage_table_header_->UpdateEntry(usage_entry_number_,
|
||||
crypto_session_.get(), &usage_entry_);
|
||||
}
|
||||
|
||||
if (!is_offline_)
|
||||
usage_provider_session_token_ = license_parser_->provider_session_token();
|
||||
|
||||
sts = StoreLicense();
|
||||
if (sts != NO_ERROR) return sts;
|
||||
}
|
||||
has_license_been_loaded_ = true;
|
||||
|
||||
return KEY_ADDED;
|
||||
}
|
||||
|
||||
CdmResponseType CdmSession::QueryStatus(CdmQueryMap* query_response) {
|
||||
@@ -1289,5 +1289,4 @@ void CdmSession::set_policy_engine(PolicyEngine* policy_engine) {
|
||||
void CdmSession::set_file_handle(DeviceFiles* file_handle) {
|
||||
file_handle_.reset(file_handle);
|
||||
}
|
||||
|
||||
} // namespace wvcdm
|
||||
|
||||
@@ -509,8 +509,8 @@ CdmSecurityLevel CryptoSession::GetSecurityLevel(
|
||||
if (length != kExpectedSecurityLevelLength) {
|
||||
LOGE(
|
||||
"Unexpected security level length: "
|
||||
"length = %zu, requested_security_level = %d",
|
||||
length, static_cast<int>(requested_security_level));
|
||||
"length = %zu, requested_security_level = %s",
|
||||
length, SecurityLevelToString(requested_security_level));
|
||||
return kSecurityLevelUnknown;
|
||||
}
|
||||
const std::string security_level(level);
|
||||
@@ -525,8 +525,8 @@ CdmSecurityLevel CryptoSession::GetSecurityLevel(
|
||||
}
|
||||
LOGE(
|
||||
"Ill-formed security level: "
|
||||
"level = \"%s\", requested_security_level = %d",
|
||||
security_level.c_str(), static_cast<int>(requested_security_level));
|
||||
"level = \"%s\", requested_security_level = %s",
|
||||
security_level.c_str(), SecurityLevelToString(requested_security_level));
|
||||
return kSecurityLevelUnknown;
|
||||
}
|
||||
|
||||
@@ -673,8 +673,8 @@ CdmResponseType CryptoSession::GetSystemIdInternal(uint32_t* system_id) {
|
||||
uint32_t* id = reinterpret_cast<uint32_t*>(&token[4]);
|
||||
*system_id = ntohl(*id);
|
||||
return NO_ERROR;
|
||||
|
||||
} else if (pre_provision_token_type_ == kClientTokenOemCert) {
|
||||
}
|
||||
if (pre_provision_token_type_ == kClientTokenOemCert) {
|
||||
// Get the OEM Cert
|
||||
std::string oem_cert;
|
||||
CdmResponseType status = GetTokenFromOemCert(&oem_cert);
|
||||
@@ -685,16 +685,15 @@ CdmResponseType CryptoSession::GetSystemIdInternal(uint32_t* system_id) {
|
||||
return EXTRACT_SYSTEM_ID_FROM_OEM_CERT_ERROR;
|
||||
|
||||
return NO_ERROR;
|
||||
|
||||
}
|
||||
if (pre_provision_token_type_ == kClientTokenDrmCert) {
|
||||
// TODO(blueeyes): Support loading the system id from a pre-provisioned
|
||||
// Drm certificate.
|
||||
} else if (pre_provision_token_type_ == kClientTokenDrmCert) {
|
||||
return NO_ERROR;
|
||||
} else {
|
||||
LOGE("Unsupported pre-provision token type: %d",
|
||||
static_cast<int>(pre_provision_token_type_));
|
||||
return UNKNOWN_CLIENT_TOKEN_TYPE;
|
||||
}
|
||||
LOGE("Unsupported pre-provision token type: %d",
|
||||
static_cast<int>(pre_provision_token_type_));
|
||||
return UNKNOWN_CLIENT_TOKEN_TYPE;
|
||||
}
|
||||
|
||||
bool CryptoSession::ExtractSystemIdFromOemCert(const std::string& oem_cert,
|
||||
@@ -721,7 +720,8 @@ CdmResponseType CryptoSession::GetProvisioningId(std::string* provisioning_id) {
|
||||
}
|
||||
|
||||
return NO_ERROR;
|
||||
} else if (pre_provision_token_type_ == kClientTokenKeybox) {
|
||||
}
|
||||
if (pre_provision_token_type_ == kClientTokenKeybox) {
|
||||
std::string token;
|
||||
CdmResponseType status = GetTokenFromKeybox(&token);
|
||||
|
||||
@@ -734,11 +734,10 @@ CdmResponseType CryptoSession::GetProvisioningId(std::string* provisioning_id) {
|
||||
|
||||
provisioning_id->assign(reinterpret_cast<char*>(&token[8]), 16);
|
||||
return NO_ERROR;
|
||||
} else {
|
||||
LOGE("Unsupported pre-provision token type: %d",
|
||||
static_cast<int>(pre_provision_token_type_));
|
||||
return UNKNOWN_CLIENT_TOKEN_TYPE;
|
||||
}
|
||||
LOGE("Unsupported pre-provision token type: %d",
|
||||
static_cast<int>(pre_provision_token_type_));
|
||||
return UNKNOWN_CLIENT_TOKEN_TYPE;
|
||||
}
|
||||
|
||||
uint8_t CryptoSession::GetSecurityPatchLevel() {
|
||||
|
||||
@@ -85,8 +85,8 @@ using video_widevine_client::sdk::
|
||||
return false; \
|
||||
}
|
||||
|
||||
namespace wvcdm {
|
||||
namespace {
|
||||
|
||||
const char kEmptyFileName[] = "";
|
||||
const char kFalse[] = "false";
|
||||
const char kHlsAttributesFileNameExt[] = ".hal";
|
||||
@@ -100,21 +100,21 @@ constexpr int64_t kFourMonthsInSeconds = (2 * 30 + 2 * 31) * 24 * 60 * 60;
|
||||
|
||||
// Helper methods
|
||||
bool SetDeviceCertificate(const std::string& certificate,
|
||||
const wvcdm::CryptoWrappedKey& private_key,
|
||||
const CryptoWrappedKey& private_key,
|
||||
DeviceCertificate* mutable_device_certificate) {
|
||||
RETURN_FALSE_IF_NULL(mutable_device_certificate);
|
||||
|
||||
mutable_device_certificate->set_certificate(certificate);
|
||||
mutable_device_certificate->set_wrapped_private_key(private_key.key());
|
||||
switch (private_key.type()) {
|
||||
case wvcdm::CryptoWrappedKey::kRsa:
|
||||
case CryptoWrappedKey::kRsa:
|
||||
mutable_device_certificate->set_key_type(DeviceCertificate::RSA);
|
||||
return true;
|
||||
case wvcdm::CryptoWrappedKey::kEcc:
|
||||
case CryptoWrappedKey::kEcc:
|
||||
mutable_device_certificate->set_key_type(DeviceCertificate::ECC);
|
||||
return true;
|
||||
case wvcdm::CryptoWrappedKey::kUninitialized: // Suppress compiler
|
||||
// warnings.
|
||||
case CryptoWrappedKey::kUninitialized: // Suppress compiler
|
||||
// warnings.
|
||||
default:
|
||||
LOGE("Unexpected key type: %d", private_key.type());
|
||||
return false;
|
||||
@@ -123,7 +123,7 @@ bool SetDeviceCertificate(const std::string& certificate,
|
||||
|
||||
bool ExtractFromDeviceCertificate(const DeviceCertificate& device_certificate,
|
||||
std::string* certificate,
|
||||
wvcdm::CryptoWrappedKey* private_key) {
|
||||
CryptoWrappedKey* private_key) {
|
||||
RETURN_FALSE_IF_NULL(certificate);
|
||||
RETURN_FALSE_IF_NULL(private_key);
|
||||
|
||||
@@ -161,29 +161,29 @@ bool ExtractFromDeviceCertificate(const DeviceCertificate& device_certificate,
|
||||
device_certificate.key_type();
|
||||
switch (key_type) {
|
||||
case DeviceCertificate::RSA:
|
||||
private_key->set_type(wvcdm::CryptoWrappedKey::kRsa);
|
||||
private_key->set_type(CryptoWrappedKey::kRsa);
|
||||
break;
|
||||
case DeviceCertificate::ECC:
|
||||
private_key->set_type(wvcdm::CryptoWrappedKey::kEcc);
|
||||
private_key->set_type(CryptoWrappedKey::kEcc);
|
||||
break;
|
||||
default:
|
||||
LOGW("Unknown DRM key type, defaulting to RSA: type = %d", key_type);
|
||||
private_key->set_type(wvcdm::CryptoWrappedKey::kRsa);
|
||||
private_key->set_type(CryptoWrappedKey::kRsa);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// Possible that device certificate is from V15, in this case, the
|
||||
// only supported key of at that time was RSA.
|
||||
LOGD("No key type info, assuming RSA");
|
||||
private_key->set_type(wvcdm::CryptoWrappedKey::kRsa);
|
||||
private_key->set_type(CryptoWrappedKey::kRsa);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FindOrInsertUsageCertificate(
|
||||
const std::string& drm_certificate,
|
||||
const wvcdm::CryptoWrappedKey& wrapped_private_key, UsageInfo* usage_info,
|
||||
uint32_t* drm_certificate_id) {
|
||||
bool FindOrInsertUsageCertificate(const std::string& drm_certificate,
|
||||
const CryptoWrappedKey& wrapped_private_key,
|
||||
UsageInfo* usage_info,
|
||||
uint32_t* drm_certificate_id) {
|
||||
RETURN_FALSE_IF_NULL(usage_info);
|
||||
RETURN_FALSE_IF_NULL(drm_certificate_id);
|
||||
|
||||
@@ -228,8 +228,7 @@ bool FindUsageCertificate(
|
||||
uint32_t drm_certificate_id,
|
||||
const google::protobuf::RepeatedPtrField<UsageInfo_DrmUsageCertificate>&
|
||||
drm_certificate_cache,
|
||||
std::string* drm_certificate,
|
||||
wvcdm::CryptoWrappedKey* wrapped_private_key) {
|
||||
std::string* drm_certificate, CryptoWrappedKey* wrapped_private_key) {
|
||||
for (const UsageInfo_DrmUsageCertificate& drm_usage_cert :
|
||||
drm_certificate_cache) {
|
||||
if (drm_usage_cert.drm_certificate_id() == drm_certificate_id) {
|
||||
@@ -285,10 +284,80 @@ bool UsageCertificateCacheCleanUp(UsageInfo* usage_info) {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace wvcdm {
|
||||
// static
|
||||
const char* DeviceFiles::CertificateStateToString(CertificateState state) {
|
||||
switch (state) {
|
||||
case kCertificateValid:
|
||||
return "Valid";
|
||||
case kCertificateExpired:
|
||||
return "Expired";
|
||||
case kCertificateNotFound:
|
||||
return "NotFound";
|
||||
case kCertificateInvalid:
|
||||
return "Invalid";
|
||||
case kCannotHandle:
|
||||
return "CannotHandle";
|
||||
}
|
||||
return UnknownEnumValueToString(static_cast<int>(state));
|
||||
}
|
||||
|
||||
// static
|
||||
const char* DeviceFiles::CertificateTypeToString(CertificateType type) {
|
||||
switch (type) {
|
||||
case kCertificateDefault:
|
||||
return "Default";
|
||||
case kCertificateLegacy:
|
||||
return "Legacy";
|
||||
case kCertificateAtsc:
|
||||
return "ATSC";
|
||||
}
|
||||
return UnknownEnumValueToString(static_cast<int>(type));
|
||||
}
|
||||
|
||||
// static
|
||||
const char* DeviceFiles::ResponseTypeToString(ResponseType type) {
|
||||
switch (type) {
|
||||
case kNoError:
|
||||
return "NoError";
|
||||
case kObjectNotInitialized:
|
||||
return "ObjectNotInitialized";
|
||||
case kParameterNull:
|
||||
return "ParameterNull";
|
||||
case kBasePathUnavailable:
|
||||
return "PathUnavailable";
|
||||
case kFileNotFound:
|
||||
return "NotFound";
|
||||
case kFileOpenFailed:
|
||||
return "OpenFailed";
|
||||
case kFileWriteError:
|
||||
return "WriteError";
|
||||
case kFileReadError:
|
||||
return "ReadError";
|
||||
case kInvalidFileSize:
|
||||
return "InvalidFileSize";
|
||||
case kHashComputationFailed:
|
||||
return "HashFailed";
|
||||
case kFileHashMismatch:
|
||||
return "HashMismatch";
|
||||
case kFileParseError1:
|
||||
return "ParseHashedFileError";
|
||||
case kFileParseError2:
|
||||
return "ParseFileError";
|
||||
case kUnknownLicenseState:
|
||||
return "UnknownLicenseState";
|
||||
case kIncorrectFileType:
|
||||
return "IncorrectFileType";
|
||||
case kIncorrectFileVersion:
|
||||
return "IncorrectFileVersion";
|
||||
case kLicenseNotPresent:
|
||||
return "LicenseNotFound";
|
||||
case kResponseTypeBase: // Not a valid value.
|
||||
break;
|
||||
}
|
||||
return UnknownEnumValueToString(static_cast<int>(type));
|
||||
}
|
||||
|
||||
// static
|
||||
std::set<std::string> DeviceFiles::reserved_license_ids_;
|
||||
@@ -671,8 +740,8 @@ bool DeviceFiles::RetrieveLicense(const std::string& key_set_id,
|
||||
video_widevine_client::sdk::File file;
|
||||
*result = RetrieveHashedFile(key_set_id + kLicenseFileNameExt, &file);
|
||||
if (*result != kNoError) {
|
||||
LOGE("Unable to retrieve key set license file: result = %d",
|
||||
static_cast<int>(*result));
|
||||
LOGE("Unable to retrieve key set license file: result = %s",
|
||||
ResponseTypeToString(*result));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1771,7 +1840,7 @@ std::string DeviceFiles::GetUsageInfoFileName(const std::string& app_id) {
|
||||
}
|
||||
|
||||
std::string DeviceFiles::GetFileNameSafeHash(const std::string& input) {
|
||||
return wvcdm::Base64SafeEncode(Md5Hash(input));
|
||||
return Base64SafeEncode(Md5Hash(input));
|
||||
}
|
||||
|
||||
} // namespace wvcdm
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#include "wv_cdm_constants.h"
|
||||
|
||||
namespace wvcdm {
|
||||
|
||||
namespace {
|
||||
std::string kEmptyString;
|
||||
wvcdm::CdmKeySetId kDummyKeySetId = "DummyKsid";
|
||||
@@ -89,8 +88,8 @@ bool RetrieveOfflineLicense(DeviceFiles* device_files,
|
||||
DeviceFiles::CdmLicenseData license_data;
|
||||
DeviceFiles::ResponseType result = DeviceFiles::kNoError;
|
||||
if (!device_files->RetrieveLicense(key_set_id, &license_data, &result)) {
|
||||
LOGW("Failed to retrieve license: key_set_id = %s, result = %d",
|
||||
key_set_id.c_str(), static_cast<int>(result));
|
||||
LOGW("Failed to retrieve license: key_set_id = %s, result = %s",
|
||||
IdToString(key_set_id), DeviceFiles::ResponseTypeToString(result));
|
||||
return false;
|
||||
}
|
||||
*license_message = std::move(license_data.license);
|
||||
@@ -127,7 +126,7 @@ bool RetrieveUsageInfoLicense(DeviceFiles* device_files,
|
||||
LOGW(
|
||||
"Failed to retrieve usage information: "
|
||||
"key_set_id = %s, usage_info_file_name = %s",
|
||||
key_set_id.c_str(), usage_info_file_name.c_str());
|
||||
IdToString(key_set_id), IdToString(usage_info_file_name));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -155,8 +154,7 @@ UsageTableHeader::UsageTableHeader()
|
||||
|
||||
bool UsageTableHeader::Init(CdmSecurityLevel security_level,
|
||||
CryptoSession* crypto_session) {
|
||||
LOGI("Initializing usage table header: security_level = %d",
|
||||
static_cast<int>(security_level));
|
||||
LOGD("security_level = %s", CdmSecurityLevelToString(security_level));
|
||||
if (crypto_session == nullptr) {
|
||||
LOGE("No crypto session provided");
|
||||
return false;
|
||||
@@ -184,8 +182,8 @@ bool UsageTableHeader::Init(CdmSecurityLevel security_level,
|
||||
kMinimumUsageTableEntriesSupported);
|
||||
potential_table_capacity_ = kMinimumUsageTableEntriesSupported;
|
||||
} else if (potential_table_capacity_ == 0) {
|
||||
LOGD("Usage table capacity is unlimited: security_level = %d",
|
||||
static_cast<int>(security_level));
|
||||
LOGD("Usage table capacity is unlimited: security_level = %s",
|
||||
CdmSecurityLevelToString(security_level));
|
||||
} else if (potential_table_capacity_ < kMinimumUsageTableEntriesSupported) {
|
||||
LOGW(
|
||||
"Reported usage table capacity is smaller than minimally required: "
|
||||
@@ -193,8 +191,8 @@ bool UsageTableHeader::Init(CdmSecurityLevel security_level,
|
||||
potential_table_capacity_, kMinimumUsageTableEntriesSupported);
|
||||
potential_table_capacity_ = kMinimumUsageTableEntriesSupported;
|
||||
} else {
|
||||
LOGD("Usage table capacity: %zu, security_level = %d",
|
||||
potential_table_capacity_, static_cast<int>(security_level));
|
||||
LOGD("Usage table capacity: %zu, security_level = %s",
|
||||
potential_table_capacity_, CdmSecurityLevelToString(security_level));
|
||||
}
|
||||
|
||||
if (!device_files_->Init(security_level)) {
|
||||
@@ -278,16 +276,17 @@ bool UsageTableHeader::Init(CdmSecurityLevel security_level,
|
||||
if (result != NO_ERROR) {
|
||||
LOGE(
|
||||
"Unable to create/delete new entry, clearing usage entries: "
|
||||
"security_level = %d, usage_entry_count = %zu",
|
||||
static_cast<int>(security_level), usage_entry_info_.size());
|
||||
"security_level = %s, usage_entry_count = %zu",
|
||||
CdmSecurityLevelToString(security_level),
|
||||
usage_entry_info_.size());
|
||||
status = result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (status != NO_ERROR || !lru_success) {
|
||||
LOGE("Failed to load usage table: security_level = %d, status = %d",
|
||||
static_cast<int>(security_level), static_cast<int>(status));
|
||||
LOGE("Failed to load usage table: security_level = %s, status = %d",
|
||||
CdmSecurityLevelToString(security_level), static_cast<int>(status));
|
||||
device_files_->DeleteAllLicenses();
|
||||
device_files_->DeleteAllUsageInfo();
|
||||
device_files_->DeleteUsageTableInfo();
|
||||
@@ -313,7 +312,10 @@ CdmResponseType UsageTableHeader::AddEntry(
|
||||
CryptoSession* crypto_session, bool persistent_license,
|
||||
const CdmKeySetId& key_set_id, const std::string& usage_info_file_name,
|
||||
const CdmKeyResponse& license_message, uint32_t* usage_entry_number) {
|
||||
LOGI("Adding usage entry");
|
||||
LOGD("oec_session_id = %u, type = %s, current_size = %zu",
|
||||
crypto_session->oec_session_id(),
|
||||
persistent_license ? "OfflineLicense" : "Streaming",
|
||||
usage_entry_info_.size());
|
||||
|
||||
metrics::CryptoMetrics* metrics = crypto_session->GetCryptoMetrics();
|
||||
if (metrics == nullptr) metrics = &alternate_crypto_metrics_;
|
||||
@@ -331,7 +333,7 @@ CdmResponseType UsageTableHeader::AddEntry(
|
||||
|
||||
if (status != NO_ERROR) return status;
|
||||
|
||||
LOGI("Locking to add entry");
|
||||
LOGV("Locking to add entry");
|
||||
std::unique_lock<std::mutex> auto_lock(usage_table_header_lock_);
|
||||
if (*usage_entry_number < usage_entry_info_.size()) {
|
||||
LOGE(
|
||||
@@ -402,7 +404,7 @@ CdmResponseType UsageTableHeader::LoadEntry(CryptoSession* crypto_session,
|
||||
const CdmUsageEntry& usage_entry,
|
||||
uint32_t usage_entry_number) {
|
||||
{
|
||||
LOGI("Locking to load entry: usage_entry_number = %u", usage_entry_number);
|
||||
LOGD("usage_entry_number = %u", usage_entry_number);
|
||||
std::unique_lock<std::mutex> auto_lock(usage_table_header_lock_);
|
||||
|
||||
if (usage_entry_number >= usage_entry_info_.size()) {
|
||||
@@ -429,7 +431,7 @@ CdmResponseType UsageTableHeader::LoadEntry(CryptoSession* crypto_session,
|
||||
CdmResponseType UsageTableHeader::UpdateEntry(uint32_t usage_entry_number,
|
||||
CryptoSession* crypto_session,
|
||||
CdmUsageEntry* usage_entry) {
|
||||
LOGI("Locking to update entry");
|
||||
LOGD("usage_entry_number = %u", usage_entry_number);
|
||||
std::unique_lock<std::mutex> auto_lock(usage_table_header_lock_);
|
||||
if (usage_entry_number >= usage_entry_info_.size()) {
|
||||
LOGE("Usage entry number %u is larger than usage entry size %zu",
|
||||
@@ -450,8 +452,7 @@ CdmResponseType UsageTableHeader::UpdateEntry(uint32_t usage_entry_number,
|
||||
CdmResponseType UsageTableHeader::InvalidateEntry(
|
||||
uint32_t usage_entry_number, bool defrag_table, DeviceFiles* device_files,
|
||||
metrics::CryptoMetrics* metrics) {
|
||||
LOGI("Locking to invalidate entry: usage_entry_number = %u",
|
||||
usage_entry_number);
|
||||
LOGD("usage_entry_number = %u", usage_entry_number);
|
||||
std::unique_lock<std::mutex> auto_lock(usage_table_header_lock_);
|
||||
// OEMCrypto does not have any concept of "deleting" an entry.
|
||||
// Instead, the CDM marks the entry's meta data as invalid (storage
|
||||
@@ -494,14 +495,14 @@ CdmResponseType UsageTableHeader::InvalidateEntry(
|
||||
}
|
||||
|
||||
size_t UsageTableHeader::UsageInfoCount() const {
|
||||
LOGI("Locking to count usage info (streaming license) entries");
|
||||
LOGV("Locking to count usage info (streaming license) entries");
|
||||
std::unique_lock<std::mutex> auto_lock(usage_table_header_lock_);
|
||||
return std::count_if(usage_entry_info_.cbegin(), usage_entry_info_.cend(),
|
||||
EntryIsUsageInfo);
|
||||
}
|
||||
|
||||
size_t UsageTableHeader::OfflineEntryCount() const {
|
||||
LOGI("Locking to count offline license entries");
|
||||
LOGV("Locking to count offline license entries");
|
||||
std::unique_lock<std::mutex> auto_lock(usage_table_header_lock_);
|
||||
return std::count_if(usage_entry_info_.cbegin(), usage_entry_info_.cend(),
|
||||
EntryIsOfflineLicense);
|
||||
@@ -511,10 +512,8 @@ CdmResponseType UsageTableHeader::MoveEntry(
|
||||
uint32_t from_usage_entry_number, const CdmUsageEntry& from_usage_entry,
|
||||
uint32_t to_usage_entry_number, DeviceFiles* device_files,
|
||||
metrics::CryptoMetrics* metrics) {
|
||||
LOGI(
|
||||
"Moving usage entry: "
|
||||
"from_usage_entry_number = %u, to_usage_entry_number = %u",
|
||||
from_usage_entry_number, to_usage_entry_number);
|
||||
LOGD("from_usage_entry_number = %u, to_usage_entry_number = %u",
|
||||
from_usage_entry_number, to_usage_entry_number);
|
||||
|
||||
// crypto_session points to an object whose scope is this method or a test
|
||||
// object whose scope is the lifetime of this class
|
||||
@@ -574,11 +573,11 @@ CdmResponseType UsageTableHeader::MoveEntry(
|
||||
CdmResponseType UsageTableHeader::GetEntry(uint32_t usage_entry_number,
|
||||
DeviceFiles* device_files,
|
||||
CdmUsageEntry* usage_entry) {
|
||||
LOGI("Getting usage entry: usage_entry_number = %u, storage_type: %d",
|
||||
usage_entry_number,
|
||||
static_cast<int>(usage_entry_number < usage_entry_info_.size()
|
||||
? usage_entry_info_[usage_entry_number].storage_type
|
||||
: kStorageTypeUnknown));
|
||||
LOGD("Getting usage_entry_number = %u, storage_type = %s", usage_entry_number,
|
||||
CdmUsageEntryStorageTypeToString(
|
||||
usage_entry_number < usage_entry_info_.size()
|
||||
? usage_entry_info_[usage_entry_number].storage_type
|
||||
: kStorageTypeUnknown));
|
||||
uint32_t entry_number;
|
||||
switch (usage_entry_info_[usage_entry_number].storage_type) {
|
||||
case kStorageLicense: {
|
||||
@@ -636,11 +635,11 @@ CdmResponseType UsageTableHeader::GetEntry(uint32_t usage_entry_number,
|
||||
CdmResponseType UsageTableHeader::StoreEntry(uint32_t usage_entry_number,
|
||||
DeviceFiles* device_files,
|
||||
const CdmUsageEntry& usage_entry) {
|
||||
LOGI("Storing usage entry: usage_entry_number = %u, storage type: %d",
|
||||
usage_entry_number,
|
||||
static_cast<int>(usage_entry_number < usage_entry_info_.size()
|
||||
? usage_entry_info_[usage_entry_number].storage_type
|
||||
: kStorageTypeUnknown));
|
||||
LOGD("usage_entry_number = %u, storage_type = %s", usage_entry_number,
|
||||
CdmUsageEntryStorageTypeToString(
|
||||
usage_entry_number < usage_entry_info_.size()
|
||||
? usage_entry_info_[usage_entry_number].storage_type
|
||||
: kStorageTypeUnknown));
|
||||
|
||||
switch (usage_entry_info_[usage_entry_number].storage_type) {
|
||||
case kStorageLicense: {
|
||||
@@ -650,8 +649,8 @@ CdmResponseType UsageTableHeader::StoreEntry(uint32_t usage_entry_number,
|
||||
if (!device_files->RetrieveLicense(
|
||||
usage_entry_info_[usage_entry_number].key_set_id, &license_data,
|
||||
&sub_error_code)) {
|
||||
LOGE("Failed to retrieve license: status = %d",
|
||||
static_cast<int>(sub_error_code));
|
||||
LOGE("Failed to retrieve license: status = %s",
|
||||
DeviceFiles::ResponseTypeToString(sub_error_code));
|
||||
return USAGE_STORE_ENTRY_RETRIEVE_LICENSE_FAILED;
|
||||
}
|
||||
|
||||
@@ -660,8 +659,8 @@ CdmResponseType UsageTableHeader::StoreEntry(uint32_t usage_entry_number,
|
||||
license_data.usage_entry_number = usage_entry_number;
|
||||
|
||||
if (!device_files->StoreLicense(license_data, &sub_error_code)) {
|
||||
LOGE("Failed to store license: status = %d",
|
||||
static_cast<int>(sub_error_code));
|
||||
LOGE("Failed to store license: status = %s",
|
||||
DeviceFiles::ResponseTypeToString(sub_error_code));
|
||||
return USAGE_STORE_LICENSE_FAILED;
|
||||
}
|
||||
break;
|
||||
@@ -720,8 +719,8 @@ bool UsageTableHeader::StoreTable(DeviceFiles* device_files) {
|
||||
CdmResponseType UsageTableHeader::Shrink(
|
||||
metrics::CryptoMetrics* metrics,
|
||||
uint32_t number_of_usage_entries_to_delete) {
|
||||
LOGI("Shrinking usage table: table_size = %zu, number_to_delete = %u",
|
||||
usage_entry_info_.size(), number_of_usage_entries_to_delete);
|
||||
LOGD("table_size = %zu, number_to_delete = %u", usage_entry_info_.size(),
|
||||
number_of_usage_entries_to_delete);
|
||||
if (usage_entry_info_.empty()) {
|
||||
LOGE("Usage entry info table unexpectedly empty");
|
||||
return NO_USAGE_ENTRIES;
|
||||
@@ -760,7 +759,7 @@ CdmResponseType UsageTableHeader::Shrink(
|
||||
|
||||
CdmResponseType UsageTableHeader::DefragTable(DeviceFiles* device_files,
|
||||
metrics::CryptoMetrics* metrics) {
|
||||
LOGV("Defragging table: current_size = %zu", usage_entry_info_.size());
|
||||
LOGV("current_size = %zu", usage_entry_info_.size());
|
||||
// Defragging the usage table involves moving valid entries near the
|
||||
// end of the usage table to the position of invalid entries near the
|
||||
// front of the table. After the entries are moved, the CDM shrinks
|
||||
@@ -1013,7 +1012,7 @@ CdmResponseType UsageTableHeader::ReleaseOldestEntry(
|
||||
|
||||
// Test only method.
|
||||
void UsageTableHeader::InvalidateEntryForTest(uint32_t usage_entry_number) {
|
||||
LOGV("Deleting entry for test: usage_entry_number = %u", usage_entry_number);
|
||||
LOGV("usage_entry_number = %u", usage_entry_number);
|
||||
if (usage_entry_number >= usage_entry_info_.size()) {
|
||||
LOGE(
|
||||
"Requested usage entry number is larger than table size: "
|
||||
@@ -1150,7 +1149,7 @@ bool UsageTableHeader::LruUpgradeAllUsageEntries() {
|
||||
}
|
||||
|
||||
bool UsageTableHeader::GetRemovalCandidate(uint32_t* entry_to_remove) {
|
||||
LOGI("Locking to determine removal candidates");
|
||||
LOGV("Locking to determine removal candidates");
|
||||
std::unique_lock<std::mutex> auto_lock(usage_table_header_lock_);
|
||||
const size_t lru_unexpired_threshold =
|
||||
HasUnlimitedTableCapacity()
|
||||
|
||||
@@ -3,13 +3,26 @@
|
||||
// Agreement.
|
||||
#include "wv_cdm_types.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <threads.h>
|
||||
|
||||
#include "wv_cdm_constants.h"
|
||||
|
||||
namespace wvcdm {
|
||||
namespace {
|
||||
const char kEmptyIdRep[] = "<empty>";
|
||||
const char kNullIdRep[] = "<null>";
|
||||
const char kUnknownValueRep[] = "<unknown>";
|
||||
|
||||
// Thread local buffer used by UnknownEnumValueToString() to represent
|
||||
// unknown enum values.
|
||||
thread_local char tl_unknown_rep_buf[32];
|
||||
|
||||
// Helper template function for casting enums to raw integer before
|
||||
// formatting into a string representation.
|
||||
template <typename EnumType>
|
||||
const char* UnknownValueRep(EnumType value) {
|
||||
return UnknownEnumValueToString(static_cast<int>(value));
|
||||
}
|
||||
} // namespace
|
||||
|
||||
const char* CdmCertificateTypeToString(CdmCertificateType type) {
|
||||
@@ -19,7 +32,21 @@ const char* CdmCertificateTypeToString(CdmCertificateType type) {
|
||||
case kCertificateX509:
|
||||
return "x509";
|
||||
}
|
||||
return kUnknownValueRep;
|
||||
return UnknownValueRep(type);
|
||||
}
|
||||
|
||||
const char* CdmClientTokenTypeToString(CdmClientTokenType type) {
|
||||
switch (type) {
|
||||
case kClientTokenKeybox:
|
||||
return "Keybox";
|
||||
case kClientTokenDrmCert:
|
||||
return "DrmCert";
|
||||
case kClientTokenOemCert:
|
||||
return "OemCert";
|
||||
case kClientTokenUninitialized:
|
||||
return "Uninitialized";
|
||||
}
|
||||
return UnknownValueRep(type);
|
||||
}
|
||||
|
||||
const char* CdmLicenseTypeToString(CdmLicenseType license_type) {
|
||||
@@ -35,7 +62,7 @@ const char* CdmLicenseTypeToString(CdmLicenseType license_type) {
|
||||
case kLicenseTypeEmbeddedKeyData:
|
||||
return "EmbeddedKeyData";
|
||||
}
|
||||
return kUnknownValueRep;
|
||||
return UnknownValueRep(license_type);
|
||||
}
|
||||
|
||||
const char* CdmSecurityLevelToString(CdmSecurityLevel security_level) {
|
||||
@@ -49,9 +76,35 @@ const char* CdmSecurityLevelToString(CdmSecurityLevel security_level) {
|
||||
case kSecurityLevelL3:
|
||||
return QUERY_VALUE_SECURITY_LEVEL_L3.c_str();
|
||||
case kSecurityLevelUnknown:
|
||||
break;
|
||||
return QUERY_VALUE_SECURITY_LEVEL_UNKNOWN.c_str();
|
||||
}
|
||||
return QUERY_VALUE_SECURITY_LEVEL_UNKNOWN.c_str();
|
||||
return UnknownValueRep(security_level);
|
||||
}
|
||||
|
||||
const char* CdmOfflineLicenseStateToString(
|
||||
CdmOfflineLicenseState license_state) {
|
||||
switch (license_state) {
|
||||
case kLicenseStateActive:
|
||||
return "Active";
|
||||
case kLicenseStateReleasing:
|
||||
return "Release";
|
||||
case kLicenseStateUnknown:
|
||||
return "Unknown";
|
||||
}
|
||||
return UnknownValueRep(license_state);
|
||||
}
|
||||
|
||||
const char* CdmUsageEntryStorageTypeToString(CdmUsageEntryStorageType type) {
|
||||
switch (type) {
|
||||
case kStorageLicense:
|
||||
return "License";
|
||||
case kStorageUsageInfo:
|
||||
return "UsageInfo";
|
||||
case kStorageTypeUnknown:
|
||||
// Special value used to indicate an empty entry.
|
||||
return "None";
|
||||
}
|
||||
return UnknownValueRep(type);
|
||||
}
|
||||
|
||||
const char* SecurityLevelToString(SecurityLevel security_level) {
|
||||
@@ -61,7 +114,13 @@ const char* SecurityLevelToString(SecurityLevel security_level) {
|
||||
case kLevel3:
|
||||
return QUERY_VALUE_SECURITY_LEVEL_L3.c_str();
|
||||
}
|
||||
return kUnknownValueRep;
|
||||
return UnknownValueRep(security_level);
|
||||
}
|
||||
|
||||
const char* UnknownEnumValueToString(int value) {
|
||||
snprintf(tl_unknown_rep_buf, sizeof(tl_unknown_rep_buf), "<unknown(%d)>",
|
||||
value);
|
||||
return tl_unknown_rep_buf;
|
||||
}
|
||||
|
||||
const char* IdToString(const std::string& id) {
|
||||
@@ -72,5 +131,4 @@ const char* IdPtrToString(const std::string* id) {
|
||||
if (id == nullptr) return kNullIdRep;
|
||||
return id->empty() ? kEmptyIdRep : id->c_str();
|
||||
}
|
||||
|
||||
} // namespace wvcdm
|
||||
|
||||
Reference in New Issue
Block a user