Support ATSC license installation

[ Merge of http://go/wvgerrit/163900/ ]

ATSC licenses can be saved by calling
MediaDrm#setPropertyString("storeAtscLicense",<value>)
where <value> is
"<atsc-key-set-ID>:<license-file-data in Base64 format>"

Before storing an ATSC license a session must be opened and the
ATSC mode must be enabled.

Use MediaDrm#setPropertyString("atscMode","enable");

Bug: 176871821
Test: WV Unit/integration/Luci tests
Test: libwvdrmdrmplugin_hal_test
Test: GtsMediaTestCases
Change-Id: Iec2a8b7f87b1122395d06856202278b92316fdfe
This commit is contained in:
Rahul Frias
2022-12-17 19:34:33 -08:00
parent 233bac3a6f
commit 1e15b36b1a
9 changed files with 388 additions and 0 deletions

View File

@@ -26,6 +26,7 @@
#include "mapErrors-inl.h"
#include "media/stagefright/MediaErrors.h"
#include "openssl/sha.h"
#include "string_conversions.h"
#include "wv_cdm_constants.h"
#include "wv_metrics.pb.h"
#include "wv_metrics_adapter.h"
@@ -1344,6 +1345,32 @@ Status WVDrmPlugin::unprovisionDevice() {
if (!success) {
return toNdkScopedAStatus(Status::ERROR_DRM_UNKNOWN);
}
} else if (name == "storeAtscLicense") {
if (!mCdmIdentifierBuilder.is_sealed()) {
ALOGE("Cdm identifier builder is not sealed. Storing ATSC license "
"prohibited");
return toNdkScopedAStatus(Status::ERROR_DRM_CANNOT_HANDLE);
}
if (!mPropertySet.use_atsc_mode()) {
ALOGE("ATSC mode not enabled. Storing ATSC license prohibited");
return toNdkScopedAStatus(Status::ERROR_DRM_CANNOT_HANDLE);
}
CdmIdentifier identifier;
auto status = mCdmIdentifierBuilder.getCdmIdentifier(&identifier);
if (status != Status::OK) {
ALOGE("Unable to get CDM Identifier = %d", status.get());
return toNdkScopedAStatus(status);
}
std::string key_set_id, license_data;
status = parseAtscLicenseData(_value, &key_set_id, &license_data);
if (status != Status::OK)
return toNdkScopedAStatus(status);
const CdmResponseType res = mCDM->StoreAtscLicense(
identifier, getRequestedSecurityLevel(), key_set_id, license_data);
return toNdkScopedAStatus(mapCdmResponseType(res));
} else {
ALOGE("App set unknown string property %s", name.c_str());
return toNdkScopedAStatus(Status::ERROR_DRM_CANNOT_HANDLE);
@@ -1871,6 +1898,57 @@ bool WVDrmPlugin::isProvisioned(wvcdm::CdmSecurityLevel securityLevel,
return mCDM->IsProvisioned(securityLevel, origin, spoid, atsc_mode_enabled);
}
WvStatus WVDrmPlugin::parseAtscLicenseData(
const std::string& in_value,
std::string* key_set_id,
std::string* serialized_license_data) {
if (key_set_id == nullptr) {
ALOGE("key_set_id null");
return WvStatus(Status::ERROR_DRM_CANNOT_HANDLE);
}
if (serialized_license_data == nullptr) {
ALOGE("serialized_license_data null");
return WvStatus(Status::ERROR_DRM_CANNOT_HANDLE);
}
if (in_value.compare(0,
strlen(wvcdm::ATSC_KEY_SET_ID_PREFIX),
&wvcdm::ATSC_KEY_SET_ID_PREFIX[0]) != 0) {
ALOGE("ATSC license input does not conform to expectations. Key set does "
"not have a valid ATSC Key set prefix %s", in_value.c_str());
return WvStatus(Status::BAD_VALUE);
}
const char kColon = ':';
const size_t pos = in_value.find(kColon);
if (pos == std::string::npos) {
ALOGE("ATSC license input does not conform to expectations. Missing colon "
"= %s", in_value.c_str());
return WvStatus(Status::BAD_VALUE);
}
if (pos == in_value.length()) {
ALOGE("ATSC license input does not conform to expectations. No data after "
"colon");
return WvStatus(Status::BAD_VALUE);
}
*key_set_id = in_value.substr(0, pos);
const std::vector<uint8_t> license_data_binary =
wvutil::Base64Decode(in_value.substr(pos+1));
if (license_data_binary.empty()) {
ALOGE("ATSC license input does not conform to expectations. License data "
"failed to decode from Base64");
return WvStatus(Status::BAD_VALUE);
}
serialized_license_data->assign(license_data_binary.begin(),
license_data_binary.end());
return WvStatus(Status::OK);
}
WvStatus WVDrmPlugin::mapAndNotifyOfCdmResponseType(
const vector<uint8_t>& sessionId, CdmResponseType res) {
notifyOfCdmResponseType(sessionId, res);