110305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu/*
210305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu * Copyright (C) 2015 The Android Open Source Project
310305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu *
410305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu * Licensed under the Apache License, Version 2.0 (the "License");
510305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu * you may not use this file except in compliance with the License.
610305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu * You may obtain a copy of the License at
710305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu *
810305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu *      http://www.apache.org/licenses/LICENSE-2.0
910305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu *
1010305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu * Unless required by applicable law or agreed to in writing, software
1110305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu * distributed under the License is distributed on an "AS IS" BASIS,
1210305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1310305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu * See the License for the specific language governing permissions and
1410305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu * limitations under the License.
1510305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu */
1610305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu
1710305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu//#define LOG_NDEBUG 0
1810305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu#define LOG_TAG "DrmSessionManager"
1910305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu#include <utils/Log.h>
2010305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu
2110305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu#include <binder/IPCThreadState.h>
225c3da20ddde6d17c3ab3cff7f7ca19f4f484f812Ronghua Wu#include <binder/IProcessInfoService.h>
235c3da20ddde6d17c3ab3cff7f7ca19f4f484f812Ronghua Wu#include <binder/IServiceManager.h>
243003807fcfa96c9cbfea18d643f47108aa116cd5Jeff Tinker#include <media/DrmSessionManager.h>
253003807fcfa96c9cbfea18d643f47108aa116cd5Jeff Tinker#include <media/DrmSessionClientInterface.h>
2614bcacaed718a506f59e8f3af66e9e0137789da6Ronghua Wu#include <media/stagefright/ProcessInfo.h>
2710305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu#include <unistd.h>
2810305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu#include <utils/String8.h>
2910305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu
3010305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wunamespace android {
3110305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu
3210305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wustatic String8 GetSessionIdString(const Vector<uint8_t> &sessionId) {
3310305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    String8 sessionIdStr;
3410305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    for (size_t i = 0; i < sessionId.size(); ++i) {
3510305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu        sessionIdStr.appendFormat("%u ", sessionId[i]);
3610305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    }
3710305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    return sessionIdStr;
3810305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu}
3910305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu
4010305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wubool isEqualSessionId(const Vector<uint8_t> &sessionId1, const Vector<uint8_t> &sessionId2) {
4110305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    if (sessionId1.size() != sessionId2.size()) {
4210305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu        return false;
4310305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    }
4410305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    for (size_t i = 0; i < sessionId1.size(); ++i) {
4510305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu        if (sessionId1[i] != sessionId2[i]) {
4610305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu            return false;
4710305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu        }
4810305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    }
4910305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    return true;
5010305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu}
5110305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu
525c3da20ddde6d17c3ab3cff7f7ca19f4f484f812Ronghua Wusp<DrmSessionManager> DrmSessionManager::Instance() {
535c3da20ddde6d17c3ab3cff7f7ca19f4f484f812Ronghua Wu    static sp<DrmSessionManager> drmSessionManager = new DrmSessionManager();
545c3da20ddde6d17c3ab3cff7f7ca19f4f484f812Ronghua Wu    return drmSessionManager;
555c3da20ddde6d17c3ab3cff7f7ca19f4f484f812Ronghua Wu}
565c3da20ddde6d17c3ab3cff7f7ca19f4f484f812Ronghua Wu
5710305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua WuDrmSessionManager::DrmSessionManager()
5810305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    : mProcessInfo(new ProcessInfo()),
5910305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu      mTime(0) {}
6010305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu
6110305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua WuDrmSessionManager::DrmSessionManager(sp<ProcessInfoInterface> processInfo)
6210305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    : mProcessInfo(processInfo),
6310305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu      mTime(0) {}
6410305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu
6510305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua WuDrmSessionManager::~DrmSessionManager() {}
6610305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu
6710305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wuvoid DrmSessionManager::addSession(
688c0164ca98bcc76f3656fb1078033bffd4a387deChih-Hung Hsieh        int pid, const sp<DrmSessionClientInterface>& drm, const Vector<uint8_t> &sessionId) {
6910305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    ALOGV("addSession(pid %d, drm %p, sessionId %s)", pid, drm.get(),
7010305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu            GetSessionIdString(sessionId).string());
7110305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu
7210305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    Mutex::Autolock lock(mLock);
7310305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    SessionInfo info;
7410305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    info.drm = drm;
7510305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    info.sessionId = sessionId;
7610305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    info.timeStamp = getTime_l();
7710305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    ssize_t index = mSessionMap.indexOfKey(pid);
7810305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    if (index < 0) {
7910305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu        // new pid
8010305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu        SessionInfos infosForPid;
8110305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu        infosForPid.push_back(info);
8210305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu        mSessionMap.add(pid, infosForPid);
8310305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    } else {
8410305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu        mSessionMap.editValueAt(index).push_back(info);
8510305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    }
8610305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu}
8710305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu
8810305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wuvoid DrmSessionManager::useSession(const Vector<uint8_t> &sessionId) {
8910305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    ALOGV("useSession(%s)", GetSessionIdString(sessionId).string());
9010305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu
9110305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    Mutex::Autolock lock(mLock);
9210305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    for (size_t i = 0; i < mSessionMap.size(); ++i) {
9310305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu        SessionInfos& infos = mSessionMap.editValueAt(i);
9410305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu        for (size_t j = 0; j < infos.size(); ++j) {
9510305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu            SessionInfo& info = infos.editItemAt(j);
9610305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu            if (isEqualSessionId(sessionId, info.sessionId)) {
9710305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu                info.timeStamp = getTime_l();
9810305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu                return;
9910305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu            }
10010305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu        }
10110305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    }
10210305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu}
10310305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu
10410305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wuvoid DrmSessionManager::removeSession(const Vector<uint8_t> &sessionId) {
10510305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    ALOGV("removeSession(%s)", GetSessionIdString(sessionId).string());
10610305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu
10710305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    Mutex::Autolock lock(mLock);
10810305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    for (size_t i = 0; i < mSessionMap.size(); ++i) {
10910305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu        SessionInfos& infos = mSessionMap.editValueAt(i);
11010305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu        for (size_t j = 0; j < infos.size(); ++j) {
11110305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu            if (isEqualSessionId(sessionId, infos[j].sessionId)) {
11210305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu                infos.removeAt(j);
11310305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu                return;
11410305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu            }
11510305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu        }
11610305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    }
11710305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu}
11810305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu
1198c0164ca98bcc76f3656fb1078033bffd4a387deChih-Hung Hsiehvoid DrmSessionManager::removeDrm(const sp<DrmSessionClientInterface>& drm) {
12010305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    ALOGV("removeDrm(%p)", drm.get());
12110305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu
12210305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    Mutex::Autolock lock(mLock);
12310305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    bool found = false;
12410305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    for (size_t i = 0; i < mSessionMap.size(); ++i) {
12510305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu        SessionInfos& infos = mSessionMap.editValueAt(i);
12610305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu        for (size_t j = 0; j < infos.size();) {
12710305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu            if (infos[j].drm == drm) {
12810305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu                ALOGV("removed session (%s)", GetSessionIdString(infos[j].sessionId).string());
12910305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu                j = infos.removeAt(j);
13010305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu                found = true;
13110305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu            } else {
13210305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu                ++j;
13310305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu            }
13410305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu        }
13510305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu        if (found) {
13610305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu            break;
13710305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu        }
13810305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    }
13910305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu}
14010305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu
14110305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wubool DrmSessionManager::reclaimSession(int callingPid) {
14210305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    ALOGV("reclaimSession(%d)", callingPid);
14310305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu
14410305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    sp<DrmSessionClientInterface> drm;
14510305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    Vector<uint8_t> sessionId;
1465c3da20ddde6d17c3ab3cff7f7ca19f4f484f812Ronghua Wu    int lowestPriorityPid;
1475c3da20ddde6d17c3ab3cff7f7ca19f4f484f812Ronghua Wu    int lowestPriority;
14810305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    {
14910305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu        Mutex::Autolock lock(mLock);
1505c3da20ddde6d17c3ab3cff7f7ca19f4f484f812Ronghua Wu        int callingPriority;
1515c3da20ddde6d17c3ab3cff7f7ca19f4f484f812Ronghua Wu        if (!mProcessInfo->getPriority(callingPid, &callingPriority)) {
1525c3da20ddde6d17c3ab3cff7f7ca19f4f484f812Ronghua Wu            return false;
1535c3da20ddde6d17c3ab3cff7f7ca19f4f484f812Ronghua Wu        }
15410305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu        if (!getLowestPriority_l(&lowestPriorityPid, &lowestPriority)) {
15510305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu            return false;
15610305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu        }
1575c3da20ddde6d17c3ab3cff7f7ca19f4f484f812Ronghua Wu        if (lowestPriority <= callingPriority) {
15810305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu            return false;
15910305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu        }
16010305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu
16110305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu        if (!getLeastUsedSession_l(lowestPriorityPid, &drm, &sessionId)) {
16210305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu            return false;
16310305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu        }
16410305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    }
16510305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu
16610305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    if (drm == NULL) {
16710305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu        return false;
16810305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    }
16910305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu
1705c3da20ddde6d17c3ab3cff7f7ca19f4f484f812Ronghua Wu    ALOGV("reclaim session(%s) opened by pid %d",
1715c3da20ddde6d17c3ab3cff7f7ca19f4f484f812Ronghua Wu            GetSessionIdString(sessionId).string(), lowestPriorityPid);
1725c3da20ddde6d17c3ab3cff7f7ca19f4f484f812Ronghua Wu
17310305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    return drm->reclaimSession(sessionId);
17410305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu}
17510305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu
17610305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wuint64_t DrmSessionManager::getTime_l() {
17710305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    return mTime++;
17810305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu}
17910305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu
18010305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wubool DrmSessionManager::getLowestPriority_l(int* lowestPriorityPid, int* lowestPriority) {
18110305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    int pid = -1;
1825c3da20ddde6d17c3ab3cff7f7ca19f4f484f812Ronghua Wu    int priority = -1;
18310305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    for (size_t i = 0; i < mSessionMap.size(); ++i) {
18410305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu        if (mSessionMap.valueAt(i).size() == 0) {
18510305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu            // no opened session by this process.
18610305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu            continue;
18710305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu        }
18810305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu        int tempPid = mSessionMap.keyAt(i);
1895c3da20ddde6d17c3ab3cff7f7ca19f4f484f812Ronghua Wu        int tempPriority;
1905c3da20ddde6d17c3ab3cff7f7ca19f4f484f812Ronghua Wu        if (!mProcessInfo->getPriority(tempPid, &tempPriority)) {
1915c3da20ddde6d17c3ab3cff7f7ca19f4f484f812Ronghua Wu            // shouldn't happen.
1925c3da20ddde6d17c3ab3cff7f7ca19f4f484f812Ronghua Wu            return false;
1935c3da20ddde6d17c3ab3cff7f7ca19f4f484f812Ronghua Wu        }
19410305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu        if (pid == -1) {
19510305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu            pid = tempPid;
19610305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu            priority = tempPriority;
19710305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu        } else {
1985c3da20ddde6d17c3ab3cff7f7ca19f4f484f812Ronghua Wu            if (tempPriority > priority) {
19910305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu                pid = tempPid;
20010305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu                priority = tempPriority;
20110305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu            }
20210305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu        }
20310305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    }
20410305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    if (pid != -1) {
20510305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu        *lowestPriorityPid = pid;
20610305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu        *lowestPriority = priority;
20710305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    }
20810305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    return (pid != -1);
20910305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu}
21010305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu
21110305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wubool DrmSessionManager::getLeastUsedSession_l(
21210305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu        int pid, sp<DrmSessionClientInterface>* drm, Vector<uint8_t>* sessionId) {
21310305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    ssize_t index = mSessionMap.indexOfKey(pid);
21410305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    if (index < 0) {
21510305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu        return false;
21610305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    }
21710305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu
21810305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    int leastUsedIndex = -1;
21910305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    int64_t minTs = LLONG_MAX;
22010305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    const SessionInfos& infos = mSessionMap.valueAt(index);
22110305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    for (size_t j = 0; j < infos.size(); ++j) {
22210305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu        if (leastUsedIndex == -1) {
22310305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu            leastUsedIndex = j;
22410305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu            minTs = infos[j].timeStamp;
22510305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu        } else {
22610305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu            if (infos[j].timeStamp < minTs) {
22710305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu                leastUsedIndex = j;
22810305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu                minTs = infos[j].timeStamp;
22910305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu            }
23010305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu        }
23110305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    }
23210305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    if (leastUsedIndex != -1) {
23310305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu        *drm = infos[leastUsedIndex].drm;
23410305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu        *sessionId = infos[leastUsedIndex].sessionId;
23510305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    }
23610305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu    return (leastUsedIndex != -1);
23710305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu}
23810305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu
23910305cc672dcb39b7cc7dc03eeafffb2fea150ecRonghua Wu}  // namespace android
240