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