1 /*
2  * Copyright 2023 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 <errno.h>
18 #include <sched.h>
19 
20 #include <android/gui/ISurfaceComposer.h>
21 #include <android/gui/ISurfaceComposerClient.h>
22 #include <binder/IBinder.h>
23 #include <binder/IServiceManager.h>
24 #include <gtest/gtest.h>
25 #include <gui/ISurfaceComposer.h>
26 
27 #include <com_android_graphics_surfaceflinger_flags.h>
28 
29 namespace android::test {
30 using namespace com::android::graphics::surfaceflinger;
31 
32 class BinderTest : public ::testing::Test {
33 protected:
34     BinderTest();
35 
36     void SetUp() override;
37 
38     void getSchedulingPolicy(gui::SchedulingPolicy* outPolicy);
39     void getNonAidlSchedulingPolicy(gui::SchedulingPolicy* outPolicy);
40     void getClientSchedulingPolicy(gui::SchedulingPolicy* outPolicy);
41     void getDisplayEventConnectionSchedulingPolicy(gui::SchedulingPolicy* outPolicy);
42 
43 private:
44     sp<gui::ISurfaceComposer> mISurfaceComposerAidl;
45     sp<ISurfaceComposer> mISurfaceComposer;
46     sp<gui::ISurfaceComposerClient> mISurfaceComposerClient;
47     sp<gui::IDisplayEventConnection> mConnection;
48 };
49 
BinderTest()50 BinderTest::BinderTest() {
51     const String16 name("SurfaceFlingerAIDL");
52     mISurfaceComposerAidl = waitForService<gui::ISurfaceComposer>(String16("SurfaceFlingerAIDL"));
53     mISurfaceComposer = waitForService<ISurfaceComposer>(String16("SurfaceFlinger"));
54     mISurfaceComposerAidl->createConnection(&mISurfaceComposerClient);
55     mISurfaceComposerAidl
56             ->createDisplayEventConnection(gui::ISurfaceComposer::VsyncSource::eVsyncSourceApp,
57                                            gui::ISurfaceComposer::EventRegistration(0), {},
58                                            &mConnection);
59 }
60 
SetUp()61 void BinderTest::SetUp() {
62     ASSERT_TRUE(mISurfaceComposerAidl);
63     ASSERT_TRUE(mISurfaceComposer);
64     ASSERT_TRUE(mISurfaceComposerClient);
65     ASSERT_TRUE(mConnection);
66 }
67 
getSchedulingPolicy(gui::SchedulingPolicy * outPolicy)68 void BinderTest::getSchedulingPolicy(gui::SchedulingPolicy* outPolicy) {
69     const auto status = mISurfaceComposerAidl->getSchedulingPolicy(outPolicy);
70     ASSERT_TRUE(status.isOk());
71 }
72 
getNonAidlSchedulingPolicy(gui::SchedulingPolicy * outPolicy)73 void BinderTest::getNonAidlSchedulingPolicy(gui::SchedulingPolicy* outPolicy) {
74     Parcel data, reply;
75     const status_t status =
76             IInterface::asBinder(mISurfaceComposer)
77                     ->transact(BnSurfaceComposer::GET_SCHEDULING_POLICY, data, &reply);
78     ASSERT_EQ(OK, status);
79 
80     outPolicy->policy = reply.readInt32();
81     outPolicy->priority = reply.readInt32();
82 }
83 
getClientSchedulingPolicy(gui::SchedulingPolicy * outPolicy)84 void BinderTest::getClientSchedulingPolicy(gui::SchedulingPolicy* outPolicy) {
85     const auto status = mISurfaceComposerClient->getSchedulingPolicy(outPolicy);
86     ASSERT_TRUE(status.isOk());
87 }
88 
getDisplayEventConnectionSchedulingPolicy(gui::SchedulingPolicy * outPolicy)89 void BinderTest::getDisplayEventConnectionSchedulingPolicy(gui::SchedulingPolicy* outPolicy) {
90     const auto status = mConnection->getSchedulingPolicy(outPolicy);
91     ASSERT_TRUE(status.isOk());
92 }
93 
TEST_F(BinderTest,SchedulingPolicy)94 TEST_F(BinderTest, SchedulingPolicy) {
95     if (!flags::misc1()) GTEST_SKIP();
96 
97     const int policy = SCHED_FIFO;
98     const int priority = sched_get_priority_min(policy);
99 
100     gui::SchedulingPolicy sfPolicy;
101     ASSERT_NO_FATAL_FAILURE(getSchedulingPolicy(&sfPolicy));
102 
103     ASSERT_EQ(policy, sfPolicy.policy & (~SCHED_RESET_ON_FORK));
104     ASSERT_EQ(priority, sfPolicy.priority);
105 }
106 
TEST_F(BinderTest,NonAidlSchedulingPolicy)107 TEST_F(BinderTest, NonAidlSchedulingPolicy) {
108     const int policy = SCHED_FIFO;
109     const int priority = sched_get_priority_min(policy);
110 
111     gui::SchedulingPolicy sfPolicy;
112     ASSERT_NO_FATAL_FAILURE(getNonAidlSchedulingPolicy(&sfPolicy));
113 
114     ASSERT_EQ(policy, sfPolicy.policy & (~SCHED_RESET_ON_FORK));
115     ASSERT_EQ(priority, sfPolicy.priority);
116 }
117 
TEST_F(BinderTest,ClientSchedulingPolicy)118 TEST_F(BinderTest, ClientSchedulingPolicy) {
119     if (!flags::misc1()) GTEST_SKIP();
120 
121     const int policy = SCHED_FIFO;
122     const int priority = sched_get_priority_min(policy);
123 
124     gui::SchedulingPolicy sfPolicy;
125     ASSERT_NO_FATAL_FAILURE(getClientSchedulingPolicy(&sfPolicy));
126 
127     ASSERT_EQ(policy, sfPolicy.policy & (~SCHED_RESET_ON_FORK));
128     ASSERT_EQ(priority, sfPolicy.priority);
129 }
130 
TEST_F(BinderTest,DisplayEventConnectionSchedulingPolicy)131 TEST_F(BinderTest, DisplayEventConnectionSchedulingPolicy) {
132     if (!flags::misc1()) GTEST_SKIP();
133 
134     const int policy = SCHED_FIFO;
135     const int priority = sched_get_priority_min(policy);
136 
137     gui::SchedulingPolicy sfPolicy;
138     ASSERT_NO_FATAL_FAILURE(getDisplayEventConnectionSchedulingPolicy(&sfPolicy));
139 
140     ASSERT_EQ(policy, sfPolicy.policy & (~SCHED_RESET_ON_FORK));
141     ASSERT_EQ(priority, sfPolicy.priority);
142 }
143 
144 class BinderTestRtCaller : public BinderTest {
145 protected:
146     void SetUp() override;
147     void TearDown() override;
148 
149 private:
150     int mOrigPolicy;
151     int mOrigPriority;
152 };
153 
SetUp()154 void BinderTestRtCaller::SetUp() {
155     const int policy = SCHED_FIFO;
156     const int priority = sched_get_priority_min(policy);
157 
158     mOrigPolicy = sched_getscheduler(0);
159     struct sched_param origSchedParam;
160     ASSERT_GE(0, sched_getparam(0, &origSchedParam)) << "errno: " << strerror(errno);
161     mOrigPriority = origSchedParam.sched_priority;
162 
163     struct sched_param param;
164     param.sched_priority = priority;
165     ASSERT_GE(0, sched_setscheduler(0, policy, &param)) << "errno: " << strerror(errno);
166 }
167 
TearDown()168 void BinderTestRtCaller::TearDown() {
169     struct sched_param origSchedParam;
170     origSchedParam.sched_priority = mOrigPriority;
171     ASSERT_GE(0, sched_setscheduler(0, mOrigPolicy, &origSchedParam))
172             << "errno: " << strerror(errno);
173 }
174 
TEST_F(BinderTestRtCaller,SchedulingPolicy)175 TEST_F(BinderTestRtCaller, SchedulingPolicy) {
176     if (!flags::misc1()) GTEST_SKIP();
177 
178     const int policy = SCHED_FIFO;
179     const int priority = sched_get_priority_min(policy);
180 
181     gui::SchedulingPolicy sfPolicy;
182     ASSERT_NO_FATAL_FAILURE(getSchedulingPolicy(&sfPolicy));
183 
184     ASSERT_EQ(policy, sfPolicy.policy & (~SCHED_RESET_ON_FORK));
185     ASSERT_EQ(priority, sfPolicy.priority);
186 }
187 
TEST_F(BinderTestRtCaller,NonAidlSchedulingPolicy)188 TEST_F(BinderTestRtCaller, NonAidlSchedulingPolicy) {
189     const int policy = SCHED_FIFO;
190     const int priority = sched_get_priority_min(policy);
191 
192     gui::SchedulingPolicy sfPolicy;
193     ASSERT_NO_FATAL_FAILURE(getNonAidlSchedulingPolicy(&sfPolicy));
194 
195     ASSERT_EQ(policy, sfPolicy.policy & (~SCHED_RESET_ON_FORK));
196     ASSERT_EQ(priority, sfPolicy.priority);
197 }
198 
TEST_F(BinderTestRtCaller,ClientSchedulingPolicy)199 TEST_F(BinderTestRtCaller, ClientSchedulingPolicy) {
200     if (!flags::misc1()) GTEST_SKIP();
201 
202     const int policy = SCHED_FIFO;
203     const int priority = sched_get_priority_min(policy);
204 
205     gui::SchedulingPolicy sfPolicy;
206     ASSERT_NO_FATAL_FAILURE(getClientSchedulingPolicy(&sfPolicy));
207 
208     ASSERT_EQ(policy, sfPolicy.policy & (~SCHED_RESET_ON_FORK));
209     ASSERT_EQ(priority, sfPolicy.priority);
210 }
211 
TEST_F(BinderTestRtCaller,DisplayEventConnectionSchedulingPolicy)212 TEST_F(BinderTestRtCaller, DisplayEventConnectionSchedulingPolicy) {
213     if (!flags::misc1()) GTEST_SKIP();
214 
215     const int policy = SCHED_FIFO;
216     const int priority = sched_get_priority_min(policy);
217 
218     gui::SchedulingPolicy sfPolicy;
219     ASSERT_NO_FATAL_FAILURE(getDisplayEventConnectionSchedulingPolicy(&sfPolicy));
220 
221     ASSERT_EQ(policy, sfPolicy.policy & (~SCHED_RESET_ON_FORK));
222     ASSERT_EQ(priority, sfPolicy.priority);
223 }
224 
225 } // namespace android::test
226