• 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 "DummyConsumer.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 
74     // Enums to control which IGraphicBufferProducer backend to test.
75     enum IGraphicBufferProducerTestCode {
76         USE_BUFFER_QUEUE_PRODUCER = 0,
77         USE_BUFFER_HUB_PRODUCER,
78     };
79 }; // namespace anonymous
80 
81 class IGraphicBufferProducerTest : public ::testing::TestWithParam<uint32_t> {
82 protected:
83 
IGraphicBufferProducerTest()84     IGraphicBufferProducerTest() {}
85 
SetUp()86     virtual void SetUp() {
87         const ::testing::TestInfo* const testInfo =
88             ::testing::UnitTest::GetInstance()->current_test_info();
89         ALOGV("Begin test: %s.%s", testInfo->test_case_name(),
90                 testInfo->name());
91 
92         mDC = new DummyConsumer;
93 
94         switch (GetParam()) {
95             case USE_BUFFER_QUEUE_PRODUCER: {
96                 BufferQueue::createBufferQueue(&mProducer, &mConsumer);
97                 break;
98             }
99             case USE_BUFFER_HUB_PRODUCER: {
100                 BufferQueue::createBufferHubQueue(&mProducer, &mConsumer);
101                 break;
102             }
103             default: {
104                 // Should never reach here.
105                 LOG_ALWAYS_FATAL("Invalid test params: %u", GetParam());
106                 break;
107             }
108         }
109 
110         // Test check: Can't connect producer if no consumer yet
111         if (GetParam() == USE_BUFFER_QUEUE_PRODUCER) {
112             // TODO(b/73267953): Make BufferHub honor producer and consumer connection.
113             ASSERT_EQ(NO_INIT, TryConnectProducer());
114         }
115 
116         // Must connect consumer before producer connects will succeed.
117         ASSERT_OK(mConsumer->consumerConnect(mDC, /*controlledByApp*/false));
118     }
119 
TearDown()120     virtual void TearDown() {
121         const ::testing::TestInfo* const testInfo =
122             ::testing::UnitTest::GetInstance()->current_test_info();
123         ALOGV("End test:   %s.%s", testInfo->test_case_name(),
124                 testInfo->name());
125     }
126 
TryConnectProducer()127     status_t TryConnectProducer() {
128         IGraphicBufferProducer::QueueBufferOutput output;
129         return mProducer->connect(TEST_TOKEN,
130                                   TEST_API,
131                                   TEST_CONTROLLED_BY_APP,
132                                   &output);
133         // TODO: use params to vary token, api, producercontrolledbyapp, etc
134     }
135 
136     // Connect to a producer in a 'correct' fashion.
137     //   Precondition: Consumer is connected.
ConnectProducer()138     void ConnectProducer() {
139         ASSERT_OK(TryConnectProducer());
140     }
141 
142     // Create a generic "valid" input for queueBuffer
143     // -- uses the default buffer format, width, etc.
CreateBufferInput()144     static IGraphicBufferProducer::QueueBufferInput CreateBufferInput() {
145         return QueueBufferInputBuilder().build();
146     }
147 
148     // Builder pattern to slightly vary *almost* correct input
149     // -- avoids copying and pasting
150     struct QueueBufferInputBuilder {
QueueBufferInputBuilderandroid::IGraphicBufferProducerTest::QueueBufferInputBuilder151         QueueBufferInputBuilder() {
152            timestamp = QUEUE_BUFFER_INPUT_TIMESTAMP;
153            isAutoTimestamp = QUEUE_BUFFER_INPUT_IS_AUTO_TIMESTAMP;
154            dataSpace = QUEUE_BUFFER_INPUT_DATASPACE;
155            crop = QUEUE_BUFFER_INPUT_RECT;
156            scalingMode = QUEUE_BUFFER_INPUT_SCALING_MODE;
157            transform = QUEUE_BUFFER_INPUT_TRANSFORM;
158            fence = QUEUE_BUFFER_INPUT_FENCE;
159         }
160 
buildandroid::IGraphicBufferProducerTest::QueueBufferInputBuilder161         IGraphicBufferProducer::QueueBufferInput build() {
162             return IGraphicBufferProducer::QueueBufferInput(
163                     timestamp,
164                     isAutoTimestamp,
165                     dataSpace,
166                     crop,
167                     scalingMode,
168                     transform,
169                     fence);
170         }
171 
setTimestampandroid::IGraphicBufferProducerTest::QueueBufferInputBuilder172         QueueBufferInputBuilder& setTimestamp(int64_t timestamp) {
173             this->timestamp = timestamp;
174             return *this;
175         }
176 
setIsAutoTimestampandroid::IGraphicBufferProducerTest::QueueBufferInputBuilder177         QueueBufferInputBuilder& setIsAutoTimestamp(bool isAutoTimestamp) {
178             this->isAutoTimestamp = isAutoTimestamp;
179             return *this;
180         }
181 
setDataSpaceandroid::IGraphicBufferProducerTest::QueueBufferInputBuilder182         QueueBufferInputBuilder& setDataSpace(android_dataspace dataSpace) {
183             this->dataSpace = dataSpace;
184             return *this;
185         }
186 
setCropandroid::IGraphicBufferProducerTest::QueueBufferInputBuilder187         QueueBufferInputBuilder& setCrop(Rect crop) {
188             this->crop = crop;
189             return *this;
190         }
191 
setScalingModeandroid::IGraphicBufferProducerTest::QueueBufferInputBuilder192         QueueBufferInputBuilder& setScalingMode(int scalingMode) {
193             this->scalingMode = scalingMode;
194             return *this;
195         }
196 
setTransformandroid::IGraphicBufferProducerTest::QueueBufferInputBuilder197         QueueBufferInputBuilder& setTransform(uint32_t transform) {
198             this->transform = transform;
199             return *this;
200         }
201 
setFenceandroid::IGraphicBufferProducerTest::QueueBufferInputBuilder202         QueueBufferInputBuilder& setFence(sp<Fence> fence) {
203             this->fence = fence;
204             return *this;
205         }
206 
207     private:
208         int64_t timestamp;
209         bool isAutoTimestamp;
210         android_dataspace dataSpace;
211         Rect crop;
212         int scalingMode;
213         uint32_t transform;
214         sp<Fence> fence;
215     }; // struct QueueBufferInputBuilder
216 
217     // To easily store dequeueBuffer results into containers
218     struct DequeueBufferResult {
219         int slot;
220         sp<Fence> fence;
221     };
222 
dequeueBuffer(uint32_t w,uint32_t h,uint32_t format,uint32_t usage,DequeueBufferResult * result)223     status_t dequeueBuffer(uint32_t w, uint32_t h, uint32_t format, uint32_t usage, DequeueBufferResult* result) {
224         return mProducer->dequeueBuffer(&result->slot, &result->fence, w, h, format, usage,
225                                         nullptr, nullptr);
226     }
227 
setupDequeueRequestBuffer(int * slot,sp<Fence> * fence,sp<GraphicBuffer> * buffer)228     void setupDequeueRequestBuffer(int *slot, sp<Fence> *fence,
229             sp<GraphicBuffer> *buffer)
230     {
231         ASSERT_TRUE(slot != nullptr);
232         ASSERT_TRUE(fence != nullptr);
233         ASSERT_TRUE(buffer != nullptr);
234 
235         ASSERT_NO_FATAL_FAILURE(ConnectProducer());
236 
237 
238         ASSERT_EQ(OK,
239                   ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
240                           (mProducer->dequeueBuffer(slot, fence, DEFAULT_WIDTH, DEFAULT_HEIGHT,
241                                                     DEFAULT_FORMAT, TEST_PRODUCER_USAGE_BITS,
242                                                     nullptr, nullptr)));
243 
244         EXPECT_LE(0, *slot);
245         EXPECT_GT(BufferQueue::NUM_BUFFER_SLOTS, *slot);
246 
247         // Request the buffer (pre-requisite for queueing)
248         ASSERT_OK(mProducer->requestBuffer(*slot, buffer));
249     }
250 
251 private: // hide from test body
252     sp<DummyConsumer> mDC;
253 
254 protected: // accessible from test body
255     sp<IGraphicBufferProducer> mProducer;
256     sp<IGraphicBufferConsumer> mConsumer;
257 };
258 
TEST_P(IGraphicBufferProducerTest,ConnectFirst_ReturnsError)259 TEST_P(IGraphicBufferProducerTest, ConnectFirst_ReturnsError) {
260     IGraphicBufferProducer::QueueBufferOutput output;
261 
262     // NULL output returns BAD_VALUE
263     EXPECT_EQ(BAD_VALUE, mProducer->connect(TEST_TOKEN,
264                                             TEST_API,
265                                             TEST_CONTROLLED_BY_APP,
266                                             /*output*/nullptr));
267 
268     // Invalid API returns bad value
269     EXPECT_EQ(BAD_VALUE, mProducer->connect(TEST_TOKEN,
270                                             /*api*/0xDEADBEEF,
271                                             TEST_CONTROLLED_BY_APP,
272                                             &output));
273 
274     // TODO: get a token from a dead process somehow
275 }
276 
TEST_P(IGraphicBufferProducerTest,ConnectAgain_ReturnsError)277 TEST_P(IGraphicBufferProducerTest, ConnectAgain_ReturnsError) {
278     ASSERT_NO_FATAL_FAILURE(ConnectProducer());
279 
280     // Can't connect when there is already a producer connected
281     IGraphicBufferProducer::QueueBufferOutput output;
282     EXPECT_EQ(BAD_VALUE, mProducer->connect(TEST_TOKEN,
283                                             TEST_API,
284                                             TEST_CONTROLLED_BY_APP,
285                                             &output));
286 
287     ASSERT_OK(mConsumer->consumerDisconnect());
288     // Can't connect when IGBP is abandoned
289     if (GetParam() == USE_BUFFER_QUEUE_PRODUCER) {
290         // TODO(b/73267953): Make BufferHub honor producer and consumer connection.
291         EXPECT_EQ(NO_INIT, mProducer->connect(TEST_TOKEN,
292                                               TEST_API,
293                                               TEST_CONTROLLED_BY_APP,
294                                               &output));
295     }
296 }
297 
TEST_P(IGraphicBufferProducerTest,Disconnect_Succeeds)298 TEST_P(IGraphicBufferProducerTest, Disconnect_Succeeds) {
299     ASSERT_NO_FATAL_FAILURE(ConnectProducer());
300 
301     ASSERT_OK(mProducer->disconnect(TEST_API));
302 }
303 
304 
TEST_P(IGraphicBufferProducerTest,Disconnect_ReturnsError)305 TEST_P(IGraphicBufferProducerTest, Disconnect_ReturnsError) {
306     ASSERT_NO_FATAL_FAILURE(ConnectProducer());
307 
308     // Must disconnect with same API number
309     ASSERT_EQ(BAD_VALUE, mProducer->disconnect(TEST_API_OTHER));
310     // API must not be out of range
311     ASSERT_EQ(BAD_VALUE, mProducer->disconnect(/*api*/0xDEADBEEF));
312 
313     // TODO: somehow kill mProducer so that this returns DEAD_OBJECT
314 }
315 
TEST_P(IGraphicBufferProducerTest,Query_Succeeds)316 TEST_P(IGraphicBufferProducerTest, Query_Succeeds) {
317     ASSERT_NO_FATAL_FAILURE(ConnectProducer());
318 
319     int32_t value = -1;
320     EXPECT_OK(mProducer->query(NATIVE_WINDOW_WIDTH, &value));
321     EXPECT_EQ(DEFAULT_WIDTH, static_cast<uint32_t>(value));
322 
323     EXPECT_OK(mProducer->query(NATIVE_WINDOW_HEIGHT, &value));
324     EXPECT_EQ(DEFAULT_HEIGHT, static_cast<uint32_t>(value));
325 
326     EXPECT_OK(mProducer->query(NATIVE_WINDOW_FORMAT, &value));
327     EXPECT_EQ(DEFAULT_FORMAT, value);
328 
329     EXPECT_OK(mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &value));
330     EXPECT_LE(0, value);
331     EXPECT_GE(BufferQueue::NUM_BUFFER_SLOTS, value);
332 
333     EXPECT_OK(mProducer->query(NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND, &value));
334     EXPECT_FALSE(value); // Can't run behind when we haven't touched the queue
335 
336     EXPECT_OK(mProducer->query(NATIVE_WINDOW_CONSUMER_USAGE_BITS, &value));
337     EXPECT_EQ(DEFAULT_CONSUMER_USAGE_BITS, value);
338 
339 }
340 
TEST_P(IGraphicBufferProducerTest,Query_ReturnsError)341 TEST_P(IGraphicBufferProducerTest, Query_ReturnsError) {
342     ASSERT_NO_FATAL_FAILURE(ConnectProducer());
343 
344     // One past the end of the last 'query' enum value. Update this if we add more enums.
345     const int NATIVE_WINDOW_QUERY_LAST_OFF_BY_ONE = NATIVE_WINDOW_BUFFER_AGE + 1;
346 
347     int value;
348     // What was out of range
349     EXPECT_EQ(BAD_VALUE, mProducer->query(/*what*/-1, &value));
350     EXPECT_EQ(BAD_VALUE, mProducer->query(/*what*/0xDEADBEEF, &value));
351     EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_QUERY_LAST_OFF_BY_ONE, &value));
352 
353     // Some enums from window.h are 'invalid'
354     EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER, &value));
355     EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_CONCRETE_TYPE, &value));
356     EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_DEFAULT_WIDTH, &value));
357     EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_DEFAULT_HEIGHT, &value));
358     EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_TRANSFORM_HINT, &value));
359     // TODO: Consider documented the above enums as unsupported or make a new enum for IGBP
360 
361     // Value was NULL
362     EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_FORMAT, /*value*/nullptr));
363 
364     ASSERT_OK(mConsumer->consumerDisconnect());
365 
366     // BQ was abandoned
367     if (GetParam() == USE_BUFFER_QUEUE_PRODUCER) {
368         // TODO(b/73267953): Make BufferHub honor producer and consumer connection.
369         EXPECT_EQ(NO_INIT, mProducer->query(NATIVE_WINDOW_FORMAT, &value));
370     }
371 
372     // TODO: other things in window.h that are supported by Surface::query
373     // but not by BufferQueue::query
374 }
375 
376 // TODO: queue under more complicated situations not involving just a single buffer
TEST_P(IGraphicBufferProducerTest,Queue_Succeeds)377 TEST_P(IGraphicBufferProducerTest, Queue_Succeeds) {
378     ASSERT_NO_FATAL_FAILURE(ConnectProducer());
379 
380     int dequeuedSlot = -1;
381     sp<Fence> dequeuedFence;
382 
383     ASSERT_EQ(OK,
384               ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
385                       (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, DEFAULT_WIDTH,
386                                                 DEFAULT_HEIGHT, DEFAULT_FORMAT,
387                                                 TEST_PRODUCER_USAGE_BITS, nullptr, nullptr)));
388 
389     EXPECT_LE(0, dequeuedSlot);
390     EXPECT_GT(BufferQueue::NUM_BUFFER_SLOTS, dequeuedSlot);
391 
392     // Request the buffer (pre-requisite for queueing)
393     sp<GraphicBuffer> dequeuedBuffer;
394     ASSERT_OK(mProducer->requestBuffer(dequeuedSlot, &dequeuedBuffer));
395 
396     // A generic "valid" input
397     IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
398     IGraphicBufferProducer::QueueBufferOutput output;
399 
400     // Queue the buffer back into the BQ
401     ASSERT_OK(mProducer->queueBuffer(dequeuedSlot, input, &output));
402 
403     {
404         EXPECT_EQ(DEFAULT_WIDTH, output.width);
405         EXPECT_EQ(DEFAULT_HEIGHT, output.height);
406         EXPECT_EQ(DEFAULT_TRANSFORM_HINT, output.transformHint);
407 
408         // Since queueBuffer was called exactly once
409         if (GetParam() == USE_BUFFER_QUEUE_PRODUCER) {
410             // TODO(b/70041889): BufferHubProducer need to support metadata: numPendingBuffers
411             EXPECT_EQ(1u, output.numPendingBuffers);
412             // TODO(b/70041952): BufferHubProducer need to support metadata: nextFrameNumber
413             EXPECT_EQ(2u, output.nextFrameNumber);
414         }
415     }
416 
417     // Buffer was not in the dequeued state
418     EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(dequeuedSlot, input, &output));
419 }
420 
TEST_P(IGraphicBufferProducerTest,Queue_ReturnsError)421 TEST_P(IGraphicBufferProducerTest, Queue_ReturnsError) {
422     ASSERT_NO_FATAL_FAILURE(ConnectProducer());
423 
424     // Invalid slot number
425     {
426         // A generic "valid" input
427         IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
428         IGraphicBufferProducer::QueueBufferOutput output;
429 
430         EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(/*slot*/-1, input, &output));
431         EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(/*slot*/0xDEADBEEF, input, &output));
432         EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(BufferQueue::NUM_BUFFER_SLOTS,
433                                                     input, &output));
434     }
435 
436     // Slot was not in the dequeued state (all slots start out in Free state)
437     {
438         IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
439         IGraphicBufferProducer::QueueBufferOutput output;
440 
441         EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(/*slot*/0, input, &output));
442     }
443 
444     // Put the slot into the "dequeued" state for the rest of the test
445     int dequeuedSlot = -1;
446     sp<Fence> dequeuedFence;
447 
448     ASSERT_EQ(OK,
449               ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
450                       (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, DEFAULT_WIDTH,
451                                                 DEFAULT_HEIGHT, DEFAULT_FORMAT,
452                                                 TEST_PRODUCER_USAGE_BITS, nullptr, nullptr)));
453 
454     // Slot was enqueued without requesting a buffer
455     {
456         IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
457         IGraphicBufferProducer::QueueBufferOutput output;
458 
459         EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(dequeuedSlot, input, &output));
460     }
461 
462     // Request the buffer so that the rest of the tests don't fail on earlier checks.
463     sp<GraphicBuffer> dequeuedBuffer;
464     ASSERT_OK(mProducer->requestBuffer(dequeuedSlot, &dequeuedBuffer));
465 
466     // Fence was NULL
467     {
468         sp<Fence> nullFence = nullptr;
469 
470         IGraphicBufferProducer::QueueBufferInput input =
471                 QueueBufferInputBuilder().setFence(nullFence).build();
472         IGraphicBufferProducer::QueueBufferOutput output;
473 
474         EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(dequeuedSlot, input, &output));
475     }
476 
477     // Scaling mode was unknown
478     {
479         IGraphicBufferProducer::QueueBufferInput input =
480                 QueueBufferInputBuilder().setScalingMode(-1).build();
481         IGraphicBufferProducer::QueueBufferOutput output;
482 
483         EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(dequeuedSlot, input, &output));
484 
485         input = QueueBufferInputBuilder().setScalingMode(0xDEADBEEF).build();
486 
487         EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(dequeuedSlot, input, &output));
488     }
489 
490     // Crop rect is out of bounds of the buffer dimensions
491     {
492         IGraphicBufferProducer::QueueBufferInput input =
493                 QueueBufferInputBuilder().setCrop(Rect(DEFAULT_WIDTH + 1, DEFAULT_HEIGHT + 1))
494                 .build();
495         IGraphicBufferProducer::QueueBufferOutput output;
496 
497         EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(dequeuedSlot, input, &output));
498     }
499 
500     // Abandon the buffer queue so that the last test fails
501     ASSERT_OK(mConsumer->consumerDisconnect());
502 
503     // The buffer queue has been abandoned.
504     if (GetParam() == USE_BUFFER_QUEUE_PRODUCER) {
505         IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
506         IGraphicBufferProducer::QueueBufferOutput output;
507 
508         // TODO(b/73267953): Make BufferHub honor producer and consumer connection.
509         EXPECT_EQ(NO_INIT, mProducer->queueBuffer(dequeuedSlot, input, &output));
510     }
511 }
512 
TEST_P(IGraphicBufferProducerTest,CancelBuffer_DoesntCrash)513 TEST_P(IGraphicBufferProducerTest, CancelBuffer_DoesntCrash) {
514     ASSERT_NO_FATAL_FAILURE(ConnectProducer());
515 
516     int dequeuedSlot = -1;
517     sp<Fence> dequeuedFence;
518 
519     ASSERT_EQ(OK,
520               ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
521                       (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, DEFAULT_WIDTH,
522                                                 DEFAULT_HEIGHT, DEFAULT_FORMAT,
523                                                 TEST_PRODUCER_USAGE_BITS, nullptr, nullptr)));
524 
525     // No return code, but at least test that it doesn't blow up...
526     // TODO: add a return code
527     mProducer->cancelBuffer(dequeuedSlot, dequeuedFence);
528 }
529 
TEST_P(IGraphicBufferProducerTest,SetMaxDequeuedBufferCount_Succeeds)530 TEST_P(IGraphicBufferProducerTest, SetMaxDequeuedBufferCount_Succeeds) {
531     ASSERT_NO_FATAL_FAILURE(ConnectProducer());
532     int minUndequeuedBuffers;
533     ASSERT_OK(mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
534             &minUndequeuedBuffers));
535 
536     const int minBuffers = 1;
537     const int maxBuffers = BufferQueue::NUM_BUFFER_SLOTS - minUndequeuedBuffers;
538 
539     ASSERT_OK(mProducer->setAsyncMode(false)) << "async mode: " << false;
540     ASSERT_OK(mProducer->setMaxDequeuedBufferCount(minBuffers))
541             << "bufferCount: " << minBuffers;
542 
543     // Should now be able to dequeue up to minBuffers times
544     DequeueBufferResult result;
545     for (int i = 0; i < minBuffers; ++i) {
546 
547         EXPECT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
548                 (dequeueBuffer(DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_FORMAT,
549                               TEST_PRODUCER_USAGE_BITS, &result)))
550                 << "iteration: " << i << ", slot: " << result.slot;
551     }
552 
553     ASSERT_OK(mProducer->setMaxDequeuedBufferCount(maxBuffers));
554 
555     // queue the first buffer to enable max dequeued buffer count checking
556     IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
557     IGraphicBufferProducer::QueueBufferOutput output;
558     sp<GraphicBuffer> buffer;
559     ASSERT_OK(mProducer->requestBuffer(result.slot, &buffer));
560     ASSERT_OK(mProducer->queueBuffer(result.slot, input, &output));
561 
562 
563     // Should now be able to dequeue up to maxBuffers times
564     int dequeuedSlot = -1;
565     sp<Fence> dequeuedFence;
566     for (int i = 0; i < maxBuffers; ++i) {
567         EXPECT_EQ(OK,
568                   ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
569                           (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, DEFAULT_WIDTH,
570                                                     DEFAULT_HEIGHT, DEFAULT_FORMAT,
571                                                     TEST_PRODUCER_USAGE_BITS, nullptr, nullptr)))
572                 << "iteration: " << i << ", slot: " << dequeuedSlot;
573     }
574 
575     // Cancel a buffer, so we can decrease the buffer count
576     ASSERT_OK(mProducer->cancelBuffer(dequeuedSlot, dequeuedFence));
577 
578     // Should now be able to decrease the max dequeued count by 1
579     ASSERT_OK(mProducer->setMaxDequeuedBufferCount(maxBuffers-1));
580 }
581 
TEST_P(IGraphicBufferProducerTest,SetMaxDequeuedBufferCount_Fails)582 TEST_P(IGraphicBufferProducerTest, SetMaxDequeuedBufferCount_Fails) {
583     ASSERT_NO_FATAL_FAILURE(ConnectProducer());
584     int minUndequeuedBuffers;
585     ASSERT_OK(mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
586                                &minUndequeuedBuffers));
587 
588     const int minBuffers = 1;
589     const int maxBuffers = BufferQueue::NUM_BUFFER_SLOTS - minUndequeuedBuffers;
590 
591     ASSERT_OK(mProducer->setAsyncMode(false)) << "async mode: " << false;
592     // Buffer count was out of range
593     EXPECT_EQ(BAD_VALUE, mProducer->setMaxDequeuedBufferCount(0))
594             << "bufferCount: " << 0;
595     EXPECT_EQ(BAD_VALUE, mProducer->setMaxDequeuedBufferCount(maxBuffers + 1))
596             << "bufferCount: " << maxBuffers + 1;
597 
598     // Set max dequeue count to 2
599     ASSERT_OK(mProducer->setMaxDequeuedBufferCount(2));
600     // Dequeue 2 buffers
601     int dequeuedSlot = -1;
602     sp<Fence> dequeuedFence;
603     for (int i = 0; i < 2; i++) {
604         ASSERT_EQ(OK,
605                   ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
606                           (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, DEFAULT_WIDTH,
607                                                     DEFAULT_HEIGHT, DEFAULT_FORMAT,
608                                                     TEST_PRODUCER_USAGE_BITS, nullptr, nullptr)))
609                 << "slot: " << dequeuedSlot;
610     }
611 
612     // Client has too many buffers dequeued
613     EXPECT_EQ(BAD_VALUE, mProducer->setMaxDequeuedBufferCount(1))
614             << "bufferCount: " << minBuffers;
615 
616     // Abandon buffer queue
617     ASSERT_OK(mConsumer->consumerDisconnect());
618 
619     // Fail because the buffer queue was abandoned
620     if (GetParam() == USE_BUFFER_QUEUE_PRODUCER) {
621         // TODO(b/73267953): Make BufferHub honor producer and consumer connection.
622         EXPECT_EQ(NO_INIT, mProducer->setMaxDequeuedBufferCount(minBuffers))
623                 << "bufferCount: " << minBuffers;
624     }
625 }
626 
TEST_P(IGraphicBufferProducerTest,SetAsyncMode_Succeeds)627 TEST_P(IGraphicBufferProducerTest, SetAsyncMode_Succeeds) {
628     if (GetParam() == USE_BUFFER_HUB_PRODUCER) {
629         // TODO(b/36724099): Add support for BufferHubProducer::setAsyncMode(true)
630         return;
631     }
632 
633     ASSERT_OK(mConsumer->setMaxAcquiredBufferCount(1)) << "maxAcquire: " << 1;
634     ASSERT_NO_FATAL_FAILURE(ConnectProducer());
635     ASSERT_OK(mProducer->setAsyncMode(true)) << "async mode: " << true;
636     ASSERT_OK(mProducer->setMaxDequeuedBufferCount(1)) << "maxDequeue: " << 1;
637 
638     int dequeuedSlot = -1;
639     sp<Fence> dequeuedFence;
640     IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
641     IGraphicBufferProducer::QueueBufferOutput output;
642     sp<GraphicBuffer> dequeuedBuffer;
643 
644     // Should now be able to queue/dequeue as many buffers as we want without
645     // blocking
646     for (int i = 0; i < 5; ++i) {
647         ASSERT_EQ(OK,
648                   ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
649                           (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, DEFAULT_WIDTH,
650                                                     DEFAULT_HEIGHT, DEFAULT_FORMAT,
651                                                     TEST_PRODUCER_USAGE_BITS, nullptr, nullptr)))
652                 << "slot : " << dequeuedSlot;
653         ASSERT_OK(mProducer->requestBuffer(dequeuedSlot, &dequeuedBuffer));
654         ASSERT_OK(mProducer->queueBuffer(dequeuedSlot, input, &output));
655     }
656 }
657 
TEST_P(IGraphicBufferProducerTest,SetAsyncMode_Fails)658 TEST_P(IGraphicBufferProducerTest, SetAsyncMode_Fails) {
659     ASSERT_NO_FATAL_FAILURE(ConnectProducer());
660     // Prerequisite to fail out a valid setBufferCount call
661     {
662         int dequeuedSlot = -1;
663         sp<Fence> dequeuedFence;
664 
665         ASSERT_EQ(OK,
666                   ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
667                           (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, DEFAULT_WIDTH,
668                                                     DEFAULT_HEIGHT, DEFAULT_FORMAT,
669                                                     TEST_PRODUCER_USAGE_BITS, nullptr, nullptr)))
670                 << "slot: " << dequeuedSlot;
671     }
672 
673     // Abandon buffer queue
674     ASSERT_OK(mConsumer->consumerDisconnect());
675 
676     // Fail because the buffer queue was abandoned
677     if (GetParam() == USE_BUFFER_QUEUE_PRODUCER) {
678         // TODO(b/36724099): Make BufferHub honor producer and consumer connection.
679         EXPECT_EQ(NO_INIT, mProducer->setAsyncMode(false)) << "asyncMode: " << false;
680     }
681 }
682 
TEST_P(IGraphicBufferProducerTest,DisconnectedProducerReturnsError_dequeueBuffer)683 TEST_P(IGraphicBufferProducerTest,
684         DisconnectedProducerReturnsError_dequeueBuffer) {
685     int slot = -1;
686     sp<Fence> fence;
687 
688     ASSERT_EQ(NO_INIT,
689               mProducer->dequeueBuffer(&slot, &fence, DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_FORMAT,
690                                        TEST_PRODUCER_USAGE_BITS, nullptr, nullptr));
691 }
692 
TEST_P(IGraphicBufferProducerTest,DisconnectedProducerReturnsError_detachNextBuffer)693 TEST_P(IGraphicBufferProducerTest,
694         DisconnectedProducerReturnsError_detachNextBuffer) {
695     sp<Fence> fence;
696     sp<GraphicBuffer> buffer;
697 
698     ASSERT_EQ(NO_INIT, mProducer->detachNextBuffer(&buffer, &fence));
699 }
700 
TEST_P(IGraphicBufferProducerTest,DisconnectedProducerReturnsError_requestBuffer)701 TEST_P(IGraphicBufferProducerTest,
702         DisconnectedProducerReturnsError_requestBuffer) {
703     ASSERT_NO_FATAL_FAILURE(ConnectProducer());
704 
705     int slot = -1;
706     sp<Fence> fence;
707 
708     ASSERT_EQ(OK,
709               ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
710                       (mProducer->dequeueBuffer(&slot, &fence, DEFAULT_WIDTH, DEFAULT_HEIGHT,
711                                                 DEFAULT_FORMAT, TEST_PRODUCER_USAGE_BITS,
712                                                 nullptr, nullptr)));
713 
714     EXPECT_LE(0, slot);
715     EXPECT_GT(BufferQueue::NUM_BUFFER_SLOTS, slot);
716 
717     ASSERT_OK(mProducer->disconnect(TEST_API));
718 
719     sp<GraphicBuffer> buffer;
720 
721     ASSERT_EQ(NO_INIT, mProducer->requestBuffer(slot, &buffer));
722 }
723 
724 
TEST_P(IGraphicBufferProducerTest,DisconnectedProducerReturnsError_detachBuffer)725 TEST_P(IGraphicBufferProducerTest,
726         DisconnectedProducerReturnsError_detachBuffer) {
727     int slot = -1;
728     sp<Fence> fence;
729     sp<GraphicBuffer> buffer;
730 
731     setupDequeueRequestBuffer(&slot, &fence, &buffer);
732 
733     ASSERT_OK(mProducer->disconnect(TEST_API));
734 
735     ASSERT_EQ(NO_INIT, mProducer->detachBuffer(slot));
736 }
737 
TEST_P(IGraphicBufferProducerTest,DisconnectedProducerReturnsError_queueBuffer)738 TEST_P(IGraphicBufferProducerTest,
739         DisconnectedProducerReturnsError_queueBuffer) {
740     int slot = -1;
741     sp<Fence> fence;
742     sp<GraphicBuffer> buffer;
743 
744     setupDequeueRequestBuffer(&slot, &fence, &buffer);
745 
746     ASSERT_OK(mProducer->disconnect(TEST_API));
747 
748     // A generic "valid" input
749     IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
750     IGraphicBufferProducer::QueueBufferOutput output;
751 
752     ASSERT_EQ(NO_INIT, mProducer->queueBuffer(slot, input, &output));
753 }
754 
TEST_P(IGraphicBufferProducerTest,DisconnectedProducerReturnsError_cancelBuffer)755 TEST_P(IGraphicBufferProducerTest,
756         DisconnectedProducerReturnsError_cancelBuffer) {
757     int slot = -1;
758     sp<Fence> fence;
759     sp<GraphicBuffer> buffer;
760 
761     setupDequeueRequestBuffer(&slot, &fence, &buffer);
762 
763     ASSERT_OK(mProducer->disconnect(TEST_API));
764 
765     ASSERT_EQ(NO_INIT, mProducer->cancelBuffer(slot, fence));
766 }
767 
TEST_P(IGraphicBufferProducerTest,DisconnectedProducerReturnsError_attachBuffer)768 TEST_P(IGraphicBufferProducerTest,
769         DisconnectedProducerReturnsError_attachBuffer) {
770     int slot = -1;
771     sp<Fence> fence;
772     sp<GraphicBuffer> buffer;
773 
774     setupDequeueRequestBuffer(&slot, &fence, &buffer);
775     ASSERT_TRUE(buffer != nullptr);
776 
777     ASSERT_OK(mProducer->detachBuffer(slot));
778     EXPECT_OK(buffer->initCheck());
779 
780     ASSERT_OK(mProducer->disconnect(TEST_API));
781 
782     ASSERT_EQ(NO_INIT, mProducer->attachBuffer(&slot, buffer));
783 }
784 
TEST_P(IGraphicBufferProducerTest,DetachThenAttach_Succeeds)785 TEST_P(IGraphicBufferProducerTest, DetachThenAttach_Succeeds) {
786     int slot = -1;
787     sp<Fence> fence;
788     sp<GraphicBuffer> buffer;
789 
790     setupDequeueRequestBuffer(&slot, &fence, &buffer);
791     ASSERT_TRUE(buffer != nullptr);
792 
793     ASSERT_OK(mProducer->detachBuffer(slot));
794     EXPECT_OK(buffer->initCheck());
795 
796     EXPECT_OK(mProducer->attachBuffer(&slot, buffer));
797     EXPECT_OK(buffer->initCheck());
798 }
799 
800 #if USE_BUFFER_HUB_AS_BUFFER_QUEUE
801 INSTANTIATE_TEST_CASE_P(IGraphicBufferProducerBackends, IGraphicBufferProducerTest,
802                         ::testing::Values(USE_BUFFER_QUEUE_PRODUCER, USE_BUFFER_HUB_PRODUCER));
803 #else
804 // TODO(b/70046255): Remove the #ifdef here and always tests both backends once BufferHubQueue can
805 // pass all existing libgui tests.
806 INSTANTIATE_TEST_CASE_P(IGraphicBufferProducerBackends, IGraphicBufferProducerTest,
807                         ::testing::Values(USE_BUFFER_QUEUE_PRODUCER));
808 #endif
809 
810 } // namespace android
811