Home | History | Annotate | Download | only in tests
      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 
     84     IGraphicBufferProducerTest() {}
     85 
     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 
    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 
    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.
    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.
    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 {
    151         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 
    161         IGraphicBufferProducer::QueueBufferInput build() {
    162             return IGraphicBufferProducer::QueueBufferInput(
    163                     timestamp,
    164                     isAutoTimestamp,
    165                     dataSpace,
    166                     crop,
    167                     scalingMode,
    168                     transform,
    169                     fence);
    170         }
    171 
    172         QueueBufferInputBuilder& setTimestamp(int64_t timestamp) {
    173             this->timestamp = timestamp;
    174             return *this;
    175         }
    176 
    177         QueueBufferInputBuilder& setIsAutoTimestamp(bool isAutoTimestamp) {
    178             this->isAutoTimestamp = isAutoTimestamp;
    179             return *this;
    180         }
    181 
    182         QueueBufferInputBuilder& setDataSpace(android_dataspace dataSpace) {
    183             this->dataSpace = dataSpace;
    184             return *this;
    185         }
    186 
    187         QueueBufferInputBuilder& setCrop(Rect crop) {
    188             this->crop = crop;
    189             return *this;
    190         }
    191 
    192         QueueBufferInputBuilder& setScalingMode(int scalingMode) {
    193             this->scalingMode = scalingMode;
    194             return *this;
    195         }
    196 
    197         QueueBufferInputBuilder& setTransform(uint32_t transform) {
    198             this->transform = transform;
    199             return *this;
    200         }
    201 
    202         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 
    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 
    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 
    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 
    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 
    298 TEST_P(IGraphicBufferProducerTest, Disconnect_Succeeds) {
    299     ASSERT_NO_FATAL_FAILURE(ConnectProducer());
    300 
    301     ASSERT_OK(mProducer->disconnect(TEST_API));
    302 }
    303 
    304 
    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 
    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 
    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
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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