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 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 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 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. 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. 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 } 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. 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. 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. 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 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; 234 ClientData(int fd_in, AHardwareBuffer* buffer_in) 235 : fd(fd_in), buffer(buffer_in) {} 236 }; 237 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 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 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 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