blob: 1624477bd1616866ef64a1ec86df5e5e3df6aa6c [file] [log] [blame]
Chong Zhanga9d45c72020-09-09 12:41:17 -07001/*
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
Chong Zhanga9d45c72020-09-09 12:41:17 -070026namespace android {
27
28using Status = ::ndk::ScopedAStatus;
29using ::aidl::android::media::BnResourceManagerClient;
30using ::aidl::android::media::IResourceManagerService;
31using ::aidl::android::media::IResourceManagerClient;
32using ::aidl::android::media::MediaResourceParcel;
33
34static int64_t getId(const std::shared_ptr<IResourceManagerClient>& client) {
35 return (int64_t) client.get();
36}
37
38struct TestProcessInfo : public ProcessInfoInterface {
39 TestProcessInfo() {}
40 virtual ~TestProcessInfo() {}
41
42 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
49 virtual bool isValidPid(int /* pid */) {
50 return true;
51 }
52
Chong Zhang97d367b2020-09-16 12:53:14 -070053 virtual bool overrideProcessInfo(
54 int /* pid */, int /* procState */, int /* oomScore */) {
55 return true;
56 }
57
58 virtual void removeProcessInfoOverride(int /* pid */) {
59 }
60
Chong Zhanga9d45c72020-09-09 12:41:17 -070061private:
62 DISALLOW_EVIL_CONSTRUCTORS(TestProcessInfo);
63};
64
65struct TestSystemCallback :
66 public ResourceManagerService::SystemCallbackInterface {
67 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
84 virtual void noteStartVideo(int uid) override {
85 mLastEvent = {EventType::VIDEO_ON, uid};
86 mEventCount++;
87 }
88
89 virtual void noteStopVideo(int uid) override {
90 mLastEvent = {EventType::VIDEO_OFF, uid};
91 mEventCount++;
92 }
93
94 virtual void noteResetVideo() override {
95 mLastEvent = {EventType::VIDEO_RESET, 0};
96 mEventCount++;
97 }
98
99 virtual bool requestCpusetBoost(bool enable) override {
100 mLastEvent = {enable ? EventType::CPUSET_ENABLE : EventType::CPUSET_DISABLE, 0};
101 mEventCount++;
102 return true;
103 }
104
105 size_t eventCount() { return mEventCount; }
106 EventType lastEventType() { return mLastEvent.type; }
107 EventEntry lastEvent() { return mLastEvent; }
108
109protected:
110 virtual ~TestSystemCallback() {}
111
112private:
113 EventEntry mLastEvent;
114 size_t mEventCount;
115
116 DISALLOW_EVIL_CONSTRUCTORS(TestSystemCallback);
117};
118
119
120struct TestClient : public BnResourceManagerClient {
121 TestClient(int pid, const std::shared_ptr<ResourceManagerService> &service)
Brian Lindahl64ee9452022-01-14 13:31:16 +0100122 : mPid(pid), mService(service) {}
Chong Zhanga9d45c72020-09-09 12:41:17 -0700123
124 Status reclaimResource(bool* _aidl_return) override {
125 mService->removeClient(mPid, getId(ref<TestClient>()));
Brian Lindahl64ee9452022-01-14 13:31:16 +0100126 mWasReclaimResourceCalled = true;
Chong Zhanga9d45c72020-09-09 12:41:17 -0700127 *_aidl_return = true;
128 return Status::ok();
129 }
130
131 Status getName(::std::string* _aidl_return) override {
132 *_aidl_return = "test_client";
133 return Status::ok();
134 }
135
Brian Lindahl64ee9452022-01-14 13:31:16 +0100136 bool checkIfReclaimedAndReset() {
137 bool wasReclaimResourceCalled = mWasReclaimResourceCalled;
138 mWasReclaimResourceCalled = false;
139 return wasReclaimResourceCalled;
Chong Zhanga9d45c72020-09-09 12:41:17 -0700140 }
141
142 virtual ~TestClient() {}
143
144private:
Brian Lindahl64ee9452022-01-14 13:31:16 +0100145 bool mWasReclaimResourceCalled = false;
Chong Zhanga9d45c72020-09-09 12:41:17 -0700146 int mPid;
147 std::shared_ptr<ResourceManagerService> mService;
148 DISALLOW_EVIL_CONSTRUCTORS(TestClient);
149};
150
151static const int kTestPid1 = 30;
152static const int kTestUid1 = 1010;
153
154static const int kTestPid2 = 20;
155static const int kTestUid2 = 1011;
156
157static const int kLowPriorityPid = 40;
158static const int kMidPriorityPid = 25;
159static const int kHighPriorityPid = 10;
160
161using EventType = TestSystemCallback::EventType;
162using EventEntry = TestSystemCallback::EventEntry;
163bool operator== (const EventEntry& lhs, const EventEntry& rhs) {
164 return lhs.type == rhs.type && lhs.arg == rhs.arg;
165}
166
Brian Lindahl64ee9452022-01-14 13:31:16 +0100167// The condition is expected to return a status but also update the local
168// result variable.
169#define CHECK_STATUS_TRUE(conditionThatUpdatesResult) \
170 do { \
171 bool result = false; \
172 EXPECT_TRUE((conditionThatUpdatesResult).isOk()); \
173 EXPECT_TRUE(result); \
174 } while(false)
Chong Zhanga9d45c72020-09-09 12:41:17 -0700175
Brian Lindahl64ee9452022-01-14 13:31:16 +0100176// The condition is expected to return a status but also update the local
177// result variable.
178#define CHECK_STATUS_FALSE(conditionThatUpdatesResult) \
179 do { \
180 bool result = true; \
181 EXPECT_TRUE((conditionThatUpdatesResult).isOk()); \
182 EXPECT_FALSE(result); \
183 } while(false)
Chong Zhanga9d45c72020-09-09 12:41:17 -0700184
185class ResourceManagerServiceTestBase : public ::testing::Test {
186public:
Brian Lindahl64ee9452022-01-14 13:31:16 +0100187 static TestClient* toTestClient(std::shared_ptr<IResourceManagerClient> testClient) {
188 return static_cast<TestClient*>(testClient.get());
189 }
190
Chong Zhanga9d45c72020-09-09 12:41:17 -0700191 ResourceManagerServiceTestBase()
192 : mSystemCB(new TestSystemCallback()),
193 mService(::ndk::SharedRefBase::make<ResourceManagerService>(
194 new TestProcessInfo, mSystemCB)),
195 mTestClient1(::ndk::SharedRefBase::make<TestClient>(kTestPid1, mService)),
196 mTestClient2(::ndk::SharedRefBase::make<TestClient>(kTestPid2, mService)),
197 mTestClient3(::ndk::SharedRefBase::make<TestClient>(kTestPid2, mService)) {
198 }
199
Brian Lindahl64ee9452022-01-14 13:31:16 +0100200 std::shared_ptr<IResourceManagerClient> createTestClient(int pid) {
201 return ::ndk::SharedRefBase::make<TestClient>(pid, mService);
202 }
203
Chong Zhanga9d45c72020-09-09 12:41:17 -0700204 sp<TestSystemCallback> mSystemCB;
205 std::shared_ptr<ResourceManagerService> mService;
206 std::shared_ptr<IResourceManagerClient> mTestClient1;
207 std::shared_ptr<IResourceManagerClient> mTestClient2;
208 std::shared_ptr<IResourceManagerClient> mTestClient3;
209
210protected:
211 static bool isEqualResources(const std::vector<MediaResourceParcel> &resources1,
212 const ResourceList &resources2) {
213 // convert resource1 to ResourceList
214 ResourceList r1;
215 for (size_t i = 0; i < resources1.size(); ++i) {
216 const auto &res = resources1[i];
217 const auto resType = std::tuple(res.type, res.subType, res.id);
218 r1[resType] = res;
219 }
220 return r1 == resources2;
221 }
222
223 static void expectEqResourceInfo(const ResourceInfo &info,
224 int uid,
225 std::shared_ptr<IResourceManagerClient> client,
226 const std::vector<MediaResourceParcel> &resources) {
227 EXPECT_EQ(uid, info.uid);
228 EXPECT_EQ(client, info.client);
229 EXPECT_TRUE(isEqualResources(resources, info.resources));
230 }
231};
232
233} // namespace android