Allow Secure Stops to be queried and deleted by application ID

This CL changes the WVDrmPlugin so that an application can segregate
its secure stops from those of other applications by setting an
application ID.

This CL is a merge of the following Widevine CLs:
https://widevine-internal-review.googlesource.com/#/c/11565/
Add getSecureStop by ssid

https://widevine-internal-review.googlesource.com/#/c/11572
Add getSecureStop by SSID and releaseAllSecureStops by app id.

https://widevine-internal-review.googlesource.com/#/c/11564/
Store Usage Info by App Id (device_file stubs)

https://widevine-internal-review.googlesource.com/#/c/11563/
Add application id to StoreUsageInfo.

https://widevine-internal-review.googlesource.com/#/c/11561/
Added Application ID to PropertySet for secure stop.

bug: 18053197
bug: 18076411
Change-Id: I5444baf67ba1b960dee2dc958bced8de82ab70a3
This commit is contained in:
Fred Gylys-Colwell
2014-11-05 17:39:44 -08:00
parent b3650a9661
commit 20191d996c
19 changed files with 421 additions and 54 deletions

View File

@@ -43,7 +43,11 @@ class UsagePropertySet : public CdmClientPropertySet {
virtual void set_session_sharing_id(uint32_t id) {
id; // noop to suppress warning
}
virtual const std::string& app_id() const { return app_id_; }
void set_app_id(const std::string& appId) { app_id_ = appId; }
private:
std::string app_id_;
std::string security_level_;
const std::string empty_;
};
@@ -582,29 +586,95 @@ CdmResponseType CdmEngine::Unprovision(CdmSecurityLevel security_level) {
return status;
}
CdmResponseType CdmEngine::GetUsageInfo(CdmUsageInfo* usage_info) {
CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id,
const CdmSecureStopId& ssid,
CdmUsageInfo* usage_info) {
if (NULL == usage_property_set_.get()) {
usage_property_set_.reset(new UsagePropertySet());
}
usage_property_set_->set_security_level(kLevelDefault);
usage_property_set_->set_app_id(app_id);
usage_session_.reset(new CdmSession(usage_property_set_.get()));
CdmResponseType status = usage_session_->Init();
if (NO_ERROR != status) {
LOGE("CdmEngine::GetUsageInfo: session init error");
return status;
}
DeviceFiles handle;
if (!handle.Init(usage_session_->GetSecurityLevel())) {
LOGE("CdmEngine::GetUsageInfo: device file init error");
return UNKNOWN_ERROR;
}
CdmKeyMessage license_request;
CdmKeyResponse license_response;
if (!handle.RetrieveUsageInfo(app_id, ssid, &license_request,
&license_response)) {
usage_property_set_->set_security_level(kLevel3);
usage_property_set_->set_app_id(app_id);
usage_session_.reset(new CdmSession(usage_property_set_.get()));
status = usage_session_->Init();
if (NO_ERROR != status) {
LOGE("CdmEngine::GetUsageInfo: session init error");
return status;
}
if (!handle.Reset(usage_session_->GetSecurityLevel())) {
LOGE("CdmEngine::GetUsageInfo: device file init error");
return UNKNOWN_ERROR;
}
if (!handle.RetrieveUsageInfo(app_id, ssid, &license_request,
&license_response)) {
// No entry found for that ssid.
return UNKNOWN_ERROR;
}
}
std::string server_url;
usage_info->resize(1);
status =
usage_session_->RestoreUsageSession(license_request, license_response);
if (KEY_ADDED != status) {
LOGE("CdmEngine::GetUsageInfo: restore usage session error %d", status);
usage_info->clear();
return status;
}
status =
usage_session_->GenerateReleaseRequest(&(*usage_info)[0], &server_url);
if (KEY_MESSAGE != status) {
LOGE("CdmEngine::GetUsageInfo: generate release request error: %d", status);
usage_info->clear();
return status;
}
return KEY_MESSAGE;
}
CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id,
CdmUsageInfo* usage_info) {
// Return a random usage report from a random security level
SecurityLevel security_level = ((rand() % 2) == 0) ? kLevelDefault : kLevel3;
CdmResponseType status = GetUsageInfo(security_level, usage_info);
CdmResponseType status = GetUsageInfo(app_id, security_level, usage_info);
if (KEY_MESSAGE == status && !usage_info->empty())
return status;
security_level = (kLevel3 == security_level) ? kLevelDefault : kLevel3;
status = GetUsageInfo(security_level, usage_info);
status = GetUsageInfo(app_id, security_level, usage_info);
if (NEED_PROVISIONING == status)
return NO_ERROR; // Valid scenario that one of the security
// levels has not been provisioned
return status;
}
CdmResponseType CdmEngine::GetUsageInfo(
SecurityLevel requested_security_level,
CdmUsageInfo* usage_info) {
CdmResponseType CdmEngine::GetUsageInfo(const std::string& app_id,
SecurityLevel requested_security_level,
CdmUsageInfo* usage_info) {
if (NULL == usage_property_set_.get()) {
usage_property_set_.reset(new UsagePropertySet());
}
usage_property_set_->set_security_level(requested_security_level);
usage_property_set_->set_app_id(app_id);
usage_session_.reset(new CdmSession(usage_property_set_.get()));
@@ -617,11 +687,11 @@ CdmResponseType CdmEngine::GetUsageInfo(
DeviceFiles handle;
if (!handle.Init(usage_session_->GetSecurityLevel())) {
LOGE("CdmEngine::GetUsageInfo: unable to initialize device files");
return status;
return UNKNOWN_ERROR;
}
std::vector<std::pair<CdmKeyMessage, CdmKeyResponse> > license_info;
if (!handle.RetrieveUsageInfo(&license_info)) {
if (!handle.RetrieveUsageInfo(app_id, &license_info)) {
LOGE("CdmEngine::GetUsageInfo: unable to read usage information");
return UNKNOWN_ERROR;
}
@@ -655,6 +725,23 @@ CdmResponseType CdmEngine::GetUsageInfo(
return KEY_MESSAGE;
}
CdmResponseType CdmEngine::ReleaseAllUsageInfo(const std::string& app_id) {
CdmResponseType status = NO_ERROR;
DeviceFiles handle[kSecurityLevelUnknown - kSecurityLevelL1];
for (int i = 0, j = kSecurityLevelL1; j < kSecurityLevelUnknown; ++i, ++j) {
if (handle[i].Init(static_cast<CdmSecurityLevel>(j))) {
if (!handle[i].DeleteAllUsageInfoForApp(app_id)) {
LOGE("CdmEngine::ReleaseAllUsageInfo: failed to delete L%d secure stops", j);
status = UNKNOWN_ERROR;
}
} else {
LOGE("CdmEngine::ReleaseAllUsageInfo: failed to initialize L%d device files", j);
status = UNKNOWN_ERROR;
}
}
return status;
}
CdmResponseType CdmEngine::ReleaseUsageInfo(
const CdmUsageInfoReleaseMessage& message) {
if (NULL == usage_session_.get()) {