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

/**
 * This is a very basic implementation of fingerprint to allow testing on the emulator. It
 * is *not* meant to be the final implementation on real devices.  For example,  it does *not*
 * implement all of the required features, such as secure template storage and recognition
 * inside a Trusted Execution Environment (TEE). However, this file is a reasonable starting
 * point as developers add fingerprint support to their platform.  See inline comments and
 * recommendations for details.
 *
 * Please see the Android Compatibility Definition Document (CDD) for a full list of requirements
 * and suggestions.
 */
#define LOG_TAG "FingerprintHal"

#include <errno.h>
#include <endian.h>
#include <inttypes.h>
#include <malloc.h>
#include <string.h>
#include <cutils/log.h>
#include <hardware/hardware.h>
#include <hardware/fingerprint.h>
#include <hardware/qemud.h>

#include <poll.h>

#define FINGERPRINT_LISTEN_SERVICE_NAME "fingerprintlisten"
#define FINGERPRINT_FILENAME \
    "/data/system/users/0/fpdata/emulator_fingerprint_storage.bin"
#define MAX_COMM_CHARS 128
#define MAX_COMM_ERRORS 8
// Typical devices will allow up to 5 fingerprints per user to maintain performance of
// t < 500ms for recognition.  This is the total number of fingerprints we'll store.
#define MAX_NUM_FINGERS 20
#define MAX_FID_VALUE 0x7FFFFFFF  // Arbitrary limit

/**
 * Most devices will have an internal state machine resembling this. There are 3 basic states, as
 * shown below. When device is not authenticating or enrolling, it is expected to be in
 * the idle state.
 *
 * Note that this is completely independent of device wake state.  If the hardware device was in
 * the "scan" state when the device drops into power collapse, it should resume scanning when power
 * is restored.  This is to facilitate rapid touch-to-unlock from keyguard.
 */
typedef enum worker_state_t {
    STATE_IDLE = 0,
    STATE_ENROLL,
    STATE_SCAN,
    STATE_EXIT
} worker_state_t;

typedef struct worker_thread_t {
    pthread_t thread;
    worker_state_t state;
    uint64_t secureid[MAX_NUM_FINGERS];
    uint64_t authenid[MAX_NUM_FINGERS];
} worker_thread_t;

typedef struct qemu_fingerprint_device_t {
    fingerprint_device_t device;  // "inheritance"
    worker_thread_t listener;
    uint64_t op_id;
    uint64_t challenge;
    uint64_t user_id;
    uint64_t group_id;
    uint64_t secure_user_id;
    uint64_t authenticator_id;
    int qchanfd;
    pthread_mutex_t lock;
} qemu_fingerprint_device_t;

/******************************************************************************/

static void saveFingerprint(worker_thread_t* listener, int idx) {
    ALOGD("----------------> %s -----------------> idx %d", __FUNCTION__, idx);

    // Save fingerprints to file
    FILE* fp = fopen(FINGERPRINT_FILENAME, "r+");  // write but don't truncate
    if (fp == NULL) {
        ALOGE("Could not open fingerprints storage at %s; "
              "fingerprints won't be saved",
              FINGERPRINT_FILENAME);
        perror("Failed to open file");
        return;
    }

    ALOGD("Write fingerprint[%d] (0x%" PRIx64 ",0x%" PRIx64 ")", idx,
          listener->secureid[idx], listener->authenid[idx]);

    if (fseek(fp, (idx) * sizeof(uint64_t), SEEK_SET) < 0) {
        ALOGE("Failed while seeking for fingerprint[%d] in emulator storage",
              idx);
        fclose(fp);
        return;
    }
    int ns = fwrite(&listener->secureid[idx], sizeof(uint64_t), 1, fp);
    if (fseek(fp, (MAX_NUM_FINGERS + idx) * sizeof(uint64_t), SEEK_SET) < 0) {
        ALOGE("Failed while seeking for fingerprint[%d] in emulator storage",
              idx);
        fclose(fp);
        return;
    }
    int na = fwrite(&listener->authenid[idx], sizeof(uint64_t), 1, fp);
    if (ns != 1 || na != 1)
        ALOGW("Corrupt emulator fingerprints storage; could not save "
              "fingerprints");

    fclose(fp);

    return;
}

static void loadFingerprints(worker_thread_t* listener) {
    ALOGD("----------------> %s ----------------->", __FUNCTION__);
    FILE* fp = fopen(FINGERPRINT_FILENAME, "a+");  // so we can create if empty
    if (fp == NULL) {
        ALOGE("Could not load fingerprints from storage at %s; "
              "it has not yet been created.",
              FINGERPRINT_FILENAME);
        perror("Failed to open/create file");
        return;
    }

    int ns = fread(listener->secureid, MAX_NUM_FINGERS * sizeof(uint64_t), 1,
                   fp);
    int na = fread(listener->authenid, MAX_NUM_FINGERS * sizeof(uint64_t), 1,
                   fp);
    if (ns != 1 || na != 1)
        ALOGW("Corrupt emulator fingerprints storage (read %d+%db)", ns, na);

    int i = 0;
    for (i = 0; i < MAX_NUM_FINGERS; i++)
        ALOGD("Read fingerprint %d (0x%" PRIx64 ",0x%" PRIx64 ")", i,
              listener->secureid[i], listener->authenid[i]);

    fclose(fp);

    return;
}

/******************************************************************************/

static uint64_t get_64bit_rand() {
    // This should use a cryptographically-secure random number generator like arc4random().
    // It should be generated inside of the TEE where possible. Here we just use something
    // very simple.
    ALOGD("----------------> %s ----------------->", __FUNCTION__);
    uint64_t r = (((uint64_t)rand()) << 32) | ((uint64_t)rand());
    return r != 0 ? r : 1;
}

static uint64_t fingerprint_get_auth_id(struct fingerprint_device* device) {
    // This should return the authentication_id generated when the fingerprint template database
    // was created.  Though this isn't expected to be secret, it is reasonable to expect it to be
    // cryptographically generated to avoid replay attacks.
    qemu_fingerprint_device_t* qdev = (qemu_fingerprint_device_t*)device;
    ALOGD("----------------> %s ----------------->", __FUNCTION__);
    uint64_t authenticator_id = 0;
    pthread_mutex_lock(&qdev->lock);
    authenticator_id = qdev->authenticator_id;
    pthread_mutex_unlock(&qdev->lock);

    return authenticator_id;
}

static int fingerprint_set_active_group(struct fingerprint_device __unused *device, uint32_t gid,
        const char *path) {
    // Groups are a future feature.  For now, the framework sends the profile owner's id (userid)
    // as the primary group id for the user.  This code should create a tuple (groupId, fingerId)
    // that represents a single fingerprint entity in the database.  For now we just generate
    // globally unique ids.
    ALOGW("Setting active finger group not implemented");
    return 0;
}

/**
 * If fingerprints are enrolled, then this function is expected to put the sensor into a
 * "scanning" state where it's actively scanning and recognizing fingerprint features.
 * Actual authentication must happen in TEE and should be monitored in a separate thread
 * since this function is expected to return immediately.
 */
static int fingerprint_authenticate(struct fingerprint_device *device,
    uint64_t operation_id, __unused uint32_t gid)
{
    qemu_fingerprint_device_t* qdev = (qemu_fingerprint_device_t*)device;

    pthread_mutex_lock(&qdev->lock);
    qdev->op_id = operation_id;
    qdev->listener.state = STATE_SCAN;
    pthread_mutex_unlock(&qdev->lock);

    return 0;
}

/**
 * This is expected to put the sensor into an "enroll" state where it's actively scanning and
 * working towards a finished fingerprint database entry. Authentication must happen in
 * a separate thread since this function is expected to return immediately.
 *
 * Note: This method should always generate a new random authenticator_id.
 *
 * Note: As with fingerprint_authenticate(), this would run in TEE on a real device.
 */
static int fingerprint_enroll(struct fingerprint_device *device,
        const hw_auth_token_t *hat,
        uint32_t __unused gid,
        uint32_t __unused timeout_sec) {
    ALOGD("fingerprint_enroll");
    qemu_fingerprint_device_t* dev = (qemu_fingerprint_device_t*)device;
    if (!hat) {
        ALOGW("%s: null auth token", __func__);
        return -EPROTONOSUPPORT;
    }
    if (hat->challenge == dev->challenge) {
        // The secure_user_id retrieved from the auth token should be stored
        // with the enrolled fingerprint template and returned in the auth result
        // for a successful authentication with that finger.
        dev->secure_user_id = hat->user_id;
    } else {
        ALOGW("%s: invalid auth token", __func__);
    }

    if (hat->version != HW_AUTH_TOKEN_VERSION) {
        return -EPROTONOSUPPORT;
    }
    if (hat->challenge != dev->challenge && !(hat->authenticator_type & HW_AUTH_FINGERPRINT)) {
        return -EPERM;
    }

    dev->user_id = hat->user_id;

    pthread_mutex_lock(&dev->lock);
    dev->listener.state = STATE_ENROLL;
    pthread_mutex_unlock(&dev->lock);

    // fingerprint id, authenticator id, and secure_user_id
    // will be stored by worked thread

    return 0;

}

/**
 * The pre-enrollment step is simply to get an authentication token that can be wrapped and
 * verified at a later step.  The primary purpose is to return a token that protects against
 * spoofing and replay attacks. It is passed to password authentication where it is wrapped and
 * propagated to the enroll step.
 */
static uint64_t fingerprint_pre_enroll(struct fingerprint_device *device) {
    ALOGD("----------------> %s ----------------->", __FUNCTION__);
    uint64_t challenge = 0;
    qemu_fingerprint_device_t* qdev = (qemu_fingerprint_device_t*)device;

    // The challenge will typically be a cryptographically-secure key
    // coming from the TEE so it can be verified at a later step. For now we just generate a
    // random value.
    challenge = get_64bit_rand();

    pthread_mutex_lock(&qdev->lock);
    qdev->challenge = challenge;
    pthread_mutex_unlock(&qdev->lock);

    return challenge;
}

static int fingerprint_post_enroll(struct fingerprint_device* device) {
    ALOGD("----------------> %s ----------------->", __FUNCTION__);
    qemu_fingerprint_device_t* qdev = (qemu_fingerprint_device_t*)device;

    pthread_mutex_lock(&qdev->lock);
    qdev->challenge = 0;
    pthread_mutex_unlock(&qdev->lock);

    return 0;
}

/**
 * Cancel is called by the framework to cancel an outstanding event.  This should *not* be called
 * by the driver since it will cause the framework to stop listening for fingerprints.
 */
static int fingerprint_cancel(struct fingerprint_device *device) {
    ALOGD("----------------> %s ----------------->", __FUNCTION__);
    qemu_fingerprint_device_t* qdev = (qemu_fingerprint_device_t*)device;

    fingerprint_msg_t msg = {0};
    msg.type = FINGERPRINT_ERROR;
    msg.data.error = FINGERPRINT_ERROR_CANCELED;

    pthread_mutex_lock(&qdev->lock);
    qdev->listener.state = STATE_IDLE;
    pthread_mutex_unlock(&qdev->lock);

    device->notify(&msg);

    return 0;
}

static int fingerprint_enumerate(struct fingerprint_device *device,
        fingerprint_finger_id_t *results, uint32_t *max_size) {
    ALOGD("----------------> %s ----------------->", __FUNCTION__);
    if (device == NULL || results == NULL || max_size == NULL) {
        ALOGE("Cannot enumerate saved fingerprints with uninitialized params");
        return -1;
    }

    qemu_fingerprint_device_t* qdev = (qemu_fingerprint_device_t*)device;
    unsigned int i = 0;
    int num = 0;
    for (i = 0; i < MAX_NUM_FINGERS; i++) {
        if (qdev->listener.secureid[i] != 0 ||
            qdev->listener.authenid[i] != 0) {
            ALOGD("ENUM: Fingerprint [%d] = 0x%" PRIx64 ",%" PRIx64, i,
                  qdev->listener.secureid[i], qdev->listener.authenid[i]);
            num++;
        }
    }

    return num;
}

static int fingerprint_remove(struct fingerprint_device *device,
        uint32_t __unused gid, uint32_t fid) {
    int idx = 0;
    fingerprint_msg_t msg = {0};
    ALOGD("----------------> %s -----------------> fid %d", __FUNCTION__, fid);
    if (device == NULL) {
        ALOGE("Can't remove fingerprint (gid=%d, fid=%d); "
              "device not initialized properly",
              gid, fid);
        return -1;
    }

    qemu_fingerprint_device_t* qdev = (qemu_fingerprint_device_t*)device;

    if (fid == 0) {
        // Delete all fingerprints
        // I'll do this one at a time, so I am not
        // holding the mutext during the notification
        bool listIsEmpty;
        do {
            pthread_mutex_lock(&qdev->lock);
            listIsEmpty = true;  // Haven't seen a valid entry yet
            for (idx = 0; idx < MAX_NUM_FINGERS; idx++) {
                uint32_t theFid = qdev->listener.authenid[idx];
                if (theFid != 0) {
                    // Delete this entry
                    qdev->listener.secureid[idx] = 0;
                    qdev->listener.authenid[idx] = 0;
                    saveFingerprint(&qdev->listener, idx);

                    // Send a notification that we deleted this one
                    pthread_mutex_unlock(&qdev->lock);
                    msg.type = FINGERPRINT_TEMPLATE_REMOVED;
                    msg.data.removed.finger.fid = theFid;
                    device->notify(&msg);

                    // Because we released the mutex, the list
                    // may have changed. Restart the 'for' loop
                    // after reacquiring the mutex.
                    listIsEmpty = false;
                    break;
                }
            }  // end for (idx < MAX_NUM_FINGERS)
        } while (!listIsEmpty);
        qdev->listener.state = STATE_IDLE;
        pthread_mutex_unlock(&qdev->lock);
    } else {
        // Delete one fingerprint
        // Look for this finger ID in our table.
        pthread_mutex_lock(&qdev->lock);
        for (idx = 0; idx < MAX_NUM_FINGERS; idx++) {
            if (qdev->listener.authenid[idx] == fid &&
                qdev->listener.secureid[idx] != 0) {
                // Found it!
                break;
            }
        }
        if (idx >= MAX_NUM_FINGERS) {
            qdev->listener.state = STATE_IDLE;
            pthread_mutex_unlock(&qdev->lock);
            ALOGE("Fingerprint ID %d not found", fid);
            return FINGERPRINT_ERROR;
        }

        qdev->listener.secureid[idx] = 0;
        qdev->listener.authenid[idx] = 0;
        saveFingerprint(&qdev->listener, idx);

        qdev->listener.state = STATE_IDLE;
        pthread_mutex_unlock(&qdev->lock);

        msg.type = FINGERPRINT_TEMPLATE_REMOVED;
        msg.data.removed.finger.fid = fid;
        device->notify(&msg);
    }

    return 0;
}

static int set_notify_callback(struct fingerprint_device *device,
                               fingerprint_notify_t notify) {
    ALOGD("----------------> %s ----------------->", __FUNCTION__);
    if (device == NULL || notify == NULL) {
        ALOGE("Failed to set notify callback @ %p for fingerprint device %p",
              device, notify);
        return -1;
    }

    qemu_fingerprint_device_t* qdev = (qemu_fingerprint_device_t*)device;
    pthread_mutex_lock(&qdev->lock);
    qdev->listener.state = STATE_IDLE;
    device->notify = notify;
    pthread_mutex_unlock(&qdev->lock);
    ALOGD("fingerprint callback notification set");

    return 0;
}

static void send_scan_notice(qemu_fingerprint_device_t* qdev, int fid) {
    ALOGD("----------------> %s ----------------->", __FUNCTION__);

    // acquired message
    fingerprint_msg_t acqu_msg = {0};
    acqu_msg.type = FINGERPRINT_ACQUIRED;
    acqu_msg.data.acquired.acquired_info = FINGERPRINT_ACQUIRED_GOOD;

    // authenticated message
    fingerprint_msg_t auth_msg = {0};
    auth_msg.type = FINGERPRINT_AUTHENTICATED;
    auth_msg.data.authenticated.finger.fid = fid;
    auth_msg.data.authenticated.finger.gid = 0;  // unused
    auth_msg.data.authenticated.hat.version = HW_AUTH_TOKEN_VERSION;
    auth_msg.data.authenticated.hat.authenticator_type =
            htobe32(HW_AUTH_FINGERPRINT);
    auth_msg.data.authenticated.hat.challenge = qdev->op_id;
    auth_msg.data.authenticated.hat.authenticator_id = qdev->authenticator_id;
    auth_msg.data.authenticated.hat.user_id = qdev->secure_user_id;
    struct timespec ts;
    clock_gettime(CLOCK_MONOTONIC, &ts);
    auth_msg.data.authenticated.hat.timestamp =
            htobe64((uint64_t)ts.tv_sec * 1000 + ts.tv_nsec / 1000000);

    //  pthread_mutex_lock(&qdev->lock);
    qdev->device.notify(&acqu_msg);
    qdev->device.notify(&auth_msg);
    //  pthread_mutex_unlock(&qdev->lock);

    return;
}

static void send_enroll_notice(qemu_fingerprint_device_t* qdev, int fid) {
    ALOGD("----------------> %s -----------------> fid %d", __FUNCTION__, fid);

    if (fid == 0) {
        ALOGD("Fingerprint ID is zero (invalid)");
        return;
    }
    if (qdev->secure_user_id == 0) {
        ALOGD("Secure user ID is zero (invalid)");
        return;
    }

    // Find an available entry in the table
    pthread_mutex_lock(&qdev->lock);
    int idx = 0;
    for (idx = 0; idx < MAX_NUM_FINGERS; idx++) {
        if (qdev->listener.secureid[idx] == 0 ||
            qdev->listener.authenid[idx] == 0) {
            // This entry is available
            break;
        }
    }
    if (idx >= MAX_NUM_FINGERS) {
        qdev->listener.state = STATE_SCAN;
        pthread_mutex_unlock(&qdev->lock);
        ALOGD("Fingerprint ID table is full");
        return;
    }

    qdev->listener.secureid[idx] = qdev->secure_user_id;
    qdev->listener.authenid[idx] = fid;
    saveFingerprint(&qdev->listener, idx);

    qdev->listener.state = STATE_SCAN;
    pthread_mutex_unlock(&qdev->lock);

    // LOCKED notification?
    fingerprint_msg_t msg = {0};
    msg.type = FINGERPRINT_TEMPLATE_ENROLLING;
    msg.data.enroll.finger.fid = fid;
    msg.data.enroll.samples_remaining = 0;
    qdev->device.notify(&msg);

    return;
}

static worker_state_t getListenerState(qemu_fingerprint_device_t* dev) {
    ALOGV("----------------> %s ----------------->", __FUNCTION__);
    worker_state_t state = STATE_IDLE;

    pthread_mutex_lock(&dev->lock);
    state = dev->listener.state;
    pthread_mutex_unlock(&dev->lock);

    return state;
}

/**
 * This a very simple event loop for the fingerprint sensor. For a given state (enroll, scan),
 * this would receive events from the sensor and forward them to fingerprintd using the
 * notify() method.
 *
 * In this simple example, we open a qemu channel (a pipe) where the developer can inject events to
 * exercise the API and test application code.
 *
 * The scanner should remain in the scanning state until either an error occurs or the operation
 * completes.
 *
 * Recoverable errors such as EINTR should be handled locally;  they should not
 * be propagated unless there's something the user can do about it (e.g. "clean sensor"). Such
 * messages should go through the onAcquired() interface.
 *
 * If an unrecoverable error occurs, an acquired message (e.g. ACQUIRED_PARTIAL) should be sent,
 * followed by an error message (e.g. FINGERPRINT_ERROR_UNABLE_TO_PROCESS).
 *
 * Note that this event loop would typically run in TEE since it must interact with the sensor
 * hardware and handle raw fingerprint data and encrypted templates.  It is expected that
 * this code monitors the TEE for resulting events, such as enrollment and authentication status.
 * Here we just have a very simple event loop that monitors a qemu channel for pseudo events.
 */
static void* listenerFunction(void* data) {
    ALOGD("----------------> %s ----------------->", __FUNCTION__);
    qemu_fingerprint_device_t* qdev = (qemu_fingerprint_device_t*)data;

    pthread_mutex_lock(&qdev->lock);
    qdev->qchanfd = qemud_channel_open(FINGERPRINT_LISTEN_SERVICE_NAME);
    if (qdev->qchanfd < 0) {
        ALOGE("listener cannot open fingerprint listener service exit");
        pthread_mutex_unlock(&qdev->lock);
        return NULL;
    }
    qdev->listener.state = STATE_IDLE;
    pthread_mutex_unlock(&qdev->lock);

    const char* cmd = "listen";
    if (qemud_channel_send(qdev->qchanfd, cmd, strlen(cmd)) < 0) {
        ALOGE("cannot write fingerprint 'listen' to host");
        goto done_quiet;
    }

    int comm_errors = 0;
    struct pollfd pfd = {
        .fd = qdev->qchanfd,
        .events = POLLIN,
    };
    while (1) {
        int size = 0;
        int fid = 0;
        char buffer[MAX_COMM_CHARS] = {0};
        bool disconnected = false;
        while (1) {
            if (getListenerState(qdev) == STATE_EXIT) {
                ALOGD("Received request to exit listener thread");
                goto done;
            }

            // Reset revents before poll() (just to be safe)
            pfd.revents = 0;

            // Poll qemud channel for 5 seconds
            // TODO: Eliminate the timeout so that polling can be interrupted
            // instantly. One possible solution is to follow the example of
            // android::Looper ($AOSP/system/core/include/utils/Looper.h and
            // $AOSP/system/core/libutils/Looper.cpp), which makes use of an
            // additional file descriptor ("wake event fd").
            int nfds = poll(&pfd, 1, 5000);
            if (nfds < 0) {
                ALOGE("Could not poll qemud channel: %s", strerror(errno));
                goto done;
            }

            if (!nfds) {
                // poll() timed out - try again
                continue;
            }

            // assert(nfds == 1)
            if (pfd.revents & POLLIN) {
                // Input data being available doesn't rule out a disconnection
                disconnected = pfd.revents & (POLLERR | POLLHUP);
                break;  // Exit inner while loop
            } else {
                // Some event(s) other than "input data available" occurred,
                // i.e. POLLERR or POLLHUP, indicating a disconnection
                ALOGW("Lost connection to qemud channel");
                goto done;
            }
        }

        // Shouldn't block since we were just notified of a POLLIN event
        if ((size = qemud_channel_recv(qdev->qchanfd, buffer,
                                       sizeof(buffer) - 1)) > 0) {
            buffer[size] = '\0';
            if (sscanf(buffer, "on:%d", &fid) == 1) {
                if (fid > 0 && fid <= MAX_FID_VALUE) {
                    switch (qdev->listener.state) {
                        case STATE_ENROLL:
                            send_enroll_notice(qdev, fid);
                            break;
                        case STATE_SCAN:
                            send_scan_notice(qdev, fid);
                            break;
                        default:
                            ALOGE("fingerprint event listener at unexpected "
                                  "state 0%x",
                                  qdev->listener.state);
                    }
                } else {
                    ALOGE("fingerprintid %d not in valid range [%d, %d] and "
                          "will be "
                          "ignored",
                          fid, 1, MAX_FID_VALUE);
                    continue;
                }
            } else if (strncmp("off", buffer, 3) == 0) {
                // TODO: Nothing to do here ? Looks valid
                ALOGD("fingerprint ID %d off", fid);
            } else {
                ALOGE("Invalid command '%s' to fingerprint listener", buffer);
            }

            if (disconnected) {
                ALOGW("Connection to qemud channel has been lost");
                break;
            }
        } else {
            ALOGE("fingerprint listener receive failure");
            if (comm_errors > MAX_COMM_ERRORS)
                break;
        }
    }

done:
    ALOGD("Listener exit with %d receive errors", comm_errors);
done_quiet:
    close(qdev->qchanfd);
    return NULL;
}

static int fingerprint_close(hw_device_t* device) {
    ALOGD("----------------> %s ----------------->", __FUNCTION__);
    if (device == NULL) {
        ALOGE("fingerprint hw device is NULL");
        return -1;
    }

    qemu_fingerprint_device_t* qdev = (qemu_fingerprint_device_t*)device;
    pthread_mutex_lock(&qdev->lock);
    // Ask listener thread to exit
    qdev->listener.state = STATE_EXIT;
    pthread_mutex_unlock(&qdev->lock);

    pthread_join(qdev->listener.thread, NULL);
    pthread_mutex_destroy(&qdev->lock);
    free(qdev);

    return 0;
}

static int fingerprint_open(const hw_module_t* module, const char __unused *id,
                            hw_device_t** device)
{

    ALOGD("----------------> %s ----------------->", __FUNCTION__);
    if (device == NULL) {
        ALOGE("NULL device on open");
        return -EINVAL;
    }

    qemu_fingerprint_device_t* qdev = (qemu_fingerprint_device_t*)calloc(
            1, sizeof(qemu_fingerprint_device_t));
    if (qdev == NULL) {
        ALOGE("Insufficient memory for virtual fingerprint device");
        return -ENOMEM;
    }

    loadFingerprints(&qdev->listener);

    qdev->device.common.tag = HARDWARE_DEVICE_TAG;
    qdev->device.common.version = HARDWARE_MODULE_API_VERSION(2, 0);
    qdev->device.common.module = (struct hw_module_t*)module;
    qdev->device.common.close = fingerprint_close;

    qdev->device.pre_enroll = fingerprint_pre_enroll;
    qdev->device.enroll = fingerprint_enroll;
    qdev->device.post_enroll = fingerprint_post_enroll;
    qdev->device.get_authenticator_id = fingerprint_get_auth_id;
    qdev->device.set_active_group = fingerprint_set_active_group;
    qdev->device.authenticate = fingerprint_authenticate;
    qdev->device.cancel = fingerprint_cancel;
    qdev->device.enumerate = fingerprint_enumerate;
    qdev->device.remove = fingerprint_remove;
    qdev->device.set_notify = set_notify_callback;
    qdev->device.notify = NULL;

    // init and create listener thread
    pthread_mutex_init(&qdev->lock, NULL);
    if (pthread_create(&qdev->listener.thread, NULL, listenerFunction, qdev) !=
        0)
        return -1;

    // "Inheritance" / casting
    *device = &qdev->device.common;

    return 0;
}

static struct hw_module_methods_t fingerprint_module_methods = {
    .open = fingerprint_open,
};

fingerprint_module_t HAL_MODULE_INFO_SYM = {
    .common = {
        .tag                = HARDWARE_MODULE_TAG,
        .module_api_version = FINGERPRINT_MODULE_API_VERSION_2_0,
        .hal_api_version    = HARDWARE_HAL_API_VERSION,
        .id                 = FINGERPRINT_HARDWARE_MODULE_ID,
        .name               = "Emulator Fingerprint HAL",
        .author             = "The Android Open Source Project",
        .methods            = &fingerprint_module_methods,
    },
};
