void *auth_thread_loop()
{
    ALOGI("%s", __func__);
    fpc_auth_start();

    int status = 1;

    while((status = fpc_capture_image()) >= 0) {
        ALOGD("%s : Got Input", __func__);

        if (status <= FINGERPRINT_ACQUIRED_TOO_FAST) {
            fingerprint_msg_t msg;
            msg.type = FINGERPRINT_ACQUIRED;
            msg.data.acquired.acquired_info = status;
            callback(&msg);
        }

        if (status == FINGERPRINT_ACQUIRED_GOOD) {

            int verify_state = fpc_auth_step();
            ALOGI("%s : Auth step = %d", __func__, verify_state);

            if (verify_state >= 0) {

                uint32_t print_id = fpc_get_print_id(verify_state);
                ALOGI("%s : Got print id : %lu", __func__, (unsigned long) print_id);

                hw_auth_token_t hat;
                fpc_get_hw_auth_obj(&hat, sizeof(hw_auth_token_t));

                ALOGI("%s : hat->challange %lu",__func__,(unsigned long) hat.challenge);
                ALOGI("%s : hat->user_id %lu",__func__,(unsigned long) hat.user_id);
                ALOGI("%s : hat->authenticator_id %lu",__func__,(unsigned long) hat.authenticator_id);
                ALOGI("%s : hat->authenticator_type %d",__func__, hat.authenticator_type);
                ALOGI("%s : hat->timestamp %lu",__func__,(unsigned long) hat.timestamp);
                ALOGI("%s : hat size %lu",__func__,(unsigned long) sizeof(hw_auth_token_t));

                fingerprint_msg_t msg;
                msg.type = FINGERPRINT_AUTHENTICATED;
                msg.data.authenticated.finger.gid = 0;
                msg.data.authenticated.finger.fid = print_id;

                msg.data.authenticated.hat = hat;

                callback(&msg);
                break;
            }
        }

        pthread_mutex_lock(&lock);
        if (!auth_thread_running) {
            pthread_mutex_unlock(&lock);
            break;
        }
        pthread_mutex_unlock(&lock);
    }

    fpc_auth_end();
    ALOGI("%s : finishing",__func__);

    pthread_mutex_lock(&lock);
    auth_thread_running = false;
    pthread_mutex_unlock(&lock);
    return NULL;
}
void *enroll_thread_loop()
{
    ALOGI("%s", __func__);
    fpc_enroll_start(1);

    int status = 1;

    while((status = fpc_capture_image()) >= 0) {
        ALOGD("%s : Got Input", __func__);

        if (status <= FINGERPRINT_ACQUIRED_TOO_FAST) {
            fingerprint_msg_t msg;
            msg.type = FINGERPRINT_ACQUIRED;
            msg.data.acquired.acquired_info = status;
            callback(&msg);
        }

        //image captured
        if (status == FINGERPRINT_ACQUIRED_GOOD) {
            ALOGI("%s : Enroll Step", __func__);
            if (fpc_enroll_step() < 100) {
                int remaining_touches = fpc_get_remaining_touches();
                ALOGI("%s : Touches Remaining : %d", __func__, remaining_touches);
                if (remaining_touches > 0) {
                    fingerprint_msg_t msg;
                    msg.type = FINGERPRINT_TEMPLATE_ENROLLING;
                    msg.data.enroll.finger.fid = 0;
                    msg.data.enroll.finger.gid = 0;
                    msg.data.enroll.samples_remaining = remaining_touches;
                    msg.data.enroll.msg = 0;
                    callback(&msg);
                }
            } else {
                int print_index = fpc_enroll_end();
                ALOGI("%s : Got print index : %d", __func__,print_index);

                uint32_t db_length = fpc_get_user_db_length();
                ALOGI("%s : User Database Length Is : %lu", __func__,(unsigned long) db_length);
                fpc_store_user_db(db_length, db_path);

                uint32_t print_id = fpc_get_print_id(print_index);
                ALOGI("%s : Got print id : %lu", __func__,(unsigned long) print_id);

                fingerprint_msg_t msg;
                msg.type = FINGERPRINT_TEMPLATE_ENROLLING;
                msg.data.enroll.finger.fid = print_id;
                msg.data.enroll.finger.gid = 0;
                msg.data.enroll.samples_remaining = 0;
                msg.data.enroll.msg = 0;
                callback(&msg);
                break;
            }
        }

        pthread_mutex_lock(&lock);
        if (!auth_thread_running) {
            pthread_mutex_unlock(&lock);
            break;
        }
        pthread_mutex_unlock(&lock);
    }

    fpc_enroll_end();
    ALOGI("%s : finishing",__func__);

    pthread_mutex_lock(&lock);
    auth_thread_running = false;
    pthread_mutex_unlock(&lock);
    return NULL;
}
void *enroll_thread_loop()
{
    ALOGI("%s", __func__);

    uint32_t print_count = fpc_get_print_count();
    ALOGD("%s : print count is : %u", __func__, print_count);

    int ret = fpc_enroll_start(print_count);
    if(ret < 0)
    {
        ALOGE("Starting enrol failed: %d\n", ret);
    }

    int status = 1;

    while((status = fpc_capture_image()) >= 0) {
        ALOGD("%s : Got Input status=%d", __func__, status);

        if (status <= FINGERPRINT_ACQUIRED_TOO_FAST) {
            fingerprint_msg_t msg;
            msg.type = FINGERPRINT_ACQUIRED;
            msg.data.acquired.acquired_info = status;
            callback(&msg);
        }

        //image captured
        if (status == FINGERPRINT_ACQUIRED_GOOD) {
            ALOGI("%s : Enroll Step", __func__);
            uint32_t remaining_touches = 0;
            int ret = fpc_enroll_step(&remaining_touches);
            ALOGE("%s: step: %d, touches=%d\n", __func__, ret, remaining_touches);
            if (ret > 0) {
                ALOGI("%s : Touches Remaining : %d", __func__, remaining_touches);
                if (remaining_touches > 0) {
                    fingerprint_msg_t msg;
                    msg.type = FINGERPRINT_TEMPLATE_ENROLLING;
                    msg.data.enroll.finger.fid = 0;
                    msg.data.enroll.finger.gid = 0;
                    msg.data.enroll.samples_remaining = remaining_touches;
                    msg.data.enroll.msg = 0;
                    callback(&msg);
                }
            } else {

                uint32_t print_id = 0;
                int print_index = fpc_enroll_end(&print_id);

                if (print_index < 0){
                    ALOGE("%s : Error getting new print index : %d", __func__,print_index);
                    fingerprint_msg_t msg;
                    msg.type = FINGERPRINT_ERROR;
                    msg.data.error = FINGERPRINT_ERROR_UNABLE_TO_PROCESS;
                    callback(&msg);
                    break;
                }

                uint32_t db_length = fpc_get_user_db_length();
                ALOGI("%s : User Database Length Is : %lu", __func__,(unsigned long) db_length);
                fpc_store_user_db(db_length, db_path);

                ALOGI("%s : Got print id : %lu", __func__,(unsigned long) print_id);

                fingerprint_msg_t msg;
                msg.type = FINGERPRINT_TEMPLATE_ENROLLING;
                msg.data.enroll.finger.fid = print_id;
                msg.data.enroll.finger.gid = fpc_gid;
                msg.data.enroll.samples_remaining = 0;
                msg.data.enroll.msg = 0;
                callback(&msg);
                break;
            }
        }
        pthread_mutex_lock(&lock);
        if (!auth_thread_running) {
            pthread_mutex_unlock(&lock);
            break;
        }
        pthread_mutex_unlock(&lock);
    }

    uint32_t print_id = 0;
    fpc_enroll_end(&print_id);
    ALOGI("%s : finishing",__func__);

    pthread_mutex_lock(&lock);
    auth_thread_running = false;
    pthread_mutex_unlock(&lock);
    return NULL;
}