diff --git a/meson.build b/meson.build
index eee8584..6b63c01 100644
--- a/meson.build
+++ b/meson.build
@@ -64,7 +64,7 @@ add_project_arguments(common_cflags, language: 'c')
host_system = host_machine.system()
# NOTE: Bump gdbus-codegen min version once we can depend on 2.64!
glib_min_version = '2.56'
-libfprint_min_version = '1.90.1'
+libfprint_min_version = '1.90.4'
fprintd_installdir = get_option('prefix') / get_option('libexecdir')
fprintd_plugindir = get_option('prefix') / get_option('libdir') / meson.project_name() / 'modules'
diff --git a/src/device.c b/src/device.c
index 7dec9f8..537bd67 100644
--- a/src/device.c
+++ b/src/device.c
@@ -327,6 +327,24 @@ on_scan_type_changed (FprintDevice *rdev,
fprint_dbus_device_get_scan_type (dbus_dev));
}
+static void
+on_finger_status_changed (FprintDevice *rdev,
+ GParamSpec *spec,
+ FpDevice *device)
+{
+ FprintDBusDevice *dbus_dev = FPRINT_DBUS_DEVICE (rdev);
+ FpFingerStatusFlags finger_status = fp_device_get_finger_status (device);
+ gboolean present, needed;
+
+ present = !!(finger_status & FP_FINGER_STATUS_PRESENT);
+ fprint_dbus_device_set_finger_present (dbus_dev, present);
+ g_debug ("Finger present %d", present);
+
+ needed = !!(finger_status & FP_FINGER_STATUS_NEEDED);
+ fprint_dbus_device_set_finger_needed (dbus_dev, needed);
+ g_debug ("Finger needed %d", needed);
+}
+
static void
fprint_device_constructed (GObject *object)
{
@@ -346,6 +364,11 @@ fprint_device_constructed (GObject *object)
rdev, G_CONNECT_SWAPPED);
on_nr_enroll_stages_changed (rdev, NULL, priv->dev);
+ g_signal_connect_object (priv->dev, "notify::finger-status",
+ G_CALLBACK (on_finger_status_changed),
+ rdev, G_CONNECT_SWAPPED);
+ on_finger_status_changed (rdev, NULL, priv->dev);
+
G_OBJECT_CLASS (fprint_device_parent_class)->constructed (object);
}
diff --git a/src/device.xml b/src/device.xml
index 92af74d..df2521f 100644
--- a/src/device.xml
+++ b/src/device.xml
@@ -573,6 +573,30 @@
+
+
+
+
+
+
+ Whether the finger is on sensor.
+
+
+
+
+
+
+
+
+
+
+
+ Whether the sensor is waiting for the finger.
+
+
+
+
+
diff --git a/tests/fprintd.py b/tests/fprintd.py
index c898e06..16d8485 100755
--- a/tests/fprintd.py
+++ b/tests/fprintd.py
@@ -297,6 +297,14 @@ class FPrintdTest(dbusmock.DBusTestCase):
return self.assertRaisesRegex(GLib.Error,
'.*net\.reactivated\.Fprint\.Error\.{}.*'.format(fprint_error))
+ @property
+ def finger_needed(self):
+ return self.device.get_cached_property('finger-needed').unpack()
+
+ @property
+ def finger_present(self):
+ return self.device.get_cached_property('finger-present').unpack()
+
# From libfprint tests
def send_retry(self, retry_error=FPrint.DeviceRetry.TOO_SHORT, con=None):
if con:
@@ -350,7 +358,7 @@ class FPrintdTest(dbusmock.DBusTestCase):
with Connection(self.sockaddr) as con:
self.send_finger_automatic(automatic, con=con)
- def send_finger_report(self, has_finger, con=None):
+ def send_finger_report(self, has_finger, con=None, iterate=True):
# Send finger on/off
if con:
con.sendall(struct.pack('ii', -4, 1 if has_finger else 0))
@@ -359,6 +367,9 @@ class FPrintdTest(dbusmock.DBusTestCase):
with Connection(self.sockaddr) as con:
self.send_finger_report(has_finger, con=con)
+ while iterate and self.finger_present != has_finger:
+ ctx.iteration(False)
+
def call_device_method_async(self, method, *args):
""" add cancellable... """
self.device.call(method, GLib.Variant(*args),
@@ -444,11 +455,19 @@ class FPrintdVirtualDeviceBaseTest(FPrintdTest):
self._abort = True
self._last_result = 'Unexpected signal'
- self.g_signal_id = self.device.connect('g-signal', signal_cb)
+ def property_cb(proxy, changed, invalidated):
+ print('Changed properties', changed, 'invalidated', invalidated)
+ self._changed_properties.append(changed.unpack())
+
+ signal_id = self.device.connect('g-signal', signal_cb)
+ self.addCleanup(self.device.disconnect, signal_id)
+
+ signal_id = self.device.connect('g-properties-changed', property_cb)
+ self.addCleanup(self.device.disconnect, signal_id)
+ self._changed_properties = []
def tearDown(self):
self.polkitd_stop()
- self.device.disconnect(self.g_signal_id)
self.device = None
self.manager = None
@@ -470,6 +489,10 @@ class FPrintdVirtualDeviceBaseTest(FPrintdTest):
device = self.device
device.EnrollStart('(s)', finger)
+ while not self.finger_needed:
+ ctx.iteration(False)
+ self.assertTrue(self.finger_needed)
+
stages = device.get_cached_property('num-enroll-stages').unpack()
for stage in range(stages):
self.send_image(img)
@@ -477,9 +500,11 @@ class FPrintdVirtualDeviceBaseTest(FPrintdTest):
self.wait_for_result('enroll-stage-passed')
else:
self.wait_for_result(expected_result)
+ self.assertFalse(self.finger_needed)
device.EnrollStop()
self.assertEqual(self._last_result, expected_result)
+ self.assertFalse(self.finger_needed)
def enroll_multiple_images(self, images_override={}, return_index=-1):
enroll_map = {
@@ -781,6 +806,12 @@ class FPrintdVirtualDeviceTest(FPrintdVirtualDeviceBaseTest):
self.assertEqual(self.device.get_cached_property('scan-type').unpack(),
'swipe')
+ def test_initial_finger_needed(self):
+ self.assertFalse(self.finger_needed)
+
+ def test_initial_finger_needed(self):
+ self.assertFalse(self.finger_present)
+
def test_allowed_claim_release_enroll(self):
self._polkitd_obj.SetAllowed(['net.reactivated.fprint.device.setusername',
'net.reactivated.fprint.device.enroll'])
@@ -1108,6 +1139,12 @@ class FPrintdVirtualDeviceClaimedTest(FPrintdVirtualDeviceBaseTest):
# Finger is enrolled, try to verify it
self.device.VerifyStart('(s)', 'any')
+ while not self.finger_needed:
+ ctx.iteration(True)
+
+ self.assertTrue(self.finger_needed)
+ self.assertFalse(self.finger_present)
+
# Try a wrong print; will stop verification
self.send_image('tented_arch')
self.wait_for_result()
@@ -1406,6 +1443,90 @@ class FPrintdVirtualDeviceClaimedTest(FPrintdVirtualDeviceBaseTest):
with self.assertFprintError('AlreadyInUse'):
self.call_device_method_from_other_client('VerifyStart', ['left-thumb'])
+ def test_enroll_finger_status(self):
+ self.assertFalse(self.finger_present)
+ self.assertFalse(self.finger_needed)
+ self.device.EnrollStart('(s)', 'right-middle-finger')
+
+ self.assertEqual(self._changed_properties, [])
+
+ while not self.finger_needed:
+ ctx.iteration(False)
+
+ self.assertIn({'finger-needed': True}, self._changed_properties)
+
+ self.assertTrue(self.finger_needed)
+ self.assertFalse(self.finger_present)
+
+ self._changed_properties = []
+ self.send_finger_report(True)
+ self.assertEqual([{'finger-present': True}], self._changed_properties)
+ self.assertTrue(self.finger_needed)
+ self.assertTrue(self.finger_present)
+
+ self._changed_properties = []
+ self.send_finger_report(False)
+ self.assertFalse(self.finger_present)
+ self.assertTrue(self.finger_needed)
+ self.assertEqual([{'finger-present': False}], self._changed_properties)
+
+ self._changed_properties = []
+ self.device.EnrollStop()
+
+ while self.finger_needed:
+ ctx.iteration(False)
+
+ self.assertFalse(self.finger_present)
+ self.assertFalse(self.finger_needed)
+ self.assertEqual([{'finger-needed': False}], self._changed_properties)
+
+ def test_verify_finger_status(self):
+ self.assertFalse(self.finger_present)
+ self.assertFalse(self.finger_needed)
+ self.assertEqual(self._changed_properties, [])
+
+ self.enroll_image('whorl')
+
+ self.assertIn({'finger-needed': True}, self._changed_properties)
+ self.assertIn({'finger-needed': False}, self._changed_properties)
+
+ self.assertFalse(self.finger_present)
+ self.assertFalse(self.finger_needed)
+
+ self._changed_properties = []
+ self.device.VerifyStart('(s)', 'any')
+ self.assertEqual(self._changed_properties, [])
+
+ while not self.finger_needed:
+ ctx.iteration(False)
+
+ self.assertIn({'finger-needed': True}, self._changed_properties)
+
+ self.assertTrue(self.finger_needed)
+ self.assertFalse(self.finger_present)
+
+ self._changed_properties = []
+ self.send_finger_report(True)
+ self.assertEqual([{'finger-present': True}], self._changed_properties)
+ self.assertTrue(self.finger_needed)
+ self.assertTrue(self.finger_present)
+
+ self._changed_properties = []
+ self.send_finger_report(False)
+ self.assertFalse(self.finger_present)
+ self.assertTrue(self.finger_needed)
+ self.assertEqual([{'finger-present': False}], self._changed_properties)
+
+ self._changed_properties = []
+ self.device.VerifyStop()
+
+ while self.finger_needed:
+ ctx.iteration(False)
+
+ self.assertFalse(self.finger_present)
+ self.assertFalse(self.finger_needed)
+ self.assertEqual([{'finger-needed': False}], self._changed_properties)
+
class FPrintdVirtualDeviceEnrollTests(FPrintdVirtualDeviceBaseTest):