Compare commits

..

1 Commits

Author SHA1 Message Date
Benjamin Berg
1528c962fa tests: Adjust timeouts to avoid CI failures
The virtual-image test is quite CPU intensive and can take a long time
in the CI setup. Adjust the timeouts so that it runs reliably.
2020-03-27 15:20:08 +00:00
37 changed files with 191 additions and 878 deletions

View File

@@ -57,7 +57,7 @@ test:
script: script:
- meson --werror -Ddrivers=all -Db_coverage=true . _build - meson --werror -Ddrivers=all -Db_coverage=true . _build
- ninja -C _build - ninja -C _build
- meson test -C _build --verbose --no-stdsplit --timeout-multiplier 3 - meson test -C _build --verbose --no-stdsplit
- ninja -C _build coverage - ninja -C _build coverage
- cat _build/meson-logs/coverage.txt - cat _build/meson-logs/coverage.txt
artifacts: artifacts:

View File

@@ -207,8 +207,6 @@ fpi_print_set_type
fpi_print_set_device_stored fpi_print_set_device_stored
fpi_print_add_from_image fpi_print_add_from_image
fpi_print_bz3_match fpi_print_bz3_match
fpi_print_generate_user_id
fpi_print_fill_from_user_id
</SECTION> </SECTION>
<SECTION> <SECTION>

View File

@@ -1,6 +1,6 @@
/* /*
* Example fingerprint enrollment program * Example fingerprint enrollment program
* Enrolls your chosen finger and saves the print to disk * Enrolls your choosen finger and saves the print to disk
* Copyright (C) 2007 Daniel Drake <dsd@gentoo.org> * Copyright (C) 2007 Daniel Drake <dsd@gentoo.org>
* Copyright (C) 2019 Marco Trevisan <marco.trevisan@canonical.com> * Copyright (C) 2019 Marco Trevisan <marco.trevisan@canonical.com>
* *
@@ -23,7 +23,6 @@
#include <stdio.h> #include <stdio.h>
#include <libfprint/fprint.h> #include <libfprint/fprint.h>
#include <glib-unix.h>
#include "storage.h" #include "storage.h"
#include "utilities.h" #include "utilities.h"
@@ -31,8 +30,6 @@
typedef struct _EnrollData typedef struct _EnrollData
{ {
GMainLoop *loop; GMainLoop *loop;
GCancellable *cancellable;
unsigned int sigint_handler;
FpFinger finger; FpFinger finger;
int ret_value; int ret_value;
} EnrollData; } EnrollData;
@@ -40,8 +37,6 @@ typedef struct _EnrollData
static void static void
enroll_data_free (EnrollData *enroll_data) enroll_data_free (EnrollData *enroll_data)
{ {
g_clear_handle_id (&enroll_data->sigint_handler, g_source_remove);
g_clear_object (&enroll_data->cancellable);
g_main_loop_unref (enroll_data->loop); g_main_loop_unref (enroll_data->loop);
g_free (enroll_data); g_free (enroll_data);
} }
@@ -142,22 +137,11 @@ on_device_opened (FpDevice *dev, GAsyncResult *res, void *user_data)
printf ("Scan your finger now.\n"); printf ("Scan your finger now.\n");
print_template = print_create_template (dev, enroll_data->finger); print_template = print_create_template (dev, enroll_data->finger);
fp_device_enroll (dev, print_template, enroll_data->cancellable, fp_device_enroll (dev, print_template, NULL, on_enroll_progress, NULL,
on_enroll_progress, NULL, NULL, NULL, (GAsyncReadyCallback) on_enroll_completed,
(GAsyncReadyCallback) on_enroll_completed,
enroll_data); enroll_data);
} }
static gboolean
sigint_cb (void *user_data)
{
EnrollData *enroll_data = user_data;
g_cancellable_cancel (enroll_data->cancellable);
return G_SOURCE_CONTINUE;
}
int int
main (void) main (void)
{ {
@@ -204,15 +188,8 @@ main (void)
enroll_data->finger = finger; enroll_data->finger = finger;
enroll_data->ret_value = EXIT_FAILURE; enroll_data->ret_value = EXIT_FAILURE;
enroll_data->loop = g_main_loop_new (NULL, FALSE); enroll_data->loop = g_main_loop_new (NULL, FALSE);
enroll_data->cancellable = g_cancellable_new ();
enroll_data->sigint_handler = g_unix_signal_add_full (G_PRIORITY_HIGH,
SIGINT,
sigint_cb,
enroll_data,
NULL);
fp_device_open (dev, enroll_data->cancellable, fp_device_open (dev, NULL, (GAsyncReadyCallback) on_device_opened,
(GAsyncReadyCallback) on_device_opened,
enroll_data); enroll_data);
g_main_loop_run (enroll_data->loop); g_main_loop_run (enroll_data->loop);

View File

@@ -1,53 +0,0 @@
#!/usr/bin/env python3
# This script can be used together with the virtual_imgdev to simulate an
# image based fingerprint reader.
#
# To use, set the FP_VIRTUAL_IMAGE environment variable for both the
# libfprint using program (e.g. fprintd) and this script.
#
# Usually this would work by adding it into the systemd unit file. The
# best way of doing so is to create
# /etc/systemd/system/fprintd.service.d/fprintd-test.conf
#
# [Service]
# RuntimeDirectory=fprint
# Environment=FP_VIRTUAL_DEVICE=/run/fprint/virtdev_sock
# Environment=G_MESSAGES_DEBUG=all
# ReadWritePaths=$RUNTIME_DIR
#
# After that run:
#
# systemctl daemon-reload
# systemctl restart fprintd.service
#
# You may also need to disable selinux.
#
# Then run this script with e.g.
# FP_VIRTUAL_DEVICE=/run/fprint/virtdev_sock ./sendvirtimg.py "ADD <username> <finger> <success|failure>"
import cairo
import sys
import os
import socket
import struct
if len(sys.argv) != 2:
sys.stderr.write('You need to pass commands!\n')
sys.stderr.write('Usage: ./sendvirtimg.py "ADD <finger> <username> <success|failure>"\n')
sys.exit(1)
command = sys.argv[1]
# Send image through socket
sockaddr = os.environ['FP_VIRTUAL_DEVICE']
if not sockaddr:
sockaddr = os.environ['FP_VIRTUAL_DEVICE_IDENT']
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.connect(sockaddr)
sock.sendall(command.encode('utf-8'))

View File

@@ -23,7 +23,6 @@
#include <stdio.h> #include <stdio.h>
#include <libfprint/fprint.h> #include <libfprint/fprint.h>
#include <glib-unix.h>
#include "storage.h" #include "storage.h"
#include "utilities.h" #include "utilities.h"
@@ -31,8 +30,6 @@
typedef struct _VerifyData typedef struct _VerifyData
{ {
GMainLoop *loop; GMainLoop *loop;
GCancellable *cancellable;
unsigned int sigint_handler;
FpFinger finger; FpFinger finger;
int ret_value; int ret_value;
} VerifyData; } VerifyData;
@@ -40,8 +37,6 @@ typedef struct _VerifyData
static void static void
verify_data_free (VerifyData *verify_data) verify_data_free (VerifyData *verify_data)
{ {
g_clear_handle_id (&verify_data->sigint_handler, g_source_remove);
g_clear_object (&verify_data->cancellable);
g_main_loop_unref (verify_data->loop); g_main_loop_unref (verify_data->loop);
g_free (verify_data); g_free (verify_data);
} }
@@ -201,7 +196,7 @@ on_list_completed (FpDevice *dev, GAsyncResult *res, gpointer user_data)
fp_print_get_description (verify_print)); fp_print_get_description (verify_print));
g_print ("Print loaded. Time to verify!\n"); g_print ("Print loaded. Time to verify!\n");
fp_device_verify (dev, verify_print, verify_data->cancellable, fp_device_verify (dev, verify_print, NULL,
on_match_cb, verify_data, NULL, on_match_cb, verify_data, NULL,
(GAsyncReadyCallback) on_verify_completed, (GAsyncReadyCallback) on_verify_completed,
verify_data); verify_data);
@@ -255,7 +250,7 @@ start_verification (FpDevice *dev, VerifyData *verify_data)
} }
g_print ("Print loaded. Time to verify!\n"); g_print ("Print loaded. Time to verify!\n");
fp_device_verify (dev, verify_print, verify_data->cancellable, fp_device_verify (dev, verify_print, NULL,
NULL, NULL, NULL, NULL, NULL, NULL,
(GAsyncReadyCallback) on_verify_completed, (GAsyncReadyCallback) on_verify_completed,
verify_data); verify_data);
@@ -281,16 +276,6 @@ on_device_opened (FpDevice *dev, GAsyncResult *res, void *user_data)
start_verification (dev, verify_data); start_verification (dev, verify_data);
} }
static gboolean
sigint_cb (void *user_data)
{
VerifyData *verify_data = user_data;
g_cancellable_cancel (verify_data->cancellable);
return G_SOURCE_CONTINUE;
}
int int
main (void) main (void)
{ {
@@ -321,14 +306,8 @@ main (void)
verify_data = g_new0 (VerifyData, 1); verify_data = g_new0 (VerifyData, 1);
verify_data->ret_value = EXIT_FAILURE; verify_data->ret_value = EXIT_FAILURE;
verify_data->loop = g_main_loop_new (NULL, FALSE); verify_data->loop = g_main_loop_new (NULL, FALSE);
verify_data->cancellable = g_cancellable_new ();
verify_data->sigint_handler = g_unix_signal_add_full (G_PRIORITY_HIGH, fp_device_open (dev, NULL, (GAsyncReadyCallback) on_device_opened,
SIGINT,
sigint_cb,
verify_data,
NULL);
fp_device_open (dev, verify_data->cancellable,
(GAsyncReadyCallback) on_device_opened,
verify_data); verify_data);
g_main_loop_run (verify_data->loop); g_main_loop_run (verify_data->loop);

View File

@@ -733,7 +733,7 @@ calibrate_run_state (FpiSsm *ssm, FpDevice *dev)
fp_dbg ("calibration failed"); fp_dbg ("calibration failed");
fpi_ssm_mark_failed (ssm, fpi_ssm_mark_failed (ssm,
fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL, fpi_device_error_new_msg (FP_DEVICE_ERROR_GENERAL,
"Calibration failed!")); "Callibration failed!"));
} }
break; break;

View File

@@ -859,15 +859,13 @@ m_capture_state (FpiSsm *ssm, FpDevice *dev)
} }
else else
{ {
FpImage *img;
unsigned int img_size;
/* Remove empty parts 2 times for the 2 frames */ /* Remove empty parts 2 times for the 2 frames */
process_removefpi_end (self); process_removefpi_end (self);
process_removefpi_end (self); process_removefpi_end (self);
img_size = self->fp_height * FE_WIDTH;
if (self->fp_height >= FE_WIDTH) img = fp_image_new (FE_WIDTH, self->fp_height);
{
FpImage *img = fp_image_new (FE_WIDTH, self->fp_height);
unsigned int img_size = self->fp_height * FE_WIDTH;
/* Images received are white on black, so invert it. */ /* Images received are white on black, so invert it. */
/* TODO detect sweep direction */ /* TODO detect sweep direction */
img->flags = FPI_IMAGE_COLORS_INVERTED | FPI_IMAGE_V_FLIPPED; img->flags = FPI_IMAGE_COLORS_INVERTED | FPI_IMAGE_V_FLIPPED;
@@ -876,12 +874,6 @@ m_capture_state (FpiSsm *ssm, FpDevice *dev)
fp_dbg ("Sending the raw fingerprint image (%dx%d)", fp_dbg ("Sending the raw fingerprint image (%dx%d)",
img->width, img->height); img->width, img->height);
fpi_image_device_image_captured (idev, img); fpi_image_device_image_captured (idev, img);
}
else
{
fpi_image_device_retry_scan (idev, FP_DEVICE_RETRY_TOO_SHORT);
}
fpi_image_device_report_finger_status (idev, FALSE); fpi_image_device_report_finger_status (idev, FALSE);
fpi_ssm_mark_completed (ssm); fpi_ssm_mark_completed (ssm);
} }

View File

@@ -316,7 +316,7 @@ typedef struct bmkt_init_resp
*/ */
typedef struct bmkt_enroll_resp typedef struct bmkt_enroll_resp
{ {
int progress; /**< Shows current progress status [0-100] */ int progress; /**< Shows current progress stutus [0-100] */
uint8_t finger_id; /**< User's finger id [1-10] */ uint8_t finger_id; /**< User's finger id [1-10] */
uint8_t user_id[BMKT_MAX_USER_ID_LEN]; /**< User name to be enrolled */ uint8_t user_id[BMKT_MAX_USER_ID_LEN]; /**< User name to be enrolled */
} bmkt_enroll_resp_t; } bmkt_enroll_resp_t;

View File

@@ -35,7 +35,7 @@ static const FpIdEntry id_table[] = {
static void static void
cmd_receive_cb (FpiUsbTransfer *transfer, cmd_recieve_cb (FpiUsbTransfer *transfer,
FpDevice *device, FpDevice *device,
gpointer user_data, gpointer user_data,
GError *error) GError *error)
@@ -234,7 +234,7 @@ synaptics_cmd_run_state (FpiSsm *ssm,
fpi_usb_transfer_submit (transfer, fpi_usb_transfer_submit (transfer,
5000, 5000,
NULL, NULL,
cmd_receive_cb, cmd_recieve_cb,
fpi_ssm_get_data (ssm)); fpi_ssm_get_data (ssm));
break; break;
@@ -321,7 +321,7 @@ synaptics_sensor_cmd (FpiDeviceSynaptics *self,
g_assert (payload || payload_len == 0); g_assert (payload || payload_len == 0);
/* seq_num of 0 means a normal command, -1 means the current commands /* seq_num of 0 means a normal command, -1 means the current commands
* sequence number should not be updated (i.e. second async command which * sequence number should not be udpated (i.e. second async command which
* may only be a cancellation currently). */ * may only be a cancellation currently). */
if (seq_num <= 0) if (seq_num <= 0)
{ {
@@ -515,7 +515,39 @@ list_msg_cb (FpiDeviceSynaptics *self,
g_object_set (print, "fpi-data", data, NULL); g_object_set (print, "fpi-data", data, NULL);
g_object_set (print, "description", get_enroll_templates_resp->templates[n].user_id, NULL); g_object_set (print, "description", get_enroll_templates_resp->templates[n].user_id, NULL);
fpi_print_fill_from_user_id (print, userid); /* The format has 24 bytes at the start and some dashes in the right places */
if (g_str_has_prefix (userid, "FP1-") && strlen (userid) >= 24 &&
userid[12] == '-' && userid[14] == '-' && userid[23] == '-')
{
g_autofree gchar *copy = g_strdup (userid);
g_autoptr(GDate) date = NULL;
gint32 date_ymd;
gint32 finger;
gchar *username;
/* Try to parse information from the string. */
copy[12] = '\0';
date_ymd = g_ascii_strtod (copy + 4, NULL);
if (date_ymd > 0)
date = g_date_new_dmy (date_ymd % 100,
(date_ymd / 100) % 100,
date_ymd / 10000);
else
date = g_date_new ();
fp_print_set_enroll_date (print, date);
copy[14] = '\0';
finger = g_ascii_strtoll (copy + 13, NULL, 16);
fp_print_set_finger (print, finger);
/* We ignore the next chunk, it is just random data.
* Then comes the username; nobody is the default if the metadata
* is unknown */
username = copy + 24;
if (strlen (username) > 0 && g_strcmp0 (username, "nobody") != 0)
fp_print_set_username (print, username);
}
g_ptr_array_add (self->list_result, g_object_ref_sink (print)); g_ptr_array_add (self->list_result, g_object_ref_sink (print));
} }
@@ -603,7 +635,7 @@ verify_msg_cb (FpiDeviceSynaptics *self,
else if (resp->result == BMKT_FP_NO_MATCH) else if (resp->result == BMKT_FP_NO_MATCH)
{ {
fp_info ("Print didn't match"); fp_info ("Print didn't match");
fpi_device_verify_report (device, FPI_MATCH_FAIL, NULL, NULL); fpi_device_verify_report (device, FPI_MATCH_FAIL, NULL, error);
verify_complete_after_finger_removal (self); verify_complete_after_finger_removal (self);
} }
else if (resp->result == BMKT_FP_DATABASE_NO_RECORD_EXISTS) else if (resp->result == BMKT_FP_DATABASE_NO_RECORD_EXISTS)
@@ -698,7 +730,7 @@ enroll_msg_cb (FpiDeviceSynaptics *self,
if (enroll_resp->progress < 100) if (enroll_resp->progress < 100)
done_stages = MIN (done_stages, ENROLL_SAMPLES - 1); done_stages = MIN (done_stages, ENROLL_SAMPLES - 1);
/* Emit a retry error if there has been no discernible /* Emit a retry error if there has been no discernable
* progress. Some firmware revisions report more required * progress. Some firmware revisions report more required
* touches. */ * touches. */
if (self->enroll_stage == done_stages) if (self->enroll_stage == done_stages)
@@ -763,6 +795,8 @@ enroll_msg_cb (FpiDeviceSynaptics *self,
} }
} }
#define TEMPLATE_ID_SIZE 20
static void static void
enroll (FpDevice *device) enroll (FpDevice *device)
{ {
@@ -770,21 +804,52 @@ enroll (FpDevice *device)
FpPrint *print = NULL; FpPrint *print = NULL;
GVariant *data = NULL; GVariant *data = NULL;
GVariant *uid = NULL; GVariant *uid = NULL;
const gchar *username;
guint finger; guint finger;
g_autofree gchar *user_id = NULL; g_autofree gchar *user_id = NULL;
gssize user_id_len; gssize user_id_len;
g_autofree guint8 *payload = NULL; g_autofree guint8 *payload = NULL;
const GDate *date;
gint y, m, d;
gint32 rand_id = 0;
fpi_device_get_enroll_data (device, &print); fpi_device_get_enroll_data (device, &print);
G_DEBUG_HERE (); G_DEBUG_HERE ();
user_id = fpi_print_generate_user_id (print); date = fp_print_get_enroll_date (print);
if (date && g_date_valid (date))
{
y = g_date_get_year (date);
m = g_date_get_month (date);
d = g_date_get_day (date);
}
else
{
y = 0;
m = 0;
d = 0;
}
username = fp_print_get_username (print);
if (!username)
username = "nobody";
if (g_strcmp0 (g_getenv ("FP_DEVICE_EMULATION"), "1") == 0)
rand_id = 0;
else
rand_id = g_random_int ();
user_id = g_strdup_printf ("FP1-%04d%02d%02d-%X-%08X-%s",
y, m, d,
fp_print_get_finger (print),
rand_id,
username);
user_id_len = strlen (user_id); user_id_len = strlen (user_id);
user_id_len = MIN (BMKT_MAX_USER_ID_LEN, user_id_len); user_id_len = MIN (BMKT_MAX_USER_ID_LEN, user_id_len);
/* We currently always use finger 1 from the devices point of view */ /* We currently always use finger 1 from the devices piont of view */
finger = 1; finger = 1;
uid = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, uid = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
@@ -964,7 +1029,7 @@ dev_probe (FpDevice *device)
if (!read_ok) if (!read_ok)
{ {
g_warning ("Transfer in response to version query was too short"); g_warning ("Transfer in response to verison query was too short");
error = fpi_device_error_new (FP_DEVICE_ERROR_PROTO); error = fpi_device_error_new (FP_DEVICE_ERROR_PROTO);
goto err_close; goto err_close;
} }

View File

@@ -1119,6 +1119,7 @@ e_handle_resp02 (FpDevice *dev, unsigned char *data,
else else
{ {
GVariant *fp_data; GVariant *fp_data;
print = fp_print_new (dev);
fpi_device_get_enroll_data (dev, &print); fpi_device_get_enroll_data (dev, &print);

View File

@@ -1,456 +0,0 @@
/*
* Virtual driver for "simple" device debugging
*
* Copyright (C) 2019 Benjamin Berg <bberg@redhat.com>
* Copyright (C) 2020 Bastien Nocera <hadess@hadess.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* This is a virtual driver to debug the non-image based drivers. A small
* python script is provided to connect to it via a socket, allowing
* prints to registered programmatically.
* Using this, it is possible to test libfprint and fprintd.
*/
#define FP_COMPONENT "virtual_device"
#include "fpi-log.h"
#include "../fpi-device.h"
#include <glib/gstdio.h>
#include <gio/gio.h>
#include <gio/gunixsocketaddress.h>
#define MAX_LINE_LEN 1024
enum {
VIRTUAL_DEVICE,
VIRTUAL_DEVICE_IDENT
};
struct _FpDeviceVirtualDevice
{
FpDevice parent;
GSocketListener *listener;
GSocketConnection *connection;
GCancellable *cancellable;
gint socket_fd;
gint client_fd;
guint line[MAX_LINE_LEN];
GHashTable *pending_prints; /* key: finger+username value: gboolean */
};
G_DECLARE_FINAL_TYPE (FpDeviceVirtualDevice, fpi_device_virtual_device, FP, DEVICE_VIRTUAL_DEVICE, FpDevice)
G_DEFINE_TYPE (FpDeviceVirtualDevice, fpi_device_virtual_device, FP_TYPE_DEVICE)
static void start_listen (FpDeviceVirtualDevice *self);
#define ADD_CMD_PREFIX "ADD "
static FpFinger
str_to_finger (const char *str)
{
g_autoptr(GEnumClass) eclass;
GEnumValue *value;
eclass = g_type_class_ref (FP_TYPE_FINGER);
value = g_enum_get_value_by_nick (eclass, str);
if (value == NULL)
return FP_FINGER_UNKNOWN;
return value->value;
}
static const char *
finger_to_str (FpFinger finger)
{
GEnumClass *eclass;
GEnumValue *value;
eclass = g_type_class_ref (FP_TYPE_FINGER);
value = g_enum_get_value (eclass, finger);
g_type_class_unref (eclass);
if (value == NULL)
return NULL;
return value->value_nick;
}
static gboolean
parse_code (const char *str)
{
if (g_strcmp0 (str, "1") == 0 ||
g_strcmp0 (str, "success") == 0 ||
g_strcmp0 (str, "SUCCESS") == 0 ||
g_strcmp0 (str, "FPI_MATCH_SUCCESS") == 0)
return FPI_MATCH_SUCCESS;
return FPI_MATCH_FAIL;
}
static void
handle_command_line (FpDeviceVirtualDevice *self,
const char *line)
{
if (g_str_has_prefix (line, ADD_CMD_PREFIX))
{
g_auto(GStrv) elems;
FpPrint *print;
FpFinger finger;
gboolean success;
g_autofree char *description = NULL;
char *key;
/* Syntax: ADD <finger> <username> <error when used> */
elems = g_strsplit (line + strlen (ADD_CMD_PREFIX), " ", 3);
if (g_strv_length (elems) != 3)
{
g_warning ("Malformed command: %s", line);
return;
}
finger = str_to_finger (elems[0]);
if (finger == FP_FINGER_UNKNOWN)
{
g_warning ("Unknown finger '%s'", elems[0]);
return;
}
print = fp_print_new (FP_DEVICE (self));
fp_print_set_finger (print, finger);
fp_print_set_username (print, elems[1]);
description = g_strdup_printf ("Fingerprint finger '%s' for user '%s'",
elems[0], elems[1]);
fp_print_set_description (print, description);
success = parse_code (elems[2]);
key = g_strdup_printf ("%s-%s", elems[0], elems[1]);
g_hash_table_insert (self->pending_prints,
key, GINT_TO_POINTER (success));
fp_dbg ("Added pending print %s for user %s (code: %s)",
elems[0], elems[1], success ? "FPI_MATCH_SUCCESS" : "FPI_MATCH_FAIL");
}
else
{
g_warning ("Unhandled command sent: '%s'", line);
}
}
static void
recv_instruction_cb (GObject *source_object,
GAsyncResult *res,
gpointer user_data)
{
g_autoptr(GError) error = NULL;
FpDeviceVirtualDevice *self;
gboolean success;
gsize bytes;
success = g_input_stream_read_all_finish (G_INPUT_STREAM (source_object), res, &bytes, &error);
if (!success || bytes == 0)
{
if (!success)
{
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) ||
g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CLOSED))
return;
g_warning ("Error receiving instruction data: %s", error->message);
}
self = FP_DEVICE_VIRTUAL_DEVICE (user_data);
goto out;
}
self = FP_DEVICE_VIRTUAL_DEVICE (user_data);
handle_command_line (self, (const char *) self->line);
out:
g_io_stream_close (G_IO_STREAM (self->connection), NULL, NULL);
g_clear_object (&self->connection);
start_listen (self);
}
static void
recv_instruction (FpDeviceVirtualDevice *self,
GInputStream *stream)
{
memset (&self->line, 0, sizeof (self->line));
g_input_stream_read_all_async (stream,
self->line,
sizeof (self->line),
G_PRIORITY_DEFAULT,
self->cancellable,
recv_instruction_cb,
self);
}
static void
new_connection_cb (GObject *source_object,
GAsyncResult *res,
gpointer user_data)
{
g_autoptr(GError) error = NULL;
g_autoptr(GSocketConnection) connection = NULL;
GInputStream *stream;
FpDeviceVirtualDevice *self = user_data;
connection = g_socket_listener_accept_finish (G_SOCKET_LISTENER (source_object),
res,
NULL,
&error);
if (!connection)
{
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
return;
g_warning ("Error accepting a new connection: %s", error->message);
start_listen (self);
return;
}
/* Always further connections (but we disconnect them immediately
* if we already have a connection). */
if (self->connection)
{
g_io_stream_close (G_IO_STREAM (connection), NULL, NULL);
start_listen (self);
return;
}
self->connection = g_steal_pointer (&connection);
stream = g_io_stream_get_input_stream (G_IO_STREAM (connection));
recv_instruction (self, stream);
fp_dbg ("Got a new connection!");
}
static void
start_listen (FpDeviceVirtualDevice *self)
{
fp_dbg ("Starting a new listener");
g_socket_listener_accept_async (self->listener,
self->cancellable,
new_connection_cb,
self);
}
static void
dev_init (FpDevice *dev)
{
fpi_device_open_complete (dev, NULL);
}
static void
dev_verify (FpDevice *dev)
{
FpPrint *print;
g_autoptr(GVariant) data = NULL;
gboolean success;
fpi_device_get_verify_data (dev, &print);
g_object_get (print, "fpi-data", &data, NULL);
success = g_variant_get_boolean (data);
fpi_device_verify_report (dev,
success ? FPI_MATCH_SUCCESS : FPI_MATCH_FAIL,
NULL, NULL);
fpi_device_verify_complete (dev, NULL);
}
static void
dev_enroll (FpDevice *dev)
{
FpDeviceVirtualDevice *self = FP_DEVICE_VIRTUAL_DEVICE (dev);
gpointer success_ptr;
FpPrint *print = NULL;
g_autofree char *key = NULL;
fpi_device_get_enroll_data (dev, &print);
key = g_strdup_printf ("%s-%s",
finger_to_str (fp_print_get_finger (print)),
fp_print_get_username (print));
if (g_hash_table_lookup_extended (self->pending_prints, key, NULL, &success_ptr))
{
gboolean success = GPOINTER_TO_INT (success_ptr);
GVariant *fp_data;
fp_data = g_variant_new_boolean (success);
fpi_print_set_type (print, FPI_PRINT_RAW);
if (fpi_device_get_driver_data (dev) == VIRTUAL_DEVICE_IDENT)
fpi_print_set_device_stored (print, TRUE);
g_object_set (print, "fpi-data", fp_data, NULL);
fpi_device_enroll_complete (dev, g_object_ref (print), NULL);
}
else
{
fpi_device_enroll_complete (dev, NULL,
fpi_device_error_new_msg (FP_DEVICE_ERROR_PROTO,
"No pending result for this username/finger combination"));
}
}
static void
dev_deinit (FpDevice *dev)
{
fpi_device_close_complete (dev, NULL);
}
static gboolean
dev_supports_identify (FpDevice *dev)
{
return fpi_device_get_driver_data (dev) == VIRTUAL_DEVICE_IDENT;
}
static void
dev_identify (FpDevice *dev)
{
GPtrArray *templates;
FpPrint *result = NULL;
guint i;
g_assert (fpi_device_get_driver_data (dev) == VIRTUAL_DEVICE_IDENT);
fpi_device_get_identify_data (dev, &templates);
for (i = 0; i < templates->len; i++)
{
FpPrint *template = g_ptr_array_index (templates, i);
g_autoptr(GVariant) data = NULL;
gboolean success;
g_object_get (dev, "fpi-data", &template, NULL);
success = g_variant_get_boolean (data);
if (success)
{
result = template;
break;
}
}
if (result)
fpi_device_identify_report (dev, result, NULL, NULL);
fpi_device_identify_complete (dev, NULL);
}
static void
fpi_device_virtual_device_finalize (GObject *object)
{
FpDeviceVirtualDevice *self = FP_DEVICE_VIRTUAL_DEVICE (object);
G_DEBUG_HERE ();
g_cancellable_cancel (self->cancellable);
g_clear_object (&self->cancellable);
g_clear_object (&self->listener);
g_clear_object (&self->connection);
g_hash_table_destroy (self->pending_prints);
}
static void
fpi_device_virtual_device_constructed (GObject *object)
{
g_autoptr(GError) error = NULL;
g_autoptr(GSocketListener) listener = NULL;
FpDeviceVirtualDevice *self = FP_DEVICE_VIRTUAL_DEVICE (object);
const char *env;
g_autoptr(GSocketAddress) addr = NULL;
G_DEBUG_HERE ();
self->client_fd = -1;
env = fpi_device_get_virtual_env (FP_DEVICE (self));
listener = g_socket_listener_new ();
g_socket_listener_set_backlog (listener, 1);
/* Remove any left over socket. */
g_unlink (env);
addr = g_unix_socket_address_new (env);
if (!g_socket_listener_add_address (listener,
addr,
G_SOCKET_TYPE_STREAM,
G_SOCKET_PROTOCOL_DEFAULT,
NULL,
NULL,
&error))
{
g_warning ("Could not listen on unix socket: %s", error->message);
fpi_device_open_complete (FP_DEVICE (self), g_steal_pointer (&error));
return;
}
self->listener = g_steal_pointer (&listener);
self->cancellable = g_cancellable_new ();
self->pending_prints = g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
NULL);
if (G_OBJECT_CLASS (fpi_device_virtual_device_parent_class)->constructed)
G_OBJECT_CLASS (fpi_device_virtual_device_parent_class)->constructed (object);
start_listen (self);
}
static void
fpi_device_virtual_device_init (FpDeviceVirtualDevice *self)
{
}
static const FpIdEntry driver_ids[] = {
{ .virtual_envvar = "FP_VIRTUAL_DEVICE", .driver_data = VIRTUAL_DEVICE },
{ .virtual_envvar = "FP_VIRTUAL_DEVICE_IDENT", .driver_data = VIRTUAL_DEVICE_IDENT },
{ .virtual_envvar = NULL }
};
static void
fpi_device_virtual_device_class_init (FpDeviceVirtualDeviceClass *klass)
{
FpDeviceClass *dev_class = FP_DEVICE_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->constructed = fpi_device_virtual_device_constructed;
object_class->finalize = fpi_device_virtual_device_finalize;
dev_class->id = FP_COMPONENT;
dev_class->full_name = "Virtual device for debugging";
dev_class->type = FP_DEVICE_TYPE_VIRTUAL;
dev_class->id_table = driver_ids;
dev_class->nr_enroll_stages = 5;
dev_class->open = dev_init;
dev_class->close = dev_deinit;
dev_class->verify = dev_verify;
dev_class->enroll = dev_enroll;
dev_class->identify = dev_identify;
dev_class->supports_identify = dev_supports_identify;
}

View File

@@ -21,7 +21,7 @@
/* /*
* This is a virtual driver to debug the image based drivers. A small * This is a virtual driver to debug the image based drivers. A small
* python script is provided to connect to it via a socket, allowing * python script is provided to connect to it via a socket, allowing
* prints to be sent to this device programmatically. * prints to be sent to this device programatically.
* Using this it is possible to test libfprint and fprintd. * Using this it is possible to test libfprint and fprintd.
*/ */
@@ -215,7 +215,6 @@ new_connection_cb (GObject *source_object, GAsyncResult *res, gpointer user_data
g_warning ("Error accepting a new connection: %s", error->message); g_warning ("Error accepting a new connection: %s", error->message);
start_listen (dev); start_listen (dev);
return;
} }
/* Always further connections (but we disconnect them immediately /* Always further connections (but we disconnect them immediately
@@ -278,7 +277,7 @@ dev_init (FpImageDevice *dev)
{ {
g_warning ("Could not listen on unix socket: %s", error->message); g_warning ("Could not listen on unix socket: %s", error->message);
fpi_image_device_open_complete (dev, g_steal_pointer (&error)); fpi_image_device_open_complete (FP_IMAGE_DEVICE (dev), g_steal_pointer (&error));
return; return;
} }

View File

@@ -94,21 +94,22 @@ async_device_init_done_cb (GObject *source_object, GAsyncResult *res, gpointer u
FpContext *context; FpContext *context;
FpContextPrivate *priv; FpContextPrivate *priv;
device = FP_DEVICE (g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), device = (FpDevice *) g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, &error);
res, &error)); if (!device)
{
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
return; return;
context = FP_CONTEXT (user_data); context = FP_CONTEXT (user_data);
priv = fp_context_get_instance_private (context); priv = fp_context_get_instance_private (context);
priv->pending_devices--; priv->pending_devices--;
if (error)
{
g_message ("Ignoring device due to initialization error: %s", error->message); g_message ("Ignoring device due to initialization error: %s", error->message);
return; return;
} }
context = FP_CONTEXT (user_data);
priv = fp_context_get_instance_private (context);
priv->pending_devices--;
g_ptr_array_add (priv->devices, device); g_ptr_array_add (priv->devices, device);
g_signal_emit (context, signals[DEVICE_ADDED_SIGNAL], 0, device); g_signal_emit (context, signals[DEVICE_ADDED_SIGNAL], 0, device);
} }
@@ -158,7 +159,7 @@ usb_device_added_cb (FpContext *self, GUsbDevice *device, GUsbContext *usb_ctx)
if (found_driver == G_TYPE_NONE) if (found_driver == G_TYPE_NONE)
{ {
g_debug ("No driver found for USB device %04X:%04X", vid, pid); g_debug ("No driver found for USB device %04X:%04X", pid, vid);
return; return;
} }

View File

@@ -28,7 +28,7 @@
* @title: Internal FpDevice * @title: Internal FpDevice
* @short_description: Internal device routines * @short_description: Internal device routines
* *
* The methods that are available for drivers to manipulate a device. See * The methods that are availabe for drivers to manipulate a device. See
* #FpDeviceClass for more information. Also note that most of these are * #FpDeviceClass for more information. Also note that most of these are
* not relevant for image based devices, see #FpImageDeviceClass in that * not relevant for image based devices, see #FpImageDeviceClass in that
* case. * case.
@@ -339,7 +339,7 @@ fp_device_class_init (FpDeviceClass *klass)
properties[PROP_OPEN] = properties[PROP_OPEN] =
g_param_spec_boolean ("open", g_param_spec_boolean ("open",
"Opened", "Opened",
"Whether the device is open or not", FALSE, "Wether the device is open or not", FALSE,
G_PARAM_STATIC_STRINGS | G_PARAM_READABLE); G_PARAM_STATIC_STRINGS | G_PARAM_READABLE);
/** /**
@@ -507,9 +507,6 @@ fp_device_supports_identify (FpDevice *device)
g_return_val_if_fail (FP_IS_DEVICE (device), FALSE); g_return_val_if_fail (FP_IS_DEVICE (device), FALSE);
if (cls->supports_identify != NULL)
return cls->supports_identify (device);
return cls->identify != NULL; return cls->identify != NULL;
} }
@@ -949,13 +946,6 @@ fp_device_identify (FpDevice *device,
if (g_task_return_error_if_cancelled (task)) if (g_task_return_error_if_cancelled (task))
return; return;
if (!fp_device_supports_identify (device))
{
g_task_return_error (task,
fpi_device_error_new (FP_DEVICE_ERROR_NOT_SUPPORTED));
return;
}
if (!priv->is_open) if (!priv->is_open)
{ {
g_task_return_error (task, g_task_return_error (task,

View File

@@ -79,7 +79,7 @@ typedef enum {
/** /**
* FpDeviceError: * FpDeviceError:
* @FP_DEVICE_ERROR_GENERAL: A general error occurred. * @FP_DEVICE_ERROR_GENERAL: A general error occured.
* @FP_DEVICE_ERROR_NOT_SUPPORTED: The device does not support the requested * @FP_DEVICE_ERROR_NOT_SUPPORTED: The device does not support the requested
* operation. * operation.
* @FP_DEVICE_ERROR_NOT_OPEN: The device needs to be opened to start this * @FP_DEVICE_ERROR_NOT_OPEN: The device needs to be opened to start this
@@ -113,7 +113,7 @@ GQuark fp_device_error_quark (void);
* FpEnrollProgress: * FpEnrollProgress:
* @device: a #FpDevice * @device: a #FpDevice
* @completed_stages: Number of completed stages * @completed_stages: Number of completed stages
* @print: (nullable) (transfer none): The last scanned print * @print: (nullable) (transfer none): The last scaned print
* @user_data: (nullable) (transfer none): User provided data * @user_data: (nullable) (transfer none): User provided data
* @error: (nullable) (transfer none): #GError or %NULL * @error: (nullable) (transfer none): #GError or %NULL
* *

View File

@@ -100,7 +100,7 @@ fp_image_device_close (FpDevice *device)
* 1. We are inactive * 1. We are inactive
* -> immediately close * -> immediately close
* 2. We are waiting for finger off * 2. We are waiting for finger off
* -> immediately deactivate * -> imediately deactivate
* 3. We are deactivating * 3. We are deactivating
* -> handled by deactivate_complete */ * -> handled by deactivate_complete */

View File

@@ -184,8 +184,10 @@ fp_image_detect_minutiae_cb (GObject *source_object,
GTask *task = G_TASK (res); GTask *task = G_TASK (res);
FpImage *image; FpImage *image;
DetectMinutiaeData *data = g_task_get_task_data (task); DetectMinutiaeData *data = g_task_get_task_data (task);
GCancellable *cancellable;
if (!g_task_had_error (task)) cancellable = g_task_get_cancellable (task);
if (!cancellable || !g_cancellable_is_cancelled (cancellable))
{ {
gint i; gint i;
image = FP_IMAGE (source_object); image = FP_IMAGE (source_object);
@@ -314,14 +316,6 @@ fp_image_detect_minutiae_thread_func (GTask *task,
return; return;
} }
if (!data->minutiae || data->minutiae->num == 0)
{
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED,
"No minutiae found");
g_object_unref (task);
return;
}
g_task_return_boolean (task, TRUE); g_task_return_boolean (task, TRUE);
g_object_unref (task); g_object_unref (task);
} }

View File

@@ -51,7 +51,7 @@ enum {
PROP_IMAGE, PROP_IMAGE,
/* The following is metadata that is stored by default for each print. /* The following is metadata that is stored by default for each print.
* Drivers may make use of these during enrollment (e.g. to additionally store * Drivers may make use of these during enrollment (e.g. to additionaly store
* the metadata on the device). */ * the metadata on the device). */
PROP_FINGER, PROP_FINGER,
PROP_USERNAME, PROP_USERNAME,
@@ -588,7 +588,7 @@ fp_print_equal (FpPrint *self, FpPrint *other)
} }
else if (self->type == FPI_PRINT_NBIS) else if (self->type == FPI_PRINT_NBIS)
{ {
guint i; gint i;
if (self->prints->len != other->prints->len) if (self->prints->len != other->prints->len)
return FALSE; return FALSE;
@@ -661,7 +661,7 @@ fp_print_serialize (FpPrint *print,
if (print->type == FPI_PRINT_NBIS) if (print->type == FPI_PRINT_NBIS)
{ {
GVariantBuilder nested = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE ("(a(aiaiai))")); GVariantBuilder nested = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE ("(a(aiaiai))"));
guint i; gint i;
g_variant_builder_open (&nested, G_VARIANT_TYPE ("a(aiaiai)")); g_variant_builder_open (&nested, G_VARIANT_TYPE ("a(aiaiai)"));
for (i = 0; i < print->prints->len; i++) for (i = 0; i < print->prints->len; i++)
@@ -812,7 +812,7 @@ fp_print_deserialize (const guchar *data,
if (type == FPI_PRINT_NBIS) if (type == FPI_PRINT_NBIS)
{ {
g_autoptr(GVariant) prints = g_variant_get_child_value (print_data, 0); g_autoptr(GVariant) prints = g_variant_get_child_value (print_data, 0);
guint i; gint i;
result = g_object_new (FP_TYPE_PRINT, result = g_object_new (FP_TYPE_PRINT,
"driver", driver, "driver", driver,

View File

@@ -28,7 +28,7 @@
* @title: Internal FpDevice * @title: Internal FpDevice
* @short_description: Internal device routines * @short_description: Internal device routines
* *
* The methods that are available for drivers to manipulate a device. See * The methods that are availabe for drivers to manipulate a device. See
* #FpDeviceClass for more information. Also note that most of these are * #FpDeviceClass for more information. Also note that most of these are
* not relevant for image based devices, see #FpImageDeviceClass in that * not relevant for image based devices, see #FpImageDeviceClass in that
* case. * case.
@@ -100,7 +100,7 @@ fpi_device_error_new (FpDeviceError error)
switch (error) switch (error)
{ {
case FP_DEVICE_ERROR_GENERAL: case FP_DEVICE_ERROR_GENERAL:
msg = "An unspecified error occurred!"; msg = "An unspecified error occured!";
break; break;
case FP_DEVICE_ERROR_NOT_SUPPORTED: case FP_DEVICE_ERROR_NOT_SUPPORTED:
@@ -138,7 +138,7 @@ fpi_device_error_new (FpDeviceError error)
default: default:
g_warning ("Unsupported error, returning general error instead!"); g_warning ("Unsupported error, returning general error instead!");
error = FP_DEVICE_ERROR_GENERAL; error = FP_DEVICE_ERROR_GENERAL;
msg = "An unspecified error occurred!"; msg = "An unspecified error occured!";
} }
return g_error_new_literal (FP_DEVICE_ERROR, error, msg); return g_error_new_literal (FP_DEVICE_ERROR, error, msg);

View File

@@ -65,10 +65,10 @@ struct _FpIdEntry
* @probe: Called immediately for all devices. Most drivers will not need to * @probe: Called immediately for all devices. Most drivers will not need to
* implement this. Drivers should setup the device identifier from the probe * implement this. Drivers should setup the device identifier from the probe
* callback which will be used to verify the compatibility of stored * callback which will be used to verify the compatibility of stored
* #FpPrint's. It is permissible to temporarily open the USB device if this * #FpPrint's. It is permissable to temporarily open the USB device if this
* is required for the operation. If an error is returned, then the device * is required for the operation. If an error is returned, then the device
* will be destroyed again immediately and never reported to the API user. * will be destroyed again immediately and never reported to the API user.
* @open: Open the device for further operations. Any of the normal actions are * @open: Open the device for futher operations. Any of the normal actions are
* guaranteed to only happen when the device is open (this includes delete). * guaranteed to only happen when the device is open (this includes delete).
* @close: Close the device again * @close: Close the device again
* @enroll: Start an enroll operation * @enroll: Start an enroll operation
@@ -79,7 +79,6 @@ struct _FpIdEntry
* @delete: Delete a print from the device * @delete: Delete a print from the device
* @cancel: Called on cancellation, this is a convenience to not need to handle * @cancel: Called on cancellation, this is a convenience to not need to handle
* the #GCancellable directly by using fpi_device_get_cancellable(). * the #GCancellable directly by using fpi_device_get_cancellable().
* @supports_identify: Whether identify operations are supported.
* *
* NOTE: If your driver is image based, then you should subclass #FpImageDevice * NOTE: If your driver is image based, then you should subclass #FpImageDevice
* instead. #FpImageDevice based drivers use a different way of interacting * instead. #FpImageDevice based drivers use a different way of interacting
@@ -130,8 +129,6 @@ struct _FpDeviceClass
void (*delete) (FpDevice * device); void (*delete) (FpDevice * device);
void (*cancel) (FpDevice *device); void (*cancel) (FpDevice *device);
gboolean (*supports_identify) (FpDevice *device);
}; };
/** /**

View File

@@ -171,16 +171,7 @@ fpi_image_device_minutiae_detected (GObject *source_object, GAsyncResult *res, g
print = fp_print_new (device); print = fp_print_new (device);
fpi_print_set_type (print, FPI_PRINT_NBIS); fpi_print_set_type (print, FPI_PRINT_NBIS);
if (!fpi_print_add_from_image (print, image, &error)) if (!fpi_print_add_from_image (print, image, &error))
{
g_clear_object (&print); g_clear_object (&print);
if (error->domain != FP_DEVICE_RETRY)
{
fpi_device_action_error (device, error);
fpi_image_device_deactivate (self);
return;
}
}
} }
if (action == FPI_DEVICE_ACTION_ENROLL) if (action == FPI_DEVICE_ACTION_ENROLL)

View File

@@ -23,7 +23,6 @@
#include "fp-print-private.h" #include "fp-print-private.h"
#include "fpi-device.h" #include "fpi-device.h"
#include "fpi-compat.h"
/** /**
* SECTION: fpi-print * SECTION: fpi-print
@@ -248,115 +247,3 @@ fpi_print_bz3_match (FpPrint *template, FpPrint *print, gint bz3_threshold, GErr
return FPI_MATCH_FAIL; return FPI_MATCH_FAIL;
} }
/**
* fpi_print_generate_user_id:
* @print: #FpPrint to generate the ID for
*
* Generates a string identifier for the represented print. This identifier
* encodes some metadata about the print. It also includes a random string
* and may be assumed to be unique.
*
* This is useful if devices are able to store a string identifier, but more
* storing more metadata may be desirable. In effect, this means the driver
* can provide somewhat more meaningful data to fp_device_list_prints().
*
* The generated ID may be truncated after 23 characters. However, more space
* is required to include the username, and it is recommended to store at
* at least 31 bytes.
*
* The generated format may change in the future. It is versioned though and
* decoding should remain functional.
*
* Returns: A unique string of 23 + strlen(username) characters
*/
gchar *
fpi_print_generate_user_id (FpPrint *print)
{
const gchar *username = NULL;
gchar *user_id = NULL;
const GDate *date;
gint y = 0, m = 0, d = 0;
gint32 rand_id = 0;
g_assert (print);
date = fp_print_get_enroll_date (print);
if (date && g_date_valid (date))
{
y = g_date_get_year (date);
m = g_date_get_month (date);
d = g_date_get_day (date);
}
username = fp_print_get_username (print);
if (!username)
username = "nobody";
if (g_strcmp0 (g_getenv ("FP_DEVICE_EMULATION"), "1") == 0)
rand_id = 0;
else
rand_id = g_random_int ();
user_id = g_strdup_printf ("FP1-%04d%02d%02d-%X-%08X-%s",
y, m, d,
fp_print_get_finger (print),
rand_id,
username);
return user_id;
}
/**
* fpi_print_fill_from_user_id:
* @print: #FpPrint to fill metadata into
* @user_id: An ID that was likely encoded using fpi_print_generate_user_id()
*
* This is the reverse operation of fpi_print_generate_user_id(), allowing
* the driver to encode some print metadata in a string.
*
* Returns: Whether a valid ID was found
*/
gboolean
fpi_print_fill_from_user_id (FpPrint *print, const char *user_id)
{
g_return_val_if_fail (user_id, FALSE);
/* The format has 24 bytes at the start and some dashes in the right places */
if (g_str_has_prefix (user_id, "FP1-") && strlen (user_id) >= 24 &&
user_id[12] == '-' && user_id[14] == '-' && user_id[23] == '-')
{
g_autofree gchar *copy = g_strdup (user_id);
g_autoptr(GDate) date = NULL;
gint32 date_ymd;
gint32 finger;
gchar *username;
/* Try to parse information from the string. */
copy[12] = '\0';
date_ymd = g_ascii_strtod (copy + 4, NULL);
if (date_ymd > 0)
date = g_date_new_dmy (date_ymd % 100,
(date_ymd / 100) % 100,
date_ymd / 10000);
else
date = g_date_new ();
fp_print_set_enroll_date (print, date);
copy[14] = '\0';
finger = g_ascii_strtoll (copy + 13, NULL, 16);
fp_print_set_finger (print, finger);
/* We ignore the next chunk, it is just random data.
* Then comes the username; nobody is the default if the metadata
* is unknown */
username = copy + 24;
if (strlen (username) > 0 && g_strcmp0 (username, "nobody") != 0)
fp_print_set_username (print, username);
return TRUE;
}
return FALSE;
}

View File

@@ -20,7 +20,7 @@ typedef enum {
/** /**
* FpiMatchResult: * FpiMatchResult:
* @FPI_MATCH_ERROR: An error occurred during matching * @FPI_MATCH_ERROR: An error occured during matching
* @FPI_MATCH_FAIL: The prints did not match * @FPI_MATCH_FAIL: The prints did not match
* @FPI_MATCH_SUCCESS: The prints matched * @FPI_MATCH_SUCCESS: The prints matched
*/ */
@@ -47,9 +47,4 @@ FpiMatchResult fpi_print_bz3_match (FpPrint * template,
gint bz3_threshold, gint bz3_threshold,
GError **error); GError **error);
/* Helpers to encode metadata into user ID strings. */
gchar * fpi_print_generate_user_id (FpPrint *print);
gboolean fpi_print_fill_from_user_id (FpPrint *print,
const char *user_id);
G_END_DECLS G_END_DECLS

View File

@@ -366,7 +366,7 @@ transfer_finish_cb (GObject *source_object, GAsyncResult *res, gpointer user_dat
* *
* Note that #FpiUsbTransfer will be stolen when this function is called. * Note that #FpiUsbTransfer will be stolen when this function is called.
* So that all associated data will be free'ed automatically, after the * So that all associated data will be free'ed automatically, after the
* callback ran unless fpi_usb_transfer_ref() is explicitly called. * callback ran unless fpi_usb_transfer_ref() is explictly called.
*/ */
void void
fpi_usb_transfer_submit (FpiUsbTransfer *transfer, fpi_usb_transfer_submit (FpiUsbTransfer *transfer,

View File

@@ -61,7 +61,7 @@ typedef enum {
* @length: The requested length of the transfer in bytes. * @length: The requested length of the transfer in bytes.
* @actual_length: The actual length of the transfer * @actual_length: The actual length of the transfer
* (see also fpi_usb_transfer_set_short_error()) * (see also fpi_usb_transfer_set_short_error())
* @buffer: The transferred data. * @buffer: The transfered data.
* *
* Helper for handling USB transfers. * Helper for handling USB transfers.
*/ */

View File

@@ -2,7 +2,7 @@
* Copyright (C) 2009 Red Hat <mjg@redhat.com> * Copyright (C) 2009 Red Hat <mjg@redhat.com>
* Copyright (C) 2008 Bastien Nocera <hadess@hadess.net> * Copyright (C) 2008 Bastien Nocera <hadess@hadess.net>
* Copyright (C) 2008 Timo Hoenig <thoenig@suse.de>, <thoenig@nouse.net> * Copyright (C) 2008 Timo Hoenig <thoenig@suse.de>, <thoenig@nouse.net>
* Copyright (C) 2019 Benjamin Berg <bberg@redhat.com> * Coypright (C) 2019 Benjamin Berg <bberg@redhat.com>
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public

View File

@@ -2,7 +2,7 @@
* Copyright (C) 2009 Red Hat <mjg@redhat.com> * Copyright (C) 2009 Red Hat <mjg@redhat.com>
* Copyright (C) 2008 Bastien Nocera <hadess@hadess.net> * Copyright (C) 2008 Bastien Nocera <hadess@hadess.net>
* Copyright (C) 2008 Timo Hoenig <thoenig@suse.de>, <thoenig@nouse.net> * Copyright (C) 2008 Timo Hoenig <thoenig@suse.de>, <thoenig@nouse.net>
* Copyright (C) 2019 Benjamin Berg <bberg@redhat.com> * Coypright (C) 2019 Benjamin Berg <bberg@redhat.com>
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public

View File

@@ -155,9 +155,6 @@ foreach driver: drivers
if driver == 'virtual_image' if driver == 'virtual_image'
drivers_sources += [ 'drivers/virtual-image.c' ] drivers_sources += [ 'drivers/virtual-image.c' ]
endif endif
if driver == 'virtual_device'
drivers_sources += [ 'drivers/virtual-device.c' ]
endif
if driver == 'synaptics' if driver == 'synaptics'
drivers_sources += [ drivers_sources += [
'drivers/synaptics/synaptics.c', 'drivers/synaptics/synaptics.c',

View File

@@ -88,7 +88,7 @@ cairo_dep = dependency('cairo', required: false)
# Drivers # Drivers
drivers = get_option('drivers').split(',') drivers = get_option('drivers').split(',')
virtual_drivers = [ 'virtual_image', 'virtual_device' ] virtual_drivers = [ 'virtual_image' ]
default_drivers = [ default_drivers = [
'upektc_img', 'upektc_img',
'vfs5011', 'vfs5011',

File diff suppressed because one or more lines are too long

View File

@@ -30,6 +30,7 @@ if get_option('introspection')
unittest_inspector = find_program('unittest_inspector.py') unittest_inspector = find_program('unittest_inspector.py')
base_args = files('virtual-image.py') base_args = files('virtual-image.py')
suite = [] suite = []
timeout = 30
r = run_command(unittest_inspector, files('virtual-image.py')) r = run_command(unittest_inspector, files('virtual-image.py'))
unit_tests = r.stdout().strip().split('\n') unit_tests = r.stdout().strip().split('\n')
@@ -38,6 +39,7 @@ if get_option('introspection')
suite += 'virtual-image' suite += 'virtual-image'
else else
unit_tests = ['virtual-image'] unit_tests = ['virtual-image']
timeout = 120
endif endif
foreach ut: unit_tests foreach ut: unit_tests
@@ -53,6 +55,7 @@ if get_option('introspection')
suite: ut_suite, suite: ut_suite,
depends: libfprint_typelib, depends: libfprint_typelib,
env: envs, env: envs,
timeout: timeout,
) )
endforeach endforeach
else else

View File

@@ -49,7 +49,7 @@ test_context_has_virtual_device (void)
GPtrArray *devices; GPtrArray *devices;
unsigned int i; unsigned int i;
fpt_setup_virtual_device_environment (FPT_VIRTUAL_DEVICE_IMAGE); fpt_setup_virtual_device_environment ();
context = fp_context_new (); context = fp_context_new ();
devices = fp_context_get_devices (context); devices = fp_context_get_devices (context);
@@ -70,7 +70,7 @@ test_context_has_virtual_device (void)
g_assert_true (FP_IS_DEVICE (virtual_device)); g_assert_true (FP_IS_DEVICE (virtual_device));
fpt_teardown_virtual_device_environment (FPT_VIRTUAL_DEVICE_IMAGE); fpt_teardown_virtual_device_environment ();
} }
static void static void
@@ -81,7 +81,7 @@ test_context_enumerates_new_devices (void)
context = fp_context_new (); context = fp_context_new ();
fpt_setup_virtual_device_environment (FPT_VIRTUAL_DEVICE_IMAGE); fpt_setup_virtual_device_environment ();
fp_context_enumerate (context); fp_context_enumerate (context);
devices = fp_context_get_devices (context); devices = fp_context_get_devices (context);
@@ -89,7 +89,7 @@ test_context_enumerates_new_devices (void)
g_assert_nonnull (devices); g_assert_nonnull (devices);
g_assert_cmpuint (devices->len, ==, 1); g_assert_cmpuint (devices->len, ==, 1);
fpt_teardown_virtual_device_environment (FPT_VIRTUAL_DEVICE_IMAGE); fpt_teardown_virtual_device_environment ();
} }
int int

View File

@@ -36,7 +36,7 @@ on_device_opened (FpDevice *dev, GAsyncResult *res, FptContext *tctx)
static void static void
test_device_open_async (void) test_device_open_async (void)
{ {
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE); g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
fp_device_open (tctx->device, NULL, (GAsyncReadyCallback) on_device_opened, tctx); fp_device_open (tctx->device, NULL, (GAsyncReadyCallback) on_device_opened, tctx);
@@ -59,7 +59,7 @@ on_device_closed (FpDevice *dev, GAsyncResult *res, FptContext *tctx)
static void static void
test_device_close_async (void) test_device_close_async (void)
{ {
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE); g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
fp_device_open (tctx->device, NULL, (GAsyncReadyCallback) on_device_opened, tctx); fp_device_open (tctx->device, NULL, (GAsyncReadyCallback) on_device_opened, tctx);
while (!tctx->user_data) while (!tctx->user_data)
@@ -76,7 +76,7 @@ static void
test_device_open_sync (void) test_device_open_sync (void)
{ {
g_autoptr(GError) error = NULL; g_autoptr(GError) error = NULL;
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE); g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
fp_device_open_sync (tctx->device, NULL, &error); fp_device_open_sync (tctx->device, NULL, &error);
g_assert_no_error (error); g_assert_no_error (error);
@@ -97,7 +97,7 @@ static void
test_device_open_sync_notify (void) test_device_open_sync_notify (void)
{ {
g_autoptr(GError) error = NULL; g_autoptr(GError) error = NULL;
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE); g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
g_signal_connect (tctx->device, "notify::open", G_CALLBACK (on_open_notify), tctx); g_signal_connect (tctx->device, "notify::open", G_CALLBACK (on_open_notify), tctx);
fp_device_open_sync (tctx->device, NULL, &error); fp_device_open_sync (tctx->device, NULL, &error);
@@ -109,7 +109,7 @@ static void
test_device_close_sync (void) test_device_close_sync (void)
{ {
g_autoptr(GError) error = NULL; g_autoptr(GError) error = NULL;
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE); g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
fp_device_open_sync (tctx->device, NULL, NULL); fp_device_open_sync (tctx->device, NULL, NULL);
fp_device_close_sync (tctx->device, NULL, &error); fp_device_close_sync (tctx->device, NULL, &error);
@@ -131,7 +131,7 @@ static void
test_device_close_sync_notify (void) test_device_close_sync_notify (void)
{ {
g_autoptr(GError) error = NULL; g_autoptr(GError) error = NULL;
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE); g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
fp_device_open_sync (tctx->device, NULL, NULL); fp_device_open_sync (tctx->device, NULL, NULL);
@@ -144,7 +144,7 @@ test_device_close_sync_notify (void)
static void static void
test_device_get_driver (void) test_device_get_driver (void)
{ {
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE); g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
fp_device_open_sync (tctx->device, NULL, NULL); fp_device_open_sync (tctx->device, NULL, NULL);
g_assert_cmpstr (fp_device_get_driver (tctx->device), ==, "virtual_image"); g_assert_cmpstr (fp_device_get_driver (tctx->device), ==, "virtual_image");
@@ -153,7 +153,7 @@ test_device_get_driver (void)
static void static void
test_device_get_device_id (void) test_device_get_device_id (void)
{ {
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE); g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
fp_device_open_sync (tctx->device, NULL, NULL); fp_device_open_sync (tctx->device, NULL, NULL);
g_assert_cmpstr (fp_device_get_device_id (tctx->device), ==, "0"); g_assert_cmpstr (fp_device_get_device_id (tctx->device), ==, "0");
@@ -162,7 +162,7 @@ test_device_get_device_id (void)
static void static void
test_device_get_name (void) test_device_get_name (void)
{ {
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE); g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
fp_device_open_sync (tctx->device, NULL, NULL); fp_device_open_sync (tctx->device, NULL, NULL);
g_assert_cmpstr (fp_device_get_name (tctx->device), ==, g_assert_cmpstr (fp_device_get_name (tctx->device), ==,
@@ -172,7 +172,7 @@ test_device_get_name (void)
static void static void
test_device_get_scan_type (void) test_device_get_scan_type (void)
{ {
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE); g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
fp_device_open_sync (tctx->device, NULL, NULL); fp_device_open_sync (tctx->device, NULL, NULL);
g_assert_cmpint (fp_device_get_scan_type (tctx->device), ==, FP_SCAN_TYPE_SWIPE); g_assert_cmpint (fp_device_get_scan_type (tctx->device), ==, FP_SCAN_TYPE_SWIPE);
@@ -181,7 +181,7 @@ test_device_get_scan_type (void)
static void static void
test_device_get_nr_enroll_stages (void) test_device_get_nr_enroll_stages (void)
{ {
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE); g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
fp_device_open_sync (tctx->device, NULL, NULL); fp_device_open_sync (tctx->device, NULL, NULL);
g_assert_cmpuint (fp_device_get_nr_enroll_stages (tctx->device), ==, 5); g_assert_cmpuint (fp_device_get_nr_enroll_stages (tctx->device), ==, 5);
@@ -190,7 +190,7 @@ test_device_get_nr_enroll_stages (void)
static void static void
test_device_supports_identify (void) test_device_supports_identify (void)
{ {
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE); g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
fp_device_open_sync (tctx->device, NULL, NULL); fp_device_open_sync (tctx->device, NULL, NULL);
g_assert_true (fp_device_supports_identify (tctx->device)); g_assert_true (fp_device_supports_identify (tctx->device));
@@ -199,7 +199,7 @@ test_device_supports_identify (void)
static void static void
test_device_supports_capture (void) test_device_supports_capture (void)
{ {
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE); g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
fp_device_open_sync (tctx->device, NULL, NULL); fp_device_open_sync (tctx->device, NULL, NULL);
g_assert_true (fp_device_supports_capture (tctx->device)); g_assert_true (fp_device_supports_capture (tctx->device));
@@ -208,7 +208,7 @@ test_device_supports_capture (void)
static void static void
test_device_has_storage (void) test_device_has_storage (void)
{ {
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE); g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
fp_device_open_sync (tctx->device, NULL, NULL); fp_device_open_sync (tctx->device, NULL, NULL);
g_assert_false (fp_device_has_storage (tctx->device)); g_assert_false (fp_device_has_storage (tctx->device));

View File

@@ -959,7 +959,7 @@ test_driver_verify_complete_retry (void)
g_test_assert_expected_messages (); g_test_assert_expected_messages ();
g_assert_true (error != g_steal_pointer (&fake_dev->ret_error)); g_assert_true (error != g_steal_pointer (&fake_dev->ret_error));
g_steal_pointer (&fake_dev->user_data); g_assert_true (error != g_steal_pointer (&fake_dev->user_data));
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_GENERAL); g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_GENERAL);
g_assert_true (match_data->called); g_assert_true (match_data->called);
g_assert_error (match_data->error, FP_DEVICE_RETRY, FP_DEVICE_RETRY_TOO_SHORT); g_assert_error (match_data->error, FP_DEVICE_RETRY, FP_DEVICE_RETRY_TOO_SHORT);
@@ -981,7 +981,7 @@ test_driver_verify_complete_retry (void)
g_test_assert_expected_messages (); g_test_assert_expected_messages ();
g_assert_true (error != g_steal_pointer (&fake_dev->ret_error)); g_assert_true (error != g_steal_pointer (&fake_dev->ret_error));
g_steal_pointer (&fake_dev->user_data); g_assert_true (error != g_steal_pointer (&fake_dev->user_data));
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_GENERAL); g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_GENERAL);
g_assert_true (match_data->called); g_assert_true (match_data->called);
g_assert_error (match_data->error, FP_DEVICE_RETRY, FP_DEVICE_RETRY_TOO_SHORT); g_assert_error (match_data->error, FP_DEVICE_RETRY, FP_DEVICE_RETRY_TOO_SHORT);
@@ -1001,7 +1001,7 @@ test_driver_verify_complete_retry (void)
g_test_assert_expected_messages (); g_test_assert_expected_messages ();
g_assert_true (error != g_steal_pointer (&fake_dev->ret_error)); g_assert_true (error != g_steal_pointer (&fake_dev->ret_error));
g_steal_pointer (&fake_dev->user_data); g_assert_true (error != g_steal_pointer (&fake_dev->user_data));
g_assert_error (error, FP_DEVICE_RETRY, FP_DEVICE_RETRY_GENERAL); g_assert_error (error, FP_DEVICE_RETRY, FP_DEVICE_RETRY_GENERAL);
g_assert_true (match_data->called); g_assert_true (match_data->called);
g_assert_error (match_data->error, FP_DEVICE_RETRY, FP_DEVICE_RETRY_GENERAL); g_assert_error (match_data->error, FP_DEVICE_RETRY, FP_DEVICE_RETRY_GENERAL);
@@ -1296,7 +1296,7 @@ test_driver_identify_complete_retry (void)
g_test_assert_expected_messages (); g_test_assert_expected_messages ();
g_assert_true (error != g_steal_pointer (&fake_dev->ret_error)); g_assert_true (error != g_steal_pointer (&fake_dev->ret_error));
g_steal_pointer (&fake_dev->user_data); g_assert_true (error != g_steal_pointer (&fake_dev->user_data));
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_GENERAL); g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_GENERAL);
g_assert_true (match_data->called); g_assert_true (match_data->called);
g_assert_error (match_data->error, FP_DEVICE_RETRY, FP_DEVICE_RETRY_TOO_SHORT); g_assert_error (match_data->error, FP_DEVICE_RETRY, FP_DEVICE_RETRY_TOO_SHORT);

View File

@@ -22,60 +22,41 @@
#include "test-utils.h" #include "test-utils.h"
struct
{
const char *envvar;
const char *driver_id;
const char *device_id;
} devtype_vars[FPT_NUM_VIRTUAL_DEVICE_TYPES] = {
{ "FP_VIRTUAL_IMAGE", "virtual_image", "virtual_image" }, /* FPT_VIRTUAL_DEVICE_IMAGE */
{ "FP_VIRTUAL_DEVICE", "virtual_device", "virtual_device" }, /* FPT_VIRTUAL_DEVICE */
{ "FP_VIRTUAL_DEVICE_IDENT", "virtual_device", "virtual_device_ident" } /* FPT_VIRTUAL_DEVICE_IDENT */
};
void void
fpt_teardown_virtual_device_environment (FptVirtualDeviceType devtype) fpt_teardown_virtual_device_environment (void)
{ {
const char *path; const char *path = g_getenv ("FP_VIRTUAL_IMAGE");
path = g_getenv (devtype_vars[devtype].envvar);
if (path) if (path)
{ {
g_autofree char *temp_dir = g_path_get_dirname (path); g_autofree char *temp_dir = g_path_get_dirname (path);
g_unsetenv (devtype_vars[devtype].envvar); g_unsetenv ("FP_VIRTUAL_IMAGE");
g_unlink (path); g_unlink (path);
g_rmdir (temp_dir); g_rmdir (temp_dir);
} }
} }
static FptVirtualDeviceType global_devtype;
static void static void
on_signal_event (int sig) on_signal_event (int sig)
{ {
fpt_teardown_virtual_device_environment (global_devtype); fpt_teardown_virtual_device_environment ();
} }
void void
fpt_setup_virtual_device_environment (FptVirtualDeviceType devtype) fpt_setup_virtual_device_environment (void)
{ {
g_autoptr(GError) error = NULL; g_autoptr(GError) error = NULL;
g_autofree char *temp_dir = NULL; g_autofree char *temp_dir = NULL;
g_autofree char *temp_path = NULL; g_autofree char *temp_path = NULL;
g_autofree char *filename = NULL;
g_assert_null (g_getenv (devtype_vars[devtype].envvar)); g_assert_null (g_getenv ("FP_VIRTUAL_IMAGE"));
temp_dir = g_dir_make_tmp ("libfprint-XXXXXX", &error); temp_dir = g_dir_make_tmp ("libfprint-XXXXXX", &error);
g_assert_no_error (error); g_assert_no_error (error);
filename = g_strdup_printf ("%s.socket", devtype_vars[devtype].device_id); temp_path = g_build_filename (temp_dir, "virtual-image.socket", NULL);
temp_path = g_build_filename (temp_dir, filename, NULL); g_setenv ("FP_VIRTUAL_IMAGE", temp_path, TRUE);
g_setenv (devtype_vars[devtype].envvar, temp_path, TRUE);
global_devtype = devtype;
signal (SIGKILL, on_signal_event); signal (SIGKILL, on_signal_event);
signal (SIGABRT, on_signal_event); signal (SIGABRT, on_signal_event);
@@ -97,16 +78,13 @@ fpt_context_new (void)
} }
FptContext * FptContext *
fpt_context_new_with_virtual_device (FptVirtualDeviceType devtype) fpt_context_new_with_virtual_imgdev (void)
{ {
FptContext *tctx; FptContext *tctx;
GPtrArray *devices; GPtrArray *devices;
unsigned int i; unsigned int i;
g_assert_true (devtype >= FPT_VIRTUAL_DEVICE_IMAGE && fpt_setup_virtual_device_environment ();
devtype < FPT_NUM_VIRTUAL_DEVICE_TYPES);
fpt_setup_virtual_device_environment (devtype);
tctx = fpt_context_new (); tctx = fpt_context_new ();
devices = fp_context_get_devices (tctx->fp_context); devices = fp_context_get_devices (tctx->fp_context);
@@ -118,7 +96,7 @@ fpt_context_new_with_virtual_device (FptVirtualDeviceType devtype)
{ {
FpDevice *device = devices->pdata[i]; FpDevice *device = devices->pdata[i];
if (g_strcmp0 (fp_device_get_driver (device), devtype_vars[devtype].driver_id) == 0) if (g_strcmp0 (fp_device_get_driver (device), "virtual_image") == 0)
{ {
tctx->device = device; tctx->device = device;
break; break;
@@ -127,7 +105,6 @@ fpt_context_new_with_virtual_device (FptVirtualDeviceType devtype)
g_assert_true (FP_IS_DEVICE (tctx->device)); g_assert_true (FP_IS_DEVICE (tctx->device));
g_object_add_weak_pointer (G_OBJECT (tctx->device), (gpointer) & tctx->device); g_object_add_weak_pointer (G_OBJECT (tctx->device), (gpointer) & tctx->device);
g_object_set_data (G_OBJECT (tctx->fp_context), "devtype", GUINT_TO_POINTER (devtype));
return tctx; return tctx;
} }
@@ -135,10 +112,6 @@ fpt_context_new_with_virtual_device (FptVirtualDeviceType devtype)
void void
fpt_context_free (FptContext *tctx) fpt_context_free (FptContext *tctx)
{ {
FptVirtualDeviceType devtype;
devtype = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (tctx->fp_context), "devtype"));
if (tctx->device && fp_device_is_open (tctx->device)) if (tctx->device && fp_device_is_open (tctx->device))
{ {
g_autoptr(GError) error = NULL; g_autoptr(GError) error = NULL;
@@ -150,5 +123,5 @@ fpt_context_free (FptContext *tctx)
g_clear_object (&tctx->fp_context); g_clear_object (&tctx->fp_context);
g_free (tctx); g_free (tctx);
fpt_teardown_virtual_device_environment (devtype); fpt_teardown_virtual_device_environment ();
} }

View File

@@ -19,15 +19,8 @@
#include <glib.h> #include <glib.h>
typedef enum { void fpt_setup_virtual_device_environment (void);
FPT_VIRTUAL_DEVICE_IMAGE = 0, void fpt_teardown_virtual_device_environment (void);
FPT_VIRTUAL_DEVICE,
FPT_VIRTUAL_DEVICE_IDENTIFY,
FPT_NUM_VIRTUAL_DEVICE_TYPES
} FptVirtualDeviceType;
void fpt_setup_virtual_device_environment (FptVirtualDeviceType devtype);
void fpt_teardown_virtual_device_environment (FptVirtualDeviceType devtype);
typedef struct _FptContext typedef struct _FptContext
{ {
@@ -37,7 +30,7 @@ typedef struct _FptContext
} FptContext; } FptContext;
FptContext * fpt_context_new (void); FptContext * fpt_context_new (void);
FptContext * fpt_context_new_with_virtual_device (FptVirtualDeviceType devtype); FptContext * fpt_context_new_with_virtual_imgdev (void);
void fpt_context_free (FptContext *test_context); void fpt_context_free (FptContext *test_context);

View File

@@ -3,10 +3,11 @@
import sys import sys
try: try:
import gi import gi
gi.require_version('FPrint', '2.0')
from gi.repository import FPrint, GLib, Gio
import os import os
import sys
from gi.repository import GLib, Gio
import unittest import unittest
import socket import socket
import struct import struct
@@ -19,8 +20,6 @@ except Exception as e:
print("Missing dependencies: %s" % str(e)) print("Missing dependencies: %s" % str(e))
sys.exit(77) sys.exit(77)
FPrint = None
# Re-run the test with the passed wrapper if set # Re-run the test with the passed wrapper if set
wrapper = os.getenv('LIBFPRINT_TEST_WRAPPER') wrapper = os.getenv('LIBFPRINT_TEST_WRAPPER')
if wrapper: if wrapper:
@@ -102,14 +101,12 @@ class VirtualImage(unittest.TestCase):
del self.con del self.con
self.dev.close_sync() self.dev.close_sync()
def send_retry(self, retry_error=None, iterate=True): def send_retry(self, retry_error=FPrint.DeviceRetry.TOO_SHORT, iterate=True):
retry_error = retry_error if retry_error else FPrint.DeviceRetry.TOO_SHORT
self.con.sendall(struct.pack('ii', -1, retry_error)) self.con.sendall(struct.pack('ii', -1, retry_error))
while iterate and ctx.pending(): while iterate and ctx.pending():
ctx.iteration(False) ctx.iteration(False)
def send_error(self, device_error=None, iterate=True): def send_error(self, device_error=FPrint.DeviceError.GENERAL, iterate=True):
device_error = device_error if device_error else FPrint.DeviceError.GENERAL
self.con.sendall(struct.pack('ii', -2, device_error)) self.con.sendall(struct.pack('ii', -2, device_error))
while iterate and ctx.pending(): while iterate and ctx.pending():
ctx.iteration(False) ctx.iteration(False)
@@ -349,12 +346,5 @@ class VirtualImage(unittest.TestCase):
assert(not self._verify_match) assert(not self._verify_match)
if __name__ == '__main__': if __name__ == '__main__':
try:
gi.require_version('FPrint', '2.0')
from gi.repository import FPrint
except Exception as e:
print("Missing dependencies: %s" % str(e))
sys.exit(77)
# avoid writing to stderr # avoid writing to stderr
unittest.main(testRunner=unittest.TextTestRunner(stream=sys.stdout, verbosity=2)) unittest.main(testRunner=unittest.TextTestRunner(stream=sys.stdout, verbosity=2))