From ef805f2341dd8559ec93f65132fd744b213faead Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Fri, 9 Apr 2021 21:31:43 +0200 Subject: [PATCH] device: Expose supported features publicly as FpDeviceFeature It can be convenient for device users to check what it supports, without having multiple functions to check each single feature. So expose this and add tests. --- doc/libfprint-2-sections.txt | 4 +- libfprint/drivers/goodixmoc/goodix.c | 2 +- libfprint/drivers/virtual-device-storage.c | 2 +- libfprint/fp-device.c | 52 +++- libfprint/fp-device.h | 28 +++ libfprint/fpi-device.c | 14 +- libfprint/fpi-device.h | 26 +- tests/capture.py | 8 + tests/goodixmoc/custom.py | 8 + tests/synaptics/custom.py | 8 + tests/test-fp-device.c | 3 + tests/test-fpi-device.c | 270 ++++++++++++++------- tests/virtual-device.py | 20 ++ tests/virtual-image.py | 14 ++ 14 files changed, 330 insertions(+), 129 deletions(-) diff --git a/doc/libfprint-2-sections.txt b/doc/libfprint-2-sections.txt index 998ea2e..3d67686 100644 --- a/doc/libfprint-2-sections.txt +++ b/doc/libfprint-2-sections.txt @@ -20,6 +20,7 @@ FP_TYPE_DEVICE FP_DEVICE_RETRY FP_DEVICE_ERROR FpDeviceType +FpDeviceFeature FpScanType FpDeviceRetry FpDeviceError @@ -33,6 +34,8 @@ fp_device_get_name fp_device_get_scan_type fp_device_get_nr_enroll_stages fp_device_get_finger_status +fp_device_get_features +fp_device_has_feature fp_device_has_storage fp_device_supports_identify fp_device_supports_capture @@ -131,7 +134,6 @@ fpi_get_driver_types FpDeviceClass FpTimeoutFunc FpiDeviceAction -FpiDeviceFeature FpIdEntry FpiDeviceUdevSubtypeFlags fpi_device_get_usb_device diff --git a/libfprint/drivers/goodixmoc/goodix.c b/libfprint/drivers/goodixmoc/goodix.c index b57ee3c..3f29642 100644 --- a/libfprint/drivers/goodixmoc/goodix.c +++ b/libfprint/drivers/goodixmoc/goodix.c @@ -1581,5 +1581,5 @@ fpi_device_goodixmoc_class_init (FpiDeviceGoodixMocClass *klass) dev_class->identify = gx_fp_verify_identify; fpi_device_class_auto_initialize_features (dev_class); - dev_class->features |= FPI_DEVICE_FEATURE_DUPLICATES_CHECK; + dev_class->features |= FP_DEVICE_FEATURE_DUPLICATES_CHECK; } diff --git a/libfprint/drivers/virtual-device-storage.c b/libfprint/drivers/virtual-device-storage.c index 9591dcc..cc67d8c 100644 --- a/libfprint/drivers/virtual-device-storage.c +++ b/libfprint/drivers/virtual-device-storage.c @@ -246,5 +246,5 @@ fpi_device_virtual_device_storage_class_init (FpDeviceVirtualDeviceStorageClass dev_class->delete = dev_delete; fpi_device_class_auto_initialize_features (dev_class); - dev_class->features |= FPI_DEVICE_FEATURE_DUPLICATES_CHECK; + dev_class->features |= FP_DEVICE_FEATURE_DUPLICATES_CHECK; } diff --git a/libfprint/fp-device.c b/libfprint/fp-device.c index c2101a6..5027e03 100644 --- a/libfprint/fp-device.c +++ b/libfprint/fp-device.c @@ -140,7 +140,7 @@ fp_device_constructed (GObject *object) FpDeviceClass *cls = FP_DEVICE_GET_CLASS (self); FpDevicePrivate *priv = fp_device_get_instance_private (self); - g_assert (cls->features != FPI_DEVICE_FEATURE_NONE); + g_assert (cls->features != FP_DEVICE_FEATURE_NONE); priv->type = cls->type; if (cls->nr_enroll_stages) @@ -629,7 +629,7 @@ fp_device_supports_identify (FpDevice *device) g_return_val_if_fail (FP_IS_DEVICE (device), FALSE); - return cls->identify && !!(cls->features & FPI_DEVICE_FEATURE_IDENTIFY); + return cls->identify && !!(cls->features & FP_DEVICE_FEATURE_IDENTIFY); } /** @@ -647,7 +647,7 @@ fp_device_supports_capture (FpDevice *device) g_return_val_if_fail (FP_IS_DEVICE (device), FALSE); - return cls->capture && !!(cls->features & FPI_DEVICE_FEATURE_CAPTURE); + return cls->capture && !!(cls->features & FP_DEVICE_FEATURE_CAPTURE); } /** @@ -666,7 +666,7 @@ fp_device_has_storage (FpDevice *device) g_return_val_if_fail (FP_IS_DEVICE (device), FALSE); - return !!(cls->features & FPI_DEVICE_FEATURE_STORAGE); + return !!(cls->features & FP_DEVICE_FEATURE_STORAGE); } /** @@ -976,7 +976,7 @@ fp_device_verify (FpDevice *device, return; } - if (!cls->verify || !(cls->features & FPI_DEVICE_FEATURE_VERIFY)) + if (!cls->verify || !(cls->features & FP_DEVICE_FEATURE_VERIFY)) { g_task_return_error (task, fpi_device_error_new_msg (FP_DEVICE_ERROR_NOT_SUPPORTED, @@ -1211,7 +1211,7 @@ fp_device_capture (FpDevice *device, return; } - if (!cls->capture || !(cls->features & FPI_DEVICE_FEATURE_CAPTURE)) + if (!cls->capture || !(cls->features & FP_DEVICE_FEATURE_CAPTURE)) { g_task_return_error (task, fpi_device_error_new_msg (FP_DEVICE_ERROR_NOT_SUPPORTED, @@ -1295,7 +1295,7 @@ fp_device_delete_print (FpDevice *device, } /* Succeed immediately if delete is not implemented. */ - if (!cls->delete || !(cls->features & FPI_DEVICE_FEATURE_STORAGE_DELETE)) + if (!cls->delete || !(cls->features & FP_DEVICE_FEATURE_STORAGE_DELETE)) { g_task_return_boolean (task, TRUE); return; @@ -1672,3 +1672,41 @@ fp_device_list_prints_sync (FpDevice *device, return fp_device_list_prints_finish (device, task, error); } + +/** + * fp_device_get_features: + * @device: a #FpDevice + * + * Gets the #FpDeviceFeature's supported by the @device. + * + * Returns: #FpDeviceFeature flags of supported features + */ +FpDeviceFeature +fp_device_get_features (FpDevice *device) +{ + g_return_val_if_fail (FP_IS_DEVICE (device), FP_DEVICE_FEATURE_NONE); + + return FP_DEVICE_GET_CLASS (device)->features; +} + +/** + * fp_device_has_feature: + * @device: a #FpDevice + * @feature: #FpDeviceFeature flags to check against device supported features + * + * Checks if @device supports the requested #FpDeviceFeature's. + * See fp_device_get_features() + * + * Returns: %TRUE if supported, %FALSE otherwise + */ +gboolean +fp_device_has_feature (FpDevice *device, + FpDeviceFeature feature) +{ + g_return_val_if_fail (FP_IS_DEVICE (device), FALSE); + + if (feature == FP_DEVICE_FEATURE_NONE) + return fp_device_get_features (device) == feature; + + return (fp_device_get_features (device) & feature) == feature; +} diff --git a/libfprint/fp-device.h b/libfprint/fp-device.h index 806ad19..2b35894 100644 --- a/libfprint/fp-device.h +++ b/libfprint/fp-device.h @@ -47,6 +47,30 @@ typedef enum { FP_DEVICE_TYPE_USB, } FpDeviceType; +/** + * FpDeviceFeature: + * @FP_DEVICE_FEATURE_NONE: Device does not support any feature + * @FP_DEVICE_FEATURE_CAPTURE: Supports image capture + * @FP_DEVICE_FEATURE_VERIFY: Supports finger verification + * @FP_DEVICE_FEATURE_IDENTIFY: Supports finger identification + * @FP_DEVICE_FEATURE_STORAGE: Device has a persistent storage + * @FP_DEVICE_FEATURE_STORAGE_LIST: Supports listing the storage templates + * @FP_DEVICE_FEATURE_STORAGE_DELETE: Supports deleting stored templates + * @FP_DEVICE_FEATURE_STORAGE_CLEAR: Supports clearing the whole storage + * @FP_DEVICE_FEATURE_DUPLICATES_CHECK: Natively supports duplicates detection + */ +typedef enum /*< flags >*/ { + FP_DEVICE_FEATURE_NONE = 0, + FP_DEVICE_FEATURE_CAPTURE = 1 << 0, + FP_DEVICE_FEATURE_IDENTIFY = 1 << 1, + FP_DEVICE_FEATURE_VERIFY = 1 << 2, + FP_DEVICE_FEATURE_STORAGE = 1 << 3, + FP_DEVICE_FEATURE_STORAGE_LIST = 1 << 4, + FP_DEVICE_FEATURE_STORAGE_DELETE = 1 << 5, + FP_DEVICE_FEATURE_STORAGE_CLEAR = 1 << 6, + FP_DEVICE_FEATURE_DUPLICATES_CHECK = 1 << 7, +} FpDeviceFeature; + /** * FpScanType: * @FP_SCAN_TYPE_SWIPE: Sensor requires swiping the finger. @@ -178,6 +202,10 @@ 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); +FpDeviceFeature fp_device_get_features (FpDevice *device); +gboolean fp_device_has_feature (FpDevice *device, + FpDeviceFeature feature); + gboolean fp_device_supports_identify (FpDevice *device); gboolean fp_device_supports_capture (FpDevice *device); gboolean fp_device_has_storage (FpDevice *device); diff --git a/libfprint/fpi-device.c b/libfprint/fpi-device.c index f6da050..2cd0637 100644 --- a/libfprint/fpi-device.c +++ b/libfprint/fpi-device.c @@ -59,24 +59,24 @@ fpi_device_class_auto_initialize_features (FpDeviceClass *device_class) g_return_if_fail (FP_IS_DEVICE_CLASS (device_class)); if (device_class->capture) - device_class->features |= FPI_DEVICE_FEATURE_CAPTURE; + device_class->features |= FP_DEVICE_FEATURE_CAPTURE; if (device_class->verify) - device_class->features |= FPI_DEVICE_FEATURE_VERIFY; + device_class->features |= FP_DEVICE_FEATURE_VERIFY; if (device_class->identify) - device_class->features |= FPI_DEVICE_FEATURE_IDENTIFY; + device_class->features |= FP_DEVICE_FEATURE_IDENTIFY; if (device_class->list) { - device_class->features |= FPI_DEVICE_FEATURE_STORAGE; - device_class->features |= FPI_DEVICE_FEATURE_STORAGE_LIST; + device_class->features |= FP_DEVICE_FEATURE_STORAGE; + device_class->features |= FP_DEVICE_FEATURE_STORAGE_LIST; } if (device_class->delete) { - device_class->features |= FPI_DEVICE_FEATURE_STORAGE; - device_class->features |= FPI_DEVICE_FEATURE_STORAGE_DELETE; + device_class->features |= FP_DEVICE_FEATURE_STORAGE; + device_class->features |= FP_DEVICE_FEATURE_STORAGE_DELETE; } } diff --git a/libfprint/fpi-device.h b/libfprint/fpi-device.h index 38a4574..f669d29 100644 --- a/libfprint/fpi-device.h +++ b/libfprint/fpi-device.h @@ -69,30 +69,6 @@ struct _FpIdEntry guint64 driver_data; }; -/** - * FpiDeviceFeature: - * @FPI_DEVICE_FEATURE_NONE: Device does not support any feature - * @FPI_DEVICE_FEATURE_CAPTURE: Supports image capture - * @FPI_DEVICE_FEATURE_IDENTIFY: Supports finger identification - * @FPI_DEVICE_FEATURE_VERIFY: Supports finger verification - * @FPI_DEVICE_FEATURE_STORAGE: Device has a persistent storage - * @FPI_DEVICE_FEATURE_STORAGE_LIST: Supports listing the storage templates - * @FPI_DEVICE_FEATURE_STORAGE_DELETE: Supports deleting stored templates - * @FPI_DEVICE_FEATURE_STORAGE_CLEAR: Supports clearing the whole storage - * @FPI_DEVICE_FEATURE_DUPLICATES_CHECK: Natively supports duplicates detection - */ -typedef enum /*< flags >*/ { - FPI_DEVICE_FEATURE_NONE = 0, - FPI_DEVICE_FEATURE_CAPTURE = 1 << 0, - FPI_DEVICE_FEATURE_IDENTIFY = 1 << 1, - FPI_DEVICE_FEATURE_VERIFY = 1 << 2, - FPI_DEVICE_FEATURE_STORAGE = 1 << 3, - FPI_DEVICE_FEATURE_STORAGE_LIST = 1 << 4, - FPI_DEVICE_FEATURE_STORAGE_DELETE = 1 << 5, - FPI_DEVICE_FEATURE_STORAGE_CLEAR = 1 << 6, - FPI_DEVICE_FEATURE_DUPLICATES_CHECK = 1 << 7, -} FpiDeviceFeature; - /** * FpDeviceClass: * @id: ID string for the driver. Should be a valid C identifier and should @@ -159,7 +135,7 @@ struct _FpDeviceClass const gchar *full_name; FpDeviceType type; const FpIdEntry *id_table; - FpiDeviceFeature features; + FpDeviceFeature features; /* Defaults for device properties */ gint nr_enroll_stages; diff --git a/tests/capture.py b/tests/capture.py index 88ed81f..c25afbf 100755 --- a/tests/capture.py +++ b/tests/capture.py @@ -17,6 +17,14 @@ c.enumerate() devices = c.get_devices() d = devices[0] +assert d.has_feature(FPrint.DeviceFeature.CAPTURE) +assert d.has_feature(FPrint.DeviceFeature.IDENTIFY) +assert d.has_feature(FPrint.DeviceFeature.VERIFY) +assert not d.has_feature(FPrint.DeviceFeature.DUPLICATES_CHECK) +assert not d.has_feature(FPrint.DeviceFeature.STORAGE) +assert not d.has_feature(FPrint.DeviceFeature.STORAGE_LIST) +assert not d.has_feature(FPrint.DeviceFeature.STORAGE_DELETE) +assert not d.has_feature(FPrint.DeviceFeature.STORAGE_CLEAR) del devices d.open_sync() diff --git a/tests/goodixmoc/custom.py b/tests/goodixmoc/custom.py index 17f3562..2fe6edd 100755 --- a/tests/goodixmoc/custom.py +++ b/tests/goodixmoc/custom.py @@ -14,6 +14,14 @@ d = devices[0] del devices assert d.get_driver() == "goodixmoc" +assert not d.has_feature(FPrint.DeviceFeature.CAPTURE) +assert d.has_feature(FPrint.DeviceFeature.IDENTIFY) +assert d.has_feature(FPrint.DeviceFeature.VERIFY) +assert d.has_feature(FPrint.DeviceFeature.DUPLICATES_CHECK) +assert d.has_feature(FPrint.DeviceFeature.STORAGE) +assert d.has_feature(FPrint.DeviceFeature.STORAGE_LIST) +assert d.has_feature(FPrint.DeviceFeature.STORAGE_DELETE) +assert not d.has_feature(FPrint.DeviceFeature.STORAGE_CLEAR) d.open_sync() diff --git a/tests/synaptics/custom.py b/tests/synaptics/custom.py index a1d0352..325f53d 100755 --- a/tests/synaptics/custom.py +++ b/tests/synaptics/custom.py @@ -14,6 +14,14 @@ d = devices[0] del devices assert d.get_driver() == "synaptics" +assert not d.has_feature(FPrint.DeviceFeature.CAPTURE) +assert d.has_feature(FPrint.DeviceFeature.IDENTIFY) +assert d.has_feature(FPrint.DeviceFeature.VERIFY) +assert not d.has_feature(FPrint.DeviceFeature.DUPLICATES_CHECK) +assert d.has_feature(FPrint.DeviceFeature.STORAGE) +assert d.has_feature(FPrint.DeviceFeature.STORAGE_LIST) +assert d.has_feature(FPrint.DeviceFeature.STORAGE_DELETE) +assert not d.has_feature(FPrint.DeviceFeature.STORAGE_CLEAR) d.open_sync() diff --git a/tests/test-fp-device.c b/tests/test-fp-device.c index b8f6f17..a473092 100644 --- a/tests/test-fp-device.c +++ b/tests/test-fp-device.c @@ -202,6 +202,7 @@ test_device_supports_identify (void) g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE); fp_device_open_sync (tctx->device, NULL, NULL); + g_assert_true (fp_device_has_feature (tctx->device, FP_DEVICE_FEATURE_IDENTIFY)); g_assert_true (fp_device_supports_identify (tctx->device)); } @@ -211,6 +212,7 @@ test_device_supports_capture (void) g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE); fp_device_open_sync (tctx->device, NULL, NULL); + g_assert_true (fp_device_has_feature (tctx->device, FP_DEVICE_FEATURE_CAPTURE)); g_assert_true (fp_device_supports_capture (tctx->device)); } @@ -220,6 +222,7 @@ test_device_has_storage (void) g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE); fp_device_open_sync (tctx->device, NULL, NULL); + g_assert_false (fp_device_has_feature (tctx->device, FP_DEVICE_FEATURE_STORAGE)); g_assert_false (fp_device_has_storage (tctx->device)); } diff --git a/tests/test-fpi-device.c b/tests/test-fpi-device.c index 7f2b21f..5a5ee96 100644 --- a/tests/test-fpi-device.c +++ b/tests/test-fpi-device.c @@ -17,6 +17,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "fp-device.h" +#include "fp-enums.h" #include #define FP_COMPONENT "device" @@ -506,21 +508,103 @@ test_driver_get_driver_data (void) g_assert_cmpuint (fpi_device_get_driver_data (device), ==, driver_data); } +static void +driver_feature_changes_check (FpDevice *device, gboolean add) +{ + g_autoptr(GFlagsClass) features_class = g_type_class_ref (FP_TYPE_DEVICE_FEATURE); + FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device); + guint expected_features; + guint initial_value; + guint i; + + if (add) + initial_value = FP_DEVICE_FEATURE_NONE; + else + initial_value = features_class->mask; + + g_assert_cmpuint (fp_device_get_features (device), ==, initial_value); + + for (i = 0, expected_features = initial_value; i < features_class->n_values; ++i) + { + FpDeviceFeature feature = features_class->values[i].value; + FpDeviceFeature added_feature = add ? feature : FP_DEVICE_FEATURE_NONE; + FpDeviceFeature removed_feature = add ? FP_DEVICE_FEATURE_NONE : feature; + + dev_class->features |= added_feature; + dev_class->features &= ~removed_feature; + + expected_features |= added_feature; + expected_features &= ~removed_feature; + + g_assert_cmpuint (fp_device_get_features (device), ==, expected_features); + + if (added_feature != FP_DEVICE_FEATURE_NONE) + g_assert_true (fp_device_has_feature (device, added_feature)); + else if (dev_class->features != FP_DEVICE_FEATURE_NONE) + g_assert_false (fp_device_has_feature (device, added_feature)); + else + g_assert_true (fp_device_has_feature (device, added_feature)); + + if (removed_feature != FP_DEVICE_FEATURE_NONE) + g_assert_false (fp_device_has_feature (device, removed_feature)); + else if (dev_class->features != FP_DEVICE_FEATURE_NONE) + g_assert_false (fp_device_has_feature (device, removed_feature)); + else + g_assert_true (fp_device_has_feature (device, removed_feature)); + + g_assert_true (fp_device_has_feature (device, expected_features)); + } + + if (add) + g_assert_cmpuint (fp_device_get_features (device), ==, features_class->mask); + else + g_assert_cmpuint (fp_device_get_features (device), ==, FP_DEVICE_FEATURE_NONE); +} + +static void +test_driver_features (void) +{ + g_autoptr(FpDevice) device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL); + g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class (); + + dev_class->features = FP_DEVICE_FEATURE_NONE; + driver_feature_changes_check (device, TRUE); + driver_feature_changes_check (device, FALSE); +} + static void test_driver_initial_features (void) { g_autoptr(FpDevice) device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL); FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device); - g_assert_cmpuint (dev_class->features, !=, FPI_DEVICE_FEATURE_NONE); - g_assert_true (dev_class->features & FPI_DEVICE_FEATURE_CAPTURE); - g_assert_true (dev_class->features & FPI_DEVICE_FEATURE_IDENTIFY); - g_assert_true (dev_class->features & FPI_DEVICE_FEATURE_VERIFY); - g_assert_false (dev_class->features & FPI_DEVICE_FEATURE_DUPLICATES_CHECK); - g_assert_true (dev_class->features & FPI_DEVICE_FEATURE_STORAGE); - g_assert_true (dev_class->features & FPI_DEVICE_FEATURE_STORAGE_LIST); - g_assert_true (dev_class->features & FPI_DEVICE_FEATURE_STORAGE_DELETE); - g_assert_false (dev_class->features & FPI_DEVICE_FEATURE_STORAGE_CLEAR); + g_assert_cmpuint (dev_class->features, !=, FP_DEVICE_FEATURE_NONE); + g_assert_true (dev_class->features & FP_DEVICE_FEATURE_CAPTURE); + g_assert_true (dev_class->features & FP_DEVICE_FEATURE_IDENTIFY); + g_assert_true (dev_class->features & FP_DEVICE_FEATURE_VERIFY); + g_assert_false (dev_class->features & FP_DEVICE_FEATURE_DUPLICATES_CHECK); + g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE); + g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE_LIST); + g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE_DELETE); + g_assert_false (dev_class->features & FP_DEVICE_FEATURE_STORAGE_CLEAR); + + g_assert_true (fp_device_has_feature (device, FP_DEVICE_FEATURE_CAPTURE)); + g_assert_true (fp_device_has_feature (device, FP_DEVICE_FEATURE_IDENTIFY)); + g_assert_true (fp_device_has_feature (device, FP_DEVICE_FEATURE_VERIFY)); + g_assert_false (fp_device_has_feature (device, FP_DEVICE_FEATURE_DUPLICATES_CHECK)); + g_assert_true (fp_device_has_feature (device, FP_DEVICE_FEATURE_STORAGE)); + g_assert_true (fp_device_has_feature (device, FP_DEVICE_FEATURE_STORAGE_LIST)); + g_assert_true (fp_device_has_feature (device, FP_DEVICE_FEATURE_STORAGE_DELETE)); + g_assert_false (fp_device_has_feature (device, FP_DEVICE_FEATURE_STORAGE_CLEAR)); + + g_assert_cmpuint (fp_device_get_features (device), + ==, + FP_DEVICE_FEATURE_CAPTURE | + FP_DEVICE_FEATURE_IDENTIFY | + FP_DEVICE_FEATURE_VERIFY | + FP_DEVICE_FEATURE_STORAGE | + FP_DEVICE_FEATURE_STORAGE_LIST | + FP_DEVICE_FEATURE_STORAGE_DELETE); } static void @@ -533,19 +617,19 @@ test_driver_initial_features_none (void) dev_class->verify = NULL; dev_class->identify = NULL; dev_class->delete = NULL; - dev_class->features = FPI_DEVICE_FEATURE_NONE; + dev_class->features = FP_DEVICE_FEATURE_NONE; fpi_device_class_auto_initialize_features (dev_class); - g_assert_cmpuint (dev_class->features, ==, FPI_DEVICE_FEATURE_NONE); - g_assert_false (dev_class->features & FPI_DEVICE_FEATURE_CAPTURE); - g_assert_false (dev_class->features & FPI_DEVICE_FEATURE_IDENTIFY); - g_assert_false (dev_class->features & FPI_DEVICE_FEATURE_VERIFY); - g_assert_false (dev_class->features & FPI_DEVICE_FEATURE_DUPLICATES_CHECK); - g_assert_false (dev_class->features & FPI_DEVICE_FEATURE_STORAGE); - g_assert_false (dev_class->features & FPI_DEVICE_FEATURE_STORAGE_LIST); - g_assert_false (dev_class->features & FPI_DEVICE_FEATURE_STORAGE_DELETE); - g_assert_false (dev_class->features & FPI_DEVICE_FEATURE_STORAGE_CLEAR); + g_assert_cmpuint (dev_class->features, ==, FP_DEVICE_FEATURE_NONE); + g_assert_false (dev_class->features & FP_DEVICE_FEATURE_CAPTURE); + g_assert_false (dev_class->features & FP_DEVICE_FEATURE_IDENTIFY); + g_assert_false (dev_class->features & FP_DEVICE_FEATURE_VERIFY); + g_assert_false (dev_class->features & FP_DEVICE_FEATURE_DUPLICATES_CHECK); + g_assert_false (dev_class->features & FP_DEVICE_FEATURE_STORAGE); + g_assert_false (dev_class->features & FP_DEVICE_FEATURE_STORAGE_LIST); + g_assert_false (dev_class->features & FP_DEVICE_FEATURE_STORAGE_DELETE); + g_assert_false (dev_class->features & FP_DEVICE_FEATURE_STORAGE_CLEAR); } static void @@ -554,19 +638,19 @@ test_driver_initial_features_no_capture (void) g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class (); dev_class->capture = NULL; - dev_class->features = FPI_DEVICE_FEATURE_NONE; + dev_class->features = FP_DEVICE_FEATURE_NONE; fpi_device_class_auto_initialize_features (dev_class); - g_assert_cmpuint (dev_class->features, !=, FPI_DEVICE_FEATURE_NONE); - g_assert_false (dev_class->features & FPI_DEVICE_FEATURE_CAPTURE); - g_assert_true (dev_class->features & FPI_DEVICE_FEATURE_IDENTIFY); - g_assert_true (dev_class->features & FPI_DEVICE_FEATURE_VERIFY); - g_assert_false (dev_class->features & FPI_DEVICE_FEATURE_DUPLICATES_CHECK); - g_assert_true (dev_class->features & FPI_DEVICE_FEATURE_STORAGE); - g_assert_true (dev_class->features & FPI_DEVICE_FEATURE_STORAGE_LIST); - g_assert_true (dev_class->features & FPI_DEVICE_FEATURE_STORAGE_DELETE); - g_assert_false (dev_class->features & FPI_DEVICE_FEATURE_STORAGE_CLEAR); + g_assert_cmpuint (dev_class->features, !=, FP_DEVICE_FEATURE_NONE); + g_assert_false (dev_class->features & FP_DEVICE_FEATURE_CAPTURE); + g_assert_true (dev_class->features & FP_DEVICE_FEATURE_IDENTIFY); + g_assert_true (dev_class->features & FP_DEVICE_FEATURE_VERIFY); + g_assert_false (dev_class->features & FP_DEVICE_FEATURE_DUPLICATES_CHECK); + g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE); + g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE_LIST); + g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE_DELETE); + g_assert_false (dev_class->features & FP_DEVICE_FEATURE_STORAGE_CLEAR); } static void @@ -575,19 +659,19 @@ test_driver_initial_features_no_verify (void) g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class (); dev_class->verify = NULL; - dev_class->features = FPI_DEVICE_FEATURE_NONE; + dev_class->features = FP_DEVICE_FEATURE_NONE; fpi_device_class_auto_initialize_features (dev_class); - g_assert_cmpuint (dev_class->features, !=, FPI_DEVICE_FEATURE_NONE); - g_assert_true (dev_class->features & FPI_DEVICE_FEATURE_CAPTURE); - g_assert_true (dev_class->features & FPI_DEVICE_FEATURE_IDENTIFY); - g_assert_false (dev_class->features & FPI_DEVICE_FEATURE_VERIFY); - g_assert_false (dev_class->features & FPI_DEVICE_FEATURE_DUPLICATES_CHECK); - g_assert_true (dev_class->features & FPI_DEVICE_FEATURE_STORAGE); - g_assert_true (dev_class->features & FPI_DEVICE_FEATURE_STORAGE_LIST); - g_assert_true (dev_class->features & FPI_DEVICE_FEATURE_STORAGE_DELETE); - g_assert_false (dev_class->features & FPI_DEVICE_FEATURE_STORAGE_CLEAR); + g_assert_cmpuint (dev_class->features, !=, FP_DEVICE_FEATURE_NONE); + g_assert_true (dev_class->features & FP_DEVICE_FEATURE_CAPTURE); + g_assert_true (dev_class->features & FP_DEVICE_FEATURE_IDENTIFY); + g_assert_false (dev_class->features & FP_DEVICE_FEATURE_VERIFY); + g_assert_false (dev_class->features & FP_DEVICE_FEATURE_DUPLICATES_CHECK); + g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE); + g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE_LIST); + g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE_DELETE); + g_assert_false (dev_class->features & FP_DEVICE_FEATURE_STORAGE_CLEAR); } static void @@ -596,19 +680,19 @@ test_driver_initial_features_no_identify (void) g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class (); dev_class->identify = NULL; - dev_class->features = FPI_DEVICE_FEATURE_NONE; + dev_class->features = FP_DEVICE_FEATURE_NONE; fpi_device_class_auto_initialize_features (dev_class); - g_assert_cmpuint (dev_class->features, !=, FPI_DEVICE_FEATURE_NONE); - g_assert_true (dev_class->features & FPI_DEVICE_FEATURE_CAPTURE); - g_assert_false (dev_class->features & FPI_DEVICE_FEATURE_IDENTIFY); - g_assert_true (dev_class->features & FPI_DEVICE_FEATURE_VERIFY); - g_assert_false (dev_class->features & FPI_DEVICE_FEATURE_DUPLICATES_CHECK); - g_assert_true (dev_class->features & FPI_DEVICE_FEATURE_STORAGE); - g_assert_true (dev_class->features & FPI_DEVICE_FEATURE_STORAGE_LIST); - g_assert_true (dev_class->features & FPI_DEVICE_FEATURE_STORAGE_DELETE); - g_assert_false (dev_class->features & FPI_DEVICE_FEATURE_STORAGE_CLEAR); + g_assert_cmpuint (dev_class->features, !=, FP_DEVICE_FEATURE_NONE); + g_assert_true (dev_class->features & FP_DEVICE_FEATURE_CAPTURE); + g_assert_false (dev_class->features & FP_DEVICE_FEATURE_IDENTIFY); + g_assert_true (dev_class->features & FP_DEVICE_FEATURE_VERIFY); + g_assert_false (dev_class->features & FP_DEVICE_FEATURE_DUPLICATES_CHECK); + g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE); + g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE_LIST); + g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE_DELETE); + g_assert_false (dev_class->features & FP_DEVICE_FEATURE_STORAGE_CLEAR); } static void @@ -618,19 +702,19 @@ test_driver_initial_features_no_storage (void) dev_class->list = NULL; dev_class->delete = NULL; - dev_class->features = FPI_DEVICE_FEATURE_NONE; + dev_class->features = FP_DEVICE_FEATURE_NONE; fpi_device_class_auto_initialize_features (dev_class); - g_assert_cmpuint (dev_class->features, !=, FPI_DEVICE_FEATURE_NONE); - g_assert_true (dev_class->features & FPI_DEVICE_FEATURE_CAPTURE); - g_assert_true (dev_class->features & FPI_DEVICE_FEATURE_IDENTIFY); - g_assert_true (dev_class->features & FPI_DEVICE_FEATURE_VERIFY); - g_assert_false (dev_class->features & FPI_DEVICE_FEATURE_DUPLICATES_CHECK); - g_assert_false (dev_class->features & FPI_DEVICE_FEATURE_STORAGE); - g_assert_false (dev_class->features & FPI_DEVICE_FEATURE_STORAGE_LIST); - g_assert_false (dev_class->features & FPI_DEVICE_FEATURE_STORAGE_DELETE); - g_assert_false (dev_class->features & FPI_DEVICE_FEATURE_STORAGE_CLEAR); + g_assert_cmpuint (dev_class->features, !=, FP_DEVICE_FEATURE_NONE); + g_assert_true (dev_class->features & FP_DEVICE_FEATURE_CAPTURE); + g_assert_true (dev_class->features & FP_DEVICE_FEATURE_IDENTIFY); + g_assert_true (dev_class->features & FP_DEVICE_FEATURE_VERIFY); + g_assert_false (dev_class->features & FP_DEVICE_FEATURE_DUPLICATES_CHECK); + g_assert_false (dev_class->features & FP_DEVICE_FEATURE_STORAGE); + g_assert_false (dev_class->features & FP_DEVICE_FEATURE_STORAGE_LIST); + g_assert_false (dev_class->features & FP_DEVICE_FEATURE_STORAGE_DELETE); + g_assert_false (dev_class->features & FP_DEVICE_FEATURE_STORAGE_CLEAR); } static void @@ -639,19 +723,19 @@ test_driver_initial_features_no_list (void) g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class (); dev_class->list = NULL; - dev_class->features = FPI_DEVICE_FEATURE_NONE; + dev_class->features = FP_DEVICE_FEATURE_NONE; fpi_device_class_auto_initialize_features (dev_class); - g_assert_cmpuint (dev_class->features, !=, FPI_DEVICE_FEATURE_NONE); - g_assert_true (dev_class->features & FPI_DEVICE_FEATURE_CAPTURE); - g_assert_true (dev_class->features & FPI_DEVICE_FEATURE_IDENTIFY); - g_assert_true (dev_class->features & FPI_DEVICE_FEATURE_VERIFY); - g_assert_false (dev_class->features & FPI_DEVICE_FEATURE_DUPLICATES_CHECK); - g_assert_true (dev_class->features & FPI_DEVICE_FEATURE_STORAGE); - g_assert_false (dev_class->features & FPI_DEVICE_FEATURE_STORAGE_LIST); - g_assert_true (dev_class->features & FPI_DEVICE_FEATURE_STORAGE_DELETE); - g_assert_false (dev_class->features & FPI_DEVICE_FEATURE_STORAGE_CLEAR); + g_assert_cmpuint (dev_class->features, !=, FP_DEVICE_FEATURE_NONE); + g_assert_true (dev_class->features & FP_DEVICE_FEATURE_CAPTURE); + g_assert_true (dev_class->features & FP_DEVICE_FEATURE_IDENTIFY); + g_assert_true (dev_class->features & FP_DEVICE_FEATURE_VERIFY); + g_assert_false (dev_class->features & FP_DEVICE_FEATURE_DUPLICATES_CHECK); + g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE); + g_assert_false (dev_class->features & FP_DEVICE_FEATURE_STORAGE_LIST); + g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE_DELETE); + g_assert_false (dev_class->features & FP_DEVICE_FEATURE_STORAGE_CLEAR); } static void @@ -660,19 +744,19 @@ test_driver_initial_features_no_delete (void) g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class (); dev_class->list = NULL; - dev_class->features = FPI_DEVICE_FEATURE_NONE; + dev_class->features = FP_DEVICE_FEATURE_NONE; fpi_device_class_auto_initialize_features (dev_class); - g_assert_cmpuint (dev_class->features, !=, FPI_DEVICE_FEATURE_NONE); - g_assert_true (dev_class->features & FPI_DEVICE_FEATURE_CAPTURE); - g_assert_true (dev_class->features & FPI_DEVICE_FEATURE_IDENTIFY); - g_assert_true (dev_class->features & FPI_DEVICE_FEATURE_VERIFY); - g_assert_false (dev_class->features & FPI_DEVICE_FEATURE_DUPLICATES_CHECK); - g_assert_true (dev_class->features & FPI_DEVICE_FEATURE_STORAGE); - g_assert_false (dev_class->features & FPI_DEVICE_FEATURE_STORAGE_LIST); - g_assert_true (dev_class->features & FPI_DEVICE_FEATURE_STORAGE_DELETE); - g_assert_false (dev_class->features & FPI_DEVICE_FEATURE_STORAGE_CLEAR); + g_assert_cmpuint (dev_class->features, !=, FP_DEVICE_FEATURE_NONE); + g_assert_true (dev_class->features & FP_DEVICE_FEATURE_CAPTURE); + g_assert_true (dev_class->features & FP_DEVICE_FEATURE_IDENTIFY); + g_assert_true (dev_class->features & FP_DEVICE_FEATURE_VERIFY); + g_assert_false (dev_class->features & FP_DEVICE_FEATURE_DUPLICATES_CHECK); + g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE); + g_assert_false (dev_class->features & FP_DEVICE_FEATURE_STORAGE_LIST); + g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE_DELETE); + g_assert_false (dev_class->features & FP_DEVICE_FEATURE_STORAGE_CLEAR); } static void @@ -1173,7 +1257,7 @@ test_driver_verify_not_supported (void) FpiDeviceFake *fake_dev; gboolean match; - dev_class->features &= ~FPI_DEVICE_FEATURE_VERIFY; + dev_class->features &= ~FP_DEVICE_FEATURE_VERIFY; device = auto_close_fake_device_new (); fake_dev = FPI_DEVICE_FAKE (device); @@ -1505,6 +1589,7 @@ test_driver_supports_identify (void) device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL); g_assert_true (fp_device_supports_identify (device)); + g_assert_true (fp_device_has_feature (device, FP_DEVICE_FEATURE_IDENTIFY)); } static void @@ -1513,10 +1598,11 @@ test_driver_do_not_support_identify (void) g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class (); g_autoptr(FpDevice) device = NULL; - dev_class->features &= ~FPI_DEVICE_FEATURE_IDENTIFY; + dev_class->features &= ~FP_DEVICE_FEATURE_IDENTIFY; device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL); g_assert_false (fp_device_supports_identify (device)); + g_assert_false (fp_device_has_feature (device, FP_DEVICE_FEATURE_IDENTIFY)); } static void @@ -1536,6 +1622,7 @@ test_driver_identify (void) fp_print_set_description (expected_matched, "fake-verified"); g_assert_true (fp_device_supports_identify (device)); + g_assert_true (fp_device_has_feature (device, FP_DEVICE_FEATURE_IDENTIFY)); match_data->gallery = prints; @@ -1569,6 +1656,7 @@ test_driver_identify_fail (void) FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device); g_assert_true (fp_device_supports_identify (device)); + g_assert_true (fp_device_has_feature (device, FP_DEVICE_FEATURE_IDENTIFY)); fake_dev->ret_print = make_fake_print (device, NULL); g_assert_true (fp_device_identify_sync (device, prints, NULL, @@ -1605,6 +1693,7 @@ test_driver_identify_retry (void) fp_print_set_description (expected_matched, "fake-verified"); g_assert_true (fp_device_supports_identify (device)); + g_assert_true (fp_device_has_feature (device, FP_DEVICE_FEATURE_IDENTIFY)); fake_dev->ret_error = fpi_device_retry_new (FP_DEVICE_RETRY_GENERAL); g_assert_false (fp_device_identify_sync (device, prints, NULL, @@ -1639,6 +1728,7 @@ test_driver_identify_error (void) fp_print_set_description (expected_matched, "fake-verified"); g_assert_true (fp_device_supports_identify (device)); + g_assert_true (fp_device_has_feature (device, FP_DEVICE_FEATURE_IDENTIFY)); fake_dev->ret_error = fpi_device_error_new (FP_DEVICE_ERROR_GENERAL); g_assert_false (fp_device_identify_sync (device, prints, NULL, @@ -1841,11 +1931,12 @@ test_driver_supports_capture (void) g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class (); g_autoptr(FpDevice) device = NULL; - dev_class->features |= FPI_DEVICE_FEATURE_CAPTURE; + dev_class->features |= FP_DEVICE_FEATURE_CAPTURE; dev_class->capture = fake_device_stub_capture; device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL); g_assert_true (fp_device_supports_capture (device)); + g_assert_true (fp_device_has_feature (device, FP_DEVICE_FEATURE_CAPTURE)); } static void @@ -1854,11 +1945,12 @@ test_driver_do_not_support_capture (void) g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class (); g_autoptr(FpDevice) device = NULL; - dev_class->features &= ~FPI_DEVICE_FEATURE_CAPTURE; + dev_class->features &= ~FP_DEVICE_FEATURE_CAPTURE; dev_class->capture = NULL; device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL); g_assert_false (fp_device_supports_capture (device)); + g_assert_false (fp_device_has_feature (device, FP_DEVICE_FEATURE_CAPTURE)); } static void @@ -1890,7 +1982,7 @@ test_driver_capture_not_supported (void) gboolean wait_for_finger = TRUE; FpiDeviceFake *fake_dev; - dev_class->features &= ~FPI_DEVICE_FEATURE_CAPTURE; + dev_class->features &= ~FP_DEVICE_FEATURE_CAPTURE; device = auto_close_fake_device_new (); fake_dev = FPI_DEVICE_FAKE (device); @@ -1928,10 +2020,11 @@ test_driver_has_storage (void) g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class (); g_autoptr(FpDevice) device = NULL; - dev_class->features |= FPI_DEVICE_FEATURE_STORAGE; + dev_class->features |= FP_DEVICE_FEATURE_STORAGE; device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL); g_assert_true (fp_device_has_storage (device)); + g_assert_true (fp_device_has_feature (device, FP_DEVICE_FEATURE_STORAGE)); } static void @@ -1940,10 +2033,11 @@ test_driver_has_not_storage (void) g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class (); g_autoptr(FpDevice) device = NULL; - dev_class->features &= ~FPI_DEVICE_FEATURE_STORAGE; + dev_class->features &= ~FP_DEVICE_FEATURE_STORAGE; device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL); g_assert_false (fp_device_has_storage (device)); + g_assert_false (fp_device_has_feature (device, FP_DEVICE_FEATURE_STORAGE)); } static void @@ -1992,10 +2086,11 @@ test_driver_list_no_storage (void) g_autoptr(GPtrArray) prints = NULL; g_autoptr(GError) error = NULL; - dev_class->features &= ~FPI_DEVICE_FEATURE_STORAGE; + dev_class->features &= ~FP_DEVICE_FEATURE_STORAGE; device = auto_close_fake_device_new (); g_assert_false (fp_device_has_storage (device)); + g_assert_false (fp_device_has_feature (device, FP_DEVICE_FEATURE_STORAGE)); prints = fp_device_list_prints_sync (device, NULL, &error); g_assert_null (prints); @@ -2661,6 +2756,7 @@ main (int argc, char *argv[]) g_test_add_func ("/driver/get_usb_device", test_driver_get_usb_device); g_test_add_func ("/driver/get_virtual_env", test_driver_get_virtual_env); g_test_add_func ("/driver/get_driver_data", test_driver_get_driver_data); + g_test_add_func ("/driver/features", test_driver_features); g_test_add_func ("/driver/initial_features", test_driver_initial_features); g_test_add_func ("/driver/initial_features/none", test_driver_initial_features_none); g_test_add_func ("/driver/initial_features/no_capture", test_driver_initial_features_no_capture); diff --git a/tests/virtual-device.py b/tests/virtual-device.py index 27cafdd..46fedba 100644 --- a/tests/virtual-device.py +++ b/tests/virtual-device.py @@ -352,6 +352,16 @@ class VirtualDevice(VirtualDeviceBase): self.assertEqual(self.dev.props.nr_enroll_stages, self.dev.get_nr_enroll_stages()) self.assertEqual(self.dev.props.open, self.dev.is_open()) + def test_device_features(self): + self.assertFalse(self.dev.has_feature(FPrint.DeviceFeature.CAPTURE)) + self.assertFalse(self.dev.has_feature(FPrint.DeviceFeature.IDENTIFY)) + self.assertTrue(self.dev.has_feature(FPrint.DeviceFeature.VERIFY)) + self.assertFalse(self.dev.has_feature(FPrint.DeviceFeature.DUPLICATES_CHECK)) + self.assertFalse(self.dev.has_feature(FPrint.DeviceFeature.STORAGE)) + self.assertFalse(self.dev.has_feature(FPrint.DeviceFeature.STORAGE_LIST)) + self.assertFalse(self.dev.has_feature(FPrint.DeviceFeature.STORAGE_DELETE)) + self.assertFalse(self.dev.has_feature(FPrint.DeviceFeature.STORAGE_CLEAR)) + def test_open_error(self): self._close_on_teardown = False self.send_command('IGNORED_COMMAND') # This will be consumed by close @@ -1019,6 +1029,16 @@ class VirtualDeviceStorage(VirtualDevice): self.assertFalse(self.dev.supports_capture()) self.assertTrue(self.dev.has_storage()) + def test_device_features(self): + self.assertFalse(self.dev.has_feature(FPrint.DeviceFeature.CAPTURE)) + self.assertTrue(self.dev.has_feature(FPrint.DeviceFeature.IDENTIFY)) + self.assertTrue(self.dev.has_feature(FPrint.DeviceFeature.VERIFY)) + self.assertTrue(self.dev.has_feature(FPrint.DeviceFeature.DUPLICATES_CHECK)) + self.assertTrue(self.dev.has_feature(FPrint.DeviceFeature.STORAGE)) + self.assertTrue(self.dev.has_feature(FPrint.DeviceFeature.STORAGE_LIST)) + self.assertTrue(self.dev.has_feature(FPrint.DeviceFeature.STORAGE_DELETE)) + self.assertFalse(self.dev.has_feature(FPrint.DeviceFeature.STORAGE_CLEAR)) + def test_duplicate_enroll(self): self.enroll_print('testprint', FPrint.Finger.LEFT_LITTLE) with self.assertRaises(GLib.Error) as error: diff --git a/tests/virtual-image.py b/tests/virtual-image.py index 7609bd6..2ee376d 100755 --- a/tests/virtual-image.py +++ b/tests/virtual-image.py @@ -140,6 +140,20 @@ class VirtualImage(unittest.TestCase): while iterate and ctx.pending(): ctx.iteration(False) + def test_features(self): + self.assertTrue(self.dev.has_feature(FPrint.DeviceFeature.CAPTURE)) + self.assertTrue(self.dev.has_feature(FPrint.DeviceFeature.IDENTIFY)) + self.assertTrue(self.dev.has_feature(FPrint.DeviceFeature.VERIFY)) + self.assertFalse(self.dev.has_feature(FPrint.DeviceFeature.DUPLICATES_CHECK)) + self.assertFalse(self.dev.has_feature(FPrint.DeviceFeature.STORAGE)) + self.assertFalse(self.dev.has_feature(FPrint.DeviceFeature.STORAGE_LIST)) + self.assertFalse(self.dev.has_feature(FPrint.DeviceFeature.STORAGE_DELETE)) + self.assertFalse(self.dev.has_feature(FPrint.DeviceFeature.STORAGE_CLEAR)) + self.assertEqual(self.dev.get_features(), + FPrint.DeviceFeature.CAPTURE | + FPrint.DeviceFeature.IDENTIFY | + FPrint.DeviceFeature.VERIFY) + def test_capture_prevents_close(self): cancel = Gio.Cancellable() def cancelled_cb(dev, res, obj):