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
isPidTrustedTestProcessInfo49 virtual bool isPidTrusted(int /* pid */) {
50 return true;
51 }
52
isPidUidTrustedTestProcessInfo53 virtual bool isPidUidTrusted(int /* pid */, int /* uid */) {
54 return true;
55 }
56
overrideProcessInfoTestProcessInfo57 virtual bool overrideProcessInfo(
58 int /* pid */, int /* procState */, int /* oomScore */) {
59 return true;
60 }
61
removeProcessInfoOverrideTestProcessInfo62 virtual void removeProcessInfoOverride(int /* pid */) {
63 }
64
65 private:
66 DISALLOW_EVIL_CONSTRUCTORS(TestProcessInfo);
67 };
68
69 struct TestSystemCallback :
70 public ResourceManagerService::SystemCallbackInterface {
TestSystemCallbackTestSystemCallback71 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
noteStartVideoTestSystemCallback88 virtual void noteStartVideo(int uid) override {
89 mLastEvent = {EventType::VIDEO_ON, uid};
90 mEventCount++;
91 }
92
noteStopVideoTestSystemCallback93 virtual void noteStopVideo(int uid) override {
94 mLastEvent = {EventType::VIDEO_OFF, uid};
95 mEventCount++;
96 }
97
noteResetVideoTestSystemCallback98 virtual void noteResetVideo() override {
99 mLastEvent = {EventType::VIDEO_RESET, 0};
100 mEventCount++;
101 }
102
requestCpusetBoostTestSystemCallback103 virtual bool requestCpusetBoost(bool enable) override {
104 mLastEvent = {enable ? EventType::CPUSET_ENABLE : EventType::CPUSET_DISABLE, 0};
105 mEventCount++;
106 return true;
107 }
108
eventCountTestSystemCallback109 size_t eventCount() { return mEventCount; }
lastEventTypeTestSystemCallback110 EventType lastEventType() { return mLastEvent.type; }
lastEventTestSystemCallback111 EventEntry lastEvent() { return mLastEvent; }
112
113 protected:
~TestSystemCallbackTestSystemCallback114 virtual ~TestSystemCallback() {}
115
116 private:
117 EventEntry mLastEvent;
118 size_t mEventCount;
119
120 DISALLOW_EVIL_CONSTRUCTORS(TestSystemCallback);
121 };
122
123
124 struct TestClient : public BnResourceManagerClient {
TestClientTestClient125 TestClient(int pid, const std::shared_ptr<ResourceManagerService> &service)
126 : mPid(pid), mService(service) {}
127
reclaimResourceTestClient128 Status reclaimResource(bool* _aidl_return) override {
129 mService->removeClient(mPid, getId(ref<TestClient>()));
130 mWasReclaimResourceCalled = true;
131 *_aidl_return = true;
132 return Status::ok();
133 }
134
getNameTestClient135 Status getName(::std::string* _aidl_return) override {
136 *_aidl_return = "test_client";
137 return Status::ok();
138 }
139
checkIfReclaimedAndResetTestClient140 bool checkIfReclaimedAndReset() {
141 bool wasReclaimResourceCalled = mWasReclaimResourceCalled;
142 mWasReclaimResourceCalled = false;
143 return wasReclaimResourceCalled;
144 }
145
~TestClientTestClient146 virtual ~TestClient() {}
147
148 private:
149 bool mWasReclaimResourceCalled = false;
150 int mPid;
151 std::shared_ptr<ResourceManagerService> mService;
152 DISALLOW_EVIL_CONSTRUCTORS(TestClient);
153 };
154
155 static const int kTestPid1 = 30;
156 static const int kTestUid1 = 1010;
157
158 static const int kTestPid2 = 20;
159 static const int kTestUid2 = 1011;
160
161 static const int kLowPriorityPid = 40;
162 static const int kMidPriorityPid = 25;
163 static const int kHighPriorityPid = 10;
164
165 using EventType = TestSystemCallback::EventType;
166 using EventEntry = TestSystemCallback::EventEntry;
167 bool operator== (const EventEntry& lhs, const EventEntry& rhs) {
168 return lhs.type == rhs.type && lhs.arg == rhs.arg;
169 }
170
171 // 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)
179
180 // 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)
188
189 class ResourceManagerServiceTestBase : public ::testing::Test {
190 public:
toTestClient(std::shared_ptr<IResourceManagerClient> testClient)191 static TestClient* toTestClient(std::shared_ptr<IResourceManagerClient> testClient) {
192 return static_cast<TestClient*>(testClient.get());
193 }
194
ResourceManagerServiceTestBase()195 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
createTestClient(int pid)204 std::shared_ptr<IResourceManagerClient> createTestClient(int pid) {
205 return ::ndk::SharedRefBase::make<TestClient>(pid, mService);
206 }
207
208 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
214 protected:
isEqualResources(const std::vector<MediaResourceParcel> & resources1,const ResourceList & resources2)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
expectEqResourceInfo(const ResourceInfo & info,int uid,std::shared_ptr<IResourceManagerClient> client,const std::vector<MediaResourceParcel> & resources)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
238