From 8d545a0b95b32eecf3870c018a45ad1d16f4115c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Tue, 8 Dec 2020 04:16:31 +0100 Subject: [PATCH] fpi-device: Add FpiDeviceFeature flags to FpDeviceClass Allows drivers to define more fine grained features for devices, not strictly depending on assumptions we can make depending on the implemented vfuncs. We keep this per class but could be in theory moved to each instance. In any case, added an utility function to initialize it in the way we can ensure that we've a consistent way for setting them across all the devices. --- doc/libfprint-2-sections.txt | 2 + libfprint/drivers/goodixmoc/goodix.c | 3 + libfprint/drivers/synaptics/synaptics.c | 2 + libfprint/drivers/upekts.c | 2 + libfprint/drivers/virtual-device-storage.c | 3 + libfprint/drivers/virtual-device.c | 2 + libfprint/fp-device.c | 13 +- libfprint/fp-image-device.c | 2 + libfprint/fpi-device.c | 34 ++++ libfprint/fpi-device.h | 29 ++++ tests/test-device-fake.c | 2 + tests/test-fpi-device.c | 192 ++++++++++++++++++++- 12 files changed, 272 insertions(+), 14 deletions(-) diff --git a/doc/libfprint-2-sections.txt b/doc/libfprint-2-sections.txt index 37fddf3..998ea2e 100644 --- a/doc/libfprint-2-sections.txt +++ b/doc/libfprint-2-sections.txt @@ -131,6 +131,7 @@ fpi_get_driver_types FpDeviceClass FpTimeoutFunc FpiDeviceAction +FpiDeviceFeature FpIdEntry FpiDeviceUdevSubtypeFlags fpi_device_get_usb_device @@ -168,6 +169,7 @@ fpi_device_enroll_progress fpi_device_verify_report fpi_device_identify_report fpi_device_list_complete +fpi_device_class_auto_initialize_features
diff --git a/libfprint/drivers/goodixmoc/goodix.c b/libfprint/drivers/goodixmoc/goodix.c index 77278c6..b57ee3c 100644 --- a/libfprint/drivers/goodixmoc/goodix.c +++ b/libfprint/drivers/goodixmoc/goodix.c @@ -1579,4 +1579,7 @@ fpi_device_goodixmoc_class_init (FpiDeviceGoodixMocClass *klass) dev_class->cancel = gx_fp_cancel; dev_class->verify = gx_fp_verify_identify; dev_class->identify = gx_fp_verify_identify; + + fpi_device_class_auto_initialize_features (dev_class); + dev_class->features |= FPI_DEVICE_FEATURE_DUPLICATES_CHECK; } diff --git a/libfprint/drivers/synaptics/synaptics.c b/libfprint/drivers/synaptics/synaptics.c index bb113cb..7f24d1d 100644 --- a/libfprint/drivers/synaptics/synaptics.c +++ b/libfprint/drivers/synaptics/synaptics.c @@ -1405,4 +1405,6 @@ fpi_device_synaptics_class_init (FpiDeviceSynapticsClass *klass) dev_class->delete = delete_print; dev_class->cancel = cancel; dev_class->list = list; + + fpi_device_class_auto_initialize_features (dev_class); } diff --git a/libfprint/drivers/upekts.c b/libfprint/drivers/upekts.c index 3471cf7..cf02161 100644 --- a/libfprint/drivers/upekts.c +++ b/libfprint/drivers/upekts.c @@ -1555,4 +1555,6 @@ fpi_device_upekts_class_init (FpiDeviceUpektsClass *klass) dev_class->verify = verify; dev_class->enroll = enroll; /* dev_class->cancel = cancel; */ + + fpi_device_class_auto_initialize_features (dev_class); } diff --git a/libfprint/drivers/virtual-device-storage.c b/libfprint/drivers/virtual-device-storage.c index 34e8971..9591dcc 100644 --- a/libfprint/drivers/virtual-device-storage.c +++ b/libfprint/drivers/virtual-device-storage.c @@ -244,4 +244,7 @@ fpi_device_virtual_device_storage_class_init (FpDeviceVirtualDeviceStorageClass dev_class->identify = dev_identify; dev_class->list = dev_list; dev_class->delete = dev_delete; + + fpi_device_class_auto_initialize_features (dev_class); + dev_class->features |= FPI_DEVICE_FEATURE_DUPLICATES_CHECK; } diff --git a/libfprint/drivers/virtual-device.c b/libfprint/drivers/virtual-device.c index 1a31b77..55962ad 100644 --- a/libfprint/drivers/virtual-device.c +++ b/libfprint/drivers/virtual-device.c @@ -776,4 +776,6 @@ fpi_device_virtual_device_class_init (FpDeviceVirtualDeviceClass *klass) dev_class->verify = dev_verify; dev_class->enroll = dev_enroll; dev_class->cancel = dev_cancel; + + fpi_device_class_auto_initialize_features (dev_class); } diff --git a/libfprint/fp-device.c b/libfprint/fp-device.c index 251ed83..7b0a659 100644 --- a/libfprint/fp-device.c +++ b/libfprint/fp-device.c @@ -140,6 +140,8 @@ 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); + priv->type = cls->type; if (cls->nr_enroll_stages) priv->nr_enroll_stages = cls->nr_enroll_stages; @@ -627,7 +629,7 @@ fp_device_supports_identify (FpDevice *device) g_return_val_if_fail (FP_IS_DEVICE (device), FALSE); - return cls->identify != NULL; + return cls->identify && !!(cls->features & FPI_DEVICE_FEATURE_IDENTIFY); } /** @@ -645,7 +647,7 @@ fp_device_supports_capture (FpDevice *device) g_return_val_if_fail (FP_IS_DEVICE (device), FALSE); - return cls->capture != NULL; + return cls->capture && !!(cls->features & FPI_DEVICE_FEATURE_CAPTURE); } /** @@ -664,7 +666,7 @@ fp_device_has_storage (FpDevice *device) g_return_val_if_fail (FP_IS_DEVICE (device), FALSE); - return cls->list != NULL; + return !!(cls->features & FPI_DEVICE_FEATURE_STORAGE); } /** @@ -1254,6 +1256,7 @@ fp_device_delete_print (FpDevice *device, { g_autoptr(GTask) task = NULL; FpDevicePrivate *priv = fp_device_get_instance_private (device); + FpDeviceClass *cls = FP_DEVICE_GET_CLASS (device); task = g_task_new (device, cancellable, callback, user_data); if (g_task_return_error_if_cancelled (task)) @@ -1274,7 +1277,7 @@ fp_device_delete_print (FpDevice *device, } /* Succeed immediately if delete is not implemented. */ - if (!FP_DEVICE_GET_CLASS (device)->delete) + if (!cls->delete || !(cls->features & FPI_DEVICE_FEATURE_STORAGE_DELETE)) { g_task_return_boolean (task, TRUE); return; @@ -1288,7 +1291,7 @@ fp_device_delete_print (FpDevice *device, g_object_ref (enrolled_print), g_object_unref); - FP_DEVICE_GET_CLASS (device)->delete (device); + cls->delete (device); } /** diff --git a/libfprint/fp-image-device.c b/libfprint/fp-image-device.c index 0200796..82e69f9 100644 --- a/libfprint/fp-image-device.c +++ b/libfprint/fp-image-device.c @@ -220,6 +220,8 @@ fp_image_device_class_init (FpImageDeviceClass *klass) fp_device_class->cancel = fp_image_device_cancel_action; + fpi_device_class_auto_initialize_features (fp_device_class); + /* Default implementations */ klass->activate = fp_image_device_default_activate; klass->deactivate = fp_image_device_default_deactivate; diff --git a/libfprint/fpi-device.c b/libfprint/fpi-device.c index 9f334e2..f6da050 100644 --- a/libfprint/fpi-device.c +++ b/libfprint/fpi-device.c @@ -46,6 +46,40 @@ fp_device_get_instance_private (FpDevice *self) g_type_class_get_instance_private_offset (dev_class)); } +/** + * fpi_device_class_auto_initialize_features: + * + * Initializes the #FpDeviceClass @features flags checking what device vfuncs + * are implemented. + * Drivers should call this at the end of the class initialization. + */ +void +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; + + if (device_class->verify) + device_class->features |= FPI_DEVICE_FEATURE_VERIFY; + + if (device_class->identify) + device_class->features |= FPI_DEVICE_FEATURE_IDENTIFY; + + if (device_class->list) + { + device_class->features |= FPI_DEVICE_FEATURE_STORAGE; + device_class->features |= FPI_DEVICE_FEATURE_STORAGE_LIST; + } + + if (device_class->delete) + { + device_class->features |= FPI_DEVICE_FEATURE_STORAGE; + device_class->features |= FPI_DEVICE_FEATURE_STORAGE_DELETE; + } +} + /** * fpi_device_retry_new: * @error: The #FpDeviceRetry error value describing the issue diff --git a/libfprint/fpi-device.h b/libfprint/fpi-device.h index 669ce15..38a4574 100644 --- a/libfprint/fpi-device.h +++ b/libfprint/fpi-device.h @@ -69,6 +69,30 @@ 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 @@ -76,6 +100,8 @@ struct _FpIdEntry * @full_name: Human readable description of the driver * @type: The type of driver * @id_table: The table of IDs to bind the driver to + * @features: The features the device supports, it can be initialized using + * fpi_device_class_auto_initialize_features() on @class_init. * @nr_enroll_stages: The number of enroll stages supported devices need; use * fpi_device_set_nr_enroll_stages() from @probe if this is dynamic. * @scan_type: The scan type of supported devices; use @@ -133,6 +159,7 @@ struct _FpDeviceClass const gchar *full_name; FpDeviceType type; const FpIdEntry *id_table; + FpiDeviceFeature features; /* Defaults for device properties */ gint nr_enroll_stages; @@ -153,6 +180,8 @@ struct _FpDeviceClass void (*cancel) (FpDevice *device); }; +void fpi_device_class_auto_initialize_features (FpDeviceClass *device_class); + /** * FpTimeoutFunc: * @device: The #FpDevice passed to fpi_device_add_timeout() diff --git a/tests/test-device-fake.c b/tests/test-device-fake.c index 2341581..1feeb18 100644 --- a/tests/test-device-fake.c +++ b/tests/test-device-fake.c @@ -279,4 +279,6 @@ fpi_device_fake_class_init (FpiDeviceFakeClass *klass) dev_class->list = fpi_device_fake_list; dev_class->delete = fpi_device_fake_delete; dev_class->cancel = fpi_device_fake_cancel; + + fpi_device_class_auto_initialize_features (dev_class); } diff --git a/tests/test-fpi-device.c b/tests/test-fpi-device.c index ab5a108..a6b7285 100644 --- a/tests/test-fpi-device.c +++ b/tests/test-fpi-device.c @@ -506,6 +506,175 @@ test_driver_get_driver_data (void) g_assert_cmpuint (fpi_device_get_driver_data (device), ==, driver_data); } +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); +} + +static void +test_driver_initial_features_none (void) +{ + g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class (); + + dev_class->list = NULL; + dev_class->capture = NULL; + dev_class->verify = NULL; + dev_class->identify = NULL; + dev_class->delete = NULL; + dev_class->features = FPI_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); +} + +static void +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; + + 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); +} + +static void +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; + + 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); +} + +static void +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; + + 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); +} + +static void +test_driver_initial_features_no_storage (void) +{ + g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class (); + + dev_class->list = NULL; + dev_class->delete = NULL; + dev_class->features = FPI_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); +} + +static void +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; + + 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); +} + +static void +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; + + 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); +} + static void on_driver_probe_async (GObject *initable, GAsyncResult *res, gpointer user_data) { @@ -1311,7 +1480,7 @@ test_driver_do_not_support_identify (void) g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class (); g_autoptr(FpDevice) device = NULL; - dev_class->identify = NULL; + dev_class->features &= ~FPI_DEVICE_FEATURE_IDENTIFY; device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL); g_assert_false (fp_device_supports_identify (device)); @@ -1639,6 +1808,7 @@ 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->capture = fake_device_stub_capture; device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL); @@ -1651,6 +1821,7 @@ 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->capture = NULL; device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL); @@ -1695,18 +1866,13 @@ test_driver_capture_error (void) g_assert_null (image); } -static void -fake_device_stub_list (FpDevice *device) -{ -} - static void test_driver_has_storage (void) { g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class (); g_autoptr(FpDevice) device = NULL; - dev_class->list = fake_device_stub_list; + dev_class->features |= FPI_DEVICE_FEATURE_STORAGE; device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL); g_assert_true (fp_device_has_storage (device)); @@ -1718,7 +1884,7 @@ test_driver_has_not_storage (void) g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class (); g_autoptr(FpDevice) device = NULL; - dev_class->list = NULL; + dev_class->features &= ~FPI_DEVICE_FEATURE_STORAGE; device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL); g_assert_false (fp_device_has_storage (device)); @@ -1770,7 +1936,7 @@ test_driver_list_no_storage (void) g_autoptr(GPtrArray) prints = NULL; g_autoptr(GError) error = NULL; - dev_class->list = NULL; + dev_class->features &= ~FPI_DEVICE_FEATURE_STORAGE; device = auto_close_fake_device_new (); g_assert_false (fp_device_has_storage (device)); @@ -2439,6 +2605,14 @@ 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/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); + g_test_add_func ("/driver/initial_features/no_verify", test_driver_initial_features_no_verify); + g_test_add_func ("/driver/initial_features/no_identify", test_driver_initial_features_no_identify); + g_test_add_func ("/driver/initial_features/no_storage", test_driver_initial_features_no_storage); + g_test_add_func ("/driver/initial_features/no_list", test_driver_initial_features_no_list); + g_test_add_func ("/driver/initial_features/no_delete", test_driver_initial_features_no_delete); g_test_add_func ("/driver/probe", test_driver_probe); g_test_add_func ("/driver/probe/error", test_driver_probe_error);