blob: 7bd9484f3a51be4c86725d0dff4d38a99b6d5ebf [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>
Atneya Nairf5b68512022-05-23 20:02:49 -040024#include <mediautils/ProcessInfoInterface.h>
Chong Zhanga9d45c72020-09-09 12:41:17 -070025
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
Brian Lindahlcf3bafb2022-01-27 14:21:38 +010049 virtual bool isPidTrusted(int /* pid */) {
50 return true;
51 }
52
53 virtual bool isPidUidTrusted(int /* pid */, int /* uid */) {
Chong Zhanga9d45c72020-09-09 12:41:17 -070054 return true;
55 }
56
Chong Zhang97d367b2020-09-16 12:53:14 -070057 virtual bool overrideProcessInfo(
58 int /* pid */, int /* procState */, int /* oomScore */) {
59 return true;
60 }
61
62 virtual void removeProcessInfoOverride(int /* pid */) {
63 }
64
Chong Zhanga9d45c72020-09-09 12:41:17 -070065private:
66 DISALLOW_EVIL_CONSTRUCTORS(TestProcessInfo);
67};
68
69struct TestSystemCallback :
70 public ResourceManagerService::SystemCallbackInterface {
71 TestSystemCallback() :
72 mLastEvent({EventType::INVALID, 0}), mEventCount(0) {}
73
74 enum EventType {
75 INVALID = -1,
76 VIDEO_ON = 0,
77 VIDEO_OFF = 1,
78 VIDEO_RESET = 2,
79 CPUSET_ENABLE = 3,
80 CPUSET_DISABLE = 4,
81 };
82
83 struct EventEntry {
84 EventType type;
85 int arg;
86 };
87
88 virtual void noteStartVideo(int uid) override {
89 mLastEvent = {EventType::VIDEO_ON, uid};
90 mEventCount++;
91 }
92
93 virtual void noteStopVideo(int uid) override {
94 mLastEvent = {EventType::VIDEO_OFF, uid};
95 mEventCount++;
96 }
97
98 virtual void noteResetVideo() override {
99 mLastEvent = {EventType::VIDEO_RESET, 0};
100 mEventCount++;
101 }
102
103 virtual bool requestCpusetBoost(bool enable) override {
104 mLastEvent = {enable ? EventType::CPUSET_ENABLE : EventType::CPUSET_DISABLE, 0};
105 mEventCount++;
106 return true;
107 }
108
109 size_t eventCount() { return mEventCount; }
110 EventType lastEventType() { return mLastEvent.type; }
111 EventEntry lastEvent() { return mLastEvent; }
112
113protected:
114 virtual ~TestSystemCallback() {}
115
116private:
117 EventEntry mLastEvent;
118 size_t mEventCount;
119
120 DISALLOW_EVIL_CONSTRUCTORS(TestSystemCallback);
121};
122
123
124struct TestClient : public BnResourceManagerClient {
125 TestClient(int pid, const std::shared_ptr<ResourceManagerService> &service)
Brian Lindahl64ee9452022-01-14 13:31:16 +0100126 : mPid(pid), mService(service) {}
Chong Zhanga9d45c72020-09-09 12:41:17 -0700127
128 Status reclaimResource(bool* _aidl_return) override {
129 mService->removeClient(mPid, getId(ref<TestClient>()));
Brian Lindahl64ee9452022-01-14 13:31:16 +0100130 mWasReclaimResourceCalled = true;
Chong Zhanga9d45c72020-09-09 12:41:17 -0700131 *_aidl_return = true;
132 return Status::ok();
133 }
134
135 Status getName(::std::string* _aidl_return) override {
136 *_aidl_return = "test_client";
137 return Status::ok();
138 }
139
Brian Lindahl64ee9452022-01-14 13:31:16 +0100140 bool checkIfReclaimedAndReset() {
141 bool wasReclaimResourceCalled = mWasReclaimResourceCalled;
142 mWasReclaimResourceCalled = false;
143 return wasReclaimResourceCalled;
Chong Zhanga9d45c72020-09-09 12:41:17 -0700144 }
145
146 virtual ~TestClient() {}
147
148private:
Brian Lindahl64ee9452022-01-14 13:31:16 +0100149 bool mWasReclaimResourceCalled = false;
Chong Zhanga9d45c72020-09-09 12:41:17 -0700150 int mPid;
151 std::shared_ptr<ResourceManagerService> mService;
152 DISALLOW_EVIL_CONSTRUCTORS(TestClient);
153};
154
155static const int kTestPid1 = 30;
156static const int kTestUid1 = 1010;
157
158static const int kTestPid2 = 20;
159static const int kTestUid2 = 1011;
160
161static const int kLowPriorityPid = 40;
162static const int kMidPriorityPid = 25;
163static const int kHighPriorityPid = 10;
164
165using EventType = TestSystemCallback::EventType;
166using EventEntry = TestSystemCallback::EventEntry;
167bool operator== (const EventEntry& lhs, const EventEntry& rhs) {
168 return lhs.type == rhs.type && lhs.arg == rhs.arg;
169}
170
Brian Lindahl64ee9452022-01-14 13:31:16 +0100171// The condition is expected to return a status but also update the local
172// result variable.
173#define CHECK_STATUS_TRUE(conditionThatUpdatesResult) \
174 do { \
175 bool result = false; \
176 EXPECT_TRUE((conditionThatUpdatesResult).isOk()); \
177 EXPECT_TRUE(result); \
178 } while(false)
Chong Zhanga9d45c72020-09-09 12:41:17 -0700179
Brian Lindahl64ee9452022-01-14 13:31:16 +0100180// The condition is expected to return a status but also update the local
181// result variable.
182#define CHECK_STATUS_FALSE(conditionThatUpdatesResult) \
183 do { \
184 bool result = true; \
185 EXPECT_TRUE((conditionThatUpdatesResult).isOk()); \
186 EXPECT_FALSE(result); \
187 } while(false)
Chong Zhanga9d45c72020-09-09 12:41:17 -0700188
189class ResourceManagerServiceTestBase : public ::testing::Test {
190public:
Brian Lindahl64ee9452022-01-14 13:31:16 +0100191 static TestClient* toTestClient(std::shared_ptr<IResourceManagerClient> testClient) {
192 return static_cast<TestClient*>(testClient.get());
193 }
194
Chong Zhanga9d45c72020-09-09 12:41:17 -0700195 ResourceManagerServiceTestBase()
196 : mSystemCB(new TestSystemCallback()),
197 mService(::ndk::SharedRefBase::make<ResourceManagerService>(
198 new TestProcessInfo, mSystemCB)),
199 mTestClient1(::ndk::SharedRefBase::make<TestClient>(kTestPid1, mService)),
200 mTestClient2(::ndk::SharedRefBase::make<TestClient>(kTestPid2, mService)),
201 mTestClient3(::ndk::SharedRefBase::make<TestClient>(kTestPid2, mService)) {
202 }
203
Brian Lindahl64ee9452022-01-14 13:31:16 +0100204 std::shared_ptr<IResourceManagerClient> createTestClient(int pid) {
205 return ::ndk::SharedRefBase::make<TestClient>(pid, mService);
206 }
207
Chong Zhanga9d45c72020-09-09 12:41:17 -0700208 sp<TestSystemCallback> mSystemCB;
209 std::shared_ptr<ResourceManagerService> mService;
210 std::shared_ptr<IResourceManagerClient> mTestClient1;
211 std::shared_ptr<IResourceManagerClient> mTestClient2;
212 std::shared_ptr<IResourceManagerClient> mTestClient3;
213
214protected:
215 static bool isEqualResources(const std::vector<MediaResourceParcel> &resources1,
216 const ResourceList &resources2) {
217 // convert resource1 to ResourceList
218 ResourceList r1;
219 for (size_t i = 0; i < resources1.size(); ++i) {
220 const auto &res = resources1[i];
221 const auto resType = std::tuple(res.type, res.subType, res.id);
222 r1[resType] = res;
223 }
224 return r1 == resources2;
225 }
226
227 static void expectEqResourceInfo(const ResourceInfo &info,
228 int uid,
229 std::shared_ptr<IResourceManagerClient> client,
230 const std::vector<MediaResourceParcel> &resources) {
231 EXPECT_EQ(uid, info.uid);
232 EXPECT_EQ(client, info.client);
233 EXPECT_TRUE(isEqualResources(resources, info.resources));
234 }
235};
236
237} // namespace android