Blob Blame History Raw
From c16f8101e29dd93e846c90574b68677c8e9ab0b6 Mon Sep 17 00:00:00 2001
From: Benjamin Berg <bberg@redhat.com>
Date: Wed, 15 Jan 2020 14:48:06 +0100
Subject: [PATCH 177/181] image-device: Avoid invalid state transition on
 cancellation

Fixes: #226
---
 libfprint/drivers/elan.c     |  2 --
 libfprint/fpi-image-device.c | 18 +++++++++++++++---
 2 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/libfprint/drivers/elan.c b/libfprint/drivers/elan.c
index 1c2a7a3..084e4bd 100644
--- a/libfprint/drivers/elan.c
+++ b/libfprint/drivers/elan.c
@@ -585,8 +585,6 @@ capture_complete (FpiSsm *ssm, FpDevice *_dev, GError *error)
 
   G_DEBUG_HERE ();
 
-  /* XXX: cancellation was specially handled by doing nothing! */
-
   /* either max frames captured or timed out waiting for the next frame */
   if (!error ||
       (g_error_matches (error, G_USB_DEVICE_ERROR, G_USB_DEVICE_ERROR_TIMED_OUT) &&
diff --git a/libfprint/fpi-image-device.c b/libfprint/fpi-image-device.c
index 888c931..b5747f6 100644
--- a/libfprint/fpi-image-device.c
+++ b/libfprint/fpi-image-device.c
@@ -428,7 +428,9 @@ fpi_image_device_retry_scan (FpImageDevice *self, FpDeviceRetry retry)
  * @error: The #GError to report
  *
  * Report an error while interacting with the device. This effectively
- * aborts the current ongoing action.
+ * aborts the current ongoing action. Note that doing so will result in
+ * the deactivation handler to be called and this function must not be
+ * used to report an error during deactivation.
  */
 void
 fpi_image_device_session_error (FpImageDevice *self, GError *error)
@@ -455,10 +457,20 @@ fpi_image_device_session_error (FpImageDevice *self, GError *error)
           return;
         }
     }
+  else if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) &&
+           fpi_device_action_is_cancelled (FP_DEVICE (self)))
+    {
+      /* Ignore cancellation errors here, as we will explicitly deactivate
+       * anyway (or, may already have done so at this point).
+       */
+      g_debug ("Driver reported a cancellation error, this is expected but not required. Ignoring.");
+      g_clear_error (&error);
+      return;
+    }
   else if (priv->state == FPI_IMAGE_DEVICE_STATE_INACTIVE)
     {
-      g_warning ("Driver reported session error; translating to deactivation failure.");
-      fpi_image_device_deactivate_complete (self, error);
+      g_warning ("Driver reported session error while deactivating already, ignoring. This indicates a driver bug.");
+      g_clear_error (&error);
       return;
     }
 
-- 
2.24.1