summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorRonghua Wu <ronghuawu@google.com>2015-03-09 22:17:35 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2015-03-09 22:17:37 +0000
commitd4164c3a1a209fd470c2f3aac09c1ce2dc319c8b (patch)
treeaf3558c066450d0c0ade9068a4035772cdbf3c43 /media
parent64c4e0264a5fb1bf4700b85668d0fb50146f28e9 (diff)
parent5c3da20ddde6d17c3ab3cff7f7ca19f4f484f812 (diff)
downloadframeworks_av-d4164c3a1a209fd470c2f3aac09c1ce2dc319c8b.zip
frameworks_av-d4164c3a1a209fd470c2f3aac09c1ce2dc319c8b.tar.gz
frameworks_av-d4164c3a1a209fd470c2f3aac09c1ce2dc319c8b.tar.bz2
Merge "drm: use DrmSessionManager for session resource managing."
Diffstat (limited to 'media')
-rw-r--r--media/libmediaplayerservice/Drm.cpp74
-rw-r--r--media/libmediaplayerservice/Drm.h3
-rw-r--r--media/libmediaplayerservice/DrmSessionManager.cpp56
-rw-r--r--media/libmediaplayerservice/DrmSessionManager.h2
-rw-r--r--media/libmediaplayerservice/ProcessInfoInterface.h2
-rw-r--r--media/libmediaplayerservice/tests/DrmSessionManager_test.cpp21
6 files changed, 135 insertions, 23 deletions
diff --git a/media/libmediaplayerservice/Drm.cpp b/media/libmediaplayerservice/Drm.cpp
index 73f1a2a..d4f6fab 100644
--- a/media/libmediaplayerservice/Drm.cpp
+++ b/media/libmediaplayerservice/Drm.cpp
@@ -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>
@@ -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;
@@ -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();
@@ -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) {
@@ -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,
@@ -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);
}
@@ -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);
}
@@ -367,6 +419,8 @@ status_t Drm::restoreKeys(Vector<uint8_t> const &sessionId,
return -EINVAL;
}
+ DrmSessionManager::Instance()->useSession(sessionId);
+
return mPlugin->restoreKeys(sessionId, keySetId);
}
@@ -382,6 +436,8 @@ status_t Drm::queryKeyStatus(Vector<uint8_t> const &sessionId,
return -EINVAL;
}
+ DrmSessionManager::Instance()->useSession(sessionId);
+
return mPlugin->queryKeyStatus(sessionId, infoMap);
}
@@ -561,6 +617,8 @@ status_t Drm::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
return -EINVAL;
}
+ DrmSessionManager::Instance()->useSession(sessionId);
+
return mPlugin->setCipherAlgorithm(sessionId, algorithm);
}
@@ -576,6 +634,8 @@ status_t Drm::setMacAlgorithm(Vector<uint8_t> const &sessionId,
return -EINVAL;
}
+ DrmSessionManager::Instance()->useSession(sessionId);
+
return mPlugin->setMacAlgorithm(sessionId, algorithm);
}
@@ -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);
}
@@ -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);
}
@@ -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);
}
@@ -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);
}
@@ -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);
}
diff --git a/media/libmediaplayerservice/Drm.h b/media/libmediaplayerservice/Drm.h
index 0e1eb2c..0cea639 100644
--- a/media/libmediaplayerservice/Drm.h
+++ b/media/libmediaplayerservice/Drm.h
@@ -28,6 +28,7 @@ namespace android {
struct DrmFactory;
struct DrmPlugin;
+struct DrmSessionClientInterface;
struct Drm : public BnDrm,
public IBinder::DeathRecipient,
@@ -138,6 +139,8 @@ private:
status_t mInitCheck;
+ sp<DrmSessionClientInterface> mDrmSessionClient;
+
sp<IDrmClient> mListener;
mutable Mutex mEventLock;
mutable Mutex mNotifyLock;
diff --git a/media/libmediaplayerservice/DrmSessionManager.cpp b/media/libmediaplayerservice/DrmSessionManager.cpp
index 43346e0..6e17eb1 100644
--- a/media/libmediaplayerservice/DrmSessionManager.cpp
+++ b/media/libmediaplayerservice/DrmSessionManager.cpp
@@ -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>
@@ -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:
@@ -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) {}
@@ -155,15 +175,18 @@ bool DrmSessionManager::reclaimSession(int callingPid) {
sp<DrmSessionClientInterface> drm;
Vector<uint8_t> sessionId;
+ int lowestPriorityPid;
+ int lowestPriority;
{
Mutex::Autolock lock(mLock);
- int callingPriority = mProcessInfo->getPriority(callingPid);
- int lowestPriorityPid;
- int lowestPriority;
+ int callingPriority;
+ if (!mProcessInfo->getPriority(callingPid, &callingPriority)) {
+ return false;
+ }
if (!getLowestPriority_l(&lowestPriorityPid, &lowestPriority)) {
return false;
}
- if (lowestPriority >= callingPriority) {
+ if (lowestPriority <= callingPriority) {
return false;
}
@@ -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);
}
@@ -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;
}
diff --git a/media/libmediaplayerservice/DrmSessionManager.h b/media/libmediaplayerservice/DrmSessionManager.h
index 1d0ed43..ba5c268 100644
--- a/media/libmediaplayerservice/DrmSessionManager.h
+++ b/media/libmediaplayerservice/DrmSessionManager.h
@@ -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);
diff --git a/media/libmediaplayerservice/ProcessInfoInterface.h b/media/libmediaplayerservice/ProcessInfoInterface.h
index bdcc1da..222f92d 100644
--- a/media/libmediaplayerservice/ProcessInfoInterface.h
+++ b/media/libmediaplayerservice/ProcessInfoInterface.h
@@ -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() {}
diff --git a/media/libmediaplayerservice/tests/DrmSessionManager_test.cpp b/media/libmediaplayerservice/tests/DrmSessionManager_test.cpp
index fa002b8..27b482b 100644
--- a/media/libmediaplayerservice/tests/DrmSessionManager_test.cpp
+++ b/media/libmediaplayerservice/tests/DrmSessionManager_test.cpp
@@ -32,7 +32,12 @@ struct FakeProcessInfo : public ProcessInfoInterface {
FakeProcessInfo() {}
virtual ~FakeProcessInfo() {}
- virtual int getPriority(int pid) { return pid; }
+ virtual bool getPriority(int pid, int* priority) {
+ // For testing, use pid as priority.
+ // Lower the value higher the priority.
+ *priority = pid;
+ return true;
+ }
private:
DISALLOW_EVIL_CONSTRUCTORS(FakeProcessInfo);
@@ -57,7 +62,7 @@ private:
DISALLOW_EVIL_CONSTRUCTORS(FakeDrm);
};
-static const int kTestPid1 = 10;
+static const int kTestPid1 = 30;
static const int kTestPid2 = 20;
static const uint8_t kTestSessionId1[] = {1, 2, 3};
static const uint8_t kTestSessionId2[] = {4, 5, 6, 7, 8};
@@ -122,7 +127,9 @@ protected:
EXPECT_EQ(kTestPid1, pid);
FakeProcessInfo processInfo;
- EXPECT_EQ(processInfo.getPriority(kTestPid1), priority);
+ int priority1;
+ processInfo.getPriority(kTestPid1, &priority1);
+ EXPECT_EQ(priority1, priority);
}
void testGetLeastUsedSession() {
@@ -210,9 +217,9 @@ TEST_F(DrmSessionManagerTest, reclaimSession) {
addSession();
// calling pid priority is too low
- EXPECT_FALSE(mDrmSessionManager->reclaimSession(5));
+ EXPECT_FALSE(mDrmSessionManager->reclaimSession(50));
- EXPECT_TRUE(mDrmSessionManager->reclaimSession(30));
+ EXPECT_TRUE(mDrmSessionManager->reclaimSession(10));
EXPECT_EQ(1, mTestDrm1->reclaimedSessions().size());
EXPECT_TRUE(isEqualSessionId(mSessionId1, mTestDrm1->reclaimedSessions()[0]));
@@ -223,9 +230,9 @@ TEST_F(DrmSessionManagerTest, reclaimSession) {
const uint8_t ids[] = {1, 3, 5};
Vector<uint8_t> sessionId;
GetSessionId(ids, ARRAY_SIZE(ids), &sessionId);
- mDrmSessionManager->addSession(30, drm, sessionId);
+ mDrmSessionManager->addSession(15, drm, sessionId);
- EXPECT_TRUE(mDrmSessionManager->reclaimSession(40));
+ EXPECT_TRUE(mDrmSessionManager->reclaimSession(18));
EXPECT_EQ(1, mTestDrm2->reclaimedSessions().size());
// mSessionId2 is reclaimed.
EXPECT_TRUE(isEqualSessionId(mSessionId2, mTestDrm2->reclaimedSessions()[0]));