Skip to content

Commit

Permalink
virtual-device: Make possible to inject sleep events while verifying/…
Browse files Browse the repository at this point in the history
…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.
  • Loading branch information
3v1n0 committed Jan 26, 2021
1 parent 1dae679 commit 7ffcc2f
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 8 deletions.
5 changes: 5 additions & 0 deletions libfprint/drivers/virtual-device-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,9 @@ struct _FpDeviceVirtualDevice
guint wait_command_id;
guint sleep_timeout_id;
guint enroll_stages_passed;
gboolean match_reported;
gboolean supports_cancellation;
gboolean injected_synthetic_cmd;
};

/* Not really final here, but we can do this to share the FpDeviceVirtualDevice
Expand All @@ -100,3 +102,6 @@ char * start_scan_command (FpDeviceVirtualDevice *self,
GError **error);
gboolean should_wait_for_command (FpDeviceVirtualDevice *self,
GError *error);
gboolean should_wait_to_sleep (FpDeviceVirtualDevice *self,
const char *scan_id,
GError *error);
16 changes: 12 additions & 4 deletions libfprint/drivers/virtual-device-storage.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,14 @@ dev_identify (FpDevice *dev)
&idx))
match = g_ptr_array_index (prints, idx);

fpi_device_identify_report (dev,
match,
new_scan,
NULL);
if (!self->match_reported)
{
self->match_reported = TRUE;
fpi_device_identify_report (dev,
match,
new_scan,
NULL);
}
}
else if (error && error->domain == FP_DEVICE_RETRY)
{
Expand All @@ -83,6 +87,10 @@ dev_identify (FpDevice *dev)
FP_FINGER_STATUS_NONE,
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));
}

Expand Down
78 changes: 74 additions & 4 deletions libfprint/drivers/virtual-device.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ maybe_continue_current_action (FpDeviceVirtualDevice *self)
{
FpDevice *dev = FP_DEVICE (self);

if (self->sleep_timeout_id)
return;

switch (fpi_device_get_current_action (dev))
{
case FPI_DEVICE_ACTION_ENROLL:
Expand Down Expand Up @@ -365,6 +368,9 @@ start_scan_command (FpDeviceVirtualDevice *self,
g_autoptr(GError) local_error = 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);

if (!self->sleep_timeout_id)
Expand All @@ -376,6 +382,8 @@ start_scan_command (FpDeviceVirtualDevice *self,

if (should_wait_for_command (self, local_error))
{
g_assert (!scan_id);

g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PENDING,
"Still waiting for command");
return NULL;
Expand All @@ -391,6 +399,51 @@ start_scan_command (FpDeviceVirtualDevice *self,
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
dev_verify (FpDevice *dev)
{
Expand Down Expand Up @@ -422,10 +475,14 @@ dev_verify (FpDevice *dev)

success = fp_print_equal (print, new_scan);

fpi_device_verify_report (dev,
success ? FPI_MATCH_SUCCESS : FPI_MATCH_FAIL,
new_scan,
NULL);
if (!self->match_reported)
{
self->match_reported = TRUE;
fpi_device_verify_report (dev,
success ? FPI_MATCH_SUCCESS : FPI_MATCH_FAIL,
new_scan,
NULL);
}
}
else
{
Expand All @@ -439,6 +496,10 @@ dev_verify (FpDevice *dev)
if (error && error->domain == FP_DEVICE_RETRY)
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));
}

Expand Down Expand Up @@ -517,6 +578,9 @@ dev_enroll (FpDevice *dev)
}
else
{
if (should_wait_to_sleep (self, id, error))
return;

self->enroll_stages_passed = 0;
fpi_device_enroll_complete (dev, NULL, g_steal_pointer (&error));
}
Expand All @@ -528,6 +592,12 @@ dev_cancel (FpDevice *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)
return;

Expand Down
19 changes: 19 additions & 0 deletions tests/virtual-device.py
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,25 @@ def test_device_sleep_on_cancellation(self):
self.assertFalse(self._verify_completed)
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):

def tearDown(self):
Expand Down

0 comments on commit 7ffcc2f

Please sign in to comment.