libfprint/SOURCES/0087-image-device-Prevent-d...

104 lines
3.7 KiB
Diff

From 56126df4a2b5ecee1a9580e8d27f4d3d6f6925cd Mon Sep 17 00:00:00 2001
From: Benjamin Berg <bberg@redhat.com>
Date: Wed, 4 Dec 2019 15:50:06 +0100
Subject: [PATCH 087/181] image-device: Prevent deactivation when waiting for
finger
At the end of enroll, the image device would put the driver into the
AWAIT_FINGER_ON state and then deactivate the device afterwards. Doing
this adds additional complexity to drivers which would need to handle
both cancellation and normal deactivation from that state.
Only put the device into the AWAIT_FINGER_ON state when we know that
another enroll stage is needed. This avoids the critical state
transition simplifying the driver state machine.
Fixes: #203
Fixes: 689aff023253e4ca970c9f76f9e4209188175d3d
---
libfprint/fp-image-device.c | 31 ++++++++++++++++++++++++++++---
1 file changed, 28 insertions(+), 3 deletions(-)
diff --git a/libfprint/fp-image-device.c b/libfprint/fp-image-device.c
index e45b6a9..26c3cb0 100644
--- a/libfprint/fp-image-device.c
+++ b/libfprint/fp-image-device.c
@@ -51,6 +51,7 @@ typedef struct
FpImageDeviceState state;
gboolean active;
+ gboolean enroll_await_on_pending;
gint enroll_stage;
guint pending_activation_timeout_id;
@@ -256,6 +257,7 @@ fp_image_device_start_capture_action (FpDevice *device)
}
priv->enroll_stage = 0;
+ priv->enroll_await_on_pending = FALSE;
/* The device might still be deactivating from a previous call.
* In that situation, try to wait for a bit before reporting back an
@@ -385,6 +387,22 @@ fp_image_device_init (FpImageDevice *self)
}
+static void
+fp_image_device_enroll_maybe_await_finger_on (FpImageDevice *self)
+{
+ FpImageDevicePrivate *priv = fp_image_device_get_instance_private (self);
+
+ if (priv->enroll_await_on_pending)
+ {
+ priv->enroll_await_on_pending = FALSE;
+ fp_image_device_change_state (self, FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON);
+ }
+ else
+ {
+ priv->enroll_await_on_pending = TRUE;
+ }
+}
+
static void
fpi_image_device_minutiae_detected (GObject *source_object, GAsyncResult *res, gpointer user_data)
{
@@ -446,11 +464,16 @@ fpi_image_device_minutiae_detected (GObject *source_object, GAsyncResult *res, g
fpi_device_enroll_progress (device, priv->enroll_stage,
g_steal_pointer (&print), error);
+ /* Start another scan or deactivate. */
if (priv->enroll_stage == IMG_ENROLL_STAGES)
{
fpi_device_enroll_complete (device, g_object_ref (enroll_print), NULL);
fp_image_device_deactivate (device);
}
+ else
+ {
+ fp_image_device_enroll_maybe_await_finger_on (FP_IMAGE_DEVICE (device));
+ }
}
else if (action == FP_DEVICE_ACTION_VERIFY)
{
@@ -572,13 +595,15 @@ fpi_image_device_report_finger_status (FpImageDevice *self,
* 2. We are still deactivating the device after an action completed
* 3. We were waiting for finger removal to start the new action
* Either way, we always end up deactivating except for the enroll case.
- * XXX: This is not quite correct though, as we assume we need another finger
- * scan even though we might be processing the last one (successfully).
+ *
+ * The enroll case is special as AWAIT_FINGER_ON should only happen after
+ * minutiae detection to prevent deactivation (without cancellation)
+ * from the AWAIT_FINGER_ON state.
*/
if (action != FP_DEVICE_ACTION_ENROLL)
fp_image_device_deactivate (device);
else
- fp_image_device_change_state (self, FP_IMAGE_DEVICE_STATE_AWAIT_FINGER_ON);
+ fp_image_device_enroll_maybe_await_finger_on (self);
}
}
--
2.24.1