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 { 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 private: 43 DISALLOW_EVIL_CONSTRUCTORS(FakeProcessInfo); 44 }; 45 46 struct FakeDrm : public DrmSessionClientInterface { 47 FakeDrm() {} 48 virtual ~FakeDrm() {} 49 50 virtual bool reclaimSession(const Vector<uint8_t>& sessionId) { 51 mReclaimedSessions.push_back(sessionId); 52 return true; 53 } 54 55 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: 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: 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 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 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 116 const PidSessionInfosMap& sessionMap() { 117 return mDrmSessionManager->mSessionMap; 118 } 119 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 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 165 TEST_F(DrmSessionManagerTest, addSession) { 166 addSession(); 167 } 168 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 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 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 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 241 TEST_F(DrmSessionManagerTest, getLowestPriority) { 242 testGetLowestPriority(); 243 } 244 245 TEST_F(DrmSessionManagerTest, getLeastUsedSession_l) { 246 testGetLeastUsedSession(); 247 } 248 249 } // namespace android 250