/*
 * Copyright (C) 2014 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.
 */

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>

#include <gtest/gtest.h>
#include <linux/android/binder.h>
#include <binder/IBinder.h>
#include <sys/mman.h>
#include <poll.h>

#define BINDER_DEV_NAME "/dev/binder"

testing::Environment* binder_env;

class BinderDriverInterfaceTestEnv : public ::testing::Environment {
        virtual void SetUp() {
            int ret;
            uint32_t max_threads = 0;

            m_binderFd = open(BINDER_DEV_NAME, O_RDWR | O_NONBLOCK | O_CLOEXEC);
            ASSERT_GE(m_binderFd, 0);
            m_buffer = mmap(NULL, 64*1024, PROT_READ, MAP_SHARED, m_binderFd, 0);
            ASSERT_NE(m_buffer, (void *)NULL);
            ret = ioctl(m_binderFd, BINDER_SET_MAX_THREADS, &max_threads);
            EXPECT_EQ(0, ret);
            EnterLooper();
        }
        virtual void TearDown() {
            close(m_binderFd);
        }
    private:
        int m_binderFd;
        void *m_buffer;
    public:
        int getBinderFd(void) {
            return m_binderFd;
        }
        void EnterLooper(void) {
            int ret;
            const uint32_t bc[] = {
                BC_ENTER_LOOPER,
            };
            struct binder_write_read bwr = binder_write_read();
            bwr.write_buffer = (uintptr_t)bc;
            bwr.write_size = sizeof(bc);
            ret = ioctl(m_binderFd, BINDER_WRITE_READ, &bwr);
            EXPECT_EQ(0, ret);
            if (ret < 0) {
                    EXPECT_EQ(0, errno);
            }
            EXPECT_EQ(sizeof(bc), bwr.write_consumed);
        }
};

class BinderDriverInterfaceTest : public ::testing::Test {
    public:
        virtual void SetUp() {
            m_binderFd = static_cast<BinderDriverInterfaceTestEnv *>(binder_env)->getBinderFd();
        }
        virtual void TearDown() {
        }
    protected:
        void binderTestIoctlRetErr2(int cmd, void *arg, int expect_ret, int expect_errno, int accept_errno) {
            int ret;

            ret = ioctl(m_binderFd, cmd, arg);
            EXPECT_EQ(expect_ret, ret);
            if (ret < 0) {
                if (errno != accept_errno)
                    EXPECT_EQ(expect_errno, errno);
            }
        }
        void binderTestIoctlErr2(int cmd, void *arg, int expect_errno, int accept_errno) {
            binderTestIoctlRetErr2(cmd, arg, -1, expect_errno, accept_errno);
        }
        void binderTestIoctlErr1(int cmd, void *arg, int expect_errno) {
            binderTestIoctlErr2(cmd, arg, expect_errno, expect_errno);
        }
        void binderTestIoctl(int cmd, void *arg) {
            binderTestIoctlRetErr2(cmd, arg, 0, 0, 0);
        }
        void binderTestIoctlUnimplemented(int cmd, void *arg) {
            int ret;

            ret = ioctl(m_binderFd, cmd, arg);
            if (ret < 0) {
                /* Not currently implmented. Allow ret == -1, errno == EINVAL */
                EXPECT_EQ(-1, ret);
                EXPECT_EQ(EINVAL, errno);
            }
        }
        void binderTestReadEmpty(void) {
            size_t i;
            uint32_t br[32];
            struct binder_write_read bwr = binder_write_read();
            SCOPED_TRACE("TestReadEmpty");
            bwr.read_buffer = (uintptr_t)br;
            bwr.read_size = sizeof(br);
            binderTestIoctlErr1(BINDER_WRITE_READ, &bwr, EAGAIN);
            EXPECT_EQ(0u, bwr.read_consumed);
            for (i = 0; i * sizeof(uint32_t) < bwr.read_consumed; i++) {
                SCOPED_TRACE(testing::Message() << "i = " << i);
                EXPECT_EQ(BR_NOOP, br[i]);
            }
        }
        void binderWaitForReadData(int timeout_ms) {
            int ret;
            pollfd pfd = pollfd();

            pfd.fd = m_binderFd;
            pfd.events = POLLIN;
            ret = poll(&pfd, 1, timeout_ms);
            EXPECT_EQ(1, ret);
        }
    private:
        int m_binderFd;
};

TEST_F(BinderDriverInterfaceTest, Version) {
    struct binder_version version;
    binderTestIoctl(BINDER_VERSION, &version);
    ASSERT_EQ(BINDER_CURRENT_PROTOCOL_VERSION, version.protocol_version);
}

TEST_F(BinderDriverInterfaceTest, WriteReadNull) {
    binderTestIoctlErr1(BINDER_WRITE_READ, NULL, EFAULT);
}

TEST_F(BinderDriverInterfaceTest, SetIdleTimeoutNull) {
    binderTestIoctlErr2(BINDER_SET_IDLE_TIMEOUT, NULL, EFAULT, EINVAL);
}

TEST_F(BinderDriverInterfaceTest, SetMaxThreadsNull) {
    binderTestIoctlErr2(BINDER_SET_MAX_THREADS, NULL, EFAULT, EINVAL); /* TODO: don't accept EINVAL */
}

TEST_F(BinderDriverInterfaceTest, SetIdlePriorityNull) {
    binderTestIoctlErr2(BINDER_SET_IDLE_PRIORITY, NULL, EFAULT, EINVAL);
}

TEST_F(BinderDriverInterfaceTest, VersionNull) {
    binderTestIoctlErr2(BINDER_VERSION, NULL, EFAULT, EINVAL); /* TODO: don't accept EINVAL */
}

TEST_F(BinderDriverInterfaceTest, SetIdleTimeoutNoTest) {
    int64_t idle_timeout = 100000;
    binderTestIoctlUnimplemented(BINDER_SET_IDLE_TIMEOUT, &idle_timeout);
}

TEST_F(BinderDriverInterfaceTest, SetMaxThreads) {
    uint32_t max_threads = 0;
    binderTestIoctl(BINDER_SET_MAX_THREADS, &max_threads);
}

TEST_F(BinderDriverInterfaceTest, SetIdlePriorityNoTest) {
    int idle_priority = 0;
    binderTestIoctlUnimplemented(BINDER_SET_IDLE_PRIORITY, &idle_priority);
}

TEST_F(BinderDriverInterfaceTest, SetContextMgrBusy) {
    int32_t dummy = 0;
    binderTestIoctlErr1(BINDER_SET_CONTEXT_MGR, &dummy, EBUSY);
}

TEST_F(BinderDriverInterfaceTest, ThreadExit) {
    int32_t dummy = 0;
    binderTestIoctl(BINDER_THREAD_EXIT, &dummy);
    static_cast<BinderDriverInterfaceTestEnv *>(binder_env)->EnterLooper();
}

TEST_F(BinderDriverInterfaceTest, WriteReadEmpty) {
    struct binder_write_read bwr = binder_write_read();
    binderTestIoctl(BINDER_WRITE_READ, &bwr);
}

TEST_F(BinderDriverInterfaceTest, Read) {
    binderTestReadEmpty();
}

TEST_F(BinderDriverInterfaceTest, IncRefsAcquireReleaseDecRefs) {
    const uint32_t bc[] = {
        BC_INCREFS,
        0,
        BC_ACQUIRE,
        0,
        BC_RELEASE,
        0,
        BC_DECREFS,
        0,
    };
    struct binder_write_read bwr = binder_write_read();
    bwr.write_buffer = (uintptr_t)bc;
    bwr.write_size = sizeof(bc);
    binderTestIoctl(BINDER_WRITE_READ, &bwr);
    EXPECT_EQ(sizeof(bc), bwr.write_consumed);
    binderTestReadEmpty();
}

TEST_F(BinderDriverInterfaceTest, Transaction) {
    binder_uintptr_t cookie = 1234;
    struct {
        uint32_t cmd1;
        struct binder_transaction_data arg1;
    } __attribute__((packed)) bc1 = {
        .cmd1 = BC_TRANSACTION,
        .arg1 = {
            .target = { 0 },
            .cookie = 0,
            .code = android::IBinder::PING_TRANSACTION,
            .flags = 0,
            .sender_pid = 0,
            .sender_euid = 0,
            .data_size = 0,
            .offsets_size = 0,
            .data = {
                .ptr = {0, 0},
            },
        },
    };
    struct {
        uint32_t cmd0;
        uint32_t cmd1;
        uint32_t cmd2;
        binder_transaction_data arg2;
        uint32_t pad[16];
    } __attribute__((packed)) br;
    struct binder_write_read bwr = binder_write_read();

    bwr.write_buffer = (uintptr_t)&bc1;
    bwr.write_size = sizeof(bc1);
    bwr.read_buffer = (uintptr_t)&br;
    bwr.read_size = sizeof(br);

    {
        SCOPED_TRACE("1st WriteRead");
        binderTestIoctl(BINDER_WRITE_READ, &bwr);
    }
    EXPECT_EQ(sizeof(bc1), bwr.write_consumed);
    if (bwr.read_consumed < offsetof(typeof(br), pad)) {
        SCOPED_TRACE("2nd WriteRead");
        binderWaitForReadData(10000);
        binderTestIoctl(BINDER_WRITE_READ, &bwr);
    }
    EXPECT_EQ(offsetof(typeof(br), pad), bwr.read_consumed);
    if (bwr.read_consumed > offsetof(typeof(br), cmd0))
        EXPECT_EQ(BR_NOOP, br.cmd0);
    if (bwr.read_consumed > offsetof(typeof(br), cmd1))
        EXPECT_EQ(BR_TRANSACTION_COMPLETE, br.cmd1);
    if (bwr.read_consumed > offsetof(typeof(br), cmd2))
        EXPECT_EQ(BR_REPLY, br.cmd2);
    if (bwr.read_consumed >= offsetof(typeof(br), pad)) {
        EXPECT_EQ(0u, br.arg2.target.ptr);
        EXPECT_EQ(0u, br.arg2.cookie);
        EXPECT_EQ(0u, br.arg2.code);
        EXPECT_EQ(0u, br.arg2.flags);
        EXPECT_EQ(0u, br.arg2.data_size);
        EXPECT_EQ(0u, br.arg2.offsets_size);

        SCOPED_TRACE("3rd WriteRead");

        binderTestReadEmpty();

        struct {
            uint32_t cmd1;
            binder_uintptr_t arg1;
        } __attribute__((packed)) bc2 = {
            .cmd1 = BC_FREE_BUFFER,
            .arg1 = br.arg2.data.ptr.buffer,
        };

        bwr.write_buffer = (uintptr_t)&bc2;
        bwr.write_size = sizeof(bc2);
        bwr.write_consumed = 0;
        bwr.read_size = 0;

        binderTestIoctl(BINDER_WRITE_READ, &bwr);
        EXPECT_EQ(sizeof(bc2), bwr.write_consumed);
    }
    binderTestReadEmpty();
}

TEST_F(BinderDriverInterfaceTest, RequestDeathNotification) {
    binder_uintptr_t cookie = 1234;
    struct {
        uint32_t cmd0;
        uint32_t arg0;
        uint32_t cmd1;
        struct binder_handle_cookie arg1;
        uint32_t cmd2;
        struct binder_handle_cookie arg2;
        uint32_t cmd3;
        uint32_t arg3;
    } __attribute__((packed)) bc = {
        .cmd0 = BC_INCREFS,
        .arg0 = 0,
        .cmd1 = BC_REQUEST_DEATH_NOTIFICATION,
        .arg1 = {
            .handle = 0,
            .cookie = cookie,
        },
        .cmd2 = BC_CLEAR_DEATH_NOTIFICATION,
        .arg2 = {
            .handle = 0,
            .cookie = cookie,
        },
        .cmd3 = BC_DECREFS,
        .arg3 = 0,
    };
    struct {
        uint32_t cmd0;
        uint32_t cmd1;
        binder_uintptr_t arg1;
        uint32_t pad[16];
    } __attribute__((packed)) br;
    struct binder_write_read bwr = binder_write_read();

    bwr.write_buffer = (uintptr_t)&bc;
    bwr.write_size = sizeof(bc);
    bwr.read_buffer = (uintptr_t)&br;
    bwr.read_size = sizeof(br);

    binderTestIoctl(BINDER_WRITE_READ, &bwr);
    EXPECT_EQ(sizeof(bc), bwr.write_consumed);
    EXPECT_EQ(sizeof(br) - sizeof(br.pad), bwr.read_consumed);
    EXPECT_EQ(BR_NOOP, br.cmd0);
    EXPECT_EQ(BR_CLEAR_DEATH_NOTIFICATION_DONE, br.cmd1);
    EXPECT_EQ(cookie, br.arg1);
    binderTestReadEmpty();
}

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

    binder_env = AddGlobalTestEnvironment(new BinderDriverInterfaceTestEnv());

    return RUN_ALL_TESTS();
}
