/*
 * Copyright (C) 2017 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 "android.hardware.usb@1.2-service.redfin"

#include <android-base/logging.h>
#include <android-base/properties.h>
#include <assert.h>
#include <dirent.h>
#include <pthread.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <chrono>
#include <regex>
#include <thread>
#include <unordered_map>

#include <cutils/uevent.h>
#include <sys/epoll.h>
#include <utils/Errors.h>
#include <utils/StrongPointer.h>

#include "Usb.h"

using android::base::GetProperty;

namespace android {
namespace hardware {
namespace usb {
namespace V1_2 {
namespace implementation {

// Set by the signal handler to destroy the thread
volatile bool destroyThread;

constexpr char kEnabledPath[] = "/sys/class/power_supply/usb/moisture_detection_enabled";
constexpr char kDetectedPath[] = "/sys/class/power_supply/usb/moisture_detected";
constexpr char kConsole[] = "init.svc.console";
constexpr char kDisableContatminantDetection[] = "vendor.usb.contaminantdisable";

void queryVersionHelper(android::hardware::usb::V1_2::implementation::Usb *usb,
                        hidl_vec<PortStatus> *currentPortStatus_1_2);

int32_t readFile(const std::string &filename, std::string *contents) {
    FILE *fp;
    ssize_t read = 0;
    char *line = NULL;
    size_t len = 0;

    fp = fopen(filename.c_str(), "r");
    if (fp != NULL) {
        if ((read = getline(&line, &len, fp)) != -1) {
            char *pos;
            if ((pos = strchr(line, '\n')) != NULL)
                *pos = '\0';
            *contents = line;
        }
        free(line);
        fclose(fp);
        return 0;
    } else {
        ALOGE("fopen failed");
    }

    return -1;
}

int32_t writeFile(const std::string &filename, const std::string &contents) {
    FILE *fp;
    std::string written;

    fp = fopen(filename.c_str(), "w");
    if (fp != NULL) {
        // FAILURE RETRY
        int ret = fputs(contents.c_str(), fp);
        fclose(fp);
        if ((ret != EOF) && !readFile(filename, &written) && written == contents)
            return 0;
    }
    return -1;
}

Status queryMoistureDetectionStatus(hidl_vec<PortStatus> *currentPortStatus_1_2) {
    std::string enabled, status;

    (*currentPortStatus_1_2)[0].supportedContaminantProtectionModes = 0;
    (*currentPortStatus_1_2)[0].supportedContaminantProtectionModes |=
        ContaminantProtectionMode::FORCE_SINK;
    (*currentPortStatus_1_2)[0].contaminantProtectionStatus = ContaminantProtectionStatus::NONE;
    (*currentPortStatus_1_2)[0].contaminantDetectionStatus = ContaminantDetectionStatus::DISABLED;
    (*currentPortStatus_1_2)[0].supportsEnableContaminantPresenceDetection = true;
    (*currentPortStatus_1_2)[0].supportsEnableContaminantPresenceProtection = false;

    if (readFile(kEnabledPath, &enabled)) {
        ALOGE("Failed to open moisture_detection_enabled");
        return Status::ERROR;
    }

    if (enabled == "1") {
        if (readFile(kDetectedPath, &status)) {
            ALOGE("Failed to open moisture_detected");
            return Status::ERROR;
        }
        if (status == "1") {
            (*currentPortStatus_1_2)[0].contaminantDetectionStatus =
                ContaminantDetectionStatus::DETECTED;
            (*currentPortStatus_1_2)[0].contaminantProtectionStatus =
                ContaminantProtectionStatus::FORCE_SINK;
        } else
            (*currentPortStatus_1_2)[0].contaminantDetectionStatus =
                ContaminantDetectionStatus::NOT_DETECTED;
    }

     ALOGI("ContaminantDetectionStatus:%d ContaminantProtectionStatus:%d",
	   (*currentPortStatus_1_2)[0].contaminantDetectionStatus,
	   (*currentPortStatus_1_2)[0].contaminantProtectionStatus);

    return Status::SUCCESS;
}

Return<void> Usb::enableContaminantPresenceDetection(const hidl_string & /*portName*/,
                                                     bool enable) {

    std::string status = GetProperty(kConsole, "");
    std::string disable = GetProperty(kDisableContatminantDetection, "");

    if (status != "running" && disable != "true")
        writeFile(kEnabledPath, enable ? "1" : "0");

    hidl_vec<PortStatus> currentPortStatus_1_2;

    queryVersionHelper(this, &currentPortStatus_1_2);
    return Void();
}

Return<void> Usb::enableContaminantPresenceProtection(const hidl_string & /*portName*/,
                                                      bool /*enable*/) {
    hidl_vec<PortStatus> currentPortStatus_1_2;

    queryVersionHelper(this, &currentPortStatus_1_2);
    return Void();
}

std::string appendRoleNodeHelper(const std::string &portName, PortRoleType type) {
    std::string node("/sys/class/typec/" + portName);

    switch (type) {
        case PortRoleType::DATA_ROLE:
            return node + "/data_role";
        case PortRoleType::POWER_ROLE:
            return node + "/power_role";
        case PortRoleType::MODE:
            return node + "/port_type";
        default:
            return "";
    }
}

std::string convertRoletoString(PortRole role) {
    if (role.type == PortRoleType::POWER_ROLE) {
        if (role.role == static_cast<uint32_t>(PortPowerRole::SOURCE))
            return "source";
        else if (role.role == static_cast<uint32_t>(PortPowerRole::SINK))
            return "sink";
    } else if (role.type == PortRoleType::DATA_ROLE) {
        if (role.role == static_cast<uint32_t>(PortDataRole::HOST))
            return "host";
        if (role.role == static_cast<uint32_t>(PortDataRole::DEVICE))
            return "device";
    } else if (role.type == PortRoleType::MODE) {
        if (role.role == static_cast<uint32_t>(PortMode_1_1::UFP))
            return "sink";
        if (role.role == static_cast<uint32_t>(PortMode_1_1::DFP))
            return "source";
    }
    return "none";
}

void extractRole(std::string *roleName) {
    std::size_t first, last;

    first = roleName->find("[");
    last = roleName->find("]");

    if (first != std::string::npos && last != std::string::npos) {
        *roleName = roleName->substr(first + 1, last - first - 1);
    }
}

void switchToDrp(const std::string &portName) {
    std::string filename = appendRoleNodeHelper(std::string(portName.c_str()), PortRoleType::MODE);
    FILE *fp;

    if (filename != "") {
        fp = fopen(filename.c_str(), "w");
        if (fp != NULL) {
            int ret = fputs("dual", fp);
            fclose(fp);
            if (ret == EOF)
                ALOGE("Fatal: Error while switching back to drp");
        } else {
            ALOGE("Fatal: Cannot open file to switch back to drp");
        }
    } else {
        ALOGE("Fatal: invalid node type");
    }
}

bool switchMode(const hidl_string &portName, const PortRole &newRole, struct Usb *usb) {
    std::string filename = appendRoleNodeHelper(std::string(portName.c_str()), newRole.type);
    std::string written;
    FILE *fp;
    bool roleSwitch = false;

    if (filename == "") {
        ALOGE("Fatal: invalid node type");
        return false;
    }

    fp = fopen(filename.c_str(), "w");
    if (fp != NULL) {
        // Hold the lock here to prevent loosing connected signals
        // as once the file is written the partner added signal
        // can arrive anytime.
        pthread_mutex_lock(&usb->mPartnerLock);
        usb->mPartnerUp = false;
        int ret = fputs(convertRoletoString(newRole).c_str(), fp);
        fclose(fp);

        if (ret != EOF) {
            struct timespec to;
            struct timespec now;

        wait_again:
            clock_gettime(CLOCK_MONOTONIC, &now);
            to.tv_sec = now.tv_sec + PORT_TYPE_TIMEOUT;
            to.tv_nsec = now.tv_nsec;

            int err = pthread_cond_timedwait(&usb->mPartnerCV, &usb->mPartnerLock, &to);
            // There are no uevent signals which implies role swap timed out.
            if (err == ETIMEDOUT) {
                ALOGI("uevents wait timedout");
                // Sanity check.
            } else if (!usb->mPartnerUp) {
                goto wait_again;
                // Role switch succeeded since usb->mPartnerUp is true.
            } else {
                roleSwitch = true;
            }
        } else {
            ALOGI("Role switch failed while wrting to file");
        }
        pthread_mutex_unlock(&usb->mPartnerLock);
    }

    if (!roleSwitch)
        switchToDrp(std::string(portName.c_str()));

    return roleSwitch;
}

Usb::Usb()
    : mLock(PTHREAD_MUTEX_INITIALIZER),
      mRoleSwitchLock(PTHREAD_MUTEX_INITIALIZER),
      mPartnerLock(PTHREAD_MUTEX_INITIALIZER),
      mPartnerUp(false) {
    pthread_condattr_t attr;
    if (pthread_condattr_init(&attr)) {
        ALOGE("pthread_condattr_init failed: %s", strerror(errno));
        abort();
    }
    if (pthread_condattr_setclock(&attr, CLOCK_MONOTONIC)) {
        ALOGE("pthread_condattr_setclock failed: %s", strerror(errno));
        abort();
    }
    if (pthread_cond_init(&mPartnerCV, &attr)) {
        ALOGE("pthread_cond_init failed: %s", strerror(errno));
        abort();
    }
    if (pthread_condattr_destroy(&attr)) {
        ALOGE("pthread_condattr_destroy failed: %s", strerror(errno));
        abort();
    }
}

Return<void> Usb::switchRole(const hidl_string &portName, const V1_0::PortRole &newRole) {
    std::string filename = appendRoleNodeHelper(std::string(portName.c_str()), newRole.type);
    std::string written;
    FILE *fp;
    bool roleSwitch = false;

    if (filename == "") {
        ALOGE("Fatal: invalid node type");
        return Void();
    }

    pthread_mutex_lock(&mRoleSwitchLock);

    ALOGI("filename write: %s role:%s", filename.c_str(), convertRoletoString(newRole).c_str());

    if (newRole.type == PortRoleType::MODE) {
        roleSwitch = switchMode(portName, newRole, this);
    } else {
        fp = fopen(filename.c_str(), "w");
        if (fp != NULL) {
            int ret = fputs(convertRoletoString(newRole).c_str(), fp);
            fclose(fp);
            if ((ret != EOF) && !readFile(filename, &written)) {
                extractRole(&written);
                ALOGI("written: %s", written.c_str());
                if (written == convertRoletoString(newRole)) {
                    roleSwitch = true;
                } else {
                    ALOGE("Role switch failed");
                }
            } else {
                ALOGE("failed to update the new role");
            }
        } else {
            ALOGE("fopen failed");
        }
    }

    pthread_mutex_lock(&mLock);
    if (mCallback_1_0 != NULL) {
        Return<void> ret = mCallback_1_0->notifyRoleSwitchStatus(
            portName, newRole, roleSwitch ? Status::SUCCESS : Status::ERROR);
        if (!ret.isOk())
            ALOGE("RoleSwitchStatus error %s", ret.description().c_str());
    } else {
        ALOGE("Not notifying the userspace. Callback is not set");
    }
    pthread_mutex_unlock(&mLock);
    pthread_mutex_unlock(&mRoleSwitchLock);

    return Void();
}

Status getAccessoryConnected(const std::string &portName, std::string *accessory) {
    std::string filename = "/sys/class/typec/" + portName + "-partner/accessory_mode";

    if (readFile(filename, accessory)) {
        ALOGE("getAccessoryConnected: Failed to open filesystem node: %s", filename.c_str());
        return Status::ERROR;
    }

    return Status::SUCCESS;
}

Status getCurrentRoleHelper(const std::string &portName, bool connected, PortRoleType type,
                            uint32_t *currentRole) {
    std::string filename;
    std::string roleName;
    std::string accessory;

    // Mode

    if (type == PortRoleType::POWER_ROLE) {
        filename = "/sys/class/typec/" + portName + "/power_role";
        *currentRole = static_cast<uint32_t>(PortPowerRole::NONE);
    } else if (type == PortRoleType::DATA_ROLE) {
        filename = "/sys/class/typec/" + portName + "/data_role";
        *currentRole = static_cast<uint32_t>(PortDataRole::NONE);
    } else if (type == PortRoleType::MODE) {
        filename = "/sys/class/typec/" + portName + "/data_role";
        *currentRole = static_cast<uint32_t>(PortMode_1_1::NONE);
    } else {
        return Status::ERROR;
    }

    if (!connected)
        return Status::SUCCESS;

    if (type == PortRoleType::MODE) {
        if (getAccessoryConnected(portName, &accessory) != Status::SUCCESS) {
            return Status::ERROR;
        }
        if (accessory == "analog_audio") {
            *currentRole = static_cast<uint32_t>(PortMode_1_1::AUDIO_ACCESSORY);
            return Status::SUCCESS;
        } else if (accessory == "debug") {
            *currentRole = static_cast<uint32_t>(PortMode_1_1::DEBUG_ACCESSORY);
            return Status::SUCCESS;
        }
    }

    if (readFile(filename, &roleName)) {
        ALOGE("getCurrentRole: Failed to open filesystem node: %s", filename.c_str());
        return Status::ERROR;
    }

    extractRole(&roleName);

    if (roleName == "source") {
        *currentRole = static_cast<uint32_t>(PortPowerRole::SOURCE);
    } else if (roleName == "sink") {
        *currentRole = static_cast<uint32_t>(PortPowerRole::SINK);
    } else if (roleName == "host") {
        if (type == PortRoleType::DATA_ROLE)
            *currentRole = static_cast<uint32_t>(PortDataRole::HOST);
        else
            *currentRole = static_cast<uint32_t>(PortMode_1_1::DFP);
    } else if (roleName == "device") {
        if (type == PortRoleType::DATA_ROLE)
            *currentRole = static_cast<uint32_t>(PortDataRole::DEVICE);
        else
            *currentRole = static_cast<uint32_t>(PortMode_1_1::UFP);
    } else if (roleName != "none") {
        /* case for none has already been addressed.
         * so we check if the role isnt none.
         */
        return Status::UNRECOGNIZED_ROLE;
    }

    return Status::SUCCESS;
}

Status getTypeCPortNamesHelper(std::unordered_map<std::string, bool> *names) {
    DIR *dp;

    dp = opendir("/sys/class/typec");
    if (dp != NULL) {
        struct dirent *ep;

        while ((ep = readdir(dp))) {
            if (ep->d_type == DT_LNK) {
                if (std::string::npos == std::string(ep->d_name).find("-partner")) {
                    std::unordered_map<std::string, bool>::const_iterator portName =
                        names->find(ep->d_name);
                    if (portName == names->end()) {
                        names->insert({ep->d_name, false});
                    }
                } else {
                    (*names)[std::strtok(ep->d_name, "-")] = true;
                }
            }
        }
        closedir(dp);
        return Status::SUCCESS;
    }

    ALOGE("Failed to open /sys/class/typec");
    return Status::ERROR;
}

bool canSwitchRoleHelper(const std::string &portName, PortRoleType /*type*/) {
    std::string filename = "/sys/class/typec/" + portName + "-partner/supports_usb_power_delivery";
    std::string supportsPD;

    if (!readFile(filename, &supportsPD)) {
        if (supportsPD == "yes") {
            return true;
        }
    }

    return false;
}

/*
 * Reuse the same method for both V1_0 and V1_1 callback objects.
 * The caller of this method would reconstruct the V1_0::PortStatus
 * object if required.
 */
Status getPortStatusHelper(hidl_vec<PortStatus> *currentPortStatus_1_2, HALVersion version) {
    std::unordered_map<std::string, bool> names;
    Status result = getTypeCPortNamesHelper(&names);
    int i = -1;

    if (result == Status::SUCCESS) {
        currentPortStatus_1_2->resize(names.size());
        for (std::pair<std::string, bool> port : names) {
            i++;
            ALOGI("%s", port.first.c_str());
            (*currentPortStatus_1_2)[i].status_1_1.status.portName = port.first;

            uint32_t currentRole;
            if (getCurrentRoleHelper(port.first, port.second, PortRoleType::POWER_ROLE,
                                     &currentRole) == Status::SUCCESS) {
                (*currentPortStatus_1_2)[i].status_1_1.status.currentPowerRole =
                    static_cast<PortPowerRole>(currentRole);
            } else {
                ALOGE("Error while retreiving portNames");
                goto done;
            }

            if (getCurrentRoleHelper(port.first, port.second, PortRoleType::DATA_ROLE,
                                     &currentRole) == Status::SUCCESS) {
                (*currentPortStatus_1_2)[i].status_1_1.status.currentDataRole =
                    static_cast<PortDataRole>(currentRole);
            } else {
                ALOGE("Error while retreiving current port role");
                goto done;
            }

            if (getCurrentRoleHelper(port.first, port.second, PortRoleType::MODE, &currentRole) ==
                Status::SUCCESS) {
                (*currentPortStatus_1_2)[i].status_1_1.currentMode =
                    static_cast<PortMode_1_1>(currentRole);
                (*currentPortStatus_1_2)[i].status_1_1.status.currentMode =
                    static_cast<V1_0::PortMode>(currentRole);
            } else {
                ALOGE("Error while retreiving current data role");
                goto done;
            }

            (*currentPortStatus_1_2)[i].status_1_1.status.canChangeMode = true;
            (*currentPortStatus_1_2)[i].status_1_1.status.canChangeDataRole =
                port.second ? canSwitchRoleHelper(port.first, PortRoleType::DATA_ROLE) : false;
            (*currentPortStatus_1_2)[i].status_1_1.status.canChangePowerRole =
                port.second ? canSwitchRoleHelper(port.first, PortRoleType::POWER_ROLE) : false;

            if (version == HALVersion::V1_0) {
                ALOGI("HAL version V1_0");
                (*currentPortStatus_1_2)[i].status_1_1.status.supportedModes = V1_0::PortMode::DRP;
            } else {
		if (version == HALVersion::V1_1)
                    ALOGI("HAL version V1_1");
		else
                    ALOGI("HAL version V1_2");
                (*currentPortStatus_1_2)[i].status_1_1.supportedModes = 0 | PortMode_1_1::DRP;
                (*currentPortStatus_1_2)[i].status_1_1.status.supportedModes = V1_0::PortMode::NONE;
                (*currentPortStatus_1_2)[i].status_1_1.status.currentMode = V1_0::PortMode::NONE;
            }

            ALOGI(
                "%d:%s connected:%d canChangeMode:%d canChagedata:%d canChangePower:%d "
                "supportedModes:%d",
                i, port.first.c_str(), port.second,
                (*currentPortStatus_1_2)[i].status_1_1.status.canChangeMode,
                (*currentPortStatus_1_2)[i].status_1_1.status.canChangeDataRole,
                (*currentPortStatus_1_2)[i].status_1_1.status.canChangePowerRole,
                (*currentPortStatus_1_2)[i].status_1_1.supportedModes);
        }
        return Status::SUCCESS;
    }
done:
    return Status::ERROR;
}

void queryVersionHelper(android::hardware::usb::V1_2::implementation::Usb *usb,
                        hidl_vec<PortStatus> *currentPortStatus_1_2) {
    hidl_vec<V1_1::PortStatus_1_1> currentPortStatus_1_1;
    hidl_vec<V1_0::PortStatus> currentPortStatus;
    Status status;
    sp<V1_1::IUsbCallback> callback_V1_1 = V1_1::IUsbCallback::castFrom(usb->mCallback_1_0);
    sp<IUsbCallback> callback_V1_2 = IUsbCallback::castFrom(usb->mCallback_1_0);

    pthread_mutex_lock(&usb->mLock);
    if (usb->mCallback_1_0 != NULL) {
        if (callback_V1_2 != NULL) {
            status = getPortStatusHelper(currentPortStatus_1_2, HALVersion::V1_2);
            queryMoistureDetectionStatus(currentPortStatus_1_2);
        } else if (callback_V1_1 != NULL) {
            status = getPortStatusHelper(currentPortStatus_1_2, HALVersion::V1_1);
            currentPortStatus_1_1.resize(currentPortStatus_1_2->size());
            for (unsigned long i = 0; i < currentPortStatus_1_2->size(); i++)
                currentPortStatus_1_1[i] = (*currentPortStatus_1_2)[i].status_1_1;
        } else {
            status = getPortStatusHelper(currentPortStatus_1_2, HALVersion::V1_0);
            currentPortStatus.resize(currentPortStatus_1_2->size());
            for (unsigned long i = 0; i < currentPortStatus_1_2->size(); i++)
                currentPortStatus[i] = (*currentPortStatus_1_2)[i].status_1_1.status;
        }

        Return<void> ret;

        if (callback_V1_2 != NULL)
            ret = callback_V1_2->notifyPortStatusChange_1_2(*currentPortStatus_1_2, status);
        else if (callback_V1_1 != NULL)
            ret = callback_V1_1->notifyPortStatusChange_1_1(currentPortStatus_1_1, status);
        else
            ret = usb->mCallback_1_0->notifyPortStatusChange(currentPortStatus, status);

        if (!ret.isOk())
            ALOGE("queryPortStatus_1_2 error %s", ret.description().c_str());
    } else {
        ALOGI("Notifying userspace skipped. Callback is NULL");
    }
    pthread_mutex_unlock(&usb->mLock);
}

Return<void> Usb::queryPortStatus() {
    hidl_vec<PortStatus> currentPortStatus_1_2;

    queryVersionHelper(this, &currentPortStatus_1_2);
    return Void();
}

struct data {
    int uevent_fd;
    android::hardware::usb::V1_2::implementation::Usb *usb;
};

static void uevent_event(uint32_t /*epevents*/, struct data *payload) {
    char msg[UEVENT_MSG_LEN + 2];
    char *cp;
    int n;

    n = uevent_kernel_multicast_recv(payload->uevent_fd, msg, UEVENT_MSG_LEN);
    if (n <= 0)
        return;
    if (n >= UEVENT_MSG_LEN) /* overflow -- discard */
        return;

    msg[n] = '\0';
    msg[n + 1] = '\0';
    cp = msg;

    while (*cp) {
        if (std::regex_match(cp, std::regex("(add)(.*)(-partner)"))) {
            ALOGI("partner added");
            pthread_mutex_lock(&payload->usb->mPartnerLock);
            payload->usb->mPartnerUp = true;
            pthread_cond_signal(&payload->usb->mPartnerCV);
            pthread_mutex_unlock(&payload->usb->mPartnerLock);
        } else if (!strncmp(cp, "DEVTYPE=typec_", strlen("DEVTYPE=typec_")) ||
                   !strncmp(cp, "POWER_SUPPLY_MOISTURE_DETECTED",
                            strlen("POWER_SUPPLY_MOISTURE_DETECTED"))) {
            hidl_vec<PortStatus> currentPortStatus_1_2;
            queryVersionHelper(payload->usb, &currentPortStatus_1_2);

            // Role switch is not in progress and port is in disconnected state
            if (!pthread_mutex_trylock(&payload->usb->mRoleSwitchLock)) {
                for (unsigned long i = 0; i < currentPortStatus_1_2.size(); i++) {
                    DIR *dp =
                        opendir(std::string("/sys/class/typec/" +
                                            std::string(currentPortStatus_1_2[i]
                                                            .status_1_1.status.portName.c_str()) +
                                            "-partner")
                                    .c_str());
                    if (dp == NULL) {
                        // PortRole role = {.role = static_cast<uint32_t>(PortMode::UFP)};
                        switchToDrp(currentPortStatus_1_2[i].status_1_1.status.portName);
                    } else {
                        closedir(dp);
                    }
                }
                pthread_mutex_unlock(&payload->usb->mRoleSwitchLock);
            }
            break;
        }
        /* advance to after the next \0 */
        while (*cp++) {
        }
    }
}

void *work(void *param) {
    int epoll_fd, uevent_fd;
    struct epoll_event ev;
    int nevents = 0;
    struct data payload;

    ALOGE("creating thread");

    uevent_fd = uevent_open_socket(64 * 1024, true);

    if (uevent_fd < 0) {
        ALOGE("uevent_init: uevent_open_socket failed\n");
        return NULL;
    }

    payload.uevent_fd = uevent_fd;
    payload.usb = (android::hardware::usb::V1_2::implementation::Usb *)param;

    fcntl(uevent_fd, F_SETFL, O_NONBLOCK);

    ev.events = EPOLLIN;
    ev.data.ptr = (void *)uevent_event;

    epoll_fd = epoll_create(64);
    if (epoll_fd == -1) {
        ALOGE("epoll_create failed; errno=%d", errno);
        goto error;
    }

    if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, uevent_fd, &ev) == -1) {
        ALOGE("epoll_ctl failed; errno=%d", errno);
        goto error;
    }

    while (!destroyThread) {
        struct epoll_event events[64];

        nevents = epoll_wait(epoll_fd, events, 64, -1);
        if (nevents == -1) {
            if (errno == EINTR)
                continue;
            ALOGE("usb epoll_wait failed; errno=%d", errno);
            break;
        }

        for (int n = 0; n < nevents; ++n) {
            if (events[n].data.ptr)
                (*(void (*)(int, struct data *payload))events[n].data.ptr)(events[n].events,
                                                                           &payload);
        }
    }

    ALOGI("exiting worker thread");
error:
    close(uevent_fd);

    if (epoll_fd >= 0)
        close(epoll_fd);

    return NULL;
}

void sighandler(int sig) {
    if (sig == SIGUSR1) {
        destroyThread = true;
        ALOGI("destroy set");
        return;
    }
    signal(SIGUSR1, sighandler);
}

Return<void> Usb::setCallback(const sp<V1_0::IUsbCallback> &callback) {
    sp<V1_1::IUsbCallback> callback_V1_1 = V1_1::IUsbCallback::castFrom(callback);
    sp<IUsbCallback> callback_V1_2 = IUsbCallback::castFrom(callback);

    if (callback != NULL) {
        if (callback_V1_2 != NULL)
            ALOGI("Registering 1.2 callback");
        else if (callback_V1_1 != NULL)
            ALOGI("Registering 1.1 callback");
    }

    pthread_mutex_lock(&mLock);
    /*
     * When both the old callback and new callback values are NULL,
     * there is no need to spin off the worker thread.
     * When both the values are not NULL, we would already have a
     * worker thread running, so updating the callback object would
     * be suffice.
     */
    if ((mCallback_1_0 == NULL && callback == NULL) ||
        (mCallback_1_0 != NULL && callback != NULL)) {
        /*
         * Always store as V1_0 callback object. Type cast to V1_1
         * when the callback is actually invoked.
         */
        mCallback_1_0 = callback;
        pthread_mutex_unlock(&mLock);
        return Void();
    }

    mCallback_1_0 = callback;
    ALOGI("registering callback");

    // Kill the worker thread if the new callback is NULL.
    if (mCallback_1_0 == NULL) {
        pthread_mutex_unlock(&mLock);
        if (!pthread_kill(mPoll, SIGUSR1)) {
            pthread_join(mPoll, NULL);
            ALOGI("pthread destroyed");
        }
        return Void();
    }

    destroyThread = false;
    signal(SIGUSR1, sighandler);

    /*
     * Create a background thread if the old callback value is NULL
     * and being updated with a new value.
     */
    if (pthread_create(&mPoll, NULL, work, this)) {
        ALOGE("pthread creation failed %d", errno);
        mCallback_1_0 = NULL;
    }

    pthread_mutex_unlock(&mLock);
    return Void();
}

}  // namespace implementation
}  // namespace V1_2
}  // namespace usb
}  // namespace hardware
}  // namespace android
