blob: 5cecb8eb194e680372795efa9a3283b5a3445193 [file] [log] [blame]
Lloyd Pique24b0a482018-03-09 18:52:26 -08001/*
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
Marin Shalamanovbed7fd32020-12-21 20:02:20 +010017// TODO(b/129481165): remove the #pragma below and fix conversion issues
18#pragma clang diagnostic push
19#pragma clang diagnostic ignored "-Wextra"
20
Lloyd Pique24b0a482018-03-09 18:52:26 -080021#undef LOG_TAG
22#define LOG_TAG "LibSurfaceFlingerUnittests"
23
24#include <gmock/gmock.h>
25#include <gtest/gtest.h>
Lloyd Pique24b0a482018-03-09 18:52:26 -080026#include <log/log.h>
Lloyd Pique24b0a482018-03-09 18:52:26 -080027#include <utils/Errors.h>
28
29#include "AsyncCallRecorder.h"
Marin Shalamanov23c44202020-12-22 19:09:20 +010030#include "DisplayHardware/DisplayMode.h"
Rachel Lee3f028662021-11-04 19:32:24 +000031#include "FrameTimeline.h"
Ana Krulecfefcb582018-08-07 14:22:37 -070032#include "Scheduler/EventThread.h"
Ady Abraham011f8ba2022-11-22 15:09:07 -080033#include "mock/MockVSyncDispatch.h"
34#include "mock/MockVSyncTracker.h"
35#include "mock/MockVsyncController.h"
Lloyd Pique24b0a482018-03-09 18:52:26 -080036
37using namespace std::chrono_literals;
38using namespace std::placeholders;
39
40using testing::_;
41using testing::Invoke;
Ady Abraham011f8ba2022-11-22 15:09:07 -080042using testing::Return;
Lloyd Pique24b0a482018-03-09 18:52:26 -080043
44namespace android {
Ady Abraham2139f732019-11-13 18:56:40 -080045
Dominik Laskowski2f01d772022-03-23 16:01:29 -070046using namespace ftl::flag_operators;
47
Lloyd Pique24b0a482018-03-09 18:52:26 -080048namespace {
49
Dominik Laskowskif1833852021-03-23 15:06:50 -070050constexpr PhysicalDisplayId INTERNAL_DISPLAY_ID = PhysicalDisplayId::fromPort(111u);
51constexpr PhysicalDisplayId EXTERNAL_DISPLAY_ID = PhysicalDisplayId::fromPort(222u);
52constexpr PhysicalDisplayId DISPLAY_ID_64BIT =
53 PhysicalDisplayId::fromEdid(0xffu, 0xffffu, 0xffff'ffffu);
54
Lloyd Pique24b0a482018-03-09 18:52:26 -080055} // namespace
56
Leon Scroggins III31d41412022-11-18 16:42:53 -050057class EventThreadTest : public testing::Test, public IEventThreadCallback {
Lloyd Pique24b0a482018-03-09 18:52:26 -080058protected:
Ady Abraham011f8ba2022-11-22 15:09:07 -080059 static constexpr std::chrono::nanoseconds kWorkDuration = 0ms;
60 static constexpr std::chrono::nanoseconds kReadyDuration = 3ms;
61
Dominik Laskowskif654d572018-12-20 11:03:06 -080062 class MockEventThreadConnection : public EventThreadConnection {
Lloyd Pique24b0a482018-03-09 18:52:26 -080063 public:
Ady Abraham0bb6a472020-10-12 10:22:13 -070064 MockEventThreadConnection(impl::EventThread* eventThread, uid_t callingUid,
65 ResyncCallback&& resyncCallback,
Huihong Luo1b0c49f2022-03-15 19:18:21 -070066 EventRegistrationFlags eventRegistration)
Ady Abraham0bb6a472020-10-12 10:22:13 -070067 : EventThreadConnection(eventThread, callingUid, std::move(resyncCallback),
Ady Abraham62f216c2020-10-13 19:07:23 -070068 eventRegistration) {}
Lloyd Pique24b0a482018-03-09 18:52:26 -080069 MOCK_METHOD1(postEvent, status_t(const DisplayEventReceiver::Event& event));
70 };
71
72 using ConnectionEventRecorder =
73 AsyncCallRecorderWithCannedReturn<status_t (*)(const DisplayEventReceiver::Event&)>;
74
75 EventThreadTest();
76 ~EventThreadTest() override;
77
Ady Abraham011f8ba2022-11-22 15:09:07 -080078 void createThread();
Huihong Luo1b0c49f2022-03-15 19:18:21 -070079 sp<MockEventThreadConnection> createConnection(ConnectionEventRecorder& recorder,
80 EventRegistrationFlags eventRegistration = {},
81 uid_t ownerUid = mConnectionUid);
Lloyd Pique24b0a482018-03-09 18:52:26 -080082
Ady Abraham011f8ba2022-11-22 15:09:07 -080083 void expectVSyncCallbackScheduleReceived(bool expectState);
Ady Abraham9c53ee72020-07-22 21:16:18 -070084 void expectVSyncSetDurationCallReceived(std::chrono::nanoseconds expectedDuration,
85 std::chrono::nanoseconds expectedReadyDuration);
Lloyd Pique24b0a482018-03-09 18:52:26 -080086 void expectVsyncEventReceivedByConnection(const char* name,
87 ConnectionEventRecorder& connectionEventRecorder,
88 nsecs_t expectedTimestamp, unsigned expectedCount);
89 void expectVsyncEventReceivedByConnection(nsecs_t expectedTimestamp, unsigned expectedCount);
Ady Abraham011f8ba2022-11-22 15:09:07 -080090 void expectVsyncEventFrameTimelinesCorrect(
91 nsecs_t expectedTimestamp,
92 /*VSyncSource::VSyncData*/ gui::VsyncEventData::FrameTimeline preferredVsyncData);
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -080093 void expectHotplugEventReceivedByConnection(PhysicalDisplayId expectedDisplayId,
Dominik Laskowski00a6fa22018-06-06 16:42:02 -070094 bool expectedConnected);
Ady Abraham447052e2019-02-13 16:07:27 -080095 void expectConfigChangedEventReceivedByConnection(PhysicalDisplayId expectedDisplayId,
Alec Mouri60aee1c2019-10-28 16:18:59 -070096 int32_t expectedConfigId,
97 nsecs_t expectedVsyncPeriod);
Leon Scroggins III31d41412022-11-18 16:42:53 -050098 void expectThrottleVsyncReceived(TimePoint expectedTimestamp, uid_t);
Ady Abraham62f216c2020-10-13 19:07:23 -070099 void expectUidFrameRateMappingEventReceivedByConnection(PhysicalDisplayId expectedDisplayId,
100 std::vector<FrameRateOverride>);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800101
Ady Abraham011f8ba2022-11-22 15:09:07 -0800102 void onVSyncEvent(nsecs_t timestamp, nsecs_t expectedPresentationTime,
103 nsecs_t deadlineTimestamp) {
104 mThread->onVsync(expectedPresentationTime, timestamp, deadlineTimestamp);
105 }
106
Leon Scroggins III31d41412022-11-18 16:42:53 -0500107 // IEventThreadCallback overrides.
108 bool isVsyncTargetForUid(TimePoint expectedVsyncTime, uid_t uid) const override {
109 mThrottleVsyncCallRecorder.getInvocable()(expectedVsyncTime, uid);
110 return uid != mThrottledConnectionUid;
111 }
112
113 Fps getLeaderRenderFrameRate(uid_t uid) const override { return 60_Hz; }
114
Ady Abraham011f8ba2022-11-22 15:09:07 -0800115 AsyncCallRecorderWithCannedReturn<
116 scheduler::ScheduleResult (*)(scheduler::VSyncDispatch::CallbackToken,
117 scheduler::VSyncDispatch::ScheduleTiming)>
118 mVSyncCallbackScheduleRecorder{0};
119 AsyncCallRecorderWithCannedReturn<
120 scheduler::ScheduleResult (*)(scheduler::VSyncDispatch::CallbackToken,
121 scheduler::VSyncDispatch::ScheduleTiming)>
122 mVSyncCallbackUpdateRecorder{0};
123 AsyncCallRecorderWithCannedReturn<
124 scheduler::VSyncDispatch::CallbackToken (*)(scheduler::VSyncDispatch::Callback,
125 std::string)>
126 mVSyncCallbackRegisterRecorder{scheduler::VSyncDispatch::CallbackToken(0)};
127 AsyncCallRecorder<void (*)(scheduler::VSyncDispatch::CallbackToken)>
128 mVSyncCallbackUnregisterRecorder;
Lloyd Pique24b0a482018-03-09 18:52:26 -0800129 AsyncCallRecorder<void (*)()> mResyncCallRecorder;
Leon Scroggins III31d41412022-11-18 16:42:53 -0500130 mutable AsyncCallRecorder<void (*)(TimePoint, uid_t)> mThrottleVsyncCallRecorder;
Lloyd Pique24b0a482018-03-09 18:52:26 -0800131 ConnectionEventRecorder mConnectionEventCallRecorder{0};
Ady Abraham0bb6a472020-10-12 10:22:13 -0700132 ConnectionEventRecorder mThrottledConnectionEventCallRecorder{0};
Lloyd Pique24b0a482018-03-09 18:52:26 -0800133
Leon Scroggins III31d41412022-11-18 16:42:53 -0500134 std::shared_ptr<scheduler::VsyncSchedule> mVsyncSchedule;
Dominik Laskowski6505f792019-09-18 11:10:05 -0700135 std::unique_ptr<impl::EventThread> mThread;
Lloyd Pique24b0a482018-03-09 18:52:26 -0800136 sp<MockEventThreadConnection> mConnection;
Ady Abraham0bb6a472020-10-12 10:22:13 -0700137 sp<MockEventThreadConnection> mThrottledConnection;
Rachel Lee3f028662021-11-04 19:32:24 +0000138 std::unique_ptr<frametimeline::impl::TokenManager> mTokenManager;
Ady Abraham0bb6a472020-10-12 10:22:13 -0700139
140 static constexpr uid_t mConnectionUid = 443;
141 static constexpr uid_t mThrottledConnectionUid = 177;
Lloyd Pique24b0a482018-03-09 18:52:26 -0800142};
143
144EventThreadTest::EventThreadTest() {
145 const ::testing::TestInfo* const test_info =
146 ::testing::UnitTest::GetInstance()->current_test_info();
147 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
148
Leon Scroggins III31d41412022-11-18 16:42:53 -0500149 auto mockDispatchPtr = std::make_shared<mock::VSyncDispatch>();
150 mVsyncSchedule = std::shared_ptr<scheduler::VsyncSchedule>(
151 new scheduler::VsyncSchedule(INTERNAL_DISPLAY_ID,
152 std::make_shared<mock::VSyncTracker>(), mockDispatchPtr,
153 nullptr));
154 mock::VSyncDispatch& mockDispatch = *mockDispatchPtr;
Ady Abraham011f8ba2022-11-22 15:09:07 -0800155 EXPECT_CALL(mockDispatch, registerCallback(_, _))
156 .WillRepeatedly(Invoke(mVSyncCallbackRegisterRecorder.getInvocable()));
157 EXPECT_CALL(mockDispatch, schedule(_, _))
158 .WillRepeatedly(Invoke(mVSyncCallbackScheduleRecorder.getInvocable()));
159 EXPECT_CALL(mockDispatch, update(_, _))
160 .WillRepeatedly(Invoke(mVSyncCallbackUpdateRecorder.getInvocable()));
161 EXPECT_CALL(mockDispatch, unregisterCallback(_))
162 .WillRepeatedly(Invoke(mVSyncCallbackUnregisterRecorder.getInvocable()));
Lloyd Pique24b0a482018-03-09 18:52:26 -0800163
Ady Abraham011f8ba2022-11-22 15:09:07 -0800164 createThread();
Huihong Luo1b0c49f2022-03-15 19:18:21 -0700165 mConnection =
166 createConnection(mConnectionEventCallRecorder,
167 gui::ISurfaceComposer::EventRegistration::modeChanged |
168 gui::ISurfaceComposer::EventRegistration::frameRateOverride);
Ady Abraham62f216c2020-10-13 19:07:23 -0700169 mThrottledConnection = createConnection(mThrottledConnectionEventCallRecorder,
Huihong Luo1b0c49f2022-03-15 19:18:21 -0700170 gui::ISurfaceComposer::EventRegistration::modeChanged,
Ady Abraham62f216c2020-10-13 19:07:23 -0700171 mThrottledConnectionUid);
Dominik Laskowski1eba0202019-01-24 09:14:40 -0800172
173 // A display must be connected for VSYNC events to be delivered.
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800174 mThread->onHotplugReceived(INTERNAL_DISPLAY_ID, true);
175 expectHotplugEventReceivedByConnection(INTERNAL_DISPLAY_ID, true);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800176}
177
178EventThreadTest::~EventThreadTest() {
179 const ::testing::TestInfo* const test_info =
180 ::testing::UnitTest::GetInstance()->current_test_info();
181 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
Dominik Laskowski029cc122019-01-23 19:52:06 -0800182
Ady Abraham011f8ba2022-11-22 15:09:07 -0800183 mThread.reset();
Dominik Laskowski029cc122019-01-23 19:52:06 -0800184 // EventThread should unregister itself as VSyncSource callback.
Ady Abraham011f8ba2022-11-22 15:09:07 -0800185 EXPECT_TRUE(mVSyncCallbackUnregisterRecorder.waitForCall().has_value());
Lloyd Pique24b0a482018-03-09 18:52:26 -0800186}
187
Ady Abraham011f8ba2022-11-22 15:09:07 -0800188void EventThreadTest::createThread() {
Rachel Lee3f028662021-11-04 19:32:24 +0000189 mTokenManager = std::make_unique<frametimeline::impl::TokenManager>();
Ady Abraham011f8ba2022-11-22 15:09:07 -0800190 mThread =
Leon Scroggins III31d41412022-11-18 16:42:53 -0500191 std::make_unique<impl::EventThread>("EventThreadTest", mVsyncSchedule, *this,
192 mTokenManager.get(), kWorkDuration, kReadyDuration);
Dominik Laskowski029cc122019-01-23 19:52:06 -0800193
194 // EventThread should register itself as VSyncSource callback.
Ady Abraham011f8ba2022-11-22 15:09:07 -0800195 EXPECT_TRUE(mVSyncCallbackRegisterRecorder.waitForCall().has_value());
Lloyd Pique24b0a482018-03-09 18:52:26 -0800196}
197
198sp<EventThreadTest::MockEventThreadConnection> EventThreadTest::createConnection(
Huihong Luo1b0c49f2022-03-15 19:18:21 -0700199 ConnectionEventRecorder& recorder, EventRegistrationFlags eventRegistration,
200 uid_t ownerUid) {
Dominik Laskowskif654d572018-12-20 11:03:06 -0800201 sp<MockEventThreadConnection> connection =
Ady Abrahamd11bade2022-08-01 16:18:03 -0700202 sp<MockEventThreadConnection>::make(mThread.get(), ownerUid,
203 mResyncCallRecorder.getInvocable(),
204 eventRegistration);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800205 EXPECT_CALL(*connection, postEvent(_)).WillRepeatedly(Invoke(recorder.getInvocable()));
206 return connection;
207}
208
Ady Abraham011f8ba2022-11-22 15:09:07 -0800209void EventThreadTest::expectVSyncCallbackScheduleReceived(bool expectState) {
210 if (expectState) {
211 ASSERT_TRUE(mVSyncCallbackScheduleRecorder.waitForCall().has_value());
212 } else {
213 ASSERT_FALSE(mVSyncCallbackScheduleRecorder.waitForUnexpectedCall().has_value());
214 }
Lloyd Pique24b0a482018-03-09 18:52:26 -0800215}
216
Ady Abraham9c53ee72020-07-22 21:16:18 -0700217void EventThreadTest::expectVSyncSetDurationCallReceived(
218 std::chrono::nanoseconds expectedDuration, std::chrono::nanoseconds expectedReadyDuration) {
Ady Abraham011f8ba2022-11-22 15:09:07 -0800219 auto args = mVSyncCallbackUpdateRecorder.waitForCall();
Lloyd Pique24b0a482018-03-09 18:52:26 -0800220 ASSERT_TRUE(args.has_value());
Ady Abraham011f8ba2022-11-22 15:09:07 -0800221 EXPECT_EQ(expectedDuration.count(), std::get<1>(args.value()).workDuration);
222 EXPECT_EQ(expectedReadyDuration.count(), std::get<1>(args.value()).readyDuration);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800223}
224
Leon Scroggins III31d41412022-11-18 16:42:53 -0500225void EventThreadTest::expectThrottleVsyncReceived(TimePoint expectedTimestamp, uid_t uid) {
Ady Abraham0bb6a472020-10-12 10:22:13 -0700226 auto args = mThrottleVsyncCallRecorder.waitForCall();
227 ASSERT_TRUE(args.has_value());
228 EXPECT_EQ(expectedTimestamp, std::get<0>(args.value()));
229 EXPECT_EQ(uid, std::get<1>(args.value()));
230}
231
Lloyd Pique24b0a482018-03-09 18:52:26 -0800232void EventThreadTest::expectVsyncEventReceivedByConnection(
233 const char* name, ConnectionEventRecorder& connectionEventRecorder,
234 nsecs_t expectedTimestamp, unsigned expectedCount) {
235 auto args = connectionEventRecorder.waitForCall();
236 ASSERT_TRUE(args.has_value()) << name << " did not receive an event for timestamp "
237 << expectedTimestamp;
238 const auto& event = std::get<0>(args.value());
239 EXPECT_EQ(DisplayEventReceiver::DISPLAY_EVENT_VSYNC, event.header.type)
240 << name << " did not get the correct event for timestamp " << expectedTimestamp;
241 EXPECT_EQ(expectedTimestamp, event.header.timestamp)
242 << name << " did not get the expected timestamp for timestamp " << expectedTimestamp;
243 EXPECT_EQ(expectedCount, event.vsync.count)
244 << name << " did not get the expected count for timestamp " << expectedTimestamp;
245}
246
247void EventThreadTest::expectVsyncEventReceivedByConnection(nsecs_t expectedTimestamp,
248 unsigned expectedCount) {
249 expectVsyncEventReceivedByConnection("mConnectionEventCallRecorder",
250 mConnectionEventCallRecorder, expectedTimestamp,
251 expectedCount);
252}
253
Rachel Leeb9c5a772022-02-04 21:17:37 -0800254void EventThreadTest::expectVsyncEventFrameTimelinesCorrect(
Ady Abraham011f8ba2022-11-22 15:09:07 -0800255 nsecs_t expectedTimestamp, VsyncEventData::FrameTimeline preferredVsyncData) {
Rachel Lee3f028662021-11-04 19:32:24 +0000256 auto args = mConnectionEventCallRecorder.waitForCall();
257 ASSERT_TRUE(args.has_value()) << " did not receive an event for timestamp "
258 << expectedTimestamp;
259 const auto& event = std::get<0>(args.value());
Rachel Leeef2e21f2022-02-01 14:51:34 -0800260 for (int i = 0; i < VsyncEventData::kFrameTimelinesLength; i++) {
Rachel Leeb9c5a772022-02-04 21:17:37 -0800261 auto prediction = mTokenManager->getPredictionsForToken(
262 event.vsync.vsyncData.frameTimelines[i].vsyncId);
Rachel Lee8d0c6102021-11-03 22:00:25 +0000263 EXPECT_TRUE(prediction.has_value());
Rachel Leeb9c5a772022-02-04 21:17:37 -0800264 EXPECT_EQ(prediction.value().endTime,
265 event.vsync.vsyncData.frameTimelines[i].deadlineTimestamp)
Rachel Lee8d0c6102021-11-03 22:00:25 +0000266 << "Deadline timestamp does not match cached value";
267 EXPECT_EQ(prediction.value().presentTime,
Rachel Leeb9c5a772022-02-04 21:17:37 -0800268 event.vsync.vsyncData.frameTimelines[i].expectedPresentationTime)
269 << "Expected vsync.vsyncData timestamp does not match cached value";
Rachel Lee8d0c6102021-11-03 22:00:25 +0000270
Rachel Lee3f028662021-11-04 19:32:24 +0000271 if (i > 0) {
Rachel Leeb9c5a772022-02-04 21:17:37 -0800272 EXPECT_GT(event.vsync.vsyncData.frameTimelines[i].deadlineTimestamp,
273 event.vsync.vsyncData.frameTimelines[i - 1].deadlineTimestamp)
Rachel Lee3f028662021-11-04 19:32:24 +0000274 << "Deadline timestamp out of order for frame timeline " << i;
Rachel Leeb9c5a772022-02-04 21:17:37 -0800275 EXPECT_GT(event.vsync.vsyncData.frameTimelines[i].expectedPresentationTime,
276 event.vsync.vsyncData.frameTimelines[i - 1].expectedPresentationTime)
277 << "Expected vsync.vsyncData timestamp out of order for frame timeline " << i;
Rachel Lee3f028662021-11-04 19:32:24 +0000278 }
Rachel Lee0d943202022-02-01 23:29:41 -0800279
280 // Vsync ID order lines up with registration into test token manager.
Rachel Leeb9c5a772022-02-04 21:17:37 -0800281 EXPECT_EQ(i, event.vsync.vsyncData.frameTimelines[i].vsyncId)
Rachel Lee0d943202022-02-01 23:29:41 -0800282 << "Vsync ID incorrect for frame timeline " << i;
Rachel Leeb9c5a772022-02-04 21:17:37 -0800283 if (i == event.vsync.vsyncData.preferredFrameTimelineIndex) {
284 EXPECT_EQ(event.vsync.vsyncData.frameTimelines[i].deadlineTimestamp,
285 preferredVsyncData.deadlineTimestamp)
Rachel Lee0d943202022-02-01 23:29:41 -0800286 << "Preferred deadline timestamp incorrect" << i;
Rachel Leeb9c5a772022-02-04 21:17:37 -0800287 EXPECT_EQ(event.vsync.vsyncData.frameTimelines[i].expectedPresentationTime,
288 preferredVsyncData.expectedPresentationTime)
289 << "Preferred expected vsync.vsyncData timestamp incorrect" << i;
Rachel Lee3f028662021-11-04 19:32:24 +0000290 }
291 }
292}
293
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800294void EventThreadTest::expectHotplugEventReceivedByConnection(PhysicalDisplayId expectedDisplayId,
295 bool expectedConnected) {
Lloyd Pique24b0a482018-03-09 18:52:26 -0800296 auto args = mConnectionEventCallRecorder.waitForCall();
297 ASSERT_TRUE(args.has_value());
298 const auto& event = std::get<0>(args.value());
299 EXPECT_EQ(DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG, event.header.type);
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800300 EXPECT_EQ(expectedDisplayId, event.header.displayId);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800301 EXPECT_EQ(expectedConnected, event.hotplug.connected);
302}
303
Ady Abraham447052e2019-02-13 16:07:27 -0800304void EventThreadTest::expectConfigChangedEventReceivedByConnection(
Alec Mouri60aee1c2019-10-28 16:18:59 -0700305 PhysicalDisplayId expectedDisplayId, int32_t expectedConfigId,
306 nsecs_t expectedVsyncPeriod) {
Ady Abraham447052e2019-02-13 16:07:27 -0800307 auto args = mConnectionEventCallRecorder.waitForCall();
308 ASSERT_TRUE(args.has_value());
309 const auto& event = std::get<0>(args.value());
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100310 EXPECT_EQ(DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE, event.header.type);
Ady Abraham447052e2019-02-13 16:07:27 -0800311 EXPECT_EQ(expectedDisplayId, event.header.displayId);
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100312 EXPECT_EQ(expectedConfigId, event.modeChange.modeId);
313 EXPECT_EQ(expectedVsyncPeriod, event.modeChange.vsyncPeriod);
Ady Abraham447052e2019-02-13 16:07:27 -0800314}
315
Ady Abraham62f216c2020-10-13 19:07:23 -0700316void EventThreadTest::expectUidFrameRateMappingEventReceivedByConnection(
317 PhysicalDisplayId expectedDisplayId, std::vector<FrameRateOverride> expectedOverrides) {
318 for (const auto [uid, frameRateHz] : expectedOverrides) {
319 auto args = mConnectionEventCallRecorder.waitForCall();
320 ASSERT_TRUE(args.has_value());
321 const auto& event = std::get<0>(args.value());
322 EXPECT_EQ(DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE, event.header.type);
323 EXPECT_EQ(expectedDisplayId, event.header.displayId);
324 EXPECT_EQ(uid, event.frameRateOverride.uid);
325 EXPECT_EQ(frameRateHz, event.frameRateOverride.frameRateHz);
326 }
327
328 auto args = mConnectionEventCallRecorder.waitForCall();
329 ASSERT_TRUE(args.has_value());
330 const auto& event = std::get<0>(args.value());
331 EXPECT_EQ(DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH, event.header.type);
332 EXPECT_EQ(expectedDisplayId, event.header.displayId);
333}
334
Lloyd Pique24b0a482018-03-09 18:52:26 -0800335namespace {
336
Rachel Leeef2e21f2022-02-01 14:51:34 -0800337using namespace testing;
338
Lloyd Pique24b0a482018-03-09 18:52:26 -0800339/* ------------------------------------------------------------------------
340 * Test cases
341 */
342
343TEST_F(EventThreadTest, canCreateAndDestroyThreadWithNoEventsSent) {
Ady Abraham011f8ba2022-11-22 15:09:07 -0800344 EXPECT_FALSE(mVSyncCallbackRegisterRecorder.waitForCall(0us).has_value());
345 EXPECT_FALSE(mVSyncCallbackScheduleRecorder.waitForCall(0us).has_value());
346 EXPECT_FALSE(mVSyncCallbackUpdateRecorder.waitForCall(0us).has_value());
347 EXPECT_FALSE(mVSyncCallbackUnregisterRecorder.waitForCall(0us).has_value());
Lloyd Pique24b0a482018-03-09 18:52:26 -0800348 EXPECT_FALSE(mResyncCallRecorder.waitForCall(0us).has_value());
Lloyd Pique24b0a482018-03-09 18:52:26 -0800349 EXPECT_FALSE(mConnectionEventCallRecorder.waitForCall(0us).has_value());
350}
351
Dominik Laskowski1eba0202019-01-24 09:14:40 -0800352TEST_F(EventThreadTest, vsyncRequestIsIgnoredIfDisplayIsDisconnected) {
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800353 mThread->onHotplugReceived(INTERNAL_DISPLAY_ID, false);
354 expectHotplugEventReceivedByConnection(INTERNAL_DISPLAY_ID, false);
Dominik Laskowski1eba0202019-01-24 09:14:40 -0800355
356 // Signal that we want the next vsync event to be posted to the connection.
Ady Abraham8532d012019-05-08 14:50:56 -0700357 mThread->requestNextVsync(mConnection);
Dominik Laskowski1eba0202019-01-24 09:14:40 -0800358
359 // EventThread should not enable vsync callbacks.
Ady Abraham011f8ba2022-11-22 15:09:07 -0800360 expectVSyncCallbackScheduleReceived(false);
Dominik Laskowski1eba0202019-01-24 09:14:40 -0800361}
362
Lloyd Pique24b0a482018-03-09 18:52:26 -0800363TEST_F(EventThreadTest, requestNextVsyncPostsASingleVSyncEventToTheConnection) {
364 // Signal that we want the next vsync event to be posted to the connection
Ady Abraham8532d012019-05-08 14:50:56 -0700365 mThread->requestNextVsync(mConnection);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800366
Ady Abraham8532d012019-05-08 14:50:56 -0700367 // EventThread should immediately request a resync.
Lloyd Pique24b0a482018-03-09 18:52:26 -0800368 EXPECT_TRUE(mResyncCallRecorder.waitForCall().has_value());
369
Ady Abraham011f8ba2022-11-22 15:09:07 -0800370 // EventThread should enable schedule a vsync callback
371 expectVSyncCallbackScheduleReceived(true);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800372
373 // Use the received callback to signal a first vsync event.
Huihong Luoab8ffef2022-08-18 13:02:26 -0700374 // The throttler should receive the event, as well as the connection.
Ady Abraham011f8ba2022-11-22 15:09:07 -0800375 onVSyncEvent(123, 456, 789);
Leon Scroggins III31d41412022-11-18 16:42:53 -0500376 expectThrottleVsyncReceived(TimePoint::fromNs(456), mConnectionUid);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800377 expectVsyncEventReceivedByConnection(123, 1u);
378
Ady Abraham011f8ba2022-11-22 15:09:07 -0800379 // EventThread is requesting one more callback due to VsyncRequest::SingleSuppressCallback
380 expectVSyncCallbackScheduleReceived(true);
381
Lloyd Pique24b0a482018-03-09 18:52:26 -0800382 // Use the received callback to signal a second vsync event.
Huihong Luoab8ffef2022-08-18 13:02:26 -0700383 // The throttler should receive the event, but the connection should
Lloyd Pique24b0a482018-03-09 18:52:26 -0800384 // not as it was only interested in the first.
Ady Abraham011f8ba2022-11-22 15:09:07 -0800385 onVSyncEvent(456, 123, 0);
Ady Abraham0bb6a472020-10-12 10:22:13 -0700386 EXPECT_FALSE(mThrottleVsyncCallRecorder.waitForUnexpectedCall().has_value());
Lloyd Pique24b0a482018-03-09 18:52:26 -0800387 EXPECT_FALSE(mConnectionEventCallRecorder.waitForUnexpectedCall().has_value());
388
389 // EventThread should also detect that at this point that it does not need
390 // any more vsync events, and should disable their generation.
Ady Abraham011f8ba2022-11-22 15:09:07 -0800391 expectVSyncCallbackScheduleReceived(false);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800392}
393
Rachel Lee3f028662021-11-04 19:32:24 +0000394TEST_F(EventThreadTest, requestNextVsyncEventFrameTimelinesCorrect) {
395 // Signal that we want the next vsync event to be posted to the connection
396 mThread->requestNextVsync(mConnection);
397
Ady Abraham011f8ba2022-11-22 15:09:07 -0800398 expectVSyncCallbackScheduleReceived(true);
Rachel Lee3f028662021-11-04 19:32:24 +0000399
400 // Use the received callback to signal a vsync event.
Huihong Luoab8ffef2022-08-18 13:02:26 -0700401 // The throttler should receive the event, as well as the connection.
Ady Abraham011f8ba2022-11-22 15:09:07 -0800402 onVSyncEvent(123, 456, 789);
403 expectVsyncEventFrameTimelinesCorrect(123, {-1, 789, 456});
Rachel Lee3f028662021-11-04 19:32:24 +0000404}
405
Rachel Leeef2e21f2022-02-01 14:51:34 -0800406TEST_F(EventThreadTest, getLatestVsyncEventData) {
407 const nsecs_t now = systemTime();
Rachel Leeb9c5a772022-02-04 21:17:37 -0800408 const nsecs_t preferredExpectedPresentationTime = now + 20000000;
Ady Abraham011f8ba2022-11-22 15:09:07 -0800409 const nsecs_t preferredDeadline = preferredExpectedPresentationTime - kReadyDuration.count();
410
411 mock::VSyncTracker& mockTracker =
412 *static_cast<mock::VSyncTracker*>(&mVsyncSchedule->getTracker());
413 EXPECT_CALL(mockTracker, nextAnticipatedVSyncTimeFrom(_))
414 .WillOnce(Return(preferredExpectedPresentationTime));
Rachel Leeef2e21f2022-02-01 14:51:34 -0800415
416 VsyncEventData vsyncEventData = mThread->getLatestVsyncEventData(mConnection);
Rachel Leeb5223cf2022-03-14 14:39:27 -0700417
418 // Check EventThread immediately requested a resync.
419 EXPECT_TRUE(mResyncCallRecorder.waitForCall().has_value());
420
Rachel Leeef2e21f2022-02-01 14:51:34 -0800421 EXPECT_GT(vsyncEventData.frameTimelines[0].deadlineTimestamp, now)
422 << "Deadline timestamp should be greater than frame time";
423 for (size_t i = 0; i < VsyncEventData::kFrameTimelinesLength; i++) {
424 auto prediction =
Rachel Leeb9c5a772022-02-04 21:17:37 -0800425 mTokenManager->getPredictionsForToken(vsyncEventData.frameTimelines[i].vsyncId);
Rachel Leeef2e21f2022-02-01 14:51:34 -0800426 EXPECT_TRUE(prediction.has_value());
427 EXPECT_EQ(prediction.value().endTime, vsyncEventData.frameTimelines[i].deadlineTimestamp)
428 << "Deadline timestamp does not match cached value";
429 EXPECT_EQ(prediction.value().presentTime,
Rachel Leeb9c5a772022-02-04 21:17:37 -0800430 vsyncEventData.frameTimelines[i].expectedPresentationTime)
Rachel Leeef2e21f2022-02-01 14:51:34 -0800431 << "Expected vsync timestamp does not match cached value";
Rachel Leeb9c5a772022-02-04 21:17:37 -0800432 EXPECT_GT(vsyncEventData.frameTimelines[i].expectedPresentationTime,
Rachel Leeef2e21f2022-02-01 14:51:34 -0800433 vsyncEventData.frameTimelines[i].deadlineTimestamp)
434 << "Expected vsync timestamp should be greater than deadline";
435
436 if (i > 0) {
437 EXPECT_GT(vsyncEventData.frameTimelines[i].deadlineTimestamp,
438 vsyncEventData.frameTimelines[i - 1].deadlineTimestamp)
439 << "Deadline timestamp out of order for frame timeline " << i;
Rachel Leeb9c5a772022-02-04 21:17:37 -0800440 EXPECT_GT(vsyncEventData.frameTimelines[i].expectedPresentationTime,
441 vsyncEventData.frameTimelines[i - 1].expectedPresentationTime)
Rachel Leeef2e21f2022-02-01 14:51:34 -0800442 << "Expected vsync timestamp out of order for frame timeline " << i;
443 }
444
445 // Vsync ID order lines up with registration into test token manager.
Rachel Leeb9c5a772022-02-04 21:17:37 -0800446 EXPECT_EQ(i, vsyncEventData.frameTimelines[i].vsyncId)
Rachel Leeef2e21f2022-02-01 14:51:34 -0800447 << "Vsync ID incorrect for frame timeline " << i;
448 if (i == vsyncEventData.preferredFrameTimelineIndex) {
449 EXPECT_EQ(vsyncEventData.frameTimelines[i].deadlineTimestamp, preferredDeadline)
450 << "Preferred deadline timestamp incorrect" << i;
Rachel Leeb9c5a772022-02-04 21:17:37 -0800451 EXPECT_EQ(vsyncEventData.frameTimelines[i].expectedPresentationTime,
452 preferredExpectedPresentationTime)
Rachel Leeef2e21f2022-02-01 14:51:34 -0800453 << "Preferred expected vsync timestamp incorrect" << i;
454 }
455 }
456}
457
Lloyd Pique24b0a482018-03-09 18:52:26 -0800458TEST_F(EventThreadTest, setVsyncRateZeroPostsNoVSyncEventsToThatConnection) {
459 // Create a first connection, register it, and request a vsync rate of zero.
460 ConnectionEventRecorder firstConnectionEventRecorder{0};
Ady Abraham62f216c2020-10-13 19:07:23 -0700461 sp<MockEventThreadConnection> firstConnection = createConnection(firstConnectionEventRecorder);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800462 mThread->setVsyncRate(0, firstConnection);
463
464 // By itself, this should not enable vsync events
Ady Abraham011f8ba2022-11-22 15:09:07 -0800465 expectVSyncCallbackScheduleReceived(false);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800466
467 // However if there is another connection which wants events at a nonzero rate.....
468 ConnectionEventRecorder secondConnectionEventRecorder{0};
469 sp<MockEventThreadConnection> secondConnection =
Ady Abraham62f216c2020-10-13 19:07:23 -0700470 createConnection(secondConnectionEventRecorder);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800471 mThread->setVsyncRate(1, secondConnection);
472
Dominik Laskowski029cc122019-01-23 19:52:06 -0800473 // EventThread should enable vsync callbacks.
Ady Abraham011f8ba2022-11-22 15:09:07 -0800474 expectVSyncCallbackScheduleReceived(true);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800475
476 // Send a vsync event. EventThread should then make a call to the
Huihong Luoab8ffef2022-08-18 13:02:26 -0700477 // the second connection. The first connection should not
Lloyd Pique24b0a482018-03-09 18:52:26 -0800478 // get the event.
Ady Abraham011f8ba2022-11-22 15:09:07 -0800479 onVSyncEvent(123, 0456, 0);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800480 EXPECT_FALSE(firstConnectionEventRecorder.waitForUnexpectedCall().has_value());
481 expectVsyncEventReceivedByConnection("secondConnection", secondConnectionEventRecorder, 123,
482 1u);
483}
484
485TEST_F(EventThreadTest, setVsyncRateOnePostsAllEventsToThatConnection) {
486 mThread->setVsyncRate(1, mConnection);
487
Dominik Laskowski029cc122019-01-23 19:52:06 -0800488 // EventThread should enable vsync callbacks.
Ady Abraham011f8ba2022-11-22 15:09:07 -0800489 expectVSyncCallbackScheduleReceived(true);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800490
491 // Send a vsync event. EventThread should then make a call to the
Huihong Luoab8ffef2022-08-18 13:02:26 -0700492 // throttler, and the connection.
Ady Abraham011f8ba2022-11-22 15:09:07 -0800493 onVSyncEvent(123, 456, 789);
Leon Scroggins III31d41412022-11-18 16:42:53 -0500494 expectThrottleVsyncReceived(TimePoint::fromNs(456), mConnectionUid);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800495 expectVsyncEventReceivedByConnection(123, 1u);
496
497 // A second event should go to the same places.
Ady Abraham011f8ba2022-11-22 15:09:07 -0800498 onVSyncEvent(456, 123, 0);
Leon Scroggins III31d41412022-11-18 16:42:53 -0500499 expectThrottleVsyncReceived(TimePoint::fromNs(123), mConnectionUid);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800500 expectVsyncEventReceivedByConnection(456, 2u);
501
502 // A third event should go to the same places.
Ady Abraham011f8ba2022-11-22 15:09:07 -0800503 onVSyncEvent(789, 777, 111);
Leon Scroggins III31d41412022-11-18 16:42:53 -0500504 expectThrottleVsyncReceived(TimePoint::fromNs(777), mConnectionUid);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800505 expectVsyncEventReceivedByConnection(789, 3u);
506}
507
508TEST_F(EventThreadTest, setVsyncRateTwoPostsEveryOtherEventToThatConnection) {
509 mThread->setVsyncRate(2, mConnection);
510
Dominik Laskowski029cc122019-01-23 19:52:06 -0800511 // EventThread should enable vsync callbacks.
Ady Abraham011f8ba2022-11-22 15:09:07 -0800512 expectVSyncCallbackScheduleReceived(true);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800513
Huihong Luoab8ffef2022-08-18 13:02:26 -0700514 // The first event will not be seen by the connection.
Ady Abraham011f8ba2022-11-22 15:09:07 -0800515 onVSyncEvent(123, 456, 789);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800516 EXPECT_FALSE(mConnectionEventCallRecorder.waitForUnexpectedCall().has_value());
Ady Abraham0bb6a472020-10-12 10:22:13 -0700517 EXPECT_FALSE(mThrottleVsyncCallRecorder.waitForUnexpectedCall().has_value());
Lloyd Pique24b0a482018-03-09 18:52:26 -0800518
Huihong Luoab8ffef2022-08-18 13:02:26 -0700519 // The second event will be seen by the connection.
Ady Abraham011f8ba2022-11-22 15:09:07 -0800520 onVSyncEvent(456, 123, 0);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800521 expectVsyncEventReceivedByConnection(456, 2u);
Ady Abraham0bb6a472020-10-12 10:22:13 -0700522 EXPECT_FALSE(mThrottleVsyncCallRecorder.waitForUnexpectedCall().has_value());
Lloyd Pique24b0a482018-03-09 18:52:26 -0800523
Huihong Luoab8ffef2022-08-18 13:02:26 -0700524 // The third event will not be seen by the connection.
Ady Abraham011f8ba2022-11-22 15:09:07 -0800525 onVSyncEvent(789, 777, 744);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800526 EXPECT_FALSE(mConnectionEventCallRecorder.waitForUnexpectedCall().has_value());
Ady Abraham0bb6a472020-10-12 10:22:13 -0700527 EXPECT_FALSE(mThrottleVsyncCallRecorder.waitForUnexpectedCall().has_value());
Lloyd Pique24b0a482018-03-09 18:52:26 -0800528
Huihong Luoab8ffef2022-08-18 13:02:26 -0700529 // The fourth event will be seen by the connection.
Ady Abraham011f8ba2022-11-22 15:09:07 -0800530 onVSyncEvent(101112, 7847, 86);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800531 expectVsyncEventReceivedByConnection(101112, 4u);
532}
533
534TEST_F(EventThreadTest, connectionsRemovedIfInstanceDestroyed) {
535 mThread->setVsyncRate(1, mConnection);
536
Dominik Laskowski029cc122019-01-23 19:52:06 -0800537 // EventThread should enable vsync callbacks.
Ady Abraham011f8ba2022-11-22 15:09:07 -0800538 expectVSyncCallbackScheduleReceived(true);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800539
540 // Destroy the only (strong) reference to the connection.
541 mConnection = nullptr;
542
Huihong Luoab8ffef2022-08-18 13:02:26 -0700543 // The first event will not be seen by the connection.
Ady Abraham011f8ba2022-11-22 15:09:07 -0800544 onVSyncEvent(123, 56, 789);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800545 EXPECT_FALSE(mConnectionEventCallRecorder.waitForUnexpectedCall().has_value());
546
547 // EventThread should disable vsync callbacks
Ady Abraham011f8ba2022-11-22 15:09:07 -0800548 expectVSyncCallbackScheduleReceived(false);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800549}
550
551TEST_F(EventThreadTest, connectionsRemovedIfEventDeliveryError) {
552 ConnectionEventRecorder errorConnectionEventRecorder{NO_MEMORY};
Ady Abraham62f216c2020-10-13 19:07:23 -0700553 sp<MockEventThreadConnection> errorConnection = createConnection(errorConnectionEventRecorder);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800554 mThread->setVsyncRate(1, errorConnection);
555
Dominik Laskowski029cc122019-01-23 19:52:06 -0800556 // EventThread should enable vsync callbacks.
Ady Abraham011f8ba2022-11-22 15:09:07 -0800557 expectVSyncCallbackScheduleReceived(true);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800558
Huihong Luoab8ffef2022-08-18 13:02:26 -0700559 // The first event will be seen by the connection, which then returns an error.
Ady Abraham011f8ba2022-11-22 15:09:07 -0800560 onVSyncEvent(123, 456, 789);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800561 expectVsyncEventReceivedByConnection("errorConnection", errorConnectionEventRecorder, 123, 1u);
562
Ady Abraham011f8ba2022-11-22 15:09:07 -0800563 // Another schedule is expected, since the connection is removed only after
564 // the next vsync is requested.
565 expectVSyncCallbackScheduleReceived(true);
566
Huihong Luoab8ffef2022-08-18 13:02:26 -0700567 // A subsequent event will not be seen by the connection.
Ady Abraham011f8ba2022-11-22 15:09:07 -0800568 onVSyncEvent(456, 123, 0);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800569 EXPECT_FALSE(errorConnectionEventRecorder.waitForUnexpectedCall().has_value());
570
571 // EventThread should disable vsync callbacks with the second event
Ady Abraham011f8ba2022-11-22 15:09:07 -0800572 expectVSyncCallbackScheduleReceived(false);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800573}
574
Alec Mouri717bcb62020-02-10 17:07:19 -0800575TEST_F(EventThreadTest, tracksEventConnections) {
Ady Abraham0bb6a472020-10-12 10:22:13 -0700576 EXPECT_EQ(2, mThread->getEventThreadConnectionCount());
Alec Mouri717bcb62020-02-10 17:07:19 -0800577 ConnectionEventRecorder errorConnectionEventRecorder{NO_MEMORY};
Ady Abraham62f216c2020-10-13 19:07:23 -0700578 sp<MockEventThreadConnection> errorConnection = createConnection(errorConnectionEventRecorder);
Alec Mouri717bcb62020-02-10 17:07:19 -0800579 mThread->setVsyncRate(1, errorConnection);
Ady Abraham0bb6a472020-10-12 10:22:13 -0700580 EXPECT_EQ(3, mThread->getEventThreadConnectionCount());
Alec Mouri717bcb62020-02-10 17:07:19 -0800581 ConnectionEventRecorder secondConnectionEventRecorder{0};
582 sp<MockEventThreadConnection> secondConnection =
Ady Abraham62f216c2020-10-13 19:07:23 -0700583 createConnection(secondConnectionEventRecorder);
Alec Mouri717bcb62020-02-10 17:07:19 -0800584 mThread->setVsyncRate(1, secondConnection);
Ady Abraham0bb6a472020-10-12 10:22:13 -0700585 EXPECT_EQ(4, mThread->getEventThreadConnectionCount());
Alec Mouri717bcb62020-02-10 17:07:19 -0800586
587 // EventThread should enable vsync callbacks.
Ady Abraham011f8ba2022-11-22 15:09:07 -0800588 expectVSyncCallbackScheduleReceived(true);
Alec Mouri717bcb62020-02-10 17:07:19 -0800589
Huihong Luoab8ffef2022-08-18 13:02:26 -0700590 // The first event will be seen by the connection, which then returns an error.
Ady Abraham011f8ba2022-11-22 15:09:07 -0800591 onVSyncEvent(123, 456, 789);
Alec Mouri717bcb62020-02-10 17:07:19 -0800592 expectVsyncEventReceivedByConnection("errorConnection", errorConnectionEventRecorder, 123, 1u);
593 expectVsyncEventReceivedByConnection("successConnection", secondConnectionEventRecorder, 123,
594 1u);
Ady Abraham0bb6a472020-10-12 10:22:13 -0700595 EXPECT_EQ(3, mThread->getEventThreadConnectionCount());
Alec Mouri717bcb62020-02-10 17:07:19 -0800596}
597
Lloyd Pique24b0a482018-03-09 18:52:26 -0800598TEST_F(EventThreadTest, eventsDroppedIfNonfatalEventDeliveryError) {
599 ConnectionEventRecorder errorConnectionEventRecorder{WOULD_BLOCK};
Ady Abraham62f216c2020-10-13 19:07:23 -0700600 sp<MockEventThreadConnection> errorConnection = createConnection(errorConnectionEventRecorder);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800601 mThread->setVsyncRate(1, errorConnection);
602
Dominik Laskowski029cc122019-01-23 19:52:06 -0800603 // EventThread should enable vsync callbacks.
Ady Abraham011f8ba2022-11-22 15:09:07 -0800604 expectVSyncCallbackScheduleReceived(true);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800605
Huihong Luoab8ffef2022-08-18 13:02:26 -0700606 // The first event will be seen by the connection, which then returns a non-fatal error.
Ady Abraham011f8ba2022-11-22 15:09:07 -0800607 onVSyncEvent(123, 456, 789);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800608 expectVsyncEventReceivedByConnection("errorConnection", errorConnectionEventRecorder, 123, 1u);
Ady Abraham011f8ba2022-11-22 15:09:07 -0800609 expectVSyncCallbackScheduleReceived(true);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800610
Huihong Luoab8ffef2022-08-18 13:02:26 -0700611 // A subsequent event will be seen by the connection, which still then returns a non-fatal
612 // error.
Ady Abraham011f8ba2022-11-22 15:09:07 -0800613 onVSyncEvent(456, 123, 0);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800614 expectVsyncEventReceivedByConnection("errorConnection", errorConnectionEventRecorder, 456, 2u);
Ady Abraham011f8ba2022-11-22 15:09:07 -0800615 expectVSyncCallbackScheduleReceived(true);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800616
617 // EventThread will not disable vsync callbacks as the errors are non-fatal.
Ady Abraham011f8ba2022-11-22 15:09:07 -0800618 onVSyncEvent(456, 123, 0);
619 expectVSyncCallbackScheduleReceived(true);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800620}
621
622TEST_F(EventThreadTest, setPhaseOffsetForwardsToVSyncSource) {
Ady Abraham9c53ee72020-07-22 21:16:18 -0700623 mThread->setDuration(321ns, 456ns);
624 expectVSyncSetDurationCallReceived(321ns, 456ns);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800625}
626
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800627TEST_F(EventThreadTest, postHotplugInternalDisconnect) {
628 mThread->onHotplugReceived(INTERNAL_DISPLAY_ID, false);
629 expectHotplugEventReceivedByConnection(INTERNAL_DISPLAY_ID, false);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800630}
631
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800632TEST_F(EventThreadTest, postHotplugInternalConnect) {
633 mThread->onHotplugReceived(INTERNAL_DISPLAY_ID, true);
634 expectHotplugEventReceivedByConnection(INTERNAL_DISPLAY_ID, true);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800635}
636
637TEST_F(EventThreadTest, postHotplugExternalDisconnect) {
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800638 mThread->onHotplugReceived(EXTERNAL_DISPLAY_ID, false);
639 expectHotplugEventReceivedByConnection(EXTERNAL_DISPLAY_ID, false);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800640}
641
642TEST_F(EventThreadTest, postHotplugExternalConnect) {
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800643 mThread->onHotplugReceived(EXTERNAL_DISPLAY_ID, true);
644 expectHotplugEventReceivedByConnection(EXTERNAL_DISPLAY_ID, true);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800645}
646
Ady Abraham447052e2019-02-13 16:07:27 -0800647TEST_F(EventThreadTest, postConfigChangedPrimary) {
Ady Abraham690f4612021-07-01 23:24:03 -0700648 const auto mode = DisplayMode::Builder(hal::HWConfigId(0))
649 .setPhysicalDisplayId(INTERNAL_DISPLAY_ID)
650 .setId(DisplayModeId(7))
651 .setVsyncPeriod(16666666)
652 .build();
Ady Abraham67434eb2022-12-01 17:48:12 -0800653 const Fps fps = mode->getFps() / 2;
Ady Abraham690f4612021-07-01 23:24:03 -0700654
Ady Abraham67434eb2022-12-01 17:48:12 -0800655 mThread->onModeChanged({fps, ftl::as_non_null(mode)});
656 expectConfigChangedEventReceivedByConnection(INTERNAL_DISPLAY_ID, 7, fps.getPeriodNsecs());
Ady Abraham447052e2019-02-13 16:07:27 -0800657}
658
659TEST_F(EventThreadTest, postConfigChangedExternal) {
Ady Abraham690f4612021-07-01 23:24:03 -0700660 const auto mode = DisplayMode::Builder(hal::HWConfigId(0))
661 .setPhysicalDisplayId(EXTERNAL_DISPLAY_ID)
662 .setId(DisplayModeId(5))
663 .setVsyncPeriod(16666666)
664 .build();
Ady Abraham67434eb2022-12-01 17:48:12 -0800665 const Fps fps = mode->getFps() / 2;
Ady Abraham690f4612021-07-01 23:24:03 -0700666
Ady Abraham67434eb2022-12-01 17:48:12 -0800667 mThread->onModeChanged({fps, ftl::as_non_null(mode)});
668 expectConfigChangedEventReceivedByConnection(EXTERNAL_DISPLAY_ID, 5, fps.getPeriodNsecs());
Ady Abraham447052e2019-02-13 16:07:27 -0800669}
670
Ady Abrahamaf0ec272019-03-28 11:38:31 -0700671TEST_F(EventThreadTest, postConfigChangedPrimary64bit) {
Ady Abraham690f4612021-07-01 23:24:03 -0700672 const auto mode = DisplayMode::Builder(hal::HWConfigId(0))
673 .setPhysicalDisplayId(DISPLAY_ID_64BIT)
674 .setId(DisplayModeId(7))
675 .setVsyncPeriod(16666666)
676 .build();
Ady Abraham67434eb2022-12-01 17:48:12 -0800677 const Fps fps = mode->getFps() / 2;
678 mThread->onModeChanged({fps, ftl::as_non_null(mode)});
679 expectConfigChangedEventReceivedByConnection(DISPLAY_ID_64BIT, 7, fps.getPeriodNsecs());
Ady Abrahamaf0ec272019-03-28 11:38:31 -0700680}
681
Ady Abraham0f4a1b12019-06-04 16:04:04 -0700682TEST_F(EventThreadTest, suppressConfigChanged) {
683 ConnectionEventRecorder suppressConnectionEventRecorder{0};
684 sp<MockEventThreadConnection> suppressConnection =
Ady Abraham62f216c2020-10-13 19:07:23 -0700685 createConnection(suppressConnectionEventRecorder);
Ady Abraham0f4a1b12019-06-04 16:04:04 -0700686
Ady Abraham690f4612021-07-01 23:24:03 -0700687 const auto mode = DisplayMode::Builder(hal::HWConfigId(0))
688 .setPhysicalDisplayId(INTERNAL_DISPLAY_ID)
689 .setId(DisplayModeId(9))
690 .setVsyncPeriod(16666666)
691 .build();
Ady Abraham67434eb2022-12-01 17:48:12 -0800692 const Fps fps = mode->getFps() / 2;
Ady Abraham690f4612021-07-01 23:24:03 -0700693
Ady Abraham67434eb2022-12-01 17:48:12 -0800694 mThread->onModeChanged({fps, ftl::as_non_null(mode)});
695 expectConfigChangedEventReceivedByConnection(INTERNAL_DISPLAY_ID, 9, fps.getPeriodNsecs());
Ady Abraham0f4a1b12019-06-04 16:04:04 -0700696
697 auto args = suppressConnectionEventRecorder.waitForCall();
698 ASSERT_FALSE(args.has_value());
699}
700
Ady Abraham62f216c2020-10-13 19:07:23 -0700701TEST_F(EventThreadTest, postUidFrameRateMapping) {
702 const std::vector<FrameRateOverride> overrides = {
703 {.uid = 1, .frameRateHz = 20},
704 {.uid = 3, .frameRateHz = 40},
705 {.uid = 5, .frameRateHz = 60},
706 };
707
708 mThread->onFrameRateOverridesChanged(INTERNAL_DISPLAY_ID, overrides);
709 expectUidFrameRateMappingEventReceivedByConnection(INTERNAL_DISPLAY_ID, overrides);
710}
711
712TEST_F(EventThreadTest, suppressUidFrameRateMapping) {
713 const std::vector<FrameRateOverride> overrides = {
714 {.uid = 1, .frameRateHz = 20},
715 {.uid = 3, .frameRateHz = 40},
716 {.uid = 5, .frameRateHz = 60},
717 };
718
719 ConnectionEventRecorder suppressConnectionEventRecorder{0};
720 sp<MockEventThreadConnection> suppressConnection =
721 createConnection(suppressConnectionEventRecorder);
722
723 mThread->onFrameRateOverridesChanged(INTERNAL_DISPLAY_ID, overrides);
724 expectUidFrameRateMappingEventReceivedByConnection(INTERNAL_DISPLAY_ID, overrides);
725
726 auto args = suppressConnectionEventRecorder.waitForCall();
727 ASSERT_FALSE(args.has_value());
728}
729
Ady Abraham0bb6a472020-10-12 10:22:13 -0700730TEST_F(EventThreadTest, requestNextVsyncWithThrottleVsyncDoesntPostVSync) {
731 // Signal that we want the next vsync event to be posted to the throttled connection
732 mThread->requestNextVsync(mThrottledConnection);
733
734 // EventThread should immediately request a resync.
735 EXPECT_TRUE(mResyncCallRecorder.waitForCall().has_value());
736
737 // EventThread should enable vsync callbacks.
Ady Abraham011f8ba2022-11-22 15:09:07 -0800738 expectVSyncCallbackScheduleReceived(true);
Ady Abraham0bb6a472020-10-12 10:22:13 -0700739
740 // Use the received callback to signal a first vsync event.
Huihong Luoab8ffef2022-08-18 13:02:26 -0700741 // The throttler should receive the event, but not the connection.
Ady Abraham011f8ba2022-11-22 15:09:07 -0800742 onVSyncEvent(123, 456, 789);
Leon Scroggins III31d41412022-11-18 16:42:53 -0500743 expectThrottleVsyncReceived(TimePoint::fromNs(456), mThrottledConnectionUid);
Ady Abraham0bb6a472020-10-12 10:22:13 -0700744 mThrottledConnectionEventCallRecorder.waitForUnexpectedCall();
Ady Abraham011f8ba2022-11-22 15:09:07 -0800745 expectVSyncCallbackScheduleReceived(true);
Ady Abraham0bb6a472020-10-12 10:22:13 -0700746
747 // Use the received callback to signal a second vsync event.
Huihong Luoab8ffef2022-08-18 13:02:26 -0700748 // The throttler should receive the event, but the connection should
Ady Abraham0bb6a472020-10-12 10:22:13 -0700749 // not as it was only interested in the first.
Ady Abraham011f8ba2022-11-22 15:09:07 -0800750 onVSyncEvent(456, 123, 0);
Leon Scroggins III31d41412022-11-18 16:42:53 -0500751 expectThrottleVsyncReceived(TimePoint::fromNs(123), mThrottledConnectionUid);
Ady Abraham0bb6a472020-10-12 10:22:13 -0700752 EXPECT_FALSE(mConnectionEventCallRecorder.waitForUnexpectedCall().has_value());
Ady Abraham011f8ba2022-11-22 15:09:07 -0800753 expectVSyncCallbackScheduleReceived(true);
Ady Abraham0bb6a472020-10-12 10:22:13 -0700754
755 // EventThread should not change the vsync state as it didn't send the event
756 // yet
Ady Abraham011f8ba2022-11-22 15:09:07 -0800757 onVSyncEvent(456, 123, 0);
758 expectVSyncCallbackScheduleReceived(true);
Ady Abraham0bb6a472020-10-12 10:22:13 -0700759}
760
Lloyd Pique24b0a482018-03-09 18:52:26 -0800761} // namespace
762} // namespace android
Marin Shalamanovbed7fd32020-12-21 20:02:20 +0100763
764// TODO(b/129481165): remove the #pragma below and fix conversion issues
765#pragma clang diagnostic pop // ignored "-Wextra"