/*
 * 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 <log/log.h>
#include <hardware/hardware.h>
#include <hardware/fingerprint.h>
#include "qemud.h"

#include <poll.h>

#define FINGERPRINT_LISTEN_SERVICE_NAME "fingerprintlisten"
#define FINGERPRINT_FILENAME "emufp.bin"
#define AUTHENTICATOR_ID_FILENAME "emuauthid.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;
    int samples_remaining;
    uint64_t secureid[MAX_NUM_FINGERS];
    uint64_t fingerid[MAX_NUM_FINGERS];
    char fp_filename[PATH_MAX];
    char authid_filename[PATH_MAX];
} 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 FILE* openForWrite(const char* filename);

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

    // Save fingerprints to file
    FILE* fp = openForWrite(listener->fp_filename);
    if (fp == NULL) {
        ALOGE("Could not open fingerprints storage at %s; "
              "fingerprints won't be saved",
              listener->fp_filename);
        perror("Failed to open file");
        return;
    }

    ALOGD("Write fingerprint[%d] (0x%" PRIx64 ",0x%" PRIx64 ")", idx,
          listener->secureid[idx], listener->fingerid[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 nf = fwrite(&listener->fingerid[idx], sizeof(uint64_t), 1, fp);
    if (ns != 1 || ns !=1)
        ALOGW("Corrupt emulator fingerprints storage; could not save "
              "fingerprints");

    fclose(fp);

    return;
}

static FILE* openForWrite(const char* filename) {

    if (!filename) return NULL;

    FILE* fp = fopen(filename, "r+");  // write but don't truncate
    if (fp == NULL) {
        fp = fopen(filename, "w");
        if (fp) {
            uint64_t zero = 0;
            int i = 0;
            for (i = 0; i < 2*MAX_NUM_FINGERS; ++i) {
                fwrite(&zero, sizeof(uint64_t), 1, fp);
            }

            //the last one is for authenticator id
            fwrite(&zero, sizeof(uint64_t), 1, fp);
        }
    }
    return fp;
}

static void saveAuthenticatorId(const char* filename, uint64_t authenid) {
    ALOGD("----------------> %s ----------------->", __FUNCTION__);
    FILE* fp = openForWrite(filename);
    if (!fp) {
        ALOGE("Failed to open emulator storage file to save authenticator id");
        return;
    }

    rewind(fp);

    int na = fwrite(&authenid, sizeof(authenid), 1, fp);
    if (na != 1) {
        ALOGE("Failed while writing authenticator id in emulator storage");
    }

    ALOGD("Save authenticator id (0x%" PRIx64 ")", authenid);

    fclose(fp);
}

static void loadAuthenticatorId(const char* authid_filename, uint64_t* pauthenid) {
    ALOGD("----------------> %s ----------------->", __FUNCTION__);
    FILE* fp = fopen(authid_filename, "r");
    if (fp == NULL) {
        ALOGE("Could not load authenticator id from storage at %s; "
              "it has not yet been created.",
              authid_filename);
        perror("Failed to open/create file");
        return;
    }

    rewind(fp);

    int na = fread(pauthenid, sizeof(*pauthenid), 1, fp);
    if (na != 1)
        ALOGW("Corrupt emulator authenticator id storage (read %d)", na);

    ALOGD("Read authenticator id (0x%" PRIx64 ")", *pauthenid);

    fclose(fp);

    return;
}

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

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

    int i = 0;
    for (i = 0; i < MAX_NUM_FINGERS; i++)
        ALOGD("Read fingerprint %d (0x%" PRIx64 ",0x%" PRIx64 ")", i,
              listener->secureid[i], listener->fingerid[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);

    ALOGD("----------------> %s auth id %" PRIx64 "----------------->", __FUNCTION__, authenticator_id);
    return authenticator_id;
}

static int fingerprint_set_active_group(struct fingerprint_device *device, uint32_t gid,
        const char *path) {
    ALOGD("----------------> %s -----------------> path %s", __FUNCTION__, path);
    qemu_fingerprint_device_t* qdev = (qemu_fingerprint_device_t*)device;
    pthread_mutex_lock(&qdev->lock);
    qdev->group_id = gid;
    snprintf(qdev->listener.fp_filename, sizeof(qdev->listener.fp_filename),
            "%s/%s", path, FINGERPRINT_FILENAME);
    snprintf(qdev->listener.authid_filename, sizeof(qdev->listener.authid_filename),
            "%s/%s", path, AUTHENTICATOR_ID_FILENAME);
    uint64_t authenticator_id = 0;
    loadFingerprints(&qdev->listener);
    loadAuthenticatorId(qdev->listener.authid_filename, &authenticator_id);
    if (authenticator_id == 0) {
        // firs time, create an authenticator id
        authenticator_id = get_64bit_rand();
        // save it to disk
        saveAuthenticatorId(qdev->listener.authid_filename, authenticator_id);
    }

    qdev->authenticator_id = authenticator_id;
    pthread_mutex_unlock(&qdev->lock);

    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) {
    fingerprint_msg_t msg = {0, {0}};
    msg.type = FINGERPRINT_ERROR;
    msg.data.error = FINGERPRINT_ERROR_UNABLE_TO_PROCESS;
    ALOGD("fingerprint_enroll");
    qemu_fingerprint_device_t* dev = (qemu_fingerprint_device_t*)device;
    if (!hat) {
        ALOGW("%s: null auth token", __func__);
        dev->device.notify(&msg);
        return 0;
    }
    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) {
        dev->device.notify(&msg);
        return 0;
    }
    if (hat->challenge != dev->challenge && !(hat->authenticator_type & HW_AUTH_FINGERPRINT)) {
        dev->device.notify(&msg);
        return 0;
    }

    dev->user_id = hat->user_id;

    pthread_mutex_lock(&dev->lock);
    dev->listener.state = STATE_ENROLL;
    dev->listener.samples_remaining = 2;
    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;

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

    fingerprint_msg_t msg = {0, {0}};
    msg.type = FINGERPRINT_ERROR;
    msg.data.error = FINGERPRINT_ERROR_CANCELED;
    qdev->device.notify(&msg);

    return 0;
}

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

    qemu_fingerprint_device_t* qdev = (qemu_fingerprint_device_t*)device;
    int template_count = 0;
    for (int i = 0; i < MAX_NUM_FINGERS; i++) {
        if (qdev->listener.secureid[i] != 0 ||
            qdev->listener.fingerid[i] != 0) {
            ALOGD("ENUM: Fingerprint [%d] = 0x%" PRIx64 ",%" PRIx64, i,
                  qdev->listener.secureid[i], qdev->listener.fingerid[i]);
            template_count++;
        }
    }
    fingerprint_msg_t message = {0, {0}};
    message.type = FINGERPRINT_TEMPLATE_ENUMERATING;
    message.data.enumerated.finger.gid = qdev->group_id;

    if(template_count == 0) {
        message.data.enumerated.remaining_templates = 0;
        message.data.enumerated.finger.fid = 0;
        qdev->device.notify(&message);
    }
    else {
        for (int i = 0; i < MAX_NUM_FINGERS; i++) {
            if (qdev->listener.secureid[i] != 0 ||
                qdev->listener.fingerid[i] != 0) {
                template_count--;
                message.data.enumerated.remaining_templates = template_count;
                message.data.enumerated.finger.fid = qdev->listener.fingerid[i];
                qdev->device.notify(&message);
            }
        }
    }

    return 0;
}

static int fingerprint_remove(struct fingerprint_device *device,
        uint32_t __unused gid, uint32_t fid) {
    int idx = 0;
    fingerprint_msg_t msg = {0, {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 -ENODEV;
    }

    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.fingerid[idx];
                if (theFid != 0) {
                    // Delete this entry
                    qdev->listener.secureid[idx] = 0;
                    qdev->listener.fingerid[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;
                    msg.data.removed.finger.gid = qdev->group_id;
                    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);
        msg.type = FINGERPRINT_TEMPLATE_REMOVED;
        msg.data.removed.finger.fid = 0;
        msg.data.removed.finger.gid = qdev->group_id;
        device->notify(&msg);
    } 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.fingerid[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);
            //msg.type = FINGERPRINT_ERROR;
            //msg.data.error = FINGERPRINT_ERROR_UNABLE_TO_REMOVE;
            //device->notify(&msg);
            msg.type = FINGERPRINT_TEMPLATE_REMOVED;
            msg.data.removed.finger.fid = 0;
            msg.data.removed.finger.gid = qdev->group_id;
            msg.data.removed.remaining_templates = 0;
            device->notify(&msg);
            return 0;
        }

        qdev->listener.secureid[idx] = 0;
        qdev->listener.fingerid[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 bool is_valid_fid(qemu_fingerprint_device_t* qdev, uint64_t fid) {
    int idx = 0;
    if (0 == fid) { return false; }
    for (idx = 0; idx < MAX_NUM_FINGERS; idx++) {
        if (qdev->listener.fingerid[idx] == fid) {
            return true;
        }
    }
    return false;
}

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

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

    // authenticated message
    fingerprint_msg_t auth_msg = {0, {0}};
    auth_msg.type = FINGERPRINT_AUTHENTICATED;
    auth_msg.data.authenticated.finger.fid = is_valid_fid(qdev, fid) ? fid : 0;
    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.fingerid[idx] == 0) {
            // This entry is available
            break;
        }
    }
    if (idx >= MAX_NUM_FINGERS) {
        qdev->listener.state = STATE_IDLE;
        pthread_mutex_unlock(&qdev->lock);
        ALOGD("Fingerprint ID table is full");
        return;
    }
    qdev->listener.samples_remaining--;
    int samples_remaining = qdev->listener.samples_remaining;
    if (samples_remaining <= 0) {
        qdev->listener.secureid[idx] = qdev->secure_user_id;
        qdev->listener.fingerid[idx] = fid;
        saveFingerprint(&qdev->listener, idx);
        qdev->listener.state = STATE_IDLE;
    }
    pthread_mutex_unlock(&qdev->lock);
    // LOCKED notification?
    fingerprint_msg_t msg = {0, {0}};
    msg.type = FINGERPRINT_TEMPLATE_ENROLLING;
    msg.data.enroll.finger.fid = fid;
    msg.data.enroll.samples_remaining = samples_remaining > 0 ? 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;

    int fd = qemud_channel_open(FINGERPRINT_LISTEN_SERVICE_NAME);
    pthread_mutex_lock(&qdev->lock);
    qdev->qchanfd = fd;
    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;
    }


    qdev->device.common.tag = HARDWARE_DEVICE_TAG;
    qdev->device.common.version = HARDWARE_MODULE_API_VERSION(2, 1);
    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_1,
        .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,
    },
};
