1 /*
2 * Copyright 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 #include <gtest/gtest.h>
18
19 #include "ResourceManagerService.h"
20 #include <aidl/android/media/BnResourceManagerClient.h>
21 #include <media/MediaResource.h>
22 #include <media/MediaResourcePolicy.h>
23 #include <media/stagefright/foundation/ADebug.h>
24 #include <media/stagefright/ProcessInfoInterface.h>
25
26 namespace android {
27
28 using Status = ::ndk::ScopedAStatus;
29 using ::aidl::android::media::BnResourceManagerClient;
30 using ::aidl::android::media::IResourceManagerService;
31 using ::aidl::android::media::IResourceManagerClient;
32 using ::aidl::android::media::MediaResourceParcel;
33
getId(const std::shared_ptr<IResourceManagerClient> & client)34 static int64_t getId(const std::shared_ptr<IResourceManagerClient>& client) {
35 return (int64_t) client.get();
36 }
37
38 struct TestProcessInfo : public ProcessInfoInterface {
TestProcessInfoTestProcessInfo39 TestProcessInfo() {}
~TestProcessInfoTestProcessInfo40 virtual ~TestProcessInfo() {}
41
getPriorityTestProcessInfo42 virtual bool getPriority(int pid, int *priority) {
43 // For testing, use pid as priority.
44 // Lower the value higher the priority.
45 *priority = pid;
46 return true;
47 }
48
isValidPidTestProcessInfo49 virtual bool isValidPid(int /* pid */) {
50 return true;
51 }
52
overrideProcessInfoTestProcessInfo53 virtual bool overrideProcessInfo(
54 int /* pid */, int /* procState */, int /* oomScore */) {
55 return true;
56 }
57
removeProcessInfoOverrideTestProcessInfo58 virtual void removeProcessInfoOverride(int /* pid */) {
59 }
60
61 private:
62 DISALLOW_EVIL_CONSTRUCTORS(TestProcessInfo);
63 };
64
65 struct TestSystemCallback :
66 public ResourceManagerService::SystemCallbackInterface {
TestSystemCallbackTestSystemCallback67 TestSystemCallback() :
68 mLastEvent({EventType::INVALID, 0}), mEventCount(0) {}
69
70 enum EventType {
71 INVALID = -1,
72 VIDEO_ON = 0,
73 VIDEO_OFF = 1,
74 VIDEO_RESET = 2,
75 CPUSET_ENABLE = 3,
76 CPUSET_DISABLE = 4,
77 };
78
79 struct EventEntry {
80 EventType type;
81 int arg;
82 };
83
noteStartVideoTestSystemCallback84 virtual void noteStartVideo(int uid) override {
85 mLastEvent = {EventType::VIDEO_ON, uid};
86 mEventCount++;
87 }
88
noteStopVideoTestSystemCallback89 virtual void noteStopVideo(int uid) override {
90 mLastEvent = {EventType::VIDEO_OFF, uid};
91 mEventCount++;
92 }
93
noteResetVideoTestSystemCallback94 virtual void noteResetVideo() override {
95 mLastEvent = {EventType::VIDEO_RESET, 0};
96 mEventCount++;
97 }
98
requestCpusetBoostTestSystemCallback99 virtual bool requestCpusetBoost(bool enable) override {
100 mLastEvent = {enable ? EventType::CPUSET_ENABLE : EventType::CPUSET_DISABLE, 0};
101 mEventCount++;
102 return true;
103 }
104
eventCountTestSystemCallback105 size_t eventCount() { return mEventCount; }
lastEventTypeTestSystemCallback106 EventType lastEventType() { return mLastEvent.type; }
lastEventTestSystemCallback107 EventEntry lastEvent() { return mLastEvent; }
108
109 protected:
~TestSystemCallbackTestSystemCallback110 virtual ~TestSystemCallback() {}
111
112 private:
113 EventEntry mLastEvent;
114 size_t mEventCount;
115
116 DISALLOW_EVIL_CONSTRUCTORS(TestSystemCallback);
117 };
118
119
120 struct TestClient : public BnResourceManagerClient {
TestClientTestClient121 TestClient(int pid, const std::shared_ptr<ResourceManagerService> &service)
122 : mReclaimed(false), mPid(pid), mService(service) {}
123
reclaimResourceTestClient124 Status reclaimResource(bool* _aidl_return) override {
125 mService->removeClient(mPid, getId(ref<TestClient>()));
126 mReclaimed = true;
127 *_aidl_return = true;
128 return Status::ok();
129 }
130
getNameTestClient131 Status getName(::std::string* _aidl_return) override {
132 *_aidl_return = "test_client";
133 return Status::ok();
134 }
135
reclaimedTestClient136 bool reclaimed() const {
137 return mReclaimed;
138 }
139
resetTestClient140 void reset() {
141 mReclaimed = false;
142 }
143
~TestClientTestClient144 virtual ~TestClient() {}
145
146 private:
147 bool mReclaimed;
148 int mPid;
149 std::shared_ptr<ResourceManagerService> mService;
150 DISALLOW_EVIL_CONSTRUCTORS(TestClient);
151 };
152
153 static const int kTestPid1 = 30;
154 static const int kTestUid1 = 1010;
155
156 static const int kTestPid2 = 20;
157 static const int kTestUid2 = 1011;
158
159 static const int kLowPriorityPid = 40;
160 static const int kMidPriorityPid = 25;
161 static const int kHighPriorityPid = 10;
162
163 using EventType = TestSystemCallback::EventType;
164 using EventEntry = TestSystemCallback::EventEntry;
165 bool operator== (const EventEntry& lhs, const EventEntry& rhs) {
166 return lhs.type == rhs.type && lhs.arg == rhs.arg;
167 }
168
169 #define CHECK_STATUS_TRUE(condition) \
170 EXPECT_TRUE((condition).isOk() && (result))
171
172 #define CHECK_STATUS_FALSE(condition) \
173 EXPECT_TRUE((condition).isOk() && !(result))
174
175 class ResourceManagerServiceTestBase : public ::testing::Test {
176 public:
ResourceManagerServiceTestBase()177 ResourceManagerServiceTestBase()
178 : mSystemCB(new TestSystemCallback()),
179 mService(::ndk::SharedRefBase::make<ResourceManagerService>(
180 new TestProcessInfo, mSystemCB)),
181 mTestClient1(::ndk::SharedRefBase::make<TestClient>(kTestPid1, mService)),
182 mTestClient2(::ndk::SharedRefBase::make<TestClient>(kTestPid2, mService)),
183 mTestClient3(::ndk::SharedRefBase::make<TestClient>(kTestPid2, mService)) {
184 }
185
186 sp<TestSystemCallback> mSystemCB;
187 std::shared_ptr<ResourceManagerService> mService;
188 std::shared_ptr<IResourceManagerClient> mTestClient1;
189 std::shared_ptr<IResourceManagerClient> mTestClient2;
190 std::shared_ptr<IResourceManagerClient> mTestClient3;
191
192 protected:
isEqualResources(const std::vector<MediaResourceParcel> & resources1,const ResourceList & resources2)193 static bool isEqualResources(const std::vector<MediaResourceParcel> &resources1,
194 const ResourceList &resources2) {
195 // convert resource1 to ResourceList
196 ResourceList r1;
197 for (size_t i = 0; i < resources1.size(); ++i) {
198 const auto &res = resources1[i];
199 const auto resType = std::tuple(res.type, res.subType, res.id);
200 r1[resType] = res;
201 }
202 return r1 == resources2;
203 }
204
expectEqResourceInfo(const ResourceInfo & info,int uid,std::shared_ptr<IResourceManagerClient> client,const std::vector<MediaResourceParcel> & resources)205 static void expectEqResourceInfo(const ResourceInfo &info,
206 int uid,
207 std::shared_ptr<IResourceManagerClient> client,
208 const std::vector<MediaResourceParcel> &resources) {
209 EXPECT_EQ(uid, info.uid);
210 EXPECT_EQ(client, info.client);
211 EXPECT_TRUE(isEqualResources(resources, info.resources));
212 }
213 };
214
215 } // namespace android
216