diff --git a/libfprint/fp-device-private.h b/libfprint/fp-device-private.h
index 5bf5954..c32cdf7 100644
--- a/libfprint/fp-device-private.h
+++ b/libfprint/fp-device-private.h
@@ -49,7 +49,8 @@ typedef struct
   GSource            *current_task_idle_return_source;
 
   /* State for tasks */
-  gboolean wait_for_finger;
+  gboolean            wait_for_finger;
+  FpFingerStatusFlags finger_status;
 } FpDevicePrivate;
 
 
diff --git a/libfprint/fp-device.c b/libfprint/fp-device.c
index 1e61447..c6fb7e3 100644
--- a/libfprint/fp-device.c
+++ b/libfprint/fp-device.c
@@ -46,6 +46,7 @@ enum {
   PROP_OPEN,
   PROP_NR_ENROLL_STAGES,
   PROP_SCAN_TYPE,
+  PROP_FINGER_STATUS,
   PROP_FPI_ENVIRON,
   PROP_FPI_USB_DEVICE,
   PROP_FPI_DRIVER_DATA,
@@ -181,6 +182,10 @@ fp_device_get_property (GObject    *object,
       g_value_set_enum (value, priv->scan_type);
       break;
 
+    case PROP_FINGER_STATUS:
+      g_value_set_enum (value, priv->finger_status);
+      break;
+
     case PROP_DRIVER:
       g_value_set_static_string (value, FP_DEVICE_GET_CLASS (priv)->id);
       break;
@@ -310,6 +315,13 @@ fp_device_class_init (FpDeviceClass *klass)
                        FP_TYPE_SCAN_TYPE, FP_SCAN_TYPE_SWIPE,
                        G_PARAM_STATIC_STRINGS | G_PARAM_READABLE);
 
+  properties[PROP_FINGER_STATUS] =
+    g_param_spec_flags ("finger-status",
+                        "FingerStatus",
+                        "The status of the finger",
+                        FP_TYPE_FINGER_STATUS_FLAGS, FP_FINGER_STATUS_NONE,
+                        G_PARAM_STATIC_STRINGS | G_PARAM_READABLE);
+
   properties[PROP_DRIVER] =
     g_param_spec_string ("driver",
                          "Driver",
@@ -469,6 +481,26 @@ fp_device_get_scan_type (FpDevice *device)
   return priv->scan_type;
 }
 
+/**
+ * fp_device_get_finger_status:
+ * @device: A #FpDevice
+ *
+ * Retrieves the finger status flags for the device.
+ * This can be used by the UI to present the relevant feedback, although it
+ * is not guaranteed to be a relevant value when not performing any action.
+ *
+ * Returns: The current #FpFingerStatusFlags
+ */
+FpFingerStatusFlags
+fp_device_get_finger_status (FpDevice *device)
+{
+  FpDevicePrivate *priv = fp_device_get_instance_private (device);
+
+  g_return_val_if_fail (FP_IS_DEVICE (device), FP_SCAN_TYPE_SWIPE);
+
+  return priv->finger_status;
+}
+
 /**
  * fp_device_get_nr_enroll_stages:
  * @device: A #FpDevice
diff --git a/libfprint/fp-device.h b/libfprint/fp-device.h
index 0be64ec..e1cb8a2 100644
--- a/libfprint/fp-device.h
+++ b/libfprint/fp-device.h
@@ -170,6 +170,7 @@ const gchar *fp_device_get_device_id (FpDevice *device);
 const gchar *fp_device_get_name (FpDevice *device);
 gboolean     fp_device_is_open (FpDevice *device);
 FpScanType   fp_device_get_scan_type (FpDevice *device);
+FpFingerStatusFlags fp_device_get_finger_status (FpDevice *device);
 gint         fp_device_get_nr_enroll_stages (FpDevice *device);
 
 gboolean     fp_device_supports_identify (FpDevice *device);
diff --git a/libfprint/fp-print.h b/libfprint/fp-print.h
index 3408e73..39cf87c 100644
--- a/libfprint/fp-print.h
+++ b/libfprint/fp-print.h
@@ -66,6 +66,18 @@ typedef enum {
   FP_FINGER_LAST = FP_FINGER_RIGHT_LITTLE,
 } FpFinger;
 
+/**
+ * FpFingerStatusFlags:
+ * @FP_FINGER_STATUS_NONE: Sensor has not the finger on it, nor requires it
+ * @FP_FINGER_STATUS_NEEDED: Sensor waits for the finger
+ * @FP_FINGER_STATUS_PRESENT: Sensor has the finger on it
+ */
+typedef enum {
+  FP_FINGER_STATUS_NONE    = 0,
+  FP_FINGER_STATUS_NEEDED  = 1 << 0,
+  FP_FINGER_STATUS_PRESENT = 1 << 1,
+} FpFingerStatusFlags;
+
 FpPrint *fp_print_new (FpDevice *device);
 
 FpPrint *fp_print_new_from_data (guchar *data,
diff --git a/libfprint/fpi-device.c b/libfprint/fpi-device.c
index e62ab19..d94ae67 100644
--- a/libfprint/fpi-device.c
+++ b/libfprint/fpi-device.c
@@ -1394,3 +1394,59 @@ fpi_device_identify_report (FpDevice *device,
   if (call_cb && data->match_cb)
     data->match_cb (device, data->match, data->print, data->match_data, data->error);
 }
+
+/**
+ * fpi_device_report_finger_status:
+ * @device: The #FpDevice
+ * @finger_status: The current #FpFingerStatusFlags to report
+ *
+ * Report the finger status for the @device.
+ * This can be used by UI to give a feedback
+ *
+ * Returns: %TRUE if changed
+ */
+gboolean
+fpi_device_report_finger_status (FpDevice           *device,
+                                 FpFingerStatusFlags finger_status)
+{
+  FpDevicePrivate *priv = fp_device_get_instance_private (device);
+  g_autofree char *status_string = NULL;
+
+  if (priv->finger_status == finger_status)
+    return FALSE;
+
+  status_string = g_flags_to_string (FP_TYPE_FINGER_STATUS_FLAGS, finger_status);
+  fp_dbg ("Device reported finger status change: %s", status_string);
+
+  priv->finger_status = finger_status;
+  g_object_notify (G_OBJECT (device), "finger-status");
+
+  return TRUE;
+}
+
+/**
+ * fpi_device_report_finger_status_changes:
+ * @device: The #FpDevice
+ * @added_status: The #FpFingerStatusFlags to add
+ * @added_status: The #FpFingerStatusFlags to remove
+ *
+ * Report the finger status for the @device adding the @added_status flags
+ * and removing the @removed_status flags.
+ *
+ * This can be used by UI to give a feedback
+ *
+ * Returns: %TRUE if changed
+ */
+gboolean
+fpi_device_report_finger_status_changes (FpDevice           *device,
+                                         FpFingerStatusFlags added_status,
+                                         FpFingerStatusFlags removed_status)
+{
+  FpDevicePrivate *priv = fp_device_get_instance_private (device);
+  FpFingerStatusFlags finger_status = priv->finger_status;
+
+  finger_status |= added_status;
+  finger_status &= ~removed_status;
+
+  return fpi_device_report_finger_status (device, finger_status);
+}
diff --git a/libfprint/fpi-device.h b/libfprint/fpi-device.h
index 94cdb35..2bab022 100644
--- a/libfprint/fpi-device.h
+++ b/libfprint/fpi-device.h
@@ -255,4 +255,10 @@ void fpi_device_identify_report (FpDevice *device,
                                  FpPrint  *print,
                                  GError   *error);
 
+gboolean fpi_device_report_finger_status (FpDevice           *device,
+                                          FpFingerStatusFlags finger_status);
+gboolean fpi_device_report_finger_status_changes (FpDevice           *device,
+                                                  FpFingerStatusFlags added_status,
+                                                  FpFingerStatusFlags removed_status);
+
 G_END_DECLS
diff --git a/tests/test-fp-device.c b/tests/test-fp-device.c
index a279b46..e3eb662 100644
--- a/tests/test-fp-device.c
+++ b/tests/test-fp-device.c
@@ -178,6 +178,15 @@ test_device_get_scan_type (void)
   g_assert_cmpint (fp_device_get_scan_type (tctx->device), ==, FP_SCAN_TYPE_SWIPE);
 }
 
+static void
+test_device_get_finger_status (void)
+{
+  g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_imgdev ();
+
+  fp_device_open_sync (tctx->device, NULL, NULL);
+  g_assert_cmpint (fp_device_get_finger_status (tctx->device), ==, FP_FINGER_STATUS_NONE);
+}
+
 static void
 test_device_get_nr_enroll_stages (void)
 {
@@ -229,6 +238,7 @@ main (int argc, char *argv[])
   g_test_add_func ("/device/sync/get_device_id", test_device_get_device_id);
   g_test_add_func ("/device/sync/get_name", test_device_get_name);
   g_test_add_func ("/device/sync/get_scan_type", test_device_get_scan_type);
+  g_test_add_func ("/device/sync/get_finger_status", test_device_get_finger_status);
   g_test_add_func ("/device/sync/get_nr_enroll_stages", test_device_get_nr_enroll_stages);
   g_test_add_func ("/device/sync/supports_identify", test_device_supports_identify);
   g_test_add_func ("/device/sync/supports_capture", test_device_supports_capture);
diff --git a/tests/test-fpi-device.c b/tests/test-fpi-device.c
index d415258..2b6b256 100644
--- a/tests/test-fpi-device.c
+++ b/tests/test-fpi-device.c
@@ -200,6 +200,147 @@ test_driver_set_scan_type_swipe (void)
   g_assert_cmpstr (pspec->name, ==, "scan-type");
 }
 
+static void
+test_driver_finger_status_inactive (void)
+{
+  g_autoptr(FpDevice) device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
+  FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
+
+  g_signal_connect (device, "notify::finger-status", G_CALLBACK (on_device_notify), NULL);
+
+  g_assert_false (fpi_device_report_finger_status (device, FP_FINGER_STATUS_NONE));
+  g_assert_cmpuint (fp_device_get_finger_status (device), ==, FP_FINGER_STATUS_NONE);
+  g_assert (fake_dev->last_called_function != on_device_notify);
+  g_assert_null (g_steal_pointer (&fake_dev->user_data));
+}
+
+static void
+test_driver_finger_status_needed (void)
+{
+  g_autoptr(FpDevice) device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
+  g_autoptr(GParamSpec) pspec = NULL;
+  FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
+
+  g_signal_connect (device, "notify::finger-status", G_CALLBACK (on_device_notify), NULL);
+
+  g_assert_true (fpi_device_report_finger_status (device, FP_FINGER_STATUS_NEEDED));
+  g_assert_cmpuint (fp_device_get_finger_status (device), ==, FP_FINGER_STATUS_NEEDED);
+
+  g_assert (fake_dev->last_called_function == on_device_notify);
+  pspec = g_steal_pointer (&fake_dev->user_data);
+  g_assert_cmpstr (pspec->name, ==, "finger-status");
+
+  fake_dev->last_called_function = NULL;
+  g_assert_false (fpi_device_report_finger_status (device, FP_FINGER_STATUS_NEEDED));
+  g_assert_null (fake_dev->last_called_function);
+  g_assert_null (g_steal_pointer (&fake_dev->user_data));
+}
+
+static void
+test_driver_finger_status_present (void)
+{
+  g_autoptr(FpDevice) device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
+  g_autoptr(GParamSpec) pspec = NULL;
+  FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
+
+  g_signal_connect (device, "notify::finger-status", G_CALLBACK (on_device_notify), NULL);
+
+  g_assert_true (fpi_device_report_finger_status (device, FP_FINGER_STATUS_PRESENT));
+  g_assert_cmpuint (fp_device_get_finger_status (device), ==, FP_FINGER_STATUS_PRESENT);
+
+  g_assert (fake_dev->last_called_function == on_device_notify);
+  pspec = g_steal_pointer (&fake_dev->user_data);
+  g_assert_cmpstr (pspec->name, ==, "finger-status");
+
+  fake_dev->last_called_function = NULL;
+  g_assert_false (fpi_device_report_finger_status (device, FP_FINGER_STATUS_PRESENT));
+  g_assert_null (fake_dev->last_called_function);
+  g_assert_null (g_steal_pointer (&fake_dev->user_data));
+}
+
+static void
+driver_finger_status_changes_check (FpDevice *device, gboolean add)
+{
+  FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
+
+  g_autoptr(GFlagsClass) status_class = g_type_class_ref (FP_TYPE_FINGER_STATUS_FLAGS);
+  guint expected_status;
+  guint initial_value;
+  guint i;
+  gulong signal_id;
+
+  if (add)
+    initial_value = FP_FINGER_STATUS_NONE;
+  else
+    initial_value = status_class->mask;
+
+  g_assert_cmpuint (fp_device_get_finger_status (device), ==, initial_value);
+
+  signal_id = g_signal_connect (device, "notify::finger-status",
+                                G_CALLBACK (on_device_notify), NULL);
+
+  for (i = 0, expected_status = initial_value; i < status_class->n_values; ++i)
+    {
+      g_autoptr(GParamSpec) pspec = NULL;
+      FpFingerStatusFlags finger_status = status_class->values[i].value;
+      FpFingerStatusFlags added_status = add ? finger_status : FP_FINGER_STATUS_NONE;
+      FpFingerStatusFlags removed_status = add ? FP_FINGER_STATUS_NONE : finger_status;
+      gboolean ret;
+
+      fake_dev->last_called_function = NULL;
+      ret = fpi_device_report_finger_status_changes (device,
+                                                     added_status,
+                                                     removed_status);
+      if (finger_status != FP_FINGER_STATUS_NONE)
+        g_assert_true (ret);
+      else
+        g_assert_false (ret);
+
+      expected_status |= added_status;
+      expected_status &= ~removed_status;
+
+      g_assert_cmpuint (fp_device_get_finger_status (device), ==, expected_status);
+
+      if (finger_status != FP_FINGER_STATUS_NONE)
+        {
+          g_assert (fake_dev->last_called_function == on_device_notify);
+          pspec = g_steal_pointer (&fake_dev->user_data);
+          g_assert_cmpstr (pspec->name, ==, "finger-status");
+        }
+
+      fake_dev->last_called_function = NULL;
+      g_assert_false (fpi_device_report_finger_status_changes (device,
+                                                               added_status,
+                                                               removed_status));
+      g_assert_null (fake_dev->last_called_function);
+      g_assert_null (g_steal_pointer (&fake_dev->user_data));
+    }
+
+  if (add)
+    g_assert_cmpuint (fp_device_get_finger_status (device), ==, status_class->mask);
+  else
+    g_assert_cmpuint (fp_device_get_finger_status (device), ==, FP_FINGER_STATUS_NONE);
+
+  fake_dev->last_called_function = NULL;
+  g_assert_false (fpi_device_report_finger_status_changes (device,
+                                                           FP_FINGER_STATUS_NONE,
+                                                           FP_FINGER_STATUS_NONE));
+
+  g_assert_null (fake_dev->last_called_function);
+  g_assert_null (g_steal_pointer (&fake_dev->user_data));
+
+  g_signal_handler_disconnect (device, signal_id);
+}
+
+static void
+test_driver_finger_status_changes (void)
+{
+  g_autoptr(FpDevice) device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
+
+  driver_finger_status_changes_check (device, TRUE);
+  driver_finger_status_changes_check (device, FALSE);
+}
+
 static void
 test_driver_get_nr_enroll_stages (void)
 {
@@ -2207,6 +2348,10 @@ main (int argc, char *argv[])
   g_test_add_func ("/driver/get_scan_type/swipe", test_driver_get_scan_type_swipe);
   g_test_add_func ("/driver/set_scan_type/press", test_driver_set_scan_type_press);
   g_test_add_func ("/driver/set_scan_type/swipe", test_driver_set_scan_type_swipe);
+  g_test_add_func ("/driver/finger_status/inactive", test_driver_finger_status_inactive);
+  g_test_add_func ("/driver/finger_status/waiting", test_driver_finger_status_needed);
+  g_test_add_func ("/driver/finger_status/present", test_driver_finger_status_present);
+  g_test_add_func ("/driver/finger_status/changes", test_driver_finger_status_changes);
   g_test_add_func ("/driver/get_nr_enroll_stages", test_driver_get_nr_enroll_stages);
   g_test_add_func ("/driver/set_nr_enroll_stages", test_driver_set_nr_enroll_stages);
   g_test_add_func ("/driver/supports_identify", test_driver_supports_identify);