Implement client code to use Drm and Crypto HALs
This change adds DrmHal & CryptoHal classes that connect to the Treble
HAL interfaces for drm. These classes mirror the existing Drm and
Crypto classes that connect to the DrmPlugin and CryptoPlugin
interfaces. Having both allows mediadrmserver to run in either mode
while the HAL is stabilized.
The shared memory interfaces between mediaserver's ACodecBufferChannel
and ICrypto had to be reworked to use the Treble HALs. Specifically,
the shared memory path for returning decrypted buffers in the
non-secure case had to become separate instead of piggy-backing on the
source shared memory buffer. A separate shared memory destination
buffer is now allocated on the buffer channel. An abstraction for a
decrypt destination buffer was also introduced to clarify ICrypto's
decrypt method.
Tests: Playback using Play Movies and ExoPlayer works on angler
with and without the treble hal enabled.
bug: 32815560
Change-Id: I5a3dc84f99902eb8cf8eabab9ad074d307744950
diff --git a/drm/libmediadrm/ICrypto.cpp b/drm/libmediadrm/ICrypto.cpp
index 8ba80c6..10e6bc3 100644
--- a/drm/libmediadrm/ICrypto.cpp
+++ b/drm/libmediadrm/ICrypto.cpp
@@ -94,18 +94,13 @@
return reply.readInt32() != 0;
}
- virtual ssize_t decrypt(
- DestinationType dstType,
- const uint8_t key[16],
- const uint8_t iv[16],
+ virtual ssize_t decrypt(const uint8_t key[16], const uint8_t iv[16],
CryptoPlugin::Mode mode, const CryptoPlugin::Pattern &pattern,
- const sp<IMemory> &sharedBuffer, size_t offset,
+ const sp<IMemory> &source, size_t offset,
const CryptoPlugin::SubSample *subSamples, size_t numSubSamples,
- void *dstPtr,
- AString *errorDetailMsg) {
+ const DestinationBuffer &destination, AString *errorDetailMsg) {
Parcel data, reply;
data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
- data.writeInt32((int32_t)dstType);
data.writeInt32(mode);
data.writeInt32(pattern.mEncryptBlocks);
data.writeInt32(pattern.mSkipBlocks);
@@ -130,18 +125,23 @@
}
data.writeInt32(totalSize);
- data.writeStrongBinder(IInterface::asBinder(sharedBuffer));
+ data.writeStrongBinder(IInterface::asBinder(source));
data.writeInt32(offset);
data.writeInt32(numSubSamples);
data.write(subSamples, sizeof(CryptoPlugin::SubSample) * numSubSamples);
- if (dstType == kDestinationTypeNativeHandle) {
- data.writeNativeHandle(static_cast<native_handle_t *>(dstPtr));
- } else if (dstType == kDestinationTypeOpaqueHandle) {
- data.writeInt64(static_cast<uint64_t>(reinterpret_cast<uintptr_t>(dstPtr)));
+ data.writeInt32((int32_t)destination.mType);
+ if (destination.mType == kDestinationTypeNativeHandle) {
+ if (destination.mHandle == NULL) {
+ return BAD_VALUE;
+ }
+ data.writeNativeHandle(destination.mHandle);
} else {
- dstType = kDestinationTypeVmPointer;
+ if (destination.mSharedMemory == NULL) {
+ return BAD_VALUE;
+ }
+ data.writeStrongBinder(IInterface::asBinder(destination.mSharedMemory));
}
remote()->transact(DECRYPT, data, &reply);
@@ -150,10 +150,6 @@
if (isCryptoError(result)) {
errorDetailMsg->setTo(reply.readCString());
- } else if (dstType == kDestinationTypeVmPointer) {
- // For the non-secure case, copy the decrypted
- // data from shared memory to its final destination
- memcpy(dstPtr, sharedBuffer->pointer(), result);
}
return result;
@@ -280,7 +276,6 @@
{
CHECK_INTERFACE(ICrypto, data, reply);
- DestinationType dstType = (DestinationType)data.readInt32();
CryptoPlugin::Mode mode = (CryptoPlugin::Mode)data.readInt32();
CryptoPlugin::Pattern pattern;
pattern.mEncryptBlocks = data.readInt32();
@@ -293,9 +288,9 @@
data.read(iv, sizeof(iv));
size_t totalSize = data.readInt32();
- sp<IMemory> sharedBuffer =
+ sp<IMemory> source =
interface_cast<IMemory>(data.readStrongBinder());
- if (sharedBuffer == NULL) {
+ if (source == NULL) {
reply->writeInt32(BAD_VALUE);
return OK;
}
@@ -308,23 +303,26 @@
}
CryptoPlugin::SubSample *subSamples =
- new CryptoPlugin::SubSample[numSubSamples];
+ new CryptoPlugin::SubSample[numSubSamples];
- data.read(
- subSamples,
+ data.read(subSamples,
sizeof(CryptoPlugin::SubSample) * numSubSamples);
- native_handle_t *nativeHandle = NULL;
- void *secureBufferId = NULL, *dstPtr;
- if (dstType == kDestinationTypeNativeHandle) {
- nativeHandle = data.readNativeHandle();
- dstPtr = static_cast<void *>(nativeHandle);
- } else if (dstType == kDestinationTypeOpaqueHandle) {
- secureBufferId = reinterpret_cast<void *>(static_cast<uintptr_t>(data.readInt64()));
- dstPtr = secureBufferId;
- } else {
- dstType = kDestinationTypeVmPointer;
- dstPtr = malloc(totalSize);
+ DestinationBuffer destination;
+ destination.mType = (DestinationType)data.readInt32();
+ if (destination.mType == kDestinationTypeNativeHandle) {
+ destination.mHandle = data.readNativeHandle();
+ if (destination.mHandle == NULL) {
+ reply->writeInt32(BAD_VALUE);
+ return OK;
+ }
+ } else if (destination.mType == kDestinationTypeSharedMemory) {
+ destination.mSharedMemory =
+ interface_cast<IMemory>(data.readStrongBinder());
+ if (destination.mSharedMemory == NULL) {
+ reply->writeInt32(BAD_VALUE);
+ return OK;
+ }
}
AString errorDetailMsg;
@@ -348,20 +346,13 @@
if (overflow || sumSubsampleSizes != totalSize) {
result = -EINVAL;
- } else if (totalSize > sharedBuffer->size()) {
+ } else if (totalSize > source->size()) {
result = -EINVAL;
- } else if ((size_t)offset > sharedBuffer->size() - totalSize) {
+ } else if ((size_t)offset > source->size() - totalSize) {
result = -EINVAL;
} else {
- result = decrypt(
- dstType,
- key,
- iv,
- mode, pattern,
- sharedBuffer, offset,
- subSamples, numSubSamples,
- dstPtr,
- &errorDetailMsg);
+ result = decrypt(key, iv, mode, pattern, source, offset,
+ subSamples, numSubSamples, destination, &errorDetailMsg);
}
reply->writeInt32(result);
@@ -370,23 +361,12 @@
reply->writeCString(errorDetailMsg.c_str());
}
- if (dstType == kDestinationTypeVmPointer) {
- if (result >= 0) {
- CHECK_LE(result, static_cast<ssize_t>(totalSize));
- // For the non-secure case, pass the decrypted
- // data back via the shared buffer rather than
- // copying it separately over binder to avoid
- // binder's 1MB limit.
- memcpy(sharedBuffer->pointer(), dstPtr, result);
- }
- free(dstPtr);
- dstPtr = NULL;
- } else if (dstType == kDestinationTypeNativeHandle) {
+ if (destination.mType == kDestinationTypeNativeHandle) {
int err;
- if ((err = native_handle_close(nativeHandle)) < 0) {
+ if ((err = native_handle_close(destination.mHandle)) < 0) {
ALOGW("secure buffer native_handle_close failed: %d", err);
}
- if ((err = native_handle_delete(nativeHandle)) < 0) {
+ if ((err = native_handle_delete(destination.mHandle)) < 0) {
ALOGW("secure buffer native_handle_delete failed: %d", err);
}
}