Implement MediaDrm offline license support in Widevine hidl service.

Merged from http://go/wvgerrit/69723.

The new APIs are getOfflineLicenseIds, getOfflineLicenseState and
removeOfflineLicense. These methods are currently stubbed out in
Widevine hidl service. This CL completes the implementation.

Test: unit tests - libwvdrmdrmplugin_hidl_test

Test: GTS
  --test com.google.android.media.gts.MediaDrmTest#testWidevineApi29

bug: 117570686
Change-Id: I96ffb75f453e36e931effefd3664b5faa8d69d30
This commit is contained in:
Edwin Wong
2019-01-21 17:07:43 -08:00
parent 19c4996b3c
commit 54104c7a22
12 changed files with 462 additions and 30 deletions

View File

@@ -27,6 +27,18 @@ namespace {
const uint64_t kReleaseSessionTimeToLive = 60; // seconds
const uint32_t kUpdateUsageInformationPeriod = 60; // seconds
const size_t kUsageReportsPerRequest = 1;
wvcdm::CdmOfflineLicenseState MapDeviceFilesLicenseState(
wvcdm::DeviceFiles::LicenseState state) {
switch (state) {
case wvcdm::DeviceFiles::LicenseState::kLicenseStateActive:
return wvcdm::kLicenseStateActive;
case wvcdm::DeviceFiles::LicenseState::kLicenseStateReleasing:
return wvcdm::kLicenseStateReleasing;
default:
return wvcdm::kLicenseStateUnknown;
}
}
} // namespace
namespace wvcdm {
@@ -1100,6 +1112,98 @@ CdmResponseType CdmEngine::DeleteUsageRecord(const std::string& app_id,
return status;
}
CdmResponseType CdmEngine::GetOfflineLicenseState(
const CdmKeySetId &key_set_id,
CdmSecurityLevel security_level,
CdmOfflineLicenseState* license_state) {
DeviceFiles handle(file_system_);
if (!handle.Init(security_level)) {
LOGE("CdmEngine::GetOfflineLicenseState: cannot initialize device files");
return GET_OFFLINE_LICENSE_STATE_ERROR_1;
}
DeviceFiles::LicenseState state;
// Dummy arguments to make the RetrieveLicense call,
// do not care about the return value except for license state.
CdmAppParameterMap app_parameters;
CdmKeyMessage key_request;
CdmKeyResponse key_response;
CdmInitData offline_init_data;
CdmKeyMessage offline_key_renewal_request;
CdmKeyResponse offline_key_renewal_response;
CdmUsageEntry usage_entry;
int64_t grace_period_end_time;
int64_t last_playback_time;
std::string offline_release_server_url;
int64_t playback_start_time;
uint32_t usage_entry_number;
DeviceFiles::ResponseType sub_error_code = DeviceFiles::kNoError;
if (handle.RetrieveLicense(key_set_id, &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,
&sub_error_code)) {
*license_state = MapDeviceFilesLicenseState(state);
} else {
LOGE("CdmEngine::GetOfflineLicenseState:: failed to retrieve license state "
"key set id = %s",
key_set_id.c_str());
return GET_OFFLINE_LICENSE_STATE_ERROR_2;
}
return NO_ERROR;
}
CdmResponseType CdmEngine::RemoveOfflineLicense(
const CdmKeySetId &key_set_id,
CdmSecurityLevel security_level) {
UsagePropertySet property_set;
property_set.set_security_level(
security_level == kSecurityLevelL3 ? kLevel3 : kLevelDefault);
DeviceFiles handle(file_system_);
CdmResponseType sts = OpenKeySetSession(key_set_id,
&property_set, nullptr /* event listener */);
if (sts != NO_ERROR) {
if (!handle.Init(security_level)) {
LOGE("CdmEngine::RemoveOfflineLicense: cannot initialize device files");
}
handle.DeleteLicense(key_set_id);
return REMOVE_OFFLINE_LICENSE_ERROR_1;
}
CdmSessionId session_id;
CdmAppParameterMap dummy_app_params;
InitializationData dummy_init_data("", "", "");
CdmKeyRequest key_request;
// Calling with no session_id is okay
sts = GenerateKeyRequest(session_id, key_set_id, dummy_init_data,
kLicenseTypeRelease, dummy_app_params, &key_request);
if (sts == KEY_MESSAGE) {
std::unique_lock<std::mutex> lock(release_key_sets_lock_);
CdmReleaseKeySetMap::iterator iter = release_key_sets_.find(key_set_id);
if (iter == release_key_sets_.end()) {
LOGE("CdmEngine::RemoveOfflineLicense: key set id not found = %s",
key_set_id.c_str());
sts = REMOVE_OFFLINE_LICENSE_ERROR_2;
} else {
session_id = iter->second.first;
sts = RemoveLicense(session_id);
}
}
if (sts != NO_ERROR) {
LOGE("CdmEngine: GenerateKeyRequest error=%d", sts);
handle.DeleteLicense(key_set_id);
}
CloseKeySetSession(key_set_id);
return sts;
}
CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id,
const CdmSecureStopId& ssid,
CdmUsageInfo* usage_info) {