Only one function for reporting usage support.
[ Merge of http://go/wvgerrit/121567 ] Replaced the two usage support functions GetUsageSupportType() and UsageInformationSupport() into a single function HasUsageInfoSupport(). Since moving to only supporting a single usage info system (usage table header + usage entries), the different usage support functions have lost their purpose. One version of the method works on an open session and will use a cached value of the property if previously set. The other can be called without opening the session (as used for query calls). This is part of larger fix for the usage table initialization process. Bug: 169195093 Test: CE CDM unit tests Change-Id: I637c24dd143e995dbb0f8848850e3c71ff1018eb
This commit is contained in:
@@ -160,8 +160,8 @@ class CdmSession {
|
||||
license_parser_->provider_session_token().size() > 0);
|
||||
}
|
||||
|
||||
virtual CdmUsageSupportType get_usage_support_type() {
|
||||
return usage_support_type_;
|
||||
virtual bool supports_usage_info() const {
|
||||
return usage_table_header_ != nullptr;
|
||||
}
|
||||
|
||||
// This method will remove keys by resetting crypto resources and
|
||||
@@ -297,8 +297,9 @@ class CdmSession {
|
||||
// Usage related flags and data
|
||||
bool is_initial_usage_update_;
|
||||
bool is_usage_update_needed_;
|
||||
CdmUsageSupportType usage_support_type_;
|
||||
UsageTableHeader* usage_table_header_;
|
||||
// Only assign |usage_table_header_| if capable of supporting usage
|
||||
// information.
|
||||
UsageTableHeader* usage_table_header_ = nullptr;
|
||||
uint32_t usage_entry_number_;
|
||||
CdmUsageEntry usage_entry_;
|
||||
std::string usage_provider_session_token_;
|
||||
|
||||
@@ -238,14 +238,13 @@ class CryptoSession {
|
||||
// Used to manipulate the CDM managed usage table header & entries,
|
||||
// delegating calls to OEMCrypto.
|
||||
|
||||
// Usage support.
|
||||
virtual CdmResponseType GetUsageSupportType(CdmUsageSupportType* type);
|
||||
|
||||
// The overloaded method with |security_level| may be called without a
|
||||
// preceding call to Open. The other method must call Open first.
|
||||
virtual bool UsageInformationSupport(bool* has_support);
|
||||
virtual bool UsageInformationSupport(SecurityLevel security_level,
|
||||
bool* has_support);
|
||||
// Determines whether the OEMCrypto library supports usage info.
|
||||
// As of V16, the only valid type of support is usage table header +
|
||||
// usage entries.
|
||||
// The first method will use a cached value if present.
|
||||
virtual bool HasUsageInfoSupport(bool* has_support);
|
||||
virtual bool HasUsageInfoSupport(SecurityLevel security_level,
|
||||
bool* has_support);
|
||||
|
||||
// Usage report.
|
||||
virtual CdmResponseType DeactivateUsageInformation(
|
||||
@@ -329,6 +328,12 @@ class CryptoSession {
|
||||
CdmResponseType SelectKey(const std::string& key_id,
|
||||
CdmCipherMode cipher_mode);
|
||||
|
||||
// Retrieves the OEMCrypto usage info support for the specified
|
||||
// |requested_security_level|.
|
||||
// Caller should acquire the OEMCrypto read lock before calling.
|
||||
bool HasUsageInfoSupportInternal(SecurityLevel requested_security_level,
|
||||
bool* has_support);
|
||||
|
||||
// These methods fall back into each other in the order given, depending on
|
||||
// how much data they were given and how much data OEMCrypto can accept in one
|
||||
// call.
|
||||
@@ -415,6 +420,15 @@ class CryptoSession {
|
||||
static int session_count_;
|
||||
static int termination_counter_;
|
||||
|
||||
enum CachedBooleanProperty {
|
||||
// Property has not yet been checked/cached.
|
||||
kBooleanUnset,
|
||||
// Property has been cached as false.
|
||||
kBooleanFalse,
|
||||
// Property has been cached as true.
|
||||
kBooleanTrue
|
||||
};
|
||||
|
||||
metrics::CryptoMetrics* metrics_;
|
||||
metrics::TimerMetric life_span_;
|
||||
uint32_t system_id_;
|
||||
@@ -430,8 +444,9 @@ class CryptoSession {
|
||||
bool is_destination_buffer_type_valid_;
|
||||
SecurityLevel requested_security_level_;
|
||||
|
||||
CdmUsageSupportType usage_support_type_;
|
||||
UsageTableHeader* usage_table_header_;
|
||||
// Open session-cached result of OEMCrypto_SupportsUsageTable().
|
||||
CachedBooleanProperty has_usage_info_support_ = kBooleanUnset;
|
||||
UsageTableHeader* usage_table_header_ = nullptr;
|
||||
static UsageTableHeader* usage_table_header_l1_;
|
||||
static UsageTableHeader* usage_table_header_l3_;
|
||||
|
||||
|
||||
@@ -575,11 +575,11 @@ CdmResponseType CdmEngine::QueryStatus(SecurityLevel security_level,
|
||||
return NO_ERROR;
|
||||
} else if (query_token == QUERY_KEY_USAGE_SUPPORT) {
|
||||
bool supports_usage_reporting;
|
||||
const bool got_info = crypto_session->UsageInformationSupport(
|
||||
const bool got_info = crypto_session->HasUsageInfoSupport(
|
||||
security_level, &supports_usage_reporting);
|
||||
|
||||
if (!got_info) {
|
||||
LOGW("UsageInformationSupport failed");
|
||||
LOGW("HasUsageInfoSupport failed");
|
||||
metrics_->GetCryptoMetrics()
|
||||
->crypto_session_usage_information_support_.SetError(got_info);
|
||||
return UNKNOWN_ERROR;
|
||||
@@ -1414,7 +1414,7 @@ CdmResponseType CdmEngine::RemoveAllUsageInfo(
|
||||
usage_session_.reset(new CdmSession(file_system_, metrics_->AddSession()));
|
||||
usage_session_->Init(usage_property_set_.get());
|
||||
|
||||
if (usage_session_->get_usage_support_type() == kUsageEntrySupport) {
|
||||
if (usage_session_->supports_usage_info()) {
|
||||
std::vector<DeviceFiles::CdmUsageData> usage_data;
|
||||
// Retrieve all usage information but delete only one before
|
||||
// refetching. This is because deleting the usage entry
|
||||
@@ -1505,7 +1505,7 @@ CdmResponseType CdmEngine::RemoveUsageInfo(
|
||||
continue;
|
||||
}
|
||||
|
||||
if (usage_session_->get_usage_support_type() == kUsageEntrySupport) {
|
||||
if (usage_session_->supports_usage_info()) {
|
||||
status = usage_session_->DeleteUsageEntry(usage_entry_number);
|
||||
if (!handle.DeleteUsageInfo(DeviceFiles::GetUsageInfoFileName(app_id),
|
||||
provider_session_token)) {
|
||||
@@ -1910,7 +1910,7 @@ void CdmEngine::OnTimerEvent() {
|
||||
for (CdmSessionList::iterator iter = sessions.begin();
|
||||
iter != sessions.end(); ++iter) {
|
||||
(*iter)->reset_usage_flags();
|
||||
if ((*iter)->get_usage_support_type() == kUsageEntrySupport &&
|
||||
if ((*iter)->supports_usage_info() &&
|
||||
(*iter)->has_provider_session_token()) {
|
||||
(*iter)->UpdateUsageEntryInformation();
|
||||
}
|
||||
|
||||
@@ -82,7 +82,6 @@ CdmSession::CdmSession(FileSystem* file_system,
|
||||
has_decrypted_since_last_report_(false),
|
||||
is_initial_usage_update_(true),
|
||||
is_usage_update_needed_(false),
|
||||
usage_support_type_(kNonSecureUsageSupport),
|
||||
usage_table_header_(nullptr),
|
||||
usage_entry_number_(0),
|
||||
mock_license_parser_in_use_(false),
|
||||
@@ -94,9 +93,7 @@ CdmSession::CdmSession(FileSystem* file_system,
|
||||
}
|
||||
|
||||
CdmSession::~CdmSession() {
|
||||
if (usage_support_type_ == kUsageEntrySupport &&
|
||||
has_provider_session_token() && usage_table_header_ != nullptr &&
|
||||
!is_release_) {
|
||||
if (has_provider_session_token() && supports_usage_info() && !is_release_) {
|
||||
UpdateUsageEntryInformation();
|
||||
}
|
||||
|
||||
@@ -162,11 +159,9 @@ CdmResponseType CdmSession::Init(CdmClientPropertySet* cdm_client_property_set,
|
||||
return SESSION_FILE_HANDLE_INIT_ERROR;
|
||||
}
|
||||
|
||||
if (crypto_session_->GetUsageSupportType(&usage_support_type_) == NO_ERROR) {
|
||||
if (usage_support_type_ == kUsageEntrySupport)
|
||||
usage_table_header_ = crypto_session_->GetUsageTableHeader();
|
||||
} else {
|
||||
usage_support_type_ = kNonSecureUsageSupport;
|
||||
bool has_support = false;
|
||||
if (crypto_session_->HasUsageInfoSupport(&has_support) && has_support) {
|
||||
usage_table_header_ = crypto_session_->GetUsageTableHeader();
|
||||
}
|
||||
|
||||
if (cdm_client_property_set != nullptr)
|
||||
@@ -222,9 +217,7 @@ CdmResponseType CdmSession::Init(CdmClientPropertySet* cdm_client_property_set,
|
||||
CdmResponseType CdmSession::ReleaseOfflineResources() {
|
||||
// |license_parser_| and |policy_engine_| are reset in Init. No need to
|
||||
// deallocate here.
|
||||
if (usage_support_type_ == kUsageEntrySupport &&
|
||||
has_provider_session_token() && usage_table_header_ != nullptr &&
|
||||
!is_release_) {
|
||||
if (has_provider_session_token() && supports_usage_info() && !is_release_) {
|
||||
UpdateUsageEntryInformation();
|
||||
}
|
||||
|
||||
@@ -319,10 +312,9 @@ CdmResponseType CdmSession::RestoreOfflineSession(const CdmKeySetId& key_set_id,
|
||||
|
||||
std::string provider_session_token;
|
||||
bool sign_fake_request = false; // TODO(b/169483174): remove this variable.
|
||||
if (usage_support_type_ == kUsageEntrySupport) {
|
||||
if (supports_usage_info()) {
|
||||
if (!license_parser_->ExtractProviderSessionToken(
|
||||
key_response_, &provider_session_token) ||
|
||||
usage_table_header_ == nullptr) {
|
||||
key_response_, &provider_session_token)) {
|
||||
provider_session_token.clear();
|
||||
sign_fake_request = true; // TODO(b/169483174): remove this line.
|
||||
} else if (!VerifyOfflineUsageEntry()) {
|
||||
@@ -378,8 +370,7 @@ CdmResponseType CdmSession::RestoreOfflineSession(const CdmKeySetId& key_set_id,
|
||||
}
|
||||
}
|
||||
|
||||
if (usage_support_type_ == kUsageEntrySupport &&
|
||||
!provider_session_token.empty() && usage_table_header_ != nullptr) {
|
||||
if (!provider_session_token.empty() && supports_usage_info()) {
|
||||
CdmResponseType sts = usage_table_header_->UpdateEntry(
|
||||
usage_entry_number_, crypto_session_.get(), &usage_entry_);
|
||||
if (sts != NO_ERROR) {
|
||||
@@ -418,8 +409,7 @@ CdmResponseType CdmSession::RestoreUsageSession(
|
||||
if (status != NO_ERROR) return status;
|
||||
|
||||
CdmResponseType sts = NO_ERROR;
|
||||
if (usage_support_type_ == kUsageEntrySupport &&
|
||||
usage_table_header_ != nullptr) {
|
||||
if (supports_usage_info()) {
|
||||
sts = usage_table_header_->LoadEntry(crypto_session_.get(), usage_entry_,
|
||||
usage_entry_number_);
|
||||
crypto_metrics_->usage_table_header_load_entry_.Increment(sts);
|
||||
@@ -437,8 +427,7 @@ CdmResponseType CdmSession::RestoreUsageSession(
|
||||
return RELEASE_LICENSE_ERROR_2;
|
||||
}
|
||||
|
||||
if (usage_support_type_ == kUsageEntrySupport &&
|
||||
usage_table_header_ != nullptr) {
|
||||
if (supports_usage_info()) {
|
||||
sts = usage_table_header_->UpdateEntry(
|
||||
usage_entry_number_, crypto_session_.get(), &usage_entry_);
|
||||
if (sts != NO_ERROR) {
|
||||
@@ -580,8 +569,7 @@ CdmResponseType CdmSession::AddKeyInternal(const CdmKeyResponse& key_response) {
|
||||
// to be created.
|
||||
CdmResponseType sts;
|
||||
std::string provider_session_token;
|
||||
if (usage_support_type_ == kUsageEntrySupport &&
|
||||
usage_table_header_ != nullptr) {
|
||||
if (supports_usage_info()) {
|
||||
if (license_parser_->ExtractProviderSessionToken(
|
||||
key_response, &provider_session_token) &&
|
||||
!provider_session_token.empty()) {
|
||||
@@ -605,8 +593,7 @@ CdmResponseType CdmSession::AddKeyInternal(const CdmKeyResponse& key_response) {
|
||||
version_info.license_service_version());
|
||||
|
||||
// Update or invalidate entry if usage table header+entries are supported
|
||||
if (usage_support_type_ == kUsageEntrySupport &&
|
||||
!provider_session_token.empty() && usage_table_header_ != nullptr) {
|
||||
if (!provider_session_token.empty() && supports_usage_info()) {
|
||||
if (sts != KEY_ADDED) {
|
||||
const CdmResponseType invalidate_sts =
|
||||
usage_table_header_->InvalidateEntry(
|
||||
@@ -630,9 +617,7 @@ CdmResponseType CdmSession::AddKeyInternal(const CdmKeyResponse& key_response) {
|
||||
license_parser_->provider_session_token().size());
|
||||
|
||||
if ((is_offline_ || has_provider_session_token()) && !is_temporary_) {
|
||||
if (has_provider_session_token() &&
|
||||
usage_support_type_ == kUsageEntrySupport &&
|
||||
usage_table_header_ != nullptr) {
|
||||
if (has_provider_session_token() && supports_usage_info()) {
|
||||
usage_table_header_->UpdateEntry(usage_entry_number_,
|
||||
crypto_session_.get(), &usage_entry_);
|
||||
}
|
||||
@@ -832,8 +817,7 @@ CdmResponseType CdmSession::GenerateReleaseRequest(CdmKeyRequest* key_request) {
|
||||
|
||||
if (KEY_MESSAGE != status) return status;
|
||||
|
||||
if (has_provider_session_token() &&
|
||||
usage_support_type_ == kUsageEntrySupport) {
|
||||
if (has_provider_session_token() && supports_usage_info()) {
|
||||
status = usage_table_header_->UpdateEntry(
|
||||
usage_entry_number_, crypto_session_.get(), &usage_entry_);
|
||||
|
||||
@@ -847,7 +831,7 @@ CdmResponseType CdmSession::GenerateReleaseRequest(CdmKeyRequest* key_request) {
|
||||
if (!StoreLicense(DeviceFiles::kLicenseStateReleasing, nullptr))
|
||||
return RELEASE_KEY_REQUEST_ERROR;
|
||||
} else if (!usage_provider_session_token_.empty()) {
|
||||
if (usage_support_type_ == kUsageEntrySupport) {
|
||||
if (supports_usage_info()) {
|
||||
if (!UpdateUsageInfo()) return RELEASE_USAGE_INFO_FAILED;
|
||||
}
|
||||
}
|
||||
@@ -880,9 +864,8 @@ CdmResponseType CdmSession::DeleteUsageEntry(uint32_t usage_entry_number) {
|
||||
LOGE("CDM session not initialized");
|
||||
return NOT_INITIALIZED_ERROR;
|
||||
}
|
||||
if (usage_support_type_ != kUsageEntrySupport) {
|
||||
LOGE("Unexpected usage support type: %d",
|
||||
static_cast<int>(usage_support_type_));
|
||||
if (!supports_usage_info()) {
|
||||
LOGE("Cannot delete entry, usage table not supported");
|
||||
return INCORRECT_USAGE_SUPPORT_TYPE_1;
|
||||
}
|
||||
|
||||
@@ -897,11 +880,9 @@ CdmResponseType CdmSession::DeleteUsageEntry(uint32_t usage_entry_number) {
|
||||
if (sts != NO_ERROR) return sts;
|
||||
|
||||
usage_table_header_ = nullptr;
|
||||
if (crypto_session_->GetUsageSupportType(&usage_support_type_) == NO_ERROR) {
|
||||
if (usage_support_type_ == kUsageEntrySupport)
|
||||
usage_table_header_ = crypto_session_->GetUsageTableHeader();
|
||||
} else {
|
||||
usage_support_type_ = kNonSecureUsageSupport;
|
||||
bool has_support = false;
|
||||
if (crypto_session_->HasUsageInfoSupport(&has_support) && has_support) {
|
||||
usage_table_header_ = crypto_session_->GetUsageTableHeader();
|
||||
}
|
||||
|
||||
if (usage_table_header_ == nullptr) {
|
||||
@@ -996,11 +977,10 @@ CdmResponseType CdmSession::StoreLicense() {
|
||||
usage_entry_number_, drm_certificate_, wrapped_private_key_)) {
|
||||
LOGE("Unable to store usage info");
|
||||
// Usage info file is corrupt. Delete current usage entry and file.
|
||||
if (usage_support_type_ == kUsageEntrySupport) {
|
||||
if (supports_usage_info()) {
|
||||
DeleteUsageEntry(usage_entry_number_);
|
||||
} else {
|
||||
LOGW("Unexpected usage support type: %d",
|
||||
static_cast<int>(usage_support_type_));
|
||||
LOGW("Cannot store, usage table not supported");
|
||||
}
|
||||
std::vector<std::string> provider_session_tokens;
|
||||
file_handle_->DeleteAllUsageInfoForApp(
|
||||
@@ -1052,8 +1032,7 @@ CdmResponseType CdmSession::RemoveKeys() {
|
||||
|
||||
CdmResponseType CdmSession::RemoveLicense() {
|
||||
if (is_offline_ || has_provider_session_token()) {
|
||||
if (usage_support_type_ == kUsageEntrySupport &&
|
||||
has_provider_session_token()) {
|
||||
if (has_provider_session_token() && supports_usage_info()) {
|
||||
DeleteUsageEntry(usage_entry_number_);
|
||||
}
|
||||
DeleteLicenseFile();
|
||||
@@ -1103,14 +1082,10 @@ void CdmSession::GetApplicationId(std::string* app_id) {
|
||||
}
|
||||
|
||||
CdmResponseType CdmSession::UpdateUsageEntryInformation() {
|
||||
if (usage_support_type_ != kUsageEntrySupport ||
|
||||
!has_provider_session_token() || usage_table_header_ == nullptr) {
|
||||
LOGE(
|
||||
"Unexpected state: usage support type = %d, PST present = %s, "
|
||||
"usage table header available = %s",
|
||||
static_cast<int>(usage_support_type_),
|
||||
has_provider_session_token() ? "yes" : "no",
|
||||
usage_table_header_ == nullptr ? "no" : "yes");
|
||||
if (!has_provider_session_token() || !supports_usage_info()) {
|
||||
LOGE("Unexpected state: usage_support = %s, PST present = %s, ",
|
||||
supports_usage_info() ? "true" : "false",
|
||||
has_provider_session_token() ? "yes" : "no");
|
||||
return INCORRECT_USAGE_SUPPORT_TYPE_2;
|
||||
}
|
||||
|
||||
|
||||
@@ -196,7 +196,7 @@ CdmResponseType ClientIdentification::Prepare(
|
||||
|
||||
if (is_license_request_) {
|
||||
bool supports_usage_information;
|
||||
if (crypto_session_->UsageInformationSupport(&supports_usage_information)) {
|
||||
if (crypto_session_->HasUsageInfoSupport(&supports_usage_information)) {
|
||||
client_capabilities->set_session_token(supports_usage_information);
|
||||
}
|
||||
|
||||
|
||||
@@ -164,6 +164,11 @@ size_t GenericEncryptionBlockSize(CdmEncryptionAlgorithm algorithm) {
|
||||
}
|
||||
return kAes128BlockSize;
|
||||
}
|
||||
|
||||
const char* SecurityLevelToString(SecurityLevel security_level) {
|
||||
return security_level == kLevel3 ? QUERY_VALUE_SECURITY_LEVEL_L3.c_str()
|
||||
: QUERY_VALUE_SECURITY_LEVEL_DEFAULT.c_str();
|
||||
}
|
||||
} // namespace
|
||||
|
||||
shared_mutex CryptoSession::static_field_mutex_;
|
||||
@@ -251,8 +256,6 @@ CryptoSession::CryptoSession(metrics::CryptoMetrics* metrics)
|
||||
update_usage_table_after_close_session_(false),
|
||||
is_destination_buffer_type_valid_(false),
|
||||
requested_security_level_(kLevelDefault),
|
||||
usage_support_type_(kUnknownUsageSupport),
|
||||
usage_table_header_(nullptr),
|
||||
api_version_(0),
|
||||
max_subsample_region_size_(0) {
|
||||
assert(metrics);
|
||||
@@ -491,8 +494,8 @@ CdmSecurityLevel CryptoSession::GetSecurityLevel() {
|
||||
|
||||
CdmSecurityLevel CryptoSession::GetSecurityLevel(
|
||||
SecurityLevel requested_security_level) {
|
||||
LOGV("Getting security level: requested_security_level = %d",
|
||||
static_cast<int>(requested_security_level));
|
||||
LOGV("Getting security level: requested_security_level = %s",
|
||||
SecurityLevelToString(requested_security_level));
|
||||
RETURN_IF_UNINITIALIZED(kSecurityLevelUninitialized);
|
||||
const char* const level = WithOecReadLock("GetSecurityLevel", [&] {
|
||||
return OEMCrypto_SecurityLevel(requested_security_level);
|
||||
@@ -610,8 +613,8 @@ bool CryptoSession::GetApiVersion(uint32_t* version) {
|
||||
|
||||
bool CryptoSession::GetApiVersion(SecurityLevel security_level,
|
||||
uint32_t* version) {
|
||||
LOGV("Getting API version: security_level = %d",
|
||||
static_cast<int>(security_level));
|
||||
LOGV("Getting API version: security_level = %s",
|
||||
SecurityLevelToString(security_level));
|
||||
if (!version) {
|
||||
LOGE("Output parameter |version| not provided");
|
||||
return false;
|
||||
@@ -628,8 +631,8 @@ bool CryptoSession::GetApiVersion(SecurityLevel security_level,
|
||||
|
||||
bool CryptoSession::GetApiMinorVersion(SecurityLevel security_level,
|
||||
uint32_t* minor_version) {
|
||||
LOGV("Getting API minor version: security_level = %d",
|
||||
static_cast<int>(security_level));
|
||||
LOGV("Getting API minor version: security_level = %s",
|
||||
SecurityLevelToString(security_level));
|
||||
if (!minor_version) {
|
||||
LOGE("Output parameter |minor_version| not provided");
|
||||
return false;
|
||||
@@ -754,9 +757,7 @@ uint8_t CryptoSession::GetSecurityPatchLevel() {
|
||||
|
||||
CdmResponseType CryptoSession::Open(SecurityLevel requested_security_level) {
|
||||
LOGD("Opening crypto session: requested_security_level = %s",
|
||||
requested_security_level == kLevel3
|
||||
? QUERY_VALUE_SECURITY_LEVEL_L3.c_str()
|
||||
: QUERY_VALUE_SECURITY_LEVEL_DEFAULT.c_str());
|
||||
SecurityLevelToString(requested_security_level));
|
||||
RETURN_IF_UNINITIALIZED(UNKNOWN_ERROR);
|
||||
if (open_) return NO_ERROR;
|
||||
|
||||
@@ -838,11 +839,11 @@ CdmResponseType CryptoSession::Open(SecurityLevel requested_security_level) {
|
||||
return USAGE_SUPPORT_GET_API_FAILED;
|
||||
}
|
||||
|
||||
CdmUsageSupportType usage_support_type;
|
||||
result = GetUsageSupportType(&usage_support_type);
|
||||
if (result == NO_ERROR) {
|
||||
metrics_->oemcrypto_usage_table_support_.Record(usage_support_type);
|
||||
if (usage_support_type == kUsageEntrySupport) {
|
||||
bool supports_usage_table = false;
|
||||
if (HasUsageInfoSupport(&supports_usage_table)) {
|
||||
metrics_->oemcrypto_usage_table_support_.Record(
|
||||
supports_usage_table ? kUsageEntrySupport : kNonSecureUsageSupport);
|
||||
if (supports_usage_table) {
|
||||
CdmSecurityLevel security_level = GetSecurityLevel();
|
||||
if (security_level == kSecurityLevelL1 ||
|
||||
security_level == kSecurityLevelL3) {
|
||||
@@ -875,7 +876,8 @@ CdmResponseType CryptoSession::Open(SecurityLevel requested_security_level) {
|
||||
} // End |static_field_mutex_| block.
|
||||
}
|
||||
} else {
|
||||
metrics_->oemcrypto_usage_table_support_.SetError(result);
|
||||
metrics_->oemcrypto_usage_table_support_.SetError(
|
||||
USAGE_INFORMATION_SUPPORT_FAILED);
|
||||
}
|
||||
|
||||
// Do not add logic after this point as it may never get exercised. In the
|
||||
@@ -898,6 +900,9 @@ void CryptoSession::Close() {
|
||||
"Close", [&] { close_sts = OEMCrypto_CloseSession(oec_session_id_); });
|
||||
metrics_->oemcrypto_close_session_.Increment(close_sts);
|
||||
|
||||
// Clear cached values.
|
||||
has_usage_info_support_ = kBooleanUnset;
|
||||
|
||||
if (close_sts != OEMCrypto_SUCCESS) {
|
||||
LOGW("OEMCrypto_CloseSession failed: status = %d",
|
||||
static_cast<int>(close_sts));
|
||||
@@ -1637,19 +1642,39 @@ CdmResponseType CryptoSession::Decrypt(
|
||||
}
|
||||
}
|
||||
|
||||
bool CryptoSession::UsageInformationSupport(bool* has_support) {
|
||||
LOGV("Checking if usage information is supported");
|
||||
bool CryptoSession::HasUsageInfoSupport(bool* has_support) {
|
||||
RETURN_IF_NOT_OPEN(false);
|
||||
return UsageInformationSupport(requested_security_level_, has_support);
|
||||
RETURN_IF_NULL(has_support, false);
|
||||
return WithOecReadLock("HasUsageInfoSupport", [&] {
|
||||
// Use cached value if set.
|
||||
if (has_usage_info_support_ != kBooleanUnset) {
|
||||
*has_support = (has_usage_info_support_ == kBooleanTrue);
|
||||
return true;
|
||||
}
|
||||
if (!HasUsageInfoSupportInternal(requested_security_level_, has_support)) {
|
||||
return false;
|
||||
}
|
||||
// Cache result if successful.
|
||||
has_usage_info_support_ = (*has_support ? kBooleanTrue : kBooleanFalse);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
bool CryptoSession::UsageInformationSupport(SecurityLevel security_level,
|
||||
bool* has_support) {
|
||||
LOGV("Checking if usage information is supported: security_level = %d",
|
||||
static_cast<int>(security_level));
|
||||
bool CryptoSession::HasUsageInfoSupport(SecurityLevel requested_security_level,
|
||||
bool* has_support) {
|
||||
RETURN_IF_UNINITIALIZED(false);
|
||||
WithOecReadLock("UsageInformationSupport", [&] {
|
||||
*has_support = OEMCrypto_SupportsUsageTable(security_level);
|
||||
RETURN_IF_NULL(has_support, false);
|
||||
return WithOecReadLock("HasUsageInfoSupport", [&] {
|
||||
return HasUsageInfoSupportInternal(requested_security_level, has_support);
|
||||
});
|
||||
}
|
||||
|
||||
bool CryptoSession::HasUsageInfoSupportInternal(
|
||||
SecurityLevel requested_security_level, bool* has_support) {
|
||||
LOGV("requested_security_level = %s",
|
||||
SecurityLevelToString(requested_security_level));
|
||||
*has_support = WithOecReadLock("HasUsageInfoSupport", [&] {
|
||||
return OEMCrypto_SupportsUsageTable(requested_security_level);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
@@ -1875,8 +1900,8 @@ CdmResponseType CryptoSession::GetHdcpCapabilities(HdcpCapability* current,
|
||||
CdmResponseType CryptoSession::GetHdcpCapabilities(SecurityLevel security_level,
|
||||
HdcpCapability* current,
|
||||
HdcpCapability* max) {
|
||||
LOGV("Getting HDCP capabilities: id = %u, security_level = %d",
|
||||
oec_session_id_, static_cast<int>(security_level));
|
||||
LOGV("Getting HDCP capabilities: id = %u, security_level = %s",
|
||||
oec_session_id_, SecurityLevelToString(security_level));
|
||||
RETURN_IF_UNINITIALIZED(CRYPTO_SESSION_NOT_INITIALIZED);
|
||||
RETURN_IF_NULL(current, PARAMETER_NULL);
|
||||
RETURN_IF_NULL(max, PARAMETER_NULL);
|
||||
@@ -1930,8 +1955,8 @@ CdmResponseType CryptoSession::GetRandom(size_t data_length,
|
||||
|
||||
CdmResponseType CryptoSession::GetNumberOfOpenSessions(
|
||||
SecurityLevel security_level, size_t* count) {
|
||||
LOGV("Getting number of open sessions: id = %u, security_level = %d",
|
||||
oec_session_id_, static_cast<int>(security_level));
|
||||
LOGV("Getting number of open sessions: id = %u, security_level = %s",
|
||||
oec_session_id_, SecurityLevelToString(security_level));
|
||||
RETURN_IF_UNINITIALIZED(CRYPTO_SESSION_NOT_INITIALIZED);
|
||||
RETURN_IF_NULL(count, PARAMETER_NULL);
|
||||
|
||||
@@ -1954,8 +1979,8 @@ CdmResponseType CryptoSession::GetNumberOfOpenSessions(
|
||||
|
||||
CdmResponseType CryptoSession::GetMaxNumberOfSessions(
|
||||
SecurityLevel security_level, size_t* max) {
|
||||
LOGV("Getting max number of sessions: id = %u, security_level = %d",
|
||||
oec_session_id_, static_cast<int>(security_level));
|
||||
LOGV("Getting max number of sessions: id = %u, security_level = %s",
|
||||
oec_session_id_, SecurityLevelToString(security_level));
|
||||
RETURN_IF_UNINITIALIZED(CRYPTO_SESSION_NOT_INITIALIZED);
|
||||
RETURN_IF_NULL(max, PARAMETER_NULL);
|
||||
|
||||
@@ -2036,8 +2061,8 @@ bool CryptoSession::GetResourceRatingTier(uint32_t* tier) {
|
||||
|
||||
bool CryptoSession::GetResourceRatingTier(SecurityLevel security_level,
|
||||
uint32_t* tier) {
|
||||
LOGV("Getting resource rating tier: security_level = %d",
|
||||
static_cast<int>(security_level));
|
||||
LOGV("Getting resource rating tier: security_level = %s",
|
||||
SecurityLevelToString(security_level));
|
||||
RETURN_IF_UNINITIALIZED(false);
|
||||
RETURN_IF_NULL(tier, false);
|
||||
|
||||
@@ -2064,8 +2089,8 @@ bool CryptoSession::GetBuildInformation(std::string* info) {
|
||||
|
||||
bool CryptoSession::GetBuildInformation(SecurityLevel security_level,
|
||||
std::string* info) {
|
||||
LOGV("Getting build information: security_level = %d",
|
||||
static_cast<int>(security_level));
|
||||
LOGV("Getting build information: security_level = %s",
|
||||
SecurityLevelToString(security_level));
|
||||
RETURN_IF_UNINITIALIZED(false);
|
||||
RETURN_IF_NULL(info, false);
|
||||
|
||||
@@ -2084,8 +2109,8 @@ bool CryptoSession::GetBuildInformation(SecurityLevel security_level,
|
||||
|
||||
bool CryptoSession::GetMaximumUsageTableEntries(SecurityLevel security_level,
|
||||
size_t* number_of_entries) {
|
||||
LOGV("Getting maximum usage table entries: security_level = %d",
|
||||
static_cast<int>(security_level));
|
||||
LOGV("Getting maximum usage table entries: security_level = %s",
|
||||
SecurityLevelToString(security_level));
|
||||
RETURN_IF_UNINITIALIZED(false);
|
||||
if (number_of_entries == nullptr) {
|
||||
LOGE("Output parameter |number_of_entries| not provided");
|
||||
@@ -2422,40 +2447,11 @@ CdmResponseType CryptoSession::GenericVerify(const std::string& message,
|
||||
}
|
||||
}
|
||||
|
||||
CdmResponseType CryptoSession::GetUsageSupportType(
|
||||
CdmUsageSupportType* usage_support_type) {
|
||||
LOGV("Getting usage support type: id = %u", oec_session_id_);
|
||||
|
||||
RETURN_IF_NULL(usage_support_type, PARAMETER_NULL);
|
||||
|
||||
if (usage_support_type_ != kUnknownUsageSupport) {
|
||||
*usage_support_type = usage_support_type_;
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
bool has_support = false;
|
||||
if (!UsageInformationSupport(&has_support)) {
|
||||
LOGE("UsageInformationSupport failed");
|
||||
return USAGE_INFORMATION_SUPPORT_FAILED;
|
||||
}
|
||||
|
||||
if (!has_support) {
|
||||
*usage_support_type = usage_support_type_ = kNonSecureUsageSupport;
|
||||
} else {
|
||||
// As of v16, all supported version of OEMCrypto provide usage entry
|
||||
// support or no usage info support.
|
||||
*usage_support_type = usage_support_type_ = kUsageEntrySupport;
|
||||
}
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
CdmResponseType CryptoSession::CreateUsageTableHeader(
|
||||
SecurityLevel requested_security_level,
|
||||
CdmUsageTableHeader* usage_table_header) {
|
||||
LOGV("Creating usage table header: requested_security_level = %s",
|
||||
requested_security_level == kLevel3
|
||||
? QUERY_VALUE_SECURITY_LEVEL_L3.c_str()
|
||||
: QUERY_VALUE_SECURITY_LEVEL_DEFAULT.c_str());
|
||||
SecurityLevelToString(requested_security_level));
|
||||
RETURN_IF_NULL(usage_table_header, PARAMETER_NULL);
|
||||
|
||||
usage_table_header->resize(kEstimatedInitialUsageTableHeader);
|
||||
@@ -2496,9 +2492,7 @@ CdmResponseType CryptoSession::LoadUsageTableHeader(
|
||||
SecurityLevel requested_security_level,
|
||||
const CdmUsageTableHeader& usage_table_header) {
|
||||
LOGV("Loading usage table header: requested_security_level = %s",
|
||||
requested_security_level == kLevel3
|
||||
? QUERY_VALUE_SECURITY_LEVEL_L3.c_str()
|
||||
: QUERY_VALUE_SECURITY_LEVEL_DEFAULT.c_str());
|
||||
SecurityLevelToString(requested_security_level));
|
||||
|
||||
OEMCryptoResult result;
|
||||
WithOecWriteLock("LoadUsageTableHeader", [&] {
|
||||
@@ -2540,9 +2534,7 @@ CdmResponseType CryptoSession::ShrinkUsageTableHeader(
|
||||
SecurityLevel requested_security_level, uint32_t new_entry_count,
|
||||
CdmUsageTableHeader* usage_table_header) {
|
||||
LOGV("Shrinking usage table header: requested_security_level = %s",
|
||||
requested_security_level == kLevel3
|
||||
? QUERY_VALUE_SECURITY_LEVEL_L3.c_str()
|
||||
: QUERY_VALUE_SECURITY_LEVEL_DEFAULT.c_str());
|
||||
SecurityLevelToString(requested_security_level));
|
||||
RETURN_IF_NULL(usage_table_header, PARAMETER_NULL);
|
||||
|
||||
size_t usage_table_header_len = 0;
|
||||
@@ -3085,5 +3077,4 @@ CryptoSession* CryptoSessionFactory::MakeCryptoSession(
|
||||
metrics::CryptoMetrics* crypto_metrics) {
|
||||
return new CryptoSession(crypto_metrics);
|
||||
}
|
||||
|
||||
} // namespace wvcdm
|
||||
|
||||
@@ -437,9 +437,8 @@ CdmResponseType CdmLicense::PrepareKeyUpdateRequest(
|
||||
}
|
||||
|
||||
// TODO(rfrias): Refactor to avoid needing to call CdmSession
|
||||
if (cdm_session &&
|
||||
cdm_session->get_usage_support_type() == kUsageEntrySupport) {
|
||||
CdmResponseType status = cdm_session->UpdateUsageEntryInformation();
|
||||
if (cdm_session && cdm_session->supports_usage_info()) {
|
||||
const CdmResponseType status = cdm_session->UpdateUsageEntryInformation();
|
||||
if (NO_ERROR != status) return status;
|
||||
}
|
||||
|
||||
@@ -843,9 +842,8 @@ CdmResponseType CdmLicense::RestoreOfflineLicense(
|
||||
}
|
||||
|
||||
if (!provider_session_token_.empty()) {
|
||||
if (cdm_session &&
|
||||
cdm_session->get_usage_support_type() == kUsageEntrySupport) {
|
||||
CdmResponseType status = cdm_session->UpdateUsageEntryInformation();
|
||||
if (cdm_session && cdm_session->supports_usage_info()) {
|
||||
const CdmResponseType status = cdm_session->UpdateUsageEntryInformation();
|
||||
if (NO_ERROR != status) return sts;
|
||||
}
|
||||
|
||||
|
||||
@@ -136,10 +136,10 @@ class MockCryptoSession : public TestCryptoSession {
|
||||
public:
|
||||
MockCryptoSession(metrics::CryptoMetrics* crypto_metrics)
|
||||
: TestCryptoSession(crypto_metrics) {
|
||||
// By default, call the concrete implementation of GetUsageSupportType.
|
||||
ON_CALL(*this, GetUsageSupportType(_))
|
||||
// By default, call the concrete implementation of HasUsageInfoSupport.
|
||||
ON_CALL(*this, HasUsageInfoSupport(_))
|
||||
.WillByDefault(
|
||||
Invoke(this, &MockCryptoSession::BaseGetUsageSupportType));
|
||||
Invoke(this, &MockCryptoSession::BaseHasUsageInfoSupport));
|
||||
}
|
||||
MOCK_METHOD1(GetClientToken, bool(std::string*));
|
||||
MOCK_METHOD1(GetProvisioningToken, CdmResponseType(std::string*));
|
||||
@@ -150,11 +150,11 @@ class MockCryptoSession : public TestCryptoSession {
|
||||
MOCK_METHOD1(LoadCertificatePrivateKey,
|
||||
CdmResponseType(const CryptoWrappedKey&));
|
||||
MOCK_METHOD0(DeleteAllUsageReports, CdmResponseType());
|
||||
MOCK_METHOD1(GetUsageSupportType, CdmResponseType(CdmUsageSupportType* type));
|
||||
MOCK_METHOD1(HasUsageInfoSupport, bool(bool*));
|
||||
MOCK_METHOD0(GetUsageTableHeader, UsageTableHeader*());
|
||||
|
||||
CdmResponseType BaseGetUsageSupportType(CdmUsageSupportType* type) {
|
||||
return CryptoSession::GetUsageSupportType(type);
|
||||
bool BaseHasUsageInfoSupport(bool* has_support) {
|
||||
return CryptoSession::HasUsageInfoSupport(has_support);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -291,17 +291,15 @@ TEST_F(CdmSessionTest, UpdateUsageEntry) {
|
||||
.WillOnce(Return(true));
|
||||
|
||||
// Set up mocks and expectations for the UpdateUsageEntryInformation call.
|
||||
EXPECT_CALL(*crypto_session_, GetUsageSupportType(_))
|
||||
.WillRepeatedly(
|
||||
DoAll(SetArgPointee<0>(kUsageEntrySupport), Return(NO_ERROR)));
|
||||
EXPECT_CALL(*crypto_session_, HasUsageInfoSupport(_))
|
||||
.WillRepeatedly(DoAll(SetArgPointee<0>(true), Return(true)));
|
||||
EXPECT_CALL(*license_parser_, provider_session_token())
|
||||
.WillRepeatedly(Return("Mock provider session token"));
|
||||
EXPECT_CALL(usage_table_header_, UpdateEntry(_, NotNull(), NotNull()))
|
||||
.WillRepeatedly(Return(NO_ERROR));
|
||||
|
||||
EXPECT_EQ(NO_ERROR, cdm_session_->Init(nullptr));
|
||||
EXPECT_EQ(kUsageEntrySupport, cdm_session_->get_usage_support_type())
|
||||
<< "Usage support type: " << cdm_session_->get_usage_support_type();
|
||||
EXPECT_TRUE(cdm_session_->supports_usage_info());
|
||||
EXPECT_EQ(NO_ERROR, cdm_session_->UpdateUsageEntryInformation());
|
||||
|
||||
// Verify the UsageEntry metric is set.
|
||||
|
||||
@@ -291,8 +291,8 @@ TEST_F(CryptoSessionMetricsTest, OpenSessionValidMetrics) {
|
||||
CryptoSession::MakeCryptoSession(&crypto_metrics));
|
||||
session->Open(wvcdm::kLevelDefault);
|
||||
// Exercise a method that will touch a metric.
|
||||
CdmUsageSupportType usage_type;
|
||||
ASSERT_EQ(NO_ERROR, session->GetUsageSupportType(&usage_type));
|
||||
bool supports_usage_table;
|
||||
ASSERT_TRUE(session->HasUsageInfoSupport(&supports_usage_table));
|
||||
|
||||
drm_metrics::WvCdmMetrics::CryptoMetrics metrics_proto;
|
||||
crypto_metrics.Serialize(&metrics_proto);
|
||||
@@ -309,6 +309,8 @@ TEST_F(CryptoSessionMetricsTest, OpenSessionValidMetrics) {
|
||||
metrics_proto.oemcrypto_initialize_time_us(0).operation_count());
|
||||
EXPECT_TRUE(metrics_proto.oemcrypto_initialize_time_us(0).has_mean());
|
||||
|
||||
const CdmUsageSupportType usage_type =
|
||||
supports_usage_table ? kUsageEntrySupport : kNonSecureUsageSupport;
|
||||
EXPECT_EQ(usage_type,
|
||||
metrics_proto.oemcrypto_usage_table_support().int_value());
|
||||
|
||||
|
||||
@@ -141,7 +141,7 @@ class MockCryptoSession : public TestCryptoSession {
|
||||
: TestCryptoSession(crypto_metrics) {}
|
||||
MOCK_METHOD0(IsOpen, bool());
|
||||
MOCK_METHOD0(request_id, const std::string&());
|
||||
MOCK_METHOD1(UsageInformationSupport, bool(bool*));
|
||||
MOCK_METHOD1(HasUsageInfoSupport, bool(bool*));
|
||||
MOCK_METHOD2(GetHdcpCapabilities,
|
||||
CdmResponseType(HdcpCapability*, HdcpCapability*));
|
||||
MOCK_METHOD1(GetSupportedCertificateTypes, bool(SupportedCertificateTypes*));
|
||||
@@ -301,7 +301,7 @@ TEST_F(CdmLicenseTest, PrepareKeyRequestValidation) {
|
||||
EXPECT_CALL(*crypto_session_, IsOpen()).WillOnce(Return(true));
|
||||
EXPECT_CALL(*crypto_session_, request_id())
|
||||
.WillOnce(ReturnRef(kCryptoRequestId));
|
||||
EXPECT_CALL(*crypto_session_, UsageInformationSupport(NotNull()))
|
||||
EXPECT_CALL(*crypto_session_, HasUsageInfoSupport(NotNull()))
|
||||
.WillOnce(
|
||||
DoAll(SetArgPointee<0>(usage_information_support), Return(true)));
|
||||
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
|
||||
@@ -424,7 +424,7 @@ TEST_F(CdmLicenseTest, PrepareKeyRequestValidationV15) {
|
||||
EXPECT_CALL(*crypto_session_, IsOpen()).WillOnce(Return(true));
|
||||
EXPECT_CALL(*crypto_session_, request_id())
|
||||
.WillOnce(ReturnRef(kCryptoRequestId));
|
||||
EXPECT_CALL(*crypto_session_, UsageInformationSupport(NotNull()))
|
||||
EXPECT_CALL(*crypto_session_, HasUsageInfoSupport(NotNull()))
|
||||
.WillOnce(
|
||||
DoAll(SetArgPointee<0>(usage_information_support), Return(true)));
|
||||
EXPECT_CALL(*crypto_session_, GetHdcpCapabilities(NotNull(), NotNull()))
|
||||
|
||||
Reference in New Issue
Block a user