• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, releaseCallback.getCallback());
89         t.addTransactionCompletedCallback(callback.function, callback.getContext());
90         t.apply();
91     }
92 
waitForCallback(CallbackHelper & helper,const ExpectedResult & expectedResult)93     static void waitForCallback(CallbackHelper& helper, const ExpectedResult& expectedResult) {
94         CallbackData callbackData;
95         helper.getCallbackData(&callbackData);
96         expectedResult.verifyCallbackData(callbackData);
97     }
98 
waitForReleaseBufferCallback(ReleaseBufferCallbackHelper & releaseCallback,const ReleaseCallbackId & expectedReleaseBufferId)99     static void waitForReleaseBufferCallback(ReleaseBufferCallbackHelper& releaseCallback,
100                                              const ReleaseCallbackId& expectedReleaseBufferId) {
101         ReleaseCallbackId actualReleaseBufferId;
102         releaseCallback.getCallbackData(&actualReleaseBufferId);
103         EXPECT_EQ(expectedReleaseBufferId, actualReleaseBufferId);
104         releaseCallback.verifyNoCallbacks();
105     }
getReleaseBufferCallbackHelper()106     static ReleaseBufferCallbackHelper* getReleaseBufferCallbackHelper() {
107         static std::vector<ReleaseBufferCallbackHelper*> sCallbacks;
108         sCallbacks.emplace_back(new ReleaseBufferCallbackHelper());
109         return sCallbacks.back();
110     }
111 
getBuffer()112     static sp<GraphicBuffer> getBuffer() {
113         return new GraphicBuffer(32, 32, PIXEL_FORMAT_RGBA_8888, 1,
114                                  BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
115                                          BufferUsage::COMPOSER_OVERLAY,
116                                  "test");
117     }
generateFrameNumber()118     static uint64_t generateFrameNumber() {
119         static uint64_t sFrameNumber = 0;
120         return ++sFrameNumber;
121     }
122 };
123 
TEST_F(ReleaseBufferCallbackTest,DISABLED_PresentBuffer)124 TEST_F(ReleaseBufferCallbackTest, DISABLED_PresentBuffer) {
125     sp<SurfaceControl> layer = createBufferStateLayer();
126     CallbackHelper transactionCallback;
127     ReleaseBufferCallbackHelper* releaseCallback = getReleaseBufferCallbackHelper();
128 
129     // If a buffer is being presented, we should not emit a release callback.
130     sp<GraphicBuffer> firstBuffer = getBuffer();
131     ReleaseCallbackId firstBufferCallbackId(firstBuffer->getId(), generateFrameNumber());
132     submitBuffer(layer, firstBuffer, Fence::NO_FENCE, transactionCallback, firstBufferCallbackId,
133                  *releaseCallback);
134     ExpectedResult expected;
135     expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer,
136                         ExpectedResult::Buffer::NOT_ACQUIRED);
137     ASSERT_NO_FATAL_FAILURE(waitForCallback(transactionCallback, expected));
138     EXPECT_NO_FATAL_FAILURE(releaseCallback->verifyNoCallbacks());
139 
140     // if state doesn't change, no release callbacks are expected
141     Transaction t;
142     t.addTransactionCompletedCallback(transactionCallback.function,
143                                       transactionCallback.getContext());
144     t.apply();
145     ASSERT_NO_FATAL_FAILURE(waitForCallback(transactionCallback, ExpectedResult()));
146     EXPECT_NO_FATAL_FAILURE(releaseCallback->verifyNoCallbacks());
147 
148     // If a presented buffer is replaced, we should emit a release callback for the
149     // previously presented buffer.
150     sp<GraphicBuffer> secondBuffer = getBuffer();
151     ReleaseCallbackId secondBufferCallbackId(secondBuffer->getId(), generateFrameNumber());
152     submitBuffer(layer, secondBuffer, Fence::NO_FENCE, transactionCallback, secondBufferCallbackId,
153                  *releaseCallback);
154     expected = ExpectedResult();
155     expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer,
156                         ExpectedResult::Buffer::NOT_ACQUIRED,
157                         ExpectedResult::PreviousBuffer::RELEASED);
158     ASSERT_NO_FATAL_FAILURE(waitForCallback(transactionCallback, expected));
159     ASSERT_NO_FATAL_FAILURE(waitForReleaseBufferCallback(*releaseCallback, firstBufferCallbackId));
160 }
161 
TEST_F(ReleaseBufferCallbackTest,DISABLED_OffScreenLayer)162 TEST_F(ReleaseBufferCallbackTest, DISABLED_OffScreenLayer) {
163     sp<SurfaceControl> layer = createBufferStateLayer();
164 
165     CallbackHelper transactionCallback;
166     ReleaseBufferCallbackHelper* releaseCallback = getReleaseBufferCallbackHelper();
167 
168     // If a buffer is being presented, we should not emit a release callback.
169     sp<GraphicBuffer> firstBuffer = getBuffer();
170     ReleaseCallbackId firstBufferCallbackId(firstBuffer->getId(), generateFrameNumber());
171     submitBuffer(layer, firstBuffer, Fence::NO_FENCE, transactionCallback, firstBufferCallbackId,
172                  *releaseCallback);
173     ExpectedResult expected;
174     expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer,
175                         ExpectedResult::Buffer::NOT_ACQUIRED);
176     ASSERT_NO_FATAL_FAILURE(waitForCallback(transactionCallback, expected));
177     releaseCallback->verifyNoCallbacks();
178 
179     // If a layer is parented offscreen then it should not emit a callback since sf still owns
180     // the buffer and can render it again.
181     Transaction t;
182     t.reparent(layer, nullptr);
183     t.addTransactionCompletedCallback(transactionCallback.function,
184                                       transactionCallback.getContext());
185     t.apply();
186     expected = ExpectedResult();
187     expected.addSurface(ExpectedResult::Transaction::NOT_PRESENTED, layer,
188                         ExpectedResult::Buffer::NOT_ACQUIRED,
189                         ExpectedResult::PreviousBuffer::NOT_RELEASED);
190     ASSERT_NO_FATAL_FAILURE(waitForCallback(transactionCallback, expected));
191     ASSERT_NO_FATAL_FAILURE(releaseCallback->verifyNoCallbacks());
192 
193     // If a presented buffer is replaced, we should emit a release callback for the
194     // previously presented buffer.
195     sp<GraphicBuffer> secondBuffer = getBuffer();
196     ReleaseCallbackId secondBufferCallbackId(secondBuffer->getId(), generateFrameNumber());
197     submitBuffer(layer, secondBuffer, Fence::NO_FENCE, transactionCallback, secondBufferCallbackId,
198                  *releaseCallback);
199     expected = ExpectedResult();
200     expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer,
201                         ExpectedResult::Buffer::NOT_ACQUIRED,
202                         ExpectedResult::PreviousBuffer::NOT_RELEASED);
203     ASSERT_NO_FATAL_FAILURE(waitForCallback(transactionCallback, expected));
204     ASSERT_NO_FATAL_FAILURE(waitForReleaseBufferCallback(*releaseCallback, firstBufferCallbackId));
205 
206     // If continue to submit buffer we continue to get release callbacks
207     sp<GraphicBuffer> thirdBuffer = getBuffer();
208     ReleaseCallbackId thirdBufferCallbackId(secondBuffer->getId(), generateFrameNumber());
209     submitBuffer(layer, thirdBuffer, Fence::NO_FENCE, transactionCallback, thirdBufferCallbackId,
210                  *releaseCallback);
211     expected = ExpectedResult();
212     expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer,
213                         ExpectedResult::Buffer::NOT_ACQUIRED,
214                         ExpectedResult::PreviousBuffer::NOT_RELEASED);
215     ASSERT_NO_FATAL_FAILURE(waitForCallback(transactionCallback, expected));
216     ASSERT_NO_FATAL_FAILURE(waitForReleaseBufferCallback(*releaseCallback, secondBufferCallbackId));
217 }
218 
TEST_F(ReleaseBufferCallbackTest,DISABLED_LayerLifecycle_layerdestroy)219 TEST_F(ReleaseBufferCallbackTest, DISABLED_LayerLifecycle_layerdestroy) {
220     sp<SurfaceControl> layer = createBufferStateLayer();
221     CallbackHelper* transactionCallback = new CallbackHelper();
222     ReleaseBufferCallbackHelper* releaseCallback = getReleaseBufferCallbackHelper();
223 
224     // If a buffer is being presented, we should not emit a release callback.
225     sp<GraphicBuffer> firstBuffer = getBuffer();
226     ReleaseCallbackId firstBufferCallbackId(firstBuffer->getId(), generateFrameNumber());
227     submitBuffer(layer, firstBuffer, Fence::NO_FENCE, *transactionCallback, firstBufferCallbackId,
228                  *releaseCallback);
229     {
230         ExpectedResult expected;
231         expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer,
232                             ExpectedResult::Buffer::NOT_ACQUIRED);
233         ASSERT_NO_FATAL_FAILURE(waitForCallback(*transactionCallback, expected));
234         ASSERT_NO_FATAL_FAILURE(releaseCallback->verifyNoCallbacks());
235     }
236 
237     // Destroying a currently presenting layer emits a callback.
238     Transaction t;
239     t.reparent(layer, nullptr);
240     t.apply();
241     layer = nullptr;
242 
243     ASSERT_NO_FATAL_FAILURE(waitForReleaseBufferCallback(*releaseCallback, firstBufferCallbackId));
244 }
245 
246 // Destroying a never presented layer emits a callback.
TEST_F(ReleaseBufferCallbackTest,DISABLED_LayerLifecycle_OffScreenLayerDestroy)247 TEST_F(ReleaseBufferCallbackTest, DISABLED_LayerLifecycle_OffScreenLayerDestroy) {
248     sp<SurfaceControl> layer = createBufferStateLayer();
249 
250     // make layer offscreen
251     Transaction t;
252     t.reparent(layer, nullptr);
253     t.apply();
254 
255     CallbackHelper* transactionCallback = new CallbackHelper();
256     ReleaseBufferCallbackHelper* releaseCallback = getReleaseBufferCallbackHelper();
257 
258     // Submitting a buffer does not emit a callback.
259     sp<GraphicBuffer> firstBuffer = getBuffer();
260     ReleaseCallbackId firstBufferCallbackId(firstBuffer->getId(), generateFrameNumber());
261     submitBuffer(layer, firstBuffer, Fence::NO_FENCE, *transactionCallback, firstBufferCallbackId,
262                  *releaseCallback);
263     {
264         ExpectedResult expected;
265         expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer,
266                             ExpectedResult::Buffer::NOT_ACQUIRED);
267         ASSERT_NO_FATAL_FAILURE(waitForCallback(*transactionCallback, expected));
268         ASSERT_NO_FATAL_FAILURE(releaseCallback->verifyNoCallbacks());
269     }
270 
271     // Submitting a second buffer will replace the drawing state buffer and emit a callback.
272     sp<GraphicBuffer> secondBuffer = getBuffer();
273     ReleaseCallbackId secondBufferCallbackId(secondBuffer->getId(), generateFrameNumber());
274     submitBuffer(layer, secondBuffer, Fence::NO_FENCE, *transactionCallback, secondBufferCallbackId,
275                  *releaseCallback);
276     {
277         ExpectedResult expected;
278         expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer,
279                             ExpectedResult::Buffer::NOT_ACQUIRED);
280         ASSERT_NO_FATAL_FAILURE(waitForCallback(*transactionCallback, expected));
281         ASSERT_NO_FATAL_FAILURE(
282                 waitForReleaseBufferCallback(*releaseCallback, firstBufferCallbackId));
283     }
284 
285     // Destroying the offscreen layer emits a callback.
286     layer = nullptr;
287     ASSERT_NO_FATAL_FAILURE(waitForReleaseBufferCallback(*releaseCallback, secondBufferCallbackId));
288 }
289 
TEST_F(ReleaseBufferCallbackTest,DISABLED_FrameDropping)290 TEST_F(ReleaseBufferCallbackTest, DISABLED_FrameDropping) {
291     sp<SurfaceControl> layer = createBufferStateLayer();
292     CallbackHelper transactionCallback;
293     ReleaseBufferCallbackHelper* releaseCallback = getReleaseBufferCallbackHelper();
294 
295     // If a buffer is being presented, we should not emit a release callback.
296     sp<GraphicBuffer> firstBuffer = getBuffer();
297     ReleaseCallbackId firstBufferCallbackId(firstBuffer->getId(), generateFrameNumber());
298 
299     // Try to present 100ms in the future
300     nsecs_t time = systemTime() + std::chrono::nanoseconds(100ms).count();
301 
302     Transaction t;
303     t.setBuffer(layer, firstBuffer, std::nullopt, firstBufferCallbackId.framenumber,
304                 releaseCallback->getCallback());
305     t.addTransactionCompletedCallback(transactionCallback.function,
306                                       transactionCallback.getContext());
307     t.setDesiredPresentTime(time);
308     t.apply();
309 
310     ExpectedResult expected;
311     expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer,
312                         ExpectedResult::Buffer::NOT_ACQUIRED);
313     ASSERT_NO_FATAL_FAILURE(waitForCallback(transactionCallback, expected));
314     EXPECT_NO_FATAL_FAILURE(releaseCallback->verifyNoCallbacks());
315 
316     // Dropping frames in transaction queue emits a callback
317     sp<GraphicBuffer> secondBuffer = getBuffer();
318     ReleaseCallbackId secondBufferCallbackId(secondBuffer->getId(), generateFrameNumber());
319     t.setBuffer(layer, secondBuffer, std::nullopt, secondBufferCallbackId.framenumber,
320                 releaseCallback->getCallback());
321     t.addTransactionCompletedCallback(transactionCallback.function,
322                                       transactionCallback.getContext());
323     t.setDesiredPresentTime(time);
324     t.apply();
325 
326     expected = ExpectedResult();
327     expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer,
328                         ExpectedResult::Buffer::NOT_ACQUIRED,
329                         ExpectedResult::PreviousBuffer::RELEASED);
330     ASSERT_NO_FATAL_FAILURE(waitForCallback(transactionCallback, expected));
331     ASSERT_NO_FATAL_FAILURE(waitForReleaseBufferCallback(*releaseCallback, firstBufferCallbackId));
332 }
333 
TEST_F(ReleaseBufferCallbackTest,DISABLED_Merge_Different_Processes)334 TEST_F(ReleaseBufferCallbackTest, DISABLED_Merge_Different_Processes) {
335     sp<TransactionCompletedListener> firstCompletedListener = new TransactionCompletedListener();
336     sp<TransactionCompletedListener> secondCompletedListener = new TransactionCompletedListener();
337 
338     CallbackHelper callback1, callback2;
339 
340     TransactionCompletedListener::setInstance(firstCompletedListener);
341 
342     sp<SurfaceControl> layer = createBufferStateLayer();
343     ReleaseBufferCallbackHelper* releaseCallback = getReleaseBufferCallbackHelper();
344 
345     sp<GraphicBuffer> firstBuffer = getBuffer();
346     ReleaseCallbackId firstBufferCallbackId(firstBuffer->getId(), generateFrameNumber());
347 
348     // Send initial buffer for the layer
349     submitBuffer(layer, firstBuffer, Fence::NO_FENCE, callback1, firstBufferCallbackId,
350                  *releaseCallback);
351 
352     ExpectedResult expected;
353     expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer,
354                         ExpectedResult::Buffer::NOT_ACQUIRED);
355     ASSERT_NO_FATAL_FAILURE(waitForCallback(callback1, expected));
356 
357     // Sent a second buffer to allow the first buffer to get released.
358     sp<GraphicBuffer> secondBuffer = getBuffer();
359     ReleaseCallbackId secondBufferCallbackId(secondBuffer->getId(), generateFrameNumber());
360 
361     Transaction transaction1;
362     transaction1.setBuffer(layer, secondBuffer, std::nullopt, secondBufferCallbackId.framenumber,
363                            releaseCallback->getCallback());
364     transaction1.addTransactionCompletedCallback(callback1.function, callback1.getContext());
365 
366     // Set a different TransactionCompletedListener to mimic a second process
367     TransactionCompletedListener::setInstance(secondCompletedListener);
368 
369     // Make sure the second "process" has a callback set up.
370     Transaction transaction2;
371     transaction2.addTransactionCompletedCallback(callback2.function, callback2.getContext());
372 
373     // This merging order, merge transaction1 first then transaction2, seems to ensure the listener
374     // for transaction2 is ordered first. This makes sure the wrong process is added first to the
375     // layer's vector of listeners. With the bug, only the secondCompletedListener will get the
376     // release callback id, since it's ordered first. Then firstCompletedListener would fail to get
377     // the release callback id and not invoke the release callback.
378     Transaction().merge(std::move(transaction1)).merge(std::move(transaction2)).apply();
379 
380     expected = ExpectedResult();
381     expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer,
382                         ExpectedResult::Buffer::NOT_ACQUIRED,
383                         ExpectedResult::PreviousBuffer::RELEASED);
384     ASSERT_NO_FATAL_FAILURE(waitForCallback(callback1, expected));
385     ASSERT_NO_FATAL_FAILURE(waitForReleaseBufferCallback(*releaseCallback, firstBufferCallbackId));
386 }
387 
TEST_F(ReleaseBufferCallbackTest,DISABLED_SetBuffer_OverwriteBuffers)388 TEST_F(ReleaseBufferCallbackTest, DISABLED_SetBuffer_OverwriteBuffers) {
389     sp<SurfaceControl> layer = createBufferStateLayer();
390     ReleaseBufferCallbackHelper* releaseCallback = getReleaseBufferCallbackHelper();
391 
392     sp<GraphicBuffer> firstBuffer = getBuffer();
393     ReleaseCallbackId firstBufferCallbackId(firstBuffer->getId(), generateFrameNumber());
394 
395     // Create transaction with a buffer.
396     Transaction transaction;
397     transaction.setBuffer(layer, firstBuffer, std::nullopt, firstBufferCallbackId.framenumber,
398                           releaseCallback->getCallback());
399 
400     sp<GraphicBuffer> secondBuffer = getBuffer();
401     ReleaseCallbackId secondBufferCallbackId(secondBuffer->getId(), generateFrameNumber());
402 
403     // Call setBuffer on the same transaction with a different buffer.
404     transaction.setBuffer(layer, secondBuffer, std::nullopt, secondBufferCallbackId.framenumber,
405                           releaseCallback->getCallback());
406 
407     ASSERT_NO_FATAL_FAILURE(waitForReleaseBufferCallback(*releaseCallback, firstBufferCallbackId));
408 }
409 
TEST_F(ReleaseBufferCallbackTest,DISABLED_Merge_Transactions_OverwriteBuffers)410 TEST_F(ReleaseBufferCallbackTest, DISABLED_Merge_Transactions_OverwriteBuffers) {
411     sp<SurfaceControl> layer = createBufferStateLayer();
412     ReleaseBufferCallbackHelper* releaseCallback = getReleaseBufferCallbackHelper();
413 
414     sp<GraphicBuffer> firstBuffer = getBuffer();
415     ReleaseCallbackId firstBufferCallbackId(firstBuffer->getId(), generateFrameNumber());
416 
417     // Create transaction with a buffer.
418     Transaction transaction1;
419     transaction1.setBuffer(layer, firstBuffer, std::nullopt, firstBufferCallbackId.framenumber,
420                            releaseCallback->getCallback());
421 
422     sp<GraphicBuffer> secondBuffer = getBuffer();
423     ReleaseCallbackId secondBufferCallbackId(secondBuffer->getId(), generateFrameNumber());
424 
425     // Create a second transaction with a new buffer for the same layer.
426     Transaction transaction2;
427     transaction2.setBuffer(layer, secondBuffer, std::nullopt, secondBufferCallbackId.framenumber,
428                            releaseCallback->getCallback());
429 
430     // merge transaction1 into transaction2 so ensure we get a proper buffer release callback.
431     transaction1.merge(std::move(transaction2));
432     ASSERT_NO_FATAL_FAILURE(waitForReleaseBufferCallback(*releaseCallback, firstBufferCallbackId));
433 }
434 
TEST_F(ReleaseBufferCallbackTest,DISABLED_MergeBuffers_Different_Processes)435 TEST_F(ReleaseBufferCallbackTest, DISABLED_MergeBuffers_Different_Processes) {
436     sp<TransactionCompletedListener> firstCompletedListener = new TransactionCompletedListener();
437     sp<TransactionCompletedListener> secondCompletedListener = new TransactionCompletedListener();
438 
439     TransactionCompletedListener::setInstance(firstCompletedListener);
440 
441     sp<SurfaceControl> layer = createBufferStateLayer();
442     ReleaseBufferCallbackHelper* releaseCallback = getReleaseBufferCallbackHelper();
443 
444     sp<GraphicBuffer> firstBuffer = getBuffer();
445     ReleaseCallbackId firstBufferCallbackId(firstBuffer->getId(), generateFrameNumber());
446 
447     Transaction transaction1;
448     transaction1.setBuffer(layer, firstBuffer, std::nullopt, firstBufferCallbackId.framenumber,
449                            releaseCallback->getCallback());
450 
451     // Sent a second buffer to allow the first buffer to get released.
452     sp<GraphicBuffer> secondBuffer = getBuffer();
453     ReleaseCallbackId secondBufferCallbackId(secondBuffer->getId(), generateFrameNumber());
454 
455     Transaction transaction2;
456     transaction2.setBuffer(layer, secondBuffer, std::nullopt, secondBufferCallbackId.framenumber,
457                            releaseCallback->getCallback());
458 
459     // Set a different TransactionCompletedListener to mimic a second process
460     TransactionCompletedListener::setInstance(secondCompletedListener);
461     Transaction().merge(std::move(transaction1)).merge(std::move(transaction2)).apply();
462 
463     // Make sure we can still get the release callback even though the merge happened in a different
464     // process.
465     ASSERT_NO_FATAL_FAILURE(waitForReleaseBufferCallback(*releaseCallback, firstBufferCallbackId));
466 }
467 
TEST_F(ReleaseBufferCallbackTest,SetBuffer_OverwriteBuffersWithNull)468 TEST_F(ReleaseBufferCallbackTest, SetBuffer_OverwriteBuffersWithNull) {
469     sp<SurfaceControl> layer = createBufferStateLayer();
470     ReleaseBufferCallbackHelper* releaseCallback = getReleaseBufferCallbackHelper();
471 
472     sp<GraphicBuffer> firstBuffer = getBuffer();
473     ReleaseCallbackId firstBufferCallbackId(firstBuffer->getId(), generateFrameNumber());
474 
475     // Create transaction with a buffer.
476     Transaction transaction;
477     transaction.setBuffer(layer, firstBuffer, std::nullopt, firstBufferCallbackId.framenumber,
478                           releaseCallback->getCallback());
479 
480     // Call setBuffer on the same transaction with a null buffer.
481     transaction.setBuffer(layer, nullptr, std::nullopt, 0, releaseCallback->getCallback());
482 
483     ASSERT_NO_FATAL_FAILURE(waitForReleaseBufferCallback(*releaseCallback, firstBufferCallbackId));
484 }
485 
486 } // namespace android
487