device: Add simple temperature model for devices

This temperature model has three states:
 * COLD
 * WARM
 * HOT

Device drivers can define the time it requires for the device to get HOT
and COLD. The underlying model assumes an exponential warming and
cooling process and enforces a cool-off time after the device has
reached the HOT state. This cool down period is however shorter than the
specified time in the driver.
This commit is contained in:
Benjamin Berg
2021-04-21 17:16:03 +02:00
parent 96e5888110
commit a2d950044d
8 changed files with 243 additions and 0 deletions
+71
View File
@@ -48,6 +48,7 @@ enum {
PROP_NR_ENROLL_STAGES,
PROP_SCAN_TYPE,
PROP_FINGER_STATUS,
PROP_TEMPERATURE,
PROP_FPI_ENVIRON,
PROP_FPI_USB_DEVICE,
PROP_FPI_UDEV_DATA_SPIDEV,
@@ -151,6 +152,36 @@ fp_device_constructed (GObject *object)
priv->device_name = g_strdup (cls->full_name);
priv->device_id = g_strdup ("0");
if (cls->temp_hot_seconds > 0)
{
priv->temp_hot_seconds = cls->temp_hot_seconds;
priv->temp_cold_seconds = cls->temp_cold_seconds;
g_assert (priv->temp_cold_seconds > 0);
}
else if (cls->temp_hot_seconds == 0)
{
priv->temp_hot_seconds = DEFAULT_TEMP_HOT_SECONDS;
priv->temp_cold_seconds = DEFAULT_TEMP_COLD_SECONDS;
}
else
{
/* Temperature management disabled */
priv->temp_hot_seconds = -1;
priv->temp_cold_seconds = -1;
}
/* Start out at not completely cold (i.e. assume we are only at the upper
* bound of COLD).
* To be fair, the warm-up from 0 to WARM should be really short either way.
*
* Note that a call to fpi_device_update_temp() is not needed here as no
* timeout must be registered.
*/
priv->temp_current = FP_TEMPERATURE_COLD;
priv->temp_current_ratio = TEMP_COLD_THRESH;
priv->temp_last_update = g_get_monotonic_time ();
priv->temp_last_active = FALSE;
G_OBJECT_CLASS (fp_device_parent_class)->constructed (object);
}
@@ -165,6 +196,8 @@ fp_device_finalize (GObject *object)
if (priv->is_open)
g_warning ("User destroyed open device! Not cleaning up properly!");
g_clear_pointer (&priv->temp_timeout, g_source_destroy);
g_slist_free_full (priv->sources, (GDestroyNotify) g_source_destroy);
g_clear_pointer (&priv->current_idle_cancel_source, g_source_destroy);
@@ -204,6 +237,10 @@ fp_device_get_property (GObject *object,
g_value_set_flags (value, priv->finger_status);
break;
case PROP_TEMPERATURE:
g_value_set_enum (value, priv->temp_current);
break;
case PROP_DRIVER:
g_value_set_static_string (value, FP_DEVICE_GET_CLASS (self)->id);
break;
@@ -358,6 +395,13 @@ fp_device_class_init (FpDeviceClass *klass)
FP_TYPE_FINGER_STATUS_FLAGS, FP_FINGER_STATUS_NONE,
G_PARAM_STATIC_STRINGS | G_PARAM_READABLE);
properties[PROP_TEMPERATURE] =
g_param_spec_enum ("temperature",
"Temperature",
"The temperature estimation for device to prevent overheating.",
FP_TYPE_TEMPERATURE, FP_TEMPERATURE_COLD,
G_PARAM_STATIC_STRINGS | G_PARAM_READABLE);
properties[PROP_DRIVER] =
g_param_spec_string ("driver",
"Driver",
@@ -616,6 +660,25 @@ fp_device_get_nr_enroll_stages (FpDevice *device)
return priv->nr_enroll_stages;
}
/**
* fp_device_get_temperature:
* @device: A #FpDevice
*
* Retrieves simple temperature information for device. It is not possible
* to use a device when this is #FP_TEMPERATURE_HOT.
*
* Returns: The current temperature estimation.
*/
FpTemperature
fp_device_get_temperature (FpDevice *device)
{
FpDevicePrivate *priv = fp_device_get_instance_private (device);
g_return_val_if_fail (FP_IS_DEVICE (device), -1);
return priv->temp_current;
}
/**
* fp_device_supports_identify:
* @device: A #FpDevice
@@ -902,6 +965,8 @@ fp_device_enroll (FpDevice *device,
priv->current_task = g_steal_pointer (&task);
maybe_cancel_on_cancelled (device, cancellable);
fpi_device_update_temp (device, TRUE);
data = g_new0 (FpEnrollData, 1);
data->print = g_object_ref_sink (template_print);
data->enroll_progress_cb = progress_cb;
@@ -995,6 +1060,8 @@ fp_device_verify (FpDevice *device,
priv->current_task = g_steal_pointer (&task);
maybe_cancel_on_cancelled (device, cancellable);
fpi_device_update_temp (device, TRUE);
data = g_new0 (FpMatchData, 1);
data->enrolled_print = g_object_ref (enrolled_print);
data->match_cb = match_cb;
@@ -1114,6 +1181,8 @@ fp_device_identify (FpDevice *device,
priv->current_task = g_steal_pointer (&task);
maybe_cancel_on_cancelled (device, cancellable);
fpi_device_update_temp (device, TRUE);
data = g_new0 (FpMatchData, 1);
/* We cannot store the gallery directly, because the ptr array may not own
* a reference to each print. Also, the caller could in principle modify the
@@ -1231,6 +1300,8 @@ fp_device_capture (FpDevice *device,
priv->current_task = g_steal_pointer (&task);
maybe_cancel_on_cancelled (device, cancellable);
fpi_device_update_temp (device, TRUE);
priv->wait_for_finger = wait_for_finger;
cls->capture (device);