• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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>
24 #include <gui/LayerState.h>
25 #include <gui/SurfaceComposerClient.h>
26 #include <gui/fake/BufferData.h>
27 #include <log/log.h>
28 #include <ui/MockFence.h>
29 #include <utils/String8.h>
30 #include <vector>
31 #include <binder/Binder.h>
32 
33 #include "FrontEnd/TransactionHandler.h"
34 #include "TestableSurfaceFlinger.h"
35 #include "TransactionState.h"
36 
37 namespace android {
38 
39 using testing::_;
40 using testing::Return;
41 
42 using frontend::TransactionHandler;
43 
44 constexpr nsecs_t TRANSACTION_TIMEOUT = s2ns(5);
45 class TransactionApplicationTest : public testing::Test {
46 public:
TransactionApplicationTest()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 
52         mFlinger.setupComposer(std::make_unique<Hwc2::mock::Composer>());
53         mFlinger.setupMockScheduler();
54         mFlinger.flinger()->addTransactionReadyFilters();
55     }
56 
~TransactionApplicationTest()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 
63     TestableSurfaceFlinger mFlinger;
64 
65     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;
71         int64_t desiredPresentTime = 0;
72         bool isAutoTimestamp = true;
73         FrameTimelineInfo frameTimelineInfo;
74         std::vector<client_cache_t> uncacheBuffers;
75         uint64_t id = static_cast<uint64_t>(-1);
76         std::vector<uint64_t> mergedTransactionIds;
77         static_assert(0xffffffffffffffff == static_cast<uint64_t>(-1));
78     };
79 
checkEqual(TransactionInfo info,TransactionState state)80     void checkEqual(TransactionInfo info, TransactionState state) {
81         EXPECT_EQ(0u, info.states.size());
82         EXPECT_EQ(0u, state.states.size());
83 
84         EXPECT_EQ(0u, info.displays.size());
85         EXPECT_EQ(0u, state.displays.size());
86         EXPECT_EQ(info.flags, state.flags);
87         EXPECT_EQ(info.desiredPresentTime, state.desiredPresentTime);
88     }
89 
setupSingle(TransactionInfo & transaction,uint32_t flags,int64_t desiredPresentTime,bool isAutoTimestamp,const FrameTimelineInfo & frameTimelineInfo)90     void setupSingle(TransactionInfo& transaction, uint32_t flags, int64_t desiredPresentTime,
91                      bool isAutoTimestamp, const FrameTimelineInfo& frameTimelineInfo) {
92         mTransactionNumber++;
93         transaction.flags |= flags;
94         transaction.desiredPresentTime = desiredPresentTime;
95         transaction.isAutoTimestamp = isAutoTimestamp;
96         transaction.frameTimelineInfo = frameTimelineInfo;
97     }
98 
NotPlacedOnTransactionQueue(uint32_t flags)99     void NotPlacedOnTransactionQueue(uint32_t flags) {
100         ASSERT_TRUE(mFlinger.getTransactionQueue().isEmpty());
101         EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
102         TransactionInfo transaction;
103         setupSingle(transaction, flags,
104                     /*desiredPresentTime*/ systemTime(), /*isAutoTimestamp*/ true,
105                     FrameTimelineInfo{});
106         nsecs_t applicationTime = systemTime();
107         mFlinger.setTransactionState(transaction.frameTimelineInfo, transaction.states,
108                                      transaction.displays, transaction.flags,
109                                      transaction.applyToken, transaction.inputWindowCommands,
110                                      transaction.desiredPresentTime, transaction.isAutoTimestamp,
111                                      transaction.uncacheBuffers, mHasListenerCallbacks, mCallbacks,
112                                      transaction.id, transaction.mergedTransactionIds);
113 
114         // 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.
116         nsecs_t returnedTime = systemTime();
117         EXPECT_LE(returnedTime, applicationTime + TRANSACTION_TIMEOUT);
118         // Each transaction should have been placed on the transaction queue
119         auto& transactionQueue = mFlinger.getTransactionQueue();
120         EXPECT_FALSE(transactionQueue.isEmpty());
121     }
122 
PlaceOnTransactionQueue(uint32_t flags)123     void PlaceOnTransactionQueue(uint32_t flags) {
124         ASSERT_TRUE(mFlinger.getTransactionQueue().isEmpty());
125         EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
126 
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();
130         TransactionInfo transaction;
131         setupSingle(transaction, flags, /*desiredPresentTime*/ time + s2ns(1), false,
132                     FrameTimelineInfo{});
133         nsecs_t applicationSentTime = systemTime();
134         mFlinger.setTransactionState(transaction.frameTimelineInfo, transaction.states,
135                                      transaction.displays, transaction.flags,
136                                      transaction.applyToken, transaction.inputWindowCommands,
137                                      transaction.desiredPresentTime, transaction.isAutoTimestamp,
138                                      transaction.uncacheBuffers, mHasListenerCallbacks, mCallbacks,
139                                      transaction.id, transaction.mergedTransactionIds);
140 
141         nsecs_t returnedTime = systemTime();
142         EXPECT_LE(returnedTime, applicationSentTime + TRANSACTION_TIMEOUT);
143         // This transaction should have been placed on the transaction queue
144         auto& transactionQueue = mFlinger.getTransactionQueue();
145         EXPECT_FALSE(transactionQueue.isEmpty());
146     }
147 
BlockedByPriorTransaction(uint32_t flags)148     void BlockedByPriorTransaction(uint32_t flags) {
149         ASSERT_TRUE(mFlinger.getTransactionQueue().isEmpty());
150         nsecs_t time = systemTime();
151         EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(2);
152 
153         // transaction that should go on the pending thread
154         TransactionInfo transactionA;
155         setupSingle(transactionA, /*flags*/ 0, /*desiredPresentTime*/ time + s2ns(1), false,
156                     FrameTimelineInfo{});
157 
158         // transaction that would not have gone on the pending thread if not
159         // blocked
160         TransactionInfo transactionB;
161         setupSingle(transactionB, flags, /*desiredPresentTime*/ systemTime(),
162                     /*isAutoTimestamp*/ true, FrameTimelineInfo{});
163 
164         nsecs_t applicationSentTime = systemTime();
165         mFlinger.setTransactionState(transactionA.frameTimelineInfo, transactionA.states,
166                                      transactionA.displays, transactionA.flags,
167                                      transactionA.applyToken, transactionA.inputWindowCommands,
168                                      transactionA.desiredPresentTime, transactionA.isAutoTimestamp,
169                                      transactionA.uncacheBuffers, mHasListenerCallbacks, mCallbacks,
170                                      transactionA.id, transactionA.mergedTransactionIds);
171 
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)
175         EXPECT_LE(systemTime(), applicationSentTime + TRANSACTION_TIMEOUT);
176         // transaction that would goes to pending transaciton queue.
177         mFlinger.flushTransactionQueues();
178 
179         applicationSentTime = systemTime();
180         mFlinger.setTransactionState(transactionB.frameTimelineInfo, transactionB.states,
181                                      transactionB.displays, transactionB.flags,
182                                      transactionB.applyToken, transactionB.inputWindowCommands,
183                                      transactionB.desiredPresentTime, transactionB.isAutoTimestamp,
184                                      transactionB.uncacheBuffers, mHasListenerCallbacks, mCallbacks,
185                                      transactionB.id, transactionB.mergedTransactionIds);
186 
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
191         EXPECT_LE(systemTime(), applicationSentTime + TRANSACTION_TIMEOUT);
192 
193         // transaction that would goes to pending transaciton queue.
194         mFlinger.flushTransactionQueues();
195 
196         // check that the transaction was applied.
197         auto transactionQueue = mFlinger.getPendingTransactionQueue();
198         EXPECT_EQ(0u, transactionQueue.size());
199     }
200 
modulateVsync()201     void modulateVsync() {
202         static_cast<void>(
203                 mFlinger.mutableScheduler().vsyncModulator().onRefreshRateChangeInitiated());
204     }
205 
206     bool mHasListenerCallbacks = false;
207     std::vector<ListenerCallbacks> mCallbacks;
208     int mTransactionNumber = 0;
209 };
210 
TEST_F(TransactionApplicationTest,AddToPendingQueue)211 TEST_F(TransactionApplicationTest, AddToPendingQueue) {
212     ASSERT_TRUE(mFlinger.getTransactionQueue().isEmpty());
213     EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
214 
215     TransactionInfo transactionA; // transaction to go on pending queue
216     setupSingle(transactionA, /*flags*/ 0, /*desiredPresentTime*/ s2ns(1), false,
217                 FrameTimelineInfo{});
218     mFlinger.setTransactionState(transactionA.frameTimelineInfo, transactionA.states,
219                                  transactionA.displays, transactionA.flags, transactionA.applyToken,
220                                  transactionA.inputWindowCommands, transactionA.desiredPresentTime,
221                                  transactionA.isAutoTimestamp, transactionA.uncacheBuffers,
222                                  mHasListenerCallbacks, mCallbacks, transactionA.id,
223                                  transactionA.mergedTransactionIds);
224 
225     auto& transactionQueue = mFlinger.getTransactionQueue();
226     ASSERT_FALSE(transactionQueue.isEmpty());
227 
228     auto transactionState = transactionQueue.pop().value();
229     checkEqual(transactionA, transactionState);
230 }
231 
TEST_F(TransactionApplicationTest,Flush_RemovesFromQueue)232 TEST_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,
242                                  transactionA.isAutoTimestamp, transactionA.uncacheBuffers,
243                                  mHasListenerCallbacks, mCallbacks, transactionA.id,
244                                  transactionA.mergedTransactionIds);
245 
246     auto& transactionQueue = mFlinger.getTransactionQueue();
247     ASSERT_FALSE(transactionQueue.isEmpty());
248 
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>();
254     mFlinger.setTransactionState(empty.frameTimelineInfo, empty.states, empty.displays, empty.flags,
255                                  empty.applyToken, empty.inputWindowCommands,
256                                  empty.desiredPresentTime, empty.isAutoTimestamp,
257                                  empty.uncacheBuffers, mHasListenerCallbacks, mCallbacks, empty.id,
258                                  empty.mergedTransactionIds);
259 
260     // flush transaction queue should flush as desiredPresentTime has
261     // passed
262     mFlinger.flushTransactionQueues();
263 
264     EXPECT_TRUE(mFlinger.getTransactionQueue().isEmpty());
265 }
266 
TEST_F(TransactionApplicationTest,NotPlacedOnTransactionQueue_SyncInputWindows)267 TEST_F(TransactionApplicationTest, NotPlacedOnTransactionQueue_SyncInputWindows) {
268     NotPlacedOnTransactionQueue(/*flags*/ 0);
269 }
270 
TEST_F(TransactionApplicationTest,PlaceOnTransactionQueue_SyncInputWindows)271 TEST_F(TransactionApplicationTest, PlaceOnTransactionQueue_SyncInputWindows) {
272     PlaceOnTransactionQueue(/*flags*/ 0);
273 }
274 
TEST_F(TransactionApplicationTest,FromHandle)275 TEST_F(TransactionApplicationTest, FromHandle) {
276     sp<IBinder> badHandle;
277     auto ret = mFlinger.fromHandle(badHandle);
278     EXPECT_EQ(nullptr, ret.get());
279 }
280 
281 class 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 
289 public:
FakeExternalTexture(BufferData & bufferData)290     FakeExternalTexture(BufferData& bufferData)
291           : mWidth(bufferData.getWidth()),
292             mHeight(bufferData.getHeight()),
293             mId(bufferData.getId()),
294             mPixelFormat(bufferData.getPixelFormat()),
295             mUsage(bufferData.getUsage()) {}
getBuffer() const296     const sp<GraphicBuffer>& getBuffer() const { return mEmptyBuffer; }
hasSameBuffer(const renderengine::ExternalTexture & other) const297     bool hasSameBuffer(const renderengine::ExternalTexture& other) const override {
298         return getId() == other.getId();
299     }
getWidth() const300     uint32_t getWidth() const override { return mWidth; }
getHeight() const301     uint32_t getHeight() const override { return mHeight; }
getId() const302     uint64_t getId() const override { return mId; }
getPixelFormat() const303     PixelFormat getPixelFormat() const override { return mPixelFormat; }
getUsage() const304     uint64_t getUsage() const override { return mUsage; }
remapBuffer()305     void remapBuffer() override {}
306     ~FakeExternalTexture() = default;
307 };
308 
309 class LatchUnsignaledTest : public TransactionApplicationTest {
310 public:
TearDown()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.
314         while (!mFlinger.getTransactionQueue().isEmpty()) {
315             mFlinger.getTransactionQueue().pop();
316         }
317         mFlinger.getPendingTransactionQueue().clear();
318         mFlinger.commitTransactionsLocked(eTransactionMask);
319         mFlinger.mutableCurrentState().layersSortedByZ.clear();
320         mFlinger.mutableDrawingState().layersSortedByZ.clear();
321     }
322 
fence(Fence::Status status)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 
createComposerState(int layerId,sp<Fence> fence,uint64_t what,std::optional<sp<IBinder>> layerHandle=std::nullopt)329     ComposerState createComposerState(int layerId, sp<Fence> fence, uint64_t what,
330                                       std::optional<sp<IBinder>> layerHandle = std::nullopt) {
331         ComposerState state;
332         state.state.bufferData =
333                 std::make_shared<fake::BufferData>(/* bufferId */ 123L, /* width */ 1,
334                                                    /* height */ 2, /* pixelFormat */ 0,
335                                                    /* outUsage */ 0);
336         state.state.bufferData->acquireFence = std::move(fence);
337         state.state.layerId = layerId;
338         state.state.surface = layerHandle.value_or(
339                 sp<Layer>::make(LayerCreationArgs(mFlinger.flinger(), nullptr, "TestLayer", 0, {}))
340                         ->getHandle());
341         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         }
347         if (what & layer_state_t::eFlagsChanged) {
348             state.state.flags = layer_state_t::eEnableBackpressure;
349             state.state.mask = layer_state_t::eEnableBackpressure;
350         }
351 
352         return state;
353     }
354 
createTransactionInfo(const sp<IBinder> & applyToken,const std::vector<ComposerState> & states)355     TransactionInfo createTransactionInfo(const sp<IBinder>& applyToken,
356                                           const std::vector<ComposerState>& states) {
357         TransactionInfo transaction;
358         const uint32_t kFlags = 0;
359         const nsecs_t kDesiredPresentTime = systemTime();
360         const bool kIsAutoTimestamp = true;
361         const auto kFrameTimelineInfo = FrameTimelineInfo{};
362 
363         setupSingle(transaction, kFlags, kDesiredPresentTime, kIsAutoTimestamp, kFrameTimelineInfo);
364         transaction.applyToken = applyToken;
365         for (const auto& state : states) {
366             transaction.states.push_back(state);
367         }
368 
369         return transaction;
370     }
371 
setTransactionStates(const std::vector<TransactionInfo> & transactions,size_t expectedTransactionsPending)372     void setTransactionStates(const std::vector<TransactionInfo>& transactions,
373                               size_t expectedTransactionsPending) {
374         EXPECT_TRUE(mFlinger.getTransactionQueue().isEmpty());
375         EXPECT_EQ(0u, mFlinger.getPendingTransactionQueue().size());
376 
377         for (auto transaction : transactions) {
378             std::vector<ResolvedComposerState> resolvedStates;
379             resolvedStates.reserve(transaction.states.size());
380             for (auto& state : transaction.states) {
381                 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);
386             }
387 
388             TransactionState transactionState(transaction.frameTimelineInfo, resolvedStates,
389                                               transaction.displays, transaction.flags,
390                                               transaction.applyToken,
391                                               transaction.inputWindowCommands,
392                                               transaction.desiredPresentTime,
393                                               transaction.isAutoTimestamp, {}, systemTime(),
394                                               mHasListenerCallbacks, mCallbacks, getpid(),
395                                               static_cast<int>(getuid()), transaction.id,
396                                               transaction.mergedTransactionIds);
397             mFlinger.setTransactionStateInternal(transactionState);
398         }
399         mFlinger.flushTransactionQueues();
400         EXPECT_TRUE(mFlinger.getTransactionQueue().isEmpty());
401         EXPECT_EQ(expectedTransactionsPending, mFlinger.getPendingTransactionCount());
402     }
403 };
404 
405 class LatchUnsignaledAutoSingleLayerTest : public LatchUnsignaledTest {
406 public:
SetUp()407     void SetUp() override {
408         LatchUnsignaledTest::SetUp();
409         SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::AutoSingleLayer;
410     }
411 };
412 
TEST_F(LatchUnsignaledAutoSingleLayerTest,Flush_RemovesSingleSignaledFromTheQueue)413 TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_RemovesSingleSignaledFromTheQueue) {
414     const sp<IBinder> kApplyToken =
415             IInterface::asBinder(TransactionCompletedListener::getIInstance());
416     const auto kLayerId = 1;
417     const auto kExpectedTransactionsPending = 0u;
418 
419     const auto signaledTransaction =
420             createTransactionInfo(kApplyToken,
421                                   {createComposerState(kLayerId, fence(Fence::Status::Signaled),
422                                                        layer_state_t::eBufferChanged)});
423     setTransactionStates({signaledTransaction}, kExpectedTransactionsPending);
424 }
425 
TEST_F(LatchUnsignaledAutoSingleLayerTest,Flush_RemovesSingleUnSignaledFromTheQueue)426 TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_RemovesSingleUnSignaledFromTheQueue) {
427     const sp<IBinder> kApplyToken =
428             IInterface::asBinder(TransactionCompletedListener::getIInstance());
429     const auto kLayerId = 1;
430     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                                   });
439     setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
440 }
441 
TEST_F(LatchUnsignaledAutoSingleLayerTest,Flush_KeepsUnSignaledInTheQueue_NonBufferCropChange)442 TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_KeepsUnSignaledInTheQueue_NonBufferCropChange) {
443     const sp<IBinder> kApplyToken =
444             IInterface::asBinder(TransactionCompletedListener::getIInstance());
445     const auto kLayerId = 1;
446     const auto kExpectedTransactionsPending = 1u;
447 
448     const auto unsignaledTransaction =
449             createTransactionInfo(kApplyToken,
450                                   {
451                                           createComposerState(kLayerId,
452                                                               fence(Fence::Status::Unsignaled),
453                                                               layer_state_t::eCropChanged |
454                                                                       layer_state_t::
455                                                                               eBufferChanged),
456                                   });
457     setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
458 }
459 
TEST_F(LatchUnsignaledAutoSingleLayerTest,Flush_KeepsUnSignaledInTheQueue_NonBufferChangeClubed)460 TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_KeepsUnSignaledInTheQueue_NonBufferChangeClubed) {
461     const sp<IBinder> kApplyToken =
462             IInterface::asBinder(TransactionCompletedListener::getIInstance());
463     const auto kLayerId = 1;
464     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                                   });
475     setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
476 }
477 
TEST_F(LatchUnsignaledAutoSingleLayerTest,Flush_KeepsInTheQueueSameApplyTokenMultiState)478 TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_KeepsInTheQueueSameApplyTokenMultiState) {
479     const sp<IBinder> kApplyToken =
480             IInterface::asBinder(TransactionCompletedListener::getIInstance());
481     const auto kLayerId = 1;
482     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                                   });
494     setTransactionStates({mixedTransaction}, kExpectedTransactionsPending);
495 }
496 
TEST_F(LatchUnsignaledAutoSingleLayerTest,Flush_KeepsInTheQueue_MultipleStateTransaction)497 TEST_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;
502     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                                   });
514     setTransactionStates({mixedTransaction}, kExpectedTransactionsPending);
515 }
516 
TEST_F(LatchUnsignaledAutoSingleLayerTest,Flush_RemovesSignaledFromTheQueue)517 TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_RemovesSignaledFromTheQueue) {
518     const sp<IBinder> kApplyToken =
519             IInterface::asBinder(TransactionCompletedListener::getIInstance());
520     const auto kLayerId1 = 1;
521     const auto kLayerId2 = 2;
522     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                                   });
538     setTransactionStates({signaledTransaction, signaledTransaction2}, kExpectedTransactionsPending);
539 }
540 
TEST_F(LatchUnsignaledAutoSingleLayerTest,UnsignaledNotAppliedWhenThereAreSignaled_UnsignaledFirst)541 TEST_F(LatchUnsignaledAutoSingleLayerTest,
542        UnsignaledNotAppliedWhenThereAreSignaled_UnsignaledFirst) {
543     const sp<IBinder> kApplyToken1 =
544             IInterface::asBinder(TransactionCompletedListener::getIInstance());
545     const sp<IBinder> kApplyToken2 = sp<BBinder>::make();
546     const sp<IBinder> kApplyToken3 = sp<BBinder>::make();
547     const auto kLayerId1 = 1;
548     const auto kLayerId2 = 2;
549     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},
575                          kExpectedTransactionsPending);
576 }
577 
TEST_F(LatchUnsignaledAutoSingleLayerTest,Flush_KeepsTransactionInTheQueueSameApplyToken)578 TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_KeepsTransactionInTheQueueSameApplyToken) {
579     const sp<IBinder> kApplyToken =
580             IInterface::asBinder(TransactionCompletedListener::getIInstance());
581     const auto kLayerId1 = 1;
582     const auto kLayerId2 = 2;
583     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                                   });
599     setTransactionStates({unsignaledTransaction, signaledTransaction},
600                          kExpectedTransactionsPending);
601 }
602 
TEST_F(LatchUnsignaledAutoSingleLayerTest,Flush_KeepsTransactionInTheQueue)603 TEST_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;
609     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},
626                          kExpectedTransactionsPending);
627 }
628 
TEST_F(LatchUnsignaledAutoSingleLayerTest,DontLatchUnsignaledWhenEarlyOffset)629 TEST_F(LatchUnsignaledAutoSingleLayerTest, DontLatchUnsignaledWhenEarlyOffset) {
630     const sp<IBinder> kApplyToken =
631             IInterface::asBinder(TransactionCompletedListener::getIInstance());
632     const auto kLayerId = 1;
633     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 
643     modulateVsync();
644     setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
645 }
646 
TEST_F(LatchUnsignaledAutoSingleLayerTest,UnsignaledNotAppliedWhenThereAreSignaled_SignaledFirst)647 TEST_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 
682 class LatchUnsignaledDisabledTest : public LatchUnsignaledTest {
683 public:
SetUp()684     void SetUp() override {
685         LatchUnsignaledTest::SetUp();
686         SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Disabled;
687     }
688 };
689 
TEST_F(LatchUnsignaledDisabledTest,Flush_RemovesSignaledFromTheQueue)690 TEST_F(LatchUnsignaledDisabledTest, Flush_RemovesSignaledFromTheQueue) {
691     const sp<IBinder> kApplyToken =
692             IInterface::asBinder(TransactionCompletedListener::getIInstance());
693     const auto kLayerId = 1;
694     const auto kExpectedTransactionsPending = 0u;
695 
696     const auto signaledTransaction =
697             createTransactionInfo(kApplyToken,
698                                   {createComposerState(kLayerId, fence(Fence::Status::Signaled),
699                                                        layer_state_t::eBufferChanged)});
700     setTransactionStates({signaledTransaction}, kExpectedTransactionsPending);
701 }
702 
TEST_F(LatchUnsignaledDisabledTest,Flush_KeepsInTheQueue)703 TEST_F(LatchUnsignaledDisabledTest, Flush_KeepsInTheQueue) {
704     const sp<IBinder> kApplyToken =
705             IInterface::asBinder(TransactionCompletedListener::getIInstance());
706     const auto kLayerId = 1;
707     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                                   });
716     setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
717 }
718 
TEST_F(LatchUnsignaledDisabledTest,Flush_KeepsInTheQueueSameLayerId)719 TEST_F(LatchUnsignaledDisabledTest, Flush_KeepsInTheQueueSameLayerId) {
720     const sp<IBinder> kApplyToken =
721             IInterface::asBinder(TransactionCompletedListener::getIInstance());
722     const auto kLayerId = 1;
723     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                                   });
735     setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
736 }
737 
TEST_F(LatchUnsignaledDisabledTest,Flush_KeepsInTheQueueDifferentLayerId)738 TEST_F(LatchUnsignaledDisabledTest, Flush_KeepsInTheQueueDifferentLayerId) {
739     const sp<IBinder> kApplyToken =
740             IInterface::asBinder(TransactionCompletedListener::getIInstance());
741     const auto kLayerId1 = 1;
742     const auto kLayerId2 = 2;
743     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                                   });
755     setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
756 }
757 
TEST_F(LatchUnsignaledDisabledTest,Flush_RemovesSignaledFromTheQueue_MultipleLayers)758 TEST_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;
763     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                                   });
779     setTransactionStates({signaledTransaction, signaledTransaction2}, kExpectedTransactionsPending);
780 }
781 
TEST_F(LatchUnsignaledDisabledTest,Flush_KeepInTheQueueDifferentApplyToken)782 TEST_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;
788     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                                   });
804     setTransactionStates({unsignaledTransaction, signaledTransaction},
805                          kExpectedTransactionsPending);
806 }
807 
TEST_F(LatchUnsignaledDisabledTest,Flush_KeepInTheQueueSameApplyToken)808 TEST_F(LatchUnsignaledDisabledTest, Flush_KeepInTheQueueSameApplyToken) {
809     const sp<IBinder> kApplyToken =
810             IInterface::asBinder(TransactionCompletedListener::getIInstance());
811     const auto kLayerId1 = 1;
812     const auto kLayerId2 = 2;
813     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                                   });
829     setTransactionStates({signaledTransaction, unsignaledTransaction},
830                          kExpectedTransactionsPending);
831 }
832 
TEST_F(LatchUnsignaledDisabledTest,Flush_KeepInTheUnsignaledTheQueue)833 TEST_F(LatchUnsignaledDisabledTest, Flush_KeepInTheUnsignaledTheQueue) {
834     const sp<IBinder> kApplyToken =
835             IInterface::asBinder(TransactionCompletedListener::getIInstance());
836     const auto kLayerId1 = 1;
837     const auto kLayerId2 = 2;
838     const auto kExpectedTransactionsPending = 2u;
839 
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},
855                          kExpectedTransactionsPending);
856 }
857 
858 class LatchUnsignaledAlwaysTest : public LatchUnsignaledTest {
859 public:
SetUp()860     void SetUp() override {
861         LatchUnsignaledTest::SetUp();
862         SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Always;
863     }
864 };
865 
TEST_F(LatchUnsignaledAlwaysTest,Flush_RemovesSignaledFromTheQueue)866 TEST_F(LatchUnsignaledAlwaysTest, Flush_RemovesSignaledFromTheQueue) {
867     const sp<IBinder> kApplyToken =
868             IInterface::asBinder(TransactionCompletedListener::getIInstance());
869     const auto kLayerId = 1;
870     const auto kExpectedTransactionsPending = 0u;
871 
872     const auto signaledTransaction =
873             createTransactionInfo(kApplyToken,
874                                   {createComposerState(kLayerId, fence(Fence::Status::Signaled),
875                                                        layer_state_t::eBufferChanged)});
876     setTransactionStates({signaledTransaction}, kExpectedTransactionsPending);
877 }
878 
TEST_F(LatchUnsignaledAlwaysTest,Flush_RemovesFromTheQueue)879 TEST_F(LatchUnsignaledAlwaysTest, Flush_RemovesFromTheQueue) {
880     const sp<IBinder> kApplyToken =
881             IInterface::asBinder(TransactionCompletedListener::getIInstance());
882     const auto kLayerId = 1;
883     const auto kExpectedTransactionsPending = 0u;
884 
885     const auto unsignaledTransaction =
886             createTransactionInfo(kApplyToken,
887                                   {createComposerState(kLayerId, fence(Fence::Status::Unsignaled),
888                                                        layer_state_t::eBufferChanged)});
889     setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
890 }
891 
TEST_F(LatchUnsignaledAlwaysTest,Flush_RemovesFromTheQueueSameLayerId)892 TEST_F(LatchUnsignaledAlwaysTest, Flush_RemovesFromTheQueueSameLayerId) {
893     const sp<IBinder> kApplyToken =
894             IInterface::asBinder(TransactionCompletedListener::getIInstance());
895     const auto kLayerId = 1;
896     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)});
904     setTransactionStates({mixedTransaction}, kExpectedTransactionsPending);
905 }
906 
TEST_F(LatchUnsignaledAlwaysTest,Flush_RemovesFromTheQueueDifferentLayerId)907 TEST_F(LatchUnsignaledAlwaysTest, Flush_RemovesFromTheQueueDifferentLayerId) {
908     const sp<IBinder> kApplyToken =
909             IInterface::asBinder(TransactionCompletedListener::getIInstance());
910     const auto kLayerId1 = 1;
911     const auto kLayerId2 = 2;
912     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)});
920     setTransactionStates({mixedTransaction}, kExpectedTransactionsPending);
921 }
922 
TEST_F(LatchUnsignaledAlwaysTest,Flush_RemovesSignaledFromTheQueue_MultipleLayers)923 TEST_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;
928     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                                   });
944     setTransactionStates({signaledTransaction, signaledTransaction2}, kExpectedTransactionsPending);
945 }
946 
TEST_F(LatchUnsignaledAlwaysTest,Flush_RemovesFromTheQueueDifferentApplyToken)947 TEST_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;
953     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                                   });
969     setTransactionStates({signaledTransaction, unsignaledTransaction},
970                          kExpectedTransactionsPending);
971 }
972 
TEST_F(LatchUnsignaledAlwaysTest,Flush_RemovesUnsignaledFromTheQueueSameApplyToken)973 TEST_F(LatchUnsignaledAlwaysTest, Flush_RemovesUnsignaledFromTheQueueSameApplyToken) {
974     const sp<IBinder> kApplyToken =
975             IInterface::asBinder(TransactionCompletedListener::getIInstance());
976     const auto kLayerId1 = 1;
977     const auto kLayerId2 = 2;
978     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                                   });
994     setTransactionStates({unsignaledTransaction, signaledTransaction},
995                          kExpectedTransactionsPending);
996 }
997 
TEST_F(LatchUnsignaledAlwaysTest,Flush_RemovesUnsignaledFromTheQueue)998 TEST_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;
1004     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},
1021                          kExpectedTransactionsPending);
1022 }
1023 
TEST_F(LatchUnsignaledAlwaysTest,RespectsBackPressureFlag)1024 TEST_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 
TEST_F(LatchUnsignaledAlwaysTest,LatchUnsignaledWhenEarlyOffset)1061 TEST_F(LatchUnsignaledAlwaysTest, LatchUnsignaledWhenEarlyOffset) {
1062     const sp<IBinder> kApplyToken =
1063             IInterface::asBinder(TransactionCompletedListener::getIInstance());
1064     const auto kLayerId = 1;
1065     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 
1075     modulateVsync();
1076     setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
1077 }
1078 
TEST(TransactionHandlerTest,QueueTransaction)1079 TEST(TransactionHandlerTest, QueueTransaction) {
1080     TransactionHandler handler;
1081     TransactionState transaction;
1082     transaction.applyToken = sp<BBinder>::make();
1083     transaction.id = 42;
1084     handler.queueTransaction(std::move(transaction));
1085     std::vector<TransactionState> transactionsReadyToBeApplied = handler.flushTransactions();
1086 
1087     EXPECT_EQ(transactionsReadyToBeApplied.size(), 1u);
1088     EXPECT_EQ(transactionsReadyToBeApplied.front().id, 42u);
1089 }
1090 
TEST(TransactionHandlerTest,TransactionsKeepTrackOfDirectMerges)1091 TEST(TransactionHandlerTest, TransactionsKeepTrackOfDirectMerges) {
1092     SurfaceComposerClient::Transaction transaction1, transaction2, transaction3, transaction4;
1093 
1094     uint64_t transaction2Id = transaction2.getId();
1095     uint64_t transaction3Id = transaction3.getId();
1096     EXPECT_NE(transaction2Id, transaction3Id);
1097 
1098     transaction1.merge(std::move(transaction2));
1099     transaction1.merge(std::move(transaction3));
1100 
1101     EXPECT_EQ(transaction1.getMergedTransactionIds().size(), 2u);
1102     EXPECT_EQ(transaction1.getMergedTransactionIds()[0], transaction3Id);
1103     EXPECT_EQ(transaction1.getMergedTransactionIds()[1], transaction2Id);
1104 }
1105 
TEST(TransactionHandlerTest,TransactionsKeepTrackOfIndirectMerges)1106 TEST(TransactionHandlerTest, TransactionsKeepTrackOfIndirectMerges) {
1107     SurfaceComposerClient::Transaction transaction1, transaction2, transaction3, transaction4;
1108 
1109     uint64_t transaction2Id = transaction2.getId();
1110     uint64_t transaction3Id = transaction3.getId();
1111     uint64_t transaction4Id = transaction4.getId();
1112     EXPECT_NE(transaction2Id, transaction3Id);
1113     EXPECT_NE(transaction2Id, transaction4Id);
1114     EXPECT_NE(transaction3Id, transaction4Id);
1115 
1116     transaction4.merge(std::move(transaction2));
1117     transaction4.merge(std::move(transaction3));
1118 
1119     EXPECT_EQ(transaction4.getMergedTransactionIds().size(), 2u);
1120     EXPECT_EQ(transaction4.getMergedTransactionIds()[0], transaction3Id);
1121     EXPECT_EQ(transaction4.getMergedTransactionIds()[1], transaction2Id);
1122 
1123     transaction1.merge(std::move(transaction4));
1124 
1125     EXPECT_EQ(transaction1.getMergedTransactionIds().size(), 3u);
1126     EXPECT_EQ(transaction1.getMergedTransactionIds()[0], transaction4Id);
1127     EXPECT_EQ(transaction1.getMergedTransactionIds()[1], transaction3Id);
1128     EXPECT_EQ(transaction1.getMergedTransactionIds()[2], transaction2Id);
1129 }
1130 
TEST(TransactionHandlerTest,TransactionMergesAreCleared)1131 TEST(TransactionHandlerTest, TransactionMergesAreCleared) {
1132     SurfaceComposerClient::Transaction transaction1, transaction2, transaction3;
1133 
1134     transaction1.merge(std::move(transaction2));
1135     transaction1.merge(std::move(transaction3));
1136 
1137     EXPECT_EQ(transaction1.getMergedTransactionIds().size(), 2u);
1138 
1139     transaction1.clear();
1140 
1141     EXPECT_EQ(transaction1.getMergedTransactionIds().empty(), true);
1142 }
1143 
TEST(TransactionHandlerTest,TransactionMergesAreCapped)1144 TEST(TransactionHandlerTest, TransactionMergesAreCapped) {
1145     SurfaceComposerClient::Transaction transaction;
1146     std::vector<uint64_t> mergedTransactionIds;
1147 
1148     for (uint i = 0; i < 20u; i++) {
1149         SurfaceComposerClient::Transaction transactionToMerge;
1150         mergedTransactionIds.push_back(transactionToMerge.getId());
1151         transaction.merge(std::move(transactionToMerge));
1152     }
1153 
1154     // Keeps latest 10 merges in order of merge recency
1155     EXPECT_EQ(transaction.getMergedTransactionIds().size(), 10u);
1156     for (uint i = 0; i < 10u; i++) {
1157         EXPECT_EQ(transaction.getMergedTransactionIds()[i],
1158                   mergedTransactionIds[mergedTransactionIds.size() - 1 - i]);
1159     }
1160 }
1161 
TEST(TransactionHandlerTest,KeepsMergesFromMoreRecentMerge)1162 TEST(TransactionHandlerTest, KeepsMergesFromMoreRecentMerge) {
1163     SurfaceComposerClient::Transaction transaction1, transaction2, transaction3;
1164     std::vector<uint64_t> mergedTransactionIds1, mergedTransactionIds2, mergedTransactionIds3;
1165     uint64_t transaction2Id = transaction2.getId();
1166     uint64_t transaction3Id = transaction3.getId();
1167 
1168     for (uint i = 0; i < 20u; i++) {
1169         SurfaceComposerClient::Transaction transactionToMerge;
1170         mergedTransactionIds1.push_back(transactionToMerge.getId());
1171         transaction1.merge(std::move(transactionToMerge));
1172     }
1173 
1174     for (uint i = 0; i < 5u; i++) {
1175         SurfaceComposerClient::Transaction transactionToMerge;
1176         mergedTransactionIds2.push_back(transactionToMerge.getId());
1177         transaction2.merge(std::move(transactionToMerge));
1178     }
1179 
1180     transaction1.merge(std::move(transaction2));
1181     EXPECT_EQ(transaction1.getMergedTransactionIds().size(), 10u);
1182     EXPECT_EQ(transaction1.getMergedTransactionIds()[0], transaction2Id);
1183     for (uint i = 0; i < 5u; i++) {
1184         EXPECT_EQ(transaction1.getMergedTransactionIds()[i + 1u],
1185                   mergedTransactionIds2[mergedTransactionIds2.size() - 1 - i]);
1186     }
1187     for (uint i = 0; i < 4u; i++) {
1188         EXPECT_EQ(transaction1.getMergedTransactionIds()[i + 6u],
1189                   mergedTransactionIds1[mergedTransactionIds1.size() - 1 - i]);
1190     }
1191 
1192     for (uint i = 0; i < 20u; i++) {
1193         SurfaceComposerClient::Transaction transactionToMerge;
1194         mergedTransactionIds3.push_back(transactionToMerge.getId());
1195         transaction3.merge(std::move(transactionToMerge));
1196     }
1197 
1198     transaction1.merge(std::move(transaction3));
1199     EXPECT_EQ(transaction1.getMergedTransactionIds().size(), 10u);
1200     EXPECT_EQ(transaction1.getMergedTransactionIds()[0], transaction3Id);
1201     for (uint i = 0; i < 9u; i++) {
1202         EXPECT_EQ(transaction1.getMergedTransactionIds()[i + 1],
1203                   mergedTransactionIds3[mergedTransactionIds3.size() - 1 - i]);
1204     }
1205 }
1206 
TEST(TransactionHandlerTest,CanAddTransactionWithFullMergedIds)1207 TEST(TransactionHandlerTest, CanAddTransactionWithFullMergedIds) {
1208     SurfaceComposerClient::Transaction transaction1, transaction2;
1209     for (uint i = 0; i < 20u; i++) {
1210         SurfaceComposerClient::Transaction transactionToMerge;
1211         transaction1.merge(std::move(transactionToMerge));
1212     }
1213 
1214     EXPECT_EQ(transaction1.getMergedTransactionIds().size(), 10u);
1215 
1216     auto transaction1Id = transaction1.getId();
1217     transaction2.merge(std::move(transaction1));
1218     EXPECT_EQ(transaction2.getMergedTransactionIds().size(), 10u);
1219     auto mergedTransactionIds = transaction2.getMergedTransactionIds();
1220     EXPECT_TRUE(std::count(mergedTransactionIds.begin(), mergedTransactionIds.end(),
1221                            transaction1Id) > 0);
1222 }
1223 
1224 } // namespace android
1225