diff --git a/media/libmediaplayerservice/DrmSessionManager.cpp b/media/libmediaplayerservice/DrmSessionManager.cpp
new file mode 100644
index 0000000..43346e0
--- /dev/null
+++ b/media/libmediaplayerservice/DrmSessionManager.cpp
@@ -0,0 +1,241 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "DrmSessionManager"
+#include <utils/Log.h>
+
+#include "DrmSessionManager.h"
+
+#include "DrmSessionClientInterface.h"
+#include "ProcessInfoInterface.h"
+#include <binder/IPCThreadState.h>
+#include <unistd.h>
+#include <utils/String8.h>
+
+namespace android {
+
+static String8 GetSessionIdString(const Vector<uint8_t> &sessionId) {
+    String8 sessionIdStr;
+    for (size_t i = 0; i < sessionId.size(); ++i) {
+        sessionIdStr.appendFormat("%u ", sessionId[i]);
+    }
+    return sessionIdStr;
+}
+
+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;
+    }
+
+protected:
+    virtual ~ProcessInfo() {}
+
+private:
+    DISALLOW_EVIL_CONSTRUCTORS(ProcessInfo);
+};
+
+bool isEqualSessionId(const Vector<uint8_t> &sessionId1, const Vector<uint8_t> &sessionId2) {
+    if (sessionId1.size() != sessionId2.size()) {
+        return false;
+    }
+    for (size_t i = 0; i < sessionId1.size(); ++i) {
+        if (sessionId1[i] != sessionId2[i]) {
+            return false;
+        }
+    }
+    return true;
+}
+
+DrmSessionManager::DrmSessionManager()
+    : mProcessInfo(new ProcessInfo()),
+      mTime(0) {}
+
+DrmSessionManager::DrmSessionManager(sp<ProcessInfoInterface> processInfo)
+    : mProcessInfo(processInfo),
+      mTime(0) {}
+
+DrmSessionManager::~DrmSessionManager() {}
+
+void DrmSessionManager::addSession(
+        int pid, sp<DrmSessionClientInterface> drm, const Vector<uint8_t> &sessionId) {
+    ALOGV("addSession(pid %d, drm %p, sessionId %s)", pid, drm.get(),
+            GetSessionIdString(sessionId).string());
+
+    Mutex::Autolock lock(mLock);
+    SessionInfo info;
+    info.drm = drm;
+    info.sessionId = sessionId;
+    info.timeStamp = getTime_l();
+    ssize_t index = mSessionMap.indexOfKey(pid);
+    if (index < 0) {
+        // new pid
+        SessionInfos infosForPid;
+        infosForPid.push_back(info);
+        mSessionMap.add(pid, infosForPid);
+    } else {
+        mSessionMap.editValueAt(index).push_back(info);
+    }
+}
+
+void DrmSessionManager::useSession(const Vector<uint8_t> &sessionId) {
+    ALOGV("useSession(%s)", GetSessionIdString(sessionId).string());
+
+    Mutex::Autolock lock(mLock);
+    for (size_t i = 0; i < mSessionMap.size(); ++i) {
+        SessionInfos& infos = mSessionMap.editValueAt(i);
+        for (size_t j = 0; j < infos.size(); ++j) {
+            SessionInfo& info = infos.editItemAt(j);
+            if (isEqualSessionId(sessionId, info.sessionId)) {
+                info.timeStamp = getTime_l();
+                return;
+            }
+        }
+    }
+}
+
+void DrmSessionManager::removeSession(const Vector<uint8_t> &sessionId) {
+    ALOGV("removeSession(%s)", GetSessionIdString(sessionId).string());
+
+    Mutex::Autolock lock(mLock);
+    for (size_t i = 0; i < mSessionMap.size(); ++i) {
+        SessionInfos& infos = mSessionMap.editValueAt(i);
+        for (size_t j = 0; j < infos.size(); ++j) {
+            if (isEqualSessionId(sessionId, infos[j].sessionId)) {
+                infos.removeAt(j);
+                return;
+            }
+        }
+    }
+}
+
+void DrmSessionManager::removeDrm(sp<DrmSessionClientInterface> drm) {
+    ALOGV("removeDrm(%p)", drm.get());
+
+    Mutex::Autolock lock(mLock);
+    bool found = false;
+    for (size_t i = 0; i < mSessionMap.size(); ++i) {
+        SessionInfos& infos = mSessionMap.editValueAt(i);
+        for (size_t j = 0; j < infos.size();) {
+            if (infos[j].drm == drm) {
+                ALOGV("removed session (%s)", GetSessionIdString(infos[j].sessionId).string());
+                j = infos.removeAt(j);
+                found = true;
+            } else {
+                ++j;
+            }
+        }
+        if (found) {
+            break;
+        }
+    }
+}
+
+bool DrmSessionManager::reclaimSession(int callingPid) {
+    ALOGV("reclaimSession(%d)", callingPid);
+
+    sp<DrmSessionClientInterface> drm;
+    Vector<uint8_t> sessionId;
+    {
+        Mutex::Autolock lock(mLock);
+        int callingPriority = mProcessInfo->getPriority(callingPid);
+        int lowestPriorityPid;
+        int lowestPriority;
+        if (!getLowestPriority_l(&lowestPriorityPid, &lowestPriority)) {
+            return false;
+        }
+        if (lowestPriority >= callingPriority) {
+            return false;
+        }
+
+        if (!getLeastUsedSession_l(lowestPriorityPid, &drm, &sessionId)) {
+            return false;
+        }
+    }
+
+    if (drm == NULL) {
+        return false;
+    }
+
+    return drm->reclaimSession(sessionId);
+}
+
+int64_t DrmSessionManager::getTime_l() {
+    return mTime++;
+}
+
+bool DrmSessionManager::getLowestPriority_l(int* lowestPriorityPid, int* lowestPriority) {
+    int pid = -1;
+    int priority = INT_MAX;
+    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);
+        if (pid == -1) {
+            pid = tempPid;
+            priority = tempPriority;
+        } else {
+            if (tempPriority < priority) {
+                pid = tempPid;
+                priority = tempPriority;
+            }
+        }
+    }
+    if (pid != -1) {
+        *lowestPriorityPid = pid;
+        *lowestPriority = priority;
+    }
+    return (pid != -1);
+}
+
+bool DrmSessionManager::getLeastUsedSession_l(
+        int pid, sp<DrmSessionClientInterface>* drm, Vector<uint8_t>* sessionId) {
+    ssize_t index = mSessionMap.indexOfKey(pid);
+    if (index < 0) {
+        return false;
+    }
+
+    int leastUsedIndex = -1;
+    int64_t minTs = LLONG_MAX;
+    const SessionInfos& infos = mSessionMap.valueAt(index);
+    for (size_t j = 0; j < infos.size(); ++j) {
+        if (leastUsedIndex == -1) {
+            leastUsedIndex = j;
+            minTs = infos[j].timeStamp;
+        } else {
+            if (infos[j].timeStamp < minTs) {
+                leastUsedIndex = j;
+                minTs = infos[j].timeStamp;
+            }
+        }
+    }
+    if (leastUsedIndex != -1) {
+        *drm = infos[leastUsedIndex].drm;
+        *sessionId = infos[leastUsedIndex].sessionId;
+    }
+    return (leastUsedIndex != -1);
+}
+
+}  // namespace android
