| Jiwen 'Steve' Cai | 0e7ee22 | 2018-10-12 17:20:40 -0700 | [diff] [blame] | 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 |  | 
| Fan Xu | ca70b7b | 2018-10-31 13:20:12 -0700 | [diff] [blame] | 19 | #include <android/frameworks/bufferhub/1.0/IBufferClient.h> | 
| Jiwen 'Steve' Cai | d9f2abe | 2018-10-20 17:03:13 -0700 | [diff] [blame] | 20 | #include <android/frameworks/bufferhub/1.0/IBufferHub.h> | 
| Fan Xu | 93c9490 | 2018-11-01 12:22:05 -0700 | [diff] [blame] | 21 | #include <android/hardware_buffer.h> | 
| Jiwen 'Steve' Cai | 0e7ee22 | 2018-10-12 17:20:40 -0700 | [diff] [blame] | 22 | #include <gtest/gtest.h> | 
| Jiwen 'Steve' Cai | d9f2abe | 2018-10-20 17:03:13 -0700 | [diff] [blame] | 23 | #include <hidl/ServiceManagement.h> | 
 | 24 | #include <hwbinder/IPCThreadState.h> | 
| Jiwen 'Steve' Cai | 0e7ee22 | 2018-10-12 17:20:40 -0700 | [diff] [blame] | 25 | #include <ui/BufferHubBuffer.h> | 
 | 26 |  | 
 | 27 | namespace android { | 
 | 28 |  | 
 | 29 | namespace { | 
 | 30 |  | 
 | 31 | const int kWidth = 640; | 
 | 32 | const int kHeight = 480; | 
 | 33 | const int kLayerCount = 1; | 
 | 34 | const int kFormat = HAL_PIXEL_FORMAT_RGBA_8888; | 
 | 35 | const int kUsage = 0; | 
 | 36 | const size_t kUserMetadataSize = 0; | 
 | 37 |  | 
| Jiwen 'Steve' Cai | 0e7ee22 | 2018-10-12 17:20:40 -0700 | [diff] [blame] | 38 | using dvr::BufferHubDefs::IsBufferGained; | 
| Tianyu Jiang | 63dd7c3 | 2018-10-30 18:35:06 -0700 | [diff] [blame] | 39 | using dvr::BufferHubDefs::kFirstClientBitMask; | 
| Jiwen 'Steve' Cai | 0e7ee22 | 2018-10-12 17:20:40 -0700 | [diff] [blame] | 40 | using dvr::BufferHubDefs::kMetadataHeaderSize; | 
| Fan Xu | ca70b7b | 2018-10-31 13:20:12 -0700 | [diff] [blame] | 41 | using frameworks::bufferhub::V1_0::BufferHubStatus; | 
 | 42 | using frameworks::bufferhub::V1_0::IBufferClient; | 
| Jiwen 'Steve' Cai | d9f2abe | 2018-10-20 17:03:13 -0700 | [diff] [blame] | 43 | using frameworks::bufferhub::V1_0::IBufferHub; | 
 | 44 | using hardware::hidl_handle; | 
| Fan Xu | 93c9490 | 2018-11-01 12:22:05 -0700 | [diff] [blame] | 45 | using hardware::graphics::common::V1_2::HardwareBufferDescription; | 
| Jiwen 'Steve' Cai | d9f2abe | 2018-10-20 17:03:13 -0700 | [diff] [blame] | 46 | using hidl::base::V1_0::IBase; | 
| Jiwen 'Steve' Cai | 0e7ee22 | 2018-10-12 17:20:40 -0700 | [diff] [blame] | 47 | using pdx::LocalChannelHandle; | 
 | 48 |  | 
| Jiwen 'Steve' Cai | d9f2abe | 2018-10-20 17:03:13 -0700 | [diff] [blame] | 49 | class BufferHubBufferTest : public ::testing::Test { | 
 | 50 |     void SetUp() override { android::hardware::ProcessState::self()->startThreadPool(); } | 
 | 51 | }; | 
 | 52 |  | 
| Jiwen 'Steve' Cai | 0e7ee22 | 2018-10-12 17:20:40 -0700 | [diff] [blame] | 53 | TEST_F(BufferHubBufferTest, CreateBufferHubBufferFails) { | 
 | 54 |     // Buffer Creation will fail: BLOB format requires height to be 1. | 
 | 55 |     auto b1 = BufferHubBuffer::Create(kWidth, /*height=*/2, kLayerCount, | 
 | 56 |                                       /*format=*/HAL_PIXEL_FORMAT_BLOB, kUsage, kUserMetadataSize); | 
 | 57 |  | 
 | 58 |     EXPECT_FALSE(b1->IsConnected()); | 
 | 59 |     EXPECT_FALSE(b1->IsValid()); | 
 | 60 |  | 
 | 61 |     // Buffer Creation will fail: user metadata size too large. | 
 | 62 |     auto b2 = BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat, kUsage, | 
 | 63 |                                       /*userMetadataSize=*/std::numeric_limits<size_t>::max()); | 
 | 64 |  | 
 | 65 |     EXPECT_FALSE(b2->IsConnected()); | 
 | 66 |     EXPECT_FALSE(b2->IsValid()); | 
 | 67 |  | 
 | 68 |     // Buffer Creation will fail: user metadata size too large. | 
 | 69 |     const size_t userMetadataSize = std::numeric_limits<size_t>::max() - kMetadataHeaderSize; | 
 | 70 |     auto b3 = BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat, kUsage, | 
 | 71 |                                       userMetadataSize); | 
 | 72 |  | 
 | 73 |     EXPECT_FALSE(b3->IsConnected()); | 
 | 74 |     EXPECT_FALSE(b3->IsValid()); | 
 | 75 | } | 
 | 76 |  | 
 | 77 | TEST_F(BufferHubBufferTest, CreateBufferHubBuffer) { | 
 | 78 |     auto b1 = BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat, kUsage, | 
 | 79 |                                       kUserMetadataSize); | 
 | 80 |     EXPECT_TRUE(b1->IsConnected()); | 
 | 81 |     EXPECT_TRUE(b1->IsValid()); | 
 | 82 |     EXPECT_NE(b1->id(), 0); | 
 | 83 | } | 
 | 84 |  | 
 | 85 | TEST_F(BufferHubBufferTest, DuplicateBufferHubBuffer) { | 
 | 86 |     auto b1 = BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat, kUsage, | 
 | 87 |                                       kUserMetadataSize); | 
 | 88 |     int id1 = b1->id(); | 
| Tianyu Jiang | 8f10b75 | 2018-10-30 17:24:51 -0700 | [diff] [blame] | 89 |     uint64_t bufferStateMask1 = b1->client_state_mask(); | 
 | 90 |     EXPECT_NE(bufferStateMask1, 0ULL); | 
| Jiwen 'Steve' Cai | 0e7ee22 | 2018-10-12 17:20:40 -0700 | [diff] [blame] | 91 |     EXPECT_TRUE(b1->IsValid()); | 
 | 92 |     EXPECT_EQ(b1->user_metadata_size(), kUserMetadataSize); | 
 | 93 |  | 
 | 94 |     auto statusOrHandle = b1->Duplicate(); | 
 | 95 |     EXPECT_TRUE(statusOrHandle); | 
 | 96 |  | 
 | 97 |     // The detached buffer should still be valid. | 
 | 98 |     EXPECT_TRUE(b1->IsConnected()); | 
 | 99 |     EXPECT_TRUE(b1->IsValid()); | 
 | 100 |  | 
 | 101 |     // Gets the channel handle for the duplicated buffer. | 
 | 102 |     LocalChannelHandle h2 = statusOrHandle.take(); | 
 | 103 |     EXPECT_TRUE(h2.valid()); | 
 | 104 |  | 
 | 105 |     std::unique_ptr<BufferHubBuffer> b2 = BufferHubBuffer::Import(std::move(h2)); | 
 | 106 |     EXPECT_FALSE(h2.valid()); | 
 | 107 |     ASSERT_TRUE(b2 != nullptr); | 
 | 108 |     EXPECT_TRUE(b2->IsValid()); | 
 | 109 |     EXPECT_EQ(b2->user_metadata_size(), kUserMetadataSize); | 
 | 110 |  | 
 | 111 |     int id2 = b2->id(); | 
| Tianyu Jiang | 8f10b75 | 2018-10-30 17:24:51 -0700 | [diff] [blame] | 112 |     uint64_t bufferStateMask2 = b2->client_state_mask(); | 
 | 113 |     EXPECT_NE(bufferStateMask2, 0ULL); | 
| Jiwen 'Steve' Cai | 0e7ee22 | 2018-10-12 17:20:40 -0700 | [diff] [blame] | 114 |  | 
 | 115 |     // These two buffer instances are based on the same physical buffer under the | 
 | 116 |     // hood, so they should share the same id. | 
 | 117 |     EXPECT_EQ(id1, id2); | 
| Tianyu Jiang | 7e204b7 | 2018-10-26 15:39:18 -0700 | [diff] [blame] | 118 |     // We use client_state_mask() to tell those two instances apart. | 
| Tianyu Jiang | 8f10b75 | 2018-10-30 17:24:51 -0700 | [diff] [blame] | 119 |     EXPECT_NE(bufferStateMask1, bufferStateMask2); | 
| Jiwen 'Steve' Cai | 0e7ee22 | 2018-10-12 17:20:40 -0700 | [diff] [blame] | 120 |  | 
 | 121 |     // Both buffer instances should be in gained state. | 
 | 122 |     EXPECT_TRUE(IsBufferGained(b1->buffer_state())); | 
 | 123 |     EXPECT_TRUE(IsBufferGained(b2->buffer_state())); | 
 | 124 |  | 
 | 125 |     // TODO(b/112338294): rewrite test after migration | 
 | 126 |     return; | 
| Jiwen 'Steve' Cai | 0e7ee22 | 2018-10-12 17:20:40 -0700 | [diff] [blame] | 127 | } | 
 | 128 |  | 
| Fan Xu | 93c9490 | 2018-11-01 12:22:05 -0700 | [diff] [blame] | 129 | TEST_F(BufferHubBufferTest, AllocateBuffer) { | 
 | 130 |     // TODO(b/116681016): directly test on BufferHubBuffer instead of the service. | 
 | 131 |     sp<IBufferHub> bufferHub = IBufferHub::getService(); | 
 | 132 |     ASSERT_NE(nullptr, bufferHub.get()); | 
| Jiwen 'Steve' Cai | d9f2abe | 2018-10-20 17:03:13 -0700 | [diff] [blame] | 133 |  | 
| Fan Xu | 93c9490 | 2018-11-01 12:22:05 -0700 | [diff] [blame] | 134 |     // Stride is an output, rfu0 and rfu1 are reserved data slot for future use. | 
 | 135 |     AHardwareBuffer_Desc aDesc = {kWidth, kHeight,        kLayerCount,  kFormat, | 
 | 136 |                                   kUsage, /*stride=*/0UL, /*rfu0=*/0UL, /*rfu1=*/0ULL}; | 
 | 137 |     HardwareBufferDescription desc; | 
 | 138 |     memcpy(&desc, &aDesc, sizeof(HardwareBufferDescription)); | 
 | 139 |  | 
 | 140 |     IBufferHub::allocateBuffer_cb callback = [](const auto& client, const auto& status) { | 
 | 141 |         EXPECT_EQ(status, BufferHubStatus::NO_ERROR); | 
 | 142 |         EXPECT_NE(nullptr, client.get()); | 
 | 143 |     }; | 
 | 144 |     EXPECT_TRUE(bufferHub->allocateBuffer(desc, kUserMetadataSize, callback).isOk()); | 
| Jiwen 'Steve' Cai | d9f2abe | 2018-10-20 17:03:13 -0700 | [diff] [blame] | 145 | } | 
 | 146 |  | 
| Fan Xu | 18d90ea | 2018-11-06 15:46:44 -0800 | [diff] [blame] | 147 | TEST_F(BufferHubBufferTest, DuplicateBuffer) { | 
 | 148 |     // TODO(b/116681016): directly test on BufferHubBuffer instead of the service. | 
 | 149 |     sp<IBufferHub> bufferhub = IBufferHub::getService(); | 
 | 150 |     ASSERT_NE(nullptr, bufferhub.get()); | 
 | 151 |  | 
 | 152 |     // Stride is an output, rfu0 and rfu1 are reserved data slot for future use. | 
 | 153 |     AHardwareBuffer_Desc aDesc = {kWidth, kHeight,        kLayerCount,  kFormat, | 
 | 154 |                                   kUsage, /*stride=*/0UL, /*rfu0=*/0UL, /*rfu1=*/0ULL}; | 
 | 155 |     HardwareBufferDescription desc; | 
 | 156 |     memcpy(&desc, &aDesc, sizeof(HardwareBufferDescription)); | 
 | 157 |  | 
 | 158 |     sp<IBufferClient> client; | 
 | 159 |     IBufferHub::allocateBuffer_cb alloc_cb = [&](const auto& outClient, const auto& status) { | 
 | 160 |         ASSERT_EQ(status, BufferHubStatus::NO_ERROR); | 
 | 161 |         ASSERT_NE(nullptr, outClient.get()); | 
 | 162 |         client = outClient; | 
 | 163 |     }; | 
 | 164 |     ASSERT_TRUE(bufferhub->allocateBuffer(desc, kUserMetadataSize, alloc_cb).isOk()); | 
 | 165 |  | 
 | 166 |     IBufferClient::duplicate_cb dup_cb = [](const auto& token, const auto& status) { | 
 | 167 |         ASSERT_EQ(status, BufferHubStatus::NO_ERROR); | 
 | 168 |         ASSERT_NE(token.getNativeHandle(), nullptr); | 
 | 169 |         EXPECT_EQ(token->numInts, 1); | 
 | 170 |         EXPECT_EQ(token->numFds, 0); | 
 | 171 |     }; | 
 | 172 |     EXPECT_TRUE(client->duplicate(dup_cb).isOk()); | 
 | 173 | } | 
 | 174 |  | 
| Fan Xu | ca70b7b | 2018-10-31 13:20:12 -0700 | [diff] [blame] | 175 | } // namespace | 
| Jiwen 'Steve' Cai | 0e7ee22 | 2018-10-12 17:20:40 -0700 | [diff] [blame] | 176 | } // namespace android |