/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "LibHidlTest"

#pragma clang diagnostic push
#pragma clang diagnostic error "-Wpadded"
#include <hidl/HidlInternal.h>
#include <hidl/HidlSupport.h>
#pragma clang diagnostic pop

#include <android-base/logging.h>
#include <android-base/properties.h>
#ifdef __ANDROID__
#include <android/api-level.h>
#endif
#include <android/hidl/memory/1.0/IMemory.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <hidl/ServiceManagement.h>
#include <hidl/Status.h>
#include <hidl/TaskRunner.h>
#include <condition_variable>
#include <fstream>
#include <vector>

#define EXPECT_ARRAYEQ(__a1__, __a2__, __size__) EXPECT_TRUE(isArrayEqual(__a1__, __a2__, __size__))
#define EXPECT_2DARRAYEQ(__a1__, __a2__, __size1__, __size2__) \
        EXPECT_TRUE(is2dArrayEqual(__a1__, __a2__, __size1__, __size2__))

template<typename T, typename S>
static inline bool isArrayEqual(const T arr1, const S arr2, size_t size) {
    for(size_t i = 0; i < size; i++)
        if(arr1[i] != arr2[i])
            return false;
    return true;
}

template<typename T, typename S>
static inline bool is2dArrayEqual(const T arr1, const S arr2, size_t size1, size_t size2) {
    for(size_t i = 0; i < size1; i++)
        for (size_t j = 0; j < size2; j++)
            if(arr1[i][j] != arr2[i][j])
                return false;
    return true;
}

bool isLibraryOpen(const std::string& lib) {
    std::ifstream ifs("/proc/self/maps");
    for (std::string line; std::getline(ifs, line);) {
        if (line.size() >= lib.size() && line.substr(line.size() - lib.size()) == lib) {
            return true;
        }
    }

    return false;
}

class LibHidlTest : public ::testing::Test {
public:
    virtual void SetUp() override {
    }
    virtual void TearDown() override {
    }
};

TEST_F(LibHidlTest, StringTest) {
    using android::hardware::hidl_string;
    hidl_string s; // empty constructor
    EXPECT_STREQ(s.c_str(), "");
    hidl_string s1 = "s1"; // copy = from cstr
    EXPECT_STREQ(s1.c_str(), "s1");
    hidl_string s2("s2"); // copy constructor from cstr
    EXPECT_STREQ(s2.c_str(), "s2");
    hidl_string s2a(nullptr); // copy constructor from null cstr
    EXPECT_STREQ("", s2a.c_str());
    s2a = nullptr; // = from nullptr cstr
    EXPECT_STREQ(s2a.c_str(), "");
    hidl_string s3 = hidl_string("s3"); // move =
    EXPECT_STREQ(s3.c_str(), "s3");
    hidl_string s4 = hidl_string("12345", 3); // copy constructor from cstr w/ length
    EXPECT_STREQ(s4.c_str(), "123");
    hidl_string s5(hidl_string(hidl_string("s5"))); // move constructor
    EXPECT_STREQ(s5.c_str(), "s5");
    hidl_string s6(std::string("s6")); // copy constructor from std::string
    EXPECT_STREQ(s6.c_str(), "s6");
    hidl_string s7 = std::string("s7"); // copy = from std::string
    EXPECT_STREQ(s7.c_str(), "s7");
    hidl_string s8(s7); // copy constructor // NOLINT, test the copy constructor
    EXPECT_STREQ(s8.c_str(), "s7");
    hidl_string s9 = s8; // copy =  // NOLINT, test the copy operator
    EXPECT_STREQ(s9.c_str(), "s7");
    char myCString[20] = "myCString";
    s.setToExternal(&myCString[0], strlen(myCString));
    EXPECT_STREQ(s.c_str(), "myCString");
    myCString[2] = 'D';
    EXPECT_STREQ(s.c_str(), "myDString");
    s.clear(); // should not affect myCString
    EXPECT_STREQ(myCString, "myDString");

    // casts
    s = "great";
    std::string myString = s;
    const char *anotherCString = s.c_str();
    EXPECT_EQ(myString, "great");
    EXPECT_STREQ(anotherCString, "great");

    const hidl_string t = "not so great";
    std::string myTString = t;
    const char * anotherTCString = t.c_str();
    EXPECT_EQ(myTString, "not so great");
    EXPECT_STREQ(anotherTCString, "not so great");

    // Assignment from hidl_string to std::string
    std::string tgt;
    hidl_string src("some stuff");
    tgt = src;
    EXPECT_STREQ(tgt.c_str(), "some stuff");

    // Stream output operator
    hidl_string msg("hidl_string works with operator<<");
    std::cout << msg;

    // Comparisons
    const char * cstr1 = "abc";
    std::string string1(cstr1);
    hidl_string hs1(cstr1);
    const char * cstrE = "abc";
    std::string stringE(cstrE);
    hidl_string hsE(cstrE);
    const char * cstrNE = "ABC";
    std::string stringNE(cstrNE);
    hidl_string hsNE(cstrNE);
    const char * cstr2 = "def";
    std::string string2(cstr2);
    hidl_string hs2(cstr2);

    EXPECT_TRUE(hs1  == hsE);
    EXPECT_FALSE(hs1 == hsNE);
    EXPECT_TRUE(hs1  == cstrE);
    EXPECT_FALSE(hs1 == cstrNE);
    EXPECT_TRUE(hs1  == stringE);
    EXPECT_FALSE(hs1 == stringNE);
    EXPECT_FALSE(hs1 != hsE);
    EXPECT_TRUE(hs1  != hsNE);
    EXPECT_FALSE(hs1 != cstrE);
    EXPECT_TRUE(hs1  != cstrNE);
    EXPECT_FALSE(hs1 != stringE);
    EXPECT_TRUE(hs1  != stringNE);

    EXPECT_TRUE(hs1 < hs2);
    EXPECT_FALSE(hs2 < hs1);
    EXPECT_TRUE(hs2 > hs1);
    EXPECT_FALSE(hs1 > hs2);
    EXPECT_TRUE(hs1 <= hs1);
    EXPECT_TRUE(hs1 <= hs2);
    EXPECT_FALSE(hs2 <= hs1);
    EXPECT_TRUE(hs1 >= hs1);
    EXPECT_TRUE(hs2 >= hs1);
    EXPECT_FALSE(hs2 <= hs1);
}

// empty string optimization should apply for any constructor
TEST_F(LibHidlTest, HidlStringEmptyLiteralAllocation) {
    using android::hardware::hidl_string;

    hidl_string empty1;
    hidl_string empty2("");
    hidl_string empty3("foo", 0);
    hidl_string empty4((std::string()));

    EXPECT_EQ(empty1.c_str(), empty2.c_str());
    EXPECT_EQ(empty1.c_str(), empty3.c_str());
    EXPECT_EQ(empty1.c_str(), empty4.c_str());
}

TEST_F(LibHidlTest, MemoryTest) {
    using android::hardware::hidl_memory;

    hidl_memory mem1 = hidl_memory(); // default constructor
    hidl_memory mem2 = mem1; // copy constructor (nullptr), NOLINT

    EXPECT_EQ(nullptr, mem2.handle());

    native_handle_t* testHandle = native_handle_create(0 /* numInts */, 0 /* numFds */);

    hidl_memory mem3 = hidl_memory("foo", testHandle, 42 /* size */); // owns testHandle
    hidl_memory mem4 = mem3; // copy constructor (regular handle), NOLINT

    EXPECT_EQ(mem3.name(), mem4.name());
    EXPECT_EQ(mem3.size(), mem4.size());
    EXPECT_NE(nullptr, mem4.handle());
    EXPECT_NE(mem3.handle(), mem4.handle()); // check handle cloned

    hidl_memory mem5 = hidl_memory("foo", nullptr, 0); // hidl memory works with nullptr handle
    hidl_memory mem6 = mem5; // NOLINT, test copying
    EXPECT_EQ(nullptr, mem5.handle());
    EXPECT_EQ(nullptr, mem6.handle());
}

TEST_F(LibHidlTest, VecInitTest) {
    using android::hardware::hidl_vec;
    using std::vector;
    int32_t array[] = {5, 6, 7};
    vector<int32_t> v(array, array + 3);

    hidl_vec<int32_t> hv0(3);  // size
    EXPECT_EQ(hv0.size(), 3ul);  // cannot say anything about its contents

    hidl_vec<int32_t> hv1 = v; // copy =
    EXPECT_ARRAYEQ(hv1, array, 3);
    EXPECT_ARRAYEQ(hv1, v, 3);
    hidl_vec<int32_t> hv2(v); // copy constructor
    EXPECT_ARRAYEQ(hv2, v, 3);

    vector<int32_t> v2 = hv1; // cast
    EXPECT_ARRAYEQ(v2, v, 3);

    hidl_vec<int32_t> v3 = {5, 6, 7}; // initializer_list
    EXPECT_EQ(v3.size(), 3ul);
    EXPECT_ARRAYEQ(v3, array, v3.size());
}

TEST_F(LibHidlTest, VecReleaseTest) {
    // this test indicates an inconsistency of behaviors which is undesirable.
    // Perhaps hidl-vec should always allocate an empty vector whenever it
    // exposes its data. Alternatively, perhaps it should always free/reject
    // empty vectors and always return nullptr for this state. While this second
    // alternative is faster, it makes client code harder to write, and it would
    // break existing client code.
    using android::hardware::hidl_vec;

    hidl_vec<int32_t> empty;
    EXPECT_EQ(nullptr, empty.releaseData());

    empty.resize(0);
    int32_t* data = empty.releaseData();
    EXPECT_NE(nullptr, data);
    delete data;
}

TEST_F(LibHidlTest, VecIterTest) {
    int32_t array[] = {5, 6, 7};
    android::hardware::hidl_vec<int32_t> hv1 = std::vector<int32_t>(array, array + 3);

    auto iter = hv1.begin();    // iterator begin()
    EXPECT_EQ(*iter++, 5);
    EXPECT_EQ(*iter, 6);
    EXPECT_EQ(*++iter, 7);
    EXPECT_EQ(*iter--, 7);
    EXPECT_EQ(*iter, 6);
    EXPECT_EQ(*--iter, 5);

    iter += 2;
    EXPECT_EQ(*iter, 7);
    iter -= 2;
    EXPECT_EQ(*iter, 5);

    iter++;
    EXPECT_EQ(*(iter + 1), 7);
    EXPECT_EQ(*(1 + iter), 7);
    EXPECT_EQ(*(iter - 1), 5);
    EXPECT_EQ(*iter, 6);

    auto five = iter - 1;
    auto seven = iter + 1;
    EXPECT_EQ(seven - five, 2);
    EXPECT_EQ(five - seven, -2);

    EXPECT_LT(five, seven);
    EXPECT_LE(five, seven);
    EXPECT_GT(seven, five);
    EXPECT_GE(seven, five);

    EXPECT_EQ(seven[0], 7);
    EXPECT_EQ(five[1], 6);
}

TEST_F(LibHidlTest, VecIterForTest) {
    using android::hardware::hidl_vec;
    int32_t array[] = {5, 6, 7};
    hidl_vec<int32_t> hv1 = std::vector<int32_t>(array, array + 3);

    int32_t sum = 0;            // range based for loop interoperability
    for (auto &&i: hv1) {
        sum += i;
    }
    EXPECT_EQ(sum, 5+6+7);

    for (auto iter = hv1.begin(); iter < hv1.end(); ++iter) {
        *iter += 10;
    }
    const hidl_vec<int32_t> &v4 = hv1;
    sum = 0;
    for (const auto &i : v4) {
        sum += i;
    }
    EXPECT_EQ(sum, 15+16+17);
}

TEST_F(LibHidlTest, VecEqTest) {
    android::hardware::hidl_vec<int32_t> hv1{5, 6, 7};
    android::hardware::hidl_vec<int32_t> hv2{5, 6, 7};
    android::hardware::hidl_vec<int32_t> hv3{5, 6, 8};

    // use the == and != operator intentionally here
    EXPECT_TRUE(hv1 == hv2);
    EXPECT_TRUE(hv1 != hv3);
}

TEST_F(LibHidlTest, VecEqInitializerTest) {
    std::vector<int32_t> reference{5, 6, 7};
    android::hardware::hidl_vec<int32_t> hv1{1, 2, 3};
    hv1 = {5, 6, 7};
    android::hardware::hidl_vec<int32_t> hv2;
    hv2 = {5, 6, 7};
    android::hardware::hidl_vec<int32_t> hv3;
    hv3 = {5, 6, 8};

    // use the == and != operator intentionally here
    EXPECT_TRUE(hv1 == hv2);
    EXPECT_TRUE(hv1 == reference);
    EXPECT_TRUE(hv1 != hv3);
}

TEST_F(LibHidlTest, VecRangeCtorTest) {
    struct ConvertibleType {
        int val;

        explicit ConvertibleType(int val) : val(val) {}
        explicit operator int() const { return val; }
        bool operator==(const int& other) const { return val == other; }
    };

    std::vector<ConvertibleType> input{
        ConvertibleType(1), ConvertibleType(2), ConvertibleType(3),
    };

    android::hardware::hidl_vec<int> hv(input.begin(), input.end());

    EXPECT_EQ(input.size(), hv.size());
    int sum = 0;
    for (unsigned i = 0; i < input.size(); i++) {
        EXPECT_EQ(input[i], hv[i]);
        sum += hv[i];
    }
    EXPECT_EQ(sum, 1 + 2 + 3);
}

struct FailsIfCopied {
    FailsIfCopied() {}

    // add failure if copied since in general this can be expensive
    FailsIfCopied(const FailsIfCopied& o) { *this = o; }
    FailsIfCopied& operator=(const FailsIfCopied&) {
        ADD_FAILURE() << "FailsIfCopied copied";
        return *this;
    }

    // fine to move this type since in general this is cheaper
    FailsIfCopied(FailsIfCopied&& o) = default;
    FailsIfCopied& operator=(FailsIfCopied&&) = default;
};

TEST_F(LibHidlTest, VecResizeNoCopy) {
    using android::hardware::hidl_vec;

    hidl_vec<FailsIfCopied> noCopies;
    noCopies.resize(3);  // instantiates three elements

    FailsIfCopied* oldPointer = noCopies.data();

    noCopies.resize(6);  // should move three elements, not copy

    // oldPointer should be invalidated at this point.
    // hidl_vec doesn't currently try to realloc but if it ever switches
    // to an implementation that does, this test wouldn't do anything.
    EXPECT_NE(oldPointer, noCopies.data());
}

TEST_F(LibHidlTest, VecFindTest) {
    using android::hardware::hidl_vec;
    hidl_vec<int32_t> hv1 = {10, 20, 30, 40};
    const hidl_vec<int32_t> hv2 = {1, 2, 3, 4};

    auto it = hv1.find(20);
    EXPECT_EQ(20, *it);
    *it = 21;
    EXPECT_EQ(21, *it);
    it = hv1.find(20);
    EXPECT_EQ(hv1.end(), it);
    it = hv1.find(21);
    EXPECT_EQ(21, *it);

    auto cit = hv2.find(4);
    EXPECT_EQ(4, *cit);
}

TEST_F(LibHidlTest, VecContainsTest) {
    using android::hardware::hidl_vec;
    hidl_vec<int32_t> hv1 = {10, 20, 30, 40};
    const hidl_vec<int32_t> hv2 = {0, 1, 2, 3, 4};

    EXPECT_TRUE(hv1.contains(10));
    EXPECT_TRUE(hv1.contains(40));
    EXPECT_FALSE(hv1.contains(1));
    EXPECT_FALSE(hv1.contains(0));
    EXPECT_TRUE(hv2.contains(0));
    EXPECT_FALSE(hv2.contains(10));

    hv1[0] = 11;
    EXPECT_FALSE(hv1.contains(10));
    EXPECT_TRUE(hv1.contains(11));
}

TEST_F(LibHidlTest, ArrayTest) {
    using android::hardware::hidl_array;
    int32_t array[] = {5, 6, 7};

    hidl_array<int32_t, 3> ha(array);
    EXPECT_ARRAYEQ(ha, array, 3);
}

TEST_F(LibHidlTest, TaskRunnerTest) {
    using android::hardware::details::TaskRunner;
    using namespace std::chrono_literals;

    std::condition_variable cv;
    std::mutex m;

    TaskRunner tr;
    tr.start(1 /* limit */);
    bool flag = false;
    tr.push([&] {
        flag = true;
        cv.notify_all();
    });

    std::unique_lock<std::mutex> lock(m);

    // 1s so this doesn't deadlock. This isn't a performance test.
    EXPECT_TRUE(cv.wait_for(lock, 1s, [&]{return flag;}));
    EXPECT_TRUE(flag);
}

TEST_F(LibHidlTest, StringCmpTest) {
    using android::hardware::hidl_string;
    const char * s = "good";
    hidl_string hs(s);
    EXPECT_NE(hs.c_str(), s);

    EXPECT_TRUE(hs == s); // operator ==
    EXPECT_TRUE(s == hs);

    EXPECT_FALSE(hs != s); // operator ==
    EXPECT_FALSE(s != hs);
}

template <typename T>
void great(android::hardware::hidl_vec<T>) {}

TEST_F(LibHidlTest, VecCopyTest) {
    android::hardware::hidl_vec<int32_t> v;
    great(v);
}

TEST_F(LibHidlTest, StdArrayTest) {
    using android::hardware::hidl_array;
    hidl_array<int32_t, 5> array{(int32_t[5]){1, 2, 3, 4, 5}};
    std::array<int32_t, 5> stdArray = array;
    EXPECT_ARRAYEQ(array.data(), stdArray.data(), 5);
    hidl_array<int32_t, 5> array2 = stdArray;
    EXPECT_ARRAYEQ(array.data(), array2.data(), 5);
}

TEST_F(LibHidlTest, MultiDimStdArrayTest) {
    using android::hardware::hidl_array;
    hidl_array<int32_t, 2, 3> array;
    for (size_t i = 0; i < 2; i++) {
        for (size_t j = 0; j < 3; j++) {
            array[i][j] = i + j + i * j;
        }
    }
    std::array<std::array<int32_t, 3>, 2> stdArray = array;
    EXPECT_2DARRAYEQ(array, stdArray, 2, 3);
    hidl_array<int32_t, 2, 3> array2 = stdArray;
    EXPECT_2DARRAYEQ(array, array2, 2, 3);
}

TEST_F(LibHidlTest, HidlVersionTest) {
    using android::hardware::hidl_version;
    hidl_version v1_0{1, 0};
    EXPECT_EQ(1, v1_0.get_major());
    EXPECT_EQ(0, v1_0.get_minor());
    hidl_version v2_0{2, 0};
    hidl_version v2_1{2, 1};
    hidl_version v2_2{2, 2};
    hidl_version v3_0{3, 0};
    hidl_version v3_0b{3,0};

    EXPECT_TRUE(v1_0 < v2_0);
    EXPECT_TRUE(v1_0 != v2_0);
    EXPECT_TRUE(v2_0 < v2_1);
    EXPECT_TRUE(v2_1 < v3_0);
    EXPECT_TRUE(v2_0 > v1_0);
    EXPECT_TRUE(v2_0 != v1_0);
    EXPECT_TRUE(v2_1 > v2_0);
    EXPECT_TRUE(v3_0 > v2_1);
    EXPECT_TRUE(v3_0 == v3_0b);
    EXPECT_FALSE(v3_0 != v3_0b);
    EXPECT_TRUE(v3_0 <= v3_0b);
    EXPECT_TRUE(v2_2 <= v3_0);
    EXPECT_TRUE(v3_0 >= v3_0b);
    EXPECT_TRUE(v3_0 >= v2_2);
}

TEST_F(LibHidlTest, ReturnMoveTest) {
    using namespace ::android;
    using ::android::hardware::Return;
    using ::android::hardware::Status;
    Return<void> ret{Status::fromStatusT(DEAD_OBJECT)};
    ret.isOk();
    ret = {Status::fromStatusT(DEAD_OBJECT)};
    ret.isOk();
}

TEST_F(LibHidlTest, ReturnTest) {
    using ::android::DEAD_OBJECT;
    using ::android::hardware::Return;
    using ::android::hardware::Status;
    using ::android::hardware::hidl_string;

    EXPECT_FALSE(Return<void>(Status::fromStatusT(DEAD_OBJECT)).isOk());
    EXPECT_TRUE(Return<void>(Status::ok()).isOk());

    hidl_string one = "1";
    hidl_string two = "2";
    const Return<hidl_string> ret = Return<hidl_string>(Status::fromStatusT(DEAD_OBJECT));

    EXPECT_EQ(one, Return<hidl_string>(one).withDefault(two));
    EXPECT_EQ(two, ret.withDefault(two));

    hidl_string&& moved = ret.withDefault(std::move(two));
    EXPECT_EQ("2", moved);

    const hidl_string three = "3";
    EXPECT_EQ(three, ret.withDefault(three));
}

TEST_F(LibHidlTest, ReturnDies) {
    using ::android::hardware::Return;
    using ::android::hardware::Status;

    EXPECT_DEATH({ Return<void>(Status::fromStatusT(-EBUSY)); }, "");
    EXPECT_DEATH({ Return<void>(Status::fromStatusT(-EBUSY)).isDeadObject(); }, "");
    EXPECT_DEATH(
            {
                Return<int> ret = Return<int>(Status::fromStatusT(-EBUSY));
                int foo = ret;  // should crash here
                (void)foo;
                ret.isOk();
            },
            "");
}

TEST_F(LibHidlTest, DetectUncheckedReturn) {
    using ::android::hardware::HidlReturnRestriction;
    using ::android::hardware::Return;
    using ::android::hardware::setProcessHidlReturnRestriction;
    using ::android::hardware::Status;

    setProcessHidlReturnRestriction(HidlReturnRestriction::FATAL_IF_UNCHECKED);

    EXPECT_DEATH(
            {
                auto ret = Return<void>(Status::ok());
                (void)ret;
            },
            "");
    EXPECT_DEATH(
            {
                auto ret = Return<void>(Status::ok());
                ret = Return<void>(Status::ok());
                ret.isOk();
            },
            "");

    auto ret = Return<void>(Status::ok());
    (void)ret.isOk();
    ret = Return<void>(Status::ok());
    (void)ret.isOk();

    setProcessHidlReturnRestriction(HidlReturnRestriction::NONE);
}

std::string toString(const ::android::hardware::Status &s) {
    using ::android::hardware::operator<<;
    std::ostringstream oss;
    oss << s;
    return oss.str();
}

TEST_F(LibHidlTest, StatusStringTest) {
    using namespace ::android;
    using ::android::hardware::Status;
    using ::testing::HasSubstr;

    EXPECT_EQ(toString(Status::ok()), "No error");

    EXPECT_THAT(toString(Status::fromStatusT(DEAD_OBJECT)), HasSubstr("DEAD_OBJECT"));

    EXPECT_THAT(toString(Status::fromStatusT(-EBUSY)), HasSubstr("busy"));

    EXPECT_THAT(toString(Status::fromExceptionCode(Status::EX_NULL_POINTER)),
            HasSubstr("EX_NULL_POINTER"));
}

TEST_F(LibHidlTest, PreloadTest) {
    // HIDL doesn't have support to load passthrough implementations on host, but we
    // could do this by loading implementations from the output directory
#ifndef __ANDROID__
    GTEST_SKIP();
#else
    using ::android::hardware::preloadPassthroughService;
    using ::android::hidl::memory::V1_0::IMemory;

    // android.hidl.memory@1.0-impl.so is installed on all devices by default up
    // to Android U in both bitnesses and not otherwise a dependency of this
    // test.
    // Android V+ devices do not have this installed by default, so skip the
    // test.
    if (android::base::GetIntProperty("ro.vendor.api_level", 0) >= __ANDROID_API_V__) {
        GTEST_SKIP();
    }
    static const std::string kLib = "android.hidl.memory@1.0-impl.so";

    EXPECT_FALSE(isLibraryOpen(kLib));
    preloadPassthroughService<IMemory>();
    EXPECT_TRUE(isLibraryOpen(kLib));
#endif
}

template <typename T, size_t start, size_t end>
static void assertZeroInRange(const T* t) {
    static_assert(start < sizeof(T));
    static_assert(end <= sizeof(T));

    const uint8_t* ptr = reinterpret_cast<const uint8_t*>(t);

    for (size_t i = start; i < end; i++) {
        EXPECT_EQ(0, ptr[i]);
    }
}

template <typename T, size_t start, size_t end>
static void uninitTest() {
    uint8_t buf[sizeof(T)];
    memset(buf, 0xFF, sizeof(T));

    T* type = new (buf) T;
    assertZeroInRange<T, start, end>(type);
    type->~T();
}

TEST_F(LibHidlTest, HidlVecUninit) {
    using ::android::hardware::hidl_vec;
    struct SomeType {};
    static_assert(sizeof(hidl_vec<SomeType>) == 16);

    // padding after mOwnsBuffer
    uninitTest<hidl_vec<SomeType>, 13, 16>();
}
TEST_F(LibHidlTest, HidlHandleUninit) {
    using ::android::hardware::hidl_handle;
    static_assert(sizeof(hidl_handle) == 16);

    // padding after mOwnsHandle
    uninitTest<hidl_handle, 9, 16>();
}
TEST_F(LibHidlTest, HidlStringUninit) {
    using ::android::hardware::hidl_string;
    static_assert(sizeof(hidl_string) == 16);

    // padding after mOwnsBuffer
    uninitTest<hidl_string, 13, 16>();
}

int main(int argc, char **argv) {
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}
