diff --git a/libfprint/drivers/virtual-device.c b/libfprint/drivers/virtual-device.c index 68f5c3d..cf36d0d 100644 --- a/libfprint/drivers/virtual-device.c +++ b/libfprint/drivers/virtual-device.c @@ -39,6 +39,7 @@ G_DEFINE_TYPE (FpDeviceVirtualDevice, fpi_device_virtual_device, FP_TYPE_DEVICE) #define SCAN_CMD_PREFIX "SCAN " #define ERROR_CMD_PREFIX "ERROR " #define RETRY_CMD_PREFIX "RETRY " +#define FINGER_CMD_PREFIX "FINGER " #define LIST_CMD "LIST" @@ -75,6 +76,8 @@ process_cmds (FpDeviceVirtualDevice * self, { gchar *cmd = g_ptr_array_index (self->pending_commands, 0); + g_debug ("Processing command %s", cmd); + /* These are always processed. */ if (g_str_has_prefix (cmd, INSERT_CMD_PREFIX)) { @@ -123,6 +126,18 @@ process_cmds (FpDeviceVirtualDevice * self, g_ptr_array_remove_index (self->pending_commands, 0); return NULL; } + else if (g_str_has_prefix (cmd, FINGER_CMD_PREFIX)) + { + gboolean finger_present; + + finger_present = g_ascii_strtoull (cmd + strlen (FINGER_CMD_PREFIX), NULL, 10) != 0; + fpi_device_report_finger_status_changes (FP_DEVICE (self), + finger_present ? FP_FINGER_STATUS_PRESENT : FP_FINGER_STATUS_NONE, + finger_present ? FP_FINGER_STATUS_NONE : FP_FINGER_STATUS_PRESENT); + + g_ptr_array_remove_index (self->pending_commands, 0); + continue; + } else { g_warning ("Could not process command: %s", cmd); diff --git a/tests/virtual-device.py b/tests/virtual-device.py index 3a514f5..570e3be 100644 --- a/tests/virtual-device.py +++ b/tests/virtual-device.py @@ -93,7 +93,8 @@ class VirtualDevice(unittest.TestCase): super().tearDown() def send_command(self, command, *args): - self.assertIn(command, ['INSERT', 'REMOVE', 'SCAN', 'ERROR', 'RETRY']) + self.assertIn(command, ['INSERT', 'REMOVE', 'SCAN', 'ERROR', 'RETRY', + 'FINGER']) with Connection(self.sockaddr) as con: params = ' '.join(str(p) for p in args) @@ -102,6 +103,16 @@ class VirtualDevice(unittest.TestCase): while ctx.pending(): ctx.iteration(False) + def send_finger_report(self, has_finger, iterate=True): + self.send_command('FINGER', 1 if has_finger else 0) + + if iterate: + expected = (FPrint.FingerStatusFlags.PRESENT if has_finger + else ~FPrint.FingerStatusFlags.PRESENT) + + while not (self.dev.get_finger_status() & expected): + ctx.iteration(True) + def enroll_print(self, nick, finger, username='testuser'): self._enrolled = None @@ -109,6 +120,8 @@ class VirtualDevice(unittest.TestCase): print("Enroll done") self._enrolled = dev.enroll_finish(res) + self.assertEqual(self.dev.get_finger_status(), FPrint.FingerStatusFlags.NONE) + self.send_command('SCAN', nick) template = FPrint.Print.new(self.dev) @@ -119,6 +132,12 @@ class VirtualDevice(unittest.TestCase): while self._enrolled is None: ctx.iteration(False) + if not self._enrolled: + self.assertEqual(self.dev.get_finger_status(), + FPrint.FingerStatusFlags.NEEDED) + + self.assertEqual(self.dev.get_finger_status(), FPrint.FingerStatusFlags.NONE) + self.assertEqual(self._enrolled.get_device_stored(), self.dev.has_storage()) @@ -181,7 +200,6 @@ class VirtualDevice(unittest.TestCase): self.check_verify(matching, 'not-testprint', match=False) - def test_enroll_verify_error(self): matching = self.enroll_print('testprint', FPrint.Finger.LEFT_RING) @@ -193,6 +211,31 @@ class VirtualDevice(unittest.TestCase): self.check_verify(FPrint.Print.new(self.dev), FPrint.DeviceRetry.TOO_SHORT, match=False) + def test_finger_status(self): + cancellable = Gio.Cancellable() + got_cb = False + + def verify_cb(dev, res): + nonlocal got_cb + got_cb = True + + self.dev.verify(FPrint.Print.new(self.dev), callback=verify_cb, cancellable=cancellable) + while not self.dev.get_finger_status() is FPrint.FingerStatusFlags.NEEDED: + ctx.iteration(True) + + self.send_finger_report(True) + self.assertEqual(self.dev.get_finger_status(), + FPrint.FingerStatusFlags.NEEDED | FPrint.FingerStatusFlags.PRESENT) + + self.send_finger_report(False) + self.assertEqual(self.dev.get_finger_status(), FPrint.FingerStatusFlags.NEEDED) + + cancellable.cancel() + while not got_cb: + ctx.iteration(True) + + self.assertEqual(self.dev.get_finger_status(), FPrint.FingerStatusFlags.NONE) + class VirtualDeviceStorage(VirtualDevice): def cleanup_device_storage(self):