| /* |
| * Copyright (C) 2015 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| //#define LOG_NDEBUG 0 |
| #define LOG_TAG "DrmSessionManager_test" |
| #include <utils/Log.h> |
| |
| #include <gtest/gtest.h> |
| |
| #include <media/Drm.h> |
| #include <media/DrmSessionClientInterface.h> |
| #include <media/DrmSessionManager.h> |
| #include <media/stagefright/foundation/ADebug.h> |
| #include <media/stagefright/ProcessInfoInterface.h> |
| |
| namespace android { |
| |
| struct FakeProcessInfo : public ProcessInfoInterface { |
| FakeProcessInfo() {} |
| virtual ~FakeProcessInfo() {} |
| |
| virtual bool getPriority(int pid, int* priority) { |
| // For testing, use pid as priority. |
| // Lower the value higher the priority. |
| *priority = pid; |
| return true; |
| } |
| |
| virtual bool isValidPid(int /* pid */) { |
| return true; |
| } |
| |
| private: |
| DISALLOW_EVIL_CONSTRUCTORS(FakeProcessInfo); |
| }; |
| |
| struct FakeDrm : public DrmSessionClientInterface { |
| FakeDrm() {} |
| virtual ~FakeDrm() {} |
| |
| virtual bool reclaimSession(const Vector<uint8_t>& sessionId) { |
| mReclaimedSessions.push_back(sessionId); |
| return true; |
| } |
| |
| const Vector<Vector<uint8_t> >& reclaimedSessions() const { |
| return mReclaimedSessions; |
| } |
| |
| private: |
| Vector<Vector<uint8_t> > mReclaimedSessions; |
| |
| DISALLOW_EVIL_CONSTRUCTORS(FakeDrm); |
| }; |
| |
| static const int kTestPid1 = 30; |
| static const int kTestPid2 = 20; |
| static const uint8_t kTestSessionId1[] = {1, 2, 3}; |
| static const uint8_t kTestSessionId2[] = {4, 5, 6, 7, 8}; |
| static const uint8_t kTestSessionId3[] = {9, 0}; |
| |
| class DrmSessionManagerTest : public ::testing::Test { |
| public: |
| DrmSessionManagerTest() |
| : mDrmSessionManager(new DrmSessionManager(new FakeProcessInfo())), |
| mTestDrm1(new FakeDrm()), |
| mTestDrm2(new FakeDrm()) { |
| GetSessionId(kTestSessionId1, ARRAY_SIZE(kTestSessionId1), &mSessionId1); |
| GetSessionId(kTestSessionId2, ARRAY_SIZE(kTestSessionId2), &mSessionId2); |
| GetSessionId(kTestSessionId3, ARRAY_SIZE(kTestSessionId3), &mSessionId3); |
| } |
| |
| protected: |
| static void GetSessionId(const uint8_t* ids, size_t num, Vector<uint8_t>* sessionId) { |
| for (size_t i = 0; i < num; ++i) { |
| sessionId->push_back(ids[i]); |
| } |
| } |
| |
| static void ExpectEqSessionInfo(const SessionInfo& info, sp<DrmSessionClientInterface> drm, |
| const Vector<uint8_t>& sessionId, int64_t timeStamp) { |
| EXPECT_EQ(drm, info.drm); |
| EXPECT_TRUE(isEqualSessionId(sessionId, info.sessionId)); |
| EXPECT_EQ(timeStamp, info.timeStamp); |
| } |
| |
| void addSession() { |
| mDrmSessionManager->addSession(kTestPid1, mTestDrm1, mSessionId1); |
| mDrmSessionManager->addSession(kTestPid2, mTestDrm2, mSessionId2); |
| mDrmSessionManager->addSession(kTestPid2, mTestDrm2, mSessionId3); |
| const PidSessionInfosMap& map = sessionMap(); |
| EXPECT_EQ(2u, map.size()); |
| ssize_t index1 = map.indexOfKey(kTestPid1); |
| ASSERT_GE(index1, 0); |
| const SessionInfos& infos1 = map[index1]; |
| EXPECT_EQ(1u, infos1.size()); |
| ExpectEqSessionInfo(infos1[0], mTestDrm1, mSessionId1, 0); |
| |
| ssize_t index2 = map.indexOfKey(kTestPid2); |
| ASSERT_GE(index2, 0); |
| const SessionInfos& infos2 = map[index2]; |
| EXPECT_EQ(2u, infos2.size()); |
| ExpectEqSessionInfo(infos2[0], mTestDrm2, mSessionId2, 1); |
| ExpectEqSessionInfo(infos2[1], mTestDrm2, mSessionId3, 2); |
| } |
| |
| const PidSessionInfosMap& sessionMap() { |
| return mDrmSessionManager->mSessionMap; |
| } |
| |
| void testGetLowestPriority() { |
| int pid; |
| int priority; |
| EXPECT_FALSE(mDrmSessionManager->getLowestPriority_l(&pid, &priority)); |
| |
| addSession(); |
| EXPECT_TRUE(mDrmSessionManager->getLowestPriority_l(&pid, &priority)); |
| |
| EXPECT_EQ(kTestPid1, pid); |
| FakeProcessInfo processInfo; |
| int priority1; |
| processInfo.getPriority(kTestPid1, &priority1); |
| EXPECT_EQ(priority1, priority); |
| } |
| |
| void testGetLeastUsedSession() { |
| sp<DrmSessionClientInterface> drm; |
| Vector<uint8_t> sessionId; |
| EXPECT_FALSE(mDrmSessionManager->getLeastUsedSession_l(kTestPid1, &drm, &sessionId)); |
| |
| addSession(); |
| |
| EXPECT_TRUE(mDrmSessionManager->getLeastUsedSession_l(kTestPid1, &drm, &sessionId)); |
| EXPECT_EQ(mTestDrm1, drm); |
| EXPECT_TRUE(isEqualSessionId(mSessionId1, sessionId)); |
| |
| EXPECT_TRUE(mDrmSessionManager->getLeastUsedSession_l(kTestPid2, &drm, &sessionId)); |
| EXPECT_EQ(mTestDrm2, drm); |
| EXPECT_TRUE(isEqualSessionId(mSessionId2, sessionId)); |
| |
| // mSessionId2 is no longer the least used session. |
| mDrmSessionManager->useSession(mSessionId2); |
| EXPECT_TRUE(mDrmSessionManager->getLeastUsedSession_l(kTestPid2, &drm, &sessionId)); |
| EXPECT_EQ(mTestDrm2, drm); |
| EXPECT_TRUE(isEqualSessionId(mSessionId3, sessionId)); |
| } |
| |
| sp<DrmSessionManager> mDrmSessionManager; |
| sp<FakeDrm> mTestDrm1; |
| sp<FakeDrm> mTestDrm2; |
| Vector<uint8_t> mSessionId1; |
| Vector<uint8_t> mSessionId2; |
| Vector<uint8_t> mSessionId3; |
| }; |
| |
| TEST_F(DrmSessionManagerTest, addSession) { |
| addSession(); |
| } |
| |
| TEST_F(DrmSessionManagerTest, useSession) { |
| addSession(); |
| |
| mDrmSessionManager->useSession(mSessionId1); |
| mDrmSessionManager->useSession(mSessionId3); |
| |
| const PidSessionInfosMap& map = sessionMap(); |
| const SessionInfos& infos1 = map.valueFor(kTestPid1); |
| const SessionInfos& infos2 = map.valueFor(kTestPid2); |
| ExpectEqSessionInfo(infos1[0], mTestDrm1, mSessionId1, 3); |
| ExpectEqSessionInfo(infos2[1], mTestDrm2, mSessionId3, 4); |
| } |
| |
| TEST_F(DrmSessionManagerTest, removeSession) { |
| addSession(); |
| |
| mDrmSessionManager->removeSession(mSessionId2); |
| |
| const PidSessionInfosMap& map = sessionMap(); |
| EXPECT_EQ(2u, map.size()); |
| const SessionInfos& infos1 = map.valueFor(kTestPid1); |
| const SessionInfos& infos2 = map.valueFor(kTestPid2); |
| EXPECT_EQ(1u, infos1.size()); |
| EXPECT_EQ(1u, infos2.size()); |
| // mSessionId2 has been removed. |
| ExpectEqSessionInfo(infos2[0], mTestDrm2, mSessionId3, 2); |
| } |
| |
| TEST_F(DrmSessionManagerTest, removeDrm) { |
| addSession(); |
| |
| sp<FakeDrm> drm = new FakeDrm; |
| const uint8_t ids[] = {123}; |
| Vector<uint8_t> sessionId; |
| GetSessionId(ids, ARRAY_SIZE(ids), &sessionId); |
| mDrmSessionManager->addSession(kTestPid2, drm, sessionId); |
| |
| mDrmSessionManager->removeDrm(mTestDrm2); |
| |
| const PidSessionInfosMap& map = sessionMap(); |
| const SessionInfos& infos2 = map.valueFor(kTestPid2); |
| EXPECT_EQ(1u, infos2.size()); |
| // mTestDrm2 has been removed. |
| ExpectEqSessionInfo(infos2[0], drm, sessionId, 3); |
| } |
| |
| TEST_F(DrmSessionManagerTest, reclaimSession) { |
| EXPECT_FALSE(mDrmSessionManager->reclaimSession(kTestPid1)); |
| addSession(); |
| |
| // calling pid priority is too low |
| EXPECT_FALSE(mDrmSessionManager->reclaimSession(50)); |
| |
| EXPECT_TRUE(mDrmSessionManager->reclaimSession(10)); |
| EXPECT_EQ(1u, mTestDrm1->reclaimedSessions().size()); |
| EXPECT_TRUE(isEqualSessionId(mSessionId1, mTestDrm1->reclaimedSessions()[0])); |
| |
| mDrmSessionManager->removeSession(mSessionId1); |
| |
| // add a session from a higher priority process. |
| sp<FakeDrm> drm = new FakeDrm; |
| const uint8_t ids[] = {1, 3, 5}; |
| Vector<uint8_t> sessionId; |
| GetSessionId(ids, ARRAY_SIZE(ids), &sessionId); |
| mDrmSessionManager->addSession(15, drm, sessionId); |
| |
| EXPECT_TRUE(mDrmSessionManager->reclaimSession(18)); |
| EXPECT_EQ(1u, mTestDrm2->reclaimedSessions().size()); |
| // mSessionId2 is reclaimed. |
| EXPECT_TRUE(isEqualSessionId(mSessionId2, mTestDrm2->reclaimedSessions()[0])); |
| } |
| |
| TEST_F(DrmSessionManagerTest, getLowestPriority) { |
| testGetLowestPriority(); |
| } |
| |
| TEST_F(DrmSessionManagerTest, getLeastUsedSession_l) { |
| testGetLeastUsedSession(); |
| } |
| |
| } // namespace android |