From 10305cc672dcb39b7cc7dc03eeafffb2fea150ec Mon Sep 17 00:00:00 2001 From: Ronghua Wu Date: Sun, 22 Feb 2015 07:55:32 -0800 Subject: Add DRM session manager. Bug: 19265536 Change-Id: Ia9f2c94c64ed6c1fe99d54de81d71c8973994865 --- media/libmediaplayerservice/tests/Android.mk | 31 +++ .../tests/DrmSessionManager_test.cpp | 242 +++++++++++++++++++++ 2 files changed, 273 insertions(+) create mode 100644 media/libmediaplayerservice/tests/Android.mk create mode 100644 media/libmediaplayerservice/tests/DrmSessionManager_test.cpp (limited to 'media/libmediaplayerservice/tests') diff --git a/media/libmediaplayerservice/tests/Android.mk b/media/libmediaplayerservice/tests/Android.mk new file mode 100644 index 0000000..69d4ad1 --- /dev/null +++ b/media/libmediaplayerservice/tests/Android.mk @@ -0,0 +1,31 @@ +# Build the unit tests. +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) +LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk + +LOCAL_MODULE := DrmSessionManager_test + +LOCAL_MODULE_TAGS := tests + +LOCAL_SRC_FILES := \ + DrmSessionManager_test.cpp \ + +LOCAL_SHARED_LIBRARIES := \ + liblog \ + libmediaplayerservice \ + libutils \ + +LOCAL_C_INCLUDES := \ + frameworks/av/include \ + frameworks/av/media/libmediaplayerservice \ + +include $(BUILD_NATIVE_TEST) + +# Include subdirectory makefiles +# ============================================================ + +# If we're building with ONE_SHOT_MAKEFILE (mm, mmm), then what the framework +# team really wants is to build the stuff defined by this makefile. +ifeq (,$(ONE_SHOT_MAKEFILE)) +include $(call first-makefiles-under,$(LOCAL_PATH)) +endif diff --git a/media/libmediaplayerservice/tests/DrmSessionManager_test.cpp b/media/libmediaplayerservice/tests/DrmSessionManager_test.cpp new file mode 100644 index 0000000..a199ee1 --- /dev/null +++ b/media/libmediaplayerservice/tests/DrmSessionManager_test.cpp @@ -0,0 +1,242 @@ +/* + * 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 + +#include + +#include "Drm.h" +#include "DrmSessionClientInterface.h" +#include "DrmSessionManager.h" +#include "ProcessInfoInterface.h" +#include + +namespace android { + +struct FakeProcessInfo : public ProcessInfoInterface { + FakeProcessInfo() {} + virtual ~FakeProcessInfo() {} + + virtual int getPriority(int pid) { return pid; } + +private: + DISALLOW_EVIL_CONSTRUCTORS(FakeProcessInfo); +}; + +struct FakeDrm : public DrmSessionClientInterface { + FakeDrm() {} + virtual ~FakeDrm() {} + + virtual bool reclaimSession(const Vector& sessionId) { + mReclaimedSessions.push_back(sessionId); + return true; + } + + const Vector >& reclaimedSessions() const { + return mReclaimedSessions; + } + +private: + Vector > mReclaimedSessions; + + DISALLOW_EVIL_CONSTRUCTORS(FakeDrm); +}; + +static const int kTestPid1 = 10; +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* sessionId) { + for (size_t i = 0; i < num; ++i) { + sessionId->push_back(ids[i]); + } + } + + static void ExpectEqSessionInfo(const SessionInfo& info, sp drm, + const Vector& 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(2, map.size()); + ssize_t index1 = map.indexOfKey(kTestPid1); + ASSERT_GE(index1, 0); + const SessionInfos& infos1 = map[index1]; + EXPECT_EQ(1, 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(2, 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; + EXPECT_EQ(processInfo.getPriority(kTestPid1), priority); + } + + void testGetLeastUsedSession() { + sp drm; + Vector 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 mDrmSessionManager; + sp mTestDrm1; + sp mTestDrm2; + Vector mSessionId1; + Vector mSessionId2; + Vector 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(2, map.size()); + const SessionInfos& infos1 = map.valueFor(kTestPid1); + const SessionInfos& infos2 = map.valueFor(kTestPid2); + EXPECT_EQ(1, infos1.size()); + EXPECT_EQ(1, infos2.size()); + // mSessionId2 has been removed. + ExpectEqSessionInfo(infos2[0], mTestDrm2, mSessionId3, 2); +} + +TEST_F(DrmSessionManagerTest, removeDrm) { + addSession(); + + sp drm = new FakeDrm; + const uint8_t ids[] = {123}; + Vector 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(1, 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(5)); + + EXPECT_TRUE(mDrmSessionManager->reclaimSession(30)); + EXPECT_EQ(1, mTestDrm1->reclaimedSessions().size()); + EXPECT_TRUE(isEqualSessionId(mSessionId1, mTestDrm1->reclaimedSessions()[0])); + + mDrmSessionManager->removeSession(mSessionId1); + + // add a session from a higher priority process. + sp drm = new FakeDrm; + const uint8_t ids[] = {456, 7890, 123}; + Vector sessionId; + GetSessionId(ids, ARRAY_SIZE(ids), &sessionId); + mDrmSessionManager->addSession(30, drm, sessionId); + + EXPECT_TRUE(mDrmSessionManager->reclaimSession(40)); + EXPECT_EQ(1, 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 -- cgit v1.1