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