virtual-device: Make possible to inject sleep events while verifying/identifying
Each command should be separated by SLEEP to be considered as something we want to perform during the current operation, otherwise will be used by next operation consuming it.
This commit is contained in:
parent
1dae6796f7
commit
7ffcc2f9e7
4 changed files with 110 additions and 8 deletions
|
@ -80,7 +80,9 @@ struct _FpDeviceVirtualDevice
|
||||||
guint wait_command_id;
|
guint wait_command_id;
|
||||||
guint sleep_timeout_id;
|
guint sleep_timeout_id;
|
||||||
guint enroll_stages_passed;
|
guint enroll_stages_passed;
|
||||||
|
gboolean match_reported;
|
||||||
gboolean supports_cancellation;
|
gboolean supports_cancellation;
|
||||||
|
gboolean injected_synthetic_cmd;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Not really final here, but we can do this to share the FpDeviceVirtualDevice
|
/* Not really final here, but we can do this to share the FpDeviceVirtualDevice
|
||||||
|
@ -100,3 +102,6 @@ char * start_scan_command (FpDeviceVirtualDevice *self,
|
||||||
GError **error);
|
GError **error);
|
||||||
gboolean should_wait_for_command (FpDeviceVirtualDevice *self,
|
gboolean should_wait_for_command (FpDeviceVirtualDevice *self,
|
||||||
GError *error);
|
GError *error);
|
||||||
|
gboolean should_wait_to_sleep (FpDeviceVirtualDevice *self,
|
||||||
|
const char *scan_id,
|
||||||
|
GError *error);
|
||||||
|
|
|
@ -69,11 +69,15 @@ dev_identify (FpDevice *dev)
|
||||||
&idx))
|
&idx))
|
||||||
match = g_ptr_array_index (prints, idx);
|
match = g_ptr_array_index (prints, idx);
|
||||||
|
|
||||||
|
if (!self->match_reported)
|
||||||
|
{
|
||||||
|
self->match_reported = TRUE;
|
||||||
fpi_device_identify_report (dev,
|
fpi_device_identify_report (dev,
|
||||||
match,
|
match,
|
||||||
new_scan,
|
new_scan,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (error && error->domain == FP_DEVICE_RETRY)
|
else if (error && error->domain == FP_DEVICE_RETRY)
|
||||||
{
|
{
|
||||||
fpi_device_identify_report (dev, NULL, NULL, g_steal_pointer (&error));
|
fpi_device_identify_report (dev, NULL, NULL, g_steal_pointer (&error));
|
||||||
|
@ -83,6 +87,10 @@ dev_identify (FpDevice *dev)
|
||||||
FP_FINGER_STATUS_NONE,
|
FP_FINGER_STATUS_NONE,
|
||||||
FP_FINGER_STATUS_PRESENT);
|
FP_FINGER_STATUS_PRESENT);
|
||||||
|
|
||||||
|
if (should_wait_to_sleep (self, scan_id, error))
|
||||||
|
return;
|
||||||
|
|
||||||
|
self->match_reported = FALSE;
|
||||||
fpi_device_identify_complete (dev, g_steal_pointer (&error));
|
fpi_device_identify_complete (dev, g_steal_pointer (&error));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,9 @@ maybe_continue_current_action (FpDeviceVirtualDevice *self)
|
||||||
{
|
{
|
||||||
FpDevice *dev = FP_DEVICE (self);
|
FpDevice *dev = FP_DEVICE (self);
|
||||||
|
|
||||||
|
if (self->sleep_timeout_id)
|
||||||
|
return;
|
||||||
|
|
||||||
switch (fpi_device_get_current_action (dev))
|
switch (fpi_device_get_current_action (dev))
|
||||||
{
|
{
|
||||||
case FPI_DEVICE_ACTION_ENROLL:
|
case FPI_DEVICE_ACTION_ENROLL:
|
||||||
|
@ -365,6 +368,9 @@ start_scan_command (FpDeviceVirtualDevice *self,
|
||||||
g_autoptr(GError) local_error = NULL;
|
g_autoptr(GError) local_error = NULL;
|
||||||
g_autofree char *scan_id = NULL;
|
g_autofree char *scan_id = NULL;
|
||||||
|
|
||||||
|
if (fp_device_get_finger_status (FP_DEVICE (self)) == FP_FINGER_STATUS_NONE)
|
||||||
|
self->injected_synthetic_cmd = FALSE;
|
||||||
|
|
||||||
scan_id = process_cmds (self, TRUE, &local_error);
|
scan_id = process_cmds (self, TRUE, &local_error);
|
||||||
|
|
||||||
if (!self->sleep_timeout_id)
|
if (!self->sleep_timeout_id)
|
||||||
|
@ -376,6 +382,8 @@ start_scan_command (FpDeviceVirtualDevice *self,
|
||||||
|
|
||||||
if (should_wait_for_command (self, local_error))
|
if (should_wait_for_command (self, local_error))
|
||||||
{
|
{
|
||||||
|
g_assert (!scan_id);
|
||||||
|
|
||||||
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PENDING,
|
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PENDING,
|
||||||
"Still waiting for command");
|
"Still waiting for command");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -391,6 +399,51 @@ start_scan_command (FpDeviceVirtualDevice *self,
|
||||||
return g_steal_pointer (&scan_id);
|
return g_steal_pointer (&scan_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
should_wait_to_sleep (FpDeviceVirtualDevice *self,
|
||||||
|
const char *scan_id,
|
||||||
|
GError *error)
|
||||||
|
{
|
||||||
|
const gchar *cmd;
|
||||||
|
|
||||||
|
if (self->sleep_timeout_id)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (!self->pending_commands->len)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
cmd = g_ptr_array_index (self->pending_commands, 0);
|
||||||
|
|
||||||
|
if (g_str_has_prefix (cmd, SLEEP_CMD_PREFIX))
|
||||||
|
{
|
||||||
|
g_free (process_cmds (self, FALSE, NULL));
|
||||||
|
|
||||||
|
g_assert (!self->injected_synthetic_cmd);
|
||||||
|
g_assert (self->sleep_timeout_id != 0);
|
||||||
|
|
||||||
|
if (!self->pending_commands->len)
|
||||||
|
{
|
||||||
|
g_autofree char *injected_cmd = NULL;
|
||||||
|
|
||||||
|
if (scan_id)
|
||||||
|
injected_cmd = g_strconcat (SCAN_CMD_PREFIX, scan_id, NULL);
|
||||||
|
else if (error && error->domain == FP_DEVICE_ERROR)
|
||||||
|
injected_cmd = g_strdup_printf (ERROR_CMD_PREFIX " %d", error->code);
|
||||||
|
else if (error && error->domain == FP_DEVICE_RETRY)
|
||||||
|
injected_cmd = g_strdup_printf (RETRY_CMD_PREFIX " %d", error->code);
|
||||||
|
else
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
g_debug ("Sleeping now, command queued for later: %s", injected_cmd);
|
||||||
|
|
||||||
|
g_ptr_array_insert (self->pending_commands, 0, g_steal_pointer (&injected_cmd));
|
||||||
|
self->injected_synthetic_cmd = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return self->sleep_timeout_id != 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dev_verify (FpDevice *dev)
|
dev_verify (FpDevice *dev)
|
||||||
{
|
{
|
||||||
|
@ -422,11 +475,15 @@ dev_verify (FpDevice *dev)
|
||||||
|
|
||||||
success = fp_print_equal (print, new_scan);
|
success = fp_print_equal (print, new_scan);
|
||||||
|
|
||||||
|
if (!self->match_reported)
|
||||||
|
{
|
||||||
|
self->match_reported = TRUE;
|
||||||
fpi_device_verify_report (dev,
|
fpi_device_verify_report (dev,
|
||||||
success ? FPI_MATCH_SUCCESS : FPI_MATCH_FAIL,
|
success ? FPI_MATCH_SUCCESS : FPI_MATCH_FAIL,
|
||||||
new_scan,
|
new_scan,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
g_debug ("Virtual device scan failed with error: %s", error->message);
|
g_debug ("Virtual device scan failed with error: %s", error->message);
|
||||||
|
@ -439,6 +496,10 @@ dev_verify (FpDevice *dev)
|
||||||
if (error && error->domain == FP_DEVICE_RETRY)
|
if (error && error->domain == FP_DEVICE_RETRY)
|
||||||
fpi_device_verify_report (dev, FPI_MATCH_ERROR, NULL, g_steal_pointer (&error));
|
fpi_device_verify_report (dev, FPI_MATCH_ERROR, NULL, g_steal_pointer (&error));
|
||||||
|
|
||||||
|
if (should_wait_to_sleep (self, scan_id, error))
|
||||||
|
return;
|
||||||
|
|
||||||
|
self->match_reported = FALSE;
|
||||||
fpi_device_verify_complete (dev, g_steal_pointer (&error));
|
fpi_device_verify_complete (dev, g_steal_pointer (&error));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -517,6 +578,9 @@ dev_enroll (FpDevice *dev)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (should_wait_to_sleep (self, id, error))
|
||||||
|
return;
|
||||||
|
|
||||||
self->enroll_stages_passed = 0;
|
self->enroll_stages_passed = 0;
|
||||||
fpi_device_enroll_complete (dev, NULL, g_steal_pointer (&error));
|
fpi_device_enroll_complete (dev, NULL, g_steal_pointer (&error));
|
||||||
}
|
}
|
||||||
|
@ -528,6 +592,12 @@ dev_cancel (FpDevice *dev)
|
||||||
{
|
{
|
||||||
FpDeviceVirtualDevice *self = FP_DEVICE_VIRTUAL_DEVICE (dev);
|
FpDeviceVirtualDevice *self = FP_DEVICE_VIRTUAL_DEVICE (dev);
|
||||||
|
|
||||||
|
if (self->injected_synthetic_cmd)
|
||||||
|
{
|
||||||
|
self->injected_synthetic_cmd = FALSE;
|
||||||
|
g_ptr_array_remove_index (self->pending_commands, 0);
|
||||||
|
}
|
||||||
|
|
||||||
if (!self->supports_cancellation)
|
if (!self->supports_cancellation)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -526,6 +526,25 @@ class VirtualDevice(unittest.TestCase):
|
||||||
self.assertFalse(self._verify_completed)
|
self.assertFalse(self._verify_completed)
|
||||||
self.cancel_verify()
|
self.cancel_verify()
|
||||||
|
|
||||||
|
def test_device_sleep_before_completing_verify(self):
|
||||||
|
enrolled = self.enroll_print('foo-print', FPrint.Finger.LEFT_RING)
|
||||||
|
|
||||||
|
self.send_command('SLEEP', 100)
|
||||||
|
self.start_verify(enrolled, identify=self.dev.supports_identify())
|
||||||
|
self.send_command('SCAN', 'bar-print')
|
||||||
|
self.send_command('SLEEP', 800)
|
||||||
|
|
||||||
|
while not self._verify_reported:
|
||||||
|
ctx.iteration(False)
|
||||||
|
|
||||||
|
self.assertFalse(self._verify_completed)
|
||||||
|
self.wait_timeout(10)
|
||||||
|
self.assertFalse(self._verify_completed)
|
||||||
|
|
||||||
|
self.complete_verify()
|
||||||
|
self.assertTrue(self._verify_reported)
|
||||||
|
|
||||||
|
|
||||||
class VirtualDeviceStorage(VirtualDevice):
|
class VirtualDeviceStorage(VirtualDevice):
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
|
|
Loading…
Reference in a new issue