virtual-device: Mark finger as needed only after we start scanning

In case we sent a sleep event to the device we may want to wait it to
emit the finger needed state before the timeout is completed.

So add a function to manage this for all the scan cases
This commit is contained in:
Marco Trevisan (Treviño) 2021-01-25 22:47:40 +01:00
parent 3db0858fb0
commit 0bb0492025
4 changed files with 70 additions and 15 deletions

View file

@ -96,5 +96,7 @@ G_DECLARE_FINAL_TYPE (FpDeviceVirtualDeviceStorage, fpi_device_virtual_device_st
char * process_cmds (FpDeviceVirtualDevice * self, gboolean scan, GError **error);
char * start_scan_command (FpDeviceVirtualDevice *self,
GError **error);
gboolean should_wait_for_command (FpDeviceVirtualDevice *self,
GError *error);

View file

@ -41,13 +41,12 @@ dev_identify (FpDevice *dev)
GPtrArray *prints;
g_autofree char *scan_id = NULL;
fpi_device_get_identify_data (dev, &prints);
fpi_device_report_finger_status (dev, FP_FINGER_STATUS_NEEDED);
scan_id = process_cmds (self, TRUE, &error);
if (should_wait_for_command (self, error))
scan_id = start_scan_command (self, &error);
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_PENDING))
return;
fpi_device_get_identify_data (dev, &prints);
if (scan_id)
{
GVariant *data = NULL;

View file

@ -358,6 +358,35 @@ should_wait_for_command (FpDeviceVirtualDevice *self,
return TRUE;
}
char *
start_scan_command (FpDeviceVirtualDevice *self,
GError **error)
{
g_autoptr(GError) local_error = NULL;
g_autofree char *scan_id = NULL;
scan_id = process_cmds (self, TRUE, &local_error);
if (!self->sleep_timeout_id)
{
fpi_device_report_finger_status_changes (FP_DEVICE (self),
FP_FINGER_STATUS_NEEDED,
FP_FINGER_STATUS_NONE);
}
if (should_wait_for_command (self, local_error))
{
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PENDING,
"Still waiting for command");
return NULL;
}
if (local_error)
g_propagate_error (error, g_steal_pointer (&local_error));
return g_steal_pointer (&scan_id);
}
static void
dev_verify (FpDevice *dev)
{
@ -366,13 +395,12 @@ dev_verify (FpDevice *dev)
FpPrint *print;
g_autofree char *scan_id = NULL;
fpi_device_get_verify_data (dev, &print);
fpi_device_report_finger_status (dev, FP_FINGER_STATUS_NEEDED);
scan_id = process_cmds (self, TRUE, &error);
if (should_wait_for_command (self, error))
scan_id = start_scan_command (self, &error);
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_PENDING))
return;
fpi_device_get_verify_data (dev, &print);
if (scan_id)
{
GVariant *data = NULL;
@ -414,13 +442,12 @@ dev_enroll (FpDevice *dev)
FpPrint *print = NULL;
g_autofree char *id = NULL;
fpi_device_report_finger_status (dev, FP_FINGER_STATUS_NEEDED);
fpi_device_get_enroll_data (dev, &print);
id = process_cmds (self, TRUE, &error);
if (should_wait_for_command (self, error))
id = start_scan_command (self, &error);
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_PENDING))
return;
fpi_device_get_enroll_data (dev, &print);
if (id)
{
GVariant *data;

View file

@ -344,6 +344,9 @@ class VirtualDevice(unittest.TestCase):
self.start_verify(FPrint.Print.new(self.dev),
identify=self.dev.supports_identify())
self.assertEqual(self.dev.get_finger_status(),
FPrint.FingerStatusFlags.NEEDED)
self.send_finger_report(True)
self.assertEqual(self.dev.get_finger_status(),
FPrint.FingerStatusFlags.NEEDED | FPrint.FingerStatusFlags.PRESENT)
@ -353,6 +356,30 @@ class VirtualDevice(unittest.TestCase):
self.cancel_verify()
def test_finger_status_after_sleep(self):
self.send_command('SLEEP', 10)
self.start_verify(FPrint.Print.new(self.dev),
identify=self.dev.supports_identify())
self.assertEqual(self.dev.get_finger_status(),
FPrint.FingerStatusFlags.NONE)
while self.dev.get_finger_status() != FPrint.FingerStatusFlags.NEEDED:
ctx.iteration(True)
self.assertEqual(self.dev.get_finger_status(),
FPrint.FingerStatusFlags.NEEDED)
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)
self.cancel_verify()
def test_change_enroll_stages(self):
notified_spec = None
def on_stage_changed(dev, spec):