• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2013 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 "IGraphicBufferProducer_test"
18 //#define LOG_NDEBUG 0
19 
20 #include "MockConsumer.h"
21 
22 #include <gtest/gtest.h>
23 
24 #include <utils/String8.h>
25 #include <utils/threads.h>
26 
27 #include <ui/GraphicBuffer.h>
28 
29 #include <gui/BufferQueue.h>
30 #include <gui/IProducerListener.h>
31 
32 #include <system/window.h>
33 
34 #include <vector>
35 
36 #define ASSERT_OK(x) ASSERT_EQ(OK, (x))
37 #define EXPECT_OK(x) EXPECT_EQ(OK, (x))
38 
39 #define TEST_TOKEN ((IProducerListener*)(NULL))
40 #define TEST_API NATIVE_WINDOW_API_CPU
41 #define TEST_API_OTHER NATIVE_WINDOW_API_EGL // valid API that's not TEST_API
42 #define TEST_CONTROLLED_BY_APP false
43 #define TEST_PRODUCER_USAGE_BITS (0)
44 
45 #ifndef USE_BUFFER_HUB_AS_BUFFER_QUEUE
46 #define USE_BUFFER_HUB_AS_BUFFER_QUEUE 0
47 #endif
48 
49 namespace android {
50 
51 namespace {
52     // Default dimensions before setDefaultBufferSize is called
53     const uint32_t DEFAULT_WIDTH = 1;
54     const uint32_t DEFAULT_HEIGHT = 1;
55 
56     // Default format before setDefaultBufferFormat is called
57     const PixelFormat DEFAULT_FORMAT = HAL_PIXEL_FORMAT_RGBA_8888;
58 
59     // Default transform hint before setTransformHint is called
60     const uint32_t DEFAULT_TRANSFORM_HINT = 0;
61 
62     // TODO: Make these constants in header
63     const int DEFAULT_CONSUMER_USAGE_BITS = 0;
64 
65     // Parameters for a generic "valid" input for queueBuffer.
66     const int64_t QUEUE_BUFFER_INPUT_TIMESTAMP = 1384888611;
67     const bool QUEUE_BUFFER_INPUT_IS_AUTO_TIMESTAMP = false;
68     const android_dataspace QUEUE_BUFFER_INPUT_DATASPACE = HAL_DATASPACE_UNKNOWN;
69     const Rect QUEUE_BUFFER_INPUT_RECT = Rect(DEFAULT_WIDTH, DEFAULT_HEIGHT);
70     const int QUEUE_BUFFER_INPUT_SCALING_MODE = 0;
71     const int QUEUE_BUFFER_INPUT_TRANSFORM = 0;
72     const sp<Fence> QUEUE_BUFFER_INPUT_FENCE = Fence::NO_FENCE;
73     const uint32_t QUEUE_BUFFER_INPUT_STICKY_TRANSFORM = 0;
74     const bool QUEUE_BUFFER_INPUT_GET_TIMESTAMPS = 0;
75     const int QUEUE_BUFFER_INPUT_SLOT = -1;
76 
77     // Enums to control which IGraphicBufferProducer backend to test.
78     enum IGraphicBufferProducerTestCode {
79         USE_BUFFER_QUEUE_PRODUCER = 0,
80         USE_BUFFER_HUB_PRODUCER,
81     };
82 }; // namespace anonymous
83 
84 class IGraphicBufferProducerTest : public ::testing::TestWithParam<uint32_t> {
85 protected:
86 
IGraphicBufferProducerTest()87     IGraphicBufferProducerTest() {}
88 
SetUp()89     virtual void SetUp() {
90         const ::testing::TestInfo* const testInfo =
91             ::testing::UnitTest::GetInstance()->current_test_info();
92         ALOGV("Begin test: %s.%s", testInfo->test_case_name(),
93                 testInfo->name());
94 
95         mMC = new MockConsumer;
96 
97         switch (GetParam()) {
98             case USE_BUFFER_QUEUE_PRODUCER: {
99                 BufferQueue::createBufferQueue(&mProducer, &mConsumer);
100                 break;
101             }
102             case USE_BUFFER_HUB_PRODUCER: {
103                 BufferQueue::createBufferHubQueue(&mProducer, &mConsumer);
104                 break;
105             }
106             default: {
107                 // Should never reach here.
108                 LOG_ALWAYS_FATAL("Invalid test params: %u", GetParam());
109                 break;
110             }
111         }
112 
113         // Test check: Can't connect producer if no consumer yet
114         if (GetParam() == USE_BUFFER_QUEUE_PRODUCER) {
115             // TODO(b/73267953): Make BufferHub honor producer and consumer connection.
116             ASSERT_EQ(NO_INIT, TryConnectProducer());
117         }
118 
119         // Must connect consumer before producer connects will succeed.
120         ASSERT_OK(mConsumer->consumerConnect(mMC, /*controlledByApp*/ false));
121     }
122 
TearDown()123     virtual void TearDown() {
124         const ::testing::TestInfo* const testInfo =
125             ::testing::UnitTest::GetInstance()->current_test_info();
126         ALOGV("End test:   %s.%s", testInfo->test_case_name(),
127                 testInfo->name());
128     }
129 
TryConnectProducer()130     status_t TryConnectProducer() {
131         IGraphicBufferProducer::QueueBufferOutput output;
132         return mProducer->connect(TEST_TOKEN,
133                                   TEST_API,
134                                   TEST_CONTROLLED_BY_APP,
135                                   &output);
136         // TODO: use params to vary token, api, producercontrolledbyapp, etc
137     }
138 
139     // Connect to a producer in a 'correct' fashion.
140     //   Precondition: Consumer is connected.
ConnectProducer()141     void ConnectProducer() {
142         ASSERT_OK(TryConnectProducer());
143     }
144 
145     // Create a generic "valid" input for queueBuffer
146     // -- uses the default buffer format, width, etc.
CreateBufferInput()147     static IGraphicBufferProducer::QueueBufferInput CreateBufferInput() {
148         return QueueBufferInputBuilder().build();
149     }
150 
151     // Builder pattern to slightly vary *almost* correct input
152     // -- avoids copying and pasting
153     struct QueueBufferInputBuilder {
QueueBufferInputBuilderandroid::IGraphicBufferProducerTest::QueueBufferInputBuilder154         QueueBufferInputBuilder() {
155            timestamp = QUEUE_BUFFER_INPUT_TIMESTAMP;
156            isAutoTimestamp = QUEUE_BUFFER_INPUT_IS_AUTO_TIMESTAMP;
157            dataSpace = QUEUE_BUFFER_INPUT_DATASPACE;
158            crop = QUEUE_BUFFER_INPUT_RECT;
159            scalingMode = QUEUE_BUFFER_INPUT_SCALING_MODE;
160            transform = QUEUE_BUFFER_INPUT_TRANSFORM;
161            fence = QUEUE_BUFFER_INPUT_FENCE;
162            stickyTransform = QUEUE_BUFFER_INPUT_STICKY_TRANSFORM;
163            getTimestamps = QUEUE_BUFFER_INPUT_GET_TIMESTAMPS;
164            slot = QUEUE_BUFFER_INPUT_SLOT;
165         }
166 
buildandroid::IGraphicBufferProducerTest::QueueBufferInputBuilder167         IGraphicBufferProducer::QueueBufferInput build() {
168             return IGraphicBufferProducer::QueueBufferInput(
169                     timestamp,
170                     isAutoTimestamp,
171                     dataSpace,
172                     crop,
173                     scalingMode,
174                     transform,
175                     fence,
176                     stickyTransform,
177                     getTimestamps,
178                     slot);
179         }
180 
setTimestampandroid::IGraphicBufferProducerTest::QueueBufferInputBuilder181         QueueBufferInputBuilder& setTimestamp(int64_t timestamp) {
182             this->timestamp = timestamp;
183             return *this;
184         }
185 
setIsAutoTimestampandroid::IGraphicBufferProducerTest::QueueBufferInputBuilder186         QueueBufferInputBuilder& setIsAutoTimestamp(bool isAutoTimestamp) {
187             this->isAutoTimestamp = isAutoTimestamp;
188             return *this;
189         }
190 
setDataSpaceandroid::IGraphicBufferProducerTest::QueueBufferInputBuilder191         QueueBufferInputBuilder& setDataSpace(android_dataspace dataSpace) {
192             this->dataSpace = dataSpace;
193             return *this;
194         }
195 
setCropandroid::IGraphicBufferProducerTest::QueueBufferInputBuilder196         QueueBufferInputBuilder& setCrop(Rect crop) {
197             this->crop = crop;
198             return *this;
199         }
200 
setScalingModeandroid::IGraphicBufferProducerTest::QueueBufferInputBuilder201         QueueBufferInputBuilder& setScalingMode(int scalingMode) {
202             this->scalingMode = scalingMode;
203             return *this;
204         }
205 
setTransformandroid::IGraphicBufferProducerTest::QueueBufferInputBuilder206         QueueBufferInputBuilder& setTransform(uint32_t transform) {
207             this->transform = transform;
208             return *this;
209         }
210 
setFenceandroid::IGraphicBufferProducerTest::QueueBufferInputBuilder211         QueueBufferInputBuilder& setFence(sp<Fence> fence) {
212             this->fence = fence;
213             return *this;
214         }
215 
setStickyTransformandroid::IGraphicBufferProducerTest::QueueBufferInputBuilder216         QueueBufferInputBuilder& setStickyTransform(uint32_t stickyTransform) {
217             this->stickyTransform = stickyTransform;
218             return *this;
219         }
220 
setGetTimestampsandroid::IGraphicBufferProducerTest::QueueBufferInputBuilder221         QueueBufferInputBuilder& setGetTimestamps(bool getTimestamps) {
222             this->getTimestamps = getTimestamps;
223             return *this;
224         }
225 
setSlotandroid::IGraphicBufferProducerTest::QueueBufferInputBuilder226         QueueBufferInputBuilder& setSlot(int slot) {
227             this->slot = slot;
228             return *this;
229         }
230 
231     private:
232         int64_t timestamp;
233         bool isAutoTimestamp;
234         android_dataspace dataSpace;
235         Rect crop;
236         int scalingMode;
237         uint32_t transform;
238         sp<Fence> fence;
239         uint32_t stickyTransform;
240         bool getTimestamps;
241         int slot;
242     }; // struct QueueBufferInputBuilder
243 
dequeueBuffer(uint32_t w,uint32_t h,uint32_t format,uint32_t usage,IGraphicBufferProducer::DequeueBufferOutput * result)244     status_t dequeueBuffer(uint32_t w, uint32_t h, uint32_t format, uint32_t usage,
245                            IGraphicBufferProducer::DequeueBufferOutput* result) {
246         result->result =
247             mProducer->dequeueBuffer(&result->slot, &result->fence, w, h, format, usage,
248                                      &result->bufferAge, nullptr);
249         return result->result;
250     }
251 
setupDequeueRequestBuffer(int * slot,sp<Fence> * fence,sp<GraphicBuffer> * buffer)252     void setupDequeueRequestBuffer(int *slot, sp<Fence> *fence,
253             sp<GraphicBuffer> *buffer)
254     {
255         ASSERT_TRUE(slot != nullptr);
256         ASSERT_TRUE(fence != nullptr);
257         ASSERT_TRUE(buffer != nullptr);
258 
259         ASSERT_NO_FATAL_FAILURE(ConnectProducer());
260 
261 
262         ASSERT_EQ(OK,
263                   ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
264                           (mProducer->dequeueBuffer(slot, fence, DEFAULT_WIDTH, DEFAULT_HEIGHT,
265                                                     DEFAULT_FORMAT, TEST_PRODUCER_USAGE_BITS,
266                                                     nullptr, nullptr)));
267 
268         EXPECT_LE(0, *slot);
269         EXPECT_GT(BufferQueue::NUM_BUFFER_SLOTS, *slot);
270 
271         // Request the buffer (pre-requisite for queueing)
272         ASSERT_OK(mProducer->requestBuffer(*slot, buffer));
273     }
274 
275 private: // hide from test body
276     sp<MockConsumer> mMC;
277 
278 protected: // accessible from test body
279     sp<IGraphicBufferProducer> mProducer;
280     sp<IGraphicBufferConsumer> mConsumer;
281 };
282 
TEST_P(IGraphicBufferProducerTest,ConnectFirst_ReturnsError)283 TEST_P(IGraphicBufferProducerTest, ConnectFirst_ReturnsError) {
284     IGraphicBufferProducer::QueueBufferOutput output;
285 
286     // NULL output returns BAD_VALUE
287     EXPECT_EQ(BAD_VALUE, mProducer->connect(TEST_TOKEN,
288                                             TEST_API,
289                                             TEST_CONTROLLED_BY_APP,
290                                             /*output*/nullptr));
291 
292     // Invalid API returns bad value
293     EXPECT_EQ(BAD_VALUE, mProducer->connect(TEST_TOKEN,
294                                             /*api*/0xDEADBEEF,
295                                             TEST_CONTROLLED_BY_APP,
296                                             &output));
297 
298     // TODO: get a token from a dead process somehow
299 }
300 
TEST_P(IGraphicBufferProducerTest,ConnectAgain_ReturnsError)301 TEST_P(IGraphicBufferProducerTest, ConnectAgain_ReturnsError) {
302     ASSERT_NO_FATAL_FAILURE(ConnectProducer());
303 
304     // Can't connect when there is already a producer connected
305     IGraphicBufferProducer::QueueBufferOutput output;
306     EXPECT_EQ(BAD_VALUE, mProducer->connect(TEST_TOKEN,
307                                             TEST_API,
308                                             TEST_CONTROLLED_BY_APP,
309                                             &output));
310 
311     ASSERT_OK(mConsumer->consumerDisconnect());
312     // Can't connect when IGBP is abandoned
313     if (GetParam() == USE_BUFFER_QUEUE_PRODUCER) {
314         // TODO(b/73267953): Make BufferHub honor producer and consumer connection.
315         EXPECT_EQ(NO_INIT, mProducer->connect(TEST_TOKEN,
316                                               TEST_API,
317                                               TEST_CONTROLLED_BY_APP,
318                                               &output));
319     }
320 }
321 
TEST_P(IGraphicBufferProducerTest,Disconnect_Succeeds)322 TEST_P(IGraphicBufferProducerTest, Disconnect_Succeeds) {
323     ASSERT_NO_FATAL_FAILURE(ConnectProducer());
324 
325     ASSERT_OK(mProducer->disconnect(TEST_API));
326 }
327 
328 
TEST_P(IGraphicBufferProducerTest,Disconnect_ReturnsError)329 TEST_P(IGraphicBufferProducerTest, Disconnect_ReturnsError) {
330     ASSERT_NO_FATAL_FAILURE(ConnectProducer());
331 
332     // Must disconnect with same API number
333     ASSERT_EQ(BAD_VALUE, mProducer->disconnect(TEST_API_OTHER));
334     // API must not be out of range
335     ASSERT_EQ(BAD_VALUE, mProducer->disconnect(/*api*/0xDEADBEEF));
336 
337     // TODO: somehow kill mProducer so that this returns DEAD_OBJECT
338 }
339 
TEST_P(IGraphicBufferProducerTest,Query_Succeeds)340 TEST_P(IGraphicBufferProducerTest, Query_Succeeds) {
341     ASSERT_NO_FATAL_FAILURE(ConnectProducer());
342 
343     int32_t value = -1;
344     EXPECT_OK(mProducer->query(NATIVE_WINDOW_WIDTH, &value));
345     EXPECT_EQ(DEFAULT_WIDTH, static_cast<uint32_t>(value));
346 
347     EXPECT_OK(mProducer->query(NATIVE_WINDOW_HEIGHT, &value));
348     EXPECT_EQ(DEFAULT_HEIGHT, static_cast<uint32_t>(value));
349 
350     EXPECT_OK(mProducer->query(NATIVE_WINDOW_FORMAT, &value));
351     EXPECT_EQ(DEFAULT_FORMAT, value);
352 
353     EXPECT_OK(mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &value));
354     EXPECT_LE(0, value);
355     EXPECT_GE(BufferQueue::NUM_BUFFER_SLOTS, value);
356 
357     EXPECT_OK(mProducer->query(NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND, &value));
358     EXPECT_FALSE(value); // Can't run behind when we haven't touched the queue
359 
360     EXPECT_OK(mProducer->query(NATIVE_WINDOW_CONSUMER_USAGE_BITS, &value));
361     EXPECT_EQ(DEFAULT_CONSUMER_USAGE_BITS, value);
362 
363     { // Test the batched version
364         std::vector<int32_t> inputs = {
365                 NATIVE_WINDOW_WIDTH,
366                 NATIVE_WINDOW_HEIGHT,
367                 NATIVE_WINDOW_FORMAT,
368                 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
369                 NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND,
370                 NATIVE_WINDOW_CONSUMER_USAGE_BITS };
371         using QueryOutput = IGraphicBufferProducer::QueryOutput;
372         std::vector<QueryOutput> outputs;
373         EXPECT_OK(mProducer->query(inputs, &outputs));
374         EXPECT_EQ(DEFAULT_WIDTH, static_cast<uint32_t>(outputs[0].value));
375         EXPECT_EQ(DEFAULT_HEIGHT, static_cast<uint32_t>(outputs[1].value));
376         EXPECT_EQ(DEFAULT_FORMAT, outputs[2].value);
377         EXPECT_LE(0, outputs[3].value);
378         EXPECT_FALSE(outputs[4].value);
379         EXPECT_EQ(DEFAULT_CONSUMER_USAGE_BITS, outputs[5].value);
380         for (const QueryOutput& output : outputs) {
381             EXPECT_OK(output.result);
382         }
383     }
384 }
385 
TEST_P(IGraphicBufferProducerTest,Query_ReturnsError)386 TEST_P(IGraphicBufferProducerTest, Query_ReturnsError) {
387     ASSERT_NO_FATAL_FAILURE(ConnectProducer());
388 
389     // One past the end of the last 'query' enum value. Update this if we add more enums.
390     const int NATIVE_WINDOW_QUERY_LAST_OFF_BY_ONE = NATIVE_WINDOW_BUFFER_AGE + 1;
391 
392     int value;
393     // What was out of range
394     EXPECT_EQ(BAD_VALUE, mProducer->query(/*what*/-1, &value));
395     EXPECT_EQ(BAD_VALUE, mProducer->query(/*what*/0xDEADBEEF, &value));
396     EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_QUERY_LAST_OFF_BY_ONE, &value));
397 
398     // Some enums from window.h are 'invalid'
399     EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER, &value));
400     EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_CONCRETE_TYPE, &value));
401     EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_DEFAULT_WIDTH, &value));
402     EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_DEFAULT_HEIGHT, &value));
403     EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_TRANSFORM_HINT, &value));
404     // TODO: Consider documented the above enums as unsupported or make a new enum for IGBP
405 
406     { // Test the batched version
407         std::vector<int32_t> inputs = {
408                 -1,
409                 static_cast<int32_t>(0xDEADBEEF),
410                 NATIVE_WINDOW_QUERY_LAST_OFF_BY_ONE,
411                 NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
412                 NATIVE_WINDOW_CONCRETE_TYPE,
413                 NATIVE_WINDOW_DEFAULT_WIDTH,
414                 NATIVE_WINDOW_DEFAULT_HEIGHT,
415                 NATIVE_WINDOW_TRANSFORM_HINT};
416         using QueryOutput = IGraphicBufferProducer::QueryOutput;
417         std::vector<QueryOutput> outputs;
418         EXPECT_OK(mProducer->query(inputs, &outputs));
419         for (const QueryOutput& output : outputs) {
420             EXPECT_EQ(BAD_VALUE, output.result);
421         }
422     }
423 
424     // Value was NULL
425     EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_FORMAT, /*value*/nullptr));
426 
427     ASSERT_OK(mConsumer->consumerDisconnect());
428 
429     // BQ was abandoned
430     if (GetParam() == USE_BUFFER_QUEUE_PRODUCER) {
431         // TODO(b/73267953): Make BufferHub honor producer and consumer connection.
432         EXPECT_EQ(NO_INIT, mProducer->query(NATIVE_WINDOW_FORMAT, &value));
433     }
434 
435     // TODO: other things in window.h that are supported by Surface::query
436     // but not by BufferQueue::query
437 }
438 
439 // TODO: queue under more complicated situations not involving just a single buffer
TEST_P(IGraphicBufferProducerTest,Queue_Succeeds)440 TEST_P(IGraphicBufferProducerTest, Queue_Succeeds) {
441     ASSERT_NO_FATAL_FAILURE(ConnectProducer());
442 
443     int dequeuedSlot = -1;
444     sp<Fence> dequeuedFence;
445 
446     ASSERT_EQ(OK,
447               ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
448                       (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, DEFAULT_WIDTH,
449                                                 DEFAULT_HEIGHT, DEFAULT_FORMAT,
450                                                 TEST_PRODUCER_USAGE_BITS, nullptr, nullptr)));
451 
452     EXPECT_LE(0, dequeuedSlot);
453     EXPECT_GT(BufferQueue::NUM_BUFFER_SLOTS, dequeuedSlot);
454 
455     // Request the buffer (pre-requisite for queueing)
456     sp<GraphicBuffer> dequeuedBuffer;
457     ASSERT_OK(mProducer->requestBuffer(dequeuedSlot, &dequeuedBuffer));
458 
459     // A generic "valid" input
460     IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
461     IGraphicBufferProducer::QueueBufferOutput output;
462 
463     // Queue the buffer back into the BQ
464     ASSERT_OK(mProducer->queueBuffer(dequeuedSlot, input, &output));
465 
466     {
467         EXPECT_EQ(DEFAULT_WIDTH, output.width);
468         EXPECT_EQ(DEFAULT_HEIGHT, output.height);
469         EXPECT_EQ(DEFAULT_TRANSFORM_HINT, output.transformHint);
470 
471         // Since queueBuffer was called exactly once
472         if (GetParam() == USE_BUFFER_QUEUE_PRODUCER) {
473             // TODO(b/70041889): BufferHubProducer need to support metadata: numPendingBuffers
474             EXPECT_EQ(1u, output.numPendingBuffers);
475             // TODO(b/70041952): BufferHubProducer need to support metadata: nextFrameNumber
476             EXPECT_EQ(2u, output.nextFrameNumber);
477         }
478     }
479 
480     // Buffer was not in the dequeued state
481     EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(dequeuedSlot, input, &output));
482 
483     { // Test batched methods
484         constexpr size_t BATCH_SIZE = 4;
485 
486         ASSERT_OK(mProducer->setMaxDequeuedBufferCount(BATCH_SIZE));
487         // Dequeue
488         using DequeueBufferInput = IGraphicBufferProducer::DequeueBufferInput;
489         using DequeueBufferOutput = IGraphicBufferProducer::DequeueBufferOutput;
490         DequeueBufferInput dequeueInput;
491         dequeueInput.width = DEFAULT_WIDTH;
492         dequeueInput.height = DEFAULT_HEIGHT;
493         dequeueInput.format = DEFAULT_FORMAT;
494         dequeueInput.usage = TEST_PRODUCER_USAGE_BITS;
495         dequeueInput.getTimestamps = false;
496         std::vector<DequeueBufferInput> dequeueInputs(BATCH_SIZE, dequeueInput);
497         std::vector<DequeueBufferOutput> dequeueOutputs;
498         EXPECT_OK(mProducer->dequeueBuffers(dequeueInputs, &dequeueOutputs));
499         ASSERT_EQ(dequeueInputs.size(), dequeueOutputs.size());
500 
501         // Request
502         std::vector<int32_t> requestInputs;
503         requestInputs.reserve(BATCH_SIZE);
504         for (const DequeueBufferOutput& dequeueOutput : dequeueOutputs) {
505             ASSERT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
506                       dequeueOutput.result);
507             requestInputs.emplace_back(dequeueOutput.slot);
508         }
509         using RequestBufferOutput = IGraphicBufferProducer::RequestBufferOutput;
510         std::vector<RequestBufferOutput> requestOutputs;
511         EXPECT_OK(mProducer->requestBuffers(requestInputs, &requestOutputs));
512         ASSERT_EQ(requestInputs.size(), requestOutputs.size());
513         for (const RequestBufferOutput& requestOutput : requestOutputs) {
514             EXPECT_OK(requestOutput.result);
515         }
516 
517         // Queue
518         using QueueBufferInput = IGraphicBufferProducer::QueueBufferInput;
519         using QueueBufferOutput = IGraphicBufferProducer::QueueBufferOutput;
520         std::vector<QueueBufferInput> queueInputs;
521         queueInputs.reserve(BATCH_SIZE);
522         for (const DequeueBufferOutput& dequeueOutput : dequeueOutputs) {
523             queueInputs.emplace_back(CreateBufferInput()).slot =
524                 dequeueOutput.slot;
525         }
526         std::vector<QueueBufferOutput> queueOutputs;
527         EXPECT_OK(mProducer->queueBuffers(queueInputs, &queueOutputs));
528         ASSERT_EQ(queueInputs.size(), queueOutputs.size());
529         for (const QueueBufferOutput& queueOutput : queueOutputs) {
530             EXPECT_OK(queueOutput.result);
531         }
532 
533         // Re-queue
534         EXPECT_OK(mProducer->queueBuffers(queueInputs, &queueOutputs));
535         ASSERT_EQ(queueInputs.size(), queueOutputs.size());
536         for (const QueueBufferOutput& queueOutput : queueOutputs) {
537             EXPECT_EQ(BAD_VALUE, queueOutput.result);
538         }
539     }
540 }
541 
TEST_P(IGraphicBufferProducerTest,Queue_ReturnsError)542 TEST_P(IGraphicBufferProducerTest, Queue_ReturnsError) {
543     ASSERT_NO_FATAL_FAILURE(ConnectProducer());
544 
545     using QueueBufferInput = IGraphicBufferProducer::QueueBufferInput;
546     using QueueBufferOutput = IGraphicBufferProducer::QueueBufferOutput;
547     // Invalid slot number
548     {
549         // A generic "valid" input
550         QueueBufferInput input = CreateBufferInput();
551         QueueBufferOutput output;
552 
553         EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(/*slot*/-1, input, &output));
554         EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(/*slot*/0xDEADBEEF, input, &output));
555         EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(BufferQueue::NUM_BUFFER_SLOTS,
556                                                     input, &output));
557 
558         { // Test with the batched version
559             constexpr size_t BATCH_SIZE = 16;
560             input.slot = -1;
561             std::vector<QueueBufferInput> inputs(BATCH_SIZE, input);
562             std::vector<QueueBufferOutput> outputs;
563             EXPECT_OK(mProducer->queueBuffers(inputs, &outputs));
564             ASSERT_EQ(inputs.size(), outputs.size());
565             for (const QueueBufferOutput& output : outputs) {
566                 EXPECT_EQ(BAD_VALUE, output.result);
567             }
568         }
569     }
570 
571     // Slot was not in the dequeued state (all slots start out in Free state)
572     {
573         QueueBufferInput input = CreateBufferInput();
574         QueueBufferOutput output;
575 
576         EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(/*slot*/0, input, &output));
577 
578         { // Test with the batched version
579             constexpr size_t BATCH_SIZE = 16;
580             input.slot = 0;
581             std::vector<QueueBufferInput> inputs(BATCH_SIZE, input);
582             std::vector<QueueBufferOutput> outputs;
583             EXPECT_OK(mProducer->queueBuffers(inputs, &outputs));
584             ASSERT_EQ(inputs.size(), outputs.size());
585             for (const QueueBufferOutput& output : outputs) {
586                 EXPECT_EQ(BAD_VALUE, output.result);
587             }
588         }
589     }
590 
591     // Put the slot into the "dequeued" state for the rest of the test
592     int dequeuedSlot = -1;
593     sp<Fence> dequeuedFence;
594 
595     ASSERT_EQ(OK,
596               ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
597                       (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, DEFAULT_WIDTH,
598                                                 DEFAULT_HEIGHT, DEFAULT_FORMAT,
599                                                 TEST_PRODUCER_USAGE_BITS, nullptr, nullptr)));
600 
601     // Slot was enqueued without requesting a buffer
602     {
603         QueueBufferInput input = CreateBufferInput();
604         QueueBufferOutput output;
605 
606         EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(dequeuedSlot, input, &output));
607 
608         { // Test with the batched version
609             constexpr size_t BATCH_SIZE = 16;
610             input.slot = dequeuedSlot;
611             std::vector<QueueBufferInput> inputs(BATCH_SIZE, input);
612             std::vector<QueueBufferOutput> outputs;
613             EXPECT_OK(mProducer->queueBuffers(inputs, &outputs));
614             ASSERT_EQ(inputs.size(), outputs.size());
615             for (const QueueBufferOutput& output : outputs) {
616                 EXPECT_EQ(BAD_VALUE, output.result);
617             }
618         }
619     }
620 
621     // Request the buffer so that the rest of the tests don't fail on earlier checks.
622     sp<GraphicBuffer> dequeuedBuffer;
623     ASSERT_OK(mProducer->requestBuffer(dequeuedSlot, &dequeuedBuffer));
624 
625     // Fence was NULL
626     {
627         sp<Fence> nullFence = nullptr;
628 
629         QueueBufferInput input =
630                 QueueBufferInputBuilder().setFence(nullFence).build();
631         QueueBufferOutput output;
632 
633         EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(dequeuedSlot, input, &output));
634 
635         { // Test with the batched version
636             constexpr size_t BATCH_SIZE = 16;
637             input.slot = dequeuedSlot;
638             std::vector<QueueBufferInput> inputs(BATCH_SIZE, input);
639             std::vector<QueueBufferOutput> outputs;
640             EXPECT_OK(mProducer->queueBuffers(inputs, &outputs));
641             ASSERT_EQ(inputs.size(), outputs.size());
642             for (const QueueBufferOutput& output : outputs) {
643                 EXPECT_EQ(BAD_VALUE, output.result);
644             }
645         }
646     }
647 
648     // Scaling mode was unknown
649     {
650         IGraphicBufferProducer::QueueBufferInput input =
651                 QueueBufferInputBuilder().setScalingMode(-1).build();
652         IGraphicBufferProducer::QueueBufferOutput output;
653 
654         EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(dequeuedSlot, input, &output));
655 
656         { // Test with the batched version
657             constexpr size_t BATCH_SIZE = 16;
658             input.slot = dequeuedSlot;
659             std::vector<QueueBufferInput> inputs(BATCH_SIZE, input);
660             std::vector<QueueBufferOutput> outputs;
661             EXPECT_OK(mProducer->queueBuffers(inputs, &outputs));
662             ASSERT_EQ(inputs.size(), outputs.size());
663             for (const QueueBufferOutput& output : outputs) {
664                 EXPECT_EQ(BAD_VALUE, output.result);
665             }
666         }
667 
668         input = QueueBufferInputBuilder().setScalingMode(0xDEADBEEF).build();
669 
670         EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(dequeuedSlot, input, &output));
671 
672         { // Test with the batched version
673             constexpr size_t BATCH_SIZE = 16;
674             input.slot = dequeuedSlot;
675             std::vector<QueueBufferInput> inputs(BATCH_SIZE, input);
676             std::vector<QueueBufferOutput> outputs;
677             EXPECT_OK(mProducer->queueBuffers(inputs, &outputs));
678             ASSERT_EQ(inputs.size(), outputs.size());
679             for (const QueueBufferOutput& output : outputs) {
680                 EXPECT_EQ(BAD_VALUE, output.result);
681             }
682         }
683     }
684 
685     // Crop rect is out of bounds of the buffer dimensions
686     {
687         IGraphicBufferProducer::QueueBufferInput input =
688                 QueueBufferInputBuilder().setCrop(Rect(DEFAULT_WIDTH + 1, DEFAULT_HEIGHT + 1))
689                 .build();
690         IGraphicBufferProducer::QueueBufferOutput output;
691 
692         EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(dequeuedSlot, input, &output));
693 
694         { // Test with the batched version
695             constexpr size_t BATCH_SIZE = 16;
696             input.slot = dequeuedSlot;
697             std::vector<QueueBufferInput> inputs(BATCH_SIZE, input);
698             std::vector<QueueBufferOutput> outputs;
699             EXPECT_OK(mProducer->queueBuffers(inputs, &outputs));
700             ASSERT_EQ(inputs.size(), outputs.size());
701             for (const QueueBufferOutput& output : outputs) {
702                 EXPECT_EQ(BAD_VALUE, output.result);
703             }
704         }
705     }
706 
707     // Abandon the buffer queue so that the last test fails
708     ASSERT_OK(mConsumer->consumerDisconnect());
709 
710     // The buffer queue has been abandoned.
711     if (GetParam() == USE_BUFFER_QUEUE_PRODUCER) {
712         IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
713         IGraphicBufferProducer::QueueBufferOutput output;
714 
715         // TODO(b/73267953): Make BufferHub honor producer and consumer connection.
716         EXPECT_EQ(NO_INIT, mProducer->queueBuffer(dequeuedSlot, input, &output));
717 
718         { // Test with the batched version
719             constexpr size_t BATCH_SIZE = 16;
720             input.slot = dequeuedSlot;
721             std::vector<QueueBufferInput> inputs(BATCH_SIZE, input);
722             std::vector<QueueBufferOutput> outputs;
723             EXPECT_OK(mProducer->queueBuffers(inputs, &outputs));
724             ASSERT_EQ(inputs.size(), outputs.size());
725             for (const QueueBufferOutput& output : outputs) {
726                 EXPECT_EQ(NO_INIT, output.result);
727             }
728         }
729     }
730 }
731 
TEST_P(IGraphicBufferProducerTest,CancelBuffer_DoesntCrash)732 TEST_P(IGraphicBufferProducerTest, CancelBuffer_DoesntCrash) {
733     ASSERT_NO_FATAL_FAILURE(ConnectProducer());
734 
735     int dequeuedSlot = -1;
736     sp<Fence> dequeuedFence;
737 
738     ASSERT_EQ(OK,
739               ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
740                       (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, DEFAULT_WIDTH,
741                                                 DEFAULT_HEIGHT, DEFAULT_FORMAT,
742                                                 TEST_PRODUCER_USAGE_BITS, nullptr, nullptr)));
743 
744     // No return code, but at least test that it doesn't blow up...
745     // TODO: add a return code
746     mProducer->cancelBuffer(dequeuedSlot, dequeuedFence);
747 
748     { // Test batched methods
749         constexpr size_t BATCH_SIZE = 4;
750         ASSERT_OK(mProducer->setMaxDequeuedBufferCount(BATCH_SIZE));
751 
752         // Dequeue
753         using DequeueBufferInput = IGraphicBufferProducer::DequeueBufferInput;
754         using DequeueBufferOutput = IGraphicBufferProducer::DequeueBufferOutput;
755         DequeueBufferInput dequeueInput;
756         dequeueInput.width = DEFAULT_WIDTH;
757         dequeueInput.height = DEFAULT_HEIGHT;
758         dequeueInput.format = DEFAULT_FORMAT;
759         dequeueInput.usage = TEST_PRODUCER_USAGE_BITS;
760         dequeueInput.getTimestamps = false;
761         std::vector<DequeueBufferInput> dequeueInputs(BATCH_SIZE, dequeueInput);
762         std::vector<DequeueBufferOutput> dequeueOutputs;
763         EXPECT_OK(mProducer->dequeueBuffers(dequeueInputs, &dequeueOutputs));
764         ASSERT_EQ(dequeueInputs.size(), dequeueOutputs.size());
765 
766         // Cancel
767         using CancelBufferInput = IGraphicBufferProducer::CancelBufferInput;
768         std::vector<CancelBufferInput> cancelInputs;
769         cancelInputs.reserve(BATCH_SIZE);
770         for (const DequeueBufferOutput& dequeueOutput : dequeueOutputs) {
771             ASSERT_EQ(OK,
772                       ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
773                       dequeueOutput.result);
774             CancelBufferInput& cancelInput = cancelInputs.emplace_back();
775             cancelInput.slot = dequeueOutput.slot;
776             cancelInput.fence = dequeueOutput.fence;
777         }
778         std::vector<status_t> cancelOutputs;
779         EXPECT_OK(mProducer->cancelBuffers(cancelInputs, &cancelOutputs));
780         ASSERT_EQ(cancelInputs.size(), cancelOutputs.size());
781         for (status_t result : cancelOutputs) {
782             EXPECT_OK(result);
783         }
784     }
785 }
786 
TEST_P(IGraphicBufferProducerTest,SetMaxDequeuedBufferCount_Succeeds)787 TEST_P(IGraphicBufferProducerTest, SetMaxDequeuedBufferCount_Succeeds) {
788     ASSERT_NO_FATAL_FAILURE(ConnectProducer());
789     int minUndequeuedBuffers;
790     ASSERT_OK(mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
791             &minUndequeuedBuffers));
792 
793     const int minBuffers = 1;
794     const int maxBuffers = BufferQueue::NUM_BUFFER_SLOTS - minUndequeuedBuffers;
795 
796     ASSERT_OK(mProducer->setAsyncMode(false)) << "async mode: " << false;
797     ASSERT_OK(mProducer->setMaxDequeuedBufferCount(minBuffers))
798             << "bufferCount: " << minBuffers;
799 
800     // Should now be able to dequeue up to minBuffers times
801     IGraphicBufferProducer::DequeueBufferOutput result;
802     for (int i = 0; i < minBuffers; ++i) {
803         EXPECT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
804                 (dequeueBuffer(DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_FORMAT,
805                                TEST_PRODUCER_USAGE_BITS, &result)))
806                 << "iteration: " << i << ", slot: " << result.slot;
807     }
808 
809     ASSERT_OK(mProducer->setMaxDequeuedBufferCount(maxBuffers));
810 
811     // queue the first buffer to enable max dequeued buffer count checking
812     IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
813     IGraphicBufferProducer::QueueBufferOutput output;
814     sp<GraphicBuffer> buffer;
815     ASSERT_OK(mProducer->requestBuffer(result.slot, &buffer));
816     ASSERT_OK(mProducer->queueBuffer(result.slot, input, &output));
817 
818     // Should now be able to dequeue up to maxBuffers times
819     int dequeuedSlot = -1;
820     sp<Fence> dequeuedFence;
821     for (int i = 0; i < maxBuffers; ++i) {
822         EXPECT_EQ(OK,
823                   ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
824                           (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, DEFAULT_WIDTH,
825                                                     DEFAULT_HEIGHT, DEFAULT_FORMAT,
826                                                     TEST_PRODUCER_USAGE_BITS, nullptr, nullptr)))
827                 << "iteration: " << i << ", slot: " << dequeuedSlot;
828     }
829 
830     // Cancel a buffer, so we can decrease the buffer count
831     ASSERT_OK(mProducer->cancelBuffer(dequeuedSlot, dequeuedFence));
832 
833     // Should now be able to decrease the max dequeued count by 1
834     ASSERT_OK(mProducer->setMaxDequeuedBufferCount(maxBuffers-1));
835 }
836 
TEST_P(IGraphicBufferProducerTest,SetMaxDequeuedBufferCount_Fails)837 TEST_P(IGraphicBufferProducerTest, SetMaxDequeuedBufferCount_Fails) {
838     ASSERT_NO_FATAL_FAILURE(ConnectProducer());
839     int minUndequeuedBuffers;
840     ASSERT_OK(mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
841                                &minUndequeuedBuffers));
842 
843     const int minBuffers = 1;
844     const int maxBuffers = BufferQueue::NUM_BUFFER_SLOTS - minUndequeuedBuffers;
845 
846     ASSERT_OK(mProducer->setAsyncMode(false)) << "async mode: " << false;
847     // Buffer count was out of range
848     EXPECT_EQ(BAD_VALUE, mProducer->setMaxDequeuedBufferCount(0))
849             << "bufferCount: " << 0;
850     EXPECT_EQ(BAD_VALUE, mProducer->setMaxDequeuedBufferCount(maxBuffers + 1))
851             << "bufferCount: " << maxBuffers + 1;
852 
853     // Set max dequeue count to 2
854     ASSERT_OK(mProducer->setMaxDequeuedBufferCount(2));
855     // Dequeue 2 buffers
856     int dequeuedSlot = -1;
857     sp<Fence> dequeuedFence;
858     for (int i = 0; i < 2; i++) {
859         ASSERT_EQ(OK,
860                   ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
861                           (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, DEFAULT_WIDTH,
862                                                     DEFAULT_HEIGHT, DEFAULT_FORMAT,
863                                                     TEST_PRODUCER_USAGE_BITS, nullptr, nullptr)))
864                 << "slot: " << dequeuedSlot;
865     }
866 
867     // Client has too many buffers dequeued
868     EXPECT_EQ(BAD_VALUE, mProducer->setMaxDequeuedBufferCount(1))
869             << "bufferCount: " << minBuffers;
870 
871     // Abandon buffer queue
872     ASSERT_OK(mConsumer->consumerDisconnect());
873 
874     // Fail because the buffer queue was abandoned
875     if (GetParam() == USE_BUFFER_QUEUE_PRODUCER) {
876         // TODO(b/73267953): Make BufferHub honor producer and consumer connection.
877         EXPECT_EQ(NO_INIT, mProducer->setMaxDequeuedBufferCount(minBuffers))
878                 << "bufferCount: " << minBuffers;
879     }
880 }
881 
TEST_P(IGraphicBufferProducerTest,SetAsyncMode_Succeeds)882 TEST_P(IGraphicBufferProducerTest, SetAsyncMode_Succeeds) {
883     if (GetParam() == USE_BUFFER_HUB_PRODUCER) {
884         // TODO(b/36724099): Add support for BufferHubProducer::setAsyncMode(true)
885         return;
886     }
887 
888     ASSERT_OK(mConsumer->setMaxAcquiredBufferCount(1)) << "maxAcquire: " << 1;
889     ASSERT_NO_FATAL_FAILURE(ConnectProducer());
890     ASSERT_OK(mProducer->setAsyncMode(true)) << "async mode: " << true;
891     ASSERT_OK(mProducer->setMaxDequeuedBufferCount(1)) << "maxDequeue: " << 1;
892 
893     int dequeuedSlot = -1;
894     sp<Fence> dequeuedFence;
895     IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
896     IGraphicBufferProducer::QueueBufferOutput output;
897     sp<GraphicBuffer> dequeuedBuffer;
898 
899     // Should now be able to queue/dequeue as many buffers as we want without
900     // blocking
901     for (int i = 0; i < 5; ++i) {
902         ASSERT_EQ(OK,
903                   ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
904                           (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, DEFAULT_WIDTH,
905                                                     DEFAULT_HEIGHT, DEFAULT_FORMAT,
906                                                     TEST_PRODUCER_USAGE_BITS, nullptr, nullptr)))
907                 << "slot : " << dequeuedSlot;
908         ASSERT_OK(mProducer->requestBuffer(dequeuedSlot, &dequeuedBuffer));
909         ASSERT_OK(mProducer->queueBuffer(dequeuedSlot, input, &output));
910     }
911 }
912 
TEST_P(IGraphicBufferProducerTest,SetAsyncMode_Fails)913 TEST_P(IGraphicBufferProducerTest, SetAsyncMode_Fails) {
914     ASSERT_NO_FATAL_FAILURE(ConnectProducer());
915     // Prerequisite to fail out a valid setBufferCount call
916     {
917         int dequeuedSlot = -1;
918         sp<Fence> dequeuedFence;
919 
920         ASSERT_EQ(OK,
921                   ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
922                           (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, DEFAULT_WIDTH,
923                                                     DEFAULT_HEIGHT, DEFAULT_FORMAT,
924                                                     TEST_PRODUCER_USAGE_BITS, nullptr, nullptr)))
925                 << "slot: " << dequeuedSlot;
926     }
927 
928     // Abandon buffer queue
929     ASSERT_OK(mConsumer->consumerDisconnect());
930 
931     // Fail because the buffer queue was abandoned
932     if (GetParam() == USE_BUFFER_QUEUE_PRODUCER) {
933         // TODO(b/36724099): Make BufferHub honor producer and consumer connection.
934         EXPECT_EQ(NO_INIT, mProducer->setAsyncMode(false)) << "asyncMode: " << false;
935     }
936 }
937 
TEST_P(IGraphicBufferProducerTest,DisconnectedProducerReturnsError_dequeueBuffer)938 TEST_P(IGraphicBufferProducerTest,
939         DisconnectedProducerReturnsError_dequeueBuffer) {
940     int slot = -1;
941     sp<Fence> fence;
942 
943     ASSERT_EQ(NO_INIT,
944               mProducer->dequeueBuffer(&slot, &fence, DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_FORMAT,
945                                        TEST_PRODUCER_USAGE_BITS, nullptr, nullptr));
946 }
947 
TEST_P(IGraphicBufferProducerTest,DisconnectedProducerReturnsError_detachNextBuffer)948 TEST_P(IGraphicBufferProducerTest,
949         DisconnectedProducerReturnsError_detachNextBuffer) {
950     sp<Fence> fence;
951     sp<GraphicBuffer> buffer;
952 
953     ASSERT_EQ(NO_INIT, mProducer->detachNextBuffer(&buffer, &fence));
954 }
955 
TEST_P(IGraphicBufferProducerTest,DisconnectedProducerReturnsError_requestBuffer)956 TEST_P(IGraphicBufferProducerTest,
957         DisconnectedProducerReturnsError_requestBuffer) {
958     ASSERT_NO_FATAL_FAILURE(ConnectProducer());
959 
960     int slot = -1;
961     sp<Fence> fence;
962 
963     ASSERT_EQ(OK,
964               ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
965                       (mProducer->dequeueBuffer(&slot, &fence, DEFAULT_WIDTH, DEFAULT_HEIGHT,
966                                                 DEFAULT_FORMAT, TEST_PRODUCER_USAGE_BITS,
967                                                 nullptr, nullptr)));
968 
969     EXPECT_LE(0, slot);
970     EXPECT_GT(BufferQueue::NUM_BUFFER_SLOTS, slot);
971 
972     ASSERT_OK(mProducer->disconnect(TEST_API));
973 
974     sp<GraphicBuffer> buffer;
975 
976     ASSERT_EQ(NO_INIT, mProducer->requestBuffer(slot, &buffer));
977 }
978 
979 
TEST_P(IGraphicBufferProducerTest,DisconnectedProducerReturnsError_detachBuffer)980 TEST_P(IGraphicBufferProducerTest,
981         DisconnectedProducerReturnsError_detachBuffer) {
982     int slot = -1;
983     sp<Fence> fence;
984     sp<GraphicBuffer> buffer;
985 
986     setupDequeueRequestBuffer(&slot, &fence, &buffer);
987 
988     ASSERT_OK(mProducer->disconnect(TEST_API));
989 
990     ASSERT_EQ(NO_INIT, mProducer->detachBuffer(slot));
991 }
992 
TEST_P(IGraphicBufferProducerTest,DisconnectedProducerReturnsError_queueBuffer)993 TEST_P(IGraphicBufferProducerTest,
994         DisconnectedProducerReturnsError_queueBuffer) {
995     int slot = -1;
996     sp<Fence> fence;
997     sp<GraphicBuffer> buffer;
998 
999     setupDequeueRequestBuffer(&slot, &fence, &buffer);
1000 
1001     ASSERT_OK(mProducer->disconnect(TEST_API));
1002 
1003     // A generic "valid" input
1004     IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
1005     IGraphicBufferProducer::QueueBufferOutput output;
1006 
1007     ASSERT_EQ(NO_INIT, mProducer->queueBuffer(slot, input, &output));
1008 }
1009 
TEST_P(IGraphicBufferProducerTest,DisconnectedProducerReturnsError_cancelBuffer)1010 TEST_P(IGraphicBufferProducerTest,
1011         DisconnectedProducerReturnsError_cancelBuffer) {
1012     int slot = -1;
1013     sp<Fence> fence;
1014     sp<GraphicBuffer> buffer;
1015 
1016     setupDequeueRequestBuffer(&slot, &fence, &buffer);
1017 
1018     ASSERT_OK(mProducer->disconnect(TEST_API));
1019 
1020     ASSERT_EQ(NO_INIT, mProducer->cancelBuffer(slot, fence));
1021 }
1022 
TEST_P(IGraphicBufferProducerTest,DisconnectedProducerReturnsError_attachBuffer)1023 TEST_P(IGraphicBufferProducerTest,
1024         DisconnectedProducerReturnsError_attachBuffer) {
1025     int slot = -1;
1026     sp<Fence> fence;
1027     sp<GraphicBuffer> buffer;
1028 
1029     setupDequeueRequestBuffer(&slot, &fence, &buffer);
1030     ASSERT_TRUE(buffer != nullptr);
1031 
1032     ASSERT_OK(mProducer->detachBuffer(slot));
1033     EXPECT_OK(buffer->initCheck());
1034 
1035     ASSERT_OK(mProducer->disconnect(TEST_API));
1036 
1037     ASSERT_EQ(NO_INIT, mProducer->attachBuffer(&slot, buffer));
1038 }
1039 
TEST_P(IGraphicBufferProducerTest,DetachThenAttach_Succeeds)1040 TEST_P(IGraphicBufferProducerTest, DetachThenAttach_Succeeds) {
1041     int slot = -1;
1042     sp<Fence> fence;
1043     sp<GraphicBuffer> buffer;
1044 
1045     setupDequeueRequestBuffer(&slot, &fence, &buffer);
1046     ASSERT_TRUE(buffer != nullptr);
1047 
1048     ASSERT_OK(mProducer->detachBuffer(slot));
1049     EXPECT_OK(buffer->initCheck());
1050 
1051     EXPECT_OK(mProducer->attachBuffer(&slot, buffer));
1052     EXPECT_OK(buffer->initCheck());
1053 
1054     ASSERT_OK(mProducer->detachBuffer(slot));
1055 
1056     { // Test batched methods
1057         constexpr size_t BATCH_SIZE = 4;
1058         ASSERT_OK(mProducer->setMaxDequeuedBufferCount(BATCH_SIZE));
1059 
1060         // Dequeue
1061         using DequeueBufferInput = IGraphicBufferProducer::DequeueBufferInput;
1062         using DequeueBufferOutput = IGraphicBufferProducer::DequeueBufferOutput;
1063         DequeueBufferInput dequeueInput;
1064         dequeueInput.width = DEFAULT_WIDTH;
1065         dequeueInput.height = DEFAULT_HEIGHT;
1066         dequeueInput.format = DEFAULT_FORMAT;
1067         dequeueInput.usage = TEST_PRODUCER_USAGE_BITS;
1068         dequeueInput.getTimestamps = false;
1069         std::vector<DequeueBufferInput> dequeueInputs(BATCH_SIZE, dequeueInput);
1070         std::vector<DequeueBufferOutput> dequeueOutputs;
1071         EXPECT_OK(mProducer->dequeueBuffers(dequeueInputs, &dequeueOutputs));
1072         ASSERT_EQ(dequeueInputs.size(), dequeueOutputs.size());
1073 
1074         // Request
1075         std::vector<int32_t> requestInputs;
1076         requestInputs.reserve(BATCH_SIZE);
1077         for (const DequeueBufferOutput& dequeueOutput : dequeueOutputs) {
1078             ASSERT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
1079                       dequeueOutput.result);
1080             requestInputs.emplace_back(dequeueOutput.slot);
1081         }
1082         using RequestBufferOutput = IGraphicBufferProducer::RequestBufferOutput;
1083         std::vector<RequestBufferOutput> requestOutputs;
1084         EXPECT_OK(mProducer->requestBuffers(requestInputs, &requestOutputs));
1085         ASSERT_EQ(requestInputs.size(), requestOutputs.size());
1086         for (const RequestBufferOutput& requestOutput : requestOutputs) {
1087             EXPECT_OK(requestOutput.result);
1088         }
1089 
1090         // Detach
1091         std::vector<int32_t> detachInputs;
1092         detachInputs.reserve(BATCH_SIZE);
1093         for (const DequeueBufferOutput& dequeueOutput : dequeueOutputs) {
1094             detachInputs.emplace_back(dequeueOutput.slot);
1095         }
1096         std::vector<status_t> detachOutputs;
1097         EXPECT_OK(mProducer->detachBuffers(detachInputs, &detachOutputs));
1098         ASSERT_EQ(detachInputs.size(), detachOutputs.size());
1099         for (status_t result : detachOutputs) {
1100             EXPECT_OK(result);
1101         }
1102 
1103         // Attach
1104         using AttachBufferOutput = IGraphicBufferProducer::AttachBufferOutput;
1105         std::vector<sp<GraphicBuffer>> attachInputs;
1106         attachInputs.reserve(BATCH_SIZE);
1107         for (const RequestBufferOutput& requestOutput : requestOutputs) {
1108             attachInputs.emplace_back(requestOutput.buffer);
1109         }
1110         std::vector<AttachBufferOutput> attachOutputs;
1111         EXPECT_OK(mProducer->attachBuffers(attachInputs, &attachOutputs));
1112         ASSERT_EQ(attachInputs.size(), attachOutputs.size());
1113         for (const AttachBufferOutput& attachOutput : attachOutputs) {
1114             EXPECT_OK(attachOutput.result);
1115             EXPECT_NE(-1, attachOutput.slot);
1116         }
1117     }
1118 }
1119 
1120 #if USE_BUFFER_HUB_AS_BUFFER_QUEUE
1121 INSTANTIATE_TEST_CASE_P(IGraphicBufferProducerBackends, IGraphicBufferProducerTest,
1122                         ::testing::Values(USE_BUFFER_QUEUE_PRODUCER, USE_BUFFER_HUB_PRODUCER));
1123 #else
1124 // TODO(b/70046255): Remove the #ifdef here and always tests both backends once BufferHubQueue can
1125 // pass all existing libgui tests.
1126 INSTANTIATE_TEST_CASE_P(IGraphicBufferProducerBackends, IGraphicBufferProducerTest,
1127                         ::testing::Values(USE_BUFFER_QUEUE_PRODUCER));
1128 #endif
1129 
1130 } // namespace android
1131