xref: /aosp_15_r20/frameworks/native/libs/gui/tests/BufferQueue_test.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1 /*
2  * Copyright (C) 2012 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 #define LOG_TAG "BufferQueue_test"
18 //#define LOG_NDEBUG 0
19 
20 #include "Constants.h"
21 #include "MockConsumer.h"
22 
23 #include <gui/BufferItem.h>
24 #include <gui/BufferItemConsumer.h>
25 #include <gui/BufferQueue.h>
26 #include <gui/IProducerListener.h>
27 #include <gui/Surface.h>
28 
29 #include <ui/GraphicBuffer.h>
30 #include <ui/PictureProfileHandle.h>
31 
32 #include <android-base/properties.h>
33 
34 #include <binder/IPCThreadState.h>
35 #include <binder/IServiceManager.h>
36 #include <binder/ProcessState.h>
37 
38 #include <utils/String8.h>
39 #include <utils/threads.h>
40 
41 #include <system/window.h>
42 
43 #include <gmock/gmock.h>
44 #include <gtest/gtest.h>
45 
46 #include <future>
47 #include <thread>
48 
49 #include <com_android_graphics_libgui_flags.h>
50 
51 using namespace std::chrono_literals;
52 
IsCuttlefish()53 static bool IsCuttlefish() {
54     return ::android::base::GetProperty("ro.product.board", "") == "cutf";
55 }
56 
57 namespace android {
58 using namespace com::android::graphics::libgui;
59 
60 class BufferQueueTest : public ::testing::Test {
61 
62 public:
63 protected:
GetMinUndequeuedBufferCount(int * bufferCount)64     void GetMinUndequeuedBufferCount(int* bufferCount) {
65         ASSERT_TRUE(bufferCount != nullptr);
66         ASSERT_EQ(OK, mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
67                     bufferCount));
68         ASSERT_GE(*bufferCount, 0);
69     }
70 
createBufferQueue()71     void createBufferQueue() {
72         BufferQueue::createBufferQueue(&mProducer, &mConsumer);
73     }
74 
testBufferItem(const IGraphicBufferProducer::QueueBufferInput & input,const BufferItem & item)75     void testBufferItem(const IGraphicBufferProducer::QueueBufferInput& input,
76             const BufferItem& item) {
77         int64_t timestamp;
78         bool isAutoTimestamp;
79         android_dataspace dataSpace;
80         Rect crop;
81         int scalingMode;
82         uint32_t transform;
83         sp<Fence> fence;
84 
85         input.deflate(&timestamp, &isAutoTimestamp, &dataSpace, &crop,
86                 &scalingMode, &transform, &fence, nullptr);
87         ASSERT_EQ(timestamp, item.mTimestamp);
88         ASSERT_EQ(isAutoTimestamp, item.mIsAutoTimestamp);
89         ASSERT_EQ(dataSpace, item.mDataSpace);
90         ASSERT_EQ(crop, item.mCrop);
91         ASSERT_EQ(static_cast<uint32_t>(scalingMode), item.mScalingMode);
92         ASSERT_EQ(transform, item.mTransform);
93         ASSERT_EQ(fence, item.mFence);
94     }
95 
96     sp<IGraphicBufferProducer> mProducer;
97     sp<IGraphicBufferConsumer> mConsumer;
98 };
99 
100 static const uint32_t TEST_DATA = 0x12345678u;
101 
102 // XXX: Tests that fork a process to hold the BufferQueue must run before tests
103 // that use a local BufferQueue, or else Binder will get unhappy
104 //
105 // In one instance this was a crash in the createBufferQueue where the
106 // binder call to create a buffer allocator apparently got garbage back.
107 // See b/36592665.
TEST_F(BufferQueueTest,DISABLED_BufferQueueInAnotherProcess)108 TEST_F(BufferQueueTest, DISABLED_BufferQueueInAnotherProcess) {
109     const String16 PRODUCER_NAME = String16("BQTestProducer");
110     const String16 CONSUMER_NAME = String16("BQTestConsumer");
111 
112     pid_t forkPid = fork();
113     ASSERT_NE(forkPid, -1);
114 
115     if (forkPid == 0) {
116         // Child process
117         sp<IGraphicBufferProducer> producer;
118         sp<IGraphicBufferConsumer> consumer;
119         BufferQueue::createBufferQueue(&producer, &consumer);
120         sp<IServiceManager> serviceManager = defaultServiceManager();
121         serviceManager->addService(PRODUCER_NAME, IInterface::asBinder(producer));
122         serviceManager->addService(CONSUMER_NAME, IInterface::asBinder(consumer));
123         ProcessState::self()->startThreadPool();
124         IPCThreadState::self()->joinThreadPool();
125         LOG_ALWAYS_FATAL("Shouldn't be here");
126     }
127 
128     sp<IServiceManager> serviceManager = defaultServiceManager();
129     sp<IBinder> binderProducer = serviceManager->waitForService(PRODUCER_NAME);
130     mProducer = interface_cast<IGraphicBufferProducer>(binderProducer);
131     EXPECT_TRUE(mProducer != nullptr);
132     sp<IBinder> binderConsumer =
133         serviceManager->getService(CONSUMER_NAME);
134     mConsumer = interface_cast<IGraphicBufferConsumer>(binderConsumer);
135     EXPECT_TRUE(mConsumer != nullptr);
136 
137     sp<MockConsumer> mc(new MockConsumer);
138     ASSERT_EQ(OK, mConsumer->consumerConnect(mc, false));
139     IGraphicBufferProducer::QueueBufferOutput output;
140     ASSERT_EQ(OK,
141             mProducer->connect(nullptr, NATIVE_WINDOW_API_CPU, false, &output));
142 
143     int slot;
144     sp<Fence> fence;
145     sp<GraphicBuffer> buffer;
146     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
147               mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN,
148                                        nullptr, nullptr));
149     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
150 
151     uint32_t* dataIn;
152     ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
153             reinterpret_cast<void**>(&dataIn)));
154     *dataIn = TEST_DATA;
155     ASSERT_EQ(OK, buffer->unlock());
156 
157     IGraphicBufferProducer::QueueBufferInput input(0, false,
158             HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
159             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
160     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
161 
162     BufferItem item;
163     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
164 
165     uint32_t* dataOut;
166     ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
167             reinterpret_cast<void**>(&dataOut)));
168     ASSERT_EQ(*dataOut, TEST_DATA);
169     ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
170 }
171 
TEST_F(BufferQueueTest,GetMaxBufferCountInQueueBufferOutput_Succeeds)172 TEST_F(BufferQueueTest, GetMaxBufferCountInQueueBufferOutput_Succeeds) {
173     createBufferQueue();
174     sp<MockConsumer> mc(new MockConsumer);
175     mConsumer->consumerConnect(mc, false);
176     int bufferCount = 50;
177     mConsumer->setMaxBufferCount(bufferCount);
178 
179     IGraphicBufferProducer::QueueBufferOutput output;
180     mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, false, &output);
181     ASSERT_EQ(output.maxBufferCount, bufferCount);
182 }
183 
TEST_F(BufferQueueTest,AcquireBuffer_ExceedsMaxAcquireCount_Fails)184 TEST_F(BufferQueueTest, AcquireBuffer_ExceedsMaxAcquireCount_Fails) {
185     createBufferQueue();
186     sp<MockConsumer> mc(new MockConsumer);
187     mConsumer->consumerConnect(mc, false);
188     IGraphicBufferProducer::QueueBufferOutput qbo;
189     mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, false, &qbo);
190     mProducer->setMaxDequeuedBufferCount(3);
191 
192     int slot;
193     sp<Fence> fence;
194     sp<GraphicBuffer> buf;
195     IGraphicBufferProducer::QueueBufferInput qbi(0, false,
196             HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
197             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
198     BufferItem item;
199 
200     for (int i = 0; i < 2; i++) {
201         ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
202                   mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0, GRALLOC_USAGE_SW_READ_OFTEN,
203                                            nullptr, nullptr));
204         ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf));
205         ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo));
206         ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
207     }
208 
209     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
210               mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0, GRALLOC_USAGE_SW_READ_OFTEN,
211                                        nullptr, nullptr));
212     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf));
213     ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo));
214 
215     // Acquire the third buffer, which should fail.
216     ASSERT_EQ(INVALID_OPERATION, mConsumer->acquireBuffer(&item, 0));
217 }
218 
TEST_F(BufferQueueTest,SetMaxAcquiredBufferCountWithIllegalValues_ReturnsError)219 TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithIllegalValues_ReturnsError) {
220     createBufferQueue();
221     sp<MockConsumer> mc(new MockConsumer);
222     mConsumer->consumerConnect(mc, false);
223 
224     EXPECT_EQ(OK, mConsumer->setMaxBufferCount(10));
225     EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(10));
226 
227     IGraphicBufferProducer::QueueBufferOutput qbo;
228     mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, false, &qbo);
229     mProducer->setMaxDequeuedBufferCount(3);
230 
231     int minBufferCount;
232     ASSERT_NO_FATAL_FAILURE(GetMinUndequeuedBufferCount(&minBufferCount));
233     EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(
234                 minBufferCount - 1));
235 
236     EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(0));
237     EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(-3));
238     EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(
239             BufferQueue::MAX_MAX_ACQUIRED_BUFFERS+1));
240     EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(100));
241 
242     int slot;
243     sp<Fence> fence;
244     sp<GraphicBuffer> buf;
245     IGraphicBufferProducer::QueueBufferInput qbi(0, false,
246             HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
247             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
248     BufferItem item;
249     EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(3));
250     for (int i = 0; i < 3; i++) {
251         ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
252                   mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0, GRALLOC_USAGE_SW_READ_OFTEN,
253                                            nullptr, nullptr));
254         ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf));
255         ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo));
256         ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
257     }
258 
259     EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(2));
260 }
261 
TEST_F(BufferQueueTest,SetMaxAcquiredBufferCountWithLegalValues_Succeeds)262 TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithLegalValues_Succeeds) {
263     createBufferQueue();
264     sp<MockConsumer> mc(new MockConsumer);
265     mConsumer->consumerConnect(mc, false);
266 
267     IGraphicBufferProducer::QueueBufferOutput qbo;
268     mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, false, &qbo);
269     mProducer->setMaxDequeuedBufferCount(2);
270 
271     int minBufferCount;
272     ASSERT_NO_FATAL_FAILURE(GetMinUndequeuedBufferCount(&minBufferCount));
273 
274     EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(1));
275     EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(2));
276     EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(minBufferCount));
277 
278     int slot;
279     sp<Fence> fence;
280     sp<GraphicBuffer> buf;
281     IGraphicBufferProducer::QueueBufferInput qbi(0, false,
282             HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
283             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
284     BufferItem item;
285 
286     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
287               mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0, GRALLOC_USAGE_SW_READ_OFTEN,
288                                        nullptr, nullptr));
289     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf));
290     ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo));
291     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
292 
293     EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(3));
294 
295     for (int i = 0; i < 2; i++) {
296         ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
297                   mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0, GRALLOC_USAGE_SW_READ_OFTEN,
298                                            nullptr, nullptr));
299         ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf));
300         ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo));
301         ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
302     }
303 
304     EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(
305             BufferQueue::MAX_MAX_ACQUIRED_BUFFERS));
306 }
307 
TEST_F(BufferQueueTest,SetMaxBufferCountWithLegalValues_Succeeds)308 TEST_F(BufferQueueTest, SetMaxBufferCountWithLegalValues_Succeeds) {
309     createBufferQueue();
310     sp<MockConsumer> mc(new MockConsumer);
311     mConsumer->consumerConnect(mc, false);
312 
313     // Test shared buffer mode
314     EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(1));
315 }
316 
TEST_F(BufferQueueTest,SetMaxBufferCountWithIllegalValues_ReturnsError)317 TEST_F(BufferQueueTest, SetMaxBufferCountWithIllegalValues_ReturnsError) {
318     createBufferQueue();
319     sp<MockConsumer> mc(new MockConsumer);
320     mConsumer->consumerConnect(mc, false);
321 
322     EXPECT_EQ(BAD_VALUE, mConsumer->setMaxBufferCount(0));
323     EXPECT_EQ(BAD_VALUE, mConsumer->setMaxBufferCount(
324             BufferQueue::NUM_BUFFER_SLOTS + 1));
325 
326     EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(5));
327     EXPECT_EQ(BAD_VALUE, mConsumer->setMaxBufferCount(3));
328 }
329 
TEST_F(BufferQueueTest,DetachAndReattachOnProducerSide)330 TEST_F(BufferQueueTest, DetachAndReattachOnProducerSide) {
331     createBufferQueue();
332     sp<MockConsumer> mc(new MockConsumer);
333     ASSERT_EQ(OK, mConsumer->consumerConnect(mc, false));
334     IGraphicBufferProducer::QueueBufferOutput output;
335     ASSERT_EQ(OK,
336               mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, false, &output));
337 
338     ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(-1)); // Index too low
339     ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(
340                 BufferQueueDefs::NUM_BUFFER_SLOTS)); // Index too high
341     ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(0)); // Not dequeued
342 
343     int slot;
344     sp<Fence> fence;
345     sp<GraphicBuffer> buffer;
346     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
347               mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN,
348                                        nullptr, nullptr));
349     ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(slot)); // Not requested
350     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
351     ASSERT_EQ(OK, mProducer->detachBuffer(slot));
352     ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(slot)); // Not dequeued
353 
354     sp<GraphicBuffer> safeToClobberBuffer;
355     // Can no longer request buffer from this slot
356     ASSERT_EQ(BAD_VALUE, mProducer->requestBuffer(slot, &safeToClobberBuffer));
357 
358     uint32_t* dataIn;
359     ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
360             reinterpret_cast<void**>(&dataIn)));
361     *dataIn = TEST_DATA;
362     ASSERT_EQ(OK, buffer->unlock());
363 
364     int newSlot;
365     ASSERT_EQ(BAD_VALUE, mProducer->attachBuffer(nullptr, safeToClobberBuffer));
366     ASSERT_EQ(BAD_VALUE, mProducer->attachBuffer(&newSlot, nullptr));
367 
368     ASSERT_EQ(OK, mProducer->attachBuffer(&newSlot, buffer));
369     IGraphicBufferProducer::QueueBufferInput input(0, false,
370             HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
371             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
372     ASSERT_EQ(OK, mProducer->queueBuffer(newSlot, input, &output));
373 
374     BufferItem item;
375     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
376 
377     uint32_t* dataOut;
378     ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
379             reinterpret_cast<void**>(&dataOut)));
380     ASSERT_EQ(*dataOut, TEST_DATA);
381     ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
382 }
383 
TEST_F(BufferQueueTest,DetachAndReattachOnConsumerSide)384 TEST_F(BufferQueueTest, DetachAndReattachOnConsumerSide) {
385     createBufferQueue();
386     sp<MockConsumer> mc(new MockConsumer);
387     ASSERT_EQ(OK, mConsumer->consumerConnect(mc, false));
388     IGraphicBufferProducer::QueueBufferOutput output;
389     ASSERT_EQ(OK,
390               mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, false, &output));
391 
392     int slot;
393     sp<Fence> fence;
394     sp<GraphicBuffer> buffer;
395     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
396               mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN,
397                                        nullptr, nullptr));
398     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
399     IGraphicBufferProducer::QueueBufferInput input(0, false,
400             HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
401             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
402     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
403 
404     ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(-1)); // Index too low
405     ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(
406             BufferQueueDefs::NUM_BUFFER_SLOTS)); // Index too high
407     ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(0)); // Not acquired
408 
409     BufferItem item;
410     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
411 
412     ASSERT_EQ(OK, mConsumer->detachBuffer(item.mSlot));
413     ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(item.mSlot)); // Not acquired
414 
415     uint32_t* dataIn;
416     ASSERT_EQ(OK, item.mGraphicBuffer->lock(
417             GraphicBuffer::USAGE_SW_WRITE_OFTEN,
418             reinterpret_cast<void**>(&dataIn)));
419     *dataIn = TEST_DATA;
420     ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
421 
422     int newSlot;
423     sp<GraphicBuffer> safeToClobberBuffer;
424     ASSERT_EQ(BAD_VALUE, mConsumer->attachBuffer(nullptr, safeToClobberBuffer));
425     ASSERT_EQ(BAD_VALUE, mConsumer->attachBuffer(&newSlot, nullptr));
426     ASSERT_EQ(OK, mConsumer->attachBuffer(&newSlot, item.mGraphicBuffer));
427 
428     ASSERT_EQ(OK, mConsumer->releaseBuffer(newSlot, 0, Fence::NO_FENCE));
429 
430     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
431               mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN,
432                                        nullptr, nullptr));
433     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
434 
435     uint32_t* dataOut;
436     ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
437             reinterpret_cast<void**>(&dataOut)));
438     ASSERT_EQ(*dataOut, TEST_DATA);
439     ASSERT_EQ(OK, buffer->unlock());
440 }
441 
TEST_F(BufferQueueTest,MoveFromConsumerToProducer)442 TEST_F(BufferQueueTest, MoveFromConsumerToProducer) {
443     createBufferQueue();
444     sp<MockConsumer> mc(new MockConsumer);
445     ASSERT_EQ(OK, mConsumer->consumerConnect(mc, false));
446     IGraphicBufferProducer::QueueBufferOutput output;
447     ASSERT_EQ(OK,
448               mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, false, &output));
449 
450     int slot;
451     sp<Fence> fence;
452     sp<GraphicBuffer> buffer;
453     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
454               mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN,
455                                        nullptr, nullptr));
456     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
457 
458     uint32_t* dataIn;
459     ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
460             reinterpret_cast<void**>(&dataIn)));
461     *dataIn = TEST_DATA;
462     ASSERT_EQ(OK, buffer->unlock());
463 
464     IGraphicBufferProducer::QueueBufferInput input(0, false,
465             HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
466             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
467     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
468 
469     BufferItem item;
470     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
471     ASSERT_EQ(OK, mConsumer->detachBuffer(item.mSlot));
472 
473     int newSlot;
474     ASSERT_EQ(OK, mProducer->attachBuffer(&newSlot, item.mGraphicBuffer));
475     ASSERT_EQ(OK, mProducer->queueBuffer(newSlot, input, &output));
476     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
477 
478     uint32_t* dataOut;
479     ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
480             reinterpret_cast<void**>(&dataOut)));
481     ASSERT_EQ(*dataOut, TEST_DATA);
482     ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
483 }
484 
TEST_F(BufferQueueTest,TestDisallowingAllocation)485 TEST_F(BufferQueueTest, TestDisallowingAllocation) {
486     createBufferQueue();
487     sp<MockConsumer> mc(new MockConsumer);
488     ASSERT_EQ(OK, mConsumer->consumerConnect(mc, true));
489     IGraphicBufferProducer::QueueBufferOutput output;
490     ASSERT_EQ(OK,
491               mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, true, &output));
492 
493     static const uint32_t WIDTH = 320;
494     static const uint32_t HEIGHT = 240;
495 
496     ASSERT_EQ(OK, mConsumer->setDefaultBufferSize(WIDTH, HEIGHT));
497 
498     int slot;
499     sp<Fence> fence;
500     sp<GraphicBuffer> buffer;
501     // This should return an error since it would require an allocation
502     ASSERT_EQ(OK, mProducer->allowAllocation(false));
503     ASSERT_EQ(WOULD_BLOCK,
504               mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN,
505                                        nullptr, nullptr));
506 
507     // This should succeed, now that we've lifted the prohibition
508     ASSERT_EQ(OK, mProducer->allowAllocation(true));
509     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
510               mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN,
511                                        nullptr, nullptr));
512 
513     // Release the previous buffer back to the BufferQueue
514     mProducer->cancelBuffer(slot, fence);
515 
516     // This should fail since we're requesting a different size
517     ASSERT_EQ(OK, mProducer->allowAllocation(false));
518     ASSERT_EQ(WOULD_BLOCK,
519               mProducer->dequeueBuffer(&slot, &fence, WIDTH * 2, HEIGHT * 2, 0,
520                                        GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr, nullptr));
521 }
522 
TEST_F(BufferQueueTest,TestGenerationNumbers)523 TEST_F(BufferQueueTest, TestGenerationNumbers) {
524     createBufferQueue();
525     sp<MockConsumer> mc(new MockConsumer);
526     ASSERT_EQ(OK, mConsumer->consumerConnect(mc, true));
527     IGraphicBufferProducer::QueueBufferOutput output;
528     ASSERT_EQ(OK,
529               mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, true, &output));
530 
531     ASSERT_EQ(OK, mProducer->setGenerationNumber(1));
532 
533     // Get one buffer to play with
534     int slot;
535     sp<Fence> fence;
536     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
537               mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS, nullptr,
538                                        nullptr));
539 
540     sp<GraphicBuffer> buffer;
541     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
542 
543     // Ensure that the generation number we set propagates to allocated buffers
544     ASSERT_EQ(1U, buffer->getGenerationNumber());
545 
546     ASSERT_EQ(OK, mProducer->detachBuffer(slot));
547 
548     ASSERT_EQ(OK, mProducer->setGenerationNumber(2));
549 
550     // These should fail, since we've changed the generation number on the queue
551     int outSlot;
552     ASSERT_EQ(BAD_VALUE, mProducer->attachBuffer(&outSlot, buffer));
553     ASSERT_EQ(BAD_VALUE, mConsumer->attachBuffer(&outSlot, buffer));
554 
555     buffer->setGenerationNumber(2);
556 
557     // This should succeed now that we've changed the buffer's generation number
558     ASSERT_EQ(OK, mProducer->attachBuffer(&outSlot, buffer));
559 
560     ASSERT_EQ(OK, mProducer->detachBuffer(outSlot));
561 
562     // This should also succeed with the new generation number
563     ASSERT_EQ(OK, mConsumer->attachBuffer(&outSlot, buffer));
564 }
565 
TEST_F(BufferQueueTest,TestSharedBufferModeWithoutAutoRefresh)566 TEST_F(BufferQueueTest, TestSharedBufferModeWithoutAutoRefresh) {
567     createBufferQueue();
568     sp<MockConsumer> mc(new MockConsumer);
569     ASSERT_EQ(OK, mConsumer->consumerConnect(mc, true));
570     IGraphicBufferProducer::QueueBufferOutput output;
571     ASSERT_EQ(OK,
572               mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, true, &output));
573 
574     ASSERT_EQ(OK, mProducer->setSharedBufferMode(true));
575 
576     // Get a buffer
577     int sharedSlot;
578     sp<Fence> fence;
579     sp<GraphicBuffer> buffer;
580     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
581               mProducer->dequeueBuffer(&sharedSlot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS,
582                                        nullptr, nullptr));
583     ASSERT_EQ(OK, mProducer->requestBuffer(sharedSlot, &buffer));
584 
585     // Queue the buffer
586     IGraphicBufferProducer::QueueBufferInput input(0, false,
587             HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
588             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
589     ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output));
590 
591     // Repeatedly queue and dequeue a buffer from the producer side, it should
592     // always return the same one. And we won't run out of buffers because it's
593     // always the same one and because async mode gets enabled.
594     int slot;
595     for (int i = 0; i < 5; i++) {
596         ASSERT_EQ(OK,
597                   mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS,
598                                            nullptr, nullptr));
599         ASSERT_EQ(sharedSlot, slot);
600         ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output));
601     }
602 
603     // acquire the buffer
604     BufferItem item;
605     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
606     ASSERT_EQ(sharedSlot, item.mSlot);
607     testBufferItem(input, item);
608     ASSERT_EQ(true, item.mQueuedBuffer);
609     ASSERT_EQ(false, item.mAutoRefresh);
610 
611     ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber, Fence::NO_FENCE));
612 
613     // attempt to acquire a second time should return no buffer available
614     ASSERT_EQ(IGraphicBufferConsumer::NO_BUFFER_AVAILABLE,
615             mConsumer->acquireBuffer(&item, 0));
616 }
617 
TEST_F(BufferQueueTest,TestSharedBufferModeWithAutoRefresh)618 TEST_F(BufferQueueTest, TestSharedBufferModeWithAutoRefresh) {
619     createBufferQueue();
620     sp<MockConsumer> mc(new MockConsumer);
621     ASSERT_EQ(OK, mConsumer->consumerConnect(mc, true));
622     IGraphicBufferProducer::QueueBufferOutput output;
623     ASSERT_EQ(OK,
624               mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, true, &output));
625 
626     ASSERT_EQ(OK, mProducer->setSharedBufferMode(true));
627     ASSERT_EQ(OK, mProducer->setAutoRefresh(true));
628 
629     // Get a buffer
630     int sharedSlot;
631     sp<Fence> fence;
632     sp<GraphicBuffer> buffer;
633     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
634               mProducer->dequeueBuffer(&sharedSlot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS,
635                                        nullptr, nullptr));
636     ASSERT_EQ(OK, mProducer->requestBuffer(sharedSlot, &buffer));
637 
638     // Queue the buffer
639     IGraphicBufferProducer::QueueBufferInput input(0, false,
640             HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
641             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
642     ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output));
643 
644     // Repeatedly acquire and release a buffer from the consumer side, it should
645     // always return the same one.
646     BufferItem item;
647     for (int i = 0; i < 5; i++) {
648         ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
649         ASSERT_EQ(sharedSlot, item.mSlot);
650         testBufferItem(input, item);
651         ASSERT_EQ(i == 0, item.mQueuedBuffer);
652         ASSERT_EQ(true, item.mAutoRefresh);
653 
654         ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber, Fence::NO_FENCE));
655     }
656 
657     // Repeatedly queue and dequeue a buffer from the producer side, it should
658     // always return the same one.
659     int slot;
660     for (int i = 0; i < 5; i++) {
661         ASSERT_EQ(OK,
662                   mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS,
663                                            nullptr, nullptr));
664         ASSERT_EQ(sharedSlot, slot);
665         ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output));
666     }
667 
668     // Repeatedly acquire and release a buffer from the consumer side, it should
669     // always return the same one. First grabbing them from the queue and then
670     // when the queue is empty, returning the shared buffer.
671     for (int i = 0; i < 10; i++) {
672         ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
673         ASSERT_EQ(sharedSlot, item.mSlot);
674         ASSERT_EQ(0, item.mTimestamp);
675         ASSERT_EQ(false, item.mIsAutoTimestamp);
676         ASSERT_EQ(HAL_DATASPACE_UNKNOWN, item.mDataSpace);
677         ASSERT_EQ(Rect(0, 0, 1, 1), item.mCrop);
678         ASSERT_EQ(NATIVE_WINDOW_SCALING_MODE_FREEZE, item.mScalingMode);
679         ASSERT_EQ(0u, item.mTransform);
680         ASSERT_EQ(Fence::NO_FENCE, item.mFence);
681         ASSERT_EQ(i == 0, item.mQueuedBuffer);
682         ASSERT_EQ(true, item.mAutoRefresh);
683 
684         ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber, Fence::NO_FENCE));
685     }
686 }
687 
TEST_F(BufferQueueTest,TestSharedBufferModeUsingAlreadyDequeuedBuffer)688 TEST_F(BufferQueueTest, TestSharedBufferModeUsingAlreadyDequeuedBuffer) {
689     createBufferQueue();
690     sp<MockConsumer> mc(new MockConsumer);
691     ASSERT_EQ(OK, mConsumer->consumerConnect(mc, true));
692     IGraphicBufferProducer::QueueBufferOutput output;
693     ASSERT_EQ(OK,
694               mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, true, &output));
695 
696     // Dequeue a buffer
697     int sharedSlot;
698     sp<Fence> fence;
699     sp<GraphicBuffer> buffer;
700     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
701               mProducer->dequeueBuffer(&sharedSlot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS,
702                                        nullptr, nullptr));
703     ASSERT_EQ(OK, mProducer->requestBuffer(sharedSlot, &buffer));
704 
705     // Enable shared buffer mode
706     ASSERT_EQ(OK, mProducer->setSharedBufferMode(true));
707 
708     // Queue the buffer
709     IGraphicBufferProducer::QueueBufferInput input(0, false,
710             HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
711             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
712     ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output));
713 
714     // Repeatedly queue and dequeue a buffer from the producer side, it should
715     // always return the same one. And we won't run out of buffers because it's
716     // always the same one and because async mode gets enabled.
717     int slot;
718     for (int i = 0; i < 5; i++) {
719         ASSERT_EQ(OK,
720                   mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS,
721                                            nullptr, nullptr));
722         ASSERT_EQ(sharedSlot, slot);
723         ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output));
724     }
725 
726     // acquire the buffer
727     BufferItem item;
728     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
729     ASSERT_EQ(sharedSlot, item.mSlot);
730     testBufferItem(input, item);
731     ASSERT_EQ(true, item.mQueuedBuffer);
732     ASSERT_EQ(false, item.mAutoRefresh);
733 
734     ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber, Fence::NO_FENCE));
735 
736     // attempt to acquire a second time should return no buffer available
737     ASSERT_EQ(IGraphicBufferConsumer::NO_BUFFER_AVAILABLE,
738             mConsumer->acquireBuffer(&item, 0));
739 }
740 
TEST_F(BufferQueueTest,TestTimeouts)741 TEST_F(BufferQueueTest, TestTimeouts) {
742     createBufferQueue();
743     sp<MockConsumer> mc(new MockConsumer);
744     ASSERT_EQ(OK, mConsumer->consumerConnect(mc, true));
745     IGraphicBufferProducer::QueueBufferOutput output;
746     ASSERT_EQ(OK,
747               mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, true, &output));
748 
749     // Fill up the queue. Since the controlledByApp flags are set to true, this
750     // queue should be in non-blocking mode, and we should be recycling the same
751     // two buffers
752     for (int i = 0; i < 5; ++i) {
753         int slot = BufferQueue::INVALID_BUFFER_SLOT;
754         sp<Fence> fence = Fence::NO_FENCE;
755         auto result = mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS,
756                                                nullptr, nullptr);
757         if (i < 2) {
758             ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
759                     result);
760         } else {
761             ASSERT_EQ(OK, result);
762         }
763         sp<GraphicBuffer> buffer;
764         ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
765         IGraphicBufferProducer::QueueBufferInput input(0ull, true,
766                 HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
767                 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
768         IGraphicBufferProducer::QueueBufferOutput output{};
769         ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
770     }
771 
772     const auto TIMEOUT = ms2ns(250);
773     mProducer->setDequeueTimeout(TIMEOUT);
774 
775     // Setting a timeout will change the BufferQueue into blocking mode (with
776     // one droppable buffer in the queue and one free from the previous
777     // dequeue/queues), so dequeue and queue two more buffers: one to replace
778     // the current droppable buffer, and a second to max out the buffer count
779     sp<GraphicBuffer> buffer; // Save a buffer to attach later
780     for (int i = 0; i < 2; ++i) {
781         int slot = BufferQueue::INVALID_BUFFER_SLOT;
782         sp<Fence> fence = Fence::NO_FENCE;
783         ASSERT_EQ(OK,
784                   mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS,
785                                            nullptr, nullptr));
786         ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
787         IGraphicBufferProducer::QueueBufferInput input(0ull, true,
788                 HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
789                 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
790         ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
791     }
792 
793     int slot = BufferQueue::INVALID_BUFFER_SLOT;
794     sp<Fence> fence = Fence::NO_FENCE;
795     auto startTime = systemTime();
796     ASSERT_EQ(TIMED_OUT,
797               mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS, nullptr,
798                                        nullptr));
799     ASSERT_GE(systemTime() - startTime, TIMEOUT);
800 
801     // We're technically attaching the same buffer multiple times (since we
802     // queued it previously), but that doesn't matter for this test
803     startTime = systemTime();
804     ASSERT_EQ(TIMED_OUT, mProducer->attachBuffer(&slot, buffer));
805     ASSERT_GE(systemTime() - startTime, TIMEOUT);
806 }
807 
TEST_F(BufferQueueTest,CanAttachWhileDisallowingAllocation)808 TEST_F(BufferQueueTest, CanAttachWhileDisallowingAllocation) {
809     createBufferQueue();
810     sp<MockConsumer> mc(new MockConsumer);
811     ASSERT_EQ(OK, mConsumer->consumerConnect(mc, true));
812     IGraphicBufferProducer::QueueBufferOutput output;
813     ASSERT_EQ(OK,
814               mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, true, &output));
815 
816     int slot = BufferQueue::INVALID_BUFFER_SLOT;
817     sp<Fence> sourceFence;
818     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
819               mProducer->dequeueBuffer(&slot, &sourceFence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS,
820                                        nullptr, nullptr));
821     sp<GraphicBuffer> buffer;
822     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
823     ASSERT_EQ(OK, mProducer->detachBuffer(slot));
824 
825     ASSERT_EQ(OK, mProducer->allowAllocation(false));
826 
827     slot = BufferQueue::INVALID_BUFFER_SLOT;
828     ASSERT_EQ(OK, mProducer->attachBuffer(&slot, buffer));
829 }
830 
TEST_F(BufferQueueTest,CanRetrieveLastQueuedBuffer)831 TEST_F(BufferQueueTest, CanRetrieveLastQueuedBuffer) {
832     createBufferQueue();
833     sp<MockConsumer> mc(new MockConsumer);
834     ASSERT_EQ(OK, mConsumer->consumerConnect(mc, false));
835     IGraphicBufferProducer::QueueBufferOutput output;
836     ASSERT_EQ(OK,
837               mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, false, &output));
838 
839     // Dequeue and queue the first buffer, storing the handle
840     int slot = BufferQueue::INVALID_BUFFER_SLOT;
841     sp<Fence> fence;
842     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
843               mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS, nullptr,
844                                        nullptr));
845     sp<GraphicBuffer> firstBuffer;
846     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &firstBuffer));
847 
848     IGraphicBufferProducer::QueueBufferInput input(0ull, true,
849         HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
850         NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
851     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
852 
853     // Dequeue a second buffer
854     slot = BufferQueue::INVALID_BUFFER_SLOT;
855     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
856               mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS, nullptr,
857                                        nullptr));
858     sp<GraphicBuffer> secondBuffer;
859     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &secondBuffer));
860 
861     // Ensure it's a new buffer
862     ASSERT_NE(firstBuffer->getNativeBuffer()->handle,
863             secondBuffer->getNativeBuffer()->handle);
864 
865     // Queue the second buffer
866     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
867 
868     // Acquire and release both buffers
869     for (size_t i = 0; i < 2; ++i) {
870         BufferItem item;
871         ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
872         ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber, Fence::NO_FENCE));
873     }
874 
875     // Make sure we got the second buffer back
876     sp<GraphicBuffer> returnedBuffer;
877     sp<Fence> returnedFence;
878     float transform[16];
879     ASSERT_EQ(OK,
880             mProducer->getLastQueuedBuffer(&returnedBuffer, &returnedFence,
881             transform));
882     ASSERT_EQ(secondBuffer->getNativeBuffer()->handle,
883             returnedBuffer->getNativeBuffer()->handle);
884 }
885 
TEST_F(BufferQueueTest,TestOccupancyHistory)886 TEST_F(BufferQueueTest, TestOccupancyHistory) {
887     createBufferQueue();
888     sp<MockConsumer> mc(new MockConsumer);
889     ASSERT_EQ(OK, mConsumer->consumerConnect(mc, false));
890     IGraphicBufferProducer::QueueBufferOutput output;
891     ASSERT_EQ(OK,
892               mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, false, &output));
893 
894     int slot = BufferQueue::INVALID_BUFFER_SLOT;
895     sp<Fence> fence = Fence::NO_FENCE;
896     sp<GraphicBuffer> buffer = nullptr;
897     IGraphicBufferProducer::QueueBufferInput input(0ull, true,
898         HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
899         NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
900     BufferItem item{};
901 
902     // Preallocate, dequeue, request, and cancel 3 buffers so we don't get
903     // BUFFER_NEEDS_REALLOCATION below
904     int slots[3] = {};
905     mProducer->setMaxDequeuedBufferCount(3);
906     for (size_t i = 0; i < 3; ++i) {
907         status_t result = mProducer->dequeueBuffer(&slots[i], &fence, 0, 0, 0,
908                                                    TEST_PRODUCER_USAGE_BITS, nullptr, nullptr);
909         ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, result);
910         ASSERT_EQ(OK, mProducer->requestBuffer(slots[i], &buffer));
911     }
912     for (size_t i = 0; i < 3; ++i) {
913         ASSERT_EQ(OK, mProducer->cancelBuffer(slots[i], Fence::NO_FENCE));
914     }
915 
916     // Create 3 segments
917 
918     // The first segment is a two-buffer segment, so we only put one buffer into
919     // the queue at a time
920     for (size_t i = 0; i < 5; ++i) {
921         ASSERT_EQ(OK,
922                   mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS,
923                                            nullptr, nullptr));
924         ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
925         ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
926         ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber, Fence::NO_FENCE));
927         std::this_thread::sleep_for(16ms);
928     }
929 
930     // Sleep between segments
931     std::this_thread::sleep_for(500ms);
932 
933     // The second segment is a double-buffer segment. It starts the same as the
934     // two-buffer segment, but then at the end, we put two buffers in the queue
935     // at the same time before draining it.
936     for (size_t i = 0; i < 5; ++i) {
937         ASSERT_EQ(OK,
938                   mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS,
939                                            nullptr, nullptr));
940         ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
941         ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
942         ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber, Fence::NO_FENCE));
943         std::this_thread::sleep_for(16ms);
944     }
945     ASSERT_EQ(OK,
946               mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS, nullptr,
947                                        nullptr));
948     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
949     ASSERT_EQ(OK,
950               mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS, nullptr,
951                                        nullptr));
952     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
953     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
954     ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber, Fence::NO_FENCE));
955     std::this_thread::sleep_for(16ms);
956     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
957     ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber, Fence::NO_FENCE));
958 
959     // Sleep between segments
960     std::this_thread::sleep_for(500ms);
961 
962     // The third segment is a triple-buffer segment, so the queue is switching
963     // between one buffer and two buffers deep.
964     ASSERT_EQ(OK,
965               mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS, nullptr,
966                                        nullptr));
967     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
968     for (size_t i = 0; i < 5; ++i) {
969         ASSERT_EQ(OK,
970                   mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS,
971                                            nullptr, nullptr));
972         ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
973         ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
974         ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber, Fence::NO_FENCE));
975         std::this_thread::sleep_for(16ms);
976     }
977     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
978     ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber, Fence::NO_FENCE));
979 
980     // Now we read the segments
981     std::vector<OccupancyTracker::Segment> history;
982     ASSERT_EQ(OK, mConsumer->getOccupancyHistory(false, &history));
983 
984     // Since we didn't force a flush, we should only get the first two segments
985     // (since the third segment hasn't been closed out by the appearance of a
986     // new segment yet)
987     ASSERT_EQ(2u, history.size());
988 
989     // The first segment (which will be history[1], since the newest segment
990     // should be at the front of the vector) should be a two-buffer segment,
991     // which implies that the occupancy average should be between 0 and 1, and
992     // usedThirdBuffer should be false
993     const auto& firstSegment = history[1];
994     ASSERT_EQ(5u, firstSegment.numFrames);
995     ASSERT_LT(0, firstSegment.occupancyAverage);
996     ASSERT_GT(1, firstSegment.occupancyAverage);
997     ASSERT_EQ(false, firstSegment.usedThirdBuffer);
998 
999     // The second segment should be a double-buffered segment, which implies that
1000     // the occupancy average should be between 0 and 1, but usedThirdBuffer
1001     // should be true
1002     const auto& secondSegment = history[0];
1003     ASSERT_EQ(7u, secondSegment.numFrames);
1004     ASSERT_LT(0, secondSegment.occupancyAverage);
1005     ASSERT_GT(1, secondSegment.occupancyAverage);
1006     ASSERT_EQ(true, secondSegment.usedThirdBuffer);
1007 
1008     // If we read the segments again without flushing, we shouldn't get any new
1009     // segments
1010     ASSERT_EQ(OK, mConsumer->getOccupancyHistory(false, &history));
1011     ASSERT_EQ(0u, history.size());
1012 
1013     // Read the segments again, this time forcing a flush so we get the third
1014     // segment
1015     ASSERT_EQ(OK, mConsumer->getOccupancyHistory(true, &history));
1016     ASSERT_EQ(1u, history.size());
1017 
1018     // This segment should be a triple-buffered segment, which implies that the
1019     // occupancy average should be between 1 and 2, and usedThirdBuffer should
1020     // be true
1021     const auto& thirdSegment = history[0];
1022     ASSERT_EQ(6u, thirdSegment.numFrames);
1023     ASSERT_LT(1, thirdSegment.occupancyAverage);
1024     ASSERT_GT(2, thirdSegment.occupancyAverage);
1025     ASSERT_EQ(true, thirdSegment.usedThirdBuffer);
1026 }
1027 
1028 struct BufferDiscardedListener : public BnProducerListener {
1029 public:
1030     BufferDiscardedListener() = default;
1031     virtual ~BufferDiscardedListener() = default;
1032 
onBufferReleasedandroid::BufferDiscardedListener1033     virtual void onBufferReleased() {}
needsReleaseNotifyandroid::BufferDiscardedListener1034     virtual bool needsReleaseNotify() { return false; }
onBuffersDiscardedandroid::BufferDiscardedListener1035     virtual void onBuffersDiscarded(const std::vector<int32_t>& slots) {
1036         mDiscardedSlots.insert(mDiscardedSlots.end(), slots.begin(), slots.end());
1037     }
1038 
getDiscardedSlotsandroid::BufferDiscardedListener1039     const std::vector<int32_t>& getDiscardedSlots() const { return mDiscardedSlots; }
1040 private:
1041     // No need to use lock given the test triggers the listener in the same
1042     // thread context.
1043     std::vector<int32_t> mDiscardedSlots;
1044 };
1045 
TEST_F(BufferQueueTest,TestDiscardFreeBuffers)1046 TEST_F(BufferQueueTest, TestDiscardFreeBuffers) {
1047     createBufferQueue();
1048     sp<MockConsumer> mc(new MockConsumer);
1049     ASSERT_EQ(OK, mConsumer->consumerConnect(mc, false));
1050     IGraphicBufferProducer::QueueBufferOutput output;
1051     sp<BufferDiscardedListener> pl(new BufferDiscardedListener);
1052     ASSERT_EQ(OK, mProducer->connect(pl,
1053             NATIVE_WINDOW_API_CPU, false, &output));
1054 
1055     int slot = BufferQueue::INVALID_BUFFER_SLOT;
1056     sp<Fence> fence = Fence::NO_FENCE;
1057     sp<GraphicBuffer> buffer = nullptr;
1058     IGraphicBufferProducer::QueueBufferInput input(0ull, true,
1059         HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
1060         NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
1061     BufferItem item{};
1062 
1063     // Preallocate, dequeue, request, and cancel 4 buffers so we don't get
1064     // BUFFER_NEEDS_REALLOCATION below
1065     int slots[4] = {};
1066     mProducer->setMaxDequeuedBufferCount(4);
1067     for (size_t i = 0; i < 4; ++i) {
1068         status_t result = mProducer->dequeueBuffer(&slots[i], &fence, 0, 0, 0,
1069                                                    TEST_PRODUCER_USAGE_BITS, nullptr, nullptr);
1070         ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, result);
1071         ASSERT_EQ(OK, mProducer->requestBuffer(slots[i], &buffer));
1072     }
1073     for (size_t i = 0; i < 4; ++i) {
1074         ASSERT_EQ(OK, mProducer->cancelBuffer(slots[i], Fence::NO_FENCE));
1075     }
1076 
1077     // Get buffers in all states: dequeued, filled, acquired, free
1078 
1079     // Fill 3 buffers
1080     ASSERT_EQ(OK,
1081               mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS, nullptr,
1082                                        nullptr));
1083     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
1084     ASSERT_EQ(OK,
1085               mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS, nullptr,
1086                                        nullptr));
1087     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
1088     ASSERT_EQ(OK,
1089               mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS, nullptr,
1090                                        nullptr));
1091     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
1092     // Dequeue 1 buffer
1093     ASSERT_EQ(OK,
1094               mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS, nullptr,
1095                                        nullptr));
1096 
1097     // Acquire and free 1 buffer
1098     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
1099     ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber, Fence::NO_FENCE));
1100     int releasedSlot = item.mSlot;
1101 
1102     // Acquire 1 buffer, leaving 1 filled buffer in queue
1103     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
1104 
1105     // Now discard the free buffers
1106     ASSERT_EQ(OK, mConsumer->discardFreeBuffers());
1107 
1108     // Check onBuffersDiscarded is called with correct slots
1109     auto buffersDiscarded = pl->getDiscardedSlots();
1110     ASSERT_EQ(buffersDiscarded.size(), 1u);
1111     ASSERT_EQ(buffersDiscarded[0], releasedSlot);
1112 
1113     // Check no free buffers in dump
1114     String8 dumpString;
1115     mConsumer->dumpState(String8{}, &dumpString);
1116 
1117     // Parse the dump to ensure that all buffer slots that are FREE also
1118     // have a null GraphicBuffer
1119     // Fragile - assumes the following format for the dump for a buffer entry:
1120     // ":%p\][^:]*state=FREE" where %p is the buffer pointer in hex.
1121     ssize_t idx = dumpString.find("state=FREE");
1122     while (idx != -1) {
1123         ssize_t bufferPtrIdx = idx - 1;
1124         while (bufferPtrIdx > 0) {
1125             if (dumpString[bufferPtrIdx] == ':') {
1126                 bufferPtrIdx++;
1127                 break;
1128             }
1129             bufferPtrIdx--;
1130         }
1131         ASSERT_GT(bufferPtrIdx, 0) << "Can't parse queue dump to validate";
1132         ssize_t nullPtrIdx = dumpString.find("0x0]", bufferPtrIdx);
1133         ASSERT_EQ(bufferPtrIdx, nullPtrIdx) << "Free buffer not discarded";
1134         idx = dumpString.find("FREE", idx + 1);
1135     }
1136 }
1137 
TEST_F(BufferQueueTest,TestBufferReplacedInQueueBuffer)1138 TEST_F(BufferQueueTest, TestBufferReplacedInQueueBuffer) {
1139     createBufferQueue();
1140     sp<MockConsumer> mc(new MockConsumer);
1141     ASSERT_EQ(OK, mConsumer->consumerConnect(mc, true));
1142     IGraphicBufferProducer::QueueBufferOutput output;
1143     ASSERT_EQ(OK,
1144               mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, true, &output));
1145     ASSERT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(1));
1146 
1147     int slot = BufferQueue::INVALID_BUFFER_SLOT;
1148     sp<Fence> fence = Fence::NO_FENCE;
1149     sp<GraphicBuffer> buffer = nullptr;
1150     IGraphicBufferProducer::QueueBufferInput input(0ull, true,
1151         HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
1152         NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
1153     BufferItem item{};
1154 
1155     // Preallocate, dequeue, request, and cancel 2 buffers so we don't get
1156     // BUFFER_NEEDS_REALLOCATION below
1157     int slots[2] = {};
1158     ASSERT_EQ(OK, mProducer->setMaxDequeuedBufferCount(2));
1159     for (size_t i = 0; i < 2; ++i) {
1160         status_t result = mProducer->dequeueBuffer(&slots[i], &fence, 0, 0, 0,
1161                                                    TEST_PRODUCER_USAGE_BITS, nullptr, nullptr);
1162         ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, result);
1163         ASSERT_EQ(OK, mProducer->requestBuffer(slots[i], &buffer));
1164     }
1165     for (size_t i = 0; i < 2; ++i) {
1166         ASSERT_EQ(OK, mProducer->cancelBuffer(slots[i], Fence::NO_FENCE));
1167     }
1168 
1169     // Fill 2 buffers without consumer consuming them. Verify that all
1170     // queued buffer returns proper bufferReplaced flag
1171     ASSERT_EQ(OK,
1172               mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS, nullptr,
1173                                        nullptr));
1174     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
1175     ASSERT_EQ(false, output.bufferReplaced);
1176     ASSERT_EQ(OK,
1177               mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS, nullptr,
1178                                        nullptr));
1179     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
1180     ASSERT_EQ(true, output.bufferReplaced);
1181 }
1182 
1183 struct BufferDetachedListener : public BnProducerListener {
1184 public:
1185     BufferDetachedListener() = default;
1186     virtual ~BufferDetachedListener() = default;
1187 
onBufferReleasedandroid::BufferDetachedListener1188     virtual void onBufferReleased() {}
needsReleaseNotifyandroid::BufferDetachedListener1189     virtual bool needsReleaseNotify() { return true; }
onBufferDetachedandroid::BufferDetachedListener1190     virtual void onBufferDetached(int slot) {
1191         mDetachedSlots.push_back(slot);
1192     }
getDetachedSlotsandroid::BufferDetachedListener1193     const std::vector<int>& getDetachedSlots() const { return mDetachedSlots; }
1194 private:
1195     std::vector<int> mDetachedSlots;
1196 };
1197 
TEST_F(BufferQueueTest,TestConsumerDetachProducerListener)1198 TEST_F(BufferQueueTest, TestConsumerDetachProducerListener) {
1199     createBufferQueue();
1200     sp<MockConsumer> mc(new MockConsumer);
1201     ASSERT_EQ(OK, mConsumer->consumerConnect(mc, true));
1202     IGraphicBufferProducer::QueueBufferOutput output;
1203     sp<BufferDetachedListener> pl(new BufferDetachedListener);
1204     ASSERT_EQ(OK, mProducer->connect(pl, NATIVE_WINDOW_API_CPU, true, &output));
1205     ASSERT_EQ(OK, mProducer->setDequeueTimeout(0));
1206     ASSERT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(1));
1207 
1208     sp<Fence> fence = Fence::NO_FENCE;
1209     sp<GraphicBuffer> buffer = nullptr;
1210     IGraphicBufferProducer::QueueBufferInput input(0ull, true,
1211         HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
1212         NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
1213 
1214     int slots[2] = {};
1215     status_t result = OK;
1216     ASSERT_EQ(OK, mProducer->setMaxDequeuedBufferCount(2));
1217 
1218     result = mProducer->dequeueBuffer(&slots[0], &fence, 0, 0, 0,
1219                                       GRALLOC_USAGE_SW_READ_RARELY, nullptr, nullptr);
1220     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, result);
1221     ASSERT_EQ(OK, mProducer->requestBuffer(slots[0], &buffer));
1222 
1223     result = mProducer->dequeueBuffer(&slots[1], &fence, 0, 0, 0,
1224                                       GRALLOC_USAGE_SW_READ_RARELY, nullptr, nullptr);
1225     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, result);
1226     ASSERT_EQ(OK, mProducer->requestBuffer(slots[1], &buffer));
1227 
1228     // Queue & detach one from two dequeued buffes.
1229     ASSERT_EQ(OK, mProducer->queueBuffer(slots[1], input, &output));
1230     BufferItem item{};
1231     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
1232     ASSERT_EQ(OK, mConsumer->detachBuffer(item.mSlot));
1233 
1234     // Check whether the slot from IProducerListener is same to the detached slot.
1235     ASSERT_EQ(pl->getDetachedSlots().size(), 1u);
1236     ASSERT_EQ(pl->getDetachedSlots()[0], slots[1]);
1237 
1238     // Dequeue another buffer.
1239     int slot;
1240     result = mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0,
1241                                       GRALLOC_USAGE_SW_READ_RARELY, nullptr, nullptr);
1242     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, result);
1243     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
1244 
1245     // Dequeue should fail here, since we dequeued 3 buffers and one buffer was
1246     // detached from consumer(Two buffers are dequeued, and the current max
1247     // dequeued buffer count is two).
1248     result = mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0,
1249                                       GRALLOC_USAGE_SW_READ_RARELY, nullptr, nullptr);
1250     ASSERT_TRUE(result == WOULD_BLOCK || result == TIMED_OUT || result == INVALID_OPERATION);
1251 }
1252 
1253 #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_CONSUMER_ATTACH_CALLBACK)
1254 struct BufferAttachedListener : public BnProducerListener {
1255 public:
BufferAttachedListenerandroid::BufferAttachedListener1256     BufferAttachedListener(bool enable) : mEnabled(enable), mAttached(0) {}
1257     virtual ~BufferAttachedListener() = default;
1258 
onBufferReleasedandroid::BufferAttachedListener1259     virtual void onBufferReleased() {}
needsReleaseNotifyandroid::BufferAttachedListener1260     virtual bool needsReleaseNotify() { return true; }
onBufferAttachedandroid::BufferAttachedListener1261     virtual void onBufferAttached() {
1262         ++mAttached;
1263     }
needsAttachNotifyandroid::BufferAttachedListener1264     virtual bool needsAttachNotify() { return mEnabled; }
1265 
getNumAttachedandroid::BufferAttachedListener1266     int getNumAttached() const { return mAttached; }
1267 private:
1268     const bool mEnabled;
1269     int mAttached;
1270 };
1271 
TEST_F(BufferQueueTest,TestConsumerAttachProducerListener)1272 TEST_F(BufferQueueTest, TestConsumerAttachProducerListener) {
1273     createBufferQueue();
1274     sp<MockConsumer> mc1(new MockConsumer);
1275     ASSERT_EQ(OK, mConsumer->consumerConnect(mc1, true));
1276     IGraphicBufferProducer::QueueBufferOutput output;
1277     // Do not enable attach callback.
1278     sp<BufferAttachedListener> pl1(new BufferAttachedListener(false));
1279     ASSERT_EQ(OK, mProducer->connect(pl1, NATIVE_WINDOW_API_CPU, true, &output));
1280     ASSERT_EQ(OK, mProducer->setDequeueTimeout(0));
1281     ASSERT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(1));
1282 
1283     sp<Fence> fence = Fence::NO_FENCE;
1284     sp<GraphicBuffer> buffer = nullptr;
1285 
1286     int slot;
1287     status_t result = OK;
1288 
1289     ASSERT_EQ(OK, mProducer->setMaxDequeuedBufferCount(1));
1290 
1291     result = mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0,
1292                                       GRALLOC_USAGE_SW_READ_RARELY, nullptr, nullptr);
1293     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, result);
1294     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
1295     ASSERT_EQ(OK, mProducer->detachBuffer(slot));
1296 
1297     // Check # of attach is zero.
1298     ASSERT_EQ(0, pl1->getNumAttached());
1299 
1300     // Attach a buffer and check the callback was not called.
1301     ASSERT_EQ(OK, mConsumer->attachBuffer(&slot, buffer));
1302     ASSERT_EQ(0, pl1->getNumAttached());
1303 
1304     mProducer = nullptr;
1305     mConsumer = nullptr;
1306     createBufferQueue();
1307 
1308     sp<MockConsumer> mc2(new MockConsumer);
1309     ASSERT_EQ(OK, mConsumer->consumerConnect(mc2, true));
1310     // Enable attach callback.
1311     sp<BufferAttachedListener> pl2(new BufferAttachedListener(true));
1312     ASSERT_EQ(OK, mProducer->connect(pl2, NATIVE_WINDOW_API_CPU, true, &output));
1313     ASSERT_EQ(OK, mProducer->setDequeueTimeout(0));
1314     ASSERT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(1));
1315 
1316     fence = Fence::NO_FENCE;
1317     buffer = nullptr;
1318 
1319     result = OK;
1320 
1321     ASSERT_EQ(OK, mProducer->setMaxDequeuedBufferCount(1));
1322 
1323     result = mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0,
1324                                       GRALLOC_USAGE_SW_READ_RARELY, nullptr, nullptr);
1325     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, result);
1326     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
1327     ASSERT_EQ(OK, mProducer->detachBuffer(slot));
1328 
1329     // Check # of attach is zero.
1330     ASSERT_EQ(0, pl2->getNumAttached());
1331 
1332     // Attach a buffer and check the callback was called.
1333     ASSERT_EQ(OK, mConsumer->attachBuffer(&slot, buffer));
1334     ASSERT_EQ(1, pl2->getNumAttached());
1335 }
1336 #endif
1337 
TEST_F(BufferQueueTest,TestStaleBufferHandleSentAfterDisconnect)1338 TEST_F(BufferQueueTest, TestStaleBufferHandleSentAfterDisconnect) {
1339     createBufferQueue();
1340     sp<MockConsumer> mc(new MockConsumer);
1341     ASSERT_EQ(OK, mConsumer->consumerConnect(mc, true));
1342     IGraphicBufferProducer::QueueBufferOutput output;
1343     sp<IProducerListener> fakeListener(new StubProducerListener);
1344     ASSERT_EQ(OK, mProducer->connect(fakeListener, NATIVE_WINDOW_API_CPU, true, &output));
1345 
1346     int slot = BufferQueue::INVALID_BUFFER_SLOT;
1347     sp<Fence> fence = Fence::NO_FENCE;
1348     sp<GraphicBuffer> buffer = nullptr;
1349     IGraphicBufferProducer::QueueBufferInput input(0ull, true,
1350             HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
1351             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
1352 
1353     // Dequeue, request, and queue one buffer
1354     status_t result = mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS,
1355                                                nullptr, nullptr);
1356     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, result);
1357     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
1358     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
1359 
1360     // Acquire and release the buffer. Upon acquiring, the buffer handle should
1361     // be non-null since this is the first time we've acquired this slot.
1362     BufferItem item;
1363     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
1364     ASSERT_EQ(slot, item.mSlot);
1365     ASSERT_NE(nullptr, item.mGraphicBuffer.get());
1366     ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber, Fence::NO_FENCE));
1367 
1368     // Dequeue and queue the buffer again
1369     ASSERT_EQ(OK,
1370               mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS, nullptr,
1371                                        nullptr));
1372     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
1373 
1374     // Acquire and release the buffer again. Upon acquiring, the buffer handle
1375     // should be null since this is not the first time we've acquired this slot.
1376     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
1377     ASSERT_EQ(slot, item.mSlot);
1378     ASSERT_EQ(nullptr, item.mGraphicBuffer.get());
1379     ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber, Fence::NO_FENCE));
1380 
1381     // Dequeue and queue the buffer again
1382     ASSERT_EQ(OK,
1383               mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS, nullptr,
1384                                        nullptr));
1385     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
1386 
1387     // Disconnect the producer end. This should clear all of the slots and mark
1388     // the buffer in the queue as stale.
1389     ASSERT_EQ(OK, mProducer->disconnect(NATIVE_WINDOW_API_CPU));
1390 
1391     // Acquire the buffer again. Upon acquiring, the buffer handle should not be
1392     // null since the queued buffer should have been marked as stale, which
1393     // should trigger the BufferQueue to resend the buffer handle.
1394     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
1395     ASSERT_EQ(slot, item.mSlot);
1396     ASSERT_NE(nullptr, item.mGraphicBuffer.get());
1397 }
1398 
TEST_F(BufferQueueTest,TestProducerConnectDisconnect)1399 TEST_F(BufferQueueTest, TestProducerConnectDisconnect) {
1400     createBufferQueue();
1401     sp<MockConsumer> mc(new MockConsumer);
1402     ASSERT_EQ(OK, mConsumer->consumerConnect(mc, true));
1403     IGraphicBufferProducer::QueueBufferOutput output;
1404     sp<IProducerListener> fakeListener(new StubProducerListener);
1405     ASSERT_EQ(NO_INIT, mProducer->disconnect(NATIVE_WINDOW_API_CPU));
1406     ASSERT_EQ(OK, mProducer->connect(fakeListener, NATIVE_WINDOW_API_CPU, true, &output));
1407     ASSERT_EQ(BAD_VALUE, mProducer->connect(fakeListener, NATIVE_WINDOW_API_MEDIA, true, &output));
1408 
1409     ASSERT_EQ(BAD_VALUE, mProducer->disconnect(NATIVE_WINDOW_API_MEDIA));
1410     ASSERT_EQ(OK, mProducer->disconnect(NATIVE_WINDOW_API_CPU));
1411     ASSERT_EQ(NO_INIT, mProducer->disconnect(NATIVE_WINDOW_API_CPU));
1412 }
1413 
TEST_F(BufferQueueTest,TestBqSetFrameRateFlagBuildTimeIsSet)1414 TEST_F(BufferQueueTest, TestBqSetFrameRateFlagBuildTimeIsSet) {
1415     ASSERT_EQ(flags::bq_setframerate(), COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_SETFRAMERATE));
1416 }
1417 
1418 struct BufferItemConsumerSetFrameRateListener : public BufferItemConsumer {
BufferItemConsumerSetFrameRateListenerandroid::BufferItemConsumerSetFrameRateListener1419     BufferItemConsumerSetFrameRateListener() : BufferItemConsumer(GRALLOC_USAGE_SW_READ_OFTEN, 1) {}
1420 
1421     MOCK_METHOD(void, onSetFrameRate, (float, int8_t, int8_t), (override));
1422 };
1423 
TEST_F(BufferQueueTest,TestSetFrameRate)1424 TEST_F(BufferQueueTest, TestSetFrameRate) {
1425     sp<BufferItemConsumerSetFrameRateListener> bufferConsumer =
1426             sp<BufferItemConsumerSetFrameRateListener>::make();
1427     sp<IGraphicBufferProducer> producer = bufferConsumer->getSurface()->getIGraphicBufferProducer();
1428 
1429     EXPECT_CALL(*bufferConsumer, onSetFrameRate(12.34f, 1, 0)).Times(1);
1430     producer->setFrameRate(12.34f, 1, 0);
1431 }
1432 
1433 class Latch {
1434 public:
Latch(int expected)1435     explicit Latch(int expected) : mExpected(expected) {}
1436     Latch(const Latch&) = delete;
1437     Latch& operator=(const Latch&) = delete;
1438 
CountDown()1439     void CountDown() {
1440         std::unique_lock<std::mutex> lock(mLock);
1441         mExpected--;
1442         if (mExpected <= 0) {
1443             mCV.notify_all();
1444         }
1445     }
1446 
Wait()1447     void Wait() {
1448         std::unique_lock<std::mutex> lock(mLock);
1449         mCV.wait(lock, [&] { return mExpected == 0; });
1450     }
1451 
1452 private:
1453     int mExpected;
1454     std::mutex mLock;
1455     std::condition_variable mCV;
1456 };
1457 
1458 struct OneshotOnDequeuedListener final : public BufferItemConsumer::FrameAvailableListener {
OneshotOnDequeuedListenerandroid::OneshotOnDequeuedListener1459     OneshotOnDequeuedListener(std::function<void()>&& oneshot)
1460           : mOneshotRunnable(std::move(oneshot)) {}
1461 
1462     std::function<void()> mOneshotRunnable;
1463 
runandroid::OneshotOnDequeuedListener1464     void run() {
1465         if (mOneshotRunnable) {
1466             mOneshotRunnable();
1467             mOneshotRunnable = nullptr;
1468         }
1469     }
1470 
onFrameDequeuedandroid::OneshotOnDequeuedListener1471     void onFrameDequeued(const uint64_t) override { run(); }
1472 
onFrameAvailableandroid::OneshotOnDequeuedListener1473     void onFrameAvailable(const BufferItem&) override {}
1474 };
1475 
1476 // See b/270004534
TEST(BufferQueueThreading,TestProducerDequeueConsumerDestroy)1477 TEST(BufferQueueThreading, TestProducerDequeueConsumerDestroy) {
1478     sp<BufferItemConsumer> bufferConsumer =
1479             sp<BufferItemConsumer>::make(GRALLOC_USAGE_SW_READ_OFTEN, 2);
1480     ASSERT_NE(nullptr, bufferConsumer.get());
1481     sp<Surface> surface = bufferConsumer->getSurface();
1482     native_window_set_buffers_format(surface.get(), PIXEL_FORMAT_RGBA_8888);
1483     native_window_set_buffers_dimensions(surface.get(), 100, 100);
1484 
1485     Latch triggerDisconnect(1);
1486     Latch resumeCallback(1);
1487     auto luckyListener = sp<OneshotOnDequeuedListener>::make([&]() {
1488         triggerDisconnect.CountDown();
1489         resumeCallback.Wait();
1490     });
1491     bufferConsumer->setFrameAvailableListener(luckyListener);
1492 
1493     std::future<void> disconnecter = std::async(std::launch::async, [&]() {
1494         triggerDisconnect.Wait();
1495         luckyListener = nullptr;
1496         bufferConsumer = nullptr;
1497         resumeCallback.CountDown();
1498     });
1499 
1500     std::future<void> render = std::async(std::launch::async, [=]() {
1501         ANativeWindow_Buffer buffer;
1502         surface->lock(&buffer, nullptr);
1503         surface->unlockAndPost();
1504     });
1505 
1506     ASSERT_EQ(std::future_status::ready, render.wait_for(1s));
1507     EXPECT_EQ(nullptr, luckyListener.get());
1508     EXPECT_EQ(nullptr, bufferConsumer.get());
1509 }
1510 
TEST_F(BufferQueueTest,TestAdditionalOptions)1511 TEST_F(BufferQueueTest, TestAdditionalOptions) {
1512     sp<BufferItemConsumer> bufferConsumer =
1513             sp<BufferItemConsumer>::make(GRALLOC_USAGE_SW_READ_OFTEN, 2);
1514     ASSERT_NE(nullptr, bufferConsumer.get());
1515     sp<Surface> surface = bufferConsumer->getSurface();
1516     native_window_set_buffers_format(surface.get(), PIXEL_FORMAT_RGBA_8888);
1517     native_window_set_buffers_dimensions(surface.get(), 100, 100);
1518 
1519     std::array<AHardwareBufferLongOptions, 1> extras = {{
1520             {.name = "android.hardware.graphics.common.Dataspace", ADATASPACE_DISPLAY_P3},
1521     }};
1522 
1523     ASSERT_EQ(NO_INIT,
1524               native_window_set_buffers_additional_options(surface.get(), extras.data(),
1525                                                            extras.size()));
1526 
1527     if (!IsCuttlefish()) {
1528         GTEST_SKIP() << "Not cuttlefish";
1529     }
1530 
1531     ASSERT_EQ(OK, native_window_api_connect(surface.get(), NATIVE_WINDOW_API_CPU));
1532     ASSERT_EQ(OK,
1533               native_window_set_buffers_additional_options(surface.get(), extras.data(),
1534                                                            extras.size()));
1535 
1536     ANativeWindowBuffer* windowBuffer = nullptr;
1537     int fence = -1;
1538     ASSERT_EQ(OK, ANativeWindow_dequeueBuffer(surface.get(), &windowBuffer, &fence));
1539 
1540     AHardwareBuffer* buffer = ANativeWindowBuffer_getHardwareBuffer(windowBuffer);
1541     ASSERT_TRUE(buffer);
1542     ADataSpace dataSpace = AHardwareBuffer_getDataSpace(buffer);
1543     EXPECT_EQ(ADATASPACE_DISPLAY_P3, dataSpace);
1544 
1545     ANativeWindow_cancelBuffer(surface.get(), windowBuffer, -1);
1546 
1547     // Check that reconnecting properly clears the options
1548     ASSERT_EQ(OK, native_window_api_disconnect(surface.get(), NATIVE_WINDOW_API_CPU));
1549     ASSERT_EQ(OK, native_window_api_connect(surface.get(), NATIVE_WINDOW_API_CPU));
1550 
1551     ASSERT_EQ(OK, ANativeWindow_dequeueBuffer(surface.get(), &windowBuffer, &fence));
1552     buffer = ANativeWindowBuffer_getHardwareBuffer(windowBuffer);
1553     ASSERT_TRUE(buffer);
1554     dataSpace = AHardwareBuffer_getDataSpace(buffer);
1555     EXPECT_EQ(ADATASPACE_UNKNOWN, dataSpace);
1556 }
1557 
TEST_F(BufferQueueTest,PassesThroughPictureProfileHandle)1558 TEST_F(BufferQueueTest, PassesThroughPictureProfileHandle) {
1559     createBufferQueue();
1560     sp<MockConsumer> mc(new MockConsumer);
1561     mConsumer->consumerConnect(mc, false);
1562 
1563     IGraphicBufferProducer::QueueBufferOutput qbo;
1564     mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, false, &qbo);
1565     mProducer->setMaxDequeuedBufferCount(2);
1566     mConsumer->setMaxAcquiredBufferCount(2);
1567 
1568     // First try to pass a valid picture profile handle
1569     {
1570         int slot;
1571         sp<Fence> fence;
1572         sp<GraphicBuffer> buf;
1573         IGraphicBufferProducer::QueueBufferInput qbi(0, false, HAL_DATASPACE_UNKNOWN,
1574                                                      Rect(0, 0, 1, 1),
1575                                                      NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
1576                                                      Fence::NO_FENCE);
1577         qbi.setPictureProfileHandle(PictureProfileHandle(1));
1578 
1579         EXPECT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
1580                   mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0, GRALLOC_USAGE_SW_READ_OFTEN,
1581                                            nullptr, nullptr));
1582         EXPECT_EQ(OK, mProducer->requestBuffer(slot, &buf));
1583         EXPECT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo));
1584 
1585         BufferItem item;
1586         EXPECT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
1587 
1588         ASSERT_TRUE(item.mPictureProfileHandle.has_value());
1589         ASSERT_EQ(item.mPictureProfileHandle, PictureProfileHandle(1));
1590     }
1591 
1592     // Then validate that the picture profile handle isn't sticky and is reset for the next buffer
1593     {
1594         int slot;
1595         sp<Fence> fence;
1596         sp<GraphicBuffer> buf;
1597         IGraphicBufferProducer::QueueBufferInput qbi(0, false, HAL_DATASPACE_UNKNOWN,
1598                                                      Rect(0, 0, 1, 1),
1599                                                      NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
1600                                                      Fence::NO_FENCE);
1601 
1602         EXPECT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
1603                   mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0, GRALLOC_USAGE_SW_READ_OFTEN,
1604                                            nullptr, nullptr));
1605         EXPECT_EQ(OK, mProducer->requestBuffer(slot, &buf));
1606         EXPECT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo));
1607 
1608         BufferItem item;
1609         EXPECT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
1610 
1611         ASSERT_FALSE(item.mPictureProfileHandle.has_value());
1612     }
1613 }
1614 
1615 } // namespace android
1616