• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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 // TODO(b/129481165): remove the #pragma below and fix conversion issues
18 #pragma clang diagnostic push
19 #pragma clang diagnostic ignored "-Wextra"
20 
21 #undef LOG_TAG
22 #define LOG_TAG "LibSurfaceFlingerUnittests"
23 
24 #include <gmock/gmock.h>
25 #include <gtest/gtest.h>
26 #include <log/log.h>
27 #include <scheduler/VsyncConfig.h>
28 #include <utils/Errors.h>
29 
30 #include "AsyncCallRecorder.h"
31 #include "DisplayHardware/DisplayMode.h"
32 #include "FrameTimeline.h"
33 #include "Scheduler/EventThread.h"
34 #include "mock/MockVSyncDispatch.h"
35 #include "mock/MockVSyncTracker.h"
36 #include "mock/MockVsyncController.h"
37 
38 using namespace std::chrono_literals;
39 using namespace std::placeholders;
40 
41 using testing::_;
42 using testing::Invoke;
43 using testing::Return;
44 
45 namespace android {
46 
47 using namespace ftl::flag_operators;
48 
49 namespace {
50 
51 constexpr PhysicalDisplayId INTERNAL_DISPLAY_ID = PhysicalDisplayId::fromPort(111u);
52 constexpr PhysicalDisplayId EXTERNAL_DISPLAY_ID = PhysicalDisplayId::fromPort(222u);
53 constexpr PhysicalDisplayId DISPLAY_ID_64BIT =
54         PhysicalDisplayId::fromEdid(0xffu, 0xffffu, 0xffff'ffffu);
55 
56 constexpr std::chrono::duration VSYNC_PERIOD(16ms);
57 
58 } // namespace
59 
60 class EventThreadTest : public testing::Test {
61 protected:
62     static constexpr std::chrono::nanoseconds kWorkDuration = 0ms;
63     static constexpr std::chrono::nanoseconds kReadyDuration = 3ms;
64 
65     class MockEventThreadConnection : public EventThreadConnection {
66     public:
MockEventThreadConnection(impl::EventThread * eventThread,uid_t callingUid,ResyncCallback && resyncCallback,EventRegistrationFlags eventRegistration)67         MockEventThreadConnection(impl::EventThread* eventThread, uid_t callingUid,
68                                   ResyncCallback&& resyncCallback,
69                                   EventRegistrationFlags eventRegistration)
70               : EventThreadConnection(eventThread, callingUid, std::move(resyncCallback),
71                                       eventRegistration) {}
72         MOCK_METHOD1(postEvent, status_t(const DisplayEventReceiver::Event& event));
73     };
74 
75     using ConnectionEventRecorder =
76             AsyncCallRecorderWithCannedReturn<status_t (*)(const DisplayEventReceiver::Event&)>;
77 
78     EventThreadTest();
79     ~EventThreadTest() override;
80 
81     void setupEventThread(std::chrono::nanoseconds vsyncPeriod);
82     sp<MockEventThreadConnection> createConnection(ConnectionEventRecorder& recorder,
83                                                    EventRegistrationFlags eventRegistration = {},
84                                                    uid_t ownerUid = mConnectionUid);
85 
86     void expectVSyncCallbackScheduleReceived(bool expectState);
87     void expectVSyncSetDurationCallReceived(std::chrono::nanoseconds expectedDuration,
88                                             std::chrono::nanoseconds expectedReadyDuration);
89     void expectVsyncEventReceivedByConnection(const char* name,
90                                               ConnectionEventRecorder& connectionEventRecorder,
91                                               nsecs_t expectedTimestamp, unsigned expectedCount);
92     void expectVsyncEventReceivedByConnection(nsecs_t expectedTimestamp, unsigned expectedCount);
93     void expectVsyncEventFrameTimelinesCorrect(
94             nsecs_t expectedTimestamp, gui::VsyncEventData::FrameTimeline preferredVsyncData);
95     void expectVsyncEventDataFrameTimelinesValidLength(VsyncEventData vsyncEventData,
96                                                        std::chrono::nanoseconds vsyncPeriod);
97     void expectHotplugEventReceivedByConnection(PhysicalDisplayId expectedDisplayId,
98                                                 bool expectedConnected);
99     void expectConfigChangedEventReceivedByConnection(PhysicalDisplayId expectedDisplayId,
100                                                       int32_t expectedConfigId,
101                                                       nsecs_t expectedVsyncPeriod);
102     void expectThrottleVsyncReceived(nsecs_t expectedTimestamp, uid_t);
103     void expectUidFrameRateMappingEventReceivedByConnection(PhysicalDisplayId expectedDisplayId,
104                                                             std::vector<FrameRateOverride>);
105 
onVSyncEvent(nsecs_t timestamp,nsecs_t expectedPresentationTime,nsecs_t deadlineTimestamp)106     void onVSyncEvent(nsecs_t timestamp, nsecs_t expectedPresentationTime,
107                       nsecs_t deadlineTimestamp) {
108         mThread->onVsync(expectedPresentationTime, timestamp, deadlineTimestamp);
109     }
110 
111     AsyncCallRecorderWithCannedReturn<
112             scheduler::ScheduleResult (*)(scheduler::VSyncDispatch::CallbackToken,
113                                           scheduler::VSyncDispatch::ScheduleTiming)>
114             mVSyncCallbackScheduleRecorder{0};
115     AsyncCallRecorderWithCannedReturn<
116             scheduler::ScheduleResult (*)(scheduler::VSyncDispatch::CallbackToken,
117                                           scheduler::VSyncDispatch::ScheduleTiming)>
118             mVSyncCallbackUpdateRecorder{0};
119     AsyncCallRecorderWithCannedReturn<
120             scheduler::VSyncDispatch::CallbackToken (*)(scheduler::VSyncDispatch::Callback,
121                                                         std::string)>
122             mVSyncCallbackRegisterRecorder{scheduler::VSyncDispatch::CallbackToken(0)};
123     AsyncCallRecorder<void (*)(scheduler::VSyncDispatch::CallbackToken)>
124             mVSyncCallbackUnregisterRecorder;
125     AsyncCallRecorder<void (*)()> mResyncCallRecorder;
126     AsyncCallRecorder<void (*)(nsecs_t, uid_t)> mThrottleVsyncCallRecorder;
127     ConnectionEventRecorder mConnectionEventCallRecorder{0};
128     ConnectionEventRecorder mThrottledConnectionEventCallRecorder{0};
129 
130     std::shared_ptr<scheduler::VsyncSchedule> mVsyncSchedule;
131     std::unique_ptr<impl::EventThread> mThread;
132     sp<MockEventThreadConnection> mConnection;
133     sp<MockEventThreadConnection> mThrottledConnection;
134     std::unique_ptr<frametimeline::impl::TokenManager> mTokenManager;
135 
136     static constexpr uid_t mConnectionUid = 443;
137     static constexpr uid_t mThrottledConnectionUid = 177;
138 };
139 
EventThreadTest()140 EventThreadTest::EventThreadTest() {
141     const ::testing::TestInfo* const test_info =
142             ::testing::UnitTest::GetInstance()->current_test_info();
143     ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
144 
145     auto mockDispatchPtr = std::make_shared<mock::VSyncDispatch>();
146     mVsyncSchedule = std::shared_ptr<scheduler::VsyncSchedule>(
147             new scheduler::VsyncSchedule(INTERNAL_DISPLAY_ID,
148                                          std::make_shared<mock::VSyncTracker>(), mockDispatchPtr,
149                                          nullptr));
150     mock::VSyncDispatch& mockDispatch = *mockDispatchPtr;
151     EXPECT_CALL(mockDispatch, registerCallback(_, _))
152             .WillRepeatedly(Invoke(mVSyncCallbackRegisterRecorder.getInvocable()));
153     EXPECT_CALL(mockDispatch, schedule(_, _))
154             .WillRepeatedly(Invoke(mVSyncCallbackScheduleRecorder.getInvocable()));
155     EXPECT_CALL(mockDispatch, update(_, _))
156             .WillRepeatedly(Invoke(mVSyncCallbackUpdateRecorder.getInvocable()));
157     EXPECT_CALL(mockDispatch, unregisterCallback(_))
158             .WillRepeatedly(Invoke(mVSyncCallbackUnregisterRecorder.getInvocable()));
159 }
160 
~EventThreadTest()161 EventThreadTest::~EventThreadTest() {
162     const ::testing::TestInfo* const test_info =
163             ::testing::UnitTest::GetInstance()->current_test_info();
164     ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
165 
166     mThread.reset();
167     // EventThread should unregister itself as VSyncSource callback.
168     EXPECT_TRUE(mVSyncCallbackUnregisterRecorder.waitForCall().has_value());
169 }
170 
setupEventThread(std::chrono::nanoseconds vsyncPeriod)171 void EventThreadTest::setupEventThread(std::chrono::nanoseconds vsyncPeriod) {
172     const auto throttleVsync = [&](nsecs_t expectedVsyncTimestamp, uid_t uid) {
173         mThrottleVsyncCallRecorder.getInvocable()(expectedVsyncTimestamp, uid);
174         return (uid == mThrottledConnectionUid);
175     };
176     const auto getVsyncPeriod = [vsyncPeriod](uid_t uid) { return vsyncPeriod.count(); };
177 
178     mTokenManager = std::make_unique<frametimeline::impl::TokenManager>();
179     mThread = std::make_unique<impl::EventThread>("EventThreadTest", mVsyncSchedule,
180                                                   mTokenManager.get(), throttleVsync,
181                                                   getVsyncPeriod, kWorkDuration, kReadyDuration);
182 
183     // EventThread should register itself as VSyncSource callback.
184     EXPECT_TRUE(mVSyncCallbackRegisterRecorder.waitForCall().has_value());
185 
186     mConnection =
187             createConnection(mConnectionEventCallRecorder,
188                              gui::ISurfaceComposer::EventRegistration::modeChanged |
189                                      gui::ISurfaceComposer::EventRegistration::frameRateOverride);
190     mThrottledConnection = createConnection(mThrottledConnectionEventCallRecorder,
191                                             gui::ISurfaceComposer::EventRegistration::modeChanged,
192                                             mThrottledConnectionUid);
193 
194     // A display must be connected for VSYNC events to be delivered.
195     mThread->onHotplugReceived(INTERNAL_DISPLAY_ID, true);
196     expectHotplugEventReceivedByConnection(INTERNAL_DISPLAY_ID, true);
197 }
198 
createConnection(ConnectionEventRecorder & recorder,EventRegistrationFlags eventRegistration,uid_t ownerUid)199 sp<EventThreadTest::MockEventThreadConnection> EventThreadTest::createConnection(
200         ConnectionEventRecorder& recorder, EventRegistrationFlags eventRegistration,
201         uid_t ownerUid) {
202     sp<MockEventThreadConnection> connection =
203             sp<MockEventThreadConnection>::make(mThread.get(), ownerUid,
204                                                 mResyncCallRecorder.getInvocable(),
205                                                 eventRegistration);
206     EXPECT_CALL(*connection, postEvent(_)).WillRepeatedly(Invoke(recorder.getInvocable()));
207     return connection;
208 }
209 
expectVSyncCallbackScheduleReceived(bool expectState)210 void EventThreadTest::expectVSyncCallbackScheduleReceived(bool expectState) {
211     if (expectState) {
212         ASSERT_TRUE(mVSyncCallbackScheduleRecorder.waitForCall().has_value());
213     } else {
214         ASSERT_FALSE(mVSyncCallbackScheduleRecorder.waitForUnexpectedCall().has_value());
215     }
216 }
217 
expectVSyncSetDurationCallReceived(std::chrono::nanoseconds expectedDuration,std::chrono::nanoseconds expectedReadyDuration)218 void EventThreadTest::expectVSyncSetDurationCallReceived(
219         std::chrono::nanoseconds expectedDuration, std::chrono::nanoseconds expectedReadyDuration) {
220     auto args = mVSyncCallbackUpdateRecorder.waitForCall();
221     ASSERT_TRUE(args.has_value());
222     EXPECT_EQ(expectedDuration.count(), std::get<1>(args.value()).workDuration);
223     EXPECT_EQ(expectedReadyDuration.count(), std::get<1>(args.value()).readyDuration);
224 }
225 
expectThrottleVsyncReceived(nsecs_t expectedTimestamp,uid_t uid)226 void EventThreadTest::expectThrottleVsyncReceived(nsecs_t expectedTimestamp, uid_t uid) {
227     auto args = mThrottleVsyncCallRecorder.waitForCall();
228     ASSERT_TRUE(args.has_value());
229     EXPECT_EQ(expectedTimestamp, std::get<0>(args.value()));
230     EXPECT_EQ(uid, std::get<1>(args.value()));
231 }
232 
expectVsyncEventReceivedByConnection(const char * name,ConnectionEventRecorder & connectionEventRecorder,nsecs_t expectedTimestamp,unsigned expectedCount)233 void EventThreadTest::expectVsyncEventReceivedByConnection(
234         const char* name, ConnectionEventRecorder& connectionEventRecorder,
235         nsecs_t expectedTimestamp, unsigned expectedCount) {
236     auto args = connectionEventRecorder.waitForCall();
237     ASSERT_TRUE(args.has_value()) << name << " did not receive an event for timestamp "
238                                   << expectedTimestamp;
239     const auto& event = std::get<0>(args.value());
240     EXPECT_EQ(DisplayEventReceiver::DISPLAY_EVENT_VSYNC, event.header.type)
241             << name << " did not get the correct event for timestamp " << expectedTimestamp;
242     EXPECT_EQ(expectedTimestamp, event.header.timestamp)
243             << name << " did not get the expected timestamp for timestamp " << expectedTimestamp;
244     EXPECT_EQ(expectedCount, event.vsync.count)
245             << name << " did not get the expected count for timestamp " << expectedTimestamp;
246 }
247 
expectVsyncEventReceivedByConnection(nsecs_t expectedTimestamp,unsigned expectedCount)248 void EventThreadTest::expectVsyncEventReceivedByConnection(nsecs_t expectedTimestamp,
249                                                            unsigned expectedCount) {
250     expectVsyncEventReceivedByConnection("mConnectionEventCallRecorder",
251                                          mConnectionEventCallRecorder, expectedTimestamp,
252                                          expectedCount);
253 }
254 
expectVsyncEventFrameTimelinesCorrect(nsecs_t expectedTimestamp,VsyncEventData::FrameTimeline preferredVsyncData)255 void EventThreadTest::expectVsyncEventFrameTimelinesCorrect(
256         nsecs_t expectedTimestamp, VsyncEventData::FrameTimeline preferredVsyncData) {
257     auto args = mConnectionEventCallRecorder.waitForCall();
258     ASSERT_TRUE(args.has_value()) << " did not receive an event for timestamp "
259                                   << expectedTimestamp;
260     const auto& event = std::get<0>(args.value());
261     for (int i = 0; i < event.vsync.vsyncData.frameTimelinesLength; i++) {
262         auto prediction = mTokenManager->getPredictionsForToken(
263                 event.vsync.vsyncData.frameTimelines[i].vsyncId);
264         EXPECT_TRUE(prediction.has_value());
265         EXPECT_EQ(prediction.value().endTime,
266                   event.vsync.vsyncData.frameTimelines[i].deadlineTimestamp)
267                 << "Deadline timestamp does not match cached value";
268         EXPECT_EQ(prediction.value().presentTime,
269                   event.vsync.vsyncData.frameTimelines[i].expectedPresentationTime)
270                 << "Expected vsync.vsyncData timestamp does not match cached value";
271 
272         if (i > 0) {
273             EXPECT_GT(event.vsync.vsyncData.frameTimelines[i].deadlineTimestamp,
274                       event.vsync.vsyncData.frameTimelines[i - 1].deadlineTimestamp)
275                     << "Deadline timestamp out of order for frame timeline " << i;
276             EXPECT_GT(event.vsync.vsyncData.frameTimelines[i].expectedPresentationTime,
277                       event.vsync.vsyncData.frameTimelines[i - 1].expectedPresentationTime)
278                     << "Expected vsync.vsyncData timestamp out of order for frame timeline " << i;
279         }
280 
281         // Vsync ID order lines up with registration into test token manager.
282         EXPECT_EQ(i, event.vsync.vsyncData.frameTimelines[i].vsyncId)
283                 << "Vsync ID incorrect for frame timeline " << i;
284         if (i == event.vsync.vsyncData.preferredFrameTimelineIndex) {
285             EXPECT_EQ(event.vsync.vsyncData.frameTimelines[i].deadlineTimestamp,
286                       preferredVsyncData.deadlineTimestamp)
287                     << "Preferred deadline timestamp incorrect" << i;
288             EXPECT_EQ(event.vsync.vsyncData.frameTimelines[i].expectedPresentationTime,
289                       preferredVsyncData.expectedPresentationTime)
290                     << "Preferred expected vsync.vsyncData timestamp incorrect" << i;
291         }
292     }
293 }
294 
expectVsyncEventDataFrameTimelinesValidLength(VsyncEventData vsyncEventData,std::chrono::nanoseconds vsyncPeriod)295 void EventThreadTest::expectVsyncEventDataFrameTimelinesValidLength(
296         VsyncEventData vsyncEventData, std::chrono::nanoseconds vsyncPeriod) {
297     float nonPreferredTimelinesAmount =
298             scheduler::VsyncConfig::kEarlyLatchMaxThreshold / vsyncPeriod;
299     EXPECT_LE(vsyncEventData.frameTimelinesLength, nonPreferredTimelinesAmount + 1)
300             << "Amount of non-preferred frame timelines too many;"
301             << " expected presentation time will be over threshold";
302     EXPECT_LT(nonPreferredTimelinesAmount, VsyncEventData::kFrameTimelinesCapacity)
303             << "Amount of non-preferred frame timelines should be less than max capacity";
304     EXPECT_GT(static_cast<int64_t>(vsyncEventData.frameTimelinesLength), 0)
305             << "Frame timelines length should be greater than 0";
306     EXPECT_LT(vsyncEventData.preferredFrameTimelineIndex, vsyncEventData.frameTimelinesLength)
307             << "Preferred frame timeline index should be less than frame timelines length";
308 }
309 
expectHotplugEventReceivedByConnection(PhysicalDisplayId expectedDisplayId,bool expectedConnected)310 void EventThreadTest::expectHotplugEventReceivedByConnection(PhysicalDisplayId expectedDisplayId,
311                                                              bool expectedConnected) {
312     auto args = mConnectionEventCallRecorder.waitForCall();
313     ASSERT_TRUE(args.has_value());
314     const auto& event = std::get<0>(args.value());
315     EXPECT_EQ(DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG, event.header.type);
316     EXPECT_EQ(expectedDisplayId, event.header.displayId);
317     EXPECT_EQ(expectedConnected, event.hotplug.connected);
318 }
319 
expectConfigChangedEventReceivedByConnection(PhysicalDisplayId expectedDisplayId,int32_t expectedConfigId,nsecs_t expectedVsyncPeriod)320 void EventThreadTest::expectConfigChangedEventReceivedByConnection(
321         PhysicalDisplayId expectedDisplayId, int32_t expectedConfigId,
322         nsecs_t expectedVsyncPeriod) {
323     auto args = mConnectionEventCallRecorder.waitForCall();
324     ASSERT_TRUE(args.has_value());
325     const auto& event = std::get<0>(args.value());
326     EXPECT_EQ(DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE, event.header.type);
327     EXPECT_EQ(expectedDisplayId, event.header.displayId);
328     EXPECT_EQ(expectedConfigId, event.modeChange.modeId);
329     EXPECT_EQ(expectedVsyncPeriod, event.modeChange.vsyncPeriod);
330 }
331 
expectUidFrameRateMappingEventReceivedByConnection(PhysicalDisplayId expectedDisplayId,std::vector<FrameRateOverride> expectedOverrides)332 void EventThreadTest::expectUidFrameRateMappingEventReceivedByConnection(
333         PhysicalDisplayId expectedDisplayId, std::vector<FrameRateOverride> expectedOverrides) {
334     for (const auto [uid, frameRateHz] : expectedOverrides) {
335         auto args = mConnectionEventCallRecorder.waitForCall();
336         ASSERT_TRUE(args.has_value());
337         const auto& event = std::get<0>(args.value());
338         EXPECT_EQ(DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE, event.header.type);
339         EXPECT_EQ(expectedDisplayId, event.header.displayId);
340         EXPECT_EQ(uid, event.frameRateOverride.uid);
341         EXPECT_EQ(frameRateHz, event.frameRateOverride.frameRateHz);
342     }
343 
344     auto args = mConnectionEventCallRecorder.waitForCall();
345     ASSERT_TRUE(args.has_value());
346     const auto& event = std::get<0>(args.value());
347     EXPECT_EQ(DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH, event.header.type);
348     EXPECT_EQ(expectedDisplayId, event.header.displayId);
349 }
350 
351 namespace {
352 
353 using namespace testing;
354 
355 /* ------------------------------------------------------------------------
356  * Test cases
357  */
358 
TEST_F(EventThreadTest,canCreateAndDestroyThreadWithNoEventsSent)359 TEST_F(EventThreadTest, canCreateAndDestroyThreadWithNoEventsSent) {
360     setupEventThread(VSYNC_PERIOD);
361 
362     EXPECT_FALSE(mVSyncCallbackRegisterRecorder.waitForCall(0us).has_value());
363     EXPECT_FALSE(mVSyncCallbackScheduleRecorder.waitForCall(0us).has_value());
364     EXPECT_FALSE(mVSyncCallbackUpdateRecorder.waitForCall(0us).has_value());
365     EXPECT_FALSE(mVSyncCallbackUnregisterRecorder.waitForCall(0us).has_value());
366     EXPECT_FALSE(mResyncCallRecorder.waitForCall(0us).has_value());
367     EXPECT_FALSE(mConnectionEventCallRecorder.waitForCall(0us).has_value());
368 }
369 
TEST_F(EventThreadTest,vsyncRequestIsIgnoredIfDisplayIsDisconnected)370 TEST_F(EventThreadTest, vsyncRequestIsIgnoredIfDisplayIsDisconnected) {
371     setupEventThread(VSYNC_PERIOD);
372 
373     mThread->onHotplugReceived(INTERNAL_DISPLAY_ID, false);
374     expectHotplugEventReceivedByConnection(INTERNAL_DISPLAY_ID, false);
375 
376     // Signal that we want the next vsync event to be posted to the connection.
377     mThread->requestNextVsync(mConnection);
378 
379     // EventThread should not enable vsync callbacks.
380     expectVSyncCallbackScheduleReceived(false);
381 }
382 
TEST_F(EventThreadTest,requestNextVsyncPostsASingleVSyncEventToTheConnection)383 TEST_F(EventThreadTest, requestNextVsyncPostsASingleVSyncEventToTheConnection) {
384     setupEventThread(VSYNC_PERIOD);
385 
386     // Signal that we want the next vsync event to be posted to the connection
387     mThread->requestNextVsync(mConnection);
388 
389     // EventThread should immediately request a resync.
390     EXPECT_TRUE(mResyncCallRecorder.waitForCall().has_value());
391 
392     // EventThread should enable schedule a vsync callback
393     expectVSyncCallbackScheduleReceived(true);
394 
395     // Use the received callback to signal a first vsync event.
396     // The throttler should receive the event, as well as the connection.
397     onVSyncEvent(123, 456, 789);
398     expectThrottleVsyncReceived(456, mConnectionUid);
399     expectVsyncEventReceivedByConnection(123, 1u);
400 
401     // EventThread is requesting one more callback due to VsyncRequest::SingleSuppressCallback
402     expectVSyncCallbackScheduleReceived(true);
403 
404     // Use the received callback to signal a second vsync event.
405     // The throttler should receive the event, but the connection should
406     // not as it was only interested in the first.
407     onVSyncEvent(456, 123, 0);
408     EXPECT_FALSE(mThrottleVsyncCallRecorder.waitForUnexpectedCall().has_value());
409     EXPECT_FALSE(mConnectionEventCallRecorder.waitForUnexpectedCall().has_value());
410 
411     // EventThread should also detect that at this point that it does not need
412     // any more vsync events, and should disable their generation.
413     expectVSyncCallbackScheduleReceived(false);
414 }
415 
TEST_F(EventThreadTest,requestNextVsyncEventFrameTimelinesCorrect)416 TEST_F(EventThreadTest, requestNextVsyncEventFrameTimelinesCorrect) {
417     setupEventThread(VSYNC_PERIOD);
418 
419     // Signal that we want the next vsync event to be posted to the connection
420     mThread->requestNextVsync(mConnection);
421 
422     expectVSyncCallbackScheduleReceived(true);
423 
424     // Use the received callback to signal a vsync event.
425     // The throttler should receive the event, as well as the connection.
426     onVSyncEvent(123, 456, 789);
427     expectVsyncEventFrameTimelinesCorrect(123, {-1, 789, 456});
428 }
429 
TEST_F(EventThreadTest,requestNextVsyncEventFrameTimelinesValidLength)430 TEST_F(EventThreadTest, requestNextVsyncEventFrameTimelinesValidLength) {
431     // The VsyncEventData should not have kFrameTimelinesCapacity amount of valid frame timelines,
432     // due to longer vsync period and kEarlyLatchMaxThreshold. Use length-2 to avoid decimal
433     // truncation (e.g. 60Hz has 16.6... ms vsync period).
434     std::chrono::nanoseconds vsyncPeriod(scheduler::VsyncConfig::kEarlyLatchMaxThreshold /
435                                          (VsyncEventData::kFrameTimelinesCapacity - 2));
436     setupEventThread(vsyncPeriod);
437 
438     // Signal that we want the next vsync event to be posted to the connection
439     mThread->requestNextVsync(mConnection);
440 
441     expectVSyncCallbackScheduleReceived(true);
442 
443     // Use the received callback to signal a vsync event.
444     // The throttler should receive the event, as well as the connection.
445     nsecs_t expectedTimestamp = 123;
446     onVSyncEvent(expectedTimestamp, 456, 789);
447 
448     auto args = mConnectionEventCallRecorder.waitForCall();
449     ASSERT_TRUE(args.has_value()) << " did not receive an event for timestamp "
450                                   << expectedTimestamp;
451     const VsyncEventData vsyncEventData = std::get<0>(args.value()).vsync.vsyncData;
452     expectVsyncEventDataFrameTimelinesValidLength(vsyncEventData, vsyncPeriod);
453 }
454 
TEST_F(EventThreadTest,getLatestVsyncEventData)455 TEST_F(EventThreadTest, getLatestVsyncEventData) {
456     setupEventThread(VSYNC_PERIOD);
457 
458     const nsecs_t now = systemTime();
459     const nsecs_t preferredExpectedPresentationTime = now + 20000000;
460     const nsecs_t preferredDeadline = preferredExpectedPresentationTime - kReadyDuration.count();
461 
462     mock::VSyncTracker& mockTracker =
463             *static_cast<mock::VSyncTracker*>(&mVsyncSchedule->getTracker());
464     EXPECT_CALL(mockTracker, nextAnticipatedVSyncTimeFrom(_))
465             .WillOnce(Return(preferredExpectedPresentationTime));
466 
467     VsyncEventData vsyncEventData = mThread->getLatestVsyncEventData(mConnection);
468 
469     // Check EventThread immediately requested a resync.
470     EXPECT_TRUE(mResyncCallRecorder.waitForCall().has_value());
471 
472     expectVsyncEventDataFrameTimelinesValidLength(vsyncEventData, VSYNC_PERIOD);
473     EXPECT_GT(vsyncEventData.frameTimelines[0].deadlineTimestamp, now)
474             << "Deadline timestamp should be greater than frame time";
475     for (size_t i = 0; i < vsyncEventData.frameTimelinesLength; i++) {
476         auto prediction =
477                 mTokenManager->getPredictionsForToken(vsyncEventData.frameTimelines[i].vsyncId);
478         EXPECT_TRUE(prediction.has_value());
479         EXPECT_EQ(prediction.value().endTime, vsyncEventData.frameTimelines[i].deadlineTimestamp)
480                 << "Deadline timestamp does not match cached value";
481         EXPECT_EQ(prediction.value().presentTime,
482                   vsyncEventData.frameTimelines[i].expectedPresentationTime)
483                 << "Expected vsync timestamp does not match cached value";
484         EXPECT_GT(vsyncEventData.frameTimelines[i].expectedPresentationTime,
485                   vsyncEventData.frameTimelines[i].deadlineTimestamp)
486                 << "Expected vsync timestamp should be greater than deadline";
487 
488         if (i > 0) {
489             EXPECT_GT(vsyncEventData.frameTimelines[i].deadlineTimestamp,
490                       vsyncEventData.frameTimelines[i - 1].deadlineTimestamp)
491                     << "Deadline timestamp out of order for frame timeline " << i;
492             EXPECT_GT(vsyncEventData.frameTimelines[i].expectedPresentationTime,
493                       vsyncEventData.frameTimelines[i - 1].expectedPresentationTime)
494                     << "Expected vsync timestamp out of order for frame timeline " << i;
495         }
496 
497         // Vsync ID order lines up with registration into test token manager.
498         EXPECT_EQ(i, vsyncEventData.frameTimelines[i].vsyncId)
499                 << "Vsync ID incorrect for frame timeline " << i;
500         if (i == vsyncEventData.preferredFrameTimelineIndex) {
501             EXPECT_EQ(vsyncEventData.frameTimelines[i].deadlineTimestamp, preferredDeadline)
502                     << "Preferred deadline timestamp incorrect" << i;
503             EXPECT_EQ(vsyncEventData.frameTimelines[i].expectedPresentationTime,
504                       preferredExpectedPresentationTime)
505                     << "Preferred expected vsync timestamp incorrect" << i;
506         }
507     }
508 }
509 
TEST_F(EventThreadTest,setVsyncRateZeroPostsNoVSyncEventsToThatConnection)510 TEST_F(EventThreadTest, setVsyncRateZeroPostsNoVSyncEventsToThatConnection) {
511     setupEventThread(VSYNC_PERIOD);
512 
513     // Create a first connection, register it, and request a vsync rate of zero.
514     ConnectionEventRecorder firstConnectionEventRecorder{0};
515     sp<MockEventThreadConnection> firstConnection = createConnection(firstConnectionEventRecorder);
516     mThread->setVsyncRate(0, firstConnection);
517 
518     // By itself, this should not enable vsync events
519     expectVSyncCallbackScheduleReceived(false);
520 
521     // However if there is another connection which wants events at a nonzero rate.....
522     ConnectionEventRecorder secondConnectionEventRecorder{0};
523     sp<MockEventThreadConnection> secondConnection =
524             createConnection(secondConnectionEventRecorder);
525     mThread->setVsyncRate(1, secondConnection);
526 
527     // EventThread should enable vsync callbacks.
528     expectVSyncCallbackScheduleReceived(true);
529 
530     // Send a vsync event. EventThread should then make a call to the
531     // the second connection. The first connection should not
532     // get the event.
533     onVSyncEvent(123, 0456, 0);
534     EXPECT_FALSE(firstConnectionEventRecorder.waitForUnexpectedCall().has_value());
535     expectVsyncEventReceivedByConnection("secondConnection", secondConnectionEventRecorder, 123,
536                                          1u);
537 }
538 
TEST_F(EventThreadTest,setVsyncRateOnePostsAllEventsToThatConnection)539 TEST_F(EventThreadTest, setVsyncRateOnePostsAllEventsToThatConnection) {
540     setupEventThread(VSYNC_PERIOD);
541 
542     mThread->setVsyncRate(1, mConnection);
543 
544     // EventThread should enable vsync callbacks.
545     expectVSyncCallbackScheduleReceived(true);
546 
547     // Send a vsync event. EventThread should then make a call to the
548     // throttler, and the connection.
549     onVSyncEvent(123, 456, 789);
550     expectThrottleVsyncReceived(456, mConnectionUid);
551     expectVsyncEventReceivedByConnection(123, 1u);
552 
553     // A second event should go to the same places.
554     onVSyncEvent(456, 123, 0);
555     expectThrottleVsyncReceived(123, mConnectionUid);
556     expectVsyncEventReceivedByConnection(456, 2u);
557 
558     // A third event should go to the same places.
559     onVSyncEvent(789, 777, 111);
560     expectThrottleVsyncReceived(777, mConnectionUid);
561     expectVsyncEventReceivedByConnection(789, 3u);
562 }
563 
TEST_F(EventThreadTest,setVsyncRateTwoPostsEveryOtherEventToThatConnection)564 TEST_F(EventThreadTest, setVsyncRateTwoPostsEveryOtherEventToThatConnection) {
565     setupEventThread(VSYNC_PERIOD);
566 
567     mThread->setVsyncRate(2, mConnection);
568 
569     // EventThread should enable vsync callbacks.
570     expectVSyncCallbackScheduleReceived(true);
571 
572     // The first event will not be seen by the connection.
573     onVSyncEvent(123, 456, 789);
574     EXPECT_FALSE(mConnectionEventCallRecorder.waitForUnexpectedCall().has_value());
575     EXPECT_FALSE(mThrottleVsyncCallRecorder.waitForUnexpectedCall().has_value());
576 
577     // The second event will be seen by the connection.
578     onVSyncEvent(456, 123, 0);
579     expectVsyncEventReceivedByConnection(456, 2u);
580     EXPECT_FALSE(mThrottleVsyncCallRecorder.waitForUnexpectedCall().has_value());
581 
582     // The third event will not be seen by the connection.
583     onVSyncEvent(789, 777, 744);
584     EXPECT_FALSE(mConnectionEventCallRecorder.waitForUnexpectedCall().has_value());
585     EXPECT_FALSE(mThrottleVsyncCallRecorder.waitForUnexpectedCall().has_value());
586 
587     // The fourth event will be seen by the connection.
588     onVSyncEvent(101112, 7847, 86);
589     expectVsyncEventReceivedByConnection(101112, 4u);
590 }
591 
TEST_F(EventThreadTest,connectionsRemovedIfInstanceDestroyed)592 TEST_F(EventThreadTest, connectionsRemovedIfInstanceDestroyed) {
593     setupEventThread(VSYNC_PERIOD);
594 
595     mThread->setVsyncRate(1, mConnection);
596 
597     // EventThread should enable vsync callbacks.
598     expectVSyncCallbackScheduleReceived(true);
599 
600     // Destroy the only (strong) reference to the connection.
601     mConnection = nullptr;
602 
603     // The first event will not be seen by the connection.
604     onVSyncEvent(123, 56, 789);
605     EXPECT_FALSE(mConnectionEventCallRecorder.waitForUnexpectedCall().has_value());
606 
607     // EventThread should disable vsync callbacks
608     expectVSyncCallbackScheduleReceived(false);
609 }
610 
TEST_F(EventThreadTest,connectionsRemovedIfEventDeliveryError)611 TEST_F(EventThreadTest, connectionsRemovedIfEventDeliveryError) {
612     setupEventThread(VSYNC_PERIOD);
613 
614     ConnectionEventRecorder errorConnectionEventRecorder{NO_MEMORY};
615     sp<MockEventThreadConnection> errorConnection = createConnection(errorConnectionEventRecorder);
616     mThread->setVsyncRate(1, errorConnection);
617 
618     // EventThread should enable vsync callbacks.
619     expectVSyncCallbackScheduleReceived(true);
620 
621     // The first event will be seen by the connection, which then returns an error.
622     onVSyncEvent(123, 456, 789);
623     expectVsyncEventReceivedByConnection("errorConnection", errorConnectionEventRecorder, 123, 1u);
624 
625     // Another schedule is expected, since the connection is removed only after
626     // the next vsync is requested.
627     expectVSyncCallbackScheduleReceived(true);
628 
629     // A subsequent event will not be seen by the connection.
630     onVSyncEvent(456, 123, 0);
631     EXPECT_FALSE(errorConnectionEventRecorder.waitForUnexpectedCall().has_value());
632 
633     // EventThread should disable vsync callbacks with the second event
634     expectVSyncCallbackScheduleReceived(false);
635 }
636 
TEST_F(EventThreadTest,tracksEventConnections)637 TEST_F(EventThreadTest, tracksEventConnections) {
638     setupEventThread(VSYNC_PERIOD);
639 
640     EXPECT_EQ(2, mThread->getEventThreadConnectionCount());
641     ConnectionEventRecorder errorConnectionEventRecorder{NO_MEMORY};
642     sp<MockEventThreadConnection> errorConnection = createConnection(errorConnectionEventRecorder);
643     mThread->setVsyncRate(1, errorConnection);
644     EXPECT_EQ(3, mThread->getEventThreadConnectionCount());
645     ConnectionEventRecorder secondConnectionEventRecorder{0};
646     sp<MockEventThreadConnection> secondConnection =
647             createConnection(secondConnectionEventRecorder);
648     mThread->setVsyncRate(1, secondConnection);
649     EXPECT_EQ(4, mThread->getEventThreadConnectionCount());
650 
651     // EventThread should enable vsync callbacks.
652     expectVSyncCallbackScheduleReceived(true);
653 
654     // The first event will be seen by the connection, which then returns an error.
655     onVSyncEvent(123, 456, 789);
656     expectVsyncEventReceivedByConnection("errorConnection", errorConnectionEventRecorder, 123, 1u);
657     expectVsyncEventReceivedByConnection("successConnection", secondConnectionEventRecorder, 123,
658                                          1u);
659     EXPECT_EQ(3, mThread->getEventThreadConnectionCount());
660 }
661 
TEST_F(EventThreadTest,eventsDroppedIfNonfatalEventDeliveryError)662 TEST_F(EventThreadTest, eventsDroppedIfNonfatalEventDeliveryError) {
663     setupEventThread(VSYNC_PERIOD);
664 
665     ConnectionEventRecorder errorConnectionEventRecorder{WOULD_BLOCK};
666     sp<MockEventThreadConnection> errorConnection = createConnection(errorConnectionEventRecorder);
667     mThread->setVsyncRate(1, errorConnection);
668 
669     // EventThread should enable vsync callbacks.
670     expectVSyncCallbackScheduleReceived(true);
671 
672     // The first event will be seen by the connection, which then returns a non-fatal error.
673     onVSyncEvent(123, 456, 789);
674     expectVsyncEventReceivedByConnection("errorConnection", errorConnectionEventRecorder, 123, 1u);
675     expectVSyncCallbackScheduleReceived(true);
676 
677     // A subsequent event will be seen by the connection, which still then returns a non-fatal
678     // error.
679     onVSyncEvent(456, 123, 0);
680     expectVsyncEventReceivedByConnection("errorConnection", errorConnectionEventRecorder, 456, 2u);
681     expectVSyncCallbackScheduleReceived(true);
682 
683     // EventThread will not disable vsync callbacks as the errors are non-fatal.
684     onVSyncEvent(456, 123, 0);
685     expectVSyncCallbackScheduleReceived(true);
686 }
687 
TEST_F(EventThreadTest,setPhaseOffsetForwardsToVSyncSource)688 TEST_F(EventThreadTest, setPhaseOffsetForwardsToVSyncSource) {
689     setupEventThread(VSYNC_PERIOD);
690 
691     mThread->setDuration(321ns, 456ns);
692     expectVSyncSetDurationCallReceived(321ns, 456ns);
693 }
694 
TEST_F(EventThreadTest,postHotplugInternalDisconnect)695 TEST_F(EventThreadTest, postHotplugInternalDisconnect) {
696     setupEventThread(VSYNC_PERIOD);
697 
698     mThread->onHotplugReceived(INTERNAL_DISPLAY_ID, false);
699     expectHotplugEventReceivedByConnection(INTERNAL_DISPLAY_ID, false);
700 }
701 
TEST_F(EventThreadTest,postHotplugInternalConnect)702 TEST_F(EventThreadTest, postHotplugInternalConnect) {
703     setupEventThread(VSYNC_PERIOD);
704 
705     mThread->onHotplugReceived(INTERNAL_DISPLAY_ID, true);
706     expectHotplugEventReceivedByConnection(INTERNAL_DISPLAY_ID, true);
707 }
708 
TEST_F(EventThreadTest,postHotplugExternalDisconnect)709 TEST_F(EventThreadTest, postHotplugExternalDisconnect) {
710     setupEventThread(VSYNC_PERIOD);
711 
712     mThread->onHotplugReceived(EXTERNAL_DISPLAY_ID, false);
713     expectHotplugEventReceivedByConnection(EXTERNAL_DISPLAY_ID, false);
714 }
715 
TEST_F(EventThreadTest,postHotplugExternalConnect)716 TEST_F(EventThreadTest, postHotplugExternalConnect) {
717     setupEventThread(VSYNC_PERIOD);
718 
719     mThread->onHotplugReceived(EXTERNAL_DISPLAY_ID, true);
720     expectHotplugEventReceivedByConnection(EXTERNAL_DISPLAY_ID, true);
721 }
722 
TEST_F(EventThreadTest,postConfigChangedPrimary)723 TEST_F(EventThreadTest, postConfigChangedPrimary) {
724     setupEventThread(VSYNC_PERIOD);
725 
726     const auto mode = DisplayMode::Builder(hal::HWConfigId(0))
727                               .setPhysicalDisplayId(INTERNAL_DISPLAY_ID)
728                               .setId(DisplayModeId(7))
729                               .setVsyncPeriod(16666666)
730                               .build();
731     const Fps fps = mode->getFps() / 2;
732 
733     mThread->onModeChanged({fps, ftl::as_non_null(mode)});
734     expectConfigChangedEventReceivedByConnection(INTERNAL_DISPLAY_ID, 7, fps.getPeriodNsecs());
735 }
736 
TEST_F(EventThreadTest,postConfigChangedExternal)737 TEST_F(EventThreadTest, postConfigChangedExternal) {
738     setupEventThread(VSYNC_PERIOD);
739 
740     const auto mode = DisplayMode::Builder(hal::HWConfigId(0))
741                               .setPhysicalDisplayId(EXTERNAL_DISPLAY_ID)
742                               .setId(DisplayModeId(5))
743                               .setVsyncPeriod(16666666)
744                               .build();
745     const Fps fps = mode->getFps() / 2;
746 
747     mThread->onModeChanged({fps, ftl::as_non_null(mode)});
748     expectConfigChangedEventReceivedByConnection(EXTERNAL_DISPLAY_ID, 5, fps.getPeriodNsecs());
749 }
750 
TEST_F(EventThreadTest,postConfigChangedPrimary64bit)751 TEST_F(EventThreadTest, postConfigChangedPrimary64bit) {
752     setupEventThread(VSYNC_PERIOD);
753 
754     const auto mode = DisplayMode::Builder(hal::HWConfigId(0))
755                               .setPhysicalDisplayId(DISPLAY_ID_64BIT)
756                               .setId(DisplayModeId(7))
757                               .setVsyncPeriod(16666666)
758                               .build();
759     const Fps fps = mode->getFps() / 2;
760     mThread->onModeChanged({fps, ftl::as_non_null(mode)});
761     expectConfigChangedEventReceivedByConnection(DISPLAY_ID_64BIT, 7, fps.getPeriodNsecs());
762 }
763 
TEST_F(EventThreadTest,suppressConfigChanged)764 TEST_F(EventThreadTest, suppressConfigChanged) {
765     setupEventThread(VSYNC_PERIOD);
766 
767     ConnectionEventRecorder suppressConnectionEventRecorder{0};
768     sp<MockEventThreadConnection> suppressConnection =
769             createConnection(suppressConnectionEventRecorder);
770 
771     const auto mode = DisplayMode::Builder(hal::HWConfigId(0))
772                               .setPhysicalDisplayId(INTERNAL_DISPLAY_ID)
773                               .setId(DisplayModeId(9))
774                               .setVsyncPeriod(16666666)
775                               .build();
776     const Fps fps = mode->getFps() / 2;
777 
778     mThread->onModeChanged({fps, ftl::as_non_null(mode)});
779     expectConfigChangedEventReceivedByConnection(INTERNAL_DISPLAY_ID, 9, fps.getPeriodNsecs());
780 
781     auto args = suppressConnectionEventRecorder.waitForCall();
782     ASSERT_FALSE(args.has_value());
783 }
784 
TEST_F(EventThreadTest,postUidFrameRateMapping)785 TEST_F(EventThreadTest, postUidFrameRateMapping) {
786     setupEventThread(VSYNC_PERIOD);
787 
788     const std::vector<FrameRateOverride> overrides = {
789             {.uid = 1, .frameRateHz = 20},
790             {.uid = 3, .frameRateHz = 40},
791             {.uid = 5, .frameRateHz = 60},
792     };
793 
794     mThread->onFrameRateOverridesChanged(INTERNAL_DISPLAY_ID, overrides);
795     expectUidFrameRateMappingEventReceivedByConnection(INTERNAL_DISPLAY_ID, overrides);
796 }
797 
TEST_F(EventThreadTest,suppressUidFrameRateMapping)798 TEST_F(EventThreadTest, suppressUidFrameRateMapping) {
799     setupEventThread(VSYNC_PERIOD);
800 
801     const std::vector<FrameRateOverride> overrides = {
802             {.uid = 1, .frameRateHz = 20},
803             {.uid = 3, .frameRateHz = 40},
804             {.uid = 5, .frameRateHz = 60},
805     };
806 
807     ConnectionEventRecorder suppressConnectionEventRecorder{0};
808     sp<MockEventThreadConnection> suppressConnection =
809             createConnection(suppressConnectionEventRecorder);
810 
811     mThread->onFrameRateOverridesChanged(INTERNAL_DISPLAY_ID, overrides);
812     expectUidFrameRateMappingEventReceivedByConnection(INTERNAL_DISPLAY_ID, overrides);
813 
814     auto args = suppressConnectionEventRecorder.waitForCall();
815     ASSERT_FALSE(args.has_value());
816 }
817 
TEST_F(EventThreadTest,requestNextVsyncWithThrottleVsyncDoesntPostVSync)818 TEST_F(EventThreadTest, requestNextVsyncWithThrottleVsyncDoesntPostVSync) {
819     setupEventThread(VSYNC_PERIOD);
820 
821     // Signal that we want the next vsync event to be posted to the throttled connection
822     mThread->requestNextVsync(mThrottledConnection);
823 
824     // EventThread should immediately request a resync.
825     EXPECT_TRUE(mResyncCallRecorder.waitForCall().has_value());
826 
827     // EventThread should enable vsync callbacks.
828     expectVSyncCallbackScheduleReceived(true);
829 
830     // Use the received callback to signal a first vsync event.
831     // The throttler should receive the event, but not the connection.
832     onVSyncEvent(123, 456, 789);
833     expectThrottleVsyncReceived(456, mThrottledConnectionUid);
834     mThrottledConnectionEventCallRecorder.waitForUnexpectedCall();
835     expectVSyncCallbackScheduleReceived(true);
836 
837     // Use the received callback to signal a second vsync event.
838     // The throttler should receive the event, but the connection should
839     // not as it was only interested in the first.
840     onVSyncEvent(456, 123, 0);
841     expectThrottleVsyncReceived(123, mThrottledConnectionUid);
842     EXPECT_FALSE(mConnectionEventCallRecorder.waitForUnexpectedCall().has_value());
843     expectVSyncCallbackScheduleReceived(true);
844 
845     // EventThread should not change the vsync state as it didn't send the event
846     // yet
847     onVSyncEvent(456, 123, 0);
848     expectVSyncCallbackScheduleReceived(true);
849 }
850 
851 } // namespace
852 } // namespace android
853 
854 // TODO(b/129481165): remove the #pragma below and fix conversion issues
855 #pragma clang diagnostic pop // ignored "-Wextra"
856