Add aidl interface support for Drm Framework
This change intends to make DrmHal/CryptoHal layer support aidl
interface implemented plugins.
Test: CtsMediaDrmTestCases, GtsMediaTestCases
Bug: 200055138
Bug: 170964303
Change-Id: I7056adf184acf1463cb4fc85e1c95ac88c2097f6
diff --git a/drm/libmediadrm/CryptoHal.cpp b/drm/libmediadrm/CryptoHal.cpp
index e0db1c4..f95d527 100644
--- a/drm/libmediadrm/CryptoHal.cpp
+++ b/drm/libmediadrm/CryptoHal.cpp
@@ -16,389 +16,100 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "CryptoHal"
-#include <utils/Log.h>
-
-#include <android/hardware/drm/1.0/types.h>
-#include <android/hidl/manager/1.2/IServiceManager.h>
-#include <hidl/ServiceManagement.h>
-#include <hidlmemory/FrameworkUtils.h>
-#include <media/hardware/CryptoAPI.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AString.h>
-#include <media/stagefright/foundation/hexdump.h>
-#include <media/stagefright/MediaErrors.h>
#include <mediadrm/CryptoHal.h>
+#include <mediadrm/CryptoHalHidl.h>
+#include <mediadrm/CryptoHalAidl.h>
#include <mediadrm/DrmUtils.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::DrmUtils::toStatusT;
-using ::android::hardware::hidl_array;
-using ::android::hardware::hidl_handle;
-using ::android::hardware::hidl_memory;
-using ::android::hardware::hidl_string;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::HidlMemory;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ::android::sp;
-
-typedef drm::V1_2::Status Status_V1_2;
-
namespace android {
-static hidl_vec<uint8_t> toHidlVec(const Vector<uint8_t> &vector) {
- hidl_vec<uint8_t> vec;
- vec.setToExternal(const_cast<uint8_t *>(vector.array()), vector.size());
- return vec;
+CryptoHal::CryptoHal() {
+ mCryptoHalAidl = sp<CryptoHalAidl>::make();
+ mCryptoHalHidl = sp<CryptoHalHidl>::make();
}
-static hidl_vec<uint8_t> toHidlVec(const void *ptr, size_t size) {
- hidl_vec<uint8_t> vec;
- vec.resize(size);
- memcpy(vec.data(), ptr, size);
- return vec;
-}
-
-static hidl_array<uint8_t, 16> toHidlArray16(const uint8_t *ptr) {
- if (!ptr) {
- return hidl_array<uint8_t, 16>();
- }
- return hidl_array<uint8_t, 16>(ptr);
-}
-
-
-static String8 toString8(hidl_string hString) {
- return String8(hString.c_str());
-}
-
-
-CryptoHal::CryptoHal()
- : mFactories(makeCryptoFactories()),
- mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT),
- mHeapSeqNum(0) {
-}
-
-CryptoHal::~CryptoHal() {
-}
-
-Vector<sp<ICryptoFactory>> CryptoHal::makeCryptoFactories() {
- Vector<sp<ICryptoFactory>> factories;
-
- auto manager = hardware::defaultServiceManager1_2();
- if (manager != NULL) {
- manager->listManifestByInterface(drm::V1_0::ICryptoFactory::descriptor,
- [&factories](const hidl_vec<hidl_string> ®istered) {
- for (const auto &instance : registered) {
- auto factory = drm::V1_0::ICryptoFactory::getService(instance);
- if (factory != NULL) {
- ALOGD("found drm@1.0 ICryptoFactory %s", instance.c_str());
- factories.push_back(factory);
- }
- }
- }
- );
- manager->listManifestByInterface(drm::V1_1::ICryptoFactory::descriptor,
- [&factories](const hidl_vec<hidl_string> ®istered) {
- for (const auto &instance : registered) {
- auto factory = drm::V1_1::ICryptoFactory::getService(instance);
- if (factory != NULL) {
- ALOGD("found drm@1.1 ICryptoFactory %s", instance.c_str());
- factories.push_back(factory);
- }
- }
- }
- );
- }
-
- if (factories.size() == 0) {
- // must be in passthrough mode, load the default passthrough service
- auto passthrough = ICryptoFactory::getService();
- if (passthrough != NULL) {
- ALOGI("makeCryptoFactories: using default passthrough crypto instance");
- factories.push_back(passthrough);
- } else {
- ALOGE("Failed to find any crypto factories");
- }
- }
- return factories;
-}
-
-sp<ICryptoPlugin> CryptoHal::makeCryptoPlugin(const sp<ICryptoFactory>& factory,
- const uint8_t uuid[16], const void *initData, size_t initDataSize) {
-
- sp<ICryptoPlugin> plugin;
- Return<void> hResult = factory->createPlugin(toHidlArray16(uuid),
- toHidlVec(initData, initDataSize),
- [&](Status status, const sp<ICryptoPlugin>& hPlugin) {
- if (status != Status::OK) {
- ALOGE("Failed to make crypto plugin");
- return;
- }
- plugin = hPlugin;
- }
- );
- if (!hResult.isOk()) {
- mInitCheck = DEAD_OBJECT;
- }
- return plugin;
-}
-
+CryptoHal::~CryptoHal() {}
status_t CryptoHal::initCheck() const {
- return mInitCheck;
+ if (mCryptoHalAidl->initCheck() == OK || mCryptoHalHidl->initCheck() == OK) return OK;
+ if (mCryptoHalAidl->initCheck() == NO_INIT || mCryptoHalHidl->initCheck() == NO_INIT)
+ return NO_INIT;
+ return mCryptoHalHidl->initCheck();
}
-
bool CryptoHal::isCryptoSchemeSupported(const uint8_t uuid[16]) {
- Mutex::Autolock autoLock(mLock);
-
- for (size_t i = 0; i < mFactories.size(); i++) {
- if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
- return true;
- }
- }
- return false;
+ return mCryptoHalAidl->isCryptoSchemeSupported(uuid) ||
+ mCryptoHalHidl->isCryptoSchemeSupported(uuid);
}
-status_t CryptoHal::createPlugin(const uint8_t uuid[16], const void *data,
- size_t size) {
- Mutex::Autolock autoLock(mLock);
-
- 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);
- }
- }
- }
-
- if (mInitCheck == NO_INIT) {
- mInitCheck = mPlugin == NULL ? ERROR_UNSUPPORTED : OK;
- }
-
- return mInitCheck;
+status_t CryptoHal::createPlugin(const uint8_t uuid[16], const void* data, size_t size) {
+ if (mCryptoHalAidl->createPlugin(uuid, data, size) != OK)
+ return mCryptoHalHidl->createPlugin(uuid, data, size);
+ return OK;
}
status_t CryptoHal::destroyPlugin() {
- Mutex::Autolock autoLock(mLock);
-
- if (mInitCheck != OK) {
- return mInitCheck;
- }
-
- mPlugin.clear();
- mPluginV1_2.clear();
- return OK;
+ // This requires plugin to be created.
+ if (mCryptoHalAidl->initCheck() == OK) return mCryptoHalAidl->destroyPlugin();
+ return mCryptoHalHidl->destroyPlugin();
}
-bool CryptoHal::requiresSecureDecoderComponent(const char *mime) const {
- Mutex::Autolock autoLock(mLock);
-
- if (mInitCheck != OK) {
- return false;
- }
-
- Return<bool> hResult = mPlugin->requiresSecureDecoderComponent(hidl_string(mime));
- if (!hResult.isOk()) {
- return false;
- }
- return hResult;
-}
-
-
-/**
- * If the heap base isn't set, get the heap base from the HidlMemory
- * and send it to the HAL so it can map a remote heap of the same
- * size. Once the heap base is established, shared memory buffers
- * are sent by providing an offset into the heap and a buffer size.
- */
-int32_t CryptoHal::setHeapBase(const sp<HidlMemory>& heap) {
- if (heap == NULL || mHeapSeqNum < 0) {
- ALOGE("setHeapBase(): heap %p mHeapSeqNum %d", heap.get(), mHeapSeqNum);
- return -1;
- }
-
- Mutex::Autolock autoLock(mLock);
-
- int32_t seqNum = mHeapSeqNum++;
- uint32_t bufferId = static_cast<uint32_t>(seqNum);
- mHeapSizes.add(seqNum, heap->size());
- Return<void> hResult = mPlugin->setSharedBufferBase(*heap, bufferId);
- ALOGE_IF(!hResult.isOk(), "setSharedBufferBase(): remote call failed");
- return seqNum;
-}
-
-void CryptoHal::clearHeapBase(int32_t seqNum) {
- Mutex::Autolock autoLock(mLock);
-
- /*
- * Clear the remote shared memory mapping by setting the shared
- * buffer base to a null hidl_memory.
- *
- * TODO: Add a releaseSharedBuffer method in a future DRM HAL
- * API version to make this explicit.
- */
- ssize_t index = mHeapSizes.indexOfKey(seqNum);
- if (index >= 0) {
- if (mPlugin != NULL) {
- uint32_t bufferId = static_cast<uint32_t>(seqNum);
- Return<void> hResult = mPlugin->setSharedBufferBase(hidl_memory(), bufferId);
- ALOGE_IF(!hResult.isOk(), "setSharedBufferBase(): remote call failed");
- }
- mHeapSizes.removeItem(seqNum);
- }
-}
-
-status_t CryptoHal::checkSharedBuffer(const ::SharedBuffer &buffer) {
- int32_t seqNum = static_cast<int32_t>(buffer.bufferId);
- // memory must be in one of the heaps that have been set
- if (mHeapSizes.indexOfKey(seqNum) < 0) {
- return UNKNOWN_ERROR;
- }
-
- // memory must be within the address space of the heap
- size_t heapSize = mHeapSizes.valueFor(seqNum);
- if (heapSize < buffer.offset + buffer.size ||
- SIZE_MAX - buffer.offset < buffer.size) {
- android_errorWriteLog(0x534e4554, "76221123");
- return UNKNOWN_ERROR;
- }
-
- return OK;
-}
-
-ssize_t CryptoHal::decrypt(const uint8_t keyId[16], const uint8_t iv[16],
- CryptoPlugin::Mode mode, const CryptoPlugin::Pattern &pattern,
- const ::SharedBuffer &hSource, size_t offset,
- const CryptoPlugin::SubSample *subSamples, size_t numSubSamples,
- const ::DestinationBuffer &hDestination, AString *errorDetailMsg) {
- Mutex::Autolock autoLock(mLock);
-
- if (mInitCheck != OK) {
- return mInitCheck;
- }
-
- Mode hMode;
- switch(mode) {
- case CryptoPlugin::kMode_Unencrypted:
- hMode = Mode::UNENCRYPTED ;
- break;
- case CryptoPlugin::kMode_AES_CTR:
- hMode = Mode::AES_CTR;
- break;
- case CryptoPlugin::kMode_AES_WV:
- hMode = Mode::AES_CBC_CTS;
- break;
- case CryptoPlugin::kMode_AES_CBC:
- hMode = Mode::AES_CBC;
- break;
- default:
- return UNKNOWN_ERROR;
- }
-
- Pattern hPattern;
- hPattern.encryptBlocks = pattern.mEncryptBlocks;
- hPattern.skipBlocks = pattern.mSkipBlocks;
-
- std::vector<SubSample> stdSubSamples;
- for (size_t i = 0; i < numSubSamples; i++) {
- SubSample subSample;
- subSample.numBytesOfClearData = subSamples[i].mNumBytesOfClearData;
- subSample.numBytesOfEncryptedData = subSamples[i].mNumBytesOfEncryptedData;
- stdSubSamples.push_back(subSample);
- }
- auto hSubSamples = hidl_vec<SubSample>(stdSubSamples);
-
- bool secure;
- if (hDestination.type == BufferType::SHARED_MEMORY) {
- status_t status = checkSharedBuffer(hDestination.nonsecureMemory);
- if (status != OK) {
- return status;
- }
- secure = false;
- } else if (hDestination.type == BufferType::NATIVE_HANDLE) {
- secure = true;
- } else {
- android_errorWriteLog(0x534e4554, "70526702");
- return UNKNOWN_ERROR;
- }
-
- status_t status = checkSharedBuffer(hSource);
- if (status != OK) {
- return status;
- }
-
- status_t err = UNKNOWN_ERROR;
- uint32_t bytesWritten = 0;
-
- Return<void> hResult;
-
- mLock.unlock();
- 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(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;
- }
- return err;
+bool CryptoHal::requiresSecureDecoderComponent(const char* mime) const {
+ // This requires plugin to be created.
+ if (mCryptoHalAidl->initCheck() == OK)
+ return mCryptoHalAidl->requiresSecureDecoderComponent(mime);
+ return mCryptoHalHidl->requiresSecureDecoderComponent(mime);
}
void CryptoHal::notifyResolution(uint32_t width, uint32_t height) {
- Mutex::Autolock autoLock(mLock);
-
- if (mInitCheck != OK) {
+ // This requires plugin to be created.
+ if (mCryptoHalAidl->initCheck() == OK) {
+ mCryptoHalAidl->notifyResolution(width, height);
return;
}
- auto hResult = mPlugin->notifyResolution(width, height);
- ALOGE_IF(!hResult.isOk(), "notifyResolution txn failed %s", hResult.description().c_str());
+ mCryptoHalHidl->notifyResolution(width, height);
}
-status_t CryptoHal::setMediaDrmSession(const Vector<uint8_t> &sessionId) {
- Mutex::Autolock autoLock(mLock);
+status_t CryptoHal::setMediaDrmSession(const Vector<uint8_t>& sessionId) {
+ // This requires plugin to be created.
+ if (mCryptoHalAidl->initCheck() == OK) return mCryptoHalAidl->setMediaDrmSession(sessionId);
+ return mCryptoHalHidl->setMediaDrmSession(sessionId);
+}
- if (mInitCheck != OK) {
- return mInitCheck;
+ssize_t CryptoHal::decrypt(const uint8_t key[16], const uint8_t iv[16], CryptoPlugin::Mode mode,
+ const CryptoPlugin::Pattern& pattern, const ::SharedBuffer& source,
+ size_t offset, const CryptoPlugin::SubSample* subSamples,
+ size_t numSubSamples, const ::DestinationBuffer& destination,
+ AString* errorDetailMsg) {
+ // This requires plugin to be created.
+ if (mCryptoHalAidl->initCheck() == OK)
+ return mCryptoHalAidl->decrypt(key, iv, mode, pattern, source, offset, subSamples,
+ numSubSamples, destination, errorDetailMsg);
+ return mCryptoHalHidl->decrypt(key, iv, mode, pattern, source, offset, subSamples,
+ numSubSamples, destination, errorDetailMsg);
+}
+
+int32_t CryptoHal::setHeap(const sp<HidlMemory>& heap) {
+ // This requires plugin to be created.
+ if (mCryptoHalAidl->initCheck() == OK) return mCryptoHalAidl->setHeap(heap);
+ return mCryptoHalHidl->setHeap(heap);
+}
+
+void CryptoHal::unsetHeap(int32_t seqNum) {
+ // This requires plugin to be created.
+ if (mCryptoHalAidl->initCheck() == OK) {
+ mCryptoHalAidl->unsetHeap(seqNum);
+ return;
}
- auto err = mPlugin->setMediaDrmSession(toHidlVec(sessionId));
- return err.isOk() ? toStatusT(err) : DEAD_OBJECT;
+ mCryptoHalHidl->unsetHeap(seqNum);
}
-status_t CryptoHal::getLogMessages(Vector<drm::V1_4::LogMessage> &logs) const {
- Mutex::Autolock autoLock(mLock);
- return DrmUtils::GetLogMessages<drm::V1_4::ICryptoPlugin>(mPlugin, logs);
+status_t CryptoHal::getLogMessages(Vector<drm::V1_4::LogMessage>& logs) const {
+ // This requires plugin to be created.
+ if (mCryptoHalAidl->initCheck() == OK) return mCryptoHalAidl->getLogMessages(logs);
+ return mCryptoHalHidl->getLogMessages(logs);
}
-} // namespace android
+
+} // namespace android
\ No newline at end of file