xref: /aosp_15_r20/frameworks/native/services/powermanager/tests/PowerHalWrapperAidlTest.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1 /*
2  * Copyright (C) 2020 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 #define LOG_TAG "PowerHalWrapperAidlTest"
18 
19 #include <aidl/android/hardware/power/Boost.h>
20 #include <aidl/android/hardware/power/IPowerHintSession.h>
21 #include <aidl/android/hardware/power/Mode.h>
22 #include <binder/IServiceManager.h>
23 #include <gmock/gmock.h>
24 #include <gtest/gtest.h>
25 #include <powermanager/PowerHalWrapper.h>
26 #include <utils/Log.h>
27 
28 #include <unistd.h>
29 #include <thread>
30 
31 
32 using android::binder::Status;
33 
34 using namespace aidl::android::hardware::power;
35 using namespace android;
36 using namespace android::power;
37 using namespace std::chrono_literals;
38 using namespace testing;
39 
40 // -------------------------------------------------------------------------------------------------
41 
42 class MockIPower : public IPower {
43 public:
44     MockIPower() = default;
45 
46     MOCK_METHOD(ndk::ScopedAStatus, isBoostSupported, (Boost boost, bool* ret), (override));
47     MOCK_METHOD(ndk::ScopedAStatus, setBoost, (Boost boost, int32_t durationMs), (override));
48     MOCK_METHOD(ndk::ScopedAStatus, isModeSupported, (Mode mode, bool* ret), (override));
49     MOCK_METHOD(ndk::ScopedAStatus, setMode, (Mode mode, bool enabled), (override));
50     MOCK_METHOD(ndk::ScopedAStatus, createHintSession,
51                 (int32_t tgid, int32_t uid, const std::vector<int32_t>& threadIds,
52                  int64_t durationNanos, std::shared_ptr<IPowerHintSession>* session),
53                 (override));
54     MOCK_METHOD(ndk::ScopedAStatus, createHintSessionWithConfig,
55                 (int32_t tgid, int32_t uid, const std::vector<int32_t>& threadIds,
56                  int64_t durationNanos, SessionTag tag, SessionConfig* config,
57                  std::shared_ptr<IPowerHintSession>* _aidl_return),
58                 (override));
59     MOCK_METHOD(ndk::ScopedAStatus, getSessionChannel,
60                 (int32_t tgid, int32_t uid, ChannelConfig* _aidl_return), (override));
61     MOCK_METHOD(ndk::ScopedAStatus, closeSessionChannel, (int32_t tgid, int32_t uid), (override));
62     MOCK_METHOD(ndk::ScopedAStatus, getHintSessionPreferredRate, (int64_t * rate), (override));
63     MOCK_METHOD(ndk::ScopedAStatus, getSupportInfo, (SupportInfo * _aidl_return), (override));
64     MOCK_METHOD(ndk::ScopedAStatus, getInterfaceVersion, (int32_t * version), (override));
65     MOCK_METHOD(ndk::ScopedAStatus, getInterfaceHash, (std::string * hash), (override));
66     MOCK_METHOD(ndk::SpAIBinder, asBinder, (), (override));
67     MOCK_METHOD(bool, isRemote, (), (override));
68     MOCK_METHOD(ndk::ScopedAStatus, getCpuHeadroom,
69                 (const CpuHeadroomParams& params, CpuHeadroomResult* headroom), (override));
70     MOCK_METHOD(ndk::ScopedAStatus, getGpuHeadroom,
71                 (const GpuHeadroomParams& params, GpuHeadroomResult* headroom), (override));
72     MOCK_METHOD(ndk::ScopedAStatus, sendCompositionData,
73                 (const std::vector<CompositionData>& in_data), (override));
74     MOCK_METHOD(ndk::ScopedAStatus, sendCompositionUpdate,
75                 (const CompositionUpdate& in_update), (override));
76 };
77 
78 // -------------------------------------------------------------------------------------------------
79 
80 class PowerHalWrapperAidlTest : public Test {
81 public:
82     void SetUp() override;
83 
84 protected:
85     std::unique_ptr<HalWrapper> mWrapper = nullptr;
86     std::shared_ptr<StrictMock<MockIPower>> mMockHal = nullptr;
87 };
88 
89 // -------------------------------------------------------------------------------------------------
90 
SetUp()91 void PowerHalWrapperAidlTest::SetUp() {
92     mMockHal = ndk::SharedRefBase::make<StrictMock<MockIPower>>();
93     EXPECT_CALL(*mMockHal, getInterfaceVersion(_)).WillRepeatedly(([](int32_t* ret) {
94         *ret = 5;
95         return ndk::ScopedAStatus::ok();
96     }));
97     mWrapper = std::make_unique<AidlHalWrapper>(mMockHal);
98     ASSERT_NE(nullptr, mWrapper);
99 }
100 
101 // -------------------------------------------------------------------------------------------------
102 
TEST_F(PowerHalWrapperAidlTest,TestSetBoostSuccessful)103 TEST_F(PowerHalWrapperAidlTest, TestSetBoostSuccessful) {
104     {
105         InSequence seq;
106         EXPECT_CALL(*mMockHal.get(), isBoostSupported(Eq(Boost::DISPLAY_UPDATE_IMMINENT), _))
107                 .Times(Exactly(1))
108                 .WillOnce(DoAll(SetArgPointee<1>(true),
109                                 Return(testing::ByMove(ndk::ScopedAStatus::ok()))));
110         EXPECT_CALL(*mMockHal.get(), setBoost(Eq(Boost::DISPLAY_UPDATE_IMMINENT), Eq(100)))
111                 .Times(Exactly(1))
112                 .WillOnce(Return(testing::ByMove(ndk::ScopedAStatus::ok())));
113     }
114 
115     auto result = mWrapper->setBoost(Boost::DISPLAY_UPDATE_IMMINENT, 100);
116     ASSERT_TRUE(result.isOk());
117 }
118 
TEST_F(PowerHalWrapperAidlTest,TestSetBoostFailed)119 TEST_F(PowerHalWrapperAidlTest, TestSetBoostFailed) {
120     {
121         InSequence seq;
122         EXPECT_CALL(*mMockHal.get(), isBoostSupported(Eq(Boost::INTERACTION), _))
123                 .Times(Exactly(1))
124                 .WillOnce(DoAll(SetArgPointee<1>(true),
125                                 Return(testing::ByMove(ndk::ScopedAStatus::ok()))));
126         EXPECT_CALL(*mMockHal.get(), setBoost(Eq(Boost::INTERACTION), Eq(100)))
127                 .Times(Exactly(1))
128                 .WillOnce(Return(testing::ByMove(ndk::ScopedAStatus::fromExceptionCode(-1))));
129         EXPECT_CALL(*mMockHal.get(), isBoostSupported(Eq(Boost::DISPLAY_UPDATE_IMMINENT), _))
130                 .Times(Exactly(1))
131                 .WillOnce(Return(testing::ByMove(ndk::ScopedAStatus::fromExceptionCode(-1))));
132     }
133 
134     auto result = mWrapper->setBoost(Boost::INTERACTION, 100);
135     ASSERT_TRUE(result.isFailed());
136     result = mWrapper->setBoost(Boost::DISPLAY_UPDATE_IMMINENT, 1000);
137     ASSERT_TRUE(result.isFailed());
138 }
139 
TEST_F(PowerHalWrapperAidlTest,TestSetBoostUnsupported)140 TEST_F(PowerHalWrapperAidlTest, TestSetBoostUnsupported) {
141     EXPECT_CALL(*mMockHal.get(), isBoostSupported(_, _))
142             .Times(Exactly(2))
143             .WillRepeatedly([](Boost, bool* ret) {
144                 *ret = false;
145                 return ndk::ScopedAStatus::ok();
146             });
147 
148     auto result = mWrapper->setBoost(Boost::INTERACTION, 1000);
149     ASSERT_TRUE(result.isUnsupported());
150     result = mWrapper->setBoost(Boost::CAMERA_SHOT, 10);
151     ASSERT_TRUE(result.isUnsupported());
152 }
153 
TEST_F(PowerHalWrapperAidlTest,TestSetBoostMultiThreadCheckSupportedOnlyOnce)154 TEST_F(PowerHalWrapperAidlTest, TestSetBoostMultiThreadCheckSupportedOnlyOnce) {
155     {
156         InSequence seq;
157         EXPECT_CALL(*mMockHal.get(), isBoostSupported(Eq(Boost::INTERACTION), _))
158                 .Times(Exactly(1))
159                 .WillOnce(DoAll(SetArgPointee<1>(true),
160                                 Return(testing::ByMove(ndk::ScopedAStatus::ok()))));
161         auto& exp = EXPECT_CALL(*mMockHal.get(), setBoost(Eq(Boost::INTERACTION), Eq(100)))
162                             .Times(Exactly(10));
163         for (int i = 0; i < 10; i++) {
164             exp.WillOnce(Return(testing::ByMove(ndk::ScopedAStatus::ok())));
165         }
166     }
167 
168     std::vector<std::thread> threads;
169     for (int i = 0; i < 10; i++) {
170         threads.push_back(std::thread([&]() {
171             auto result = mWrapper->setBoost(Boost::INTERACTION, 100);
172             ASSERT_TRUE(result.isOk());
173         }));
174     }
175     std::for_each(threads.begin(), threads.end(), [](std::thread& t) { t.join(); });
176 }
177 
TEST_F(PowerHalWrapperAidlTest,TestSetModeSuccessful)178 TEST_F(PowerHalWrapperAidlTest, TestSetModeSuccessful) {
179     {
180         InSequence seq;
181         EXPECT_CALL(*mMockHal.get(), isModeSupported(Eq(Mode::DISPLAY_INACTIVE), _))
182                 .Times(Exactly(1))
183                 .WillOnce(DoAll(SetArgPointee<1>(true),
184                                 Return(testing::ByMove(ndk::ScopedAStatus::ok()))));
185         EXPECT_CALL(*mMockHal.get(), setMode(Eq(Mode::DISPLAY_INACTIVE), Eq(false)))
186                 .Times(Exactly(1))
187                 .WillOnce(Return(testing::ByMove(ndk::ScopedAStatus::ok())));
188     }
189 
190     auto result = mWrapper->setMode(Mode::DISPLAY_INACTIVE, false);
191     ASSERT_TRUE(result.isOk());
192 }
193 
TEST_F(PowerHalWrapperAidlTest,TestSetModeFailed)194 TEST_F(PowerHalWrapperAidlTest, TestSetModeFailed) {
195     {
196         InSequence seq;
197         EXPECT_CALL(*mMockHal.get(), isModeSupported(Eq(Mode::LAUNCH), _))
198                 .Times(Exactly(1))
199                 .WillOnce(DoAll(SetArgPointee<1>(true),
200                                 Return(testing::ByMove(ndk::ScopedAStatus::ok()))));
201         EXPECT_CALL(*mMockHal.get(), setMode(Eq(Mode::LAUNCH), Eq(true)))
202                 .Times(Exactly(1))
203                 .WillOnce(Return(testing::ByMove(ndk::ScopedAStatus::fromExceptionCode(-1))));
204         EXPECT_CALL(*mMockHal.get(), isModeSupported(Eq(Mode::DISPLAY_INACTIVE), _))
205                 .Times(Exactly(1))
206                 .WillOnce(Return(testing::ByMove(ndk::ScopedAStatus::fromExceptionCode(-1))));
207     }
208 
209     auto result = mWrapper->setMode(Mode::LAUNCH, true);
210     ASSERT_TRUE(result.isFailed());
211     result = mWrapper->setMode(Mode::DISPLAY_INACTIVE, false);
212     ASSERT_TRUE(result.isFailed());
213 }
214 
TEST_F(PowerHalWrapperAidlTest,TestSetModeUnsupported)215 TEST_F(PowerHalWrapperAidlTest, TestSetModeUnsupported) {
216     EXPECT_CALL(*mMockHal.get(), isModeSupported(Eq(Mode::LAUNCH), _))
217             .Times(Exactly(1))
218             .WillOnce(DoAll(SetArgPointee<1>(false),
219                             Return(testing::ByMove(ndk::ScopedAStatus::ok()))));
220 
221     auto result = mWrapper->setMode(Mode::LAUNCH, true);
222     ASSERT_TRUE(result.isUnsupported());
223 
224     EXPECT_CALL(*mMockHal.get(), isModeSupported(Eq(Mode::CAMERA_STREAMING_HIGH), _))
225             .Times(Exactly(1))
226             .WillOnce(DoAll(SetArgPointee<1>(false),
227                             Return(testing::ByMove(ndk::ScopedAStatus::ok()))));
228     result = mWrapper->setMode(Mode::CAMERA_STREAMING_HIGH, true);
229     ASSERT_TRUE(result.isUnsupported());
230 }
231 
TEST_F(PowerHalWrapperAidlTest,TestSetModeMultiThreadCheckSupportedOnlyOnce)232 TEST_F(PowerHalWrapperAidlTest, TestSetModeMultiThreadCheckSupportedOnlyOnce) {
233     {
234         InSequence seq;
235         EXPECT_CALL(*mMockHal.get(), isModeSupported(Eq(Mode::LAUNCH), _))
236                 .Times(Exactly(1))
237                 .WillOnce(DoAll(SetArgPointee<1>(true),
238                                 Return(testing::ByMove(ndk::ScopedAStatus::ok()))));
239         auto& exp = EXPECT_CALL(*mMockHal.get(), setMode(Eq(Mode::LAUNCH), Eq(false)))
240                             .Times(Exactly(10));
241         for (int i = 0; i < 10; i++) {
242             exp.WillOnce(Return(testing::ByMove(ndk::ScopedAStatus::ok())));
243         }
244     }
245 
246     std::vector<std::thread> threads;
247     for (int i = 0; i < 10; i++) {
248         threads.push_back(std::thread([&]() {
249             auto result = mWrapper->setMode(Mode::LAUNCH, false);
250             ASSERT_TRUE(result.isOk());
251         }));
252     }
253     std::for_each(threads.begin(), threads.end(), [](std::thread& t) { t.join(); });
254 }
255 
TEST_F(PowerHalWrapperAidlTest,TestCreateHintSessionSuccessful)256 TEST_F(PowerHalWrapperAidlTest, TestCreateHintSessionSuccessful) {
257     std::vector<int> threadIds{gettid()};
258     int32_t tgid = 999;
259     int32_t uid = 1001;
260     int64_t durationNanos = 16666666L;
261     EXPECT_CALL(*mMockHal.get(),
262                 createHintSession(Eq(tgid), Eq(uid), Eq(threadIds), Eq(durationNanos), _))
263             .Times(Exactly(1))
264             .WillOnce(Return(testing::ByMove(ndk::ScopedAStatus::ok())));
265     auto result = mWrapper->createHintSession(tgid, uid, threadIds, durationNanos);
266     ASSERT_TRUE(result.isOk());
267 }
268 
TEST_F(PowerHalWrapperAidlTest,TestCreateHintSessionWithConfigSuccessful)269 TEST_F(PowerHalWrapperAidlTest, TestCreateHintSessionWithConfigSuccessful) {
270     std::vector<int> threadIds{gettid()};
271     int32_t tgid = 999;
272     int32_t uid = 1001;
273     int64_t durationNanos = 16666666L;
274     SessionTag tag = SessionTag::OTHER;
275     SessionConfig out;
276     EXPECT_CALL(*mMockHal.get(),
277                 createHintSessionWithConfig(Eq(tgid), Eq(uid), Eq(threadIds), Eq(durationNanos),
278                                             Eq(tag), _, _))
279             .Times(Exactly(1))
280             .WillOnce(Return(testing::ByMove(ndk::ScopedAStatus::ok())));
281     auto result =
282             mWrapper->createHintSessionWithConfig(tgid, uid, threadIds, durationNanos, tag, &out);
283     ASSERT_TRUE(result.isOk());
284 }
285 
TEST_F(PowerHalWrapperAidlTest,TestCreateHintSessionFailed)286 TEST_F(PowerHalWrapperAidlTest, TestCreateHintSessionFailed) {
287     int32_t tgid = 999;
288     int32_t uid = 1001;
289     std::vector<int> threadIds{};
290     int64_t durationNanos = 16666666L;
291     EXPECT_CALL(*mMockHal.get(),
292                 createHintSession(Eq(tgid), Eq(uid), Eq(threadIds), Eq(durationNanos), _))
293             .Times(Exactly(1))
294             .WillOnce(Return(testing::ByMove(
295                     ndk::ScopedAStatus::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT))));
296     auto result = mWrapper->createHintSession(tgid, uid, threadIds, durationNanos);
297     ASSERT_TRUE(result.isFailed());
298 }
299 
TEST_F(PowerHalWrapperAidlTest,TestGetHintSessionPreferredRate)300 TEST_F(PowerHalWrapperAidlTest, TestGetHintSessionPreferredRate) {
301     EXPECT_CALL(*mMockHal.get(), getHintSessionPreferredRate(_))
302             .Times(Exactly(1))
303             .WillOnce(Return(testing::ByMove(ndk::ScopedAStatus::ok())));
304     auto result = mWrapper->getHintSessionPreferredRate();
305     ASSERT_TRUE(result.isOk());
306     int64_t rate = result.value();
307     ASSERT_GE(0, rate);
308 }
309 
TEST_F(PowerHalWrapperAidlTest,TestSessionChannel)310 TEST_F(PowerHalWrapperAidlTest, TestSessionChannel) {
311     int32_t tgid = 999;
312     int32_t uid = 1001;
313     EXPECT_CALL(*mMockHal.get(), getSessionChannel(Eq(tgid), Eq(uid), _))
314             .Times(Exactly(1))
315             .WillOnce(Return(testing::ByMove(ndk::ScopedAStatus::ok())));
316     EXPECT_CALL(*mMockHal.get(), closeSessionChannel(Eq(tgid), Eq(uid)))
317             .Times(Exactly(1))
318             .WillOnce(Return(testing::ByMove(ndk::ScopedAStatus::ok())));
319     auto createResult = mWrapper->getSessionChannel(tgid, uid);
320     ASSERT_TRUE(createResult.isOk());
321     auto closeResult = mWrapper->closeSessionChannel(tgid, uid);
322     ASSERT_TRUE(closeResult.isOk());
323 }
324 
TEST_F(PowerHalWrapperAidlTest,TestCreateHintSessionWithConfigUnsupported)325 TEST_F(PowerHalWrapperAidlTest, TestCreateHintSessionWithConfigUnsupported) {
326     std::vector<int> threadIds{gettid()};
327     int32_t tgid = 999;
328     int32_t uid = 1001;
329     int64_t durationNanos = 16666666L;
330     SessionTag tag = SessionTag::OTHER;
331     SessionConfig out;
332     EXPECT_CALL(*mMockHal.get(),
333                 createHintSessionWithConfig(Eq(tgid), Eq(uid), Eq(threadIds), Eq(durationNanos),
334                                             Eq(tag), _, _))
335             .Times(1)
336             .WillOnce(Return(testing::ByMove(
337                     ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION))));
338     auto result =
339             mWrapper->createHintSessionWithConfig(tgid, uid, threadIds, durationNanos, tag, &out);
340     ASSERT_TRUE(result.isUnsupported());
341     Mock::VerifyAndClearExpectations(mMockHal.get());
342     EXPECT_CALL(*mMockHal.get(),
343                 createHintSessionWithConfig(Eq(tgid), Eq(uid), Eq(threadIds), Eq(durationNanos),
344                                             Eq(tag), _, _))
345             .WillOnce(Return(
346                     testing::ByMove(ndk::ScopedAStatus::fromStatus(STATUS_UNKNOWN_TRANSACTION))));
347     result = mWrapper->createHintSessionWithConfig(tgid, uid, threadIds, durationNanos, tag, &out);
348     ASSERT_TRUE(result.isUnsupported());
349 }
350