Home | History | Annotate | Download | only in jni
      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