Merge "Add additional error conditions to MediaDrm"
diff --git a/drm/libmediadrm/CryptoHal.cpp b/drm/libmediadrm/CryptoHal.cpp
index 3035c5a..4dda5d7 100644
--- a/drm/libmediadrm/CryptoHal.cpp
+++ b/drm/libmediadrm/CryptoHal.cpp
@@ -30,16 +30,16 @@
#include <media/stagefright/MediaErrors.h>
#include <mediadrm/CryptoHal.h>
+using drm::V1_0::BufferType;
+using drm::V1_0::DestinationBuffer;
+using drm::V1_0::ICryptoFactory;
+using drm::V1_0::ICryptoPlugin;
+using drm::V1_0::Mode;
+using drm::V1_0::Pattern;
+using drm::V1_0::SharedBuffer;
+using drm::V1_0::Status;
+using drm::V1_0::SubSample;
-using ::android::hardware::drm::V1_0::BufferType;
-using ::android::hardware::drm::V1_0::DestinationBuffer;
-using ::android::hardware::drm::V1_0::ICryptoFactory;
-using ::android::hardware::drm::V1_0::ICryptoPlugin;
-using ::android::hardware::drm::V1_0::Mode;
-using ::android::hardware::drm::V1_0::Pattern;
-using ::android::hardware::drm::V1_0::SharedBuffer;
-using ::android::hardware::drm::V1_0::Status;
-using ::android::hardware::drm::V1_0::SubSample;
using ::android::hardware::hidl_array;
using ::android::hardware::hidl_handle;
using ::android::hardware::hidl_memory;
@@ -50,6 +50,7 @@
using ::android::hidl::manager::V1_0::IServiceManager;
using ::android::sp;
+typedef drm::V1_2::Status Status_V1_2;
namespace android {
@@ -76,6 +77,18 @@
}
}
+static status_t toStatusT_1_2(Status_V1_2 status) {
+ switch (status) {
+ case Status_V1_2::ERROR_DRM_SESSION_LOST_STATE:
+ return ERROR_DRM_SESSION_LOST_STATE;;
+ case Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE:
+ return ERROR_DRM_FRAME_TOO_LARGE;
+ case Status_V1_2::ERROR_DRM_INSUFFICIENT_SECURITY:
+ return ERROR_DRM_INSUFFICIENT_SECURITY;
+ default:
+ return toStatusT(static_cast<Status>(status));
+ }
+}
static hidl_vec<uint8_t> toHidlVec(const Vector<uint8_t> &vector) {
hidl_vec<uint8_t> vec;
@@ -196,6 +209,9 @@
for (size_t i = 0; i < mFactories.size(); i++) {
if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
mPlugin = makeCryptoPlugin(mFactories[i], uuid, data, size);
+ if (mPlugin != NULL) {
+ mPluginV1_2 = drm::V1_2::ICryptoPlugin::castFrom(mPlugin);
+ }
}
}
@@ -216,6 +232,7 @@
}
mPlugin.clear();
+ mPluginV1_2.clear();
return OK;
}
@@ -389,21 +406,33 @@
status_t err = UNKNOWN_ERROR;
uint32_t bytesWritten = 0;
- Return<void> hResult = mPlugin->decrypt(secure, toHidlArray16(keyId), toHidlArray16(iv), hMode,
- hPattern, hSubSamples, hSource, offset, hDestination,
- [&](Status status, uint32_t hBytesWritten, hidl_string hDetailedError) {
- if (status == Status::OK) {
- bytesWritten = hBytesWritten;
- *errorDetailMsg = toString8(hDetailedError);
- }
- err = toStatusT(status);
- }
- );
+ Return<void> hResult;
- if (!hResult.isOk()) {
- err = DEAD_OBJECT;
+ if (mPluginV1_2 != NULL) {
+ hResult = mPluginV1_2->decrypt_1_2(secure, toHidlArray16(keyId), toHidlArray16(iv),
+ hMode, hPattern, hSubSamples, hSource, offset, hDestination,
+ [&](Status_V1_2 status, uint32_t hBytesWritten, hidl_string hDetailedError) {
+ if (status == Status_V1_2::OK) {
+ bytesWritten = hBytesWritten;
+ *errorDetailMsg = toString8(hDetailedError);
+ }
+ err = toStatusT_1_2(status);
+ }
+ );
+ } else {
+ hResult = mPlugin->decrypt(secure, toHidlArray16(keyId), toHidlArray16(iv),
+ hMode, hPattern, hSubSamples, hSource, offset, hDestination,
+ [&](Status status, uint32_t hBytesWritten, hidl_string hDetailedError) {
+ if (status == Status::OK) {
+ bytesWritten = hBytesWritten;
+ *errorDetailMsg = toString8(hDetailedError);
+ }
+ err = toStatusT(status);
+ }
+ );
}
+ err = hResult.isOk() ? err : DEAD_OBJECT;
if (err == OK) {
return bytesWritten;
}
diff --git a/drm/libmediadrm/DrmHal.cpp b/drm/libmediadrm/DrmHal.cpp
index 66c509f..fc847ff 100644
--- a/drm/libmediadrm/DrmHal.cpp
+++ b/drm/libmediadrm/DrmHal.cpp
@@ -41,6 +41,7 @@
using drm::V1_0::KeyedVector;
using drm::V1_0::KeyStatusType;
+using drm::V1_0::KeyRequestType;
using drm::V1_0::KeyType;
using drm::V1_0::KeyValue;
using drm::V1_0::SecureStop;
@@ -60,6 +61,9 @@
using ::android::os::PersistableBundle;
using ::android::sp;
+typedef drm::V1_1::KeyRequestType KeyRequestType_V1_1;
+typedef drm::V1_2::Status Status_V1_2;
+
namespace {
// This constant corresponds to the PROPERTY_DEVICE_UNIQUE_ID constant
@@ -239,7 +243,7 @@
return ERROR_DRM_CANNOT_HANDLE;
break;
case Status::ERROR_DRM_INVALID_STATE:
- return ERROR_DRM_TAMPER_DETECTED;
+ return ERROR_DRM_INVALID_STATE;
break;
case Status::BAD_VALUE:
return BAD_VALUE;
@@ -260,6 +264,19 @@
}
}
+static status_t toStatusT_1_2(Status_V1_2 status) {
+ switch (status) {
+ case Status_V1_2::ERROR_DRM_RESOURCE_CONTENTION:
+ return ERROR_DRM_RESOURCE_CONTENTION;
+ case Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE:
+ return ERROR_DRM_FRAME_TOO_LARGE;
+ case Status_V1_2::ERROR_DRM_INSUFFICIENT_SECURITY:
+ return ERROR_DRM_INSUFFICIENT_SECURITY;
+ default:
+ return toStatusT(static_cast<Status>(status));
+ }
+}
+
Mutex DrmHal::mLock;
@@ -319,8 +336,11 @@
setListener(NULL);
mInitCheck = NO_INIT;
-
- if (mPlugin != NULL) {
+ if (mPluginV1_2 != NULL) {
+ if (!mPluginV1_2->setListener(NULL).isOk()) {
+ mInitCheck = DEAD_OBJECT;
+ }
+ } else if (mPlugin != NULL) {
if (!mPlugin->setListener(NULL).isOk()) {
mInitCheck = DEAD_OBJECT;
}
@@ -532,6 +552,22 @@
return Void();
}
+Return<void> DrmHal::sendSessionLostState(
+ const hidl_vec<uint8_t>& sessionId) {
+
+ mEventLock.lock();
+ sp<IDrmClient> listener = mListener;
+ mEventLock.unlock();
+
+ if (listener != NULL) {
+ Parcel obj;
+ writeByteArray(obj, sessionId);
+ Mutex::Autolock lock(mNotifyLock);
+ listener->notify(DrmPlugin::kDrmPluginEventSessionLostState, 0, &obj);
+ }
+ return Void();
+}
+
bool DrmHal::isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
Mutex::Autolock autoLock(mLock);
@@ -568,16 +604,22 @@
if (mPlugin == NULL) {
mInitCheck = ERROR_UNSUPPORTED;
} else {
- if (!mPlugin->setListener(this).isOk()) {
- mPlugin = NULL;
- mPluginV1_1 = NULL;
- mPluginV1_2 = NULL;
+ mInitCheck = OK;
+ if (mPluginV1_2 != NULL) {
+ if (!mPluginV1_2->setListener(this).isOk()) {
+ mInitCheck = DEAD_OBJECT;
+ }
+ } else if (!mPlugin->setListener(this).isOk()) {
mInitCheck = DEAD_OBJECT;
- } else {
- mInitCheck = OK;
+ }
+ if (mInitCheck != OK) {
+ mPlugin.clear();
+ mPluginV1_1.clear();
+ mPluginV1_2.clear();
}
}
+
return mInitCheck;
}
@@ -694,6 +736,39 @@
return DEAD_OBJECT;
}
+static DrmPlugin::KeyRequestType toKeyRequestType(
+ KeyRequestType keyRequestType) {
+ switch (keyRequestType) {
+ case KeyRequestType::INITIAL:
+ return DrmPlugin::kKeyRequestType_Initial;
+ break;
+ case KeyRequestType::RENEWAL:
+ return DrmPlugin::kKeyRequestType_Renewal;
+ break;
+ case KeyRequestType::RELEASE:
+ return DrmPlugin::kKeyRequestType_Release;
+ break;
+ default:
+ return DrmPlugin::kKeyRequestType_Unknown;
+ break;
+ }
+}
+
+static DrmPlugin::KeyRequestType toKeyRequestType_1_1(
+ KeyRequestType_V1_1 keyRequestType) {
+ switch (keyRequestType) {
+ case KeyRequestType_V1_1::NONE:
+ return DrmPlugin::kKeyRequestType_None;
+ break;
+ case KeyRequestType_V1_1::UPDATE:
+ return DrmPlugin::kKeyRequestType_Update;
+ break;
+ default:
+ return toKeyRequestType(static_cast<KeyRequestType>(keyRequestType));
+ break;
+ }
+}
+
status_t DrmHal::getKeyRequest(Vector<uint8_t> const &sessionId,
Vector<uint8_t> const &initData, String8 const &mimeType,
DrmPlugin::KeyType keyType, KeyedVector<String8,
@@ -720,73 +795,51 @@
::KeyedVector hOptionalParameters = toHidlKeyedVector(optionalParameters);
status_t err = UNKNOWN_ERROR;
+ Return<void> hResult;
- if (mPluginV1_1 != NULL) {
- Return<void> hResult =
- mPluginV1_1->getKeyRequest_1_1(
+ if (mPluginV1_2 != NULL) {
+ hResult = mPluginV1_2->getKeyRequest_1_2(
+ toHidlVec(sessionId), toHidlVec(initData),
+ toHidlString(mimeType), hKeyType, hOptionalParameters,
+ [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
+ KeyRequestType_V1_1 hKeyRequestType,
+ const hidl_string& hDefaultUrl) {
+ if (status == Status_V1_2::OK) {
+ request = toVector(hRequest);
+ defaultUrl = toString8(hDefaultUrl);
+ *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
+ }
+ err = toStatusT_1_2(status);
+ });
+ } else if (mPluginV1_1 != NULL) {
+ hResult = mPluginV1_1->getKeyRequest_1_1(
toHidlVec(sessionId), toHidlVec(initData),
toHidlString(mimeType), hKeyType, hOptionalParameters,
[&](Status status, const hidl_vec<uint8_t>& hRequest,
- drm::V1_1::KeyRequestType hKeyRequestType,
- const hidl_string& hDefaultUrl) {
-
- if (status == Status::OK) {
- request = toVector(hRequest);
- defaultUrl = toString8(hDefaultUrl);
-
- switch (hKeyRequestType) {
- case drm::V1_1::KeyRequestType::INITIAL:
- *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
- break;
- case drm::V1_1::KeyRequestType::RENEWAL:
- *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
- break;
- case drm::V1_1::KeyRequestType::RELEASE:
- *keyRequestType = DrmPlugin::kKeyRequestType_Release;
- break;
- case drm::V1_1::KeyRequestType::NONE:
- *keyRequestType = DrmPlugin::kKeyRequestType_None;
- break;
- case drm::V1_1::KeyRequestType::UPDATE:
- *keyRequestType = DrmPlugin::kKeyRequestType_Update;
- break;
- default:
- *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
- break;
- }
- err = toStatusT(status);
- }
- });
- return hResult.isOk() ? err : DEAD_OBJECT;
- }
-
- Return<void> hResult = mPlugin->getKeyRequest(toHidlVec(sessionId),
- toHidlVec(initData), toHidlString(mimeType), hKeyType, hOptionalParameters,
- [&](Status status, const hidl_vec<uint8_t>& hRequest,
- drm::V1_0::KeyRequestType hKeyRequestType,
- const hidl_string& hDefaultUrl) {
-
- if (status == Status::OK) {
- request = toVector(hRequest);
- defaultUrl = toString8(hDefaultUrl);
-
- switch (hKeyRequestType) {
- case drm::V1_0::KeyRequestType::INITIAL:
- *keyRequestType = DrmPlugin::kKeyRequestType_Initial;
- break;
- case drm::V1_0::KeyRequestType::RENEWAL:
- *keyRequestType = DrmPlugin::kKeyRequestType_Renewal;
- break;
- case drm::V1_0::KeyRequestType::RELEASE:
- *keyRequestType = DrmPlugin::kKeyRequestType_Release;
- break;
- default:
- *keyRequestType = DrmPlugin::kKeyRequestType_Unknown;
- break;
+ KeyRequestType_V1_1 hKeyRequestType,
+ const hidl_string& hDefaultUrl) {
+ if (status == Status::OK) {
+ request = toVector(hRequest);
+ defaultUrl = toString8(hDefaultUrl);
+ *keyRequestType = toKeyRequestType_1_1(hKeyRequestType);
}
err = toStatusT(status);
- }
- });
+ });
+ } else {
+ hResult = mPlugin->getKeyRequest(
+ toHidlVec(sessionId), toHidlVec(initData),
+ toHidlString(mimeType), hKeyType, hOptionalParameters,
+ [&](Status status, const hidl_vec<uint8_t>& hRequest,
+ KeyRequestType hKeyRequestType,
+ const hidl_string& hDefaultUrl) {
+ if (status == Status::OK) {
+ request = toVector(hRequest);
+ defaultUrl = toString8(hDefaultUrl);
+ *keyRequestType = toKeyRequestType(hKeyRequestType);
+ }
+ err = toStatusT(status);
+ });
+ }
err = hResult.isOk() ? err : DEAD_OBJECT;
keyRequestTimer.SetAttribute(err);
@@ -868,18 +921,33 @@
INIT_CHECK();
status_t err = UNKNOWN_ERROR;
+ Return<void> hResult;
- Return<void> hResult = mPlugin->getProvisionRequest(
- toHidlString(certType), toHidlString(certAuthority),
- [&](Status status, const hidl_vec<uint8_t>& hRequest,
- const hidl_string& hDefaultUrl) {
- if (status == Status::OK) {
- request = toVector(hRequest);
- defaultUrl = toString8(hDefaultUrl);
+ if (mPluginV1_2 != NULL) {
+ Return<void> hResult = mPluginV1_2->getProvisionRequest_1_2(
+ toHidlString(certType), toHidlString(certAuthority),
+ [&](Status_V1_2 status, const hidl_vec<uint8_t>& hRequest,
+ const hidl_string& hDefaultUrl) {
+ if (status == Status_V1_2::OK) {
+ request = toVector(hRequest);
+ defaultUrl = toString8(hDefaultUrl);
+ }
+ err = toStatusT_1_2(status);
}
- err = toStatusT(status);
- }
- );
+ );
+ } else {
+ Return<void> hResult = mPlugin->getProvisionRequest(
+ toHidlString(certType), toHidlString(certAuthority),
+ [&](Status status, const hidl_vec<uint8_t>& hRequest,
+ const hidl_string& hDefaultUrl) {
+ if (status == Status::OK) {
+ request = toVector(hRequest);
+ defaultUrl = toString8(hDefaultUrl);
+ }
+ err = toStatusT(status);
+ }
+ );
+ }
err = hResult.isOk() ? err : DEAD_OBJECT;
mMetrics.mGetProvisionRequestCounter.Increment(err);
diff --git a/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp b/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp
index a488f86..fc0cceb 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp
@@ -42,10 +42,42 @@
return Void();
}
+Return<void> CryptoPlugin::decrypt(
+ bool secure,
+ const hidl_array<uint8_t, 16>& keyId,
+ const hidl_array<uint8_t, 16>& iv,
+ Mode mode,
+ const Pattern& pattern,
+ const hidl_vec<SubSample>& subSamples,
+ const SharedBuffer& source,
+ uint64_t offset,
+ const DestinationBuffer& destination,
+ decrypt_cb _hidl_cb) {
+
+ Status status = Status::ERROR_DRM_UNKNOWN;
+ hidl_string detailedError;
+ uint32_t bytesWritten = 0;
+
+ Return<void> hResult = decrypt_1_2(
+ secure, keyId, iv, mode, pattern, subSamples, source, offset, destination,
+ [&](Status_V1_2 hStatus, uint32_t hBytesWritten, hidl_string hDetailedError) {
+ status = toStatus_1_0(hStatus);
+ if (status == Status::OK) {
+ bytesWritten = hBytesWritten;
+ detailedError = hDetailedError;
+ }
+ }
+ );
+
+ status = hResult.isOk() ? status : Status::ERROR_DRM_CANNOT_HANDLE;
+ _hidl_cb(status, bytesWritten, detailedError);
+ return Void();
+}
+
// Returns negative values for error code and positive values for the size of
// decrypted data. In theory, the output size can be larger than the input
// size, but in practice this will never happen for AES-CTR.
-Return<void> CryptoPlugin::decrypt(
+Return<void> CryptoPlugin::decrypt_1_2(
bool secure,
const hidl_array<uint8_t, KEY_ID_SIZE>& keyId,
const hidl_array<uint8_t, KEY_IV_SIZE>& iv,
@@ -55,17 +87,17 @@
const SharedBuffer& source,
uint64_t offset,
const DestinationBuffer& destination,
- decrypt_cb _hidl_cb) {
+ decrypt_1_2_cb _hidl_cb) {
UNUSED(pattern);
if (secure) {
- _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0,
+ _hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, 0,
"Secure decryption is not supported with ClearKey.");
return Void();
}
if (mSharedBufferMap.find(source.bufferId) == mSharedBufferMap.end()) {
- _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0,
+ _hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, 0,
"source decrypt buffer base not set");
return Void();
}
@@ -73,7 +105,7 @@
if (destination.type == BufferType::SHARED_MEMORY) {
const SharedBuffer& dest = destination.nonsecureMemory;
if (mSharedBufferMap.find(dest.bufferId) == mSharedBufferMap.end()) {
- _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0,
+ _hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, 0,
"destination decrypt buffer base not set");
return Void();
}
@@ -81,12 +113,12 @@
sp<IMemory> sourceBase = mSharedBufferMap[source.bufferId];
if (sourceBase == nullptr) {
- _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "source is a nullptr");
+ _hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, 0, "source is a nullptr");
return Void();
}
if (source.offset + offset + source.size > sourceBase->getSize()) {
- _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size");
+ _hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size");
return Void();
}
@@ -98,12 +130,12 @@
const SharedBuffer& destBuffer = destination.nonsecureMemory;
sp<IMemory> destBase = mSharedBufferMap[destBuffer.bufferId];
if (destBase == nullptr) {
- _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "destination is a nullptr");
+ _hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, 0, "destination is a nullptr");
return Void();
}
if (destBuffer.offset + destBuffer.size > destBase->getSize()) {
- _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size");
+ _hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size");
return Void();
}
destPtr = static_cast<void *>(base + destination.nonsecureMemory.offset);
@@ -128,7 +160,7 @@
if (mode == Mode::UNENCRYPTED) {
if (haveEncryptedSubsamples) {
- _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0,
+ _hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, 0,
"Encrypted subsamples found in allegedly unencrypted data.");
return Void();
}
@@ -144,22 +176,21 @@
}
}
- _hidl_cb(Status::OK, static_cast<ssize_t>(offset), "");
+ _hidl_cb(Status_V1_2::OK, static_cast<ssize_t>(offset), "");
return Void();
} else if (mode == Mode::AES_CTR) {
size_t bytesDecrypted;
- Status res = mSession->decrypt(keyId.data(), iv.data(), srcPtr,
+ Status_V1_2 res = mSession->decrypt(keyId.data(), iv.data(), srcPtr,
static_cast<uint8_t*>(destPtr), toVector(subSamples), &bytesDecrypted);
- if (res == Status::OK) {
- _hidl_cb(Status::OK, static_cast<ssize_t>(bytesDecrypted), "");
+ if (res == Status_V1_2::OK) {
+ _hidl_cb(Status_V1_2::OK, static_cast<ssize_t>(bytesDecrypted), "");
return Void();
} else {
- _hidl_cb(Status::ERROR_DRM_DECRYPT, static_cast<ssize_t>(res),
- "Decryption Error");
+ _hidl_cb(res, 0, "Decryption Error");
return Void();
}
} else {
- _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0,
+ _hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, 0,
"Selected encryption mode is not supported by the ClearKey DRM Plugin.");
return Void();
}
diff --git a/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp b/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp
index 7184b53..badb99e 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp
@@ -61,15 +61,23 @@
namespace V1_2 {
namespace clearkey {
-using ::android::hardware::drm::V1_2::KeySetId;
-using ::android::hardware::drm::V1_2::OfflineLicenseState;
+KeyRequestType toKeyRequestType_V1_0(KeyRequestType_V1_1 keyRequestType) {
+ switch (keyRequestType) {
+ case KeyRequestType_V1_1::NONE:
+ case KeyRequestType_V1_1::UPDATE:
+ return KeyRequestType::UNKNOWN;
+ default:
+ return static_cast<KeyRequestType>(keyRequestType);
+ }
+}
DrmPlugin::DrmPlugin(SessionLibrary* sessionLibrary)
: mSessionLibrary(sessionLibrary),
mOpenSessionOkCount(0),
mCloseSessionOkCount(0),
mCloseSessionNotOpenedCount(0),
- mNextSecureStopId(kSecureStopIdStart) {
+ mNextSecureStopId(kSecureStopIdStart),
+ mMockError(Status_V1_2::OK) {
mPlayPolicy.clear();
initProperties();
mSecureStops.clear();
@@ -84,6 +92,7 @@
mStringProperties[kPluginDescriptionKey] = kPluginDescriptionValue;
mStringProperties[kAlgorithmsKey] = kAlgorithmsValue;
mStringProperties[kListenerTestSupportKey] = kListenerTestSupportValue;
+ mStringProperties[kDrmErrorTestKey] = kDrmErrorTestValue;
std::vector<uint8_t> valueVector;
valueVector.clear();
@@ -112,6 +121,7 @@
Return<void> DrmPlugin::openSession(openSession_cb _hidl_cb) {
sp<Session> session = mSessionLibrary->createSession();
+ processMockError(session);
std::vector<uint8_t> sessionId = session->sessionId();
Status status = setSecurityLevel(sessionId, SecurityLevel::SW_SECURE_CRYPTO);
@@ -123,6 +133,7 @@
Return<void> DrmPlugin::openSession_1_1(SecurityLevel securityLevel,
openSession_1_1_cb _hidl_cb) {
sp<Session> session = mSessionLibrary->createSession();
+ processMockError(session);
std::vector<uint8_t> sessionId = session->sessionId();
Status status = setSecurityLevel(sessionId, securityLevel);
@@ -138,6 +149,10 @@
sp<Session> session = mSessionLibrary->findSession(toVector(sessionId));
if (session.get()) {
+ if (session->getMockError() != Status_V1_2::OK) {
+ sendSessionLostState(sessionId);
+ return Status::ERROR_DRM_INVALID_STATE;
+ }
mCloseSessionOkCount++;
mSessionLibrary->destroySession(session);
return Status::OK;
@@ -146,13 +161,13 @@
return Status::ERROR_DRM_SESSION_NOT_OPENED;
}
-Status DrmPlugin::getKeyRequestCommon(const hidl_vec<uint8_t>& scope,
+Status_V1_2 DrmPlugin::getKeyRequestCommon(const hidl_vec<uint8_t>& scope,
const hidl_vec<uint8_t>& initData,
const hidl_string& mimeType,
KeyType keyType,
const hidl_vec<KeyValue>& optionalParameters,
std::vector<uint8_t> *request,
- KeyRequestType *keyRequestType,
+ KeyRequestType_V1_1 *keyRequestType,
std::string *defaultUrl) {
UNUSED(optionalParameters);
@@ -161,18 +176,18 @@
// Those tests pass in an empty initData, we use the empty initData to
// signal such specific use case.
if (keyType == KeyType::OFFLINE && 0 == initData.size()) {
- return Status::ERROR_DRM_CANNOT_HANDLE;
+ return Status_V1_2::ERROR_DRM_CANNOT_HANDLE;
}
*defaultUrl = "";
- *keyRequestType = KeyRequestType::UNKNOWN;
+ *keyRequestType = KeyRequestType_V1_1::UNKNOWN;
*request = std::vector<uint8_t>();
if (scope.size() == 0 ||
(keyType != KeyType::STREAMING &&
keyType != KeyType::OFFLINE &&
keyType != KeyType::RELEASE)) {
- return Status::BAD_VALUE;
+ return Status_V1_2::BAD_VALUE;
}
const std::vector<uint8_t> scopeId = toVector(scope);
@@ -181,12 +196,16 @@
std::vector<uint8_t> sessionId(scopeId.begin(), scopeId.end());
session = mSessionLibrary->findSession(sessionId);
if (!session.get()) {
- return Status::ERROR_DRM_SESSION_NOT_OPENED;
+ return Status_V1_2::ERROR_DRM_SESSION_NOT_OPENED;
+ } else if (session->getMockError() != Status_V1_2::OK) {
+ return session->getMockError();
}
- *keyRequestType = KeyRequestType::INITIAL;
+
+ *keyRequestType = KeyRequestType_V1_1::INITIAL;
}
- Status status = session->getKeyRequest(initData, mimeType, keyType, request);
+ Status_V1_2 status = static_cast<Status_V1_2>(
+ session->getKeyRequest(initData, mimeType, keyType, request));
if (keyType == KeyType::RELEASE) {
std::vector<uint8_t> keySetId(scopeId.begin(), scopeId.end());
@@ -198,7 +217,7 @@
DeviceFiles::kLicenseStateReleasing,
emptyResponse)) {
ALOGE("Problem releasing offline license");
- return Status::ERROR_DRM_UNKNOWN;
+ return Status_V1_2::ERROR_DRM_UNKNOWN;
}
if (mReleaseKeysMap.find(keySetIdString) == mReleaseKeysMap.end()) {
sp<Session> session = mSessionLibrary->createSession();
@@ -209,7 +228,7 @@
} else {
ALOGE("Offline license not found, nothing to release");
}
- *keyRequestType = KeyRequestType::RELEASE;
+ *keyRequestType = KeyRequestType_V1_1::RELEASE;
}
return status;
}
@@ -223,15 +242,15 @@
getKeyRequest_cb _hidl_cb) {
UNUSED(optionalParameters);
- KeyRequestType keyRequestType = KeyRequestType::UNKNOWN;
+ KeyRequestType_V1_1 keyRequestType = KeyRequestType_V1_1::UNKNOWN;
std::string defaultUrl("");
std::vector<uint8_t> request;
- Status status = getKeyRequestCommon(
+ Status_V1_2 status = getKeyRequestCommon(
scope, initData, mimeType, keyType, optionalParameters,
&request, &keyRequestType, &defaultUrl);
- _hidl_cb(status, toHidlVec(request),
- static_cast<drm::V1_0::KeyRequestType>(keyRequestType),
+ _hidl_cb(toStatus_1_0(status), toHidlVec(request),
+ toKeyRequestType_V1_0(keyRequestType),
hidl_string(defaultUrl));
return Void();
}
@@ -245,10 +264,31 @@
getKeyRequest_1_1_cb _hidl_cb) {
UNUSED(optionalParameters);
- KeyRequestType keyRequestType = KeyRequestType::UNKNOWN;
+ KeyRequestType_V1_1 keyRequestType = KeyRequestType_V1_1::UNKNOWN;
std::string defaultUrl("");
std::vector<uint8_t> request;
- Status status = getKeyRequestCommon(
+ Status_V1_2 status = getKeyRequestCommon(
+ scope, initData, mimeType, keyType, optionalParameters,
+ &request, &keyRequestType, &defaultUrl);
+
+ _hidl_cb(toStatus_1_0(status), toHidlVec(request),
+ keyRequestType, hidl_string(defaultUrl));
+ return Void();
+}
+
+Return<void> DrmPlugin::getKeyRequest_1_2(
+ const hidl_vec<uint8_t>& scope,
+ const hidl_vec<uint8_t>& initData,
+ const hidl_string& mimeType,
+ KeyType keyType,
+ const hidl_vec<KeyValue>& optionalParameters,
+ getKeyRequest_1_2_cb _hidl_cb) {
+ UNUSED(optionalParameters);
+
+ KeyRequestType_V1_1 keyRequestType = KeyRequestType_V1_1::UNKNOWN;
+ std::string defaultUrl("");
+ std::vector<uint8_t> request;
+ Status_V1_2 status = getKeyRequestCommon(
scope, initData, mimeType, keyType, optionalParameters,
&request, &keyRequestType, &defaultUrl);
@@ -434,6 +474,8 @@
value = mStringProperties[kAlgorithmsKey];
} else if (name == kListenerTestSupportKey) {
value = mStringProperties[kListenerTestSupportKey];
+ } else if (name == kDrmErrorTestKey) {
+ value = mStringProperties[kDrmErrorTestKey];
} else {
ALOGE("App requested unknown string property %s", name.c_str());
_hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, "");
@@ -478,6 +520,16 @@
return Status::BAD_VALUE;
}
+ if (name == kDrmErrorTestKey) {
+ if (value == kResourceContentionValue) {
+ mMockError = Status_V1_2::ERROR_DRM_RESOURCE_CONTENTION;
+ } else if (value == kLostStateValue) {
+ mMockError = Status_V1_2::ERROR_DRM_SESSION_LOST_STATE;
+ } else if (value == kFrameTooLargeValue) {
+ mMockError = Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE;
+ }
+ }
+
mStringProperties[key] = std::string(value.c_str());
return Status::OK;
}
diff --git a/drm/mediadrm/plugins/clearkey/hidl/Session.cpp b/drm/mediadrm/plugins/clearkey/hidl/Session.cpp
index f4c49b9..a9d7016 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/Session.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/Session.cpp
@@ -68,25 +68,30 @@
}
}
-Status Session::decrypt(
+Status_V1_2 Session::decrypt(
const KeyId keyId, const Iv iv, const uint8_t* srcPtr,
uint8_t* destPtr, const std::vector<SubSample> subSamples,
size_t* bytesDecryptedOut) {
Mutex::Autolock lock(mMapLock);
+ if (getMockError() != Status_V1_2::OK) {
+ return getMockError();
+ }
+
std::vector<uint8_t> keyIdVector;
keyIdVector.clear();
keyIdVector.insert(keyIdVector.end(), keyId, keyId + kBlockSize);
std::map<std::vector<uint8_t>, std::vector<uint8_t> >::iterator itr;
itr = mKeyMap.find(keyIdVector);
if (itr == mKeyMap.end()) {
- return Status::ERROR_DRM_NO_LICENSE;
+ return Status_V1_2::ERROR_DRM_NO_LICENSE;
}
AesCtrDecryptor decryptor;
- return decryptor.decrypt(
+ Status status = decryptor.decrypt(
itr->second /*key*/, iv, srcPtr, destPtr, subSamples,
subSamples.size(), bytesDecryptedOut);
+ return static_cast<Status_V1_2>(status);
}
} // namespace clearkey
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/ClearKeyDrmProperties.h b/drm/mediadrm/plugins/clearkey/hidl/include/ClearKeyDrmProperties.h
index f83903c..1bbc822 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/ClearKeyDrmProperties.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/ClearKeyDrmProperties.h
@@ -35,6 +35,11 @@
static const std::string kAlgorithmsValue("");
static const std::string kListenerTestSupportKey("listenerTestSupport");
static const std::string kListenerTestSupportValue("true");
+static const std::string kDrmErrorTestKey("drmErrorTest");
+static const std::string kDrmErrorTestValue("");
+static const std::string kResourceContentionValue("resourceContention");
+static const std::string kLostStateValue("lostState");
+static const std::string kFrameTooLargeValue("frameTooLarge");
static const std::string kDeviceIdKey("deviceId");
static const uint8_t kTestDeviceIdData[] =
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/ClearKeyTypes.h b/drm/mediadrm/plugins/clearkey/hidl/include/ClearKeyTypes.h
index 7e9b6bd..2dafa36 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/ClearKeyTypes.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/ClearKeyTypes.h
@@ -17,7 +17,7 @@
#ifndef CLEARKEY_MACROS_H_
#define CLEARKEY_MACROS_H_
-#include <android/hardware/drm/1.0/types.h>
+#include <android/hardware/drm/1.2/types.h>
#include <map>
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/CryptoPlugin.h b/drm/mediadrm/plugins/clearkey/hidl/include/CryptoPlugin.h
index 480dc7e..8680f0c 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/CryptoPlugin.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/CryptoPlugin.h
@@ -17,7 +17,7 @@
#ifndef CLEARKEY_CRYPTO_PLUGIN_H_
#define CLEARKEY_CRYPTO_PLUGIN_H_
-#include <android/hardware/drm/1.0/ICryptoPlugin.h>
+#include <android/hardware/drm/1.2/ICryptoPlugin.h>
#include <android/hidl/memory/1.0/IMemory.h>
#include "ClearKeyTypes.h"
@@ -35,13 +35,14 @@
namespace V1_2 {
namespace clearkey {
-using ::android::hardware::drm::V1_0::DestinationBuffer;
-using ::android::hardware::drm::V1_0::ICryptoPlugin;
-using ::android::hardware::drm::V1_0::Mode;
-using ::android::hardware::drm::V1_0::Pattern;
-using ::android::hardware::drm::V1_0::SharedBuffer;
-using ::android::hardware::drm::V1_0::Status;
-using ::android::hardware::drm::V1_0::SubSample;
+namespace drm = ::android::hardware::drm;
+using drm::V1_0::DestinationBuffer;
+using drm::V1_0::Mode;
+using drm::V1_0::Pattern;
+using drm::V1_0::SharedBuffer;
+using drm::V1_0::Status;
+using drm::V1_0::SubSample;
+
using ::android::hardware::hidl_array;
using ::android::hardware::hidl_memory;
using ::android::hardware::hidl_string;
@@ -51,7 +52,9 @@
using ::android::hidl::memory::V1_0::IMemory;
using ::android::sp;
-struct CryptoPlugin : public ICryptoPlugin {
+typedef drm::V1_2::Status Status_V1_2;
+
+struct CryptoPlugin : public drm::V1_2::ICryptoPlugin {
explicit CryptoPlugin(const hidl_vec<uint8_t>& sessionId) {
mInitStatus = setMediaDrmSession(sessionId);
}
@@ -80,6 +83,18 @@
const DestinationBuffer& destination,
decrypt_cb _hidl_cb);
+ Return<void> decrypt_1_2(
+ bool secure,
+ const hidl_array<uint8_t, KEY_ID_SIZE>& keyId,
+ const hidl_array<uint8_t, KEY_IV_SIZE>& iv,
+ Mode mode,
+ const Pattern& pattern,
+ const hidl_vec<SubSample>& subSamples,
+ const SharedBuffer& source,
+ uint64_t offset,
+ const DestinationBuffer& destination,
+ decrypt_1_2_cb _hidl_cb);
+
Return<void> setSharedBufferBase(const hidl_memory& base,
uint32_t bufferId);
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h b/drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h
index 256c5d6..a9b897b 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h
@@ -18,6 +18,7 @@
#define CLEARKEY_DRM_PLUGIN_H_
#include <android/hardware/drm/1.2/IDrmPlugin.h>
+#include <android/hardware/drm/1.2/IDrmPluginListener.h>
#include <map>
#include <stdio.h>
@@ -34,22 +35,24 @@
namespace V1_2 {
namespace clearkey {
-using ::android::hardware::drm::V1_0::EventType;
-using ::android::hardware::drm::V1_0::IDrmPluginListener;
-using ::android::hardware::drm::V1_0::KeyStatus;
-using ::android::hardware::drm::V1_0::KeyType;
-using ::android::hardware::drm::V1_0::KeyValue;
-using ::android::hardware::drm::V1_0::SecureStop;
-using ::android::hardware::drm::V1_0::SecureStopId;
-using ::android::hardware::drm::V1_0::SessionId;
-using ::android::hardware::drm::V1_0::Status;
-using ::android::hardware::drm::V1_1::DrmMetricGroup;
-using ::android::hardware::drm::V1_1::HdcpLevel;
-using ::android::hardware::drm::V1_1::KeyRequestType;
-using ::android::hardware::drm::V1_1::SecureStopRelease;
-using ::android::hardware::drm::V1_1::SecurityLevel;
-using ::android::hardware::drm::V1_2::IDrmPlugin;
-using ::android::hardware::drm::V1_2::OfflineLicenseState;
+namespace drm = ::android::hardware::drm;
+using drm::V1_0::EventType;
+using drm::V1_0::IDrmPluginListener;
+using drm::V1_0::KeyRequestType;
+using drm::V1_0::KeyStatus;
+using drm::V1_0::KeyType;
+using drm::V1_0::KeyValue;
+using drm::V1_0::SecureStop;
+using drm::V1_0::SecureStopId;
+using drm::V1_0::SessionId;
+using drm::V1_0::Status;
+using drm::V1_1::DrmMetricGroup;
+using drm::V1_1::HdcpLevel;
+using drm::V1_1::SecureStopRelease;
+using drm::V1_1::SecurityLevel;
+using drm::V1_2::IDrmPlugin;
+using drm::V1_2::KeySetId;
+using drm::V1_2::OfflineLicenseState;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
@@ -57,6 +60,10 @@
using ::android::hardware::Void;
using ::android::sp;
+typedef drm::V1_1::KeyRequestType KeyRequestType_V1_1;
+typedef drm::V1_2::IDrmPluginListener IDrmPluginListener_V1_2;
+typedef drm::V1_2::Status Status_V1_2;
+
struct DrmPlugin : public IDrmPlugin {
explicit DrmPlugin(SessionLibrary* sessionLibrary);
@@ -84,6 +91,14 @@
const hidl_vec<KeyValue>& optionalParameters,
getKeyRequest_1_1_cb _hidl_cb) override;
+ Return<void> getKeyRequest_1_2(
+ const hidl_vec<uint8_t>& scope,
+ const hidl_vec<uint8_t>& initData,
+ const hidl_string& mimeType,
+ KeyType keyType,
+ const hidl_vec<KeyValue>& optionalParameters,
+ getKeyRequest_1_2_cb _hidl_cb) override;
+
Return<void> provideKeyResponse(
const hidl_vec<uint8_t>& scope,
const hidl_vec<uint8_t>& response,
@@ -116,6 +131,18 @@
return Void();
}
+ Return<void> getProvisionRequest_1_2(
+ const hidl_string& certificateType,
+ const hidl_string& certificateAuthority,
+ getProvisionRequest_1_2_cb _hidl_cb) {
+ UNUSED(certificateType);
+ UNUSED(certificateAuthority);
+
+ hidl_string defaultUrl;
+ _hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, hidl_vec<uint8_t>(), defaultUrl);
+ return Void();
+ }
+
Return<void> provideProvisionResponse(
const hidl_vec<uint8_t>& response,
provideProvisionResponse_cb _hidl_cb) {
@@ -256,12 +283,17 @@
Return<void> setListener(const sp<IDrmPluginListener>& listener) {
mListener = listener;
+ mListenerV1_2 = IDrmPluginListener_V1_2::castFrom(listener);
return Void();
};
- Return<void> sendEvent(EventType eventType, const hidl_vec<uint8_t>& sessionId,
+ Return<void> sendEvent(
+ EventType eventType,
+ const hidl_vec<uint8_t>& sessionId,
const hidl_vec<uint8_t>& data) {
- if (mListener != NULL) {
+ if (mListenerV1_2 != NULL) {
+ mListenerV1_2->sendEvent(eventType, sessionId, data);
+ } else if (mListener != NULL) {
mListener->sendEvent(eventType, sessionId, data);
} else {
ALOGE("Null event listener, event not sent");
@@ -269,8 +301,12 @@
return Void();
}
- Return<void> sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId, int64_t expiryTimeInMS) {
- if (mListener != NULL) {
+ Return<void> sendExpirationUpdate(
+ const hidl_vec<uint8_t>& sessionId,
+ int64_t expiryTimeInMS) {
+ if (mListenerV1_2 != NULL) {
+ mListenerV1_2->sendExpirationUpdate(sessionId, expiryTimeInMS);
+ } else if (mListener != NULL) {
mListener->sendExpirationUpdate(sessionId, expiryTimeInMS);
} else {
ALOGE("Null event listener, event not sent");
@@ -278,9 +314,12 @@
return Void();
}
- Return<void> sendKeysChange(const hidl_vec<uint8_t>& sessionId,
+ Return<void> sendKeysChange(
+ const hidl_vec<uint8_t>& sessionId,
const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
- if (mListener != NULL) {
+ if (mListenerV1_2 != NULL) {
+ mListenerV1_2->sendKeysChange(sessionId, keyStatusList, hasNewUsableKey);
+ } else if (mListener != NULL) {
mListener->sendKeysChange(sessionId, keyStatusList, hasNewUsableKey);
} else {
ALOGE("Null event listener, event not sent");
@@ -288,6 +327,14 @@
return Void();
}
+ Return<void> sendSessionLostState(
+ const hidl_vec<uint8_t>& sessionId) {
+ if (mListenerV1_2 != NULL) {
+ mListenerV1_2->sendSessionLostState(sessionId);
+ }
+ return Void();
+ }
+
Return<void> getSecureStops(getSecureStops_cb _hidl_cb);
Return<void> getSecureStop(const hidl_vec<uint8_t>& secureStopId,
@@ -314,13 +361,13 @@
Return<Status> setSecurityLevel(const hidl_vec<uint8_t>& sessionId,
SecurityLevel level);
- Status getKeyRequestCommon(const hidl_vec<uint8_t>& scope,
+ Status_V1_2 getKeyRequestCommon(const hidl_vec<uint8_t>& scope,
const hidl_vec<uint8_t>& initData,
const hidl_string& mimeType,
KeyType keyType,
const hidl_vec<KeyValue>& optionalParameters,
std::vector<uint8_t> *request,
- KeyRequestType *getKeyRequestType,
+ KeyRequestType_V1_1 *getKeyRequestType,
std::string *defaultUrl);
struct ClearkeySecureStop {
@@ -335,12 +382,21 @@
std::map<std::string, std::vector<uint8_t> > mReleaseKeysMap;
std::map<std::vector<uint8_t>, SecurityLevel> mSecurityLevel;
sp<IDrmPluginListener> mListener;
+ sp<IDrmPluginListener_V1_2> mListenerV1_2;
SessionLibrary *mSessionLibrary;
int64_t mOpenSessionOkCount;
int64_t mCloseSessionOkCount;
int64_t mCloseSessionNotOpenedCount;
uint32_t mNextSecureStopId;
+ // set by property to mock error scenarios
+ Status_V1_2 mMockError;
+
+ void processMockError(const sp<Session> &session) {
+ session->setMockError(mMockError);
+ mMockError = Status_V1_2::OK;
+ }
+
DeviceFiles mFileHandle;
CLEARKEY_DISALLOW_COPY_AND_ASSIGN_AND_NEW(DrmPlugin);
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/Session.h b/drm/mediadrm/plugins/clearkey/hidl/include/Session.h
index f35560d..a159e5a 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/Session.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/Session.h
@@ -30,13 +30,16 @@
namespace V1_2 {
namespace clearkey {
-using ::android::hardware::drm::V1_0::Status;
-using ::android::hardware::drm::V1_0::SubSample;
+namespace drm = ::android::hardware::drm;
+using drm::V1_0::Status;
+using drm::V1_0::SubSample;
+
+typedef drm::V1_2::Status Status_V1_2;
class Session : public RefBase {
public:
explicit Session(const std::vector<uint8_t>& sessionId)
- : mSessionId(sessionId) {}
+ : mSessionId(sessionId), mMockError(Status_V1_2::OK) {}
virtual ~Session() {}
const std::vector<uint8_t>& sessionId() const { return mSessionId; }
@@ -50,17 +53,23 @@
Status provideKeyResponse(
const std::vector<uint8_t>& response);
- Status decrypt(
+ Status_V1_2 decrypt(
const KeyId keyId, const Iv iv, const uint8_t* srcPtr,
uint8_t* dstPtr, const std::vector<SubSample> subSamples,
size_t* bytesDecryptedOut);
+ void setMockError(Status_V1_2 error) {mMockError = error;}
+ Status_V1_2 getMockError() const {return mMockError;}
+
private:
CLEARKEY_DISALLOW_COPY_AND_ASSIGN(Session);
const std::vector<uint8_t> mSessionId;
KeyMap mKeyMap;
Mutex mMapLock;
+
+ // For mocking error return scenarios
+ Status_V1_2 mMockError;
};
} // namespace clearkey
diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/TypeConvert.h b/drm/mediadrm/plugins/clearkey/hidl/include/TypeConvert.h
index f6d30c9..b0f8607 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/include/TypeConvert.h
+++ b/drm/mediadrm/plugins/clearkey/hidl/include/TypeConvert.h
@@ -68,6 +68,17 @@
return vec;
}
+inline Status toStatus_1_0(Status_V1_2 status) {
+ switch (status) {
+ case Status_V1_2::ERROR_DRM_INSUFFICIENT_SECURITY:
+ case Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE:
+ case Status_V1_2::ERROR_DRM_SESSION_LOST_STATE:
+ return Status::ERROR_DRM_UNKNOWN;
+ default:
+ return static_cast<Status>(status);
+ }
+}
+
} // namespace clearkey
} // namespace V1_2
} // namespace drm
diff --git a/media/libmedia/include/media/CryptoHal.h b/media/libmedia/include/media/CryptoHal.h
index ff8789d..73c029f 100644
--- a/media/libmedia/include/media/CryptoHal.h
+++ b/media/libmedia/include/media/CryptoHal.h
@@ -21,6 +21,7 @@
#include <android/hardware/drm/1.0/ICryptoFactory.h>
#include <android/hardware/drm/1.0/ICryptoPlugin.h>
#include <android/hardware/drm/1.1/ICryptoFactory.h>
+#include <android/hardware/drm/1.2/ICryptoPlugin.h>
#include <mediadrm/ICrypto.h>
#include <utils/KeyedVector.h>
@@ -72,6 +73,7 @@
const Vector<sp<ICryptoFactory>> mFactories;
sp<ICryptoPlugin> mPlugin;
+ sp<drm::V1_2::ICryptoPlugin> mPluginV1_2;
/**
* mInitCheck is:
diff --git a/media/libmedia/include/media/DrmHal.h b/media/libmedia/include/media/DrmHal.h
index 3302982..de0f3c7 100644
--- a/media/libmedia/include/media/DrmHal.h
+++ b/media/libmedia/include/media/DrmHal.h
@@ -20,11 +20,11 @@
#include <android/hardware/drm/1.0/IDrmFactory.h>
#include <android/hardware/drm/1.0/IDrmPlugin.h>
-#include <android/hardware/drm/1.0/IDrmPluginListener.h>
#include <android/hardware/drm/1.1/IDrmFactory.h>
#include <android/hardware/drm/1.1/IDrmPlugin.h>
#include <android/hardware/drm/1.2/IDrmFactory.h>
#include <android/hardware/drm/1.2/IDrmPlugin.h>
+#include <android/hardware/drm/1.2/IDrmPluginListener.h>
#include <media/MediaAnalyticsItem.h>
#include <mediadrm/DrmMetrics.h>
@@ -43,6 +43,8 @@
using ::android::hardware::Return;
using ::android::hardware::Void;
+typedef drm::V1_2::IDrmPluginListener IDrmPluginListener_V1_2;
+
namespace android {
struct DrmSessionClientInterface;
@@ -54,7 +56,7 @@
struct DrmHal : public BnDrm,
public IBinder::DeathRecipient,
- public IDrmPluginListener {
+ public IDrmPluginListener_V1_2 {
DrmHal();
virtual ~DrmHal();
@@ -176,6 +178,8 @@
Return<void> sendKeysChange(const hidl_vec<uint8_t>& sessionId,
const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey);
+ Return<void> sendSessionLostState(const hidl_vec<uint8_t>& sessionId);
+
virtual void binderDied(const wp<IBinder> &the_late_who);
private:
diff --git a/media/libstagefright/include/media/stagefright/MediaErrors.h b/media/libstagefright/include/media/stagefright/MediaErrors.h
index 6a5c6b6..09639e2 100644
--- a/media/libstagefright/include/media/stagefright/MediaErrors.h
+++ b/media/libstagefright/include/media/stagefright/MediaErrors.h
@@ -70,7 +70,12 @@
ERROR_DRM_DEVICE_REVOKED = DRM_ERROR_BASE - 9,
ERROR_DRM_RESOURCE_BUSY = DRM_ERROR_BASE - 10,
ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION = DRM_ERROR_BASE - 11,
- ERROR_DRM_LAST_USED_ERRORCODE = DRM_ERROR_BASE - 11,
+ ERROR_DRM_INSUFFICIENT_SECURITY = DRM_ERROR_BASE - 12,
+ ERROR_DRM_FRAME_TOO_LARGE = DRM_ERROR_BASE - 13,
+ ERROR_DRM_RESOURCE_CONTENTION = DRM_ERROR_BASE - 14,
+ ERROR_DRM_SESSION_LOST_STATE = DRM_ERROR_BASE - 15,
+ ERROR_DRM_INVALID_STATE = DRM_ERROR_BASE - 16,
+ ERROR_DRM_LAST_USED_ERRORCODE = DRM_ERROR_BASE - 16,
ERROR_DRM_VENDOR_MAX = DRM_ERROR_BASE - 500,
ERROR_DRM_VENDOR_MIN = DRM_ERROR_BASE - 999,