device: Add API to update features during probe
This allows updating the supported feature bitfield during probe.
This commit is contained in:
parent
145f7287fa
commit
8a5bec6619
8 changed files with 116 additions and 90 deletions
|
@ -159,6 +159,7 @@ fpi_device_action_is_cancelled
|
||||||
fpi_device_add_timeout
|
fpi_device_add_timeout
|
||||||
fpi_device_set_nr_enroll_stages
|
fpi_device_set_nr_enroll_stages
|
||||||
fpi_device_set_scan_type
|
fpi_device_set_scan_type
|
||||||
|
fpi_device_update_features
|
||||||
fpi_device_remove
|
fpi_device_remove
|
||||||
fpi_device_report_finger_status
|
fpi_device_report_finger_status
|
||||||
fpi_device_report_finger_status_changes
|
fpi_device_report_finger_status_changes
|
||||||
|
|
|
@ -40,6 +40,7 @@ typedef struct
|
||||||
gchar *device_id;
|
gchar *device_id;
|
||||||
gchar *device_name;
|
gchar *device_name;
|
||||||
FpScanType scan_type;
|
FpScanType scan_type;
|
||||||
|
FpDeviceFeature features;
|
||||||
|
|
||||||
guint64 driver_data;
|
guint64 driver_data;
|
||||||
|
|
||||||
|
|
|
@ -147,6 +147,7 @@ fp_device_constructed (GObject *object)
|
||||||
if (cls->nr_enroll_stages)
|
if (cls->nr_enroll_stages)
|
||||||
priv->nr_enroll_stages = cls->nr_enroll_stages;
|
priv->nr_enroll_stages = cls->nr_enroll_stages;
|
||||||
priv->scan_type = cls->scan_type;
|
priv->scan_type = cls->scan_type;
|
||||||
|
priv->features = cls->features;
|
||||||
priv->device_name = g_strdup (cls->full_name);
|
priv->device_name = g_strdup (cls->full_name);
|
||||||
priv->device_id = g_strdup ("0");
|
priv->device_id = g_strdup ("0");
|
||||||
|
|
||||||
|
@ -628,10 +629,11 @@ gboolean
|
||||||
fp_device_supports_identify (FpDevice *device)
|
fp_device_supports_identify (FpDevice *device)
|
||||||
{
|
{
|
||||||
FpDeviceClass *cls = FP_DEVICE_GET_CLASS (device);
|
FpDeviceClass *cls = FP_DEVICE_GET_CLASS (device);
|
||||||
|
FpDevicePrivate *priv = fp_device_get_instance_private (device);
|
||||||
|
|
||||||
g_return_val_if_fail (FP_IS_DEVICE (device), FALSE);
|
g_return_val_if_fail (FP_IS_DEVICE (device), FALSE);
|
||||||
|
|
||||||
return cls->identify && !!(cls->features & FP_DEVICE_FEATURE_IDENTIFY);
|
return cls->identify && !!(priv->features & FP_DEVICE_FEATURE_IDENTIFY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -647,10 +649,11 @@ gboolean
|
||||||
fp_device_supports_capture (FpDevice *device)
|
fp_device_supports_capture (FpDevice *device)
|
||||||
{
|
{
|
||||||
FpDeviceClass *cls = FP_DEVICE_GET_CLASS (device);
|
FpDeviceClass *cls = FP_DEVICE_GET_CLASS (device);
|
||||||
|
FpDevicePrivate *priv = fp_device_get_instance_private (device);
|
||||||
|
|
||||||
g_return_val_if_fail (FP_IS_DEVICE (device), FALSE);
|
g_return_val_if_fail (FP_IS_DEVICE (device), FALSE);
|
||||||
|
|
||||||
return cls->capture && !!(cls->features & FP_DEVICE_FEATURE_CAPTURE);
|
return cls->capture && !!(priv->features & FP_DEVICE_FEATURE_CAPTURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -666,11 +669,11 @@ fp_device_supports_capture (FpDevice *device)
|
||||||
gboolean
|
gboolean
|
||||||
fp_device_has_storage (FpDevice *device)
|
fp_device_has_storage (FpDevice *device)
|
||||||
{
|
{
|
||||||
FpDeviceClass *cls = FP_DEVICE_GET_CLASS (device);
|
FpDevicePrivate *priv = fp_device_get_instance_private (device);
|
||||||
|
|
||||||
g_return_val_if_fail (FP_IS_DEVICE (device), FALSE);
|
g_return_val_if_fail (FP_IS_DEVICE (device), FALSE);
|
||||||
|
|
||||||
return !!(cls->features & FP_DEVICE_FEATURE_STORAGE);
|
return !!(priv->features & FP_DEVICE_FEATURE_STORAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -980,7 +983,7 @@ fp_device_verify (FpDevice *device,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cls->verify || !(cls->features & FP_DEVICE_FEATURE_VERIFY))
|
if (!cls->verify || !(priv->features & FP_DEVICE_FEATURE_VERIFY))
|
||||||
{
|
{
|
||||||
g_task_return_error (task,
|
g_task_return_error (task,
|
||||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_NOT_SUPPORTED,
|
fpi_device_error_new_msg (FP_DEVICE_ERROR_NOT_SUPPORTED,
|
||||||
|
@ -1099,7 +1102,7 @@ fp_device_identify (FpDevice *device,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cls->identify || !(cls->features & FP_DEVICE_FEATURE_IDENTIFY))
|
if (!cls->identify || !(priv->features & FP_DEVICE_FEATURE_IDENTIFY))
|
||||||
{
|
{
|
||||||
g_task_return_error (task,
|
g_task_return_error (task,
|
||||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_NOT_SUPPORTED,
|
fpi_device_error_new_msg (FP_DEVICE_ERROR_NOT_SUPPORTED,
|
||||||
|
@ -1216,7 +1219,7 @@ fp_device_capture (FpDevice *device,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cls->capture || !(cls->features & FP_DEVICE_FEATURE_CAPTURE))
|
if (!cls->capture || !(priv->features & FP_DEVICE_FEATURE_CAPTURE))
|
||||||
{
|
{
|
||||||
g_task_return_error (task,
|
g_task_return_error (task,
|
||||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_NOT_SUPPORTED,
|
fpi_device_error_new_msg (FP_DEVICE_ERROR_NOT_SUPPORTED,
|
||||||
|
@ -1300,7 +1303,7 @@ fp_device_delete_print (FpDevice *device,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Succeed immediately if delete is not implemented. */
|
/* Succeed immediately if delete is not implemented. */
|
||||||
if (!cls->delete || !(cls->features & FP_DEVICE_FEATURE_STORAGE_DELETE))
|
if (!cls->delete || !(priv->features & FP_DEVICE_FEATURE_STORAGE_DELETE))
|
||||||
{
|
{
|
||||||
g_task_return_boolean (task, TRUE);
|
g_task_return_boolean (task, TRUE);
|
||||||
return;
|
return;
|
||||||
|
@ -1377,7 +1380,7 @@ fp_device_list_prints (FpDevice *device,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cls->list || !(cls->features & FP_DEVICE_FEATURE_STORAGE))
|
if (!cls->list || !(priv->features & FP_DEVICE_FEATURE_STORAGE))
|
||||||
{
|
{
|
||||||
g_task_return_error (task,
|
g_task_return_error (task,
|
||||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_NOT_SUPPORTED,
|
fpi_device_error_new_msg (FP_DEVICE_ERROR_NOT_SUPPORTED,
|
||||||
|
@ -1454,7 +1457,7 @@ fp_device_clear_storage (FpDevice *device,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(cls->features & FP_DEVICE_FEATURE_STORAGE))
|
if (!(priv->features & FP_DEVICE_FEATURE_STORAGE))
|
||||||
{
|
{
|
||||||
g_task_return_error (task,
|
g_task_return_error (task,
|
||||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_NOT_SUPPORTED,
|
fpi_device_error_new_msg (FP_DEVICE_ERROR_NOT_SUPPORTED,
|
||||||
|
@ -1462,7 +1465,7 @@ fp_device_clear_storage (FpDevice *device,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(cls->features & FP_DEVICE_FEATURE_STORAGE_CLEAR))
|
if (!(priv->features & FP_DEVICE_FEATURE_STORAGE_CLEAR))
|
||||||
{
|
{
|
||||||
g_task_return_error (task,
|
g_task_return_error (task,
|
||||||
fpi_device_error_new_msg (FP_DEVICE_ERROR_NOT_SUPPORTED,
|
fpi_device_error_new_msg (FP_DEVICE_ERROR_NOT_SUPPORTED,
|
||||||
|
@ -1805,9 +1808,11 @@ fp_device_clear_storage_sync (FpDevice *device,
|
||||||
FpDeviceFeature
|
FpDeviceFeature
|
||||||
fp_device_get_features (FpDevice *device)
|
fp_device_get_features (FpDevice *device)
|
||||||
{
|
{
|
||||||
|
FpDevicePrivate *priv = fp_device_get_instance_private (device);
|
||||||
|
|
||||||
g_return_val_if_fail (FP_IS_DEVICE (device), FP_DEVICE_FEATURE_NONE);
|
g_return_val_if_fail (FP_IS_DEVICE (device), FP_DEVICE_FEATURE_NONE);
|
||||||
|
|
||||||
return FP_DEVICE_GET_CLASS (device)->features;
|
return priv->features;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -277,6 +277,29 @@ fpi_device_set_scan_type (FpDevice *device,
|
||||||
g_object_notify (G_OBJECT (device), "scan-type");
|
g_object_notify (G_OBJECT (device), "scan-type");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fpi_device_update_features:
|
||||||
|
* @device: The #FpDevice
|
||||||
|
* @update: The feature flags to update
|
||||||
|
* @value: The value to set the flags to
|
||||||
|
*
|
||||||
|
* Updates the feature flags for the device. This can be used
|
||||||
|
* to runtime detect features that are supported by the device.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
fpi_device_update_features (FpDevice *device,
|
||||||
|
FpDeviceFeature update,
|
||||||
|
FpDeviceFeature value)
|
||||||
|
{
|
||||||
|
FpDevicePrivate *priv = fp_device_get_instance_private (device);
|
||||||
|
|
||||||
|
g_return_if_fail (FP_IS_DEVICE (device));
|
||||||
|
g_return_if_fail (priv->current_action == FPI_DEVICE_ACTION_PROBE);
|
||||||
|
g_return_if_fail ((value & update) == value);
|
||||||
|
|
||||||
|
priv->features = (priv->features & ~update) | (value & update);
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
GSource source;
|
GSource source;
|
||||||
|
|
|
@ -249,6 +249,10 @@ void fpi_device_set_nr_enroll_stages (FpDevice *device,
|
||||||
void fpi_device_set_scan_type (FpDevice *device,
|
void fpi_device_set_scan_type (FpDevice *device,
|
||||||
FpScanType scan_type);
|
FpScanType scan_type);
|
||||||
|
|
||||||
|
void fpi_device_update_features (FpDevice *device,
|
||||||
|
FpDeviceFeature update,
|
||||||
|
FpDeviceFeature value);
|
||||||
|
|
||||||
void fpi_device_action_error (FpDevice *device,
|
void fpi_device_action_error (FpDevice *device,
|
||||||
GError *error);
|
GError *error);
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,8 @@ fpi_device_fake_probe (FpDevice *device)
|
||||||
fake_dev->last_called_function = fpi_device_fake_probe;
|
fake_dev->last_called_function = fpi_device_fake_probe;
|
||||||
g_assert_cmpuint (fpi_device_get_current_action (device), ==, FPI_DEVICE_ACTION_PROBE);
|
g_assert_cmpuint (fpi_device_get_current_action (device), ==, FPI_DEVICE_ACTION_PROBE);
|
||||||
|
|
||||||
|
fpi_device_update_features (device, fake_dev->probe_features_update, fake_dev->probe_features_value);
|
||||||
|
|
||||||
if (fake_dev->return_action_error)
|
if (fake_dev->return_action_error)
|
||||||
{
|
{
|
||||||
fpi_device_action_error (device, fake_dev->ret_error);
|
fpi_device_action_error (device, fake_dev->ret_error);
|
||||||
|
|
|
@ -41,4 +41,7 @@ struct _FpiDeviceFake
|
||||||
|
|
||||||
gpointer action_data;
|
gpointer action_data;
|
||||||
gpointer user_data;
|
gpointer user_data;
|
||||||
|
|
||||||
|
FpDeviceFeature probe_features_update;
|
||||||
|
FpDeviceFeature probe_features_value;
|
||||||
};
|
};
|
||||||
|
|
|
@ -509,67 +509,49 @@ test_driver_get_driver_data (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
driver_feature_changes_check (FpDevice *device, gboolean add)
|
test_driver_features_probe_updates (void)
|
||||||
{
|
|
||||||
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(FpDevice) device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
|
||||||
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
|
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
|
||||||
|
FpiDeviceFake *fake_dev;
|
||||||
|
|
||||||
dev_class->features = FP_DEVICE_FEATURE_NONE;
|
g_assert_cmpuint (dev_class->features, !=, FP_DEVICE_FEATURE_NONE);
|
||||||
driver_feature_changes_check (device, TRUE);
|
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_CAPTURE);
|
||||||
driver_feature_changes_check (device, FALSE);
|
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_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE_CLEAR);
|
||||||
|
|
||||||
|
/* Effectively clears FP_DEVICE_FEATURE_STORAGE_DELETE */
|
||||||
|
fake_dev = FPI_DEVICE_FAKE (device);
|
||||||
|
fake_dev->probe_features_update = FP_DEVICE_FEATURE_STORAGE_LIST | FP_DEVICE_FEATURE_STORAGE_DELETE;
|
||||||
|
fake_dev->probe_features_value = FP_DEVICE_FEATURE_STORAGE_LIST;
|
||||||
|
|
||||||
|
g_async_initable_init_async (G_ASYNC_INITABLE (device),
|
||||||
|
G_PRIORITY_DEFAULT, NULL, NULL, NULL);
|
||||||
|
while (g_main_context_iteration (NULL, FALSE))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
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_false (fp_device_has_feature (device, FP_DEVICE_FEATURE_STORAGE_DELETE));
|
||||||
|
g_assert_true (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_CLEAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -588,6 +570,11 @@ test_driver_initial_features (void)
|
||||||
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE_DELETE);
|
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE_DELETE);
|
||||||
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE_CLEAR);
|
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE_CLEAR);
|
||||||
|
|
||||||
|
g_async_initable_init_async (G_ASYNC_INITABLE (device),
|
||||||
|
G_PRIORITY_DEFAULT, NULL, NULL, NULL);
|
||||||
|
while (g_main_context_iteration (NULL, FALSE))
|
||||||
|
continue;
|
||||||
|
|
||||||
g_assert_true (fp_device_has_feature (device, FP_DEVICE_FEATURE_CAPTURE));
|
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_IDENTIFY));
|
||||||
g_assert_true (fp_device_has_feature (device, FP_DEVICE_FEATURE_VERIFY));
|
g_assert_true (fp_device_has_feature (device, FP_DEVICE_FEATURE_VERIFY));
|
||||||
|
@ -2849,7 +2836,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_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_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/get_driver_data", test_driver_get_driver_data);
|
||||||
g_test_add_func ("/driver/features", test_driver_features);
|
g_test_add_func ("/driver/features/probe_updates", test_driver_features_probe_updates);
|
||||||
g_test_add_func ("/driver/initial_features", test_driver_initial_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/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_capture", test_driver_initial_features_no_capture);
|
||||||
|
|
Loading…
Reference in a new issue