blob: 6c7d06bd0de0b46cc52458d35e5535df609b35ee [file] [log] [blame]
Jiwen 'Steve' Cai0e7ee222018-10-12 17:20:40 -07001/*
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 Xuca70b7b2018-10-31 13:20:12 -070019#include <android/frameworks/bufferhub/1.0/IBufferClient.h>
Jiwen 'Steve' Caid9f2abe2018-10-20 17:03:13 -070020#include <android/frameworks/bufferhub/1.0/IBufferHub.h>
Fan Xu93c94902018-11-01 12:22:05 -070021#include <android/hardware_buffer.h>
Fan Xu467e08f2018-11-09 15:58:51 -080022#include <cutils/native_handle.h>
Jiwen 'Steve' Cai0e7ee222018-10-12 17:20:40 -070023#include <gtest/gtest.h>
Jiwen 'Steve' Caid9f2abe2018-10-20 17:03:13 -070024#include <hidl/ServiceManagement.h>
25#include <hwbinder/IPCThreadState.h>
Jiwen 'Steve' Cai0e7ee222018-10-12 17:20:40 -070026#include <ui/BufferHubBuffer.h>
27
28namespace android {
29
30namespace {
31
32const int kWidth = 640;
33const int kHeight = 480;
34const int kLayerCount = 1;
35const int kFormat = HAL_PIXEL_FORMAT_RGBA_8888;
36const int kUsage = 0;
37const size_t kUserMetadataSize = 0;
38
Tianyuf669f6a2018-10-10 15:34:32 -070039using dvr::BufferHubDefs::IsBufferReleased;
Tianyu Jiang63dd7c32018-10-30 18:35:06 -070040using dvr::BufferHubDefs::kFirstClientBitMask;
Jiwen 'Steve' Cai0e7ee222018-10-12 17:20:40 -070041using dvr::BufferHubDefs::kMetadataHeaderSize;
Fan Xuca70b7b2018-10-31 13:20:12 -070042using frameworks::bufferhub::V1_0::BufferHubStatus;
43using frameworks::bufferhub::V1_0::IBufferClient;
Jiwen 'Steve' Caid9f2abe2018-10-20 17:03:13 -070044using frameworks::bufferhub::V1_0::IBufferHub;
45using hardware::hidl_handle;
Fan Xu93c94902018-11-01 12:22:05 -070046using hardware::graphics::common::V1_2::HardwareBufferDescription;
Jiwen 'Steve' Caid9f2abe2018-10-20 17:03:13 -070047using hidl::base::V1_0::IBase;
Jiwen 'Steve' Cai0e7ee222018-10-12 17:20:40 -070048using pdx::LocalChannelHandle;
49
Jiwen 'Steve' Caid9f2abe2018-10-20 17:03:13 -070050class BufferHubBufferTest : public ::testing::Test {
51 void SetUp() override { android::hardware::ProcessState::self()->startThreadPool(); }
52};
53
Jiwen 'Steve' Cai0e7ee222018-10-12 17:20:40 -070054TEST_F(BufferHubBufferTest, CreateBufferHubBufferFails) {
55 // Buffer Creation will fail: BLOB format requires height to be 1.
56 auto b1 = BufferHubBuffer::Create(kWidth, /*height=*/2, kLayerCount,
57 /*format=*/HAL_PIXEL_FORMAT_BLOB, kUsage, kUserMetadataSize);
58
59 EXPECT_FALSE(b1->IsConnected());
60 EXPECT_FALSE(b1->IsValid());
61
62 // Buffer Creation will fail: user metadata size too large.
63 auto b2 = BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat, kUsage,
64 /*userMetadataSize=*/std::numeric_limits<size_t>::max());
65
66 EXPECT_FALSE(b2->IsConnected());
67 EXPECT_FALSE(b2->IsValid());
68
69 // Buffer Creation will fail: user metadata size too large.
70 const size_t userMetadataSize = std::numeric_limits<size_t>::max() - kMetadataHeaderSize;
71 auto b3 = BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat, kUsage,
72 userMetadataSize);
73
74 EXPECT_FALSE(b3->IsConnected());
75 EXPECT_FALSE(b3->IsValid());
76}
77
78TEST_F(BufferHubBufferTest, CreateBufferHubBuffer) {
79 auto b1 = BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat, kUsage,
80 kUserMetadataSize);
81 EXPECT_TRUE(b1->IsConnected());
82 EXPECT_TRUE(b1->IsValid());
83 EXPECT_NE(b1->id(), 0);
84}
85
86TEST_F(BufferHubBufferTest, DuplicateBufferHubBuffer) {
87 auto b1 = BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat, kUsage,
88 kUserMetadataSize);
89 int id1 = b1->id();
Tianyu Jiang8f10b752018-10-30 17:24:51 -070090 uint64_t bufferStateMask1 = b1->client_state_mask();
91 EXPECT_NE(bufferStateMask1, 0ULL);
Jiwen 'Steve' Cai0e7ee222018-10-12 17:20:40 -070092 EXPECT_TRUE(b1->IsValid());
93 EXPECT_EQ(b1->user_metadata_size(), kUserMetadataSize);
94
95 auto statusOrHandle = b1->Duplicate();
96 EXPECT_TRUE(statusOrHandle);
97
98 // The detached buffer should still be valid.
99 EXPECT_TRUE(b1->IsConnected());
100 EXPECT_TRUE(b1->IsValid());
101
102 // Gets the channel handle for the duplicated buffer.
103 LocalChannelHandle h2 = statusOrHandle.take();
104 EXPECT_TRUE(h2.valid());
105
106 std::unique_ptr<BufferHubBuffer> b2 = BufferHubBuffer::Import(std::move(h2));
107 EXPECT_FALSE(h2.valid());
108 ASSERT_TRUE(b2 != nullptr);
109 EXPECT_TRUE(b2->IsValid());
110 EXPECT_EQ(b2->user_metadata_size(), kUserMetadataSize);
111
112 int id2 = b2->id();
Tianyu Jiang8f10b752018-10-30 17:24:51 -0700113 uint64_t bufferStateMask2 = b2->client_state_mask();
114 EXPECT_NE(bufferStateMask2, 0ULL);
Jiwen 'Steve' Cai0e7ee222018-10-12 17:20:40 -0700115
116 // These two buffer instances are based on the same physical buffer under the
117 // hood, so they should share the same id.
118 EXPECT_EQ(id1, id2);
Tianyu Jiang7e204b72018-10-26 15:39:18 -0700119 // We use client_state_mask() to tell those two instances apart.
Tianyu Jiang8f10b752018-10-30 17:24:51 -0700120 EXPECT_NE(bufferStateMask1, bufferStateMask2);
Jiwen 'Steve' Cai0e7ee222018-10-12 17:20:40 -0700121
Tianyuf669f6a2018-10-10 15:34:32 -0700122 // Both buffer instances should be in released state currently.
123 EXPECT_TRUE(IsBufferReleased(b1->buffer_state()));
124 EXPECT_TRUE(IsBufferReleased(b2->buffer_state()));
Jiwen 'Steve' Cai0e7ee222018-10-12 17:20:40 -0700125
126 // TODO(b/112338294): rewrite test after migration
127 return;
Jiwen 'Steve' Cai0e7ee222018-10-12 17:20:40 -0700128}
129
Fan Xua7422fe2018-11-19 15:21:32 -0800130TEST_F(BufferHubBufferTest, AllocateAndFreeBuffer) {
Fan Xu93c94902018-11-01 12:22:05 -0700131 // TODO(b/116681016): directly test on BufferHubBuffer instead of the service.
132 sp<IBufferHub> bufferHub = IBufferHub::getService();
133 ASSERT_NE(nullptr, bufferHub.get());
Jiwen 'Steve' Caid9f2abe2018-10-20 17:03:13 -0700134
Fan Xu93c94902018-11-01 12:22:05 -0700135 // Stride is an output, rfu0 and rfu1 are reserved data slot for future use.
136 AHardwareBuffer_Desc aDesc = {kWidth, kHeight, kLayerCount, kFormat,
137 kUsage, /*stride=*/0UL, /*rfu0=*/0UL, /*rfu1=*/0ULL};
138 HardwareBufferDescription desc;
139 memcpy(&desc, &aDesc, sizeof(HardwareBufferDescription));
140
Fan Xua7422fe2018-11-19 15:21:32 -0800141 sp<IBufferClient> client;
142 BufferHubStatus ret;
143 IBufferHub::allocateBuffer_cb callback = [&](const auto& outClient, const auto& outStatus) {
144 client = outClient;
145 ret = outStatus;
Fan Xu93c94902018-11-01 12:22:05 -0700146 };
147 EXPECT_TRUE(bufferHub->allocateBuffer(desc, kUserMetadataSize, callback).isOk());
Fan Xua7422fe2018-11-19 15:21:32 -0800148 EXPECT_EQ(ret, BufferHubStatus::NO_ERROR);
149 ASSERT_NE(nullptr, client.get());
150
151 EXPECT_EQ(BufferHubStatus::NO_ERROR, client->close());
152 EXPECT_EQ(BufferHubStatus::CLIENT_CLOSED, client->close());
153}
154
155TEST_F(BufferHubBufferTest, DuplicateFreedBuffer) {
156 // TODO(b/116681016): directly test on BufferHubBuffer instead of the service.
157 sp<IBufferHub> bufferHub = IBufferHub::getService();
158 ASSERT_NE(nullptr, bufferHub.get());
159
160 // Stride is an output, rfu0 and rfu1 are reserved data slot for future use.
161 AHardwareBuffer_Desc aDesc = {kWidth, kHeight, kLayerCount, kFormat,
162 kUsage, /*stride=*/0UL, /*rfu0=*/0UL, /*rfu1=*/0ULL};
163 HardwareBufferDescription desc;
164 memcpy(&desc, &aDesc, sizeof(HardwareBufferDescription));
165
166 sp<IBufferClient> client;
167 BufferHubStatus ret;
168 IBufferHub::allocateBuffer_cb callback = [&](const auto& outClient, const auto& outStatus) {
169 client = outClient;
170 ret = outStatus;
171 };
172 EXPECT_TRUE(bufferHub->allocateBuffer(desc, kUserMetadataSize, callback).isOk());
173 EXPECT_EQ(ret, BufferHubStatus::NO_ERROR);
174 ASSERT_NE(nullptr, client.get());
175
176 EXPECT_EQ(BufferHubStatus::NO_ERROR, client->close());
177
178 hidl_handle token;
179 IBufferClient::duplicate_cb dup_cb = [&](const auto& outToken, const auto& status) {
180 token = outToken;
181 ret = status;
182 };
183 EXPECT_TRUE(client->duplicate(dup_cb).isOk());
184 EXPECT_EQ(ret, BufferHubStatus::CLIENT_CLOSED);
185 EXPECT_EQ(token.getNativeHandle(), nullptr);
Jiwen 'Steve' Caid9f2abe2018-10-20 17:03:13 -0700186}
187
Fan Xu467e08f2018-11-09 15:58:51 -0800188TEST_F(BufferHubBufferTest, DuplicateAndImportBuffer) {
Fan Xu18d90ea2018-11-06 15:46:44 -0800189 // TODO(b/116681016): directly test on BufferHubBuffer instead of the service.
190 sp<IBufferHub> bufferhub = IBufferHub::getService();
191 ASSERT_NE(nullptr, bufferhub.get());
192
193 // Stride is an output, rfu0 and rfu1 are reserved data slot for future use.
194 AHardwareBuffer_Desc aDesc = {kWidth, kHeight, kLayerCount, kFormat,
195 kUsage, /*stride=*/0UL, /*rfu0=*/0UL, /*rfu1=*/0ULL};
196 HardwareBufferDescription desc;
197 memcpy(&desc, &aDesc, sizeof(HardwareBufferDescription));
198
199 sp<IBufferClient> client;
Fan Xuc32c1722018-11-16 14:38:29 -0800200 BufferHubStatus ret;
Fan Xu18d90ea2018-11-06 15:46:44 -0800201 IBufferHub::allocateBuffer_cb alloc_cb = [&](const auto& outClient, const auto& status) {
Fan Xu18d90ea2018-11-06 15:46:44 -0800202 client = outClient;
Fan Xuc32c1722018-11-16 14:38:29 -0800203 ret = status;
Fan Xu18d90ea2018-11-06 15:46:44 -0800204 };
205 ASSERT_TRUE(bufferhub->allocateBuffer(desc, kUserMetadataSize, alloc_cb).isOk());
Fan Xuc32c1722018-11-16 14:38:29 -0800206 EXPECT_EQ(ret, BufferHubStatus::NO_ERROR);
207 ASSERT_NE(nullptr, client.get());
Fan Xu18d90ea2018-11-06 15:46:44 -0800208
Fan Xuc32c1722018-11-16 14:38:29 -0800209 hidl_handle token;
210 IBufferClient::duplicate_cb dup_cb = [&](const auto& outToken, const auto& status) {
211 token = outToken;
212 ret = status;
Fan Xu18d90ea2018-11-06 15:46:44 -0800213 };
Fan Xu467e08f2018-11-09 15:58:51 -0800214 ASSERT_TRUE(client->duplicate(dup_cb).isOk());
Fan Xuc32c1722018-11-16 14:38:29 -0800215 EXPECT_EQ(ret, BufferHubStatus::NO_ERROR);
216 ASSERT_NE(token.getNativeHandle(), nullptr);
217 EXPECT_EQ(token->numInts, 1);
218 EXPECT_EQ(token->numFds, 0);
Fan Xu467e08f2018-11-09 15:58:51 -0800219
220 sp<IBufferClient> client2;
221 IBufferHub::importBuffer_cb import_cb = [&](const auto& outClient, const auto& status) {
222 ret = status;
223 client2 = outClient;
224 };
225 ASSERT_TRUE(bufferhub->importBuffer(token, import_cb).isOk());
226 EXPECT_EQ(ret, BufferHubStatus::NO_ERROR);
227 EXPECT_NE(nullptr, client2.get());
228 // TODO(b/116681016): once BufferNode.id() is exposed via BufferHubBuffer, check origin.id =
229 // improted.id here.
230}
231
232// nullptr must not crash the service
233TEST_F(BufferHubBufferTest, ImportNullToken) {
234 // TODO(b/116681016): directly test on BufferHubBuffer instead of the service.
235 sp<IBufferHub> bufferhub = IBufferHub::getService();
236 ASSERT_NE(nullptr, bufferhub.get());
237
238 hidl_handle nullToken;
239 sp<IBufferClient> client;
240 BufferHubStatus ret;
241 IBufferHub::importBuffer_cb import_cb = [&](const auto& outClient, const auto& status) {
242 client = outClient;
243 ret = status;
244 };
245 ASSERT_TRUE(bufferhub->importBuffer(nullToken, import_cb).isOk());
246 EXPECT_EQ(ret, BufferHubStatus::INVALID_TOKEN);
247 EXPECT_EQ(nullptr, client.get());
248}
249
250// This test has a very little chance to fail (number of existing tokens / 2 ^ 32)
251TEST_F(BufferHubBufferTest, ImportInvalidToken) {
252 // TODO(b/116681016): directly test on BufferHubBuffer instead of the service.
253 sp<IBufferHub> bufferhub = IBufferHub::getService();
254 ASSERT_NE(nullptr, bufferhub.get());
255
256 native_handle_t* tokenHandle = native_handle_create(/*numFds=*/0, /*numInts=*/1);
257 tokenHandle->data[0] = 0;
258
259 hidl_handle invalidToken(tokenHandle);
260 sp<IBufferClient> client;
261 BufferHubStatus ret;
262 IBufferHub::importBuffer_cb import_cb = [&](const auto& outClient, const auto& status) {
263 client = outClient;
264 ret = status;
265 };
266 ASSERT_TRUE(bufferhub->importBuffer(invalidToken, import_cb).isOk());
267 EXPECT_EQ(ret, BufferHubStatus::INVALID_TOKEN);
268 EXPECT_EQ(nullptr, client.get());
269
270 native_handle_delete(tokenHandle);
Fan Xu18d90ea2018-11-06 15:46:44 -0800271}
272
Fan Xua7422fe2018-11-19 15:21:32 -0800273TEST_F(BufferHubBufferTest, ImportFreedBuffer) {
274 // TODO(b/116681016): directly test on BufferHubBuffer instead of the service.
275 sp<IBufferHub> bufferhub = IBufferHub::getService();
276 ASSERT_NE(nullptr, bufferhub.get());
277
278 // Stride is an output, rfu0 and rfu1 are reserved data slot for future use.
279 AHardwareBuffer_Desc aDesc = {kWidth, kHeight, kLayerCount, kFormat,
280 kUsage, /*stride=*/0UL, /*rfu0=*/0UL, /*rfu1=*/0ULL};
281 HardwareBufferDescription desc;
282 memcpy(&desc, &aDesc, sizeof(HardwareBufferDescription));
283
284 sp<IBufferClient> client;
285 BufferHubStatus ret;
286 IBufferHub::allocateBuffer_cb alloc_cb = [&](const auto& outClient, const auto& status) {
287 client = outClient;
288 ret = status;
289 };
290 ASSERT_TRUE(bufferhub->allocateBuffer(desc, kUserMetadataSize, alloc_cb).isOk());
291 EXPECT_EQ(ret, BufferHubStatus::NO_ERROR);
292 ASSERT_NE(nullptr, client.get());
293
294 hidl_handle token;
295 IBufferClient::duplicate_cb dup_cb = [&](const auto& outToken, const auto& status) {
296 token = outToken;
297 ret = status;
298 };
299 ASSERT_TRUE(client->duplicate(dup_cb).isOk());
300 EXPECT_EQ(ret, BufferHubStatus::NO_ERROR);
301 ASSERT_NE(token.getNativeHandle(), nullptr);
302 EXPECT_EQ(token->numInts, 1);
303 EXPECT_EQ(token->numFds, 0);
304
305 // Close the client. Now the token should be invalid.
306 client->close();
307
308 sp<IBufferClient> client2;
309 IBufferHub::importBuffer_cb import_cb = [&](const auto& outClient, const auto& status) {
310 client2 = outClient;
311 ret = status;
312 };
313 EXPECT_TRUE(bufferhub->importBuffer(token, import_cb).isOk());
314 EXPECT_EQ(ret, BufferHubStatus::INVALID_TOKEN);
315 EXPECT_EQ(nullptr, client2.get());
316}
317
Fan Xuca70b7b2018-10-31 13:20:12 -0700318} // namespace
Jiwen 'Steve' Cai0e7ee222018-10-12 17:20:40 -0700319} // namespace android