From 993109a7f8d15a20f460d85501dcf549b3fb45ab Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Mon, 25 Jan 2021 16:47:19 +0100
Subject: [PATCH] virtual-device: Implement cancel vfunc, to stop timeouts

---
 libfprint/drivers/virtual-device.c | 21 +++++++++++++++++++++
 tests/virtual-device.py            |  5 ++---
 2 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/libfprint/drivers/virtual-device.c b/libfprint/drivers/virtual-device.c
index 61e98df..2f9c3a8 100644
--- a/libfprint/drivers/virtual-device.c
+++ b/libfprint/drivers/virtual-device.c
@@ -92,6 +92,15 @@ process_cmds (FpDeviceVirtualDevice * self,
               gboolean                scan,
               GError                **error)
 {
+  if (g_cancellable_is_cancelled (self->cancellable) ||
+      (fpi_device_get_current_action (FP_DEVICE (self)) != FPI_DEVICE_ACTION_NONE &&
+       g_cancellable_is_cancelled (fpi_device_get_cancellable (FP_DEVICE (self)))))
+    {
+      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CANCELLED,
+                           "Operation was cancelled");
+      return NULL;
+    }
+
   while (self->pending_commands->len > 0)
     {
       gchar *cmd = g_ptr_array_index (self->pending_commands, 0);
@@ -457,6 +466,17 @@ dev_enroll (FpDevice *dev)
     }
 }
 
+static void
+dev_cancel (FpDevice *dev)
+{
+  FpDeviceVirtualDevice *self = FP_DEVICE_VIRTUAL_DEVICE (dev);
+
+  g_debug ("Got cancellation!");
+  g_clear_handle_id (&self->sleep_timeout_id, g_source_remove);
+
+  maybe_continue_current_action (self);
+}
+
 static void
 dev_deinit (FpDevice *dev)
 {
@@ -511,4 +531,5 @@ fpi_device_virtual_device_class_init (FpDeviceVirtualDeviceClass *klass)
   dev_class->close = dev_deinit;
   dev_class->verify = dev_verify;
   dev_class->enroll = dev_enroll;
+  dev_class->cancel = dev_cancel;
 }
diff --git a/tests/virtual-device.py b/tests/virtual-device.py
index 323b23a..fb0f2bb 100644
--- a/tests/virtual-device.py
+++ b/tests/virtual-device.py
@@ -440,8 +440,6 @@ class VirtualDevice(unittest.TestCase):
             self.dev.close_sync()
 
     def test_device_sleep(self):
-        enrolled = self.enroll_print('testprint', FPrint.Finger.LEFT_LITTLE)
-
         timeout_reached = False
         def on_timeout():
             nonlocal timeout_reached
@@ -450,7 +448,8 @@ class VirtualDevice(unittest.TestCase):
         self.send_command('SLEEP', 1500)
         GLib.timeout_add(300, on_timeout)
 
-        self.start_verify(enrolled, identify=self.dev.supports_identify())
+        self.start_verify(FPrint.Print.new(self.dev),
+            identify=self.dev.supports_identify())
         while not timeout_reached:
             ctx.iteration(False)