diff --git a/libfprint/drivers/virtual-device-private.h b/libfprint/drivers/virtual-device-private.h index d0d8077..068da00 100644 --- a/libfprint/drivers/virtual-device-private.h +++ b/libfprint/drivers/virtual-device-private.h @@ -80,6 +80,7 @@ struct _FpDeviceVirtualDevice guint wait_command_id; guint sleep_timeout_id; guint enroll_stages_passed; + gboolean supports_cancellation; }; /* Not really final here, but we can do this to share the FpDeviceVirtualDevice diff --git a/libfprint/drivers/virtual-device.c b/libfprint/drivers/virtual-device.c index 2f9c3a8..27749ba 100644 --- a/libfprint/drivers/virtual-device.c +++ b/libfprint/drivers/virtual-device.c @@ -43,6 +43,7 @@ G_DEFINE_TYPE (FpDeviceVirtualDevice, fpi_device_virtual_device, FP_TYPE_DEVICE) #define SLEEP_CMD_PREFIX "SLEEP " #define SET_ENROLL_STAGES_PREFIX "SET_ENROLL_STAGES " #define SET_SCAN_TYPE_PREFIX "SET_SCAN_TYPE " +#define SET_CANCELLATION_PREFIX "SET_CANCELLATION_ENABLED " #define LIST_CMD "LIST" #define UNPLUG_CMD "UNPLUG" @@ -257,6 +258,14 @@ recv_instruction_cb (GObject *source_object, else g_warning ("Scan type '%s' not found", scan_type); } + else if (g_str_has_prefix (cmd, SET_CANCELLATION_PREFIX)) + { + self->supports_cancellation = g_ascii_strtoull ( + cmd + strlen (SET_CANCELLATION_PREFIX), NULL, 10) != 0; + + g_debug ("Cancellation support toggled: %d", + self->supports_cancellation); + } else { g_ptr_array_add (self->pending_commands, g_steal_pointer (&cmd)); @@ -471,6 +480,9 @@ dev_cancel (FpDevice *dev) { FpDeviceVirtualDevice *self = FP_DEVICE_VIRTUAL_DEVICE (dev); + if (!self->supports_cancellation) + return; + g_debug ("Got cancellation!"); g_clear_handle_id (&self->sleep_timeout_id, g_source_remove); @@ -505,6 +517,7 @@ fpi_device_virtual_device_finalize (GObject *object) static void fpi_device_virtual_device_init (FpDeviceVirtualDevice *self) { + self->supports_cancellation = TRUE; self->pending_commands = g_ptr_array_new_with_free_func (g_free); } diff --git a/tests/virtual-device.py b/tests/virtual-device.py index fb0f2bb..41e5728 100644 --- a/tests/virtual-device.py +++ b/tests/virtual-device.py @@ -96,7 +96,8 @@ class VirtualDevice(unittest.TestCase): def send_command(self, command, *args): self.assertIn(command, ['INSERT', 'REMOVE', 'SCAN', 'ERROR', 'RETRY', - 'FINGER', 'UNPLUG', 'SLEEP', 'SET_ENROLL_STAGES', 'SET_SCAN_TYPE']) + 'FINGER', 'UNPLUG', 'SLEEP', 'SET_ENROLL_STAGES', 'SET_SCAN_TYPE', + 'SET_CANCELLATION_ENABLED']) with Connection(self.sockaddr) as con: params = ' '.join(str(p) for p in args) @@ -453,6 +454,43 @@ class VirtualDevice(unittest.TestCase): while not timeout_reached: ctx.iteration(False) + self.assertFalse(self._verify_completed) + + timeout_reached = False + self._cancellable.cancel() + GLib.timeout_add(200, on_timeout) + + while not timeout_reached: + ctx.iteration(False) + + self.assertTrue(self._verify_completed) + self.cancel_verify() + + def test_device_sleep_on_cancellation(self): + timeout_reached = False + def on_timeout(): + nonlocal timeout_reached + timeout_reached = True + + self.send_command('SET_CANCELLATION_ENABLED', int(False)) + self.send_command('SLEEP', 1500) + self.send_command('SCAN', 'foo-print') + GLib.timeout_add(300, on_timeout) + + self.start_verify(FPrint.Print.new(self.dev), + identify=self.dev.supports_identify()) + while not timeout_reached: + ctx.iteration(False) + + self.assertFalse(self._verify_completed) + + timeout_reached = False + self._cancellable.cancel() + GLib.timeout_add(300, on_timeout) + + while not timeout_reached: + ctx.iteration(False) + self.assertFalse(self._verify_completed) self.cancel_verify()