Loading include/media/ICrypto.h +1 −1 Original line number Diff line number Diff line Loading @@ -31,7 +31,7 @@ struct ICrypto : public IInterface { virtual status_t initCheck() const = 0; virtual bool isCryptoSchemeSupported(const uint8_t uuid[16]) const = 0; virtual bool isCryptoSchemeSupported(const uint8_t uuid[16]) = 0; virtual status_t createPlugin( const uint8_t uuid[16], const void *data, size_t size) = 0; Loading media/libmedia/ICrypto.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -48,7 +48,7 @@ struct BpCrypto : public BpInterface<ICrypto> { return reply.readInt32(); } virtual bool isCryptoSchemeSupported(const uint8_t uuid[16]) const { virtual bool isCryptoSchemeSupported(const uint8_t uuid[16]) { Parcel data, reply; data.writeInterfaceToken(ICrypto::getInterfaceDescriptor()); data.write(uuid, 16); Loading media/libmediaplayerservice/Crypto.cpp +126 −35 Original line number Diff line number Diff line Loading @@ -17,6 +17,8 @@ //#define LOG_NDEBUG 0 #define LOG_TAG "Crypto" #include <utils/Log.h> #include <dirent.h> #include <dlfcn.h> #include "Crypto.h" Loading @@ -26,87 +28,176 @@ #include <media/stagefright/foundation/hexdump.h> #include <media/stagefright/MediaErrors.h> #include <dlfcn.h> namespace android { KeyedVector<Vector<uint8_t>, String8> Crypto::mUUIDToLibraryPathMap; KeyedVector<String8, wp<SharedLibrary> > Crypto::mLibraryPathToOpenLibraryMap; Mutex Crypto::mMapLock; static bool operator<(const Vector<uint8_t> &lhs, const Vector<uint8_t> &rhs) { if (lhs.size() < rhs.size()) { return true; } else if (lhs.size() > rhs.size()) { return false; } return memcmp((void *)lhs.array(), (void *)rhs.array(), rhs.size()) < 0; } Crypto::Crypto() : mInitCheck(NO_INIT), mLibHandle(NULL), mFactory(NULL), mPlugin(NULL) { mInitCheck = init(); } Crypto::~Crypto() { delete mPlugin; mPlugin = NULL; closeFactory(); } void Crypto::closeFactory() { delete mFactory; mFactory = NULL; if (mLibHandle != NULL) { dlclose(mLibHandle); mLibHandle = NULL; } mLibrary.clear(); } status_t Crypto::initCheck() const { return mInitCheck; } status_t Crypto::init() { mLibHandle = dlopen("libdrmdecrypt.so", RTLD_NOW); /* * Search the plugins directory for a plugin that supports the scheme * specified by uuid * * If found: * mLibrary holds a strong pointer to the dlopen'd library * mFactory is set to the library's factory method * mInitCheck is set to OK * * If not found: * mLibrary is cleared and mFactory are set to NULL * mInitCheck is set to an error (!OK) */ void Crypto::findFactoryForScheme(const uint8_t uuid[16]) { closeFactory(); if (mLibHandle == NULL) { ALOGE("Unable to locate libdrmdecrypt.so"); // lock static maps Mutex::Autolock autoLock(mMapLock); return ERROR_UNSUPPORTED; // first check cache Vector<uint8_t> uuidVector; uuidVector.appendArray(uuid, sizeof(uuid)); ssize_t index = mUUIDToLibraryPathMap.indexOfKey(uuidVector); if (index >= 0) { if (loadLibraryForScheme(mUUIDToLibraryPathMap[index], uuid)) { mInitCheck = OK; return; } else { ALOGE("Failed to load from cached library path!"); mInitCheck = ERROR_UNSUPPORTED; return; } } typedef CryptoFactory *(*CreateCryptoFactoryFunc)(); CreateCryptoFactoryFunc createCryptoFactory = (CreateCryptoFactoryFunc)dlsym(mLibHandle, "createCryptoFactory"); // no luck, have to search String8 dirPath("/vendor/lib/mediadrm"); String8 pluginPath; DIR* pDir = opendir(dirPath.string()); if (pDir) { struct dirent* pEntry; while ((pEntry = readdir(pDir))) { pluginPath = dirPath + "/" + pEntry->d_name; if (pluginPath.getPathExtension() == ".so") { if (loadLibraryForScheme(pluginPath, uuid)) { mUUIDToLibraryPathMap.add(uuidVector, pluginPath); mInitCheck = OK; closedir(pDir); return; } } } if (createCryptoFactory == NULL || ((mFactory = createCryptoFactory()) == NULL)) { if (createCryptoFactory == NULL) { ALOGE("Unable to find symbol 'createCryptoFactory'."); closedir(pDir); } // try the legacy libdrmdecrypt.so pluginPath = "libdrmdecrypt.so"; if (loadLibraryForScheme(pluginPath, uuid)) { mUUIDToLibraryPathMap.add(uuidVector, pluginPath); mInitCheck = OK; return; } ALOGE("Failed to find crypto plugin"); mInitCheck = ERROR_UNSUPPORTED; } bool Crypto::loadLibraryForScheme(const String8 &path, const uint8_t uuid[16]) { // get strong pointer to open shared library ssize_t index = mLibraryPathToOpenLibraryMap.indexOfKey(path); if (index >= 0) { mLibrary = mLibraryPathToOpenLibraryMap[index].promote(); } else { ALOGE("createCryptoFactory() failed."); index = mLibraryPathToOpenLibraryMap.add(path, NULL); } dlclose(mLibHandle); mLibHandle = NULL; if (!mLibrary.get()) { mLibrary = new SharedLibrary(path); if (!*mLibrary) { return false; } return ERROR_UNSUPPORTED; mLibraryPathToOpenLibraryMap.replaceValueAt(index, mLibrary); } return OK; typedef CryptoFactory *(*CreateCryptoFactoryFunc)(); CreateCryptoFactoryFunc createCryptoFactory = (CreateCryptoFactoryFunc)mLibrary->lookup("createCryptoFactory"); if (createCryptoFactory == NULL || (mFactory = createCryptoFactory()) == NULL || !mFactory->isCryptoSchemeSupported(uuid)) { closeFactory(); return false; } return true; } bool Crypto::isCryptoSchemeSupported(const uint8_t uuid[16]) const { bool Crypto::isCryptoSchemeSupported(const uint8_t uuid[16]) { Mutex::Autolock autoLock(mLock); if (mInitCheck != OK) { return false; if (mFactory && mFactory->isCryptoSchemeSupported(uuid)) { return true; } return mFactory->isCryptoSchemeSupported(uuid); findFactoryForScheme(uuid); return (mInitCheck == OK); } status_t Crypto::createPlugin( const uint8_t uuid[16], const void *data, size_t size) { Mutex::Autolock autoLock(mLock); if (mInitCheck != OK) { return mInitCheck; } if (mPlugin != NULL) { return -EINVAL; } if (!mFactory || !mFactory->isCryptoSchemeSupported(uuid)) { findFactoryForScheme(uuid); } if (mInitCheck != OK) { return mInitCheck; } return mFactory->createPlugin(uuid, data, size, &mPlugin); } Loading media/libmediaplayerservice/Crypto.h +12 −3 Original line number Diff line number Diff line Loading @@ -20,6 +20,9 @@ #include <media/ICrypto.h> #include <utils/threads.h> #include <utils/KeyedVector.h> #include "SharedLibrary.h" namespace android { Loading @@ -32,7 +35,7 @@ struct Crypto : public BnCrypto { virtual status_t initCheck() const; virtual bool isCryptoSchemeSupported(const uint8_t uuid[16]) const; virtual bool isCryptoSchemeSupported(const uint8_t uuid[16]); virtual status_t createPlugin( const uint8_t uuid[16], const void *data, size_t size); Loading @@ -56,11 +59,17 @@ private: mutable Mutex mLock; status_t mInitCheck; void *mLibHandle; sp<SharedLibrary> mLibrary; CryptoFactory *mFactory; CryptoPlugin *mPlugin; status_t init(); static KeyedVector<Vector<uint8_t>, String8> mUUIDToLibraryPathMap; static KeyedVector<String8, wp<SharedLibrary> > mLibraryPathToOpenLibraryMap; static Mutex mMapLock; void findFactoryForScheme(const uint8_t uuid[16]); bool loadLibraryForScheme(const String8 &path, const uint8_t uuid[16]); void closeFactory(); DISALLOW_EVIL_CONSTRUCTORS(Crypto); }; Loading Loading
include/media/ICrypto.h +1 −1 Original line number Diff line number Diff line Loading @@ -31,7 +31,7 @@ struct ICrypto : public IInterface { virtual status_t initCheck() const = 0; virtual bool isCryptoSchemeSupported(const uint8_t uuid[16]) const = 0; virtual bool isCryptoSchemeSupported(const uint8_t uuid[16]) = 0; virtual status_t createPlugin( const uint8_t uuid[16], const void *data, size_t size) = 0; Loading
media/libmedia/ICrypto.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -48,7 +48,7 @@ struct BpCrypto : public BpInterface<ICrypto> { return reply.readInt32(); } virtual bool isCryptoSchemeSupported(const uint8_t uuid[16]) const { virtual bool isCryptoSchemeSupported(const uint8_t uuid[16]) { Parcel data, reply; data.writeInterfaceToken(ICrypto::getInterfaceDescriptor()); data.write(uuid, 16); Loading
media/libmediaplayerservice/Crypto.cpp +126 −35 Original line number Diff line number Diff line Loading @@ -17,6 +17,8 @@ //#define LOG_NDEBUG 0 #define LOG_TAG "Crypto" #include <utils/Log.h> #include <dirent.h> #include <dlfcn.h> #include "Crypto.h" Loading @@ -26,87 +28,176 @@ #include <media/stagefright/foundation/hexdump.h> #include <media/stagefright/MediaErrors.h> #include <dlfcn.h> namespace android { KeyedVector<Vector<uint8_t>, String8> Crypto::mUUIDToLibraryPathMap; KeyedVector<String8, wp<SharedLibrary> > Crypto::mLibraryPathToOpenLibraryMap; Mutex Crypto::mMapLock; static bool operator<(const Vector<uint8_t> &lhs, const Vector<uint8_t> &rhs) { if (lhs.size() < rhs.size()) { return true; } else if (lhs.size() > rhs.size()) { return false; } return memcmp((void *)lhs.array(), (void *)rhs.array(), rhs.size()) < 0; } Crypto::Crypto() : mInitCheck(NO_INIT), mLibHandle(NULL), mFactory(NULL), mPlugin(NULL) { mInitCheck = init(); } Crypto::~Crypto() { delete mPlugin; mPlugin = NULL; closeFactory(); } void Crypto::closeFactory() { delete mFactory; mFactory = NULL; if (mLibHandle != NULL) { dlclose(mLibHandle); mLibHandle = NULL; } mLibrary.clear(); } status_t Crypto::initCheck() const { return mInitCheck; } status_t Crypto::init() { mLibHandle = dlopen("libdrmdecrypt.so", RTLD_NOW); /* * Search the plugins directory for a plugin that supports the scheme * specified by uuid * * If found: * mLibrary holds a strong pointer to the dlopen'd library * mFactory is set to the library's factory method * mInitCheck is set to OK * * If not found: * mLibrary is cleared and mFactory are set to NULL * mInitCheck is set to an error (!OK) */ void Crypto::findFactoryForScheme(const uint8_t uuid[16]) { closeFactory(); if (mLibHandle == NULL) { ALOGE("Unable to locate libdrmdecrypt.so"); // lock static maps Mutex::Autolock autoLock(mMapLock); return ERROR_UNSUPPORTED; // first check cache Vector<uint8_t> uuidVector; uuidVector.appendArray(uuid, sizeof(uuid)); ssize_t index = mUUIDToLibraryPathMap.indexOfKey(uuidVector); if (index >= 0) { if (loadLibraryForScheme(mUUIDToLibraryPathMap[index], uuid)) { mInitCheck = OK; return; } else { ALOGE("Failed to load from cached library path!"); mInitCheck = ERROR_UNSUPPORTED; return; } } typedef CryptoFactory *(*CreateCryptoFactoryFunc)(); CreateCryptoFactoryFunc createCryptoFactory = (CreateCryptoFactoryFunc)dlsym(mLibHandle, "createCryptoFactory"); // no luck, have to search String8 dirPath("/vendor/lib/mediadrm"); String8 pluginPath; DIR* pDir = opendir(dirPath.string()); if (pDir) { struct dirent* pEntry; while ((pEntry = readdir(pDir))) { pluginPath = dirPath + "/" + pEntry->d_name; if (pluginPath.getPathExtension() == ".so") { if (loadLibraryForScheme(pluginPath, uuid)) { mUUIDToLibraryPathMap.add(uuidVector, pluginPath); mInitCheck = OK; closedir(pDir); return; } } } if (createCryptoFactory == NULL || ((mFactory = createCryptoFactory()) == NULL)) { if (createCryptoFactory == NULL) { ALOGE("Unable to find symbol 'createCryptoFactory'."); closedir(pDir); } // try the legacy libdrmdecrypt.so pluginPath = "libdrmdecrypt.so"; if (loadLibraryForScheme(pluginPath, uuid)) { mUUIDToLibraryPathMap.add(uuidVector, pluginPath); mInitCheck = OK; return; } ALOGE("Failed to find crypto plugin"); mInitCheck = ERROR_UNSUPPORTED; } bool Crypto::loadLibraryForScheme(const String8 &path, const uint8_t uuid[16]) { // get strong pointer to open shared library ssize_t index = mLibraryPathToOpenLibraryMap.indexOfKey(path); if (index >= 0) { mLibrary = mLibraryPathToOpenLibraryMap[index].promote(); } else { ALOGE("createCryptoFactory() failed."); index = mLibraryPathToOpenLibraryMap.add(path, NULL); } dlclose(mLibHandle); mLibHandle = NULL; if (!mLibrary.get()) { mLibrary = new SharedLibrary(path); if (!*mLibrary) { return false; } return ERROR_UNSUPPORTED; mLibraryPathToOpenLibraryMap.replaceValueAt(index, mLibrary); } return OK; typedef CryptoFactory *(*CreateCryptoFactoryFunc)(); CreateCryptoFactoryFunc createCryptoFactory = (CreateCryptoFactoryFunc)mLibrary->lookup("createCryptoFactory"); if (createCryptoFactory == NULL || (mFactory = createCryptoFactory()) == NULL || !mFactory->isCryptoSchemeSupported(uuid)) { closeFactory(); return false; } return true; } bool Crypto::isCryptoSchemeSupported(const uint8_t uuid[16]) const { bool Crypto::isCryptoSchemeSupported(const uint8_t uuid[16]) { Mutex::Autolock autoLock(mLock); if (mInitCheck != OK) { return false; if (mFactory && mFactory->isCryptoSchemeSupported(uuid)) { return true; } return mFactory->isCryptoSchemeSupported(uuid); findFactoryForScheme(uuid); return (mInitCheck == OK); } status_t Crypto::createPlugin( const uint8_t uuid[16], const void *data, size_t size) { Mutex::Autolock autoLock(mLock); if (mInitCheck != OK) { return mInitCheck; } if (mPlugin != NULL) { return -EINVAL; } if (!mFactory || !mFactory->isCryptoSchemeSupported(uuid)) { findFactoryForScheme(uuid); } if (mInitCheck != OK) { return mInitCheck; } return mFactory->createPlugin(uuid, data, size, &mPlugin); } Loading
media/libmediaplayerservice/Crypto.h +12 −3 Original line number Diff line number Diff line Loading @@ -20,6 +20,9 @@ #include <media/ICrypto.h> #include <utils/threads.h> #include <utils/KeyedVector.h> #include "SharedLibrary.h" namespace android { Loading @@ -32,7 +35,7 @@ struct Crypto : public BnCrypto { virtual status_t initCheck() const; virtual bool isCryptoSchemeSupported(const uint8_t uuid[16]) const; virtual bool isCryptoSchemeSupported(const uint8_t uuid[16]); virtual status_t createPlugin( const uint8_t uuid[16], const void *data, size_t size); Loading @@ -56,11 +59,17 @@ private: mutable Mutex mLock; status_t mInitCheck; void *mLibHandle; sp<SharedLibrary> mLibrary; CryptoFactory *mFactory; CryptoPlugin *mPlugin; status_t init(); static KeyedVector<Vector<uint8_t>, String8> mUUIDToLibraryPathMap; static KeyedVector<String8, wp<SharedLibrary> > mLibraryPathToOpenLibraryMap; static Mutex mMapLock; void findFactoryForScheme(const uint8_t uuid[16]); bool loadLibraryForScheme(const String8 &path, const uint8_t uuid[16]); void closeFactory(); DISALLOW_EVIL_CONSTRUCTORS(Crypto); }; Loading