Enable usage header table and entries
[ Merge of http://go/wvgerrit/24022 ] b/34327459 Test: Verified by unit, integration tests on angler Change-Id: Idb17dc472dddbdad217c35bdaa3fb20ae8152371
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
#include "string_conversions.h"
|
||||
#include "wv_cdm_constants.h"
|
||||
#include "wv_cdm_event_listener.h"
|
||||
#include "usage_table_header.h"
|
||||
|
||||
namespace {
|
||||
const size_t kKeySetIdLength = 14;
|
||||
@@ -38,8 +39,20 @@ 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_(NULL),
|
||||
usage_entry_number_(0),
|
||||
mock_license_parser_in_use_(false),
|
||||
mock_policy_engine_in_use_(false) {
|
||||
CdmResponseType sts =
|
||||
crypto_session_->GetUsageSupportType(&usage_support_type_);
|
||||
|
||||
if (sts != NO_ERROR) {
|
||||
LOGW("CdmSession::CdmSession: Failed to get usage support type");
|
||||
}
|
||||
if (usage_support_type_ == kUsageEntrySupport)
|
||||
usage_table_header_ = UsageTableHeader::GetInstance(file_system,
|
||||
crypto_session_.get());
|
||||
life_span_.Start();
|
||||
}
|
||||
|
||||
@@ -178,28 +191,37 @@ CdmResponseType CdmSession::RestoreOfflineSession(
|
||||
int64_t playback_start_time;
|
||||
int64_t last_playback_time;
|
||||
int64_t grace_period_end_time;
|
||||
std::string usage_entry;
|
||||
uint32_t usage_entry_number = 0;
|
||||
|
||||
if (!file_handle_->RetrieveLicense(
|
||||
key_set_id, &license_state, &offline_init_data_, &key_request_,
|
||||
&key_response_, &offline_key_renewal_request_,
|
||||
&offline_key_renewal_response_, &offline_release_server_url_,
|
||||
&playback_start_time, &last_playback_time, &grace_period_end_time,
|
||||
&app_parameters_, &usage_entry, &usage_entry_number)) {
|
||||
LOGE("CdmSession::Init failed to retrieve license. key set id = %s",
|
||||
key_set_id.c_str());
|
||||
&app_parameters_, &usage_entry_, &usage_entry_number_)) {
|
||||
LOGE("CdmSession::RestoreOfflineSession: failed to retrieve license. "
|
||||
"key set id = %s", key_set_id.c_str());
|
||||
return GET_LICENSE_ERROR;
|
||||
}
|
||||
|
||||
// Do not restore a released offline license, unless a release retry
|
||||
if (!(license_type == kLicenseTypeRelease ||
|
||||
license_state == DeviceFiles::kLicenseStateActive)) {
|
||||
LOGE("CdmSession::Init invalid offline license state = %d, type = %d",
|
||||
license_state, license_type);
|
||||
LOGE("CdmSession::RestoreOfflineSession: invalid offline license state = "
|
||||
"%d, type = %d", license_state, license_type);
|
||||
return GET_RELEASED_LICENSE_ERROR;
|
||||
}
|
||||
|
||||
if (usage_support_type_ == kUsageEntrySupport) {
|
||||
CdmResponseType sts = usage_table_header_->LoadEntry(crypto_session_.get(),
|
||||
usage_entry_,
|
||||
usage_entry_number_);
|
||||
if (sts != NO_ERROR) {
|
||||
LOGE("CdmSession::RestoreOfflineSession: failed to load usage entry = %d",
|
||||
sts);
|
||||
return sts;
|
||||
}
|
||||
}
|
||||
|
||||
if (license_type == kLicenseTypeRelease) {
|
||||
if (!license_parser_->RestoreLicenseForRelease(key_request_,
|
||||
key_response_)) {
|
||||
@@ -213,6 +235,20 @@ CdmResponseType CdmSession::RestoreOfflineSession(
|
||||
}
|
||||
}
|
||||
|
||||
if (usage_support_type_ == kUsageEntrySupport) {
|
||||
CdmResponseType sts =
|
||||
usage_table_header_->UpdateEntry(crypto_session_.get(), &usage_entry_);
|
||||
if (sts != NO_ERROR) {
|
||||
LOGE("CdmSession::RestoreOfflineSession failed to update usage entry = "
|
||||
"%d", sts);
|
||||
return sts;
|
||||
}
|
||||
if (!StoreLicense(license_state)) {
|
||||
LOGW("CdmSession::RestoreUsageSession: unable to save updated usage "
|
||||
"info");
|
||||
}
|
||||
}
|
||||
|
||||
license_received_ = true;
|
||||
is_offline_ = true;
|
||||
is_release_ = license_type == kLicenseTypeRelease;
|
||||
@@ -220,14 +256,45 @@ CdmResponseType CdmSession::RestoreOfflineSession(
|
||||
}
|
||||
|
||||
CdmResponseType CdmSession::RestoreUsageSession(
|
||||
const CdmKeyMessage& key_request, const CdmKeyResponse& key_response) {
|
||||
key_request_ = key_request;
|
||||
key_response_ = key_response;
|
||||
const DeviceFiles::CdmUsageData& usage_data) {
|
||||
if (!key_set_id_.empty()) {
|
||||
file_handle_->UnreserveLicenseId(key_set_id_);
|
||||
}
|
||||
key_set_id_ = usage_data.key_set_id;
|
||||
key_request_ = usage_data.license_request;
|
||||
key_response_ = usage_data.license;
|
||||
usage_entry_ = usage_data.usage_entry;
|
||||
usage_entry_number_ = usage_data.usage_entry_number;
|
||||
usage_provider_session_token_ = usage_data.provider_session_token;
|
||||
|
||||
if (usage_support_type_ == kUsageEntrySupport) {
|
||||
CdmResponseType sts = usage_table_header_->LoadEntry(
|
||||
crypto_session_.get(), usage_entry_, usage_entry_number_);
|
||||
if (sts != NO_ERROR) {
|
||||
LOGE("CdmSession::RestoreUsageSession: failed to load usage entry = %d",
|
||||
sts);
|
||||
return sts;
|
||||
}
|
||||
}
|
||||
|
||||
if (!license_parser_->RestoreLicenseForRelease(key_request_, key_response_)) {
|
||||
return RELEASE_LICENSE_ERROR_2;
|
||||
}
|
||||
|
||||
if (usage_support_type_ == kUsageEntrySupport) {
|
||||
CdmResponseType sts =
|
||||
usage_table_header_->UpdateEntry(crypto_session_.get(), &usage_entry_);
|
||||
if (sts != NO_ERROR) {
|
||||
LOGE("CdmSession::RestoreUsageSession: failed to update usage entry: %d",
|
||||
sts);
|
||||
return sts;
|
||||
}
|
||||
if (!UpdateUsageInfo()) {
|
||||
LOGW("CdmSession::RestoreUsageSession: unable to save updated usage "
|
||||
"info");
|
||||
}
|
||||
}
|
||||
|
||||
license_received_ = true;
|
||||
is_offline_ = false;
|
||||
is_release_ = true;
|
||||
@@ -353,7 +420,36 @@ CdmResponseType CdmSession::AddKey(const CdmKeyResponse& key_response) {
|
||||
} else if (license_received_) { // renewal
|
||||
return RenewKey(key_response);
|
||||
} else {
|
||||
CdmResponseType sts = license_parser_->HandleKeyResponse(key_response);
|
||||
// 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 (usage_support_type_ == kUsageEntrySupport) {
|
||||
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), &usage_entry_number_);
|
||||
if (sts != NO_ERROR) return sts;
|
||||
}
|
||||
}
|
||||
sts = license_parser_->HandleKeyResponse(key_response);
|
||||
|
||||
// Update or delete entry if usage table header+entries are supported
|
||||
if (usage_support_type_ == kUsageEntrySupport &&
|
||||
!provider_session_token.empty()) {
|
||||
if (sts != KEY_ADDED) {
|
||||
CdmResponseType sts =
|
||||
usage_table_header_->DeleteEntry(usage_entry_number_);
|
||||
if (sts != NO_ERROR) {
|
||||
LOGW("CdmSession::AddKey: Delete usage entry failed = %d", sts);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sts != KEY_ADDED) return (sts == KEY_ERROR) ? ADD_KEY_ERROR : sts;
|
||||
|
||||
@@ -361,6 +457,13 @@ CdmResponseType CdmSession::AddKey(const CdmKeyResponse& key_response) {
|
||||
key_response_ = key_response;
|
||||
|
||||
if (is_offline_ || !license_parser_->provider_session_token().empty()) {
|
||||
if (usage_support_type_ == kUsageEntrySupport)
|
||||
usage_table_header_->UpdateEntry(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;
|
||||
}
|
||||
@@ -522,9 +625,24 @@ CdmResponseType CdmSession::GenerateReleaseRequest(
|
||||
|
||||
if (KEY_MESSAGE != status) return status;
|
||||
|
||||
if (usage_support_type_ == kUsageEntrySupport) {
|
||||
status = usage_table_header_->UpdateEntry(crypto_session_.get(),
|
||||
&usage_entry_);
|
||||
if (status != NO_ERROR) {
|
||||
LOGE("CdmSession::GenerateReleaseRequest: Update usage entry failed = "
|
||||
"%d", status);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_offline_) { // Mark license as being released
|
||||
if (!StoreLicense(DeviceFiles::kLicenseStateReleasing))
|
||||
return RELEASE_KEY_REQUEST_ERROR;
|
||||
} else if (!usage_provider_session_token_.empty()) {
|
||||
if (usage_support_type_ == kUsageEntrySupport) {
|
||||
if (!UpdateUsageInfo())
|
||||
return RELEASE_USAGE_INFO_FAILED;
|
||||
}
|
||||
}
|
||||
return KEY_MESSAGE;
|
||||
}
|
||||
@@ -537,10 +655,41 @@ CdmResponseType CdmSession::ReleaseKey(const CdmKeyResponse& key_response) {
|
||||
|
||||
if (is_offline_ || !license_parser_->provider_session_token().empty()) {
|
||||
DeleteLicense();
|
||||
|
||||
// Deletion of usage entry cannot occur while in use by a crypto session.
|
||||
// So close and reopen after deletion.
|
||||
if (usage_support_type_ == kUsageEntrySupport) {
|
||||
M_TIME(
|
||||
crypto_session_->Close(),
|
||||
&metrics_,
|
||||
crypto_session_close_);
|
||||
|
||||
CdmResponseType sts = usage_table_header_->DeleteEntry(usage_entry_number_);
|
||||
if (sts != NO_ERROR) return sts;
|
||||
|
||||
M_TIME(
|
||||
sts = crypto_session_->Open(requested_security_level_),
|
||||
&metrics_,
|
||||
crypto_session_open_,
|
||||
sts,
|
||||
requested_security_level_);
|
||||
if (NO_ERROR != sts) return sts;
|
||||
}
|
||||
}
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
CdmResponseType CdmSession::DeleteUsageEntry(
|
||||
const DeviceFiles::CdmUsageData& usage_data) {
|
||||
if (usage_support_type_ != kUsageEntrySupport) {
|
||||
LOGE("CdmSession::DeleteUsageEntry: Unexpected usage type supported: %d",
|
||||
usage_support_type_);
|
||||
return INCORRECT_USAGE_SUPPORT_TYPE_1;
|
||||
}
|
||||
|
||||
return usage_table_header_->DeleteEntry(usage_data.usage_entry_number);
|
||||
}
|
||||
|
||||
bool CdmSession::IsKeyLoaded(const KeyId& key_id) {
|
||||
return license_parser_->IsKeyLoaded(key_id);
|
||||
}
|
||||
@@ -624,13 +773,11 @@ CdmResponseType CdmSession::StoreLicense() {
|
||||
|
||||
std::string app_id;
|
||||
GetApplicationId(&app_id);
|
||||
std::string usage_entry;
|
||||
uint32_t usage_entry_number = 0;
|
||||
if (!file_handle_->StoreUsageInfo(provider_session_token, key_request_,
|
||||
key_response_,
|
||||
DeviceFiles::GetUsageInfoFileName(app_id),
|
||||
key_set_id_, usage_entry,
|
||||
usage_entry_number)) {
|
||||
key_set_id_, usage_entry_,
|
||||
usage_entry_number_)) {
|
||||
LOGE("CdmSession::StoreLicense: Unable to store usage info");
|
||||
return STORE_USAGE_INFO_ERROR;
|
||||
}
|
||||
@@ -638,15 +785,13 @@ CdmResponseType CdmSession::StoreLicense() {
|
||||
}
|
||||
|
||||
bool CdmSession::StoreLicense(DeviceFiles::LicenseState state) {
|
||||
std::string usage_entry;
|
||||
uint32_t usage_entry_number = 0;
|
||||
return file_handle_->StoreLicense(
|
||||
key_set_id_, state, offline_init_data_, key_request_, key_response_,
|
||||
offline_key_renewal_request_, offline_key_renewal_response_,
|
||||
offline_release_server_url_, policy_engine_->GetPlaybackStartTime(),
|
||||
policy_engine_->GetLastPlaybackTime(),
|
||||
policy_engine_->GetGracePeriodEndTime(), app_parameters_, usage_entry,
|
||||
usage_entry_number);
|
||||
policy_engine_->GetGracePeriodEndTime(), app_parameters_, usage_entry_,
|
||||
usage_entry_number_);
|
||||
}
|
||||
|
||||
CdmResponseType CdmSession::ReleaseCrypto() {
|
||||
@@ -712,7 +857,7 @@ CdmResponseType CdmSession::DeleteMultipleUsageInformation(
|
||||
return sts;
|
||||
}
|
||||
|
||||
CdmResponseType CdmSession::UpdateUsageInformation() {
|
||||
CdmResponseType CdmSession::UpdateUsageTableInformation() {
|
||||
CdmResponseType sts;
|
||||
M_TIME(
|
||||
sts = crypto_session_->UpdateUsageInformation(),
|
||||
@@ -722,6 +867,28 @@ CdmResponseType CdmSession::UpdateUsageInformation() {
|
||||
return sts;
|
||||
}
|
||||
|
||||
CdmResponseType CdmSession::UpdateUsageEntryInformation() {
|
||||
if (usage_support_type_ != kUsageEntrySupport) {
|
||||
LOGE("CdmSession::UpdateUsageEntryInformation: Unexpected usage type "
|
||||
"supported: %d", usage_support_type_);
|
||||
return INCORRECT_USAGE_SUPPORT_TYPE_2;
|
||||
}
|
||||
|
||||
CdmResponseType sts = usage_table_header_->UpdateEntry(crypto_session_.get(),
|
||||
&usage_entry_);
|
||||
|
||||
if (sts != NO_ERROR) return sts;
|
||||
|
||||
if (is_offline_)
|
||||
StoreLicense(is_release_
|
||||
? DeviceFiles::kLicenseStateReleasing
|
||||
: DeviceFiles::kLicenseStateActive);
|
||||
else if (!usage_provider_session_token_.empty())
|
||||
UpdateUsageInfo();
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
CdmResponseType CdmSession::GenericEncrypt(const std::string& in_buffer,
|
||||
const std::string& key_id,
|
||||
const std::string& iv,
|
||||
@@ -814,6 +981,24 @@ CdmResponseType CdmSession::GenericVerify(const std::string& message,
|
||||
return sts;
|
||||
}
|
||||
|
||||
bool CdmSession::UpdateUsageInfo() {
|
||||
std::string app_id;
|
||||
GetApplicationId(&app_id);
|
||||
|
||||
DeviceFiles::CdmUsageData usage_data;
|
||||
usage_data.provider_session_token = usage_provider_session_token_;
|
||||
usage_data.license_request = key_request_;
|
||||
usage_data.license = key_response_;
|
||||
usage_data.key_set_id = key_set_id_;
|
||||
usage_data.usage_entry = usage_entry_;
|
||||
usage_data.usage_entry_number = usage_entry_number_;
|
||||
|
||||
return file_handle_->UpdateUsageInfo(
|
||||
DeviceFiles::GetUsageInfoFileName(app_id),
|
||||
usage_provider_session_token_,
|
||||
usage_data);
|
||||
}
|
||||
|
||||
// For testing only - takes ownership of pointers
|
||||
|
||||
void CdmSession::set_license_parser(CdmLicense* license_parser) {
|
||||
|
||||
Reference in New Issue
Block a user