xref: /aosp_15_r20/frameworks/native/services/surfaceflinger/tests/ReleaseBufferCallback_test.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1 /*
2  * Copyright (C) 2021 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 #include <gui/test/CallbackUtils.h>
18 #include "LayerTransactionTest.h"
19 
20 using namespace std::chrono_literals;
21 
22 namespace android {
23 
24 using android::hardware::graphics::common::V1_1::BufferUsage;
25 
26 ::testing::Environment* const binderEnv =
27         ::testing::AddGlobalTestEnvironment(new BinderEnvironment());
28 
29 // b/181132765 - disabled until cuttlefish failures are investigated
30 class ReleaseBufferCallbackHelper {
31 public:
function(void * callbackContext,ReleaseCallbackId callbackId,const sp<Fence> & releaseFence,std::optional<uint32_t>)32     static void function(void* callbackContext, ReleaseCallbackId callbackId,
33                          const sp<Fence>& releaseFence,
34                          std::optional<uint32_t> /*currentMaxAcquiredBufferCount*/) {
35         if (!callbackContext) {
36             FAIL() << "failed to get callback context";
37         }
38         ReleaseBufferCallbackHelper* helper =
39                 static_cast<ReleaseBufferCallbackHelper*>(callbackContext);
40         std::lock_guard lock(helper->mMutex);
41         helper->mCallbackDataQueue.emplace(callbackId, releaseFence);
42         helper->mConditionVariable.notify_all();
43     }
44 
getCallbackData(ReleaseCallbackId * callbackId)45     void getCallbackData(ReleaseCallbackId* callbackId) {
46         std::unique_lock lock(mMutex);
47         if (mCallbackDataQueue.empty()) {
48             if (!mConditionVariable.wait_for(lock, std::chrono::seconds(3),
49                                              [&] { return !mCallbackDataQueue.empty(); })) {
50                 FAIL() << "failed to get releaseBuffer callback";
51             }
52         }
53 
54         auto callbackData = mCallbackDataQueue.front();
55         mCallbackDataQueue.pop();
56         *callbackId = callbackData.first;
57     }
58 
verifyNoCallbacks()59     void verifyNoCallbacks() {
60         // Wait to see if there are extra callbacks
61         std::this_thread::sleep_for(300ms);
62 
63         std::lock_guard lock(mMutex);
64         EXPECT_EQ(mCallbackDataQueue.size(), 0U) << "extra callbacks received";
65         mCallbackDataQueue = {};
66     }
67 
getCallback()68     android::ReleaseBufferCallback getCallback() {
69         return std::bind(function, static_cast<void*>(this) /* callbackContext */,
70                          std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
71     }
72 
73     std::mutex mMutex;
74     std::condition_variable mConditionVariable;
75     std::queue<std::pair<ReleaseCallbackId, sp<Fence>>> mCallbackDataQueue;
76 };
77 
78 class ReleaseBufferCallbackTest : public LayerTransactionTest {
79 public:
createBufferStateLayer()80     virtual sp<SurfaceControl> createBufferStateLayer() {
81         return createLayer(mClient, "test", 0, 0, ISurfaceComposerClient::eFXSurfaceBufferState);
82     }
83 
submitBuffer(const sp<SurfaceControl> & layer,sp<GraphicBuffer> buffer,sp<Fence> fence,CallbackHelper & callback,const ReleaseCallbackId & id,ReleaseBufferCallbackHelper & releaseCallback)84     static void submitBuffer(const sp<SurfaceControl>& layer, sp<GraphicBuffer> buffer,
85                              sp<Fence> fence, CallbackHelper& callback, const ReleaseCallbackId& id,
86                              ReleaseBufferCallbackHelper& releaseCallback) {
87         Transaction t;
88         t.setBuffer(layer, buffer, fence, id.framenumber, 0 /* producerId */,
89                     releaseCallback.getCallback());
90         t.addTransactionCompletedCallback(callback.function, callback.getContext());
91         t.apply();
92     }
93 
waitForCallback(CallbackHelper & helper,const ExpectedResult & expectedResult)94     static void waitForCallback(CallbackHelper& helper, const ExpectedResult& expectedResult) {
95         CallbackData callbackData;
96         helper.getCallbackData(&callbackData);
97         expectedResult.verifyCallbackData(callbackData);
98     }
99 
waitForReleaseBufferCallback(ReleaseBufferCallbackHelper & releaseCallback,const ReleaseCallbackId & expectedReleaseBufferId)100     static void waitForReleaseBufferCallback(ReleaseBufferCallbackHelper& releaseCallback,
101                                              const ReleaseCallbackId& expectedReleaseBufferId) {
102         ReleaseCallbackId actualReleaseBufferId;
103         releaseCallback.getCallbackData(&actualReleaseBufferId);
104         EXPECT_EQ(expectedReleaseBufferId, actualReleaseBufferId);
105         releaseCallback.verifyNoCallbacks();
106     }
getReleaseBufferCallbackHelper()107     static ReleaseBufferCallbackHelper* getReleaseBufferCallbackHelper() {
108         static std::vector<ReleaseBufferCallbackHelper*> sCallbacks;
109         sCallbacks.emplace_back(new ReleaseBufferCallbackHelper());
110         return sCallbacks.back();
111     }
112 
getBuffer()113     static sp<GraphicBuffer> getBuffer() {
114         return sp<GraphicBuffer>::make(32u, 32u, PIXEL_FORMAT_RGBA_8888, 1u,
115                                        BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
116                                                BufferUsage::COMPOSER_OVERLAY,
117                                        "test");
118     }
generateFrameNumber()119     static uint64_t generateFrameNumber() {
120         static uint64_t sFrameNumber = 0;
121         return ++sFrameNumber;
122     }
123 };
124 
TEST_F(ReleaseBufferCallbackTest,DISABLED_PresentBuffer)125 TEST_F(ReleaseBufferCallbackTest, DISABLED_PresentBuffer) {
126     sp<SurfaceControl> layer = createBufferStateLayer();
127     CallbackHelper transactionCallback;
128     ReleaseBufferCallbackHelper* releaseCallback = getReleaseBufferCallbackHelper();
129 
130     // If a buffer is being presented, we should not emit a release callback.
131     sp<GraphicBuffer> firstBuffer = getBuffer();
132     ReleaseCallbackId firstBufferCallbackId(firstBuffer->getId(), generateFrameNumber());
133     submitBuffer(layer, firstBuffer, Fence::NO_FENCE, transactionCallback, firstBufferCallbackId,
134                  *releaseCallback);
135     ExpectedResult expected;
136     expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer,
137                         ExpectedResult::Buffer::NOT_ACQUIRED);
138     ASSERT_NO_FATAL_FAILURE(waitForCallback(transactionCallback, expected));
139     EXPECT_NO_FATAL_FAILURE(releaseCallback->verifyNoCallbacks());
140 
141     // if state doesn't change, no release callbacks are expected
142     Transaction t;
143     t.addTransactionCompletedCallback(transactionCallback.function,
144                                       transactionCallback.getContext());
145     t.apply();
146     ASSERT_NO_FATAL_FAILURE(waitForCallback(transactionCallback, ExpectedResult()));
147     EXPECT_NO_FATAL_FAILURE(releaseCallback->verifyNoCallbacks());
148 
149     // If a presented buffer is replaced, we should emit a release callback for the
150     // previously presented buffer.
151     sp<GraphicBuffer> secondBuffer = getBuffer();
152     ReleaseCallbackId secondBufferCallbackId(secondBuffer->getId(), generateFrameNumber());
153     submitBuffer(layer, secondBuffer, Fence::NO_FENCE, transactionCallback, secondBufferCallbackId,
154                  *releaseCallback);
155     expected = ExpectedResult();
156     expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer,
157                         ExpectedResult::Buffer::NOT_ACQUIRED,
158                         ExpectedResult::PreviousBuffer::RELEASED);
159     ASSERT_NO_FATAL_FAILURE(waitForCallback(transactionCallback, expected));
160     ASSERT_NO_FATAL_FAILURE(waitForReleaseBufferCallback(*releaseCallback, firstBufferCallbackId));
161 }
162 
TEST_F(ReleaseBufferCallbackTest,DISABLED_OffScreenLayer)163 TEST_F(ReleaseBufferCallbackTest, DISABLED_OffScreenLayer) {
164     sp<SurfaceControl> layer = createBufferStateLayer();
165 
166     CallbackHelper transactionCallback;
167     ReleaseBufferCallbackHelper* releaseCallback = getReleaseBufferCallbackHelper();
168 
169     // If a buffer is being presented, we should not emit a release callback.
170     sp<GraphicBuffer> firstBuffer = getBuffer();
171     ReleaseCallbackId firstBufferCallbackId(firstBuffer->getId(), generateFrameNumber());
172     submitBuffer(layer, firstBuffer, Fence::NO_FENCE, transactionCallback, firstBufferCallbackId,
173                  *releaseCallback);
174     ExpectedResult expected;
175     expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer,
176                         ExpectedResult::Buffer::NOT_ACQUIRED);
177     ASSERT_NO_FATAL_FAILURE(waitForCallback(transactionCallback, expected));
178     releaseCallback->verifyNoCallbacks();
179 
180     // If a layer is parented offscreen then it should not emit a callback since sf still owns
181     // the buffer and can render it again.
182     Transaction t;
183     t.reparent(layer, nullptr);
184     t.addTransactionCompletedCallback(transactionCallback.function,
185                                       transactionCallback.getContext());
186     t.apply();
187     expected = ExpectedResult();
188     expected.addSurface(ExpectedResult::Transaction::NOT_PRESENTED, layer,
189                         ExpectedResult::Buffer::NOT_ACQUIRED,
190                         ExpectedResult::PreviousBuffer::NOT_RELEASED);
191     ASSERT_NO_FATAL_FAILURE(waitForCallback(transactionCallback, expected));
192     ASSERT_NO_FATAL_FAILURE(releaseCallback->verifyNoCallbacks());
193 
194     // If a presented buffer is replaced, we should emit a release callback for the
195     // previously presented buffer.
196     sp<GraphicBuffer> secondBuffer = getBuffer();
197     ReleaseCallbackId secondBufferCallbackId(secondBuffer->getId(), generateFrameNumber());
198     submitBuffer(layer, secondBuffer, Fence::NO_FENCE, transactionCallback, secondBufferCallbackId,
199                  *releaseCallback);
200     expected = ExpectedResult();
201     expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer,
202                         ExpectedResult::Buffer::NOT_ACQUIRED,
203                         ExpectedResult::PreviousBuffer::NOT_RELEASED);
204     ASSERT_NO_FATAL_FAILURE(waitForCallback(transactionCallback, expected));
205     ASSERT_NO_FATAL_FAILURE(waitForReleaseBufferCallback(*releaseCallback, firstBufferCallbackId));
206 
207     // If continue to submit buffer we continue to get release callbacks
208     sp<GraphicBuffer> thirdBuffer = getBuffer();
209     ReleaseCallbackId thirdBufferCallbackId(secondBuffer->getId(), generateFrameNumber());
210     submitBuffer(layer, thirdBuffer, Fence::NO_FENCE, transactionCallback, thirdBufferCallbackId,
211                  *releaseCallback);
212     expected = ExpectedResult();
213     expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer,
214                         ExpectedResult::Buffer::NOT_ACQUIRED,
215                         ExpectedResult::PreviousBuffer::NOT_RELEASED);
216     ASSERT_NO_FATAL_FAILURE(waitForCallback(transactionCallback, expected));
217     ASSERT_NO_FATAL_FAILURE(waitForReleaseBufferCallback(*releaseCallback, secondBufferCallbackId));
218 }
219 
TEST_F(ReleaseBufferCallbackTest,DISABLED_LayerLifecycle_layerdestroy)220 TEST_F(ReleaseBufferCallbackTest, DISABLED_LayerLifecycle_layerdestroy) {
221     sp<SurfaceControl> layer = createBufferStateLayer();
222     CallbackHelper* transactionCallback = new CallbackHelper();
223     ReleaseBufferCallbackHelper* releaseCallback = getReleaseBufferCallbackHelper();
224 
225     // If a buffer is being presented, we should not emit a release callback.
226     sp<GraphicBuffer> firstBuffer = getBuffer();
227     ReleaseCallbackId firstBufferCallbackId(firstBuffer->getId(), generateFrameNumber());
228     submitBuffer(layer, firstBuffer, Fence::NO_FENCE, *transactionCallback, firstBufferCallbackId,
229                  *releaseCallback);
230     {
231         ExpectedResult expected;
232         expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer,
233                             ExpectedResult::Buffer::NOT_ACQUIRED);
234         ASSERT_NO_FATAL_FAILURE(waitForCallback(*transactionCallback, expected));
235         ASSERT_NO_FATAL_FAILURE(releaseCallback->verifyNoCallbacks());
236     }
237 
238     // Destroying a currently presenting layer emits a callback.
239     Transaction t;
240     t.reparent(layer, nullptr);
241     t.apply();
242     layer = nullptr;
243 
244     ASSERT_NO_FATAL_FAILURE(waitForReleaseBufferCallback(*releaseCallback, firstBufferCallbackId));
245 }
246 
247 // Destroying a never presented layer emits a callback.
TEST_F(ReleaseBufferCallbackTest,DISABLED_LayerLifecycle_OffScreenLayerDestroy)248 TEST_F(ReleaseBufferCallbackTest, DISABLED_LayerLifecycle_OffScreenLayerDestroy) {
249     sp<SurfaceControl> layer = createBufferStateLayer();
250 
251     // make layer offscreen
252     Transaction t;
253     t.reparent(layer, nullptr);
254     t.apply();
255 
256     CallbackHelper* transactionCallback = new CallbackHelper();
257     ReleaseBufferCallbackHelper* releaseCallback = getReleaseBufferCallbackHelper();
258 
259     // Submitting a buffer does not emit a callback.
260     sp<GraphicBuffer> firstBuffer = getBuffer();
261     ReleaseCallbackId firstBufferCallbackId(firstBuffer->getId(), generateFrameNumber());
262     submitBuffer(layer, firstBuffer, Fence::NO_FENCE, *transactionCallback, firstBufferCallbackId,
263                  *releaseCallback);
264     {
265         ExpectedResult expected;
266         expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer,
267                             ExpectedResult::Buffer::NOT_ACQUIRED);
268         ASSERT_NO_FATAL_FAILURE(waitForCallback(*transactionCallback, expected));
269         ASSERT_NO_FATAL_FAILURE(releaseCallback->verifyNoCallbacks());
270     }
271 
272     // Submitting a second buffer will replace the drawing state buffer and emit a callback.
273     sp<GraphicBuffer> secondBuffer = getBuffer();
274     ReleaseCallbackId secondBufferCallbackId(secondBuffer->getId(), generateFrameNumber());
275     submitBuffer(layer, secondBuffer, Fence::NO_FENCE, *transactionCallback, secondBufferCallbackId,
276                  *releaseCallback);
277     {
278         ExpectedResult expected;
279         expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer,
280                             ExpectedResult::Buffer::NOT_ACQUIRED);
281         ASSERT_NO_FATAL_FAILURE(waitForCallback(*transactionCallback, expected));
282         ASSERT_NO_FATAL_FAILURE(
283                 waitForReleaseBufferCallback(*releaseCallback, firstBufferCallbackId));
284     }
285 
286     // Destroying the offscreen layer emits a callback.
287     layer = nullptr;
288     ASSERT_NO_FATAL_FAILURE(waitForReleaseBufferCallback(*releaseCallback, secondBufferCallbackId));
289 }
290 
TEST_F(ReleaseBufferCallbackTest,DISABLED_FrameDropping)291 TEST_F(ReleaseBufferCallbackTest, DISABLED_FrameDropping) {
292     sp<SurfaceControl> layer = createBufferStateLayer();
293     CallbackHelper transactionCallback;
294     ReleaseBufferCallbackHelper* releaseCallback = getReleaseBufferCallbackHelper();
295 
296     // If a buffer is being presented, we should not emit a release callback.
297     sp<GraphicBuffer> firstBuffer = getBuffer();
298     ReleaseCallbackId firstBufferCallbackId(firstBuffer->getId(), generateFrameNumber());
299 
300     // Try to present 100ms in the future
301     nsecs_t time = systemTime() + std::chrono::nanoseconds(100ms).count();
302 
303     Transaction t;
304     t.setBuffer(layer, firstBuffer, std::nullopt, firstBufferCallbackId.framenumber,
305                 0 /* producerId */, releaseCallback->getCallback());
306     t.addTransactionCompletedCallback(transactionCallback.function,
307                                       transactionCallback.getContext());
308     t.setDesiredPresentTime(time);
309     t.apply();
310 
311     ExpectedResult expected;
312     expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer,
313                         ExpectedResult::Buffer::NOT_ACQUIRED);
314     ASSERT_NO_FATAL_FAILURE(waitForCallback(transactionCallback, expected));
315     EXPECT_NO_FATAL_FAILURE(releaseCallback->verifyNoCallbacks());
316 
317     // Dropping frames in transaction queue emits a callback
318     sp<GraphicBuffer> secondBuffer = getBuffer();
319     ReleaseCallbackId secondBufferCallbackId(secondBuffer->getId(), generateFrameNumber());
320     t.setBuffer(layer, secondBuffer, std::nullopt, secondBufferCallbackId.framenumber,
321                 0 /* producerId */, releaseCallback->getCallback());
322     t.addTransactionCompletedCallback(transactionCallback.function,
323                                       transactionCallback.getContext());
324     t.setDesiredPresentTime(time);
325     t.apply();
326 
327     expected = ExpectedResult();
328     expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer,
329                         ExpectedResult::Buffer::NOT_ACQUIRED,
330                         ExpectedResult::PreviousBuffer::RELEASED);
331     ASSERT_NO_FATAL_FAILURE(waitForCallback(transactionCallback, expected));
332     ASSERT_NO_FATAL_FAILURE(waitForReleaseBufferCallback(*releaseCallback, firstBufferCallbackId));
333 }
334 
TEST_F(ReleaseBufferCallbackTest,DISABLED_Merge_Different_Processes)335 TEST_F(ReleaseBufferCallbackTest, DISABLED_Merge_Different_Processes) {
336     sp<TransactionCompletedListener> firstCompletedListener =
337             sp<TransactionCompletedListener>::make();
338     sp<TransactionCompletedListener> secondCompletedListener =
339             sp<TransactionCompletedListener>::make();
340 
341     CallbackHelper callback1, callback2;
342 
343     TransactionCompletedListener::setInstance(firstCompletedListener);
344 
345     sp<SurfaceControl> layer = createBufferStateLayer();
346     ReleaseBufferCallbackHelper* releaseCallback = getReleaseBufferCallbackHelper();
347 
348     sp<GraphicBuffer> firstBuffer = getBuffer();
349     ReleaseCallbackId firstBufferCallbackId(firstBuffer->getId(), generateFrameNumber());
350 
351     // Send initial buffer for the layer
352     submitBuffer(layer, firstBuffer, Fence::NO_FENCE, callback1, firstBufferCallbackId,
353                  *releaseCallback);
354 
355     ExpectedResult expected;
356     expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer,
357                         ExpectedResult::Buffer::NOT_ACQUIRED);
358     ASSERT_NO_FATAL_FAILURE(waitForCallback(callback1, expected));
359 
360     // Sent a second buffer to allow the first buffer to get released.
361     sp<GraphicBuffer> secondBuffer = getBuffer();
362     ReleaseCallbackId secondBufferCallbackId(secondBuffer->getId(), generateFrameNumber());
363 
364     Transaction transaction1;
365     transaction1.setBuffer(layer, secondBuffer, std::nullopt, secondBufferCallbackId.framenumber,
366                            0 /* producerId */, releaseCallback->getCallback());
367     transaction1.addTransactionCompletedCallback(callback1.function, callback1.getContext());
368 
369     // Set a different TransactionCompletedListener to mimic a second process
370     TransactionCompletedListener::setInstance(secondCompletedListener);
371 
372     // Make sure the second "process" has a callback set up.
373     Transaction transaction2;
374     transaction2.addTransactionCompletedCallback(callback2.function, callback2.getContext());
375 
376     // This merging order, merge transaction1 first then transaction2, seems to ensure the listener
377     // for transaction2 is ordered first. This makes sure the wrong process is added first to the
378     // layer's vector of listeners. With the bug, only the secondCompletedListener will get the
379     // release callback id, since it's ordered first. Then firstCompletedListener would fail to get
380     // the release callback id and not invoke the release callback.
381     Transaction().merge(std::move(transaction1)).merge(std::move(transaction2)).apply();
382 
383     expected = ExpectedResult();
384     expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer,
385                         ExpectedResult::Buffer::NOT_ACQUIRED,
386                         ExpectedResult::PreviousBuffer::RELEASED);
387     ASSERT_NO_FATAL_FAILURE(waitForCallback(callback1, expected));
388     ASSERT_NO_FATAL_FAILURE(waitForReleaseBufferCallback(*releaseCallback, firstBufferCallbackId));
389 }
390 
TEST_F(ReleaseBufferCallbackTest,DISABLED_SetBuffer_OverwriteBuffers)391 TEST_F(ReleaseBufferCallbackTest, DISABLED_SetBuffer_OverwriteBuffers) {
392     sp<SurfaceControl> layer = createBufferStateLayer();
393     ReleaseBufferCallbackHelper* releaseCallback = getReleaseBufferCallbackHelper();
394 
395     sp<GraphicBuffer> firstBuffer = getBuffer();
396     ReleaseCallbackId firstBufferCallbackId(firstBuffer->getId(), generateFrameNumber());
397 
398     // Create transaction with a buffer.
399     Transaction transaction;
400     transaction.setBuffer(layer, firstBuffer, std::nullopt, firstBufferCallbackId.framenumber,
401                           0 /* producerId */, releaseCallback->getCallback());
402 
403     sp<GraphicBuffer> secondBuffer = getBuffer();
404     ReleaseCallbackId secondBufferCallbackId(secondBuffer->getId(), generateFrameNumber());
405 
406     // Call setBuffer on the same transaction with a different buffer.
407     transaction.setBuffer(layer, secondBuffer, std::nullopt, secondBufferCallbackId.framenumber,
408                           0 /* producerId */, releaseCallback->getCallback());
409 
410     ASSERT_NO_FATAL_FAILURE(waitForReleaseBufferCallback(*releaseCallback, firstBufferCallbackId));
411 }
412 
TEST_F(ReleaseBufferCallbackTest,DISABLED_Merge_Transactions_OverwriteBuffers)413 TEST_F(ReleaseBufferCallbackTest, DISABLED_Merge_Transactions_OverwriteBuffers) {
414     sp<SurfaceControl> layer = createBufferStateLayer();
415     ReleaseBufferCallbackHelper* releaseCallback = getReleaseBufferCallbackHelper();
416 
417     sp<GraphicBuffer> firstBuffer = getBuffer();
418     ReleaseCallbackId firstBufferCallbackId(firstBuffer->getId(), generateFrameNumber());
419 
420     // Create transaction with a buffer.
421     Transaction transaction1;
422     transaction1.setBuffer(layer, firstBuffer, std::nullopt, firstBufferCallbackId.framenumber,
423                            0 /* producerId */, releaseCallback->getCallback());
424 
425     sp<GraphicBuffer> secondBuffer = getBuffer();
426     ReleaseCallbackId secondBufferCallbackId(secondBuffer->getId(), generateFrameNumber());
427 
428     // Create a second transaction with a new buffer for the same layer.
429     Transaction transaction2;
430     transaction2.setBuffer(layer, secondBuffer, std::nullopt, secondBufferCallbackId.framenumber,
431                            0 /* producerId */, releaseCallback->getCallback());
432 
433     // merge transaction1 into transaction2 so ensure we get a proper buffer release callback.
434     transaction1.merge(std::move(transaction2));
435     ASSERT_NO_FATAL_FAILURE(waitForReleaseBufferCallback(*releaseCallback, firstBufferCallbackId));
436 }
437 
TEST_F(ReleaseBufferCallbackTest,DISABLED_MergeBuffers_Different_Processes)438 TEST_F(ReleaseBufferCallbackTest, DISABLED_MergeBuffers_Different_Processes) {
439     sp<TransactionCompletedListener> firstCompletedListener =
440             sp<TransactionCompletedListener>::make();
441     sp<TransactionCompletedListener> secondCompletedListener =
442             sp<TransactionCompletedListener>::make();
443 
444     TransactionCompletedListener::setInstance(firstCompletedListener);
445 
446     sp<SurfaceControl> layer = createBufferStateLayer();
447     ReleaseBufferCallbackHelper* releaseCallback = getReleaseBufferCallbackHelper();
448 
449     sp<GraphicBuffer> firstBuffer = getBuffer();
450     ReleaseCallbackId firstBufferCallbackId(firstBuffer->getId(), generateFrameNumber());
451 
452     Transaction transaction1;
453     transaction1.setBuffer(layer, firstBuffer, std::nullopt, firstBufferCallbackId.framenumber,
454                            0 /* producerId */, releaseCallback->getCallback());
455 
456     // Sent a second buffer to allow the first buffer to get released.
457     sp<GraphicBuffer> secondBuffer = getBuffer();
458     ReleaseCallbackId secondBufferCallbackId(secondBuffer->getId(), generateFrameNumber());
459 
460     Transaction transaction2;
461     transaction2.setBuffer(layer, secondBuffer, std::nullopt, secondBufferCallbackId.framenumber,
462                            0 /* producerId */, releaseCallback->getCallback());
463 
464     // Set a different TransactionCompletedListener to mimic a second process
465     TransactionCompletedListener::setInstance(secondCompletedListener);
466     Transaction().merge(std::move(transaction1)).merge(std::move(transaction2)).apply();
467 
468     // Make sure we can still get the release callback even though the merge happened in a different
469     // process.
470     ASSERT_NO_FATAL_FAILURE(waitForReleaseBufferCallback(*releaseCallback, firstBufferCallbackId));
471 }
472 
TEST_F(ReleaseBufferCallbackTest,SetBuffer_OverwriteBuffersWithNull)473 TEST_F(ReleaseBufferCallbackTest, SetBuffer_OverwriteBuffersWithNull) {
474     sp<SurfaceControl> layer = createBufferStateLayer();
475     ReleaseBufferCallbackHelper* releaseCallback = getReleaseBufferCallbackHelper();
476 
477     sp<GraphicBuffer> firstBuffer = getBuffer();
478     ReleaseCallbackId firstBufferCallbackId(firstBuffer->getId(), generateFrameNumber());
479 
480     // Create transaction with a buffer.
481     Transaction transaction;
482     transaction.setBuffer(layer, firstBuffer, std::nullopt, firstBufferCallbackId.framenumber,
483                           0 /* producerId */, releaseCallback->getCallback());
484 
485     // Call setBuffer on the same transaction with a null buffer.
486     transaction.setBuffer(layer, nullptr, std::nullopt, 0, 0 /* producerId */,
487                           releaseCallback->getCallback());
488 
489     ASSERT_NO_FATAL_FAILURE(waitForReleaseBufferCallback(*releaseCallback, firstBufferCallbackId));
490 }
491 
492 } // namespace android
493