xref: /aosp_15_r20/frameworks/base/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp (revision d57664e9bc4670b3ecf6748a746a57c557b6bc9e)
1 /*
2  * Copyright (C) 2021 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 "PerformanceHintNativeTest"
18 
19 #include <aidl/android/hardware/power/ChannelConfig.h>
20 #include <aidl/android/hardware/power/SessionConfig.h>
21 #include <aidl/android/hardware/power/SessionMode.h>
22 #include <aidl/android/hardware/power/SessionTag.h>
23 #include <aidl/android/hardware/power/WorkDuration.h>
24 #include <aidl/android/os/IHintManager.h>
25 #include <aidl/android/os/SessionCreationConfig.h>
26 #include <android/binder_manager.h>
27 #include <android/binder_status.h>
28 #include <android/performance_hint.h>
29 #include <fmq/AidlMessageQueue.h>
30 #include <gmock/gmock.h>
31 #include <gtest/gtest.h>
32 #include <performance_hint_private.h>
33 
34 #include <memory>
35 #include <vector>
36 
37 using namespace std::chrono_literals;
38 namespace hal = aidl::android::hardware::power;
39 using aidl::android::os::IHintManager;
40 using aidl::android::os::IHintSession;
41 using aidl::android::os::SessionCreationConfig;
42 using ndk::ScopedAStatus;
43 using ndk::SpAIBinder;
44 using HalChannelMessageContents = hal::ChannelMessage::ChannelMessageContents;
45 
46 using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
47 using HalFlagQueue = ::android::AidlMessageQueue<int8_t, SynchronizedReadWrite>;
48 
49 using namespace android;
50 using namespace testing;
51 
52 class MockIHintManager : public IHintManager {
53 public:
54     MOCK_METHOD(ScopedAStatus, createHintSessionWithConfig,
55                 (const SpAIBinder& token, hal::SessionTag tag,
56                  const SessionCreationConfig& creationConfig, hal::SessionConfig* config,
57                  std::shared_ptr<IHintSession>* _aidl_return),
58                 (override));
59     MOCK_METHOD(ScopedAStatus, getHintSessionPreferredRate, (int64_t * _aidl_return), (override));
60     MOCK_METHOD(ScopedAStatus, getMaxGraphicsPipelineThreadsCount, (int32_t* _aidl_return),
61                 (override));
62     MOCK_METHOD(ScopedAStatus, setHintSessionThreads,
63                 (const std::shared_ptr<IHintSession>& hintSession,
64                  const ::std::vector<int32_t>& tids),
65                 (override));
66     MOCK_METHOD(ScopedAStatus, getHintSessionThreadIds,
67                 (const std::shared_ptr<IHintSession>& hintSession, ::std::vector<int32_t>* tids),
68                 (override));
69     MOCK_METHOD(ScopedAStatus, getSessionChannel,
70                 (const ::ndk::SpAIBinder& in_token,
71                  std::optional<hal::ChannelConfig>* _aidl_return),
72                 (override));
73     MOCK_METHOD(ScopedAStatus, closeSessionChannel, (), (override));
74     MOCK_METHOD(ScopedAStatus, getCpuHeadroom,
75                 (const ::aidl::android::os::CpuHeadroomParamsInternal& in_params,
76                  std::optional<hal::CpuHeadroomResult>* _aidl_return),
77                 (override));
78     MOCK_METHOD(ScopedAStatus, getCpuHeadroomMinIntervalMillis, (int64_t* _aidl_return),
79                 (override));
80     MOCK_METHOD(ScopedAStatus, getGpuHeadroom,
81                 (const ::aidl::android::os::GpuHeadroomParamsInternal& in_params,
82                  std::optional<hal::GpuHeadroomResult>* _aidl_return),
83                 (override));
84     MOCK_METHOD(ScopedAStatus, getGpuHeadroomMinIntervalMillis, (int64_t* _aidl_return),
85                 (override));
86     MOCK_METHOD(ScopedAStatus, passSessionManagerBinder, (const SpAIBinder& sessionManager));
87     MOCK_METHOD(SpAIBinder, asBinder, (), (override));
88     MOCK_METHOD(bool, isRemote, (), (override));
89 };
90 
91 class MockIHintSession : public IHintSession {
92 public:
93     MOCK_METHOD(ScopedAStatus, updateTargetWorkDuration, (int64_t targetDurationNanos), (override));
94     MOCK_METHOD(ScopedAStatus, reportActualWorkDuration,
95                 (const ::std::vector<int64_t>& actualDurationNanos,
96                  const ::std::vector<int64_t>& timeStampNanos),
97                 (override));
98     MOCK_METHOD(ScopedAStatus, sendHint, (int32_t hint), (override));
99     MOCK_METHOD(ScopedAStatus, setMode, (int32_t mode, bool enabled), (override));
100     MOCK_METHOD(ScopedAStatus, close, (), (override));
101     MOCK_METHOD(ScopedAStatus, reportActualWorkDuration2,
102                 (const ::std::vector<hal::WorkDuration>& workDurations), (override));
103     MOCK_METHOD(ScopedAStatus, associateToLayers,
104                 (const std::vector<::ndk::SpAIBinder>& in_layerTokens), (override));
105     MOCK_METHOD(SpAIBinder, asBinder, (), (override));
106     MOCK_METHOD(bool, isRemote, (), (override));
107 };
108 
109 class PerformanceHintTest : public Test {
110 public:
SetUp()111     void SetUp() override {
112         mMockIHintManager = ndk::SharedRefBase::make<NiceMock<MockIHintManager>>();
113         APerformanceHint_getRateLimiterPropertiesForTesting(&mMaxLoadHintsPerInterval,
114                                                             &mLoadHintInterval);
115         APerformanceHint_setIHintManagerForTesting(&mMockIHintManager);
116         APerformanceHint_setUseGraphicsPipelineForTesting(true);
117         APerformanceHint_setUseNewLoadHintBehaviorForTesting(true);
118     }
119 
TearDown()120     void TearDown() override {
121         mMockIHintManager = nullptr;
122         // Destroys MockIHintManager.
123         APerformanceHint_setIHintManagerForTesting(nullptr);
124     }
125 
createManager()126     APerformanceHintManager* createManager() {
127         APerformanceHint_setUseFMQForTesting(mUsingFMQ);
128         ON_CALL(*mMockIHintManager, getHintSessionPreferredRate(_))
129                 .WillByDefault(DoAll(SetArgPointee<0>(123L), [] { return ScopedAStatus::ok(); }));
130         ON_CALL(*mMockIHintManager, getMaxGraphicsPipelineThreadsCount(_))
131                 .WillByDefault(DoAll(SetArgPointee<0>(5), [] { return ScopedAStatus::ok(); }));
132         return APerformanceHint_getManager();
133     }
134 
createSession(APerformanceHintManager * manager,int64_t targetDuration=56789L,bool isHwui=false)135     APerformanceHintSession* createSession(APerformanceHintManager* manager,
136                                            int64_t targetDuration = 56789L, bool isHwui = false) {
137         mMockSession = ndk::SharedRefBase::make<NiceMock<MockIHintSession>>();
138         const int64_t sessionId = 123;
139         std::vector<int32_t> tids;
140         tids.push_back(1);
141         tids.push_back(2);
142 
143         ON_CALL(*mMockIHintManager, createHintSessionWithConfig(_, _, _, _, _))
144                 .WillByDefault(DoAll(SetArgPointee<3>(hal::SessionConfig({.id = sessionId})),
145                                      SetArgPointee<4>(std::shared_ptr<IHintSession>(mMockSession)),
146                                      [] { return ScopedAStatus::ok(); }));
147 
148         ON_CALL(*mMockIHintManager, setHintSessionThreads(_, _)).WillByDefault([] {
149             return ScopedAStatus::ok();
150         });
151         ON_CALL(*mMockSession, sendHint(_)).WillByDefault([] { return ScopedAStatus::ok(); });
152         ON_CALL(*mMockSession, setMode(_, _)).WillByDefault([] { return ScopedAStatus::ok(); });
153         ON_CALL(*mMockSession, close()).WillByDefault([] { return ScopedAStatus::ok(); });
154         ON_CALL(*mMockSession, updateTargetWorkDuration(_)).WillByDefault([] {
155             return ScopedAStatus::ok();
156         });
157         ON_CALL(*mMockSession, reportActualWorkDuration(_, _)).WillByDefault([] {
158             return ScopedAStatus::ok();
159         });
160         ON_CALL(*mMockSession, reportActualWorkDuration2(_)).WillByDefault([] {
161             return ScopedAStatus::ok();
162         });
163         if (isHwui) {
164             return APerformanceHint_createSessionInternal(manager, tids.data(), tids.size(),
165                                                           targetDuration, SessionTag::HWUI);
166         }
167         return APerformanceHint_createSession(manager, tids.data(), tids.size(), targetDuration);
168     }
169 
createSessionUsingConfig(APerformanceHintManager * manager,SessionCreationConfig config,bool isHwui=false)170     APerformanceHintSession* createSessionUsingConfig(APerformanceHintManager* manager,
171                                                       SessionCreationConfig config,
172                                                       bool isHwui = false) {
173         mMockSession = ndk::SharedRefBase::make<NiceMock<MockIHintSession>>();
174         const int64_t sessionId = 123;
175 
176         ON_CALL(*mMockIHintManager, createHintSessionWithConfig(_, _, _, _, _))
177                 .WillByDefault(DoAll(SetArgPointee<3>(hal::SessionConfig({.id = sessionId})),
178                                      SetArgPointee<4>(std::shared_ptr<IHintSession>(mMockSession)),
179                                      [] { return ScopedAStatus::ok(); }));
180 
181         ON_CALL(*mMockIHintManager, setHintSessionThreads(_, _)).WillByDefault([] {
182             return ScopedAStatus::ok();
183         });
184         ON_CALL(*mMockSession, sendHint(_)).WillByDefault([] { return ScopedAStatus::ok(); });
185         ON_CALL(*mMockSession, setMode(_, true)).WillByDefault([] { return ScopedAStatus::ok(); });
186         ON_CALL(*mMockSession, close()).WillByDefault([] { return ScopedAStatus::ok(); });
187         ON_CALL(*mMockSession, updateTargetWorkDuration(_)).WillByDefault([] {
188             return ScopedAStatus::ok();
189         });
190         ON_CALL(*mMockSession, reportActualWorkDuration(_, _)).WillByDefault([] {
191             return ScopedAStatus::ok();
192         });
193         ON_CALL(*mMockSession, reportActualWorkDuration2(_)).WillByDefault([] {
194             return ScopedAStatus::ok();
195         });
196 
197         if (isHwui) {
198             return APerformanceHint_createSessionUsingConfigInternal(
199                     manager, reinterpret_cast<ASessionCreationConfig*>(&config), SessionTag::HWUI);
200         }
201 
202         return APerformanceHint_createSessionUsingConfig(manager,
203                                                          reinterpret_cast<ASessionCreationConfig*>(
204                                                                  &config));
205     }
206 
setFMQEnabled(bool enabled)207     void setFMQEnabled(bool enabled) {
208         mUsingFMQ = enabled;
209         if (enabled) {
210             mMockFMQ = std::make_shared<
211                     AidlMessageQueue<hal::ChannelMessage, SynchronizedReadWrite>>(kMockQueueSize,
212                                                                                   true);
213             mMockFlagQueue =
214                     std::make_shared<AidlMessageQueue<int8_t, SynchronizedReadWrite>>(1, true);
215             hardware::EventFlag::createEventFlag(mMockFlagQueue->getEventFlagWord(), &mEventFlag);
216 
217             ON_CALL(*mMockIHintManager, getSessionChannel(_, _))
218                     .WillByDefault([&](ndk::SpAIBinder, std::optional<hal::ChannelConfig>* config) {
219                         config->emplace(
220                                 hal::ChannelConfig{.channelDescriptor = mMockFMQ->dupeDesc(),
221                                                    .eventFlagDescriptor =
222                                                            mMockFlagQueue->dupeDesc(),
223                                                    .readFlagBitmask =
224                                                            static_cast<int32_t>(mReadBits),
225                                                    .writeFlagBitmask =
226                                                            static_cast<int32_t>(mWriteBits)});
227                         return ::ndk::ScopedAStatus::ok();
228                     });
229         }
230     }
231     uint32_t mReadBits = 0x00000001;
232     uint32_t mWriteBits = 0x00000002;
233     std::shared_ptr<NiceMock<MockIHintManager>> mMockIHintManager = nullptr;
234     std::shared_ptr<NiceMock<MockIHintSession>> mMockSession = nullptr;
235     std::shared_ptr<AidlMessageQueue<hal::ChannelMessage, SynchronizedReadWrite>> mMockFMQ;
236     std::shared_ptr<AidlMessageQueue<int8_t, SynchronizedReadWrite>> mMockFlagQueue;
237     hardware::EventFlag* mEventFlag;
238     int kMockQueueSize = 20;
239     bool mUsingFMQ = false;
240 
241     int32_t mMaxLoadHintsPerInterval;
242     int64_t mLoadHintInterval;
243 
244     template <HalChannelMessageContents::Tag T, class C = HalChannelMessageContents::_at<T>>
expectToReadFromFmq(C expected)245     void expectToReadFromFmq(C expected) {
246         hal::ChannelMessage readData;
247         mMockFMQ->readBlocking(&readData, 1, mReadBits, mWriteBits, 1000000000, mEventFlag);
248         C got = static_cast<C>(readData.data.get<T>());
249         ASSERT_EQ(got, expected);
250     }
251 };
252 
equalsWithoutTimestamp(hal::WorkDuration lhs,hal::WorkDuration rhs)253 bool equalsWithoutTimestamp(hal::WorkDuration lhs, hal::WorkDuration rhs) {
254     return lhs.workPeriodStartTimestampNanos == rhs.workPeriodStartTimestampNanos &&
255             lhs.cpuDurationNanos == rhs.cpuDurationNanos &&
256             lhs.gpuDurationNanos == rhs.gpuDurationNanos && lhs.durationNanos == rhs.durationNanos;
257 }
258 
TEST_F(PerformanceHintTest,TestGetPreferredUpdateRateNanos)259 TEST_F(PerformanceHintTest, TestGetPreferredUpdateRateNanos) {
260     APerformanceHintManager* manager = createManager();
261     int64_t preferredUpdateRateNanos = APerformanceHint_getPreferredUpdateRateNanos(manager);
262     EXPECT_EQ(123L, preferredUpdateRateNanos);
263 }
264 
TEST_F(PerformanceHintTest,TestSession)265 TEST_F(PerformanceHintTest, TestSession) {
266     APerformanceHintManager* manager = createManager();
267     APerformanceHintSession* session = createSession(manager);
268     ASSERT_TRUE(session);
269 
270     int64_t targetDurationNanos = 10;
271     EXPECT_CALL(*mMockSession, updateTargetWorkDuration(Eq(targetDurationNanos))).Times(Exactly(1));
272     int result = APerformanceHint_updateTargetWorkDuration(session, targetDurationNanos);
273     EXPECT_EQ(0, result);
274 
275     // subsequent call with same target should be ignored but return no error
276     result = APerformanceHint_updateTargetWorkDuration(session, targetDurationNanos);
277     EXPECT_EQ(0, result);
278 
279     usleep(2); // Sleep for longer than preferredUpdateRateNanos.
280     int64_t actualDurationNanos = 20;
281     std::vector<int64_t> actualDurations;
282     actualDurations.push_back(20);
283     EXPECT_CALL(*mMockSession, reportActualWorkDuration2(_)).Times(Exactly(1));
284     result = APerformanceHint_reportActualWorkDuration(session, actualDurationNanos);
285     EXPECT_EQ(0, result);
286     result = APerformanceHint_updateTargetWorkDuration(session, -1L);
287     EXPECT_EQ(EINVAL, result);
288     result = APerformanceHint_reportActualWorkDuration(session, -1L);
289     EXPECT_EQ(EINVAL, result);
290 
291     SessionHint hintId = SessionHint::CPU_LOAD_RESET;
292     EXPECT_CALL(*mMockSession, sendHint(Eq(hintId))).Times(Exactly(1));
293     result = APerformanceHint_sendHint(session, hintId);
294     EXPECT_EQ(0, result);
295     EXPECT_CALL(*mMockSession, sendHint(Eq(SessionHint::CPU_LOAD_UP))).Times(Exactly(1));
296     result = APerformanceHint_notifyWorkloadIncrease(session, true, false, "Test hint");
297     EXPECT_EQ(0, result);
298     EXPECT_CALL(*mMockSession, sendHint(Eq(SessionHint::CPU_LOAD_RESET))).Times(Exactly(1));
299     EXPECT_CALL(*mMockSession, sendHint(Eq(SessionHint::GPU_LOAD_RESET))).Times(Exactly(1));
300     result = APerformanceHint_notifyWorkloadReset(session, true, true, "Test hint");
301     EXPECT_EQ(0, result);
302     EXPECT_CALL(*mMockSession, sendHint(Eq(SessionHint::CPU_LOAD_SPIKE))).Times(Exactly(1));
303     EXPECT_CALL(*mMockSession, sendHint(Eq(SessionHint::GPU_LOAD_SPIKE))).Times(Exactly(1));
304     result = APerformanceHint_notifyWorkloadSpike(session, true, true, "Test hint");
305     EXPECT_EQ(0, result);
306 
307     result = APerformanceHint_sendHint(session, static_cast<SessionHint>(-1));
308     EXPECT_EQ(EINVAL, result);
309 
310     Mock::VerifyAndClearExpectations(mMockSession.get());
311     for (int i = 0; i < mMaxLoadHintsPerInterval; ++i) {
312         APerformanceHint_sendHint(session, hintId);
313     }
314 
315     // Expect to get rate limited if we try to send faster than the limiter allows
316     EXPECT_CALL(*mMockSession, sendHint(_)).Times(Exactly(0));
317     result = APerformanceHint_notifyWorkloadIncrease(session, true, true, "Test hint");
318     EXPECT_EQ(result, EBUSY);
319     EXPECT_CALL(*mMockSession, sendHint(_)).Times(Exactly(0));
320     result = APerformanceHint_notifyWorkloadReset(session, true, true, "Test hint");
321     EXPECT_CALL(*mMockSession, close()).Times(Exactly(1));
322     APerformanceHint_closeSession(session);
323 }
324 
TEST_F(PerformanceHintTest,TestUpdatedSessionCreation)325 TEST_F(PerformanceHintTest, TestUpdatedSessionCreation) {
326     EXPECT_CALL(*mMockIHintManager, createHintSessionWithConfig(_, _, _, _, _)).Times(1);
327     APerformanceHintManager* manager = createManager();
328     APerformanceHintSession* session = createSession(manager);
329     ASSERT_TRUE(session);
330     APerformanceHint_closeSession(session);
331 }
332 
TEST_F(PerformanceHintTest,TestSessionCreationUsingConfig)333 TEST_F(PerformanceHintTest, TestSessionCreationUsingConfig) {
334     EXPECT_CALL(*mMockIHintManager, createHintSessionWithConfig(_, _, _, _, _)).Times(1);
335     SessionCreationConfig config{.tids = std::vector<int32_t>(1, 2),
336                                  .targetWorkDurationNanos = 5678,
337                                  .modesToEnable = std::vector<hal::SessionMode>(0)};
338     APerformanceHintManager* manager = createManager();
339     APerformanceHintSession* session = createSessionUsingConfig(manager, config);
340     ASSERT_TRUE(session);
341     APerformanceHint_closeSession(session);
342 }
343 
TEST_F(PerformanceHintTest,TestHwuiSessionCreation)344 TEST_F(PerformanceHintTest, TestHwuiSessionCreation) {
345     EXPECT_CALL(*mMockIHintManager, createHintSessionWithConfig(_, hal::SessionTag::HWUI, _, _, _))
346             .Times(1);
347     APerformanceHintManager* manager = createManager();
348     APerformanceHintSession* session = createSession(manager, 56789L, true);
349     ASSERT_TRUE(session);
350     APerformanceHint_closeSession(session);
351 }
352 
TEST_F(PerformanceHintTest,SetThreads)353 TEST_F(PerformanceHintTest, SetThreads) {
354     APerformanceHintManager* manager = createManager();
355 
356     APerformanceHintSession* session = createSession(manager);
357     ASSERT_TRUE(session);
358 
359     int32_t emptyTids[2];
360     int result = APerformanceHint_setThreads(session, emptyTids, 0);
361     EXPECT_EQ(EINVAL, result);
362 
363     std::vector<int32_t> newTids;
364     newTids.push_back(1);
365     newTids.push_back(3);
366     EXPECT_CALL(*mMockIHintManager, setHintSessionThreads(_, Eq(newTids))).Times(Exactly(1));
367     result = APerformanceHint_setThreads(session, newTids.data(), newTids.size());
368     EXPECT_EQ(0, result);
369 
370     testing::Mock::VerifyAndClearExpectations(mMockIHintManager.get());
371     std::vector<int32_t> invalidTids;
372     invalidTids.push_back(4);
373     invalidTids.push_back(6);
374     EXPECT_CALL(*mMockIHintManager, setHintSessionThreads(_, Eq(invalidTids)))
375             .Times(Exactly(1))
376             .WillOnce(Return(ByMove(ScopedAStatus::fromExceptionCode(EX_SECURITY))));
377     result = APerformanceHint_setThreads(session, invalidTids.data(), invalidTids.size());
378     EXPECT_EQ(EPERM, result);
379 }
380 
TEST_F(PerformanceHintTest,SetPowerEfficient)381 TEST_F(PerformanceHintTest, SetPowerEfficient) {
382     APerformanceHintManager* manager = createManager();
383     APerformanceHintSession* session = createSession(manager);
384     ASSERT_TRUE(session);
385 
386     EXPECT_CALL(*mMockSession, setMode(_, Eq(true))).Times(Exactly(1));
387     int result = APerformanceHint_setPreferPowerEfficiency(session, true);
388     EXPECT_EQ(0, result);
389 
390     EXPECT_CALL(*mMockSession, setMode(_, Eq(false))).Times(Exactly(1));
391     result = APerformanceHint_setPreferPowerEfficiency(session, false);
392     EXPECT_EQ(0, result);
393 }
394 
TEST_F(PerformanceHintTest,CreateZeroTargetDurationSession)395 TEST_F(PerformanceHintTest, CreateZeroTargetDurationSession) {
396     APerformanceHintManager* manager = createManager();
397     APerformanceHintSession* session = createSession(manager, 0);
398     ASSERT_TRUE(session);
399 }
400 
401 MATCHER_P(WorkDurationEq, expected, "") {
402     if (arg.size() != expected.size()) {
403         *result_listener << "WorkDuration vectors are different sizes. Expected: "
404                          << expected.size() << ", Actual: " << arg.size();
405         return false;
406     }
407     for (int i = 0; i < expected.size(); ++i) {
408         hal::WorkDuration expectedWorkDuration = expected[i];
409         hal::WorkDuration actualWorkDuration = arg[i];
410         if (!equalsWithoutTimestamp(expectedWorkDuration, actualWorkDuration)) {
411             *result_listener << "WorkDuration at [" << i << "] is different: "
412                              << "Expected: " << expectedWorkDuration.toString()
413                              << ", Actual: " << actualWorkDuration.toString();
414             return false;
415         }
416     }
417     return true;
418 }
419 
TEST_F(PerformanceHintTest,TestAPerformanceHint_reportActualWorkDuration2)420 TEST_F(PerformanceHintTest, TestAPerformanceHint_reportActualWorkDuration2) {
421     APerformanceHintManager* manager = createManager();
422     APerformanceHintSession* session = createSession(manager);
423     ASSERT_TRUE(session);
424 
425     int64_t targetDurationNanos = 10;
426     EXPECT_CALL(*mMockSession, updateTargetWorkDuration(Eq(targetDurationNanos))).Times(Exactly(1));
427     int result = APerformanceHint_updateTargetWorkDuration(session, targetDurationNanos);
428     EXPECT_EQ(0, result);
429 
430     usleep(2); // Sleep for longer than preferredUpdateRateNanos.
431     struct TestPair {
432         hal::WorkDuration duration;
433         int expectedResult;
434     };
435     std::vector<TestPair> testPairs{
436             {{1, 20, 1, 13, 8}, OK},       {{1, -20, 1, 13, 8}, EINVAL},
437             {{1, 20, -1, 13, 8}, EINVAL},  {{1, -20, 1, -13, 8}, EINVAL},
438             {{1, -20, 1, 13, -8}, EINVAL},
439     };
440     for (auto&& pair : testPairs) {
441         std::vector<hal::WorkDuration> actualWorkDurations;
442         actualWorkDurations.push_back(pair.duration);
443 
444         EXPECT_CALL(*mMockSession, reportActualWorkDuration2(WorkDurationEq(actualWorkDurations)))
445                 .Times(Exactly(pair.expectedResult == OK));
446         result = APerformanceHint_reportActualWorkDuration2(session,
447                                                             reinterpret_cast<AWorkDuration*>(
448                                                                     &pair.duration));
449         EXPECT_EQ(pair.expectedResult, result);
450     }
451 
452     EXPECT_CALL(*mMockSession, close()).Times(Exactly(1));
453     APerformanceHint_closeSession(session);
454 }
455 
TEST_F(PerformanceHintTest,TestAWorkDuration)456 TEST_F(PerformanceHintTest, TestAWorkDuration) {
457     AWorkDuration* aWorkDuration = AWorkDuration_create();
458     ASSERT_NE(aWorkDuration, nullptr);
459 
460     AWorkDuration_setWorkPeriodStartTimestampNanos(aWorkDuration, 1);
461     AWorkDuration_setActualTotalDurationNanos(aWorkDuration, 20);
462     AWorkDuration_setActualCpuDurationNanos(aWorkDuration, 13);
463     AWorkDuration_setActualGpuDurationNanos(aWorkDuration, 8);
464     AWorkDuration_release(aWorkDuration);
465 }
466 
TEST_F(PerformanceHintTest,TestCreateUsingFMQ)467 TEST_F(PerformanceHintTest, TestCreateUsingFMQ) {
468     setFMQEnabled(true);
469     APerformanceHintManager* manager = createManager();
470     APerformanceHintSession* session = createSession(manager);
471     ASSERT_TRUE(session);
472 }
473 
TEST_F(PerformanceHintTest,TestUpdateTargetWorkDurationUsingFMQ)474 TEST_F(PerformanceHintTest, TestUpdateTargetWorkDurationUsingFMQ) {
475     setFMQEnabled(true);
476     APerformanceHintManager* manager = createManager();
477     APerformanceHintSession* session = createSession(manager);
478     APerformanceHint_updateTargetWorkDuration(session, 456);
479     expectToReadFromFmq<HalChannelMessageContents::Tag::targetDuration>(456);
480 }
481 
TEST_F(PerformanceHintTest,TestSendHintUsingFMQ)482 TEST_F(PerformanceHintTest, TestSendHintUsingFMQ) {
483     setFMQEnabled(true);
484     APerformanceHintManager* manager = createManager();
485     APerformanceHintSession* session = createSession(manager);
486     APerformanceHint_sendHint(session, SessionHint::CPU_LOAD_UP);
487     expectToReadFromFmq<HalChannelMessageContents::Tag::hint>(hal::SessionHint::CPU_LOAD_UP);
488 }
489 
TEST_F(PerformanceHintTest,TestReportActualUsingFMQ)490 TEST_F(PerformanceHintTest, TestReportActualUsingFMQ) {
491     setFMQEnabled(true);
492     APerformanceHintManager* manager = createManager();
493     APerformanceHintSession* session = createSession(manager);
494     hal::WorkDuration duration{.timeStampNanos = 3,
495                                .durationNanos = 999999,
496                                .workPeriodStartTimestampNanos = 1,
497                                .cpuDurationNanos = 999999,
498                                .gpuDurationNanos = 999999};
499 
500     hal::WorkDurationFixedV1 durationExpected{
501             .durationNanos = duration.durationNanos,
502             .workPeriodStartTimestampNanos = duration.workPeriodStartTimestampNanos,
503             .cpuDurationNanos = duration.cpuDurationNanos,
504             .gpuDurationNanos = duration.gpuDurationNanos,
505     };
506 
507     APerformanceHint_reportActualWorkDuration2(session,
508                                                reinterpret_cast<AWorkDuration*>(&duration));
509     expectToReadFromFmq<HalChannelMessageContents::Tag::workDuration>(durationExpected);
510 }
511 
TEST_F(PerformanceHintTest,TestASessionCreationConfig)512 TEST_F(PerformanceHintTest, TestASessionCreationConfig) {
513     ASessionCreationConfig* config = ASessionCreationConfig_create();
514     ASSERT_NE(config, nullptr);
515 
516     const int32_t testTids[2] = {1, 2};
517     const size_t size = 2;
518     EXPECT_EQ(ASessionCreationConfig_setTids(config, testTids, size), 0);
519     EXPECT_EQ(ASessionCreationConfig_setTargetWorkDurationNanos(config, 20), 0);
520     EXPECT_EQ(ASessionCreationConfig_setPreferPowerEfficiency(config, true), 0);
521     EXPECT_EQ(ASessionCreationConfig_setGraphicsPipeline(config, true), 0);
522     ASessionCreationConfig_release(config);
523 }
524