Loading media/libmediaplayerservice/Drm.cpp +72 −2 Original line number Diff line number Diff line Loading @@ -23,6 +23,8 @@ #include "Drm.h" #include "DrmSessionClientInterface.h" #include "DrmSessionManager.h" #include <media/drm/DrmAPI.h> #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/AString.h> Loading @@ -33,6 +35,10 @@ namespace android { static inline int getCallingPid() { return IPCThreadState::self()->getCallingPid(); } static bool checkPermission(const char* permissionString) { #ifndef HAVE_ANDROID_OS return true; Loading @@ -57,14 +63,41 @@ static bool operator<(const Vector<uint8_t> &lhs, const Vector<uint8_t> &rhs) { return memcmp((void *)lhs.array(), (void *)rhs.array(), rhs.size()) < 0; } struct DrmSessionClient : public DrmSessionClientInterface { DrmSessionClient(Drm* drm) : mDrm(drm) {} virtual bool reclaimSession(const Vector<uint8_t>& sessionId) { sp<Drm> drm = mDrm.promote(); if (drm == NULL) { return true; } status_t err = drm->closeSession(sessionId); if (err != OK) { return false; } drm->sendEvent(DrmPlugin::kDrmPluginEventSessionReclaimed, 0, &sessionId, NULL); return true; } protected: virtual ~DrmSessionClient() {} private: wp<Drm> mDrm; DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient); }; Drm::Drm() : mInitCheck(NO_INIT), mDrmSessionClient(new DrmSessionClient(this)), mListener(NULL), mFactory(NULL), mPlugin(NULL) { } Drm::~Drm() { DrmSessionManager::Instance()->removeDrm(mDrmSessionClient); delete mPlugin; mPlugin = NULL; closeFactory(); Loading Loading @@ -289,7 +322,18 @@ status_t Drm::openSession(Vector<uint8_t> &sessionId) { return -EINVAL; } return mPlugin->openSession(sessionId); status_t err = mPlugin->openSession(sessionId); if (err == ERROR_DRM_RESOURCE_BUSY) { bool retry = false; retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid()); if (retry) { err = mPlugin->openSession(sessionId); } } if (err == OK) { DrmSessionManager::Instance()->addSession(getCallingPid(), mDrmSessionClient, sessionId); } return err; } status_t Drm::closeSession(Vector<uint8_t> const &sessionId) { Loading @@ -303,7 +347,11 @@ status_t Drm::closeSession(Vector<uint8_t> const &sessionId) { return -EINVAL; } return mPlugin->closeSession(sessionId); status_t err = mPlugin->closeSession(sessionId); if (err == OK) { DrmSessionManager::Instance()->removeSession(sessionId); } return err; } status_t Drm::getKeyRequest(Vector<uint8_t> const &sessionId, Loading @@ -321,6 +369,8 @@ status_t Drm::getKeyRequest(Vector<uint8_t> const &sessionId, return -EINVAL; } DrmSessionManager::Instance()->useSession(sessionId); return mPlugin->getKeyRequest(sessionId, initData, mimeType, keyType, optionalParameters, request, defaultUrl); } Loading @@ -338,6 +388,8 @@ status_t Drm::provideKeyResponse(Vector<uint8_t> const &sessionId, return -EINVAL; } DrmSessionManager::Instance()->useSession(sessionId); return mPlugin->provideKeyResponse(sessionId, response, keySetId); } Loading Loading @@ -367,6 +419,8 @@ status_t Drm::restoreKeys(Vector<uint8_t> const &sessionId, return -EINVAL; } DrmSessionManager::Instance()->useSession(sessionId); return mPlugin->restoreKeys(sessionId, keySetId); } Loading @@ -382,6 +436,8 @@ status_t Drm::queryKeyStatus(Vector<uint8_t> const &sessionId, return -EINVAL; } DrmSessionManager::Instance()->useSession(sessionId); return mPlugin->queryKeyStatus(sessionId, infoMap); } Loading Loading @@ -561,6 +617,8 @@ status_t Drm::setCipherAlgorithm(Vector<uint8_t> const &sessionId, return -EINVAL; } DrmSessionManager::Instance()->useSession(sessionId); return mPlugin->setCipherAlgorithm(sessionId, algorithm); } Loading @@ -576,6 +634,8 @@ status_t Drm::setMacAlgorithm(Vector<uint8_t> const &sessionId, return -EINVAL; } DrmSessionManager::Instance()->useSession(sessionId); return mPlugin->setMacAlgorithm(sessionId, algorithm); } Loading @@ -594,6 +654,8 @@ status_t Drm::encrypt(Vector<uint8_t> const &sessionId, return -EINVAL; } DrmSessionManager::Instance()->useSession(sessionId); return mPlugin->encrypt(sessionId, keyId, input, iv, output); } Loading @@ -612,6 +674,8 @@ status_t Drm::decrypt(Vector<uint8_t> const &sessionId, return -EINVAL; } DrmSessionManager::Instance()->useSession(sessionId); return mPlugin->decrypt(sessionId, keyId, input, iv, output); } Loading @@ -629,6 +693,8 @@ status_t Drm::sign(Vector<uint8_t> const &sessionId, return -EINVAL; } DrmSessionManager::Instance()->useSession(sessionId); return mPlugin->sign(sessionId, keyId, message, signature); } Loading @@ -647,6 +713,8 @@ status_t Drm::verify(Vector<uint8_t> const &sessionId, return -EINVAL; } DrmSessionManager::Instance()->useSession(sessionId); return mPlugin->verify(sessionId, keyId, message, signature, match); } Loading @@ -669,6 +737,8 @@ status_t Drm::signRSA(Vector<uint8_t> const &sessionId, return -EPERM; } DrmSessionManager::Instance()->useSession(sessionId); return mPlugin->signRSA(sessionId, algorithm, message, wrappedKey, signature); } Loading media/libmediaplayerservice/Drm.h +3 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ namespace android { struct DrmFactory; struct DrmPlugin; struct DrmSessionClientInterface; struct Drm : public BnDrm, public IBinder::DeathRecipient, Loading Loading @@ -138,6 +139,8 @@ private: status_t mInitCheck; sp<DrmSessionClientInterface> mDrmSessionClient; sp<IDrmClient> mListener; mutable Mutex mEventLock; mutable Mutex mNotifyLock; Loading media/libmediaplayerservice/DrmSessionManager.cpp +43 −13 Original line number Diff line number Diff line Loading @@ -23,6 +23,8 @@ #include "DrmSessionClientInterface.h" #include "ProcessInfoInterface.h" #include <binder/IPCThreadState.h> #include <binder/IProcessInfoService.h> #include <binder/IServiceManager.h> #include <unistd.h> #include <utils/String8.h> Loading @@ -39,12 +41,25 @@ static String8 GetSessionIdString(const Vector<uint8_t> &sessionId) { struct ProcessInfo : public ProcessInfoInterface { ProcessInfo() {} virtual int getPriority(int pid) { // TODO: implement // Get process state to determine priority. // According to the define of PROCESS_STATE_***, higher the value lower // the priority. So we will do a converting from state to priority here. return -1; virtual bool getPriority(int pid, int* priority) { sp<IBinder> binder = defaultServiceManager()->getService(String16("processinfo")); sp<IProcessInfoService> service = interface_cast<IProcessInfoService>(binder); size_t length = 1; int32_t states; status_t err = service->getProcessStatesFromPids(length, &pid, &states); if (err != OK) { ALOGE("getProcessStatesFromPids failed"); return false; } ALOGV("pid %d states %d", pid, states); if (states < 0) { return false; } // Use process state as the priority. Lower the value, higher the priority. *priority = states; return true; } protected: Loading @@ -66,6 +81,11 @@ bool isEqualSessionId(const Vector<uint8_t> &sessionId1, const Vector<uint8_t> & return true; } sp<DrmSessionManager> DrmSessionManager::Instance() { static sp<DrmSessionManager> drmSessionManager = new DrmSessionManager(); return drmSessionManager; } DrmSessionManager::DrmSessionManager() : mProcessInfo(new ProcessInfo()), mTime(0) {} Loading Loading @@ -155,15 +175,18 @@ bool DrmSessionManager::reclaimSession(int callingPid) { sp<DrmSessionClientInterface> drm; Vector<uint8_t> sessionId; { Mutex::Autolock lock(mLock); int callingPriority = mProcessInfo->getPriority(callingPid); int lowestPriorityPid; int lowestPriority; { Mutex::Autolock lock(mLock); int callingPriority; if (!mProcessInfo->getPriority(callingPid, &callingPriority)) { return false; } if (!getLowestPriority_l(&lowestPriorityPid, &lowestPriority)) { return false; } if (lowestPriority >= callingPriority) { if (lowestPriority <= callingPriority) { return false; } Loading @@ -176,6 +199,9 @@ bool DrmSessionManager::reclaimSession(int callingPid) { return false; } ALOGV("reclaim session(%s) opened by pid %d", GetSessionIdString(sessionId).string(), lowestPriorityPid); return drm->reclaimSession(sessionId); } Loading @@ -185,19 +211,23 @@ int64_t DrmSessionManager::getTime_l() { bool DrmSessionManager::getLowestPriority_l(int* lowestPriorityPid, int* lowestPriority) { int pid = -1; int priority = INT_MAX; int priority = -1; for (size_t i = 0; i < mSessionMap.size(); ++i) { if (mSessionMap.valueAt(i).size() == 0) { // no opened session by this process. continue; } int tempPid = mSessionMap.keyAt(i); int tempPriority = mProcessInfo->getPriority(tempPid); int tempPriority; if (!mProcessInfo->getPriority(tempPid, &tempPriority)) { // shouldn't happen. return false; } if (pid == -1) { pid = tempPid; priority = tempPriority; } else { if (tempPriority < priority) { if (tempPriority > priority) { pid = tempPid; priority = tempPriority; } Loading media/libmediaplayerservice/DrmSessionManager.h +2 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,8 @@ typedef Vector<SessionInfo > SessionInfos; typedef KeyedVector<int, SessionInfos > PidSessionInfosMap; struct DrmSessionManager : public RefBase { static sp<DrmSessionManager> Instance(); DrmSessionManager(); DrmSessionManager(sp<ProcessInfoInterface> processInfo); Loading media/libmediaplayerservice/ProcessInfoInterface.h +1 −1 Original line number Diff line number Diff line Loading @@ -22,7 +22,7 @@ namespace android { struct ProcessInfoInterface : public RefBase { virtual int getPriority(int pid) = 0; virtual bool getPriority(int pid, int* priority) = 0; protected: virtual ~ProcessInfoInterface() {} Loading Loading
media/libmediaplayerservice/Drm.cpp +72 −2 Original line number Diff line number Diff line Loading @@ -23,6 +23,8 @@ #include "Drm.h" #include "DrmSessionClientInterface.h" #include "DrmSessionManager.h" #include <media/drm/DrmAPI.h> #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/AString.h> Loading @@ -33,6 +35,10 @@ namespace android { static inline int getCallingPid() { return IPCThreadState::self()->getCallingPid(); } static bool checkPermission(const char* permissionString) { #ifndef HAVE_ANDROID_OS return true; Loading @@ -57,14 +63,41 @@ static bool operator<(const Vector<uint8_t> &lhs, const Vector<uint8_t> &rhs) { return memcmp((void *)lhs.array(), (void *)rhs.array(), rhs.size()) < 0; } struct DrmSessionClient : public DrmSessionClientInterface { DrmSessionClient(Drm* drm) : mDrm(drm) {} virtual bool reclaimSession(const Vector<uint8_t>& sessionId) { sp<Drm> drm = mDrm.promote(); if (drm == NULL) { return true; } status_t err = drm->closeSession(sessionId); if (err != OK) { return false; } drm->sendEvent(DrmPlugin::kDrmPluginEventSessionReclaimed, 0, &sessionId, NULL); return true; } protected: virtual ~DrmSessionClient() {} private: wp<Drm> mDrm; DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient); }; Drm::Drm() : mInitCheck(NO_INIT), mDrmSessionClient(new DrmSessionClient(this)), mListener(NULL), mFactory(NULL), mPlugin(NULL) { } Drm::~Drm() { DrmSessionManager::Instance()->removeDrm(mDrmSessionClient); delete mPlugin; mPlugin = NULL; closeFactory(); Loading Loading @@ -289,7 +322,18 @@ status_t Drm::openSession(Vector<uint8_t> &sessionId) { return -EINVAL; } return mPlugin->openSession(sessionId); status_t err = mPlugin->openSession(sessionId); if (err == ERROR_DRM_RESOURCE_BUSY) { bool retry = false; retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid()); if (retry) { err = mPlugin->openSession(sessionId); } } if (err == OK) { DrmSessionManager::Instance()->addSession(getCallingPid(), mDrmSessionClient, sessionId); } return err; } status_t Drm::closeSession(Vector<uint8_t> const &sessionId) { Loading @@ -303,7 +347,11 @@ status_t Drm::closeSession(Vector<uint8_t> const &sessionId) { return -EINVAL; } return mPlugin->closeSession(sessionId); status_t err = mPlugin->closeSession(sessionId); if (err == OK) { DrmSessionManager::Instance()->removeSession(sessionId); } return err; } status_t Drm::getKeyRequest(Vector<uint8_t> const &sessionId, Loading @@ -321,6 +369,8 @@ status_t Drm::getKeyRequest(Vector<uint8_t> const &sessionId, return -EINVAL; } DrmSessionManager::Instance()->useSession(sessionId); return mPlugin->getKeyRequest(sessionId, initData, mimeType, keyType, optionalParameters, request, defaultUrl); } Loading @@ -338,6 +388,8 @@ status_t Drm::provideKeyResponse(Vector<uint8_t> const &sessionId, return -EINVAL; } DrmSessionManager::Instance()->useSession(sessionId); return mPlugin->provideKeyResponse(sessionId, response, keySetId); } Loading Loading @@ -367,6 +419,8 @@ status_t Drm::restoreKeys(Vector<uint8_t> const &sessionId, return -EINVAL; } DrmSessionManager::Instance()->useSession(sessionId); return mPlugin->restoreKeys(sessionId, keySetId); } Loading @@ -382,6 +436,8 @@ status_t Drm::queryKeyStatus(Vector<uint8_t> const &sessionId, return -EINVAL; } DrmSessionManager::Instance()->useSession(sessionId); return mPlugin->queryKeyStatus(sessionId, infoMap); } Loading Loading @@ -561,6 +617,8 @@ status_t Drm::setCipherAlgorithm(Vector<uint8_t> const &sessionId, return -EINVAL; } DrmSessionManager::Instance()->useSession(sessionId); return mPlugin->setCipherAlgorithm(sessionId, algorithm); } Loading @@ -576,6 +634,8 @@ status_t Drm::setMacAlgorithm(Vector<uint8_t> const &sessionId, return -EINVAL; } DrmSessionManager::Instance()->useSession(sessionId); return mPlugin->setMacAlgorithm(sessionId, algorithm); } Loading @@ -594,6 +654,8 @@ status_t Drm::encrypt(Vector<uint8_t> const &sessionId, return -EINVAL; } DrmSessionManager::Instance()->useSession(sessionId); return mPlugin->encrypt(sessionId, keyId, input, iv, output); } Loading @@ -612,6 +674,8 @@ status_t Drm::decrypt(Vector<uint8_t> const &sessionId, return -EINVAL; } DrmSessionManager::Instance()->useSession(sessionId); return mPlugin->decrypt(sessionId, keyId, input, iv, output); } Loading @@ -629,6 +693,8 @@ status_t Drm::sign(Vector<uint8_t> const &sessionId, return -EINVAL; } DrmSessionManager::Instance()->useSession(sessionId); return mPlugin->sign(sessionId, keyId, message, signature); } Loading @@ -647,6 +713,8 @@ status_t Drm::verify(Vector<uint8_t> const &sessionId, return -EINVAL; } DrmSessionManager::Instance()->useSession(sessionId); return mPlugin->verify(sessionId, keyId, message, signature, match); } Loading @@ -669,6 +737,8 @@ status_t Drm::signRSA(Vector<uint8_t> const &sessionId, return -EPERM; } DrmSessionManager::Instance()->useSession(sessionId); return mPlugin->signRSA(sessionId, algorithm, message, wrappedKey, signature); } Loading
media/libmediaplayerservice/Drm.h +3 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ namespace android { struct DrmFactory; struct DrmPlugin; struct DrmSessionClientInterface; struct Drm : public BnDrm, public IBinder::DeathRecipient, Loading Loading @@ -138,6 +139,8 @@ private: status_t mInitCheck; sp<DrmSessionClientInterface> mDrmSessionClient; sp<IDrmClient> mListener; mutable Mutex mEventLock; mutable Mutex mNotifyLock; Loading
media/libmediaplayerservice/DrmSessionManager.cpp +43 −13 Original line number Diff line number Diff line Loading @@ -23,6 +23,8 @@ #include "DrmSessionClientInterface.h" #include "ProcessInfoInterface.h" #include <binder/IPCThreadState.h> #include <binder/IProcessInfoService.h> #include <binder/IServiceManager.h> #include <unistd.h> #include <utils/String8.h> Loading @@ -39,12 +41,25 @@ static String8 GetSessionIdString(const Vector<uint8_t> &sessionId) { struct ProcessInfo : public ProcessInfoInterface { ProcessInfo() {} virtual int getPriority(int pid) { // TODO: implement // Get process state to determine priority. // According to the define of PROCESS_STATE_***, higher the value lower // the priority. So we will do a converting from state to priority here. return -1; virtual bool getPriority(int pid, int* priority) { sp<IBinder> binder = defaultServiceManager()->getService(String16("processinfo")); sp<IProcessInfoService> service = interface_cast<IProcessInfoService>(binder); size_t length = 1; int32_t states; status_t err = service->getProcessStatesFromPids(length, &pid, &states); if (err != OK) { ALOGE("getProcessStatesFromPids failed"); return false; } ALOGV("pid %d states %d", pid, states); if (states < 0) { return false; } // Use process state as the priority. Lower the value, higher the priority. *priority = states; return true; } protected: Loading @@ -66,6 +81,11 @@ bool isEqualSessionId(const Vector<uint8_t> &sessionId1, const Vector<uint8_t> & return true; } sp<DrmSessionManager> DrmSessionManager::Instance() { static sp<DrmSessionManager> drmSessionManager = new DrmSessionManager(); return drmSessionManager; } DrmSessionManager::DrmSessionManager() : mProcessInfo(new ProcessInfo()), mTime(0) {} Loading Loading @@ -155,15 +175,18 @@ bool DrmSessionManager::reclaimSession(int callingPid) { sp<DrmSessionClientInterface> drm; Vector<uint8_t> sessionId; { Mutex::Autolock lock(mLock); int callingPriority = mProcessInfo->getPriority(callingPid); int lowestPriorityPid; int lowestPriority; { Mutex::Autolock lock(mLock); int callingPriority; if (!mProcessInfo->getPriority(callingPid, &callingPriority)) { return false; } if (!getLowestPriority_l(&lowestPriorityPid, &lowestPriority)) { return false; } if (lowestPriority >= callingPriority) { if (lowestPriority <= callingPriority) { return false; } Loading @@ -176,6 +199,9 @@ bool DrmSessionManager::reclaimSession(int callingPid) { return false; } ALOGV("reclaim session(%s) opened by pid %d", GetSessionIdString(sessionId).string(), lowestPriorityPid); return drm->reclaimSession(sessionId); } Loading @@ -185,19 +211,23 @@ int64_t DrmSessionManager::getTime_l() { bool DrmSessionManager::getLowestPriority_l(int* lowestPriorityPid, int* lowestPriority) { int pid = -1; int priority = INT_MAX; int priority = -1; for (size_t i = 0; i < mSessionMap.size(); ++i) { if (mSessionMap.valueAt(i).size() == 0) { // no opened session by this process. continue; } int tempPid = mSessionMap.keyAt(i); int tempPriority = mProcessInfo->getPriority(tempPid); int tempPriority; if (!mProcessInfo->getPriority(tempPid, &tempPriority)) { // shouldn't happen. return false; } if (pid == -1) { pid = tempPid; priority = tempPriority; } else { if (tempPriority < priority) { if (tempPriority > priority) { pid = tempPid; priority = tempPriority; } Loading
media/libmediaplayerservice/DrmSessionManager.h +2 −0 Original line number Diff line number Diff line Loading @@ -42,6 +42,8 @@ typedef Vector<SessionInfo > SessionInfos; typedef KeyedVector<int, SessionInfos > PidSessionInfosMap; struct DrmSessionManager : public RefBase { static sp<DrmSessionManager> Instance(); DrmSessionManager(); DrmSessionManager(sp<ProcessInfoInterface> processInfo); Loading
media/libmediaplayerservice/ProcessInfoInterface.h +1 −1 Original line number Diff line number Diff line Loading @@ -22,7 +22,7 @@ namespace android { struct ProcessInfoInterface : public RefBase { virtual int getPriority(int pid) = 0; virtual bool getPriority(int pid, int* priority) = 0; protected: virtual ~ProcessInfoInterface() {} Loading