Translate Some CDM Errors as Events

The CDM may use the eventing mechanism or the error return-value mechanism to
notify callers of errors that the Java APIs expect to be passed via the
eventing mechanism.  We need to detect when an error has been synchronously
returned via the error return value of a method and fire an appropriate event.

bug: 8620943

Merge of https://widevine-internal-review.googlesource.com/#/c/5261/
from the Widevine CDM repo.

Change-Id: I2055854dc960845dc775b1fceab9d0850b63fbb5
This commit is contained in:
Jeff Tinker
2013-04-25 06:12:01 -07:00
parent 15cf441d17
commit 187d3e94e8
2 changed files with 37 additions and 27 deletions

View File

@@ -161,7 +161,11 @@ class WVDrmPlugin : public android::DrmPlugin,
WVGenericCryptoInterface* mCrypto;
map<CdmSessionId, CryptoSession> mCryptoSessions;
static status_t mapOEMCryptoResult(OEMCryptoResult res);
status_t mapAndNotifyOfCdmResponseType(const Vector<uint8_t>& sessionId,
CdmResponseType res);
status_t mapAndNotifyOfOEMCryptoResult(const Vector<uint8_t>& sessionId,
OEMCryptoResult res);
};
} // namespace wvdrm

View File

@@ -48,7 +48,7 @@ status_t WVDrmPlugin::openSession(Vector<uint8_t>& sessionId) {
CdmResponseType res = mCDM->OpenSession("com.widevine", &cdmSessionId);
if (!isCdmResponseTypeSuccess(res)) {
return mapCdmResponseType(res);
return mapAndNotifyOfCdmResponseType(sessionId, res);
}
bool success = false;
@@ -94,7 +94,7 @@ status_t WVDrmPlugin::openSession(Vector<uint8_t>& sessionId) {
if (!isCdmResponseTypeSuccess(res)) {
// We got an error code we can return.
return mapCdmResponseType(res);
return mapAndNotifyOfCdmResponseType(sessionId, res);
} else {
// We got a failure that did not give us an error code, such as a failure
// of AttachEventListener() or the key being missing from the map.
@@ -111,7 +111,7 @@ status_t WVDrmPlugin::closeSession(const Vector<uint8_t>& sessionId) {
mCryptoSessions.erase(cdmSessionId);
}
return mapCdmResponseType(res);
return mapAndNotifyOfCdmResponseType(sessionId, res);
}
status_t WVDrmPlugin::getKeyRequest(
@@ -177,7 +177,7 @@ status_t WVDrmPlugin::getKeyRequest(
keyRequest.size());
}
return mapCdmResponseType(res);
return mapAndNotifyOfCdmResponseType(sessionId, res);
}
status_t WVDrmPlugin::provideKeyResponse(
@@ -190,7 +190,7 @@ status_t WVDrmPlugin::provideKeyResponse(
CdmResponseType res = mCDM->AddKey(cdmSessionId, cdmResponse);
return mapCdmResponseType(res);
return mapAndNotifyOfCdmResponseType(sessionId, res);
}
status_t WVDrmPlugin::removeKeys(const Vector<uint8_t>& keySetId) {
@@ -252,20 +252,15 @@ status_t WVDrmPlugin::getProvisionRequest(Vector<uint8_t>& request,
}
status_t WVDrmPlugin::provideProvisionResponse(
const Vector<uint8_t>& response) {
const Vector<uint8_t>& response) {
CdmProvisioningResponse cdmResponse(response.begin(), response.end());
CdmResponseType res = mCDM->HandleProvisioningResponse(cdmResponse);
return mapCdmResponseType(res);
}
status_t WVDrmPlugin::getSecureStops(List<Vector<uint8_t> >& secureStops) {
CdmSecureStops cdmSecureStops;
CdmResponseType res = mCDM->GetSecureStops(&cdmSecureStops);
if (isCdmResponseTypeSuccess(res)) {
secureStops.clear();
for (CdmSecureStops::const_iterator iter = cdmSecureStops.begin();
@@ -280,7 +275,6 @@ status_t WVDrmPlugin::getSecureStops(List<Vector<uint8_t> >& secureStops) {
secureStops.push_back(stop);
}
}
return mapCdmResponseType(res);
}
@@ -430,7 +424,7 @@ status_t WVDrmPlugin::encrypt(const Vector<uint8_t>& sessionId,
if (res != OEMCrypto_SUCCESS) {
ALOGE("OEMCrypto_SelectKey failed with %u", res);
return mapOEMCryptoResult(res);
return mapAndNotifyOfOEMCryptoResult(sessionId, res);
}
output.resize(input.size());
@@ -443,7 +437,7 @@ status_t WVDrmPlugin::encrypt(const Vector<uint8_t>& sessionId,
return android::OK;
} else {
ALOGE("OEMCrypto_Generic_Encrypt failed with %u", res);
return mapOEMCryptoResult(res);
return mapAndNotifyOfOEMCryptoResult(sessionId, res);
}
}
@@ -469,7 +463,7 @@ status_t WVDrmPlugin::decrypt(const Vector<uint8_t>& sessionId,
if (res != OEMCrypto_SUCCESS) {
ALOGE("OEMCrypto_SelectKey failed with %u", res);
return mapOEMCryptoResult(res);
return mapAndNotifyOfOEMCryptoResult(sessionId, res);
}
output.resize(input.size());
@@ -482,7 +476,7 @@ status_t WVDrmPlugin::decrypt(const Vector<uint8_t>& sessionId,
return android::OK;
} else {
ALOGE("OEMCrypto_Generic_Decrypt failed with %u", res);
return mapOEMCryptoResult(res);
return mapAndNotifyOfOEMCryptoResult(sessionId, res);
}
}
@@ -507,7 +501,7 @@ status_t WVDrmPlugin::sign(const Vector<uint8_t>& sessionId,
if (res != OEMCrypto_SUCCESS) {
ALOGE("OEMCrypto_SelectKey failed with %u", res);
return mapOEMCryptoResult(res);
return mapAndNotifyOfOEMCryptoResult(sessionId, res);
}
size_t signatureSize = 0;
@@ -520,7 +514,7 @@ status_t WVDrmPlugin::sign(const Vector<uint8_t>& sessionId,
ALOGE("OEMCrypto_Generic_Sign failed with %u when requesting signature "
"size", res);
if (res != OEMCrypto_SUCCESS) {
return mapOEMCryptoResult(res);
return mapAndNotifyOfOEMCryptoResult(sessionId, res);
} else {
return android::ERROR_DRM_UNKNOWN;
}
@@ -536,7 +530,7 @@ status_t WVDrmPlugin::sign(const Vector<uint8_t>& sessionId,
return android::OK;
} else {
ALOGE("OEMCrypto_Generic_Sign failed with %u", res);
return mapOEMCryptoResult(res);
return mapAndNotifyOfOEMCryptoResult(sessionId, res);
}
}
@@ -562,7 +556,7 @@ status_t WVDrmPlugin::verify(const Vector<uint8_t>& sessionId,
if (res != OEMCrypto_SUCCESS) {
ALOGE("OEMCrypto_SelectKey failed with %u", res);
return mapOEMCryptoResult(res);
return mapAndNotifyOfOEMCryptoResult(sessionId, res);
}
res = mCrypto->verify(cryptoSession.oecSessionId(), message.array(),
@@ -577,14 +571,14 @@ status_t WVDrmPlugin::verify(const Vector<uint8_t>& sessionId,
return android::OK;
} else {
ALOGE("OEMCrypto_Generic_Verify failed with %u", res);
return mapOEMCryptoResult(res);
return mapAndNotifyOfOEMCryptoResult(sessionId, res);
}
}
void WVDrmPlugin::onEvent(const CdmSessionId& cdmSessionId,
CdmEventType cdmEventType) {
Vector<uint8_t> sessionId;
EventType eventType;
EventType eventType = kDrmPluginEventVendorDefined;
switch (cdmEventType) {
case LICENSE_EXPIRED_EVENT:
@@ -593,9 +587,6 @@ void WVDrmPlugin::onEvent(const CdmSessionId& cdmSessionId,
case LICENSE_RENEWAL_NEEDED_EVENT:
eventType = kDrmPluginEventKeyNeeded;
break;
default:
ALOGE("Unknown CDM Event Received by WVDrmPlugin: %u", cdmEventType);
return;
}
sessionId.appendArray(reinterpret_cast<const uint8_t*>(cdmSessionId.data()),
@@ -605,7 +596,21 @@ void WVDrmPlugin::onEvent(const CdmSessionId& cdmSessionId,
sendEvent(eventType, 0, &sessionId, NULL);
}
status_t WVDrmPlugin::mapOEMCryptoResult(OEMCryptoResult res) {
status_t WVDrmPlugin::mapAndNotifyOfCdmResponseType(
const Vector<uint8_t>& sessionId,
CdmResponseType res) {
if (res == wvcdm::NEED_PROVISIONING) {
sendEvent(kDrmPluginEventProvisionRequired, 0, &sessionId, NULL);
} else if (res == wvcdm::NEED_KEY) {
sendEvent(kDrmPluginEventKeyNeeded, 0, &sessionId, NULL);
}
return mapCdmResponseType(res);
}
status_t WVDrmPlugin::mapAndNotifyOfOEMCryptoResult(
const Vector<uint8_t>& sessionId,
OEMCryptoResult res) {
// Note that we only cover those errors that OEMCryptoCENC.h states may be
// returned by the generic crypto methods.
switch (res) {
@@ -616,6 +621,7 @@ status_t WVDrmPlugin::mapOEMCryptoResult(OEMCryptoResult res) {
case OEMCrypto_ERROR_SHORT_BUFFER:
return kErrorIncorrectBufferSize;
case OEMCrypto_ERROR_NO_DEVICE_KEY:
sendEvent(kDrmPluginEventProvisionRequired, 0, &sessionId, NULL);
return android::ERROR_DRM_NOT_PROVISIONED;
case OEMCrypto_ERROR_INVALID_SESSION:
return android::ERROR_DRM_SESSION_NOT_OPENED;