Merge "Only one function for reporting usage support." into sc-dev am: d4b24490f2
Original change: https://googleplex-android-review.googlesource.com/c/platform/vendor/widevine/+/14137666 Change-Id: I295763f3af61727205b77a3914681ec635e8ab02
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
|
||||
@@ -298,8 +298,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)
|
||||
@@ -225,9 +220,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();
|
||||
}
|
||||
|
||||
@@ -322,10 +315,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()) {
|
||||
@@ -381,8 +373,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) {
|
||||
@@ -421,8 +412,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);
|
||||
@@ -440,8 +430,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) {
|
||||
@@ -583,8 +572,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()) {
|
||||
@@ -608,8 +596,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(
|
||||
@@ -633,9 +620,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_);
|
||||
}
|
||||
@@ -835,8 +820,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_);
|
||||
|
||||
@@ -850,7 +834,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;
|
||||
}
|
||||
}
|
||||
@@ -883,9 +867,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;
|
||||
}
|
||||
|
||||
@@ -900,11 +883,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) {
|
||||
@@ -999,11 +980,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(
|
||||
@@ -1055,8 +1035,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();
|
||||
@@ -1106,14 +1085,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