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 "Drm.h"
24 #include "DrmSessionClientInterface.h"
25 #include "DrmSessionManager.h"
26 #include <media/stagefright/foundation/ADebug.h>
27 #include <media/stagefright/ProcessInfoInterface.h>
28
29 namespace android {
30
31 struct FakeProcessInfo : public ProcessInfoInterface {
FakeProcessInfoandroid::FakeProcessInfo32 FakeProcessInfo() {}
~FakeProcessInfoandroid::FakeProcessInfo33 virtual ~FakeProcessInfo() {}
34
getPriorityandroid::FakeProcessInfo35 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 private:
43 DISALLOW_EVIL_CONSTRUCTORS(FakeProcessInfo);
44 };
45
46 struct FakeDrm : public DrmSessionClientInterface {
FakeDrmandroid::FakeDrm47 FakeDrm() {}
~FakeDrmandroid::FakeDrm48 virtual ~FakeDrm() {}
49
reclaimSessionandroid::FakeDrm50 virtual bool reclaimSession(const Vector<uint8_t>& sessionId) {
51 mReclaimedSessions.push_back(sessionId);
52 return true;
53 }
54
reclaimedSessionsandroid::FakeDrm55 const Vector<Vector<uint8_t> >& reclaimedSessions() const {
56 return mReclaimedSessions;
57 }
58
59 private:
60 Vector<Vector<uint8_t> > mReclaimedSessions;
61
62 DISALLOW_EVIL_CONSTRUCTORS(FakeDrm);
63 };
64
65 static const int kTestPid1 = 30;
66 static const int kTestPid2 = 20;
67 static const uint8_t kTestSessionId1[] = {1, 2, 3};
68 static const uint8_t kTestSessionId2[] = {4, 5, 6, 7, 8};
69 static const uint8_t kTestSessionId3[] = {9, 0};
70
71 class DrmSessionManagerTest : public ::testing::Test {
72 public:
DrmSessionManagerTest()73 DrmSessionManagerTest()
74 : mDrmSessionManager(new DrmSessionManager(new FakeProcessInfo())),
75 mTestDrm1(new FakeDrm()),
76 mTestDrm2(new FakeDrm()) {
77 GetSessionId(kTestSessionId1, ARRAY_SIZE(kTestSessionId1), &mSessionId1);
78 GetSessionId(kTestSessionId2, ARRAY_SIZE(kTestSessionId2), &mSessionId2);
79 GetSessionId(kTestSessionId3, ARRAY_SIZE(kTestSessionId3), &mSessionId3);
80 }
81
82 protected:
GetSessionId(const uint8_t * ids,size_t num,Vector<uint8_t> * sessionId)83 static void GetSessionId(const uint8_t* ids, size_t num, Vector<uint8_t>* sessionId) {
84 for (size_t i = 0; i < num; ++i) {
85 sessionId->push_back(ids[i]);
86 }
87 }
88
ExpectEqSessionInfo(const SessionInfo & info,sp<DrmSessionClientInterface> drm,const Vector<uint8_t> & sessionId,int64_t timeStamp)89 static void ExpectEqSessionInfo(const SessionInfo& info, sp<DrmSessionClientInterface> drm,
90 const Vector<uint8_t>& sessionId, int64_t timeStamp) {
91 EXPECT_EQ(drm, info.drm);
92 EXPECT_TRUE(isEqualSessionId(sessionId, info.sessionId));
93 EXPECT_EQ(timeStamp, info.timeStamp);
94 }
95
addSession()96 void addSession() {
97 mDrmSessionManager->addSession(kTestPid1, mTestDrm1, mSessionId1);
98 mDrmSessionManager->addSession(kTestPid2, mTestDrm2, mSessionId2);
99 mDrmSessionManager->addSession(kTestPid2, mTestDrm2, mSessionId3);
100 const PidSessionInfosMap& map = sessionMap();
101 EXPECT_EQ(2u, map.size());
102 ssize_t index1 = map.indexOfKey(kTestPid1);
103 ASSERT_GE(index1, 0);
104 const SessionInfos& infos1 = map[index1];
105 EXPECT_EQ(1u, infos1.size());
106 ExpectEqSessionInfo(infos1[0], mTestDrm1, mSessionId1, 0);
107
108 ssize_t index2 = map.indexOfKey(kTestPid2);
109 ASSERT_GE(index2, 0);
110 const SessionInfos& infos2 = map[index2];
111 EXPECT_EQ(2u, infos2.size());
112 ExpectEqSessionInfo(infos2[0], mTestDrm2, mSessionId2, 1);
113 ExpectEqSessionInfo(infos2[1], mTestDrm2, mSessionId3, 2);
114 }
115
sessionMap()116 const PidSessionInfosMap& sessionMap() {
117 return mDrmSessionManager->mSessionMap;
118 }
119
testGetLowestPriority()120 void testGetLowestPriority() {
121 int pid;
122 int priority;
123 EXPECT_FALSE(mDrmSessionManager->getLowestPriority_l(&pid, &priority));
124
125 addSession();
126 EXPECT_TRUE(mDrmSessionManager->getLowestPriority_l(&pid, &priority));
127
128 EXPECT_EQ(kTestPid1, pid);
129 FakeProcessInfo processInfo;
130 int priority1;
131 processInfo.getPriority(kTestPid1, &priority1);
132 EXPECT_EQ(priority1, priority);
133 }
134
testGetLeastUsedSession()135 void testGetLeastUsedSession() {
136 sp<DrmSessionClientInterface> drm;
137 Vector<uint8_t> sessionId;
138 EXPECT_FALSE(mDrmSessionManager->getLeastUsedSession_l(kTestPid1, &drm, &sessionId));
139
140 addSession();
141
142 EXPECT_TRUE(mDrmSessionManager->getLeastUsedSession_l(kTestPid1, &drm, &sessionId));
143 EXPECT_EQ(mTestDrm1, drm);
144 EXPECT_TRUE(isEqualSessionId(mSessionId1, sessionId));
145
146 EXPECT_TRUE(mDrmSessionManager->getLeastUsedSession_l(kTestPid2, &drm, &sessionId));
147 EXPECT_EQ(mTestDrm2, drm);
148 EXPECT_TRUE(isEqualSessionId(mSessionId2, sessionId));
149
150 // mSessionId2 is no longer the least used session.
151 mDrmSessionManager->useSession(mSessionId2);
152 EXPECT_TRUE(mDrmSessionManager->getLeastUsedSession_l(kTestPid2, &drm, &sessionId));
153 EXPECT_EQ(mTestDrm2, drm);
154 EXPECT_TRUE(isEqualSessionId(mSessionId3, sessionId));
155 }
156
157 sp<DrmSessionManager> mDrmSessionManager;
158 sp<FakeDrm> mTestDrm1;
159 sp<FakeDrm> mTestDrm2;
160 Vector<uint8_t> mSessionId1;
161 Vector<uint8_t> mSessionId2;
162 Vector<uint8_t> mSessionId3;
163 };
164
TEST_F(DrmSessionManagerTest,addSession)165 TEST_F(DrmSessionManagerTest, addSession) {
166 addSession();
167 }
168
TEST_F(DrmSessionManagerTest,useSession)169 TEST_F(DrmSessionManagerTest, useSession) {
170 addSession();
171
172 mDrmSessionManager->useSession(mSessionId1);
173 mDrmSessionManager->useSession(mSessionId3);
174
175 const PidSessionInfosMap& map = sessionMap();
176 const SessionInfos& infos1 = map.valueFor(kTestPid1);
177 const SessionInfos& infos2 = map.valueFor(kTestPid2);
178 ExpectEqSessionInfo(infos1[0], mTestDrm1, mSessionId1, 3);
179 ExpectEqSessionInfo(infos2[1], mTestDrm2, mSessionId3, 4);
180 }
181
TEST_F(DrmSessionManagerTest,removeSession)182 TEST_F(DrmSessionManagerTest, removeSession) {
183 addSession();
184
185 mDrmSessionManager->removeSession(mSessionId2);
186
187 const PidSessionInfosMap& map = sessionMap();
188 EXPECT_EQ(2u, map.size());
189 const SessionInfos& infos1 = map.valueFor(kTestPid1);
190 const SessionInfos& infos2 = map.valueFor(kTestPid2);
191 EXPECT_EQ(1u, infos1.size());
192 EXPECT_EQ(1u, infos2.size());
193 // mSessionId2 has been removed.
194 ExpectEqSessionInfo(infos2[0], mTestDrm2, mSessionId3, 2);
195 }
196
TEST_F(DrmSessionManagerTest,removeDrm)197 TEST_F(DrmSessionManagerTest, removeDrm) {
198 addSession();
199
200 sp<FakeDrm> drm = new FakeDrm;
201 const uint8_t ids[] = {123};
202 Vector<uint8_t> sessionId;
203 GetSessionId(ids, ARRAY_SIZE(ids), &sessionId);
204 mDrmSessionManager->addSession(kTestPid2, drm, sessionId);
205
206 mDrmSessionManager->removeDrm(mTestDrm2);
207
208 const PidSessionInfosMap& map = sessionMap();
209 const SessionInfos& infos2 = map.valueFor(kTestPid2);
210 EXPECT_EQ(1u, infos2.size());
211 // mTestDrm2 has been removed.
212 ExpectEqSessionInfo(infos2[0], drm, sessionId, 3);
213 }
214
TEST_F(DrmSessionManagerTest,reclaimSession)215 TEST_F(DrmSessionManagerTest, reclaimSession) {
216 EXPECT_FALSE(mDrmSessionManager->reclaimSession(kTestPid1));
217 addSession();
218
219 // calling pid priority is too low
220 EXPECT_FALSE(mDrmSessionManager->reclaimSession(50));
221
222 EXPECT_TRUE(mDrmSessionManager->reclaimSession(10));
223 EXPECT_EQ(1u, mTestDrm1->reclaimedSessions().size());
224 EXPECT_TRUE(isEqualSessionId(mSessionId1, mTestDrm1->reclaimedSessions()[0]));
225
226 mDrmSessionManager->removeSession(mSessionId1);
227
228 // add a session from a higher priority process.
229 sp<FakeDrm> drm = new FakeDrm;
230 const uint8_t ids[] = {1, 3, 5};
231 Vector<uint8_t> sessionId;
232 GetSessionId(ids, ARRAY_SIZE(ids), &sessionId);
233 mDrmSessionManager->addSession(15, drm, sessionId);
234
235 EXPECT_TRUE(mDrmSessionManager->reclaimSession(18));
236 EXPECT_EQ(1u, mTestDrm2->reclaimedSessions().size());
237 // mSessionId2 is reclaimed.
238 EXPECT_TRUE(isEqualSessionId(mSessionId2, mTestDrm2->reclaimedSessions()[0]));
239 }
240
TEST_F(DrmSessionManagerTest,getLowestPriority)241 TEST_F(DrmSessionManagerTest, getLowestPriority) {
242 testGetLowestPriority();
243 }
244
TEST_F(DrmSessionManagerTest,getLeastUsedSession_l)245 TEST_F(DrmSessionManagerTest, getLeastUsedSession_l) {
246 testGetLeastUsedSession();
247 }
248
249 } // namespace android
250