Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright 2018 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 "BufferHubBufferTest"
     18 
     19 #include <errno.h>
     20 #include <sys/epoll.h>
     21 
     22 #include <android/frameworks/bufferhub/1.0/IBufferHub.h>
     23 #include <android/hardware_buffer.h>
     24 #include <cutils/native_handle.h>
     25 #include <gmock/gmock.h>
     26 #include <gtest/gtest.h>
     27 #include <hidl/ServiceManagement.h>
     28 #include <hwbinder/IPCThreadState.h>
     29 #include <ui/BufferHubBuffer.h>
     30 #include <ui/BufferHubEventFd.h>
     31 
     32 namespace android {
     33 
     34 namespace {
     35 
     36 using ::android::BufferHubDefs::isAnyClientAcquired;
     37 using ::android::BufferHubDefs::isAnyClientGained;
     38 using ::android::BufferHubDefs::isAnyClientPosted;
     39 using ::android::BufferHubDefs::isClientAcquired;
     40 using ::android::BufferHubDefs::isClientGained;
     41 using ::android::BufferHubDefs::isClientPosted;
     42 using ::android::BufferHubDefs::isClientReleased;
     43 using ::android::BufferHubDefs::kMetadataHeaderSize;
     44 using ::android::frameworks::bufferhub::V1_0::IBufferHub;
     45 using ::testing::IsNull;
     46 using ::testing::NotNull;
     47 
     48 const int kWidth = 640;
     49 const int kHeight = 480;
     50 const int kLayerCount = 1;
     51 const int kFormat = HAL_PIXEL_FORMAT_RGBA_8888;
     52 const int kUsage = 0;
     53 const AHardwareBuffer_Desc kDesc = {kWidth, kHeight,        kLayerCount,  kFormat,
     54                                     kUsage, /*stride=*/0UL, /*rfu0=*/0UL, /*rfu1=*/0ULL};
     55 const size_t kUserMetadataSize = 1;
     56 
     57 class BufferHubBufferTest : public ::testing::Test {
     58 protected:
     59     void SetUp() override {
     60         android::hardware::ProcessState::self()->startThreadPool();
     61 
     62         if (!BufferHubServiceRunning()) {
     63             // TODO(b/112940221): Enforce the test cross all devices once BufferHub lands in Android
     64             // R for all Android varieties.
     65             GTEST_SKIP() << "Skip test as the BufferHub service is not running.";
     66         }
     67     }
     68 
     69     bool BufferHubServiceRunning() {
     70         sp<IBufferHub> bufferhub = IBufferHub::getService();
     71         return bufferhub.get() != nullptr;
     72     }
     73 };
     74 
     75 bool cmpAHardwareBufferDesc(const AHardwareBuffer_Desc& desc, const AHardwareBuffer_Desc& other) {
     76     // Not comparing stride because it's unknown before allocation
     77     return desc.format == other.format && desc.height == other.height &&
     78             desc.layers == other.layers && desc.usage == other.usage && desc.width == other.width;
     79 }
     80 
     81 class BufferHubBufferStateTransitionTest : public BufferHubBufferTest {
     82 protected:
     83     void SetUp() override {
     84         BufferHubBufferTest::SetUp();
     85 
     86         if (IsSkipped()) {
     87             // If the base class' SetUp() stated the test should be skipped, we should short
     88             // circuit this sub-class' logic.
     89             return;
     90         }
     91 
     92         CreateTwoClientsOfABuffer();
     93     }
     94 
     95     std::unique_ptr<BufferHubBuffer> b1;
     96     uint32_t b1ClientMask = 0U;
     97     std::unique_ptr<BufferHubBuffer> b2;
     98     uint32_t b2ClientMask = 0U;
     99 
    100 private:
    101     // Creates b1 and b2 as the clients of the same buffer for testing.
    102     void CreateTwoClientsOfABuffer();
    103 };
    104 
    105 void BufferHubBufferStateTransitionTest::CreateTwoClientsOfABuffer() {
    106     b1 = BufferHubBuffer::create(kWidth, kHeight, kLayerCount, kFormat, kUsage, kUserMetadataSize);
    107     ASSERT_THAT(b1, NotNull());
    108     b1ClientMask = b1->clientStateMask();
    109     ASSERT_NE(b1ClientMask, 0U);
    110 
    111     sp<NativeHandle> token = b1->duplicate();
    112     ASSERT_THAT(token, NotNull());
    113 
    114     b2 = BufferHubBuffer::import(token);
    115     ASSERT_THAT(b2, NotNull());
    116 
    117     b2ClientMask = b2->clientStateMask();
    118     ASSERT_NE(b2ClientMask, 0U);
    119     ASSERT_NE(b2ClientMask, b1ClientMask);
    120 }
    121 
    122 TEST_F(BufferHubBufferTest, CreateBufferFails) {
    123     // Buffer Creation will fail: BLOB format requires height to be 1.
    124     auto b1 = BufferHubBuffer::create(kWidth, /*height=*/2, kLayerCount,
    125                                       /*format=*/HAL_PIXEL_FORMAT_BLOB, kUsage, kUserMetadataSize);
    126 
    127     EXPECT_THAT(b1, IsNull());
    128 
    129     // Buffer Creation will fail: user metadata size too large.
    130     auto b2 = BufferHubBuffer::create(kWidth, kHeight, kLayerCount, kFormat, kUsage,
    131                                       /*userMetadataSize=*/std::numeric_limits<size_t>::max());
    132 
    133     EXPECT_THAT(b2, IsNull());
    134 
    135     // Buffer Creation will fail: user metadata size too large.
    136     const size_t userMetadataSize = std::numeric_limits<size_t>::max() - kMetadataHeaderSize;
    137     auto b3 = BufferHubBuffer::create(kWidth, kHeight, kLayerCount, kFormat, kUsage,
    138                                       userMetadataSize);
    139 
    140     EXPECT_THAT(b3, IsNull());
    141 }
    142 
    143 TEST_F(BufferHubBufferTest, CreateBuffer) {
    144     auto b1 = BufferHubBuffer::create(kWidth, kHeight, kLayerCount, kFormat, kUsage,
    145                                       kUserMetadataSize);
    146     ASSERT_THAT(b1, NotNull());
    147     EXPECT_TRUE(b1->isConnected());
    148     EXPECT_TRUE(b1->isValid());
    149     EXPECT_TRUE(cmpAHardwareBufferDesc(b1->desc(), kDesc));
    150     EXPECT_EQ(b1->userMetadataSize(), kUserMetadataSize);
    151 }
    152 
    153 TEST_F(BufferHubBufferTest, DuplicateAndImportBuffer) {
    154     auto b1 = BufferHubBuffer::create(kWidth, kHeight, kLayerCount, kFormat, kUsage,
    155                                       kUserMetadataSize);
    156     ASSERT_THAT(b1, NotNull());
    157     EXPECT_TRUE(b1->isValid());
    158 
    159     sp<NativeHandle> token = b1->duplicate();
    160     ASSERT_THAT(token, NotNull());
    161 
    162     // The detached buffer should still be valid.
    163     EXPECT_TRUE(b1->isConnected());
    164     EXPECT_TRUE(b1->isValid());
    165 
    166     std::unique_ptr<BufferHubBuffer> b2 = BufferHubBuffer::import(token);
    167 
    168     ASSERT_THAT(b2, NotNull());
    169     EXPECT_TRUE(b2->isValid());
    170 
    171     EXPECT_TRUE(cmpAHardwareBufferDesc(b1->desc(), b2->desc()));
    172     EXPECT_EQ(b1->userMetadataSize(), b2->userMetadataSize());
    173 
    174     // These two buffer instances are based on the same physical buffer under the
    175     // hood, so they should share the same id.
    176     EXPECT_EQ(b1->id(), b2->id());
    177     // We use clientStateMask() to tell those two instances apart.
    178     EXPECT_NE(b1->clientStateMask(), b2->clientStateMask());
    179 
    180     // Both buffer instances should be in released state currently.
    181     EXPECT_TRUE(b1->isReleased());
    182     EXPECT_TRUE(b2->isReleased());
    183 
    184     // The event fd should behave like duped event fds.
    185     const BufferHubEventFd& eventFd1 = b1->eventFd();
    186     ASSERT_GE(eventFd1.get(), 0);
    187     const BufferHubEventFd& eventFd2 = b2->eventFd();
    188     ASSERT_GE(eventFd2.get(), 0);
    189 
    190     base::unique_fd epollFd(epoll_create(64));
    191     ASSERT_GE(epollFd.get(), 0);
    192 
    193     // Add eventFd1 to epoll set, and signal eventFd2.
    194     epoll_event e = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 0}};
    195     ASSERT_EQ(epoll_ctl(epollFd.get(), EPOLL_CTL_ADD, eventFd1.get(), &e), 0) << strerror(errno);
    196 
    197     std::array<epoll_event, 1> events;
    198     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
    199 
    200     eventFd2.signal();
    201     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1);
    202 
    203     // The epoll fd is edge triggered, so it only responds to the eventFd once.
    204     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
    205 
    206     eventFd2.signal();
    207     eventFd2.clear();
    208     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
    209 }
    210 
    211 TEST_F(BufferHubBufferTest, ImportFreedBuffer) {
    212     auto b1 = BufferHubBuffer::create(kWidth, kHeight, kLayerCount, kFormat, kUsage,
    213                                       kUserMetadataSize);
    214     ASSERT_THAT(b1, NotNull());
    215     EXPECT_TRUE(b1->isValid());
    216 
    217     sp<NativeHandle> token = b1->duplicate();
    218     ASSERT_THAT(token, NotNull());
    219 
    220     // Explicitly destroy b1. Backend buffer should be freed and token becomes invalid
    221     b1.reset();
    222 
    223     std::unique_ptr<BufferHubBuffer> b2 = BufferHubBuffer::import(token);
    224 
    225     // Import should fail with INVALID_TOKEN
    226     EXPECT_THAT(b2, IsNull());
    227 }
    228 
    229 // nullptr must not crash the service
    230 TEST_F(BufferHubBufferTest, ImportNullToken) {
    231     auto b1 = BufferHubBuffer::import(nullptr);
    232     EXPECT_THAT(b1, IsNull());
    233 }
    234 
    235 TEST_F(BufferHubBufferTest, ImportInvalidToken) {
    236     native_handle_t* token = native_handle_create(/*numFds=*/0, /*numInts=*/1);
    237     token->data[0] = 0;
    238 
    239     sp<NativeHandle> tokenHandle = NativeHandle::create(token, /*ownHandle=*/true);
    240     auto b1 = BufferHubBuffer::import(tokenHandle);
    241 
    242     EXPECT_THAT(b1, IsNull());
    243 }
    244 
    245 TEST_F(BufferHubBufferStateTransitionTest, GainBuffer_fromReleasedState) {
    246     ASSERT_TRUE(b1->isReleased());
    247 
    248     // Successful gaining the buffer should change the buffer state bit of b1 to
    249     // gained state, other client state bits to released state.
    250     EXPECT_EQ(b1->gain(), 0);
    251     EXPECT_TRUE(isClientGained(b1->bufferState(), b1ClientMask));
    252 }
    253 
    254 TEST_F(BufferHubBufferStateTransitionTest, GainBuffer_fromGainedState) {
    255     ASSERT_EQ(b1->gain(), 0);
    256     auto currentBufferState = b1->bufferState();
    257     ASSERT_TRUE(isClientGained(currentBufferState, b1ClientMask));
    258 
    259     // Gaining from gained state by the same client should not return error.
    260     EXPECT_EQ(b1->gain(), 0);
    261 
    262     // Gaining from gained state by another client should return error.
    263     EXPECT_EQ(b2->gain(), -EBUSY);
    264 }
    265 
    266 TEST_F(BufferHubBufferStateTransitionTest, GainBuffer_fromAcquiredState) {
    267     ASSERT_EQ(b1->gain(), 0);
    268     ASSERT_EQ(b1->post(), 0);
    269     ASSERT_EQ(b2->acquire(), 0);
    270     ASSERT_TRUE(isAnyClientAcquired(b1->bufferState()));
    271 
    272     // Gaining from acquired state should fail.
    273     EXPECT_EQ(b1->gain(), -EBUSY);
    274     EXPECT_EQ(b2->gain(), -EBUSY);
    275 }
    276 
    277 TEST_F(BufferHubBufferStateTransitionTest, GainBuffer_fromOtherClientInPostedState) {
    278     ASSERT_EQ(b1->gain(), 0);
    279     ASSERT_EQ(b1->post(), 0);
    280     ASSERT_TRUE(isAnyClientPosted(b1->bufferState()));
    281 
    282     // Gaining a buffer who has other posted client should succeed.
    283     EXPECT_EQ(b1->gain(), 0);
    284 }
    285 
    286 TEST_F(BufferHubBufferStateTransitionTest, GainBuffer_fromSelfInPostedState) {
    287     ASSERT_EQ(b1->gain(), 0);
    288     ASSERT_EQ(b1->post(), 0);
    289     ASSERT_TRUE(isAnyClientPosted(b1->bufferState()));
    290 
    291     // A posted client should be able to gain the buffer when there is no other clients in
    292     // acquired state.
    293     EXPECT_EQ(b2->gain(), 0);
    294 }
    295 
    296 TEST_F(BufferHubBufferStateTransitionTest, PostBuffer_fromOtherInGainedState) {
    297     ASSERT_EQ(b1->gain(), 0);
    298     ASSERT_TRUE(isClientGained(b1->bufferState(), b1ClientMask));
    299 
    300     EXPECT_EQ(b2->post(), -EBUSY);
    301 }
    302 
    303 TEST_F(BufferHubBufferStateTransitionTest, PostBuffer_fromSelfInGainedState) {
    304     ASSERT_EQ(b1->gain(), 0);
    305     ASSERT_TRUE(isClientGained(b1->bufferState(), b1ClientMask));
    306 
    307     EXPECT_EQ(b1->post(), 0);
    308     auto currentBufferState = b1->bufferState();
    309     EXPECT_TRUE(isClientReleased(currentBufferState, b1ClientMask));
    310     EXPECT_TRUE(isClientPosted(currentBufferState, b2ClientMask));
    311 }
    312 
    313 TEST_F(BufferHubBufferStateTransitionTest, PostBuffer_fromPostedState) {
    314     ASSERT_EQ(b1->gain(), 0);
    315     ASSERT_EQ(b1->post(), 0);
    316     ASSERT_TRUE(isAnyClientPosted(b1->bufferState()));
    317 
    318     // Post from posted state should fail.
    319     EXPECT_EQ(b1->post(), -EBUSY);
    320     EXPECT_EQ(b2->post(), -EBUSY);
    321 }
    322 
    323 TEST_F(BufferHubBufferStateTransitionTest, PostBuffer_fromAcquiredState) {
    324     ASSERT_EQ(b1->gain(), 0);
    325     ASSERT_EQ(b1->post(), 0);
    326     ASSERT_EQ(b2->acquire(), 0);
    327     ASSERT_TRUE(isAnyClientAcquired(b1->bufferState()));
    328 
    329     // Posting from acquired state should fail.
    330     EXPECT_EQ(b1->post(), -EBUSY);
    331     EXPECT_EQ(b2->post(), -EBUSY);
    332 }
    333 
    334 TEST_F(BufferHubBufferStateTransitionTest, PostBuffer_fromReleasedState) {
    335     ASSERT_TRUE(b1->isReleased());
    336 
    337     // Posting from released state should fail.
    338     EXPECT_EQ(b1->post(), -EBUSY);
    339     EXPECT_EQ(b2->post(), -EBUSY);
    340 }
    341 
    342 TEST_F(BufferHubBufferStateTransitionTest, AcquireBuffer_fromSelfInPostedState) {
    343     ASSERT_EQ(b1->gain(), 0);
    344     ASSERT_EQ(b1->post(), 0);
    345     ASSERT_TRUE(isClientPosted(b1->bufferState(), b2ClientMask));
    346 
    347     // Acquire from posted state should pass.
    348     EXPECT_EQ(b2->acquire(), 0);
    349 }
    350 
    351 TEST_F(BufferHubBufferStateTransitionTest, AcquireBuffer_fromOtherInPostedState) {
    352     ASSERT_EQ(b1->gain(), 0);
    353     ASSERT_EQ(b1->post(), 0);
    354     ASSERT_TRUE(isClientPosted(b1->bufferState(), b2ClientMask));
    355 
    356     // Acquire from released state should fail, although there are other clients
    357     // in posted state.
    358     EXPECT_EQ(b1->acquire(), -EBUSY);
    359 }
    360 
    361 TEST_F(BufferHubBufferStateTransitionTest, AcquireBuffer_fromSelfInAcquiredState) {
    362     ASSERT_EQ(b1->gain(), 0);
    363     ASSERT_EQ(b1->post(), 0);
    364     ASSERT_EQ(b2->acquire(), 0);
    365     auto currentBufferState = b1->bufferState();
    366     ASSERT_TRUE(isClientAcquired(currentBufferState, b2ClientMask));
    367 
    368     // Acquiring from acquired state by the same client should not error out.
    369     EXPECT_EQ(b2->acquire(), 0);
    370 }
    371 
    372 TEST_F(BufferHubBufferStateTransitionTest, AcquireBuffer_fromReleasedState) {
    373     ASSERT_TRUE(b1->isReleased());
    374 
    375     // Acquiring form released state should fail.
    376     EXPECT_EQ(b1->acquire(), -EBUSY);
    377     EXPECT_EQ(b2->acquire(), -EBUSY);
    378 }
    379 
    380 TEST_F(BufferHubBufferStateTransitionTest, AcquireBuffer_fromGainedState) {
    381     ASSERT_EQ(b1->gain(), 0);
    382     ASSERT_TRUE(isAnyClientGained(b1->bufferState()));
    383 
    384     // Acquiring from gained state should fail.
    385     EXPECT_EQ(b1->acquire(), -EBUSY);
    386     EXPECT_EQ(b2->acquire(), -EBUSY);
    387 }
    388 
    389 TEST_F(BufferHubBufferStateTransitionTest, ReleaseBuffer_fromSelfInReleasedState) {
    390     ASSERT_TRUE(b1->isReleased());
    391 
    392     EXPECT_EQ(b1->release(), 0);
    393 }
    394 
    395 TEST_F(BufferHubBufferStateTransitionTest, ReleaseBuffer_fromSelfInGainedState) {
    396     ASSERT_TRUE(b1->isReleased());
    397     ASSERT_EQ(b1->gain(), 0);
    398     ASSERT_TRUE(isAnyClientGained(b1->bufferState()));
    399 
    400     EXPECT_EQ(b1->release(), 0);
    401 }
    402 
    403 TEST_F(BufferHubBufferStateTransitionTest, ReleaseBuffer_fromSelfInPostedState) {
    404     ASSERT_EQ(b1->gain(), 0);
    405     ASSERT_EQ(b1->post(), 0);
    406     ASSERT_TRUE(isAnyClientPosted(b1->bufferState()));
    407 
    408     EXPECT_EQ(b2->release(), 0);
    409 }
    410 
    411 TEST_F(BufferHubBufferStateTransitionTest, ReleaseBuffer_fromSelfInAcquiredState) {
    412     ASSERT_EQ(b1->gain(), 0);
    413     ASSERT_EQ(b1->post(), 0);
    414     ASSERT_EQ(b2->acquire(), 0);
    415     ASSERT_TRUE(isAnyClientAcquired(b1->bufferState()));
    416 
    417     EXPECT_EQ(b2->release(), 0);
    418 }
    419 
    420 TEST_F(BufferHubBufferStateTransitionTest, BasicUsage) {
    421     // 1 producer buffer and 1 consumer buffer initialised in testcase setup.
    422     // Test if this set of basic operation succeed:
    423     // Producer post three times to the consumer, and released by consumer.
    424     for (int i = 0; i < 3; ++i) {
    425         ASSERT_EQ(b1->gain(), 0);
    426         ASSERT_EQ(b1->post(), 0);
    427         ASSERT_EQ(b2->acquire(), 0);
    428         ASSERT_EQ(b2->release(), 0);
    429     }
    430 }
    431 
    432 TEST_F(BufferHubBufferTest, createNewConsumerAfterGain) {
    433     // Create a poducer buffer and gain.
    434     std::unique_ptr<BufferHubBuffer> b1 =
    435             BufferHubBuffer::create(kWidth, kHeight, kLayerCount, kFormat, kUsage,
    436                                     kUserMetadataSize);
    437     ASSERT_THAT(b1, NotNull());
    438     ASSERT_EQ(b1->gain(), 0);
    439 
    440     // Create a consumer of the buffer and test if the consumer can acquire the
    441     // buffer if producer posts.
    442     sp<NativeHandle> token = b1->duplicate();
    443     ASSERT_THAT(token, NotNull());
    444 
    445     std::unique_ptr<BufferHubBuffer> b2 = BufferHubBuffer::import(token);
    446 
    447     ASSERT_THAT(b2, NotNull());
    448     ASSERT_NE(b1->clientStateMask(), b2->clientStateMask());
    449 
    450     ASSERT_EQ(b1->post(), 0);
    451     EXPECT_EQ(b2->acquire(), 0);
    452 }
    453 
    454 TEST_F(BufferHubBufferTest, createNewConsumerAfterPost) {
    455     // Create a poducer buffer and post.
    456     std::unique_ptr<BufferHubBuffer> b1 =
    457             BufferHubBuffer::create(kWidth, kHeight, kLayerCount, kFormat, kUsage,
    458                                     kUserMetadataSize);
    459     ASSERT_EQ(b1->gain(), 0);
    460     ASSERT_EQ(b1->post(), 0);
    461 
    462     // Create a consumer of the buffer and test if the consumer can acquire the
    463     // buffer if producer posts.
    464     sp<NativeHandle> token = b1->duplicate();
    465     ASSERT_THAT(token, NotNull());
    466 
    467     std::unique_ptr<BufferHubBuffer> b2 = BufferHubBuffer::import(token);
    468 
    469     ASSERT_THAT(b2, NotNull());
    470     ASSERT_NE(b1->clientStateMask(), b2->clientStateMask());
    471 
    472     EXPECT_EQ(b2->acquire(), 0);
    473 }
    474 
    475 } // namespace
    476 
    477 } // namespace android
    478