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