blob: e936ee0b2968a6af4f0934298882df4b3ab8e748 [file] [log] [blame]
Valerie Haud251afb2019-03-29 14:19:02 -07001/*
2 * Copyright 2019 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 "CompositionTest"
19
20#include <compositionengine/Display.h>
21#include <compositionengine/mock/DisplaySurface.h>
22#include <gmock/gmock.h>
23#include <gtest/gtest.h>
Vishnu Nair59f6d2d2022-10-05 16:59:56 -070024#include <gui/LayerState.h>
Valerie Haud251afb2019-03-29 14:19:02 -070025#include <gui/SurfaceComposerClient.h>
Vishnu Nair59f6d2d2022-10-05 16:59:56 -070026#include <gui/fake/BufferData.h>
Valerie Haud251afb2019-03-29 14:19:02 -070027#include <log/log.h>
ramindani4d48f902021-09-20 21:07:45 +000028#include <ui/MockFence.h>
Valerie Haud251afb2019-03-29 14:19:02 -070029#include <utils/String8.h>
Vishnu Nair59f6d2d2022-10-05 16:59:56 -070030#include <vector>
31#include <binder/Binder.h>
Dominik Laskowski068173d2021-08-11 17:22:59 -070032
Vishnu Naira61e4fb2022-10-18 18:29:37 +000033#include "FrontEnd/TransactionHandler.h"
Valerie Haud251afb2019-03-29 14:19:02 -070034#include "TestableSurfaceFlinger.h"
Vishnu Nair40fff5c2022-11-04 02:46:28 +000035#include "TransactionState.h"
Valerie Haud251afb2019-03-29 14:19:02 -070036
37namespace android {
38
39using testing::_;
40using testing::Return;
41
Vishnu Nairaf6d2972022-11-18 06:26:38 +000042using frontend::TransactionHandler;
43
Vishnu Nair1523dad2022-09-29 16:05:18 -070044constexpr nsecs_t TRANSACTION_TIMEOUT = s2ns(5);
Valerie Haud251afb2019-03-29 14:19:02 -070045class TransactionApplicationTest : public testing::Test {
46public:
47 TransactionApplicationTest() {
48 const ::testing::TestInfo* const test_info =
49 ::testing::UnitTest::GetInstance()->current_test_info();
50 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
51
Dominik Laskowskiaee9a622023-02-11 14:24:19 -050052 mFlinger.setupComposer(std::make_unique<Hwc2::mock::Composer>());
53 mFlinger.setupMockScheduler();
54 mFlinger.flinger()->addTransactionReadyFilters();
Valerie Haud251afb2019-03-29 14:19:02 -070055 }
56
57 ~TransactionApplicationTest() {
58 const ::testing::TestInfo* const test_info =
59 ::testing::UnitTest::GetInstance()->current_test_info();
60 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
61 }
62
Valerie Haud251afb2019-03-29 14:19:02 -070063 TestableSurfaceFlinger mFlinger;
64
Valerie Haud251afb2019-03-29 14:19:02 -070065 struct TransactionInfo {
66 Vector<ComposerState> states;
67 Vector<DisplayState> displays;
68 uint32_t flags = 0;
69 sp<IBinder> applyToken = IInterface::asBinder(TransactionCompletedListener::getIInstance());
70 InputWindowCommands inputWindowCommands;
Ady Abrahamf0c56492020-12-17 18:04:15 -080071 int64_t desiredPresentTime = 0;
72 bool isAutoTimestamp = true;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -100073 FrameTimelineInfo frameTimelineInfo;
Patrick Williams6c6dd3b2023-02-13 22:53:06 +000074 std::vector<client_cache_t> uncacheBuffers;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -100075 uint64_t id = static_cast<uint64_t>(-1);
Pablo Gamito23780be2023-04-18 08:30:00 +000076 std::vector<uint64_t> mergedTransactionIds;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -100077 static_assert(0xffffffffffffffff == static_cast<uint64_t>(-1));
Valerie Haud251afb2019-03-29 14:19:02 -070078 };
79
Vishnu Nair6b591152021-10-08 11:45:14 -070080 void checkEqual(TransactionInfo info, TransactionState state) {
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -100081 EXPECT_EQ(0u, info.states.size());
82 EXPECT_EQ(0u, state.states.size());
Valerie Haud251afb2019-03-29 14:19:02 -070083
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -100084 EXPECT_EQ(0u, info.displays.size());
85 EXPECT_EQ(0u, state.displays.size());
Valerie Haud251afb2019-03-29 14:19:02 -070086 EXPECT_EQ(info.flags, state.flags);
87 EXPECT_EQ(info.desiredPresentTime, state.desiredPresentTime);
88 }
89
Patrick Williams641f7f22022-06-22 19:25:35 +000090 void setupSingle(TransactionInfo& transaction, uint32_t flags, int64_t desiredPresentTime,
91 bool isAutoTimestamp, const FrameTimelineInfo& frameTimelineInfo) {
Valerie Haud251afb2019-03-29 14:19:02 -070092 mTransactionNumber++;
Vishnu Nair1523dad2022-09-29 16:05:18 -070093 transaction.flags |= flags;
Valerie Haud251afb2019-03-29 14:19:02 -070094 transaction.desiredPresentTime = desiredPresentTime;
Ady Abrahamf0c56492020-12-17 18:04:15 -080095 transaction.isAutoTimestamp = isAutoTimestamp;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -100096 transaction.frameTimelineInfo = frameTimelineInfo;
Valerie Haud251afb2019-03-29 14:19:02 -070097 }
98
Patrick Williams641f7f22022-06-22 19:25:35 +000099 void NotPlacedOnTransactionQueue(uint32_t flags) {
Vishnu Nair60d902e2022-07-20 02:55:37 +0000100 ASSERT_TRUE(mFlinger.getTransactionQueue().isEmpty());
Dominik Laskowski46f3e3b2021-08-10 11:44:24 -0700101 EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
Valerie Haud251afb2019-03-29 14:19:02 -0700102 TransactionInfo transaction;
Patrick Williams641f7f22022-06-22 19:25:35 +0000103 setupSingle(transaction, flags,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800104 /*desiredPresentTime*/ systemTime(), /*isAutoTimestamp*/ true,
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000105 FrameTimelineInfo{});
Valerie Haud251afb2019-03-29 14:19:02 -0700106 nsecs_t applicationTime = systemTime();
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000107 mFlinger.setTransactionState(transaction.frameTimelineInfo, transaction.states,
Ady Abraham22c7b5c2020-09-22 19:33:40 -0700108 transaction.displays, transaction.flags,
Valerie Haud251afb2019-03-29 14:19:02 -0700109 transaction.applyToken, transaction.inputWindowCommands,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800110 transaction.desiredPresentTime, transaction.isAutoTimestamp,
Patrick Williams6c6dd3b2023-02-13 22:53:06 +0000111 transaction.uncacheBuffers, mHasListenerCallbacks, mCallbacks,
Pablo Gamito23780be2023-04-18 08:30:00 +0000112 transaction.id, transaction.mergedTransactionIds);
Valerie Haud251afb2019-03-29 14:19:02 -0700113
Patrick Williams641f7f22022-06-22 19:25:35 +0000114 // If transaction is synchronous, SF applyTransactionState should time out (5s) wating for
115 // SF to commit the transaction. If this is animation, it should not time out waiting.
Valerie Haud251afb2019-03-29 14:19:02 -0700116 nsecs_t returnedTime = systemTime();
Vishnu Nair1523dad2022-09-29 16:05:18 -0700117 EXPECT_LE(returnedTime, applicationTime + TRANSACTION_TIMEOUT);
Arthur Hung58144272021-01-16 03:43:53 +0000118 // Each transaction should have been placed on the transaction queue
Vishnu Nair60d902e2022-07-20 02:55:37 +0000119 auto& transactionQueue = mFlinger.getTransactionQueue();
120 EXPECT_FALSE(transactionQueue.isEmpty());
Valerie Haud251afb2019-03-29 14:19:02 -0700121 }
122
Patrick Williams641f7f22022-06-22 19:25:35 +0000123 void PlaceOnTransactionQueue(uint32_t flags) {
Vishnu Nair60d902e2022-07-20 02:55:37 +0000124 ASSERT_TRUE(mFlinger.getTransactionQueue().isEmpty());
Dominik Laskowski46f3e3b2021-08-10 11:44:24 -0700125 EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
Valerie Haud251afb2019-03-29 14:19:02 -0700126
127 // first check will see desired present time has not passed,
128 // but afterwards it will look like the desired present time has passed
129 nsecs_t time = systemTime();
Valerie Haud251afb2019-03-29 14:19:02 -0700130 TransactionInfo transaction;
Patrick Williams641f7f22022-06-22 19:25:35 +0000131 setupSingle(transaction, flags, /*desiredPresentTime*/ time + s2ns(1), false,
132 FrameTimelineInfo{});
Valerie Haud251afb2019-03-29 14:19:02 -0700133 nsecs_t applicationSentTime = systemTime();
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000134 mFlinger.setTransactionState(transaction.frameTimelineInfo, transaction.states,
Ady Abraham22c7b5c2020-09-22 19:33:40 -0700135 transaction.displays, transaction.flags,
Valerie Haud251afb2019-03-29 14:19:02 -0700136 transaction.applyToken, transaction.inputWindowCommands,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800137 transaction.desiredPresentTime, transaction.isAutoTimestamp,
Patrick Williams6c6dd3b2023-02-13 22:53:06 +0000138 transaction.uncacheBuffers, mHasListenerCallbacks, mCallbacks,
Pablo Gamito23780be2023-04-18 08:30:00 +0000139 transaction.id, transaction.mergedTransactionIds);
Valerie Haud251afb2019-03-29 14:19:02 -0700140
141 nsecs_t returnedTime = systemTime();
Vishnu Nair1523dad2022-09-29 16:05:18 -0700142 EXPECT_LE(returnedTime, applicationSentTime + TRANSACTION_TIMEOUT);
Valerie Haud251afb2019-03-29 14:19:02 -0700143 // This transaction should have been placed on the transaction queue
Vishnu Nair60d902e2022-07-20 02:55:37 +0000144 auto& transactionQueue = mFlinger.getTransactionQueue();
145 EXPECT_FALSE(transactionQueue.isEmpty());
Valerie Haud251afb2019-03-29 14:19:02 -0700146 }
147
Patrick Williams641f7f22022-06-22 19:25:35 +0000148 void BlockedByPriorTransaction(uint32_t flags) {
Vishnu Nair60d902e2022-07-20 02:55:37 +0000149 ASSERT_TRUE(mFlinger.getTransactionQueue().isEmpty());
Valerie Haud251afb2019-03-29 14:19:02 -0700150 nsecs_t time = systemTime();
Patrick Williams641f7f22022-06-22 19:25:35 +0000151 EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(2);
152
Valerie Haud251afb2019-03-29 14:19:02 -0700153 // transaction that should go on the pending thread
154 TransactionInfo transactionA;
Patrick Williams641f7f22022-06-22 19:25:35 +0000155 setupSingle(transactionA, /*flags*/ 0, /*desiredPresentTime*/ time + s2ns(1), false,
156 FrameTimelineInfo{});
Valerie Haud251afb2019-03-29 14:19:02 -0700157
158 // transaction that would not have gone on the pending thread if not
159 // blocked
160 TransactionInfo transactionB;
Patrick Williams641f7f22022-06-22 19:25:35 +0000161 setupSingle(transactionB, flags, /*desiredPresentTime*/ systemTime(),
162 /*isAutoTimestamp*/ true, FrameTimelineInfo{});
Valerie Haud251afb2019-03-29 14:19:02 -0700163
164 nsecs_t applicationSentTime = systemTime();
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000165 mFlinger.setTransactionState(transactionA.frameTimelineInfo, transactionA.states,
Ady Abraham22c7b5c2020-09-22 19:33:40 -0700166 transactionA.displays, transactionA.flags,
Valerie Haud251afb2019-03-29 14:19:02 -0700167 transactionA.applyToken, transactionA.inputWindowCommands,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800168 transactionA.desiredPresentTime, transactionA.isAutoTimestamp,
Patrick Williams6c6dd3b2023-02-13 22:53:06 +0000169 transactionA.uncacheBuffers, mHasListenerCallbacks, mCallbacks,
Pablo Gamito23780be2023-04-18 08:30:00 +0000170 transactionA.id, transactionA.mergedTransactionIds);
Valerie Haud251afb2019-03-29 14:19:02 -0700171
172 // This thread should not have been blocked by the above transaction
173 // (5s is the timeout period that applyTransactionState waits for SF to
174 // commit the transaction)
Vishnu Nair1523dad2022-09-29 16:05:18 -0700175 EXPECT_LE(systemTime(), applicationSentTime + TRANSACTION_TIMEOUT);
Arthur Hung58144272021-01-16 03:43:53 +0000176 // transaction that would goes to pending transaciton queue.
177 mFlinger.flushTransactionQueues();
Valerie Haud251afb2019-03-29 14:19:02 -0700178
179 applicationSentTime = systemTime();
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000180 mFlinger.setTransactionState(transactionB.frameTimelineInfo, transactionB.states,
Ady Abraham22c7b5c2020-09-22 19:33:40 -0700181 transactionB.displays, transactionB.flags,
Valerie Haud251afb2019-03-29 14:19:02 -0700182 transactionB.applyToken, transactionB.inputWindowCommands,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800183 transactionB.desiredPresentTime, transactionB.isAutoTimestamp,
Patrick Williams6c6dd3b2023-02-13 22:53:06 +0000184 transactionB.uncacheBuffers, mHasListenerCallbacks, mCallbacks,
Pablo Gamito23780be2023-04-18 08:30:00 +0000185 transactionB.id, transactionB.mergedTransactionIds);
Valerie Haud251afb2019-03-29 14:19:02 -0700186
187 // this thread should have been blocked by the above transaction
188 // if this is an animation, this thread should be blocked for 5s
189 // in setTransactionState waiting for transactionA to flush. Otherwise,
190 // the transaction should be placed on the pending queue
Vishnu Nair1523dad2022-09-29 16:05:18 -0700191 EXPECT_LE(systemTime(), applicationSentTime + TRANSACTION_TIMEOUT);
Valerie Haud251afb2019-03-29 14:19:02 -0700192
Arthur Hung58144272021-01-16 03:43:53 +0000193 // transaction that would goes to pending transaciton queue.
194 mFlinger.flushTransactionQueues();
195
Ady Abrahame46243a2021-02-23 19:33:49 -0800196 // check that the transaction was applied.
Arthur Hung58144272021-01-16 03:43:53 +0000197 auto transactionQueue = mFlinger.getPendingTransactionQueue();
Ady Abrahame46243a2021-02-23 19:33:49 -0800198 EXPECT_EQ(0u, transactionQueue.size());
Valerie Haud251afb2019-03-29 14:19:02 -0700199 }
200
Dominik Laskowski1c99a002023-01-20 17:10:36 -0500201 void modulateVsync() {
202 static_cast<void>(
Dominik Laskowski14956dc2023-02-22 13:43:57 -0500203 mFlinger.mutableScheduler().vsyncModulator().onRefreshRateChangeInitiated());
Dominik Laskowski1c99a002023-01-20 17:10:36 -0500204 }
205
Valerie Haud251afb2019-03-29 14:19:02 -0700206 bool mHasListenerCallbacks = false;
207 std::vector<ListenerCallbacks> mCallbacks;
208 int mTransactionNumber = 0;
209};
210
Vishnu Nair60d902e2022-07-20 02:55:37 +0000211TEST_F(TransactionApplicationTest, AddToPendingQueue) {
212 ASSERT_TRUE(mFlinger.getTransactionQueue().isEmpty());
Dominik Laskowski46f3e3b2021-08-10 11:44:24 -0700213 EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
Valerie Haud251afb2019-03-29 14:19:02 -0700214
Valerie Haud251afb2019-03-29 14:19:02 -0700215 TransactionInfo transactionA; // transaction to go on pending queue
Patrick Williams641f7f22022-06-22 19:25:35 +0000216 setupSingle(transactionA, /*flags*/ 0, /*desiredPresentTime*/ s2ns(1), false,
217 FrameTimelineInfo{});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000218 mFlinger.setTransactionState(transactionA.frameTimelineInfo, transactionA.states,
Ady Abraham22c7b5c2020-09-22 19:33:40 -0700219 transactionA.displays, transactionA.flags, transactionA.applyToken,
220 transactionA.inputWindowCommands, transactionA.desiredPresentTime,
Patrick Williams6c6dd3b2023-02-13 22:53:06 +0000221 transactionA.isAutoTimestamp, transactionA.uncacheBuffers,
Pablo Gamito23780be2023-04-18 08:30:00 +0000222 mHasListenerCallbacks, mCallbacks, transactionA.id,
223 transactionA.mergedTransactionIds);
Valerie Haud251afb2019-03-29 14:19:02 -0700224
Zhuoyao Zhang3d3540d2021-01-14 05:14:54 +0000225 auto& transactionQueue = mFlinger.getTransactionQueue();
Vishnu Nair60d902e2022-07-20 02:55:37 +0000226 ASSERT_FALSE(transactionQueue.isEmpty());
Valerie Haud251afb2019-03-29 14:19:02 -0700227
Vishnu Nair60d902e2022-07-20 02:55:37 +0000228 auto transactionState = transactionQueue.pop().value();
Valerie Haud251afb2019-03-29 14:19:02 -0700229 checkEqual(transactionA, transactionState);
Vishnu Nair60d902e2022-07-20 02:55:37 +0000230}
231
232TEST_F(TransactionApplicationTest, Flush_RemovesFromQueue) {
233 ASSERT_TRUE(mFlinger.getTransactionQueue().isEmpty());
234 EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
235
236 TransactionInfo transactionA; // transaction to go on pending queue
237 setupSingle(transactionA, /*flags*/ 0, /*desiredPresentTime*/ s2ns(1), false,
238 FrameTimelineInfo{});
239 mFlinger.setTransactionState(transactionA.frameTimelineInfo, transactionA.states,
240 transactionA.displays, transactionA.flags, transactionA.applyToken,
241 transactionA.inputWindowCommands, transactionA.desiredPresentTime,
Patrick Williams6c6dd3b2023-02-13 22:53:06 +0000242 transactionA.isAutoTimestamp, transactionA.uncacheBuffers,
Pablo Gamito23780be2023-04-18 08:30:00 +0000243 mHasListenerCallbacks, mCallbacks, transactionA.id,
244 transactionA.mergedTransactionIds);
Vishnu Nair60d902e2022-07-20 02:55:37 +0000245
246 auto& transactionQueue = mFlinger.getTransactionQueue();
247 ASSERT_FALSE(transactionQueue.isEmpty());
Valerie Haud251afb2019-03-29 14:19:02 -0700248
249 // because flushing uses the cached expected present time, we send an empty
250 // transaction here (sending a null applyToken to fake it as from a
251 // different process) to re-query and reset the cached expected present time
252 TransactionInfo empty;
253 empty.applyToken = sp<IBinder>();
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000254 mFlinger.setTransactionState(empty.frameTimelineInfo, empty.states, empty.displays, empty.flags,
255 empty.applyToken, empty.inputWindowCommands,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800256 empty.desiredPresentTime, empty.isAutoTimestamp,
Pablo Gamito23780be2023-04-18 08:30:00 +0000257 empty.uncacheBuffers, mHasListenerCallbacks, mCallbacks, empty.id,
258 empty.mergedTransactionIds);
Valerie Haud251afb2019-03-29 14:19:02 -0700259
Zhuoyao Zhang3d3540d2021-01-14 05:14:54 +0000260 // flush transaction queue should flush as desiredPresentTime has
Valerie Haud251afb2019-03-29 14:19:02 -0700261 // passed
Zhuoyao Zhang3d3540d2021-01-14 05:14:54 +0000262 mFlinger.flushTransactionQueues();
Valerie Haud251afb2019-03-29 14:19:02 -0700263
Vishnu Nair60d902e2022-07-20 02:55:37 +0000264 EXPECT_TRUE(mFlinger.getTransactionQueue().isEmpty());
Valerie Haud251afb2019-03-29 14:19:02 -0700265}
266
Valerie Haud251afb2019-03-29 14:19:02 -0700267TEST_F(TransactionApplicationTest, NotPlacedOnTransactionQueue_SyncInputWindows) {
Patrick Williams641f7f22022-06-22 19:25:35 +0000268 NotPlacedOnTransactionQueue(/*flags*/ 0);
Valerie Haud251afb2019-03-29 14:19:02 -0700269}
270
Valerie Haud251afb2019-03-29 14:19:02 -0700271TEST_F(TransactionApplicationTest, PlaceOnTransactionQueue_SyncInputWindows) {
Patrick Williams641f7f22022-06-22 19:25:35 +0000272 PlaceOnTransactionQueue(/*flags*/ 0);
Valerie Haud251afb2019-03-29 14:19:02 -0700273}
274
Valerie Hau09e60052019-12-15 14:51:15 -0800275TEST_F(TransactionApplicationTest, FromHandle) {
276 sp<IBinder> badHandle;
277 auto ret = mFlinger.fromHandle(badHandle);
Vishnu Nair07e2a482022-10-18 19:18:16 +0000278 EXPECT_EQ(nullptr, ret.get());
Valerie Hau09e60052019-12-15 14:51:15 -0800279}
ramindani4d48f902021-09-20 21:07:45 +0000280
Vishnu Nair7ee4f462023-04-19 09:54:09 -0700281class FakeExternalTexture : public renderengine::ExternalTexture {
282 const sp<GraphicBuffer> mEmptyBuffer = nullptr;
283 uint32_t mWidth;
284 uint32_t mHeight;
285 uint64_t mId;
286 PixelFormat mPixelFormat;
287 uint64_t mUsage;
288
289public:
290 FakeExternalTexture(BufferData& bufferData)
291 : mWidth(bufferData.getWidth()),
292 mHeight(bufferData.getHeight()),
293 mId(bufferData.getId()),
294 mPixelFormat(bufferData.getPixelFormat()),
295 mUsage(bufferData.getUsage()) {}
296 const sp<GraphicBuffer>& getBuffer() const { return mEmptyBuffer; }
297 bool hasSameBuffer(const renderengine::ExternalTexture& other) const override {
298 return getId() == other.getId();
299 }
300 uint32_t getWidth() const override { return mWidth; }
301 uint32_t getHeight() const override { return mHeight; }
302 uint64_t getId() const override { return mId; }
303 PixelFormat getPixelFormat() const override { return mPixelFormat; }
304 uint64_t getUsage() const override { return mUsage; }
305 void remapBuffer() override {}
306 ~FakeExternalTexture() = default;
307};
308
Ady Abraham9dada822022-02-03 10:26:59 -0800309class LatchUnsignaledTest : public TransactionApplicationTest {
310public:
311 void TearDown() override {
312 // Clear all transaction queues to release all transactions we sent
313 // in the tests. Otherwise, gmock complains about memory leaks.
Vishnu Nair60d902e2022-07-20 02:55:37 +0000314 while (!mFlinger.getTransactionQueue().isEmpty()) {
315 mFlinger.getTransactionQueue().pop();
316 }
Ady Abraham9dada822022-02-03 10:26:59 -0800317 mFlinger.getPendingTransactionQueue().clear();
Ady Abraham9dada822022-02-03 10:26:59 -0800318 mFlinger.commitTransactionsLocked(eTransactionMask);
319 mFlinger.mutableCurrentState().layersSortedByZ.clear();
320 mFlinger.mutableDrawingState().layersSortedByZ.clear();
321 }
322
323 static sp<Fence> fence(Fence::Status status) {
324 const auto fence = sp<mock::MockFence>::make();
325 EXPECT_CALL(*fence, getStatus()).WillRepeatedly(Return(status));
326 return fence;
327 }
328
Vishnu Nairf01a6f12023-04-03 22:34:17 +0000329 ComposerState createComposerState(int layerId, sp<Fence> fence, uint64_t what,
330 std::optional<sp<IBinder>> layerHandle = std::nullopt) {
Ady Abraham9dada822022-02-03 10:26:59 -0800331 ComposerState state;
Vishnu Nair59f6d2d2022-10-05 16:59:56 -0700332 state.state.bufferData =
333 std::make_shared<fake::BufferData>(/* bufferId */ 123L, /* width */ 1,
334 /* height */ 2, /* pixelFormat */ 0,
335 /* outUsage */ 0);
Ady Abraham9dada822022-02-03 10:26:59 -0800336 state.state.bufferData->acquireFence = std::move(fence);
337 state.state.layerId = layerId;
Vishnu Nairf01a6f12023-04-03 22:34:17 +0000338 state.state.surface = layerHandle.value_or(
Patrick Williams83f36b22022-09-14 17:57:35 +0000339 sp<Layer>::make(LayerCreationArgs(mFlinger.flinger(), nullptr, "TestLayer", 0, {}))
Vishnu Nairf01a6f12023-04-03 22:34:17 +0000340 ->getHandle());
Ady Abraham9dada822022-02-03 10:26:59 -0800341 state.state.bufferData->flags = BufferData::BufferDataChange::fenceChanged;
342
343 state.state.what = what;
344 if (what & layer_state_t::eCropChanged) {
345 state.state.crop = Rect(1, 2, 3, 4);
346 }
Vishnu Nairf01a6f12023-04-03 22:34:17 +0000347 if (what & layer_state_t::eFlagsChanged) {
348 state.state.flags = layer_state_t::eEnableBackpressure;
349 state.state.mask = layer_state_t::eEnableBackpressure;
350 }
351
Ady Abraham9dada822022-02-03 10:26:59 -0800352 return state;
353 }
354
355 TransactionInfo createTransactionInfo(const sp<IBinder>& applyToken,
356 const std::vector<ComposerState>& states) {
357 TransactionInfo transaction;
Vishnu Nair1523dad2022-09-29 16:05:18 -0700358 const uint32_t kFlags = 0;
Ady Abraham9dada822022-02-03 10:26:59 -0800359 const nsecs_t kDesiredPresentTime = systemTime();
360 const bool kIsAutoTimestamp = true;
361 const auto kFrameTimelineInfo = FrameTimelineInfo{};
362
Patrick Williams641f7f22022-06-22 19:25:35 +0000363 setupSingle(transaction, kFlags, kDesiredPresentTime, kIsAutoTimestamp, kFrameTimelineInfo);
Ady Abraham9dada822022-02-03 10:26:59 -0800364 transaction.applyToken = applyToken;
365 for (const auto& state : states) {
366 transaction.states.push_back(state);
367 }
368
369 return transaction;
370 }
371
372 void setTransactionStates(const std::vector<TransactionInfo>& transactions,
Ady Abraham9dada822022-02-03 10:26:59 -0800373 size_t expectedTransactionsPending) {
Vishnu Nair60d902e2022-07-20 02:55:37 +0000374 EXPECT_TRUE(mFlinger.getTransactionQueue().isEmpty());
Ady Abraham9dada822022-02-03 10:26:59 -0800375 EXPECT_EQ(0u, mFlinger.getPendingTransactionQueue().size());
376
Vishnu Nair40fff5c2022-11-04 02:46:28 +0000377 for (auto transaction : transactions) {
378 std::vector<ResolvedComposerState> resolvedStates;
379 resolvedStates.reserve(transaction.states.size());
380 for (auto& state : transaction.states) {
Vishnu Nair7ee4f462023-04-19 09:54:09 -0700381 ResolvedComposerState resolvedState;
382 resolvedState.state = std::move(state.state);
383 resolvedState.externalTexture =
384 std::make_shared<FakeExternalTexture>(*resolvedState.state.bufferData);
385 resolvedStates.emplace_back(resolvedState);
Vishnu Nair40fff5c2022-11-04 02:46:28 +0000386 }
387
388 TransactionState transactionState(transaction.frameTimelineInfo, resolvedStates,
389 transaction.displays, transaction.flags,
390 transaction.applyToken,
391 transaction.inputWindowCommands,
392 transaction.desiredPresentTime,
Chavi Weingartenc78f53c2023-04-14 18:50:53 +0000393 transaction.isAutoTimestamp, {}, systemTime(),
Vishnu Nair40fff5c2022-11-04 02:46:28 +0000394 mHasListenerCallbacks, mCallbacks, getpid(),
Pablo Gamito23780be2023-04-18 08:30:00 +0000395 static_cast<int>(getuid()), transaction.id,
396 transaction.mergedTransactionIds);
Vishnu Nair40fff5c2022-11-04 02:46:28 +0000397 mFlinger.setTransactionStateInternal(transactionState);
Ady Abraham9dada822022-02-03 10:26:59 -0800398 }
399 mFlinger.flushTransactionQueues();
Vishnu Nair60d902e2022-07-20 02:55:37 +0000400 EXPECT_TRUE(mFlinger.getTransactionQueue().isEmpty());
Vishnu Nair59f6d2d2022-10-05 16:59:56 -0700401 EXPECT_EQ(expectedTransactionsPending, mFlinger.getPendingTransactionCount());
Ady Abraham9dada822022-02-03 10:26:59 -0800402 }
403};
404
405class LatchUnsignaledAutoSingleLayerTest : public LatchUnsignaledTest {
406public:
407 void SetUp() override {
408 LatchUnsignaledTest::SetUp();
409 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::AutoSingleLayer;
410 }
411};
412
413TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_RemovesSingleSignaledFromTheQueue) {
414 const sp<IBinder> kApplyToken =
415 IInterface::asBinder(TransactionCompletedListener::getIInstance());
416 const auto kLayerId = 1;
Ady Abraham9dada822022-02-03 10:26:59 -0800417 const auto kExpectedTransactionsPending = 0u;
418
419 const auto signaledTransaction =
420 createTransactionInfo(kApplyToken,
421 {createComposerState(kLayerId, fence(Fence::Status::Signaled),
422 layer_state_t::eBufferChanged)});
Vishnu Nair1523dad2022-09-29 16:05:18 -0700423 setTransactionStates({signaledTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000424}
425
Ady Abraham9dada822022-02-03 10:26:59 -0800426TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_RemovesSingleUnSignaledFromTheQueue) {
427 const sp<IBinder> kApplyToken =
428 IInterface::asBinder(TransactionCompletedListener::getIInstance());
429 const auto kLayerId = 1;
Ady Abraham9dada822022-02-03 10:26:59 -0800430 const auto kExpectedTransactionsPending = 0u;
431
432 const auto unsignaledTransaction =
433 createTransactionInfo(kApplyToken,
434 {
435 createComposerState(kLayerId,
436 fence(Fence::Status::Unsignaled),
437 layer_state_t::eBufferChanged),
438 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700439 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000440}
441
Ady Abraham9dada822022-02-03 10:26:59 -0800442TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_KeepsUnSignaledInTheQueue_NonBufferCropChange) {
443 const sp<IBinder> kApplyToken =
444 IInterface::asBinder(TransactionCompletedListener::getIInstance());
445 const auto kLayerId = 1;
Ady Abraham9dada822022-02-03 10:26:59 -0800446 const auto kExpectedTransactionsPending = 1u;
447
448 const auto unsignaledTransaction =
449 createTransactionInfo(kApplyToken,
450 {
451 createComposerState(kLayerId,
452 fence(Fence::Status::Unsignaled),
Vishnu Nair59f6d2d2022-10-05 16:59:56 -0700453 layer_state_t::eCropChanged |
454 layer_state_t::
455 eBufferChanged),
Ady Abraham9dada822022-02-03 10:26:59 -0800456 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700457 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000458}
459
Ady Abraham9dada822022-02-03 10:26:59 -0800460TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_KeepsUnSignaledInTheQueue_NonBufferChangeClubed) {
461 const sp<IBinder> kApplyToken =
462 IInterface::asBinder(TransactionCompletedListener::getIInstance());
463 const auto kLayerId = 1;
Ady Abraham9dada822022-02-03 10:26:59 -0800464 const auto kExpectedTransactionsPending = 1u;
465
466 const auto unsignaledTransaction =
467 createTransactionInfo(kApplyToken,
468 {
469 createComposerState(kLayerId,
470 fence(Fence::Status::Unsignaled),
471 layer_state_t::eCropChanged |
472 layer_state_t::
473 eBufferChanged),
474 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700475 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000476}
477
Ady Abraham9dada822022-02-03 10:26:59 -0800478TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_KeepsInTheQueueSameApplyTokenMultiState) {
479 const sp<IBinder> kApplyToken =
480 IInterface::asBinder(TransactionCompletedListener::getIInstance());
481 const auto kLayerId = 1;
Ady Abraham9dada822022-02-03 10:26:59 -0800482 const auto kExpectedTransactionsPending = 1u;
483
484 const auto mixedTransaction =
485 createTransactionInfo(kApplyToken,
486 {
487 createComposerState(kLayerId,
488 fence(Fence::Status::Unsignaled),
489 layer_state_t::eBufferChanged),
490 createComposerState(kLayerId,
491 fence(Fence::Status::Signaled),
492 layer_state_t::eBufferChanged),
493 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700494 setTransactionStates({mixedTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000495}
496
Ady Abraham9dada822022-02-03 10:26:59 -0800497TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_KeepsInTheQueue_MultipleStateTransaction) {
498 const sp<IBinder> kApplyToken =
499 IInterface::asBinder(TransactionCompletedListener::getIInstance());
500 const auto kLayerId1 = 1;
501 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800502 const auto kExpectedTransactionsPending = 1u;
503
504 const auto mixedTransaction =
505 createTransactionInfo(kApplyToken,
506 {
507 createComposerState(kLayerId1,
508 fence(Fence::Status::Unsignaled),
509 layer_state_t::eBufferChanged),
510 createComposerState(kLayerId2,
511 fence(Fence::Status::Signaled),
512 layer_state_t::eBufferChanged),
513 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700514 setTransactionStates({mixedTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000515}
516
Ady Abraham9dada822022-02-03 10:26:59 -0800517TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_RemovesSignaledFromTheQueue) {
518 const sp<IBinder> kApplyToken =
519 IInterface::asBinder(TransactionCompletedListener::getIInstance());
520 const auto kLayerId1 = 1;
521 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800522 const auto kExpectedTransactionsPending = 0u;
523
524 const auto signaledTransaction =
525 createTransactionInfo(kApplyToken,
526 {
527 createComposerState(kLayerId1,
528 fence(Fence::Status::Signaled),
529 layer_state_t::eBufferChanged),
530 });
531 const auto signaledTransaction2 =
532 createTransactionInfo(kApplyToken,
533 {
534 createComposerState(kLayerId2,
535 fence(Fence::Status::Signaled),
536 layer_state_t::eBufferChanged),
537 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700538 setTransactionStates({signaledTransaction, signaledTransaction2}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000539}
540
Ady Abrahame1bfaac2022-02-22 21:32:08 -0800541TEST_F(LatchUnsignaledAutoSingleLayerTest,
542 UnsignaledNotAppliedWhenThereAreSignaled_UnsignaledFirst) {
Ady Abraham9dada822022-02-03 10:26:59 -0800543 const sp<IBinder> kApplyToken1 =
544 IInterface::asBinder(TransactionCompletedListener::getIInstance());
545 const sp<IBinder> kApplyToken2 = sp<BBinder>::make();
Ady Abrahame1bfaac2022-02-22 21:32:08 -0800546 const sp<IBinder> kApplyToken3 = sp<BBinder>::make();
Ady Abraham9dada822022-02-03 10:26:59 -0800547 const auto kLayerId1 = 1;
548 const auto kLayerId2 = 2;
Ady Abrahame1bfaac2022-02-22 21:32:08 -0800549 const auto kExpectedTransactionsPending = 1u;
550
551 const auto unsignaledTransaction =
552 createTransactionInfo(kApplyToken1,
553 {
554 createComposerState(kLayerId1,
555 fence(Fence::Status::Unsignaled),
556 layer_state_t::eBufferChanged),
557 });
558
559 const auto signaledTransaction =
560 createTransactionInfo(kApplyToken2,
561 {
562 createComposerState(kLayerId2,
563 fence(Fence::Status::Signaled),
564 layer_state_t::eBufferChanged),
565 });
566 const auto signaledTransaction2 =
567 createTransactionInfo(kApplyToken3,
568 {
569 createComposerState(kLayerId2,
570 fence(Fence::Status::Signaled),
571 layer_state_t::eBufferChanged),
572 });
573
574 setTransactionStates({unsignaledTransaction, signaledTransaction, signaledTransaction2},
Vishnu Nair1523dad2022-09-29 16:05:18 -0700575 kExpectedTransactionsPending);
Ady Abrahame1bfaac2022-02-22 21:32:08 -0800576}
577
Ady Abraham9dada822022-02-03 10:26:59 -0800578TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_KeepsTransactionInTheQueueSameApplyToken) {
579 const sp<IBinder> kApplyToken =
580 IInterface::asBinder(TransactionCompletedListener::getIInstance());
581 const auto kLayerId1 = 1;
582 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800583 const auto kExpectedTransactionsPending = 1u;
584
585 const auto unsignaledTransaction =
586 createTransactionInfo(kApplyToken,
587 {
588 createComposerState(kLayerId1,
589 fence(Fence::Status::Unsignaled),
590 layer_state_t::eBufferChanged),
591 });
592 const auto signaledTransaction =
593 createTransactionInfo(kApplyToken,
594 {
595 createComposerState(kLayerId2,
596 fence(Fence::Status::Signaled),
597 layer_state_t::eBufferChanged),
598 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700599 setTransactionStates({unsignaledTransaction, signaledTransaction},
Ady Abraham9dada822022-02-03 10:26:59 -0800600 kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000601}
602
Ady Abraham9dada822022-02-03 10:26:59 -0800603TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_KeepsTransactionInTheQueue) {
604 const sp<IBinder> kApplyToken1 =
605 IInterface::asBinder(TransactionCompletedListener::getIInstance());
606 const sp<IBinder> kApplyToken2 = sp<BBinder>::make();
607 const auto kLayerId1 = 1;
608 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800609 const auto kExpectedTransactionsPending = 1u;
610
611 const auto unsignaledTransaction =
612 createTransactionInfo(kApplyToken1,
613 {
614 createComposerState(kLayerId1,
615 fence(Fence::Status::Unsignaled),
616 layer_state_t::eBufferChanged),
617 });
618 const auto unsignaledTransaction2 =
619 createTransactionInfo(kApplyToken2,
620 {
621 createComposerState(kLayerId2,
622 fence(Fence::Status::Unsignaled),
623 layer_state_t::eBufferChanged),
624 });
625 setTransactionStates({unsignaledTransaction, unsignaledTransaction2},
Vishnu Nair1523dad2022-09-29 16:05:18 -0700626 kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000627}
628
Ady Abraham2739e832022-02-14 17:42:00 -0800629TEST_F(LatchUnsignaledAutoSingleLayerTest, DontLatchUnsignaledWhenEarlyOffset) {
630 const sp<IBinder> kApplyToken =
631 IInterface::asBinder(TransactionCompletedListener::getIInstance());
632 const auto kLayerId = 1;
Ady Abraham2739e832022-02-14 17:42:00 -0800633 const auto kExpectedTransactionsPending = 1u;
634
635 const auto unsignaledTransaction =
636 createTransactionInfo(kApplyToken,
637 {
638 createComposerState(kLayerId,
639 fence(Fence::Status::Unsignaled),
640 layer_state_t::eBufferChanged),
641 });
642
Dominik Laskowski1c99a002023-01-20 17:10:36 -0500643 modulateVsync();
Vishnu Nair1523dad2022-09-29 16:05:18 -0700644 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
Ady Abraham2739e832022-02-14 17:42:00 -0800645}
646
Vishnu Nairf01a6f12023-04-03 22:34:17 +0000647TEST_F(LatchUnsignaledAutoSingleLayerTest, UnsignaledNotAppliedWhenThereAreSignaled_SignaledFirst) {
648 const sp<IBinder> kApplyToken1 =
649 IInterface::asBinder(TransactionCompletedListener::getIInstance());
650 const sp<IBinder> kApplyToken2 = sp<BBinder>::make();
651 const sp<IBinder> kApplyToken3 = sp<BBinder>::make();
652 const auto kLayerId1 = 1;
653 const auto kLayerId2 = 2;
654 const auto kExpectedTransactionsPending = 1u;
655
656 const auto signaledTransaction =
657 createTransactionInfo(kApplyToken1,
658 {
659 createComposerState(kLayerId1,
660 fence(Fence::Status::Signaled),
661 layer_state_t::eBufferChanged),
662 });
663 const auto signaledTransaction2 =
664 createTransactionInfo(kApplyToken2,
665 {
666 createComposerState(kLayerId1,
667 fence(Fence::Status::Signaled),
668 layer_state_t::eBufferChanged),
669 });
670 const auto unsignaledTransaction =
671 createTransactionInfo(kApplyToken3,
672 {
673 createComposerState(kLayerId2,
674 fence(Fence::Status::Unsignaled),
675 layer_state_t::eBufferChanged),
676 });
677
678 setTransactionStates({signaledTransaction, signaledTransaction2, unsignaledTransaction},
679 kExpectedTransactionsPending);
680}
681
Ady Abraham9dada822022-02-03 10:26:59 -0800682class LatchUnsignaledDisabledTest : public LatchUnsignaledTest {
683public:
684 void SetUp() override {
685 LatchUnsignaledTest::SetUp();
686 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Disabled;
687 }
688};
689
690TEST_F(LatchUnsignaledDisabledTest, Flush_RemovesSignaledFromTheQueue) {
691 const sp<IBinder> kApplyToken =
692 IInterface::asBinder(TransactionCompletedListener::getIInstance());
693 const auto kLayerId = 1;
Ady Abraham9dada822022-02-03 10:26:59 -0800694 const auto kExpectedTransactionsPending = 0u;
695
696 const auto signaledTransaction =
697 createTransactionInfo(kApplyToken,
698 {createComposerState(kLayerId, fence(Fence::Status::Signaled),
699 layer_state_t::eBufferChanged)});
Vishnu Nair1523dad2022-09-29 16:05:18 -0700700 setTransactionStates({signaledTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000701}
702
Ady Abraham9dada822022-02-03 10:26:59 -0800703TEST_F(LatchUnsignaledDisabledTest, Flush_KeepsInTheQueue) {
704 const sp<IBinder> kApplyToken =
705 IInterface::asBinder(TransactionCompletedListener::getIInstance());
706 const auto kLayerId = 1;
Ady Abraham9dada822022-02-03 10:26:59 -0800707 const auto kExpectedTransactionsPending = 1u;
708
709 const auto unsignaledTransaction =
710 createTransactionInfo(kApplyToken,
711 {
712 createComposerState(kLayerId,
713 fence(Fence::Status::Unsignaled),
714 layer_state_t::eBufferChanged),
715 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700716 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000717}
718
Ady Abraham9dada822022-02-03 10:26:59 -0800719TEST_F(LatchUnsignaledDisabledTest, Flush_KeepsInTheQueueSameLayerId) {
720 const sp<IBinder> kApplyToken =
721 IInterface::asBinder(TransactionCompletedListener::getIInstance());
722 const auto kLayerId = 1;
Ady Abraham9dada822022-02-03 10:26:59 -0800723 const auto kExpectedTransactionsPending = 1u;
724
725 const auto unsignaledTransaction =
726 createTransactionInfo(kApplyToken,
727 {
728 createComposerState(kLayerId,
729 fence(Fence::Status::Unsignaled),
730 layer_state_t::eBufferChanged),
731 createComposerState(kLayerId,
732 fence(Fence::Status::Unsignaled),
733 layer_state_t::eBufferChanged),
734 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700735 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000736}
737
Ady Abraham9dada822022-02-03 10:26:59 -0800738TEST_F(LatchUnsignaledDisabledTest, Flush_KeepsInTheQueueDifferentLayerId) {
739 const sp<IBinder> kApplyToken =
740 IInterface::asBinder(TransactionCompletedListener::getIInstance());
741 const auto kLayerId1 = 1;
742 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800743 const auto kExpectedTransactionsPending = 1u;
744
745 const auto unsignaledTransaction =
746 createTransactionInfo(kApplyToken,
747 {
748 createComposerState(kLayerId1,
749 fence(Fence::Status::Unsignaled),
750 layer_state_t::eBufferChanged),
751 createComposerState(kLayerId2,
752 fence(Fence::Status::Unsignaled),
753 layer_state_t::eBufferChanged),
754 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700755 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000756}
757
Ady Abraham9dada822022-02-03 10:26:59 -0800758TEST_F(LatchUnsignaledDisabledTest, Flush_RemovesSignaledFromTheQueue_MultipleLayers) {
759 const sp<IBinder> kApplyToken =
760 IInterface::asBinder(TransactionCompletedListener::getIInstance());
761 const auto kLayerId1 = 1;
762 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800763 const auto kExpectedTransactionsPending = 0u;
764
765 const auto signaledTransaction =
766 createTransactionInfo(kApplyToken,
767 {
768 createComposerState(kLayerId1,
769 fence(Fence::Status::Signaled),
770 layer_state_t::eBufferChanged),
771 });
772 const auto signaledTransaction2 =
773 createTransactionInfo(kApplyToken,
774 {
775 createComposerState(kLayerId2,
776 fence(Fence::Status::Signaled),
777 layer_state_t::eBufferChanged),
778 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700779 setTransactionStates({signaledTransaction, signaledTransaction2}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000780}
781
Ady Abraham9dada822022-02-03 10:26:59 -0800782TEST_F(LatchUnsignaledDisabledTest, Flush_KeepInTheQueueDifferentApplyToken) {
783 const sp<IBinder> kApplyToken1 =
784 IInterface::asBinder(TransactionCompletedListener::getIInstance());
785 const sp<IBinder> kApplyToken2 = sp<BBinder>::make();
786 const auto kLayerId1 = 1;
787 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800788 const auto kExpectedTransactionsPending = 1u;
789
790 const auto unsignaledTransaction =
791 createTransactionInfo(kApplyToken1,
792 {
793 createComposerState(kLayerId1,
794 fence(Fence::Status::Unsignaled),
795 layer_state_t::eBufferChanged),
796 });
797 const auto signaledTransaction =
798 createTransactionInfo(kApplyToken2,
799 {
800 createComposerState(kLayerId2,
801 fence(Fence::Status::Signaled),
802 layer_state_t::eBufferChanged),
803 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700804 setTransactionStates({unsignaledTransaction, signaledTransaction},
Ady Abraham9dada822022-02-03 10:26:59 -0800805 kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000806}
807
Ady Abraham9dada822022-02-03 10:26:59 -0800808TEST_F(LatchUnsignaledDisabledTest, Flush_KeepInTheQueueSameApplyToken) {
809 const sp<IBinder> kApplyToken =
810 IInterface::asBinder(TransactionCompletedListener::getIInstance());
811 const auto kLayerId1 = 1;
812 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800813 const auto kExpectedTransactionsPending = 1u;
814
815 const auto signaledTransaction =
816 createTransactionInfo(kApplyToken,
817 {
818 createComposerState(kLayerId1,
819 fence(Fence::Status::Signaled),
820 layer_state_t::eBufferChanged),
821 });
822 const auto unsignaledTransaction =
823 createTransactionInfo(kApplyToken,
824 {
825 createComposerState(kLayerId2,
826 fence(Fence::Status::Unsignaled),
827 layer_state_t::eBufferChanged),
828 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700829 setTransactionStates({signaledTransaction, unsignaledTransaction},
Ady Abraham9dada822022-02-03 10:26:59 -0800830 kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000831}
832
Ady Abraham9dada822022-02-03 10:26:59 -0800833TEST_F(LatchUnsignaledDisabledTest, Flush_KeepInTheUnsignaledTheQueue) {
834 const sp<IBinder> kApplyToken =
835 IInterface::asBinder(TransactionCompletedListener::getIInstance());
836 const auto kLayerId1 = 1;
837 const auto kLayerId2 = 2;
Vishnu Nair59f6d2d2022-10-05 16:59:56 -0700838 const auto kExpectedTransactionsPending = 2u;
Ady Abraham9dada822022-02-03 10:26:59 -0800839
840 const auto unsignaledTransaction =
841 createTransactionInfo(kApplyToken,
842 {
843 createComposerState(kLayerId1,
844 fence(Fence::Status::Unsignaled),
845 layer_state_t::eBufferChanged),
846 });
847 const auto unsignaledTransaction2 =
848 createTransactionInfo(kApplyToken,
849 {
850 createComposerState(kLayerId2,
851 fence(Fence::Status::Unsignaled),
852 layer_state_t::eBufferChanged),
853 });
854 setTransactionStates({unsignaledTransaction, unsignaledTransaction2},
Vishnu Nair1523dad2022-09-29 16:05:18 -0700855 kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000856}
857
Ady Abraham9dada822022-02-03 10:26:59 -0800858class LatchUnsignaledAlwaysTest : public LatchUnsignaledTest {
859public:
860 void SetUp() override {
861 LatchUnsignaledTest::SetUp();
862 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Always;
863 }
864};
865
866TEST_F(LatchUnsignaledAlwaysTest, Flush_RemovesSignaledFromTheQueue) {
867 const sp<IBinder> kApplyToken =
868 IInterface::asBinder(TransactionCompletedListener::getIInstance());
869 const auto kLayerId = 1;
Ady Abraham9dada822022-02-03 10:26:59 -0800870 const auto kExpectedTransactionsPending = 0u;
871
872 const auto signaledTransaction =
873 createTransactionInfo(kApplyToken,
874 {createComposerState(kLayerId, fence(Fence::Status::Signaled),
875 layer_state_t::eBufferChanged)});
Vishnu Nair1523dad2022-09-29 16:05:18 -0700876 setTransactionStates({signaledTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000877}
878
Ady Abraham9dada822022-02-03 10:26:59 -0800879TEST_F(LatchUnsignaledAlwaysTest, Flush_RemovesFromTheQueue) {
880 const sp<IBinder> kApplyToken =
881 IInterface::asBinder(TransactionCompletedListener::getIInstance());
882 const auto kLayerId = 1;
Ady Abraham9dada822022-02-03 10:26:59 -0800883 const auto kExpectedTransactionsPending = 0u;
884
885 const auto unsignaledTransaction =
886 createTransactionInfo(kApplyToken,
887 {createComposerState(kLayerId, fence(Fence::Status::Unsignaled),
888 layer_state_t::eBufferChanged)});
Vishnu Nair1523dad2022-09-29 16:05:18 -0700889 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000890}
891
Ady Abraham9dada822022-02-03 10:26:59 -0800892TEST_F(LatchUnsignaledAlwaysTest, Flush_RemovesFromTheQueueSameLayerId) {
893 const sp<IBinder> kApplyToken =
894 IInterface::asBinder(TransactionCompletedListener::getIInstance());
895 const auto kLayerId = 1;
Ady Abraham9dada822022-02-03 10:26:59 -0800896 const auto kExpectedTransactionsPending = 0u;
897
898 const auto mixedTransaction =
899 createTransactionInfo(kApplyToken,
900 {createComposerState(kLayerId, fence(Fence::Status::Unsignaled),
901 layer_state_t::eBufferChanged),
902 createComposerState(kLayerId, fence(Fence::Status::Signaled),
903 layer_state_t::eBufferChanged)});
Vishnu Nair1523dad2022-09-29 16:05:18 -0700904 setTransactionStates({mixedTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000905}
906
Ady Abraham9dada822022-02-03 10:26:59 -0800907TEST_F(LatchUnsignaledAlwaysTest, Flush_RemovesFromTheQueueDifferentLayerId) {
908 const sp<IBinder> kApplyToken =
909 IInterface::asBinder(TransactionCompletedListener::getIInstance());
910 const auto kLayerId1 = 1;
911 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800912 const auto kExpectedTransactionsPending = 0u;
913
914 const auto mixedTransaction =
915 createTransactionInfo(kApplyToken,
916 {createComposerState(kLayerId1, fence(Fence::Status::Unsignaled),
917 layer_state_t::eBufferChanged),
918 createComposerState(kLayerId2, fence(Fence::Status::Signaled),
919 layer_state_t::eBufferChanged)});
Vishnu Nair1523dad2022-09-29 16:05:18 -0700920 setTransactionStates({mixedTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000921}
922
Ady Abraham9dada822022-02-03 10:26:59 -0800923TEST_F(LatchUnsignaledAlwaysTest, Flush_RemovesSignaledFromTheQueue_MultipleLayers) {
924 const sp<IBinder> kApplyToken =
925 IInterface::asBinder(TransactionCompletedListener::getIInstance());
926 const auto kLayerId1 = 1;
927 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800928 const auto kExpectedTransactionsPending = 0u;
929
930 const auto signaledTransaction =
931 createTransactionInfo(kApplyToken,
932 {
933 createComposerState(kLayerId1,
934 fence(Fence::Status::Signaled),
935 layer_state_t::eBufferChanged),
936 });
937 const auto signaledTransaction2 =
938 createTransactionInfo(kApplyToken,
939 {
940 createComposerState(kLayerId2,
941 fence(Fence::Status::Signaled),
942 layer_state_t::eBufferChanged),
943 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700944 setTransactionStates({signaledTransaction, signaledTransaction2}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000945}
946
Ady Abraham9dada822022-02-03 10:26:59 -0800947TEST_F(LatchUnsignaledAlwaysTest, Flush_RemovesFromTheQueueDifferentApplyToken) {
948 const sp<IBinder> kApplyToken1 =
949 IInterface::asBinder(TransactionCompletedListener::getIInstance());
950 const sp<IBinder> kApplyToken2 = sp<BBinder>::make();
951 const auto kLayerId1 = 1;
952 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800953 const auto kExpectedTransactionsPending = 0u;
954
955 const auto signaledTransaction =
956 createTransactionInfo(kApplyToken1,
957 {
958 createComposerState(kLayerId1,
959 fence(Fence::Status::Signaled),
960 layer_state_t::eBufferChanged),
961 });
962 const auto unsignaledTransaction =
963 createTransactionInfo(kApplyToken2,
964 {
965 createComposerState(kLayerId2,
966 fence(Fence::Status::Unsignaled),
967 layer_state_t::eBufferChanged),
968 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700969 setTransactionStates({signaledTransaction, unsignaledTransaction},
Ady Abraham9dada822022-02-03 10:26:59 -0800970 kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000971}
972
Ady Abraham9dada822022-02-03 10:26:59 -0800973TEST_F(LatchUnsignaledAlwaysTest, Flush_RemovesUnsignaledFromTheQueueSameApplyToken) {
974 const sp<IBinder> kApplyToken =
975 IInterface::asBinder(TransactionCompletedListener::getIInstance());
976 const auto kLayerId1 = 1;
977 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800978 const auto kExpectedTransactionsPending = 0u;
979
980 const auto unsignaledTransaction =
981 createTransactionInfo(kApplyToken,
982 {
983 createComposerState(kLayerId1,
984 fence(Fence::Status::Unsignaled),
985 layer_state_t::eBufferChanged),
986 });
987 const auto signaledTransaction =
988 createTransactionInfo(kApplyToken,
989 {
990 createComposerState(kLayerId2,
991 fence(Fence::Status::Signaled),
992 layer_state_t::eBufferChanged),
993 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700994 setTransactionStates({unsignaledTransaction, signaledTransaction},
Ady Abraham9dada822022-02-03 10:26:59 -0800995 kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000996}
997
Ady Abraham9dada822022-02-03 10:26:59 -0800998TEST_F(LatchUnsignaledAlwaysTest, Flush_RemovesUnsignaledFromTheQueue) {
999 const sp<IBinder> kApplyToken1 =
1000 IInterface::asBinder(TransactionCompletedListener::getIInstance());
1001 const sp<IBinder> kApplyToken2 = sp<BBinder>::make();
1002 const auto kLayerId1 = 1;
1003 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -08001004 const auto kExpectedTransactionsPending = 0u;
1005
1006 const auto unsignaledTransaction =
1007 createTransactionInfo(kApplyToken1,
1008 {
1009 createComposerState(kLayerId1,
1010 fence(Fence::Status::Unsignaled),
1011 layer_state_t::eBufferChanged),
1012 });
1013 const auto unsignaledTransaction2 =
1014 createTransactionInfo(kApplyToken2,
1015 {
1016 createComposerState(kLayerId2,
1017 fence(Fence::Status::Unsignaled),
1018 layer_state_t::eBufferChanged),
1019 });
1020 setTransactionStates({unsignaledTransaction, unsignaledTransaction2},
Vishnu Nair1523dad2022-09-29 16:05:18 -07001021 kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +00001022}
1023
Vishnu Nairf01a6f12023-04-03 22:34:17 +00001024TEST_F(LatchUnsignaledAlwaysTest, RespectsBackPressureFlag) {
1025 const sp<IBinder> kApplyToken1 =
1026 IInterface::asBinder(TransactionCompletedListener::getIInstance());
1027 const sp<IBinder> kApplyToken2 = sp<BBinder>::make();
1028 const auto kLayerId1 = 1;
1029 const auto kExpectedTransactionsPending = 1u;
1030 auto layer =
1031 sp<Layer>::make(LayerCreationArgs(mFlinger.flinger(), nullptr, "TestLayer", 0, {}));
1032 auto layerHandle = layer->getHandle();
1033 const auto setBackPressureFlagTransaction =
1034 createTransactionInfo(kApplyToken1,
1035 {createComposerState(kLayerId1, fence(Fence::Status::Unsignaled),
1036 layer_state_t::eBufferChanged |
1037 layer_state_t::eFlagsChanged,
1038 {layerHandle})});
1039 setTransactionStates({setBackPressureFlagTransaction}, 0u);
1040
1041 const auto unsignaledTransaction =
1042 createTransactionInfo(kApplyToken1,
1043 {
1044 createComposerState(kLayerId1,
1045 fence(Fence::Status::Unsignaled),
1046 layer_state_t::eBufferChanged,
1047 {layerHandle}),
1048 });
1049 const auto unsignaledTransaction2 =
1050 createTransactionInfo(kApplyToken1,
1051 {
1052 createComposerState(kLayerId1,
1053 fence(Fence::Status::Unsignaled),
1054 layer_state_t::eBufferChanged,
1055 {layerHandle}),
1056 });
1057 setTransactionStates({unsignaledTransaction, unsignaledTransaction2},
1058 kExpectedTransactionsPending);
1059}
1060
Ady Abraham2739e832022-02-14 17:42:00 -08001061TEST_F(LatchUnsignaledAlwaysTest, LatchUnsignaledWhenEarlyOffset) {
1062 const sp<IBinder> kApplyToken =
1063 IInterface::asBinder(TransactionCompletedListener::getIInstance());
1064 const auto kLayerId = 1;
Ady Abraham2739e832022-02-14 17:42:00 -08001065 const auto kExpectedTransactionsPending = 0u;
1066
1067 const auto unsignaledTransaction =
1068 createTransactionInfo(kApplyToken,
1069 {
1070 createComposerState(kLayerId,
1071 fence(Fence::Status::Unsignaled),
1072 layer_state_t::eBufferChanged),
1073 });
1074
Dominik Laskowski1c99a002023-01-20 17:10:36 -05001075 modulateVsync();
Vishnu Nair1523dad2022-09-29 16:05:18 -07001076 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
Ady Abraham2739e832022-02-14 17:42:00 -08001077}
1078
Vishnu Nair59f6d2d2022-10-05 16:59:56 -07001079TEST(TransactionHandlerTest, QueueTransaction) {
1080 TransactionHandler handler;
1081 TransactionState transaction;
1082 transaction.applyToken = sp<BBinder>::make();
1083 transaction.id = 42;
1084 handler.queueTransaction(std::move(transaction));
Vishnu Nair4d9cef92023-06-24 22:34:41 +00001085 handler.collectTransactions();
Vishnu Nair59f6d2d2022-10-05 16:59:56 -07001086 std::vector<TransactionState> transactionsReadyToBeApplied = handler.flushTransactions();
1087
1088 EXPECT_EQ(transactionsReadyToBeApplied.size(), 1u);
1089 EXPECT_EQ(transactionsReadyToBeApplied.front().id, 42u);
1090}
1091
Pablo Gamito23780be2023-04-18 08:30:00 +00001092TEST(TransactionHandlerTest, TransactionsKeepTrackOfDirectMerges) {
1093 SurfaceComposerClient::Transaction transaction1, transaction2, transaction3, transaction4;
1094
1095 uint64_t transaction2Id = transaction2.getId();
1096 uint64_t transaction3Id = transaction3.getId();
1097 EXPECT_NE(transaction2Id, transaction3Id);
1098
1099 transaction1.merge(std::move(transaction2));
1100 transaction1.merge(std::move(transaction3));
1101
1102 EXPECT_EQ(transaction1.getMergedTransactionIds().size(), 2u);
1103 EXPECT_EQ(transaction1.getMergedTransactionIds()[0], transaction3Id);
1104 EXPECT_EQ(transaction1.getMergedTransactionIds()[1], transaction2Id);
1105}
1106
1107TEST(TransactionHandlerTest, TransactionsKeepTrackOfIndirectMerges) {
1108 SurfaceComposerClient::Transaction transaction1, transaction2, transaction3, transaction4;
1109
1110 uint64_t transaction2Id = transaction2.getId();
1111 uint64_t transaction3Id = transaction3.getId();
1112 uint64_t transaction4Id = transaction4.getId();
1113 EXPECT_NE(transaction2Id, transaction3Id);
1114 EXPECT_NE(transaction2Id, transaction4Id);
1115 EXPECT_NE(transaction3Id, transaction4Id);
1116
1117 transaction4.merge(std::move(transaction2));
1118 transaction4.merge(std::move(transaction3));
1119
1120 EXPECT_EQ(transaction4.getMergedTransactionIds().size(), 2u);
1121 EXPECT_EQ(transaction4.getMergedTransactionIds()[0], transaction3Id);
1122 EXPECT_EQ(transaction4.getMergedTransactionIds()[1], transaction2Id);
1123
1124 transaction1.merge(std::move(transaction4));
1125
1126 EXPECT_EQ(transaction1.getMergedTransactionIds().size(), 3u);
1127 EXPECT_EQ(transaction1.getMergedTransactionIds()[0], transaction4Id);
1128 EXPECT_EQ(transaction1.getMergedTransactionIds()[1], transaction3Id);
1129 EXPECT_EQ(transaction1.getMergedTransactionIds()[2], transaction2Id);
1130}
1131
1132TEST(TransactionHandlerTest, TransactionMergesAreCleared) {
1133 SurfaceComposerClient::Transaction transaction1, transaction2, transaction3;
1134
1135 transaction1.merge(std::move(transaction2));
1136 transaction1.merge(std::move(transaction3));
1137
1138 EXPECT_EQ(transaction1.getMergedTransactionIds().size(), 2u);
1139
1140 transaction1.clear();
1141
1142 EXPECT_EQ(transaction1.getMergedTransactionIds().empty(), true);
1143}
1144
1145TEST(TransactionHandlerTest, TransactionMergesAreCapped) {
1146 SurfaceComposerClient::Transaction transaction;
1147 std::vector<uint64_t> mergedTransactionIds;
1148
1149 for (uint i = 0; i < 20u; i++) {
1150 SurfaceComposerClient::Transaction transactionToMerge;
1151 mergedTransactionIds.push_back(transactionToMerge.getId());
1152 transaction.merge(std::move(transactionToMerge));
1153 }
1154
1155 // Keeps latest 10 merges in order of merge recency
1156 EXPECT_EQ(transaction.getMergedTransactionIds().size(), 10u);
1157 for (uint i = 0; i < 10u; i++) {
1158 EXPECT_EQ(transaction.getMergedTransactionIds()[i],
1159 mergedTransactionIds[mergedTransactionIds.size() - 1 - i]);
1160 }
1161}
1162
1163TEST(TransactionHandlerTest, KeepsMergesFromMoreRecentMerge) {
1164 SurfaceComposerClient::Transaction transaction1, transaction2, transaction3;
1165 std::vector<uint64_t> mergedTransactionIds1, mergedTransactionIds2, mergedTransactionIds3;
1166 uint64_t transaction2Id = transaction2.getId();
1167 uint64_t transaction3Id = transaction3.getId();
1168
1169 for (uint i = 0; i < 20u; i++) {
1170 SurfaceComposerClient::Transaction transactionToMerge;
1171 mergedTransactionIds1.push_back(transactionToMerge.getId());
1172 transaction1.merge(std::move(transactionToMerge));
1173 }
1174
1175 for (uint i = 0; i < 5u; i++) {
1176 SurfaceComposerClient::Transaction transactionToMerge;
1177 mergedTransactionIds2.push_back(transactionToMerge.getId());
1178 transaction2.merge(std::move(transactionToMerge));
1179 }
1180
1181 transaction1.merge(std::move(transaction2));
1182 EXPECT_EQ(transaction1.getMergedTransactionIds().size(), 10u);
1183 EXPECT_EQ(transaction1.getMergedTransactionIds()[0], transaction2Id);
1184 for (uint i = 0; i < 5u; i++) {
1185 EXPECT_EQ(transaction1.getMergedTransactionIds()[i + 1u],
1186 mergedTransactionIds2[mergedTransactionIds2.size() - 1 - i]);
1187 }
1188 for (uint i = 0; i < 4u; i++) {
1189 EXPECT_EQ(transaction1.getMergedTransactionIds()[i + 6u],
1190 mergedTransactionIds1[mergedTransactionIds1.size() - 1 - i]);
1191 }
1192
1193 for (uint i = 0; i < 20u; i++) {
1194 SurfaceComposerClient::Transaction transactionToMerge;
1195 mergedTransactionIds3.push_back(transactionToMerge.getId());
1196 transaction3.merge(std::move(transactionToMerge));
1197 }
1198
1199 transaction1.merge(std::move(transaction3));
1200 EXPECT_EQ(transaction1.getMergedTransactionIds().size(), 10u);
1201 EXPECT_EQ(transaction1.getMergedTransactionIds()[0], transaction3Id);
1202 for (uint i = 0; i < 9u; i++) {
1203 EXPECT_EQ(transaction1.getMergedTransactionIds()[i + 1],
1204 mergedTransactionIds3[mergedTransactionIds3.size() - 1 - i]);
1205 }
1206}
1207
1208TEST(TransactionHandlerTest, CanAddTransactionWithFullMergedIds) {
1209 SurfaceComposerClient::Transaction transaction1, transaction2;
1210 for (uint i = 0; i < 20u; i++) {
1211 SurfaceComposerClient::Transaction transactionToMerge;
1212 transaction1.merge(std::move(transactionToMerge));
1213 }
1214
1215 EXPECT_EQ(transaction1.getMergedTransactionIds().size(), 10u);
1216
1217 auto transaction1Id = transaction1.getId();
1218 transaction2.merge(std::move(transaction1));
1219 EXPECT_EQ(transaction2.getMergedTransactionIds().size(), 10u);
1220 auto mergedTransactionIds = transaction2.getMergedTransactionIds();
1221 EXPECT_TRUE(std::count(mergedTransactionIds.begin(), mergedTransactionIds.end(),
1222 transaction1Id) > 0);
1223}
1224
Valerie Haud251afb2019-03-29 14:19:02 -07001225} // namespace android