DrmSessionManager_test.cpp revision 3003807fcfa96c9cbfea18d643f47108aa116cd5
1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//#define LOG_NDEBUG 0
18#define LOG_TAG "DrmSessionManager_test"
19#include <utils/Log.h>
20
21#include <gtest/gtest.h>
22
23#include <media/Drm.h>
24#include <media/DrmSessionClientInterface.h>
25#include <media/DrmSessionManager.h>
26#include <media/stagefright/foundation/ADebug.h>
27#include <media/stagefright/ProcessInfoInterface.h>
28
29namespace android {
30
31struct FakeProcessInfo : public ProcessInfoInterface {
32    FakeProcessInfo() {}
33    virtual ~FakeProcessInfo() {}
34
35    virtual bool getPriority(int pid, int* priority) {
36        // For testing, use pid as priority.
37        // Lower the value higher the priority.
38        *priority = pid;
39        return true;
40    }
41
42    virtual bool isValidPid(int /* pid */) {
43        return true;
44    }
45
46private:
47    DISALLOW_EVIL_CONSTRUCTORS(FakeProcessInfo);
48};
49
50struct FakeDrm : public DrmSessionClientInterface {
51    FakeDrm() {}
52    virtual ~FakeDrm() {}
53
54    virtual bool reclaimSession(const Vector<uint8_t>& sessionId) {
55        mReclaimedSessions.push_back(sessionId);
56        return true;
57    }
58
59    const Vector<Vector<uint8_t> >& reclaimedSessions() const {
60        return mReclaimedSessions;
61    }
62
63private:
64    Vector<Vector<uint8_t> > mReclaimedSessions;
65
66    DISALLOW_EVIL_CONSTRUCTORS(FakeDrm);
67};
68
69static const int kTestPid1 = 30;
70static const int kTestPid2 = 20;
71static const uint8_t kTestSessionId1[] = {1, 2, 3};
72static const uint8_t kTestSessionId2[] = {4, 5, 6, 7, 8};
73static const uint8_t kTestSessionId3[] = {9, 0};
74
75class DrmSessionManagerTest : public ::testing::Test {
76public:
77    DrmSessionManagerTest()
78        : mDrmSessionManager(new DrmSessionManager(new FakeProcessInfo())),
79          mTestDrm1(new FakeDrm()),
80          mTestDrm2(new FakeDrm()) {
81        GetSessionId(kTestSessionId1, ARRAY_SIZE(kTestSessionId1), &mSessionId1);
82        GetSessionId(kTestSessionId2, ARRAY_SIZE(kTestSessionId2), &mSessionId2);
83        GetSessionId(kTestSessionId3, ARRAY_SIZE(kTestSessionId3), &mSessionId3);
84    }
85
86protected:
87    static void GetSessionId(const uint8_t* ids, size_t num, Vector<uint8_t>* sessionId) {
88        for (size_t i = 0; i < num; ++i) {
89            sessionId->push_back(ids[i]);
90        }
91    }
92
93    static void ExpectEqSessionInfo(const SessionInfo& info, sp<DrmSessionClientInterface> drm,
94            const Vector<uint8_t>& sessionId, int64_t timeStamp) {
95        EXPECT_EQ(drm, info.drm);
96        EXPECT_TRUE(isEqualSessionId(sessionId, info.sessionId));
97        EXPECT_EQ(timeStamp, info.timeStamp);
98    }
99
100    void addSession() {
101        mDrmSessionManager->addSession(kTestPid1, mTestDrm1, mSessionId1);
102        mDrmSessionManager->addSession(kTestPid2, mTestDrm2, mSessionId2);
103        mDrmSessionManager->addSession(kTestPid2, mTestDrm2, mSessionId3);
104        const PidSessionInfosMap& map = sessionMap();
105        EXPECT_EQ(2u, map.size());
106        ssize_t index1 = map.indexOfKey(kTestPid1);
107        ASSERT_GE(index1, 0);
108        const SessionInfos& infos1 = map[index1];
109        EXPECT_EQ(1u, infos1.size());
110        ExpectEqSessionInfo(infos1[0], mTestDrm1, mSessionId1, 0);
111
112        ssize_t index2 = map.indexOfKey(kTestPid2);
113        ASSERT_GE(index2, 0);
114        const SessionInfos& infos2 = map[index2];
115        EXPECT_EQ(2u, infos2.size());
116        ExpectEqSessionInfo(infos2[0], mTestDrm2, mSessionId2, 1);
117        ExpectEqSessionInfo(infos2[1], mTestDrm2, mSessionId3, 2);
118    }
119
120    const PidSessionInfosMap& sessionMap() {
121        return mDrmSessionManager->mSessionMap;
122    }
123
124    void testGetLowestPriority() {
125        int pid;
126        int priority;
127        EXPECT_FALSE(mDrmSessionManager->getLowestPriority_l(&pid, &priority));
128
129        addSession();
130        EXPECT_TRUE(mDrmSessionManager->getLowestPriority_l(&pid, &priority));
131
132        EXPECT_EQ(kTestPid1, pid);
133        FakeProcessInfo processInfo;
134        int priority1;
135        processInfo.getPriority(kTestPid1, &priority1);
136        EXPECT_EQ(priority1, priority);
137    }
138
139    void testGetLeastUsedSession() {
140        sp<DrmSessionClientInterface> drm;
141        Vector<uint8_t> sessionId;
142        EXPECT_FALSE(mDrmSessionManager->getLeastUsedSession_l(kTestPid1, &drm, &sessionId));
143
144        addSession();
145
146        EXPECT_TRUE(mDrmSessionManager->getLeastUsedSession_l(kTestPid1, &drm, &sessionId));
147        EXPECT_EQ(mTestDrm1, drm);
148        EXPECT_TRUE(isEqualSessionId(mSessionId1, sessionId));
149
150        EXPECT_TRUE(mDrmSessionManager->getLeastUsedSession_l(kTestPid2, &drm, &sessionId));
151        EXPECT_EQ(mTestDrm2, drm);
152        EXPECT_TRUE(isEqualSessionId(mSessionId2, sessionId));
153
154        // mSessionId2 is no longer the least used session.
155        mDrmSessionManager->useSession(mSessionId2);
156        EXPECT_TRUE(mDrmSessionManager->getLeastUsedSession_l(kTestPid2, &drm, &sessionId));
157        EXPECT_EQ(mTestDrm2, drm);
158        EXPECT_TRUE(isEqualSessionId(mSessionId3, sessionId));
159    }
160
161    sp<DrmSessionManager> mDrmSessionManager;
162    sp<FakeDrm> mTestDrm1;
163    sp<FakeDrm> mTestDrm2;
164    Vector<uint8_t> mSessionId1;
165    Vector<uint8_t> mSessionId2;
166    Vector<uint8_t> mSessionId3;
167};
168
169TEST_F(DrmSessionManagerTest, addSession) {
170    addSession();
171}
172
173TEST_F(DrmSessionManagerTest, useSession) {
174    addSession();
175
176    mDrmSessionManager->useSession(mSessionId1);
177    mDrmSessionManager->useSession(mSessionId3);
178
179    const PidSessionInfosMap& map = sessionMap();
180    const SessionInfos& infos1 = map.valueFor(kTestPid1);
181    const SessionInfos& infos2 = map.valueFor(kTestPid2);
182    ExpectEqSessionInfo(infos1[0], mTestDrm1, mSessionId1, 3);
183    ExpectEqSessionInfo(infos2[1], mTestDrm2, mSessionId3, 4);
184}
185
186TEST_F(DrmSessionManagerTest, removeSession) {
187    addSession();
188
189    mDrmSessionManager->removeSession(mSessionId2);
190
191    const PidSessionInfosMap& map = sessionMap();
192    EXPECT_EQ(2u, map.size());
193    const SessionInfos& infos1 = map.valueFor(kTestPid1);
194    const SessionInfos& infos2 = map.valueFor(kTestPid2);
195    EXPECT_EQ(1u, infos1.size());
196    EXPECT_EQ(1u, infos2.size());
197    // mSessionId2 has been removed.
198    ExpectEqSessionInfo(infos2[0], mTestDrm2, mSessionId3, 2);
199}
200
201TEST_F(DrmSessionManagerTest, removeDrm) {
202    addSession();
203
204    sp<FakeDrm> drm = new FakeDrm;
205    const uint8_t ids[] = {123};
206    Vector<uint8_t> sessionId;
207    GetSessionId(ids, ARRAY_SIZE(ids), &sessionId);
208    mDrmSessionManager->addSession(kTestPid2, drm, sessionId);
209
210    mDrmSessionManager->removeDrm(mTestDrm2);
211
212    const PidSessionInfosMap& map = sessionMap();
213    const SessionInfos& infos2 = map.valueFor(kTestPid2);
214    EXPECT_EQ(1u, infos2.size());
215    // mTestDrm2 has been removed.
216    ExpectEqSessionInfo(infos2[0], drm, sessionId, 3);
217}
218
219TEST_F(DrmSessionManagerTest, reclaimSession) {
220    EXPECT_FALSE(mDrmSessionManager->reclaimSession(kTestPid1));
221    addSession();
222
223    // calling pid priority is too low
224    EXPECT_FALSE(mDrmSessionManager->reclaimSession(50));
225
226    EXPECT_TRUE(mDrmSessionManager->reclaimSession(10));
227    EXPECT_EQ(1u, mTestDrm1->reclaimedSessions().size());
228    EXPECT_TRUE(isEqualSessionId(mSessionId1, mTestDrm1->reclaimedSessions()[0]));
229
230    mDrmSessionManager->removeSession(mSessionId1);
231
232    // add a session from a higher priority process.
233    sp<FakeDrm> drm = new FakeDrm;
234    const uint8_t ids[] = {1, 3, 5};
235    Vector<uint8_t> sessionId;
236    GetSessionId(ids, ARRAY_SIZE(ids), &sessionId);
237    mDrmSessionManager->addSession(15, drm, sessionId);
238
239    EXPECT_TRUE(mDrmSessionManager->reclaimSession(18));
240    EXPECT_EQ(1u, mTestDrm2->reclaimedSessions().size());
241    // mSessionId2 is reclaimed.
242    EXPECT_TRUE(isEqualSessionId(mSessionId2, mTestDrm2->reclaimedSessions()[0]));
243}
244
245TEST_F(DrmSessionManagerTest, getLowestPriority) {
246    testGetLowestPriority();
247}
248
249TEST_F(DrmSessionManagerTest, getLeastUsedSession_l) {
250    testGetLeastUsedSession();
251}
252
253} // namespace android
254