blob: 3aafd456d9cf88507297c5cd648461da38786f86 [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
17#undef LOG_TAG
18#define LOG_TAG "LibSurfaceFlingerUnittests"
19
20#include <gmock/gmock.h>
21#include <gtest/gtest.h>
Lloyd Pique24b0a482018-03-09 18:52:26 -080022#include <log/log.h>
Lloyd Pique24b0a482018-03-09 18:52:26 -080023#include <utils/Errors.h>
24
25#include "AsyncCallRecorder.h"
Ana Krulecfefcb582018-08-07 14:22:37 -070026#include "Scheduler/EventThread.h"
Ady Abraham2139f732019-11-13 18:56:40 -080027#include "Scheduler/HwcStrongTypes.h"
Lloyd Pique24b0a482018-03-09 18:52:26 -080028
29using namespace std::chrono_literals;
30using namespace std::placeholders;
31
32using testing::_;
33using testing::Invoke;
34
35namespace android {
Ady Abraham2139f732019-11-13 18:56:40 -080036
Lloyd Pique24b0a482018-03-09 18:52:26 -080037namespace {
38
Marin Shalamanova524a092020-07-27 21:39:55 +020039constexpr PhysicalDisplayId INTERNAL_DISPLAY_ID(111);
40constexpr PhysicalDisplayId EXTERNAL_DISPLAY_ID(222);
41constexpr PhysicalDisplayId DISPLAY_ID_64BIT(0xabcd12349876fedcULL);
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -080042
Lloyd Pique24b0a482018-03-09 18:52:26 -080043class MockVSyncSource : public VSyncSource {
44public:
Dominik Laskowski6505f792019-09-18 11:10:05 -070045 const char* getName() const override { return "test"; }
46
Lloyd Pique24b0a482018-03-09 18:52:26 -080047 MOCK_METHOD1(setVSyncEnabled, void(bool));
48 MOCK_METHOD1(setCallback, void(VSyncSource::Callback*));
Ady Abraham9c53ee72020-07-22 21:16:18 -070049 MOCK_METHOD2(setDuration,
50 void(std::chrono::nanoseconds workDuration,
51 std::chrono::nanoseconds readyDuration));
Ady Abrahamb838aed2019-02-12 15:30:16 -080052 MOCK_METHOD1(pauseVsyncCallback, void(bool));
Ady Abraham5e7371c2020-03-24 14:47:24 -070053 MOCK_CONST_METHOD1(dump, void(std::string&));
Lloyd Pique24b0a482018-03-09 18:52:26 -080054};
55
56} // namespace
57
58class EventThreadTest : public testing::Test {
59protected:
Dominik Laskowskif654d572018-12-20 11:03:06 -080060 class MockEventThreadConnection : public EventThreadConnection {
Lloyd Pique24b0a482018-03-09 18:52:26 -080061 public:
Ady Abraham0bb6a472020-10-12 10:22:13 -070062 MockEventThreadConnection(impl::EventThread* eventThread, uid_t callingUid,
63 ResyncCallback&& resyncCallback,
Ady Abraham0f4a1b12019-06-04 16:04:04 -070064 ISurfaceComposer::ConfigChanged configChanged)
Ady Abraham0bb6a472020-10-12 10:22:13 -070065 : EventThreadConnection(eventThread, callingUid, std::move(resyncCallback),
66 configChanged) {}
Lloyd Pique24b0a482018-03-09 18:52:26 -080067 MOCK_METHOD1(postEvent, status_t(const DisplayEventReceiver::Event& event));
68 };
69
70 using ConnectionEventRecorder =
71 AsyncCallRecorderWithCannedReturn<status_t (*)(const DisplayEventReceiver::Event&)>;
72
73 EventThreadTest();
74 ~EventThreadTest() override;
75
Dominik Laskowski6505f792019-09-18 11:10:05 -070076 void createThread(std::unique_ptr<VSyncSource>);
Ady Abraham0f4a1b12019-06-04 16:04:04 -070077 sp<MockEventThreadConnection> createConnection(ConnectionEventRecorder& recorder,
Ady Abraham0bb6a472020-10-12 10:22:13 -070078 ISurfaceComposer::ConfigChanged configChanged,
79 uid_t ownerUid = mConnectionUid);
Lloyd Pique24b0a482018-03-09 18:52:26 -080080
81 void expectVSyncSetEnabledCallReceived(bool expectedState);
Ady Abraham9c53ee72020-07-22 21:16:18 -070082 void expectVSyncSetDurationCallReceived(std::chrono::nanoseconds expectedDuration,
83 std::chrono::nanoseconds expectedReadyDuration);
Lloyd Pique24b0a482018-03-09 18:52:26 -080084 VSyncSource::Callback* expectVSyncSetCallbackCallReceived();
85 void expectInterceptCallReceived(nsecs_t expectedTimestamp);
86 void expectVsyncEventReceivedByConnection(const char* name,
87 ConnectionEventRecorder& connectionEventRecorder,
88 nsecs_t expectedTimestamp, unsigned expectedCount);
89 void expectVsyncEventReceivedByConnection(nsecs_t expectedTimestamp, unsigned expectedCount);
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -080090 void expectHotplugEventReceivedByConnection(PhysicalDisplayId expectedDisplayId,
Dominik Laskowski00a6fa22018-06-06 16:42:02 -070091 bool expectedConnected);
Ady Abraham447052e2019-02-13 16:07:27 -080092 void expectConfigChangedEventReceivedByConnection(PhysicalDisplayId expectedDisplayId,
Alec Mouri60aee1c2019-10-28 16:18:59 -070093 int32_t expectedConfigId,
94 nsecs_t expectedVsyncPeriod);
Ady Abraham0bb6a472020-10-12 10:22:13 -070095 void expectThrottleVsyncReceived(nsecs_t expectedTimestamp, uid_t);
Lloyd Pique24b0a482018-03-09 18:52:26 -080096
97 AsyncCallRecorder<void (*)(bool)> mVSyncSetEnabledCallRecorder;
98 AsyncCallRecorder<void (*)(VSyncSource::Callback*)> mVSyncSetCallbackCallRecorder;
Ady Abraham9c53ee72020-07-22 21:16:18 -070099 AsyncCallRecorder<void (*)(std::chrono::nanoseconds, std::chrono::nanoseconds)>
100 mVSyncSetDurationCallRecorder;
Lloyd Pique24b0a482018-03-09 18:52:26 -0800101 AsyncCallRecorder<void (*)()> mResyncCallRecorder;
102 AsyncCallRecorder<void (*)(nsecs_t)> mInterceptVSyncCallRecorder;
Ady Abraham0bb6a472020-10-12 10:22:13 -0700103 AsyncCallRecorder<void (*)(nsecs_t, uid_t)> mThrottleVsyncCallRecorder;
Lloyd Pique24b0a482018-03-09 18:52:26 -0800104 ConnectionEventRecorder mConnectionEventCallRecorder{0};
Ady Abraham0bb6a472020-10-12 10:22:13 -0700105 ConnectionEventRecorder mThrottledConnectionEventCallRecorder{0};
Lloyd Pique24b0a482018-03-09 18:52:26 -0800106
Dominik Laskowski6505f792019-09-18 11:10:05 -0700107 MockVSyncSource* mVSyncSource;
Dominik Laskowski029cc122019-01-23 19:52:06 -0800108 VSyncSource::Callback* mCallback = nullptr;
Dominik Laskowski6505f792019-09-18 11:10:05 -0700109 std::unique_ptr<impl::EventThread> mThread;
Lloyd Pique24b0a482018-03-09 18:52:26 -0800110 sp<MockEventThreadConnection> mConnection;
Ady Abraham0bb6a472020-10-12 10:22:13 -0700111 sp<MockEventThreadConnection> mThrottledConnection;
112
113 static constexpr uid_t mConnectionUid = 443;
114 static constexpr uid_t mThrottledConnectionUid = 177;
Lloyd Pique24b0a482018-03-09 18:52:26 -0800115};
116
117EventThreadTest::EventThreadTest() {
118 const ::testing::TestInfo* const test_info =
119 ::testing::UnitTest::GetInstance()->current_test_info();
120 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
121
Dominik Laskowski6505f792019-09-18 11:10:05 -0700122 auto vsyncSource = std::make_unique<MockVSyncSource>();
123 mVSyncSource = vsyncSource.get();
124
125 EXPECT_CALL(*mVSyncSource, setVSyncEnabled(_))
Lloyd Pique24b0a482018-03-09 18:52:26 -0800126 .WillRepeatedly(Invoke(mVSyncSetEnabledCallRecorder.getInvocable()));
127
Dominik Laskowski6505f792019-09-18 11:10:05 -0700128 EXPECT_CALL(*mVSyncSource, setCallback(_))
Lloyd Pique24b0a482018-03-09 18:52:26 -0800129 .WillRepeatedly(Invoke(mVSyncSetCallbackCallRecorder.getInvocable()));
130
Ady Abraham9c53ee72020-07-22 21:16:18 -0700131 EXPECT_CALL(*mVSyncSource, setDuration(_, _))
132 .WillRepeatedly(Invoke(mVSyncSetDurationCallRecorder.getInvocable()));
Lloyd Pique24b0a482018-03-09 18:52:26 -0800133
Dominik Laskowski6505f792019-09-18 11:10:05 -0700134 createThread(std::move(vsyncSource));
Ady Abraham0f4a1b12019-06-04 16:04:04 -0700135 mConnection = createConnection(mConnectionEventCallRecorder,
136 ISurfaceComposer::eConfigChangedDispatch);
Ady Abraham0bb6a472020-10-12 10:22:13 -0700137 mThrottledConnection =
138 createConnection(mThrottledConnectionEventCallRecorder,
139 ISurfaceComposer::eConfigChangedDispatch, mThrottledConnectionUid);
Dominik Laskowski1eba0202019-01-24 09:14:40 -0800140
141 // A display must be connected for VSYNC events to be delivered.
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800142 mThread->onHotplugReceived(INTERNAL_DISPLAY_ID, true);
143 expectHotplugEventReceivedByConnection(INTERNAL_DISPLAY_ID, true);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800144}
145
146EventThreadTest::~EventThreadTest() {
147 const ::testing::TestInfo* const test_info =
148 ::testing::UnitTest::GetInstance()->current_test_info();
149 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
Dominik Laskowski029cc122019-01-23 19:52:06 -0800150
151 // EventThread should unregister itself as VSyncSource callback.
Lloyd Pique0655b8e2019-01-31 18:20:27 -0800152 EXPECT_TRUE(!mVSyncSetCallbackCallRecorder.waitForUnexpectedCall().has_value());
Lloyd Pique24b0a482018-03-09 18:52:26 -0800153}
154
Dominik Laskowski6505f792019-09-18 11:10:05 -0700155void EventThreadTest::createThread(std::unique_ptr<VSyncSource> source) {
Ady Abraham0bb6a472020-10-12 10:22:13 -0700156 const auto throttleVsync = [&](nsecs_t expectedVsyncTimestamp, uid_t uid) {
157 mThrottleVsyncCallRecorder.getInvocable()(expectedVsyncTimestamp, uid);
158 return (uid == mThrottledConnectionUid);
159 };
160
Dominik Laskowski6505f792019-09-18 11:10:05 -0700161 mThread = std::make_unique<impl::EventThread>(std::move(source),
Adithya Srinivasan5f683cf2020-09-15 14:21:04 -0700162 /*tokenManager=*/nullptr,
Ady Abraham0bb6a472020-10-12 10:22:13 -0700163 mInterceptVSyncCallRecorder.getInvocable(),
164 throttleVsync);
Dominik Laskowski029cc122019-01-23 19:52:06 -0800165
166 // EventThread should register itself as VSyncSource callback.
167 mCallback = expectVSyncSetCallbackCallReceived();
168 ASSERT_TRUE(mCallback);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800169}
170
171sp<EventThreadTest::MockEventThreadConnection> EventThreadTest::createConnection(
Ady Abraham0bb6a472020-10-12 10:22:13 -0700172 ConnectionEventRecorder& recorder, ISurfaceComposer::ConfigChanged configChanged,
173 uid_t ownerUid) {
Dominik Laskowskif654d572018-12-20 11:03:06 -0800174 sp<MockEventThreadConnection> connection =
Ady Abraham0bb6a472020-10-12 10:22:13 -0700175 new MockEventThreadConnection(mThread.get(), ownerUid,
176 mResyncCallRecorder.getInvocable(), configChanged);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800177 EXPECT_CALL(*connection, postEvent(_)).WillRepeatedly(Invoke(recorder.getInvocable()));
178 return connection;
179}
180
181void EventThreadTest::expectVSyncSetEnabledCallReceived(bool expectedState) {
182 auto args = mVSyncSetEnabledCallRecorder.waitForCall();
183 ASSERT_TRUE(args.has_value());
184 EXPECT_EQ(expectedState, std::get<0>(args.value()));
185}
186
Ady Abraham9c53ee72020-07-22 21:16:18 -0700187void EventThreadTest::expectVSyncSetDurationCallReceived(
188 std::chrono::nanoseconds expectedDuration, std::chrono::nanoseconds expectedReadyDuration) {
189 auto args = mVSyncSetDurationCallRecorder.waitForCall();
Lloyd Pique24b0a482018-03-09 18:52:26 -0800190 ASSERT_TRUE(args.has_value());
Ady Abraham9c53ee72020-07-22 21:16:18 -0700191 EXPECT_EQ(expectedDuration, std::get<0>(args.value()));
192 EXPECT_EQ(expectedReadyDuration, std::get<1>(args.value()));
Lloyd Pique24b0a482018-03-09 18:52:26 -0800193}
194
195VSyncSource::Callback* EventThreadTest::expectVSyncSetCallbackCallReceived() {
196 auto callbackSet = mVSyncSetCallbackCallRecorder.waitForCall();
197 return callbackSet.has_value() ? std::get<0>(callbackSet.value()) : nullptr;
198}
199
200void EventThreadTest::expectInterceptCallReceived(nsecs_t expectedTimestamp) {
201 auto args = mInterceptVSyncCallRecorder.waitForCall();
202 ASSERT_TRUE(args.has_value());
203 EXPECT_EQ(expectedTimestamp, std::get<0>(args.value()));
204}
205
Ady Abraham0bb6a472020-10-12 10:22:13 -0700206void EventThreadTest::expectThrottleVsyncReceived(nsecs_t expectedTimestamp, uid_t uid) {
207 auto args = mThrottleVsyncCallRecorder.waitForCall();
208 ASSERT_TRUE(args.has_value());
209 EXPECT_EQ(expectedTimestamp, std::get<0>(args.value()));
210 EXPECT_EQ(uid, std::get<1>(args.value()));
211}
212
Lloyd Pique24b0a482018-03-09 18:52:26 -0800213void EventThreadTest::expectVsyncEventReceivedByConnection(
214 const char* name, ConnectionEventRecorder& connectionEventRecorder,
215 nsecs_t expectedTimestamp, unsigned expectedCount) {
216 auto args = connectionEventRecorder.waitForCall();
217 ASSERT_TRUE(args.has_value()) << name << " did not receive an event for timestamp "
218 << expectedTimestamp;
219 const auto& event = std::get<0>(args.value());
220 EXPECT_EQ(DisplayEventReceiver::DISPLAY_EVENT_VSYNC, event.header.type)
221 << name << " did not get the correct event for timestamp " << expectedTimestamp;
222 EXPECT_EQ(expectedTimestamp, event.header.timestamp)
223 << name << " did not get the expected timestamp for timestamp " << expectedTimestamp;
224 EXPECT_EQ(expectedCount, event.vsync.count)
225 << name << " did not get the expected count for timestamp " << expectedTimestamp;
226}
227
228void EventThreadTest::expectVsyncEventReceivedByConnection(nsecs_t expectedTimestamp,
229 unsigned expectedCount) {
230 expectVsyncEventReceivedByConnection("mConnectionEventCallRecorder",
231 mConnectionEventCallRecorder, expectedTimestamp,
232 expectedCount);
233}
234
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800235void EventThreadTest::expectHotplugEventReceivedByConnection(PhysicalDisplayId expectedDisplayId,
236 bool expectedConnected) {
Lloyd Pique24b0a482018-03-09 18:52:26 -0800237 auto args = mConnectionEventCallRecorder.waitForCall();
238 ASSERT_TRUE(args.has_value());
239 const auto& event = std::get<0>(args.value());
240 EXPECT_EQ(DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG, event.header.type);
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800241 EXPECT_EQ(expectedDisplayId, event.header.displayId);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800242 EXPECT_EQ(expectedConnected, event.hotplug.connected);
243}
244
Ady Abraham447052e2019-02-13 16:07:27 -0800245void EventThreadTest::expectConfigChangedEventReceivedByConnection(
Alec Mouri60aee1c2019-10-28 16:18:59 -0700246 PhysicalDisplayId expectedDisplayId, int32_t expectedConfigId,
247 nsecs_t expectedVsyncPeriod) {
Ady Abraham447052e2019-02-13 16:07:27 -0800248 auto args = mConnectionEventCallRecorder.waitForCall();
249 ASSERT_TRUE(args.has_value());
250 const auto& event = std::get<0>(args.value());
251 EXPECT_EQ(DisplayEventReceiver::DISPLAY_EVENT_CONFIG_CHANGED, event.header.type);
252 EXPECT_EQ(expectedDisplayId, event.header.displayId);
253 EXPECT_EQ(expectedConfigId, event.config.configId);
Alec Mouri60aee1c2019-10-28 16:18:59 -0700254 EXPECT_EQ(expectedVsyncPeriod, event.config.vsyncPeriod);
Ady Abraham447052e2019-02-13 16:07:27 -0800255}
256
Lloyd Pique24b0a482018-03-09 18:52:26 -0800257namespace {
258
259/* ------------------------------------------------------------------------
260 * Test cases
261 */
262
263TEST_F(EventThreadTest, canCreateAndDestroyThreadWithNoEventsSent) {
264 EXPECT_FALSE(mVSyncSetEnabledCallRecorder.waitForUnexpectedCall().has_value());
265 EXPECT_FALSE(mVSyncSetCallbackCallRecorder.waitForCall(0us).has_value());
Ady Abraham9c53ee72020-07-22 21:16:18 -0700266 EXPECT_FALSE(mVSyncSetDurationCallRecorder.waitForCall(0us).has_value());
Lloyd Pique24b0a482018-03-09 18:52:26 -0800267 EXPECT_FALSE(mResyncCallRecorder.waitForCall(0us).has_value());
268 EXPECT_FALSE(mInterceptVSyncCallRecorder.waitForCall(0us).has_value());
269 EXPECT_FALSE(mConnectionEventCallRecorder.waitForCall(0us).has_value());
270}
271
Dominik Laskowski1eba0202019-01-24 09:14:40 -0800272TEST_F(EventThreadTest, vsyncRequestIsIgnoredIfDisplayIsDisconnected) {
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800273 mThread->onHotplugReceived(INTERNAL_DISPLAY_ID, false);
274 expectHotplugEventReceivedByConnection(INTERNAL_DISPLAY_ID, false);
Dominik Laskowski1eba0202019-01-24 09:14:40 -0800275
276 // Signal that we want the next vsync event to be posted to the connection.
Ady Abraham8532d012019-05-08 14:50:56 -0700277 mThread->requestNextVsync(mConnection);
Dominik Laskowski1eba0202019-01-24 09:14:40 -0800278
279 // EventThread should not enable vsync callbacks.
280 EXPECT_FALSE(mVSyncSetEnabledCallRecorder.waitForUnexpectedCall().has_value());
Dominik Laskowski1eba0202019-01-24 09:14:40 -0800281}
282
Lloyd Pique24b0a482018-03-09 18:52:26 -0800283TEST_F(EventThreadTest, requestNextVsyncPostsASingleVSyncEventToTheConnection) {
284 // Signal that we want the next vsync event to be posted to the connection
Ady Abraham8532d012019-05-08 14:50:56 -0700285 mThread->requestNextVsync(mConnection);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800286
Ady Abraham8532d012019-05-08 14:50:56 -0700287 // EventThread should immediately request a resync.
Lloyd Pique24b0a482018-03-09 18:52:26 -0800288 EXPECT_TRUE(mResyncCallRecorder.waitForCall().has_value());
289
Dominik Laskowski029cc122019-01-23 19:52:06 -0800290 // EventThread should enable vsync callbacks.
Lloyd Pique24b0a482018-03-09 18:52:26 -0800291 expectVSyncSetEnabledCallReceived(true);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800292
293 // Use the received callback to signal a first vsync event.
294 // The interceptor should receive the event, as well as the connection.
Ady Abraham9c53ee72020-07-22 21:16:18 -0700295 mCallback->onVSyncEvent(123, 456, 789);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800296 expectInterceptCallReceived(123);
Ady Abraham0bb6a472020-10-12 10:22:13 -0700297 expectThrottleVsyncReceived(456, mConnectionUid);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800298 expectVsyncEventReceivedByConnection(123, 1u);
299
300 // Use the received callback to signal a second vsync event.
Ady Abraham0bb6a472020-10-12 10:22:13 -0700301 // The interceptor should receive the event, but the connection should
Lloyd Pique24b0a482018-03-09 18:52:26 -0800302 // not as it was only interested in the first.
Ady Abraham9c53ee72020-07-22 21:16:18 -0700303 mCallback->onVSyncEvent(456, 123, 0);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800304 expectInterceptCallReceived(456);
Ady Abraham0bb6a472020-10-12 10:22:13 -0700305 EXPECT_FALSE(mThrottleVsyncCallRecorder.waitForUnexpectedCall().has_value());
Lloyd Pique24b0a482018-03-09 18:52:26 -0800306 EXPECT_FALSE(mConnectionEventCallRecorder.waitForUnexpectedCall().has_value());
307
308 // EventThread should also detect that at this point that it does not need
309 // any more vsync events, and should disable their generation.
310 expectVSyncSetEnabledCallReceived(false);
311}
312
313TEST_F(EventThreadTest, setVsyncRateZeroPostsNoVSyncEventsToThatConnection) {
314 // Create a first connection, register it, and request a vsync rate of zero.
315 ConnectionEventRecorder firstConnectionEventRecorder{0};
Ady Abraham0f4a1b12019-06-04 16:04:04 -0700316 sp<MockEventThreadConnection> firstConnection =
317 createConnection(firstConnectionEventRecorder,
318 ISurfaceComposer::eConfigChangedSuppress);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800319 mThread->setVsyncRate(0, firstConnection);
320
321 // By itself, this should not enable vsync events
322 EXPECT_FALSE(mVSyncSetEnabledCallRecorder.waitForUnexpectedCall().has_value());
323 EXPECT_FALSE(mVSyncSetCallbackCallRecorder.waitForCall(0us).has_value());
324
325 // However if there is another connection which wants events at a nonzero rate.....
326 ConnectionEventRecorder secondConnectionEventRecorder{0};
327 sp<MockEventThreadConnection> secondConnection =
Ady Abraham0f4a1b12019-06-04 16:04:04 -0700328 createConnection(secondConnectionEventRecorder,
329 ISurfaceComposer::eConfigChangedSuppress);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800330 mThread->setVsyncRate(1, secondConnection);
331
Dominik Laskowski029cc122019-01-23 19:52:06 -0800332 // EventThread should enable vsync callbacks.
Lloyd Pique24b0a482018-03-09 18:52:26 -0800333 expectVSyncSetEnabledCallReceived(true);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800334
335 // Send a vsync event. EventThread should then make a call to the
336 // interceptor, and the second connection. The first connection should not
337 // get the event.
Ady Abraham9c53ee72020-07-22 21:16:18 -0700338 mCallback->onVSyncEvent(123, 456, 0);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800339 expectInterceptCallReceived(123);
340 EXPECT_FALSE(firstConnectionEventRecorder.waitForUnexpectedCall().has_value());
341 expectVsyncEventReceivedByConnection("secondConnection", secondConnectionEventRecorder, 123,
342 1u);
343}
344
345TEST_F(EventThreadTest, setVsyncRateOnePostsAllEventsToThatConnection) {
346 mThread->setVsyncRate(1, mConnection);
347
Dominik Laskowski029cc122019-01-23 19:52:06 -0800348 // EventThread should enable vsync callbacks.
Lloyd Pique24b0a482018-03-09 18:52:26 -0800349 expectVSyncSetEnabledCallReceived(true);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800350
351 // Send a vsync event. EventThread should then make a call to the
352 // interceptor, and the connection.
Ady Abraham9c53ee72020-07-22 21:16:18 -0700353 mCallback->onVSyncEvent(123, 456, 789);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800354 expectInterceptCallReceived(123);
Ady Abraham0bb6a472020-10-12 10:22:13 -0700355 expectThrottleVsyncReceived(456, mConnectionUid);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800356 expectVsyncEventReceivedByConnection(123, 1u);
357
358 // A second event should go to the same places.
Ady Abraham9c53ee72020-07-22 21:16:18 -0700359 mCallback->onVSyncEvent(456, 123, 0);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800360 expectInterceptCallReceived(456);
Ady Abraham0bb6a472020-10-12 10:22:13 -0700361 expectThrottleVsyncReceived(123, mConnectionUid);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800362 expectVsyncEventReceivedByConnection(456, 2u);
363
364 // A third event should go to the same places.
Ady Abraham9c53ee72020-07-22 21:16:18 -0700365 mCallback->onVSyncEvent(789, 777, 111);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800366 expectInterceptCallReceived(789);
Ady Abraham0bb6a472020-10-12 10:22:13 -0700367 expectThrottleVsyncReceived(777, mConnectionUid);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800368 expectVsyncEventReceivedByConnection(789, 3u);
369}
370
371TEST_F(EventThreadTest, setVsyncRateTwoPostsEveryOtherEventToThatConnection) {
372 mThread->setVsyncRate(2, mConnection);
373
Dominik Laskowski029cc122019-01-23 19:52:06 -0800374 // EventThread should enable vsync callbacks.
Lloyd Pique24b0a482018-03-09 18:52:26 -0800375 expectVSyncSetEnabledCallReceived(true);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800376
377 // The first event will be seen by the interceptor, and not the connection.
Ady Abraham9c53ee72020-07-22 21:16:18 -0700378 mCallback->onVSyncEvent(123, 456, 789);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800379 expectInterceptCallReceived(123);
380 EXPECT_FALSE(mConnectionEventCallRecorder.waitForUnexpectedCall().has_value());
Ady Abraham0bb6a472020-10-12 10:22:13 -0700381 EXPECT_FALSE(mThrottleVsyncCallRecorder.waitForUnexpectedCall().has_value());
Lloyd Pique24b0a482018-03-09 18:52:26 -0800382
383 // The second event will be seen by the interceptor and the connection.
Ady Abraham9c53ee72020-07-22 21:16:18 -0700384 mCallback->onVSyncEvent(456, 123, 0);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800385 expectInterceptCallReceived(456);
386 expectVsyncEventReceivedByConnection(456, 2u);
Ady Abraham0bb6a472020-10-12 10:22:13 -0700387 EXPECT_FALSE(mThrottleVsyncCallRecorder.waitForUnexpectedCall().has_value());
Lloyd Pique24b0a482018-03-09 18:52:26 -0800388
389 // The third event will be seen by the interceptor, and not the connection.
Ady Abraham9c53ee72020-07-22 21:16:18 -0700390 mCallback->onVSyncEvent(789, 777, 744);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800391 expectInterceptCallReceived(789);
392 EXPECT_FALSE(mConnectionEventCallRecorder.waitForUnexpectedCall().has_value());
Ady Abraham0bb6a472020-10-12 10:22:13 -0700393 EXPECT_FALSE(mThrottleVsyncCallRecorder.waitForUnexpectedCall().has_value());
Lloyd Pique24b0a482018-03-09 18:52:26 -0800394
395 // The fourth event will be seen by the interceptor and the connection.
Ady Abraham9c53ee72020-07-22 21:16:18 -0700396 mCallback->onVSyncEvent(101112, 7847, 86);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800397 expectInterceptCallReceived(101112);
398 expectVsyncEventReceivedByConnection(101112, 4u);
399}
400
401TEST_F(EventThreadTest, connectionsRemovedIfInstanceDestroyed) {
402 mThread->setVsyncRate(1, mConnection);
403
Dominik Laskowski029cc122019-01-23 19:52:06 -0800404 // EventThread should enable vsync callbacks.
Lloyd Pique24b0a482018-03-09 18:52:26 -0800405 expectVSyncSetEnabledCallReceived(true);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800406
407 // Destroy the only (strong) reference to the connection.
408 mConnection = nullptr;
409
410 // The first event will be seen by the interceptor, and not the connection.
Ady Abraham9c53ee72020-07-22 21:16:18 -0700411 mCallback->onVSyncEvent(123, 456, 789);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800412 expectInterceptCallReceived(123);
413 EXPECT_FALSE(mConnectionEventCallRecorder.waitForUnexpectedCall().has_value());
414
415 // EventThread should disable vsync callbacks
416 expectVSyncSetEnabledCallReceived(false);
417}
418
419TEST_F(EventThreadTest, connectionsRemovedIfEventDeliveryError) {
420 ConnectionEventRecorder errorConnectionEventRecorder{NO_MEMORY};
Ady Abraham0f4a1b12019-06-04 16:04:04 -0700421 sp<MockEventThreadConnection> errorConnection =
422 createConnection(errorConnectionEventRecorder,
423 ISurfaceComposer::eConfigChangedSuppress);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800424 mThread->setVsyncRate(1, errorConnection);
425
Dominik Laskowski029cc122019-01-23 19:52:06 -0800426 // EventThread should enable vsync callbacks.
Lloyd Pique24b0a482018-03-09 18:52:26 -0800427 expectVSyncSetEnabledCallReceived(true);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800428
429 // The first event will be seen by the interceptor, and by the connection,
430 // which then returns an error.
Ady Abraham9c53ee72020-07-22 21:16:18 -0700431 mCallback->onVSyncEvent(123, 456, 789);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800432 expectInterceptCallReceived(123);
433 expectVsyncEventReceivedByConnection("errorConnection", errorConnectionEventRecorder, 123, 1u);
434
435 // A subsequent event will be seen by the interceptor and not by the
436 // connection.
Ady Abraham9c53ee72020-07-22 21:16:18 -0700437 mCallback->onVSyncEvent(456, 123, 0);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800438 expectInterceptCallReceived(456);
439 EXPECT_FALSE(errorConnectionEventRecorder.waitForUnexpectedCall().has_value());
440
441 // EventThread should disable vsync callbacks with the second event
442 expectVSyncSetEnabledCallReceived(false);
443}
444
Alec Mouri717bcb62020-02-10 17:07:19 -0800445TEST_F(EventThreadTest, tracksEventConnections) {
Ady Abraham0bb6a472020-10-12 10:22:13 -0700446 EXPECT_EQ(2, mThread->getEventThreadConnectionCount());
Alec Mouri717bcb62020-02-10 17:07:19 -0800447 ConnectionEventRecorder errorConnectionEventRecorder{NO_MEMORY};
448 sp<MockEventThreadConnection> errorConnection =
449 createConnection(errorConnectionEventRecorder,
450 ISurfaceComposer::eConfigChangedSuppress);
451 mThread->setVsyncRate(1, errorConnection);
Ady Abraham0bb6a472020-10-12 10:22:13 -0700452 EXPECT_EQ(3, mThread->getEventThreadConnectionCount());
Alec Mouri717bcb62020-02-10 17:07:19 -0800453 ConnectionEventRecorder secondConnectionEventRecorder{0};
454 sp<MockEventThreadConnection> secondConnection =
455 createConnection(secondConnectionEventRecorder,
456 ISurfaceComposer::eConfigChangedSuppress);
457 mThread->setVsyncRate(1, secondConnection);
Ady Abraham0bb6a472020-10-12 10:22:13 -0700458 EXPECT_EQ(4, mThread->getEventThreadConnectionCount());
Alec Mouri717bcb62020-02-10 17:07:19 -0800459
460 // EventThread should enable vsync callbacks.
461 expectVSyncSetEnabledCallReceived(true);
462
463 // The first event will be seen by the interceptor, and by the connection,
464 // which then returns an error.
Ady Abraham9c53ee72020-07-22 21:16:18 -0700465 mCallback->onVSyncEvent(123, 456, 789);
Alec Mouri717bcb62020-02-10 17:07:19 -0800466 expectInterceptCallReceived(123);
467 expectVsyncEventReceivedByConnection("errorConnection", errorConnectionEventRecorder, 123, 1u);
468 expectVsyncEventReceivedByConnection("successConnection", secondConnectionEventRecorder, 123,
469 1u);
Ady Abraham0bb6a472020-10-12 10:22:13 -0700470 EXPECT_EQ(3, mThread->getEventThreadConnectionCount());
Alec Mouri717bcb62020-02-10 17:07:19 -0800471}
472
Lloyd Pique24b0a482018-03-09 18:52:26 -0800473TEST_F(EventThreadTest, eventsDroppedIfNonfatalEventDeliveryError) {
474 ConnectionEventRecorder errorConnectionEventRecorder{WOULD_BLOCK};
Ady Abraham0f4a1b12019-06-04 16:04:04 -0700475 sp<MockEventThreadConnection> errorConnection =
476 createConnection(errorConnectionEventRecorder,
477 ISurfaceComposer::eConfigChangedSuppress);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800478 mThread->setVsyncRate(1, errorConnection);
479
Dominik Laskowski029cc122019-01-23 19:52:06 -0800480 // EventThread should enable vsync callbacks.
Lloyd Pique24b0a482018-03-09 18:52:26 -0800481 expectVSyncSetEnabledCallReceived(true);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800482
483 // The first event will be seen by the interceptor, and by the connection,
484 // which then returns an non-fatal error.
Ady Abraham9c53ee72020-07-22 21:16:18 -0700485 mCallback->onVSyncEvent(123, 456, 789);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800486 expectInterceptCallReceived(123);
487 expectVsyncEventReceivedByConnection("errorConnection", errorConnectionEventRecorder, 123, 1u);
488
489 // A subsequent event will be seen by the interceptor, and by the connection,
490 // which still then returns an non-fatal error.
Ady Abraham9c53ee72020-07-22 21:16:18 -0700491 mCallback->onVSyncEvent(456, 123, 0);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800492 expectInterceptCallReceived(456);
493 expectVsyncEventReceivedByConnection("errorConnection", errorConnectionEventRecorder, 456, 2u);
494
495 // EventThread will not disable vsync callbacks as the errors are non-fatal.
496 EXPECT_FALSE(mVSyncSetEnabledCallRecorder.waitForUnexpectedCall().has_value());
497}
498
499TEST_F(EventThreadTest, setPhaseOffsetForwardsToVSyncSource) {
Ady Abraham9c53ee72020-07-22 21:16:18 -0700500 mThread->setDuration(321ns, 456ns);
501 expectVSyncSetDurationCallReceived(321ns, 456ns);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800502}
503
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800504TEST_F(EventThreadTest, postHotplugInternalDisconnect) {
505 mThread->onHotplugReceived(INTERNAL_DISPLAY_ID, false);
506 expectHotplugEventReceivedByConnection(INTERNAL_DISPLAY_ID, false);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800507}
508
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800509TEST_F(EventThreadTest, postHotplugInternalConnect) {
510 mThread->onHotplugReceived(INTERNAL_DISPLAY_ID, true);
511 expectHotplugEventReceivedByConnection(INTERNAL_DISPLAY_ID, true);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800512}
513
514TEST_F(EventThreadTest, postHotplugExternalDisconnect) {
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800515 mThread->onHotplugReceived(EXTERNAL_DISPLAY_ID, false);
516 expectHotplugEventReceivedByConnection(EXTERNAL_DISPLAY_ID, false);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800517}
518
519TEST_F(EventThreadTest, postHotplugExternalConnect) {
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800520 mThread->onHotplugReceived(EXTERNAL_DISPLAY_ID, true);
521 expectHotplugEventReceivedByConnection(EXTERNAL_DISPLAY_ID, true);
Lloyd Pique24b0a482018-03-09 18:52:26 -0800522}
523
Ady Abraham447052e2019-02-13 16:07:27 -0800524TEST_F(EventThreadTest, postConfigChangedPrimary) {
Alec Mouri60aee1c2019-10-28 16:18:59 -0700525 mThread->onConfigChanged(INTERNAL_DISPLAY_ID, HwcConfigIndexType(7), 16666666);
526 expectConfigChangedEventReceivedByConnection(INTERNAL_DISPLAY_ID, 7, 16666666);
Ady Abraham447052e2019-02-13 16:07:27 -0800527}
528
529TEST_F(EventThreadTest, postConfigChangedExternal) {
Alec Mouri60aee1c2019-10-28 16:18:59 -0700530 mThread->onConfigChanged(EXTERNAL_DISPLAY_ID, HwcConfigIndexType(5), 16666666);
531 expectConfigChangedEventReceivedByConnection(EXTERNAL_DISPLAY_ID, 5, 16666666);
Ady Abraham447052e2019-02-13 16:07:27 -0800532}
533
Ady Abrahamaf0ec272019-03-28 11:38:31 -0700534TEST_F(EventThreadTest, postConfigChangedPrimary64bit) {
Alec Mouri60aee1c2019-10-28 16:18:59 -0700535 mThread->onConfigChanged(DISPLAY_ID_64BIT, HwcConfigIndexType(7), 16666666);
536 expectConfigChangedEventReceivedByConnection(DISPLAY_ID_64BIT, 7, 16666666);
Ady Abrahamaf0ec272019-03-28 11:38:31 -0700537}
538
Ady Abraham0f4a1b12019-06-04 16:04:04 -0700539TEST_F(EventThreadTest, suppressConfigChanged) {
540 ConnectionEventRecorder suppressConnectionEventRecorder{0};
541 sp<MockEventThreadConnection> suppressConnection =
542 createConnection(suppressConnectionEventRecorder,
543 ISurfaceComposer::eConfigChangedSuppress);
544
Alec Mouri60aee1c2019-10-28 16:18:59 -0700545 mThread->onConfigChanged(INTERNAL_DISPLAY_ID, HwcConfigIndexType(9), 16666666);
546 expectConfigChangedEventReceivedByConnection(INTERNAL_DISPLAY_ID, 9, 16666666);
Ady Abraham0f4a1b12019-06-04 16:04:04 -0700547
548 auto args = suppressConnectionEventRecorder.waitForCall();
549 ASSERT_FALSE(args.has_value());
550}
551
Ady Abraham0bb6a472020-10-12 10:22:13 -0700552TEST_F(EventThreadTest, requestNextVsyncWithThrottleVsyncDoesntPostVSync) {
553 // Signal that we want the next vsync event to be posted to the throttled connection
554 mThread->requestNextVsync(mThrottledConnection);
555
556 // EventThread should immediately request a resync.
557 EXPECT_TRUE(mResyncCallRecorder.waitForCall().has_value());
558
559 // EventThread should enable vsync callbacks.
560 expectVSyncSetEnabledCallReceived(true);
561
562 // Use the received callback to signal a first vsync event.
563 // The interceptor should receive the event, but not the connection.
564 mCallback->onVSyncEvent(123, 456, 789);
565 expectInterceptCallReceived(123);
566 expectThrottleVsyncReceived(456, mThrottledConnectionUid);
567 mThrottledConnectionEventCallRecorder.waitForUnexpectedCall();
568
569 // Use the received callback to signal a second vsync event.
570 // The interceptor should receive the event, but the connection should
571 // not as it was only interested in the first.
572 mCallback->onVSyncEvent(456, 123, 0);
573 expectInterceptCallReceived(456);
574 expectThrottleVsyncReceived(123, mThrottledConnectionUid);
575 EXPECT_FALSE(mConnectionEventCallRecorder.waitForUnexpectedCall().has_value());
576
577 // EventThread should not change the vsync state as it didn't send the event
578 // yet
579 EXPECT_FALSE(mVSyncSetEnabledCallRecorder.waitForUnexpectedCall().has_value());
580}
581
Lloyd Pique24b0a482018-03-09 18:52:26 -0800582} // namespace
583} // namespace android