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 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 virtual bool isValidPid(int /* pid */) { 43 return true; 44 } 45 46 private: 47 DISALLOW_EVIL_CONSTRUCTORS(FakeProcessInfo); 48 }; 49 50 struct 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 63 private: 64 Vector<Vector<uint8_t> > mReclaimedSessions; 65 66 DISALLOW_EVIL_CONSTRUCTORS(FakeDrm); 67 }; 68 69 static const int kTestPid1 = 30; 70 static const int kTestPid2 = 20; 71 static const uint8_t kTestSessionId1[] = {1, 2, 3}; 72 static const uint8_t kTestSessionId2[] = {4, 5, 6, 7, 8}; 73 static const uint8_t kTestSessionId3[] = {9, 0}; 74 75 class DrmSessionManagerTest : public ::testing::Test { 76 public: 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 86 protected: 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 169 TEST_F(DrmSessionManagerTest, addSession) { 170 addSession(); 171 } 172 173 TEST_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 186 TEST_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 201 TEST_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 219 TEST_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 245 TEST_F(DrmSessionManagerTest, getLowestPriority) { 246 testGetLowestPriority(); 247 } 248 249 TEST_F(DrmSessionManagerTest, getLeastUsedSession_l) { 250 testGetLeastUsedSession(); 251 } 252 253 } // namespace android 254