1 /*
2 * Copyright (C) 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 #include <errno.h>
18 #include <sys/types.h>
19 #include <sys/socket.h>
20 #include <sys/un.h>
21 #include <unistd.h>
22
23 #include <sstream>
24 #include <string>
25
26 #include <android/hardware_buffer.h>
27 #include <gtest/gtest.h>
28
29 //#define LOG_NDEBUG 0
30
31 #define BAD_VALUE -EINVAL
32 #define NO_ERROR 0
33
34 namespace {
35
36 #define FORMAT_CASE(x) case AHARDWAREBUFFER_FORMAT_ ## x: os << #x ; break
37
PrintAhbFormat(std::ostream & os,uint64_t format)38 void PrintAhbFormat(std::ostream& os, uint64_t format) {
39 switch (format) {
40 FORMAT_CASE(R8G8B8A8_UNORM);
41 FORMAT_CASE(R8G8B8X8_UNORM);
42 FORMAT_CASE(R8G8B8_UNORM);
43 FORMAT_CASE(R5G6B5_UNORM);
44 FORMAT_CASE(R16G16B16A16_FLOAT);
45 FORMAT_CASE(R10G10B10A2_UNORM);
46 FORMAT_CASE(BLOB);
47 FORMAT_CASE(D16_UNORM);
48 FORMAT_CASE(D24_UNORM);
49 FORMAT_CASE(D24_UNORM_S8_UINT);
50 FORMAT_CASE(D32_FLOAT);
51 FORMAT_CASE(D32_FLOAT_S8_UINT);
52 FORMAT_CASE(S8_UINT);
53 default: os << "unknown"; break;
54 }
55 }
56
57 #define BITS_CASE(x) case AHARDWAREBUFFER_USAGE_ ## x: os << #x ; break
58 #define PRINT_FLAG(x) \
59 do { if (usage & AHARDWAREBUFFER_USAGE_ ## x) { os << #x << " "; } } while (0)
60
PrintAhbUsage(std::ostream & os,uint64_t usage)61 void PrintAhbUsage(std::ostream& os, uint64_t usage) {
62 if (usage == 0) {
63 os << "none";
64 return;
65 }
66 switch (usage & AHARDWAREBUFFER_USAGE_CPU_READ_MASK) {
67 BITS_CASE(CPU_READ_NEVER);
68 BITS_CASE(CPU_READ_RARELY);
69 BITS_CASE(CPU_READ_OFTEN);
70 default: break;
71 }
72 switch (usage & AHARDWAREBUFFER_USAGE_CPU_WRITE_MASK) {
73 BITS_CASE(CPU_WRITE_NEVER);
74 BITS_CASE(CPU_WRITE_RARELY);
75 BITS_CASE(CPU_WRITE_OFTEN);
76 default: break;
77 }
78
79 PRINT_FLAG(GPU_SAMPLED_IMAGE);
80 PRINT_FLAG(GPU_COLOR_OUTPUT);
81 PRINT_FLAG(PROTECTED_CONTENT);
82 PRINT_FLAG(VIDEO_ENCODE);
83 PRINT_FLAG(SENSOR_DIRECT_DATA);
84 PRINT_FLAG(GPU_DATA_BUFFER);
85 PRINT_FLAG(GPU_CUBE_MAP);
86 PRINT_FLAG(GPU_MIPMAP_COMPLETE);
87
88 PRINT_FLAG(VENDOR_0);
89 PRINT_FLAG(VENDOR_1);
90 PRINT_FLAG(VENDOR_2);
91 PRINT_FLAG(VENDOR_3);
92 PRINT_FLAG(VENDOR_4);
93 PRINT_FLAG(VENDOR_5);
94 PRINT_FLAG(VENDOR_6);
95 PRINT_FLAG(VENDOR_7);
96 PRINT_FLAG(VENDOR_8);
97 PRINT_FLAG(VENDOR_9);
98 PRINT_FLAG(VENDOR_10);
99 PRINT_FLAG(VENDOR_11);
100 PRINT_FLAG(VENDOR_12);
101 PRINT_FLAG(VENDOR_13);
102 PRINT_FLAG(VENDOR_14);
103 PRINT_FLAG(VENDOR_15);
104 PRINT_FLAG(VENDOR_16);
105 PRINT_FLAG(VENDOR_17);
106 PRINT_FLAG(VENDOR_18);
107 PRINT_FLAG(VENDOR_19);
108 }
109
GetDescription(AHardwareBuffer * buffer)110 AHardwareBuffer_Desc GetDescription(AHardwareBuffer* buffer) {
111 AHardwareBuffer_Desc description;
112 AHardwareBuffer_describe(buffer, &description);
113 return description;
114 }
115
116 } // namespace
117
118 // GTest printer for AHardwareBuffer_Desc. Has to be in the global namespace.
PrintTo(const AHardwareBuffer_Desc & desc,::std::ostream * os)119 void PrintTo(const AHardwareBuffer_Desc& desc, ::std::ostream* os) {
120 *os << "AHardwareBuffer_Desc " << desc.width << "x" << desc.height;
121 if (desc.layers > 1) {
122 *os << ", " << desc.layers << " layers";
123 }
124 *os << ", usage = ";
125 PrintAhbUsage(*os, desc.usage);
126 *os << ", format = ";
127 PrintAhbFormat(*os, desc.format);
128 }
129
130 // Equality operators for AHardwareBuffer_Desc. Have to be in the global namespace.
operator ==(const AHardwareBuffer_Desc & a,const AHardwareBuffer_Desc & b)131 bool operator==(const AHardwareBuffer_Desc& a, const AHardwareBuffer_Desc& b) {
132 return a.width == b.width && a.height == b.height && a.layers == b.layers &&
133 a.usage == b.usage && a.format == b.format;
134 }
operator !=(const AHardwareBuffer_Desc & a,const AHardwareBuffer_Desc & b)135 bool operator!=(const AHardwareBuffer_Desc& a, const AHardwareBuffer_Desc& b) {
136 return !(a == b);
137 }
138
139 namespace android {
140
141 // Test that passing in NULL values to allocate works as expected.
TEST(AHardwareBufferTest,AllocateFailsWithNullInput)142 TEST(AHardwareBufferTest, AllocateFailsWithNullInput) {
143 AHardwareBuffer* buffer;
144 AHardwareBuffer_Desc desc;
145
146 memset(&desc, 0, sizeof(AHardwareBuffer_Desc));
147
148 int res = AHardwareBuffer_allocate(&desc, NULL);
149 EXPECT_EQ(BAD_VALUE, res);
150 res = AHardwareBuffer_allocate(NULL, &buffer);
151 EXPECT_EQ(BAD_VALUE, res);
152 res = AHardwareBuffer_allocate(NULL, NULL);
153 EXPECT_EQ(BAD_VALUE, res);
154 }
155
156 // Test that passing in NULL values to allocate works as expected.
TEST(AHardwareBufferTest,BlobFormatRequiresHeight1)157 TEST(AHardwareBufferTest, BlobFormatRequiresHeight1) {
158 AHardwareBuffer* buffer;
159 AHardwareBuffer_Desc desc = {};
160
161 desc.width = 2;
162 desc.height = 4;
163 desc.layers = 1;
164 desc.usage = AHARDWAREBUFFER_USAGE_CPU_READ_RARELY;
165 desc.format = AHARDWAREBUFFER_FORMAT_BLOB;
166 int res = AHardwareBuffer_allocate(&desc, &buffer);
167 EXPECT_EQ(BAD_VALUE, res);
168
169 desc.height = 1;
170 res = AHardwareBuffer_allocate(&desc, &buffer);
171 EXPECT_EQ(NO_ERROR, res);
172 EXPECT_EQ(desc, GetDescription(buffer));
173 AHardwareBuffer_release(buffer);
174 buffer = NULL;
175 }
176
177 // Test that allocate can create an AHardwareBuffer correctly.
TEST(AHardwareBufferTest,AllocateSucceeds)178 TEST(AHardwareBufferTest, AllocateSucceeds) {
179 AHardwareBuffer* buffer = NULL;
180 AHardwareBuffer_Desc desc = {};
181
182 desc.width = 2;
183 desc.height = 4;
184 desc.layers = 1;
185 desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
186 desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
187 int res = AHardwareBuffer_allocate(&desc, &buffer);
188 EXPECT_EQ(NO_ERROR, res);
189 EXPECT_EQ(desc, GetDescription(buffer));
190 AHardwareBuffer_release(buffer);
191 buffer = NULL;
192
193 desc.width = 4;
194 desc.height = 12;
195 desc.layers = 1;
196 desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
197 desc.format = AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM;
198 res = AHardwareBuffer_allocate(&desc, &buffer);
199 EXPECT_EQ(NO_ERROR, res);
200 EXPECT_EQ(desc, GetDescription(buffer));
201 AHardwareBuffer_release(buffer);
202 }
203
TEST(AHardwareBufferTest,DescribeSucceeds)204 TEST(AHardwareBufferTest, DescribeSucceeds) {
205 AHardwareBuffer* buffer = NULL;
206 AHardwareBuffer_Desc desc = {};
207
208 desc.width = 2;
209 desc.height = 4;
210 desc.layers = 1;
211 desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
212 desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
213 int res = AHardwareBuffer_allocate(&desc, &buffer);
214 EXPECT_EQ(NO_ERROR, res);
215
216 // Description of a null buffer should be all zeros.
217 AHardwareBuffer_Desc scratch_desc;
218 memset(&scratch_desc, 0, sizeof(AHardwareBuffer_Desc));
219 AHardwareBuffer_describe(NULL, &scratch_desc);
220 EXPECT_EQ(0U, scratch_desc.width);
221 EXPECT_EQ(0U, scratch_desc.height);
222
223 // This shouldn't crash.
224 AHardwareBuffer_describe(buffer, NULL);
225
226 // Description of created buffer should match requsted description.
227 EXPECT_EQ(desc, GetDescription(buffer));
228 AHardwareBuffer_release(buffer);
229 }
230
231 struct ClientData {
232 int fd;
233 AHardwareBuffer* buffer;
ClientDataandroid::ClientData234 ClientData(int fd_in, AHardwareBuffer* buffer_in)
235 : fd(fd_in), buffer(buffer_in) {}
236 };
237
clientFunction(void * data)238 static void* clientFunction(void* data) {
239 ClientData* pdata = reinterpret_cast<ClientData*>(data);
240 int err = AHardwareBuffer_sendHandleToUnixSocket(pdata->buffer, pdata->fd);
241 EXPECT_EQ(NO_ERROR, err);
242 close(pdata->fd);
243 return 0;
244 }
245
TEST(AHardwareBufferTest,SendAndRecvSucceeds)246 TEST(AHardwareBufferTest, SendAndRecvSucceeds) {
247 AHardwareBuffer* buffer = NULL;
248 AHardwareBuffer_Desc desc = {};
249
250 desc.width = 2;
251 desc.height = 4;
252 desc.layers = 1;
253 desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
254 desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
255
256 // Test that an invalid buffer fails.
257 int err = AHardwareBuffer_sendHandleToUnixSocket(NULL, 0);
258 EXPECT_EQ(BAD_VALUE, err);
259 err = 0;
260 err = AHardwareBuffer_sendHandleToUnixSocket(buffer, 0);
261 EXPECT_EQ(BAD_VALUE, err);
262
263 // Allocate the buffer.
264 err = AHardwareBuffer_allocate(&desc, &buffer);
265 EXPECT_EQ(NO_ERROR, err);
266
267 int fds[2];
268 err = socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, fds);
269
270 // Launch a client that will send the buffer back.
271 ClientData data(fds[1], buffer);
272 pthread_t thread;
273 EXPECT_EQ(0, pthread_create(&thread, NULL, clientFunction, &data));
274
275 // Receive the buffer.
276 err = AHardwareBuffer_recvHandleFromUnixSocket(fds[0], NULL);
277 EXPECT_EQ(BAD_VALUE, err);
278
279 AHardwareBuffer* received = NULL;
280 err = AHardwareBuffer_recvHandleFromUnixSocket(fds[0], &received);
281 EXPECT_EQ(NO_ERROR, err);
282 EXPECT_TRUE(received != NULL);
283 EXPECT_EQ(desc, GetDescription(received));
284
285 void* ret_val;
286 EXPECT_EQ(0, pthread_join(thread, &ret_val));
287 EXPECT_EQ(NULL, ret_val);
288 close(fds[0]);
289
290 AHardwareBuffer_release(buffer);
291 AHardwareBuffer_release(received);
292 }
293
TEST(AHardwareBufferTest,LockAndUnlockSucceed)294 TEST(AHardwareBufferTest, LockAndUnlockSucceed) {
295 AHardwareBuffer* buffer = NULL;
296 AHardwareBuffer_Desc desc = {};
297
298 desc.width = 2;
299 desc.height = 4;
300 desc.layers = 1;
301 desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE | AHARDWAREBUFFER_USAGE_CPU_READ_RARELY;
302 desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
303
304 // Test that an invalid buffer fails.
305 int err = AHardwareBuffer_lock(NULL, 0, -1, NULL, NULL);
306 EXPECT_EQ(BAD_VALUE, err);
307 err = 0;
308
309 // Allocate the buffer.
310 err = AHardwareBuffer_allocate(&desc, &buffer);
311 EXPECT_EQ(NO_ERROR, err);
312 void* bufferData = NULL;
313 err = AHardwareBuffer_lock(buffer, AHARDWAREBUFFER_USAGE_CPU_READ_RARELY, -1,
314 NULL, &bufferData);
315 EXPECT_EQ(NO_ERROR, err);
316 EXPECT_TRUE(bufferData != NULL);
317 int32_t fence = -1;
318 err = AHardwareBuffer_unlock(buffer, &fence);
319
320 AHardwareBuffer_release(buffer);
321 }
322
TEST(AHardwareBufferTest,ProtectedContentAndCpuReadIncompatible)323 TEST(AHardwareBufferTest, ProtectedContentAndCpuReadIncompatible) {
324 AHardwareBuffer* buffer = NULL;
325 AHardwareBuffer_Desc desc = {};
326 desc.width = 120;
327 desc.width = 240;
328 desc.layers = 1;
329 desc.usage = AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT | AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN;
330 desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
331
332 // Allocation of a CPU-readable buffer should succeed...
333 int err = AHardwareBuffer_allocate(&desc, &buffer);
334 EXPECT_EQ(NO_ERROR, err);
335 AHardwareBuffer_release(buffer);
336 buffer = nullptr;
337
338 // ...but not if it's a protected buffer.
339 desc.usage =
340 AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT |
341 AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN |
342 AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT;
343 err = AHardwareBuffer_allocate(&desc, &buffer);
344 EXPECT_NE(NO_ERROR, err);
345
346 desc.usage =
347 AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT |
348 AHARDWAREBUFFER_USAGE_CPU_READ_RARELY |
349 AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT;
350 err = AHardwareBuffer_allocate(&desc, &buffer);
351 EXPECT_NE(NO_ERROR, err);
352 }
353
354 } // namespace android
355