Skip to content

Commit

Permalink
virtual-device: Add support for sleeping and sending errors on list a…
Browse files Browse the repository at this point in the history
…nd delete
  • Loading branch information
3v1n0 committed Jan 26, 2021
1 parent 7ffcc2f commit 88a38c3
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 10 deletions.
1 change: 1 addition & 0 deletions libfprint/drivers/virtual-device-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ struct _FpDeviceVirtualDevice
gboolean match_reported;
gboolean supports_cancellation;
gboolean injected_synthetic_cmd;
gboolean ignore_wait;
};

/* Not really final here, but we can do this to share the FpDeviceVirtualDevice
Expand Down
22 changes: 20 additions & 2 deletions libfprint/drivers/virtual-device-storage.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,19 @@ static void
dev_list (FpDevice *dev)
{
g_autoptr(GPtrArray) prints_list = NULL;
g_autoptr(GError) error = NULL;
FpDeviceVirtualDevice *vdev = FP_DEVICE_VIRTUAL_DEVICE (dev);
struct ListData data;

process_cmds (vdev, FALSE, NULL);
process_cmds (vdev, FALSE, &error);
if (should_wait_for_command (vdev, error))
return;

if (error && !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
{
fpi_device_list_complete (dev, NULL, g_steal_pointer (&error));
return;
}

prints_list = g_ptr_array_new_full (g_hash_table_size (vdev->prints_storage), NULL);
data.dev = dev;
Expand All @@ -140,11 +149,20 @@ static void
dev_delete (FpDevice *dev)
{
g_autoptr(GVariant) data = NULL;
g_autoptr(GError) error = NULL;
FpDeviceVirtualDevice *vdev = FP_DEVICE_VIRTUAL_DEVICE (dev);
FpPrint *print = NULL;
const char *id = NULL;

process_cmds (vdev, FALSE, NULL);
process_cmds (vdev, FALSE, &error);
if (should_wait_for_command (vdev, error))
return;

if (error && !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
{
fpi_device_delete_complete (dev, g_steal_pointer (&error));
return;
}

fpi_device_get_delete_data (dev, &print);

Expand Down
41 changes: 33 additions & 8 deletions libfprint/drivers/virtual-device.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,14 @@ maybe_continue_current_action (FpDeviceVirtualDevice *self)
FP_DEVICE_GET_CLASS (self)->identify (dev);
break;

case FPI_DEVICE_ACTION_LIST:
FP_DEVICE_GET_CLASS (self)->list (dev);
break;

case FPI_DEVICE_ACTION_DELETE:
FP_DEVICE_GET_CLASS (self)->delete (dev);
break;

default:
break;
}
Expand Down Expand Up @@ -141,6 +149,14 @@ process_cmds (FpDeviceVirtualDevice * self,

return NULL;
}
else if (g_str_has_prefix (cmd, ERROR_CMD_PREFIX))
{
g_propagate_error (error,
fpi_device_error_new (g_ascii_strtoull (cmd + strlen (ERROR_CMD_PREFIX), NULL, 10)));

g_ptr_array_remove_index (self->pending_commands, 0);
return NULL;
}

/* If we are not scanning, then we have to stop here. */
if (!scan)
Expand All @@ -153,14 +169,6 @@ process_cmds (FpDeviceVirtualDevice * self,
g_ptr_array_remove_index (self->pending_commands, 0);
return res;
}
else if (g_str_has_prefix (cmd, ERROR_CMD_PREFIX))
{
g_propagate_error (error,
fpi_device_error_new (g_ascii_strtoull (cmd + strlen (ERROR_CMD_PREFIX), NULL, 10)));

g_ptr_array_remove_index (self->pending_commands, 0);
return NULL;
}
else if (g_str_has_prefix (cmd, RETRY_CMD_PREFIX))
{
g_propagate_error (error,
Expand Down Expand Up @@ -338,6 +346,20 @@ wait_for_command_timeout (gpointer data)
GError *error = NULL;

self->wait_command_id = 0;

switch (fpi_device_get_current_action (FP_DEVICE (self)))
{
case FPI_DEVICE_ACTION_LIST:
case FPI_DEVICE_ACTION_DELETE:
self->ignore_wait = TRUE;
maybe_continue_current_action (self);
self->ignore_wait = FALSE;
return FALSE;

default:
break;
}

error = g_error_new (G_IO_ERROR, G_IO_ERROR_TIMED_OUT, "No commands arrived in time to run!");
fpi_device_action_error (FP_DEVICE (self), error);

Expand All @@ -351,6 +373,9 @@ should_wait_for_command (FpDeviceVirtualDevice *self,
if (!error && self->sleep_timeout_id)
return TRUE;

if (self->ignore_wait)
return FALSE;

if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
return FALSE;

Expand Down
41 changes: 41 additions & 0 deletions tests/virtual-device.py
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,47 @@ def test_list_delete(self):
self.dev.delete_print_sync(p)
self.assertFalse(self.dev.list_prints_sync())

def test_delete_error(self):
deleted_res = None
def on_deleted(dev, res):
nonlocal deleted_res
try:
deleted_res = dev.delete_print_finish(res)
except GLib.Error as e:
deleted_res = e

self.send_command('SLEEP', 100)
self.send_error(FPrint.DeviceError.DATA_NOT_FOUND)
self.dev.delete_print(FPrint.Print.new(self.dev), callback=on_deleted)
self.wait_timeout(2)
self.assertIsNone(deleted_res)

while not deleted_res:
ctx.iteration(True)

self.assertEqual(deleted_res.code, int(FPrint.DeviceError.DATA_NOT_FOUND))

def test_list_error(self):
list_res = None

def on_listed(dev, res):
nonlocal list_res
try:
list_res = dev.list_prints_finish(res)
except GLib.Error as e:
list_res = e

self.send_command('SLEEP', 100)
self.send_error(FPrint.DeviceError.BUSY)
self.dev.list_prints(callback=on_listed)
self.wait_timeout(2)
self.assertIsNone(list_res)

while not list_res:
ctx.iteration(True)

self.assertEqual(list_res.code, int(FPrint.DeviceError.BUSY))

def test_list_delete_missing(self):
p = self.enroll_print('testprint', FPrint.Finger.RIGHT_THUMB)
self.send_command('REMOVE', 'testprint')
Expand Down

0 comments on commit 88a38c3

Please sign in to comment.