Support multiple codecs per crypto instance

The initial drm hidl hal implementation assumed one
codec per crypto instance, but in fact there can be
multiple codecs per crypto instance. This change
extends the drm hal to allow multiple memory heaps
per crypto plugin. It fixes the issue of mapping
memory frequently during playback.

bug:35275191

Test: manual verification with Play Movies on angler
and in binderized mode on marlin

Change-Id: I0ec36856248623d2ad8acb8ce9873e9274883a40
This commit is contained in:
Jeff Tinker
2017-02-16 12:20:30 -08:00
parent 7ddf7abff5
commit 0b3f41ec8d
4 changed files with 39 additions and 14 deletions

View File

@@ -62,8 +62,16 @@ interface ICryptoPlugin {
* After the shared buffer base is established, the decrypt() method
* receives SharedBuffer instances which specify the buffer address range
* for decrypt source and destination addresses.
*
* There can be multiple shared buffers per crypto plugin. The buffers
* are distinguished by the bufferId.
*
* @param base the base IMemory of the memory buffer identified by
* bufferId
* @param bufferId identifies the specific shared buffer for which
* the base is being set.
*/
setSharedBufferBase(memory base);
setSharedBufferBase(memory base, uint32_t bufferId);
/**
* Decrypt an array of subsamples from the source memory buffer to the

View File

@@ -49,8 +49,9 @@ namespace implementation {
return toStatus(mLegacyPlugin->setMediaDrmSession(toVector(sessionId)));
}
Return<void> CryptoPlugin::setSharedBufferBase(const hidl_memory& base) {
mSharedBufferBase = mapMemory(base);
Return<void> CryptoPlugin::setSharedBufferBase(const hidl_memory& base,
uint32_t bufferId) {
mSharedBufferMap[bufferId] = mapMemory(base);
return Void();
}
@@ -62,11 +63,19 @@ namespace implementation {
const DestinationBuffer& destination,
decrypt_cb _hidl_cb) {
if (mSharedBufferBase == NULL) {
_hidl_cb(Status::BAD_VALUE, 0, "decrypt buffer base not set");
if (mSharedBufferMap.find(source.bufferId) == mSharedBufferMap.end()) {
_hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "source decrypt buffer base not set");
return Void();
}
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, "destination decrypt buffer base not set");
return Void();
}
}
android::CryptoPlugin::Mode legacyMode;
switch(mode) {
case Mode::UNENCRYPTED:
@@ -97,20 +106,22 @@ namespace implementation {
}
AString detailMessage;
sp<IMemory> sourceBase = mSharedBufferMap[source.bufferId];
if (source.offset + offset + source.size > mSharedBufferBase->getSize()) {
if (source.offset + offset + source.size > sourceBase->getSize()) {
_hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size");
return Void();
}
uint8_t *base = static_cast<uint8_t *>
(static_cast<void *>(mSharedBufferBase->getPointer()));
(static_cast<void *>(sourceBase->getPointer()));
void *srcPtr = static_cast<void *>(base + source.offset + offset);
void *destPtr = NULL;
if (destination.type == BufferType::SHARED_MEMORY) {
const SharedBuffer& destBuffer = destination.nonsecureMemory;
if (destBuffer.offset + destBuffer.size > mSharedBufferBase->getSize()) {
sp<IMemory> destBase = mSharedBufferMap[destBuffer.bufferId];
if (destBuffer.offset + destBuffer.size > destBase->getSize()) {
_hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size");
return Void();
}

View File

@@ -57,8 +57,8 @@ struct CryptoPlugin : public ICryptoPlugin {
Return<Status> setMediaDrmSession(const hidl_vec<uint8_t>& sessionId)
override;
Return<void> setSharedBufferBase(const ::android::hardware::hidl_memory& base)
override;
Return<void> setSharedBufferBase(const ::android::hardware::hidl_memory& base,
uint32_t bufferId) override;
Return<void> decrypt(bool secure, const hidl_array<uint8_t, 16>& keyId,
const hidl_array<uint8_t, 16>& iv, Mode mode, const Pattern& pattern,
@@ -68,7 +68,7 @@ struct CryptoPlugin : public ICryptoPlugin {
private:
android::CryptoPlugin *mLegacyPlugin;
sp<IMemory> mSharedBufferBase;
std::map<uint32_t, sp<IMemory> > mSharedBufferMap;
CryptoPlugin() = delete;
CryptoPlugin(const CryptoPlugin &) = delete;

View File

@@ -293,11 +293,17 @@ enum BufferType : uint32_t {
};
/**
* A SharedBuffer describes a decrypt buffer which is defined by an offset and
* a size. The offset is relative to the shared memory base which is established
* using setSharedMemoryBase().
* SharedBuffer describes a decrypt buffer which is defined by a bufferId, an
* offset and a size. The offset is relative to the shared memory base for the
* memory region identified by bufferId, which is established by
* setSharedMemoryBase().
*/
struct SharedBuffer {
/**
* The unique buffer identifier
*/
uint32_t bufferId;
/**
* The offset from the shared memory base
*/