Commit 704c19b8 authored by Bastien Nocera's avatar Bastien Nocera

device: Restart verification if error is "retry"

fprintd's API docs say that "retry" errors for verification
"the verification is still ongoing" and that "[the] user should retry
scanning their finger.

Unfortunately, retry errors are fatal in libfprint. Make fprintd restart
operations when "retry" is the error for either identification or
verification purposes.

We need to also make sure that a "*Stop" D-Bus call will return as
normal if called while we're stopping a verification or identification
in order to restart it.

Closes: #22
parent 8f90390c
Pipeline #54795 passed with stage
in 4 minutes and 38 seconds
......@@ -749,8 +749,30 @@ static void fprint_device_release(FprintDevice *rdev,
}
}
static void verify_cb(struct fp_dev *dev, int r, struct fp_img *img,
void *user_data)
static void verify_cb(struct fp_dev *dev,
int r,
struct fp_img *img,
void *user_data);
static void
verify_restart_cb(struct fp_dev *dev,
void *user_data)
{
struct FprintDevice *rdev = user_data;
FprintDevicePrivate *priv = DEVICE_GET_PRIVATE(rdev);
if (priv->current_action != ACTION_VERIFY)
return;
g_debug("verify_restart_cb: restarting verification");
fp_async_verify_start(priv->dev, priv->verify_data, verify_cb, rdev);
}
static void
verify_cb(struct fp_dev *dev,
int r,
struct fp_img *img,
void *user_data)
{
struct FprintDevice *rdev = user_data;
FprintDevicePrivate *priv = DEVICE_GET_PRIVATE(rdev);
......@@ -761,8 +783,20 @@ static void verify_cb(struct fp_dev *dev, int r, struct fp_img *img,
g_debug("verify_cb: result %s (%d)", name, r);
if (r == FP_VERIFY_NO_MATCH || r == FP_VERIFY_MATCH || r < 0)
priv->action_done = TRUE;
if (r == FP_VERIFY_RETRY ||
r == FP_VERIFY_RETRY_TOO_SHORT ||
r == FP_VERIFY_RETRY_CENTER_FINGER ||
r == FP_VERIFY_RETRY_REMOVE_FINGER) {
g_debug ("verify_cb: stopping current verification to retry");
fp_img_free(img);
if (fp_async_verify_stop(priv->dev, verify_restart_cb, user_data) == 0) {
g_signal_emit(rdev, signals[SIGNAL_VERIFY_STATUS], 0, name, priv->action_done);
return;
}
/* fallthrough to error out if restarting failed */
}
priv->action_done = TRUE;
set_disconnected (priv, name);
g_signal_emit(rdev, signals[SIGNAL_VERIFY_STATUS], 0, name, priv->action_done);
fp_img_free(img);
......@@ -773,8 +807,32 @@ static void verify_cb(struct fp_dev *dev, int r, struct fp_img *img,
}
}
static void identify_cb(struct fp_dev *dev, int r,
size_t match_offset, struct fp_img *img, void *user_data)
static void identify_cb(struct fp_dev *dev,
int r,
size_t match_offset,
struct fp_img *img,
void *user_data);
static void
identify_restart_cb(struct fp_dev *dev,
void *user_data)
{
struct FprintDevice *rdev = user_data;
FprintDevicePrivate *priv = DEVICE_GET_PRIVATE(rdev);
if (priv->current_action != ACTION_IDENTIFY)
return;
g_debug("identify_restart_cb: restarting identification");
fp_async_identify_start (priv->dev, priv->identify_data, identify_cb, rdev);
}
static void
identify_cb(struct fp_dev *dev,
int r,
size_t match_offset,
struct fp_img *img,
void *user_data)
{
struct FprintDevice *rdev = user_data;
FprintDevicePrivate *priv = DEVICE_GET_PRIVATE(rdev);
......@@ -785,8 +843,20 @@ static void identify_cb(struct fp_dev *dev, int r,
g_debug("identify_cb: result %s (%d)", name, r);
if (r == FP_VERIFY_NO_MATCH || r == FP_VERIFY_MATCH || r < 0)
priv->action_done = TRUE;
if (r == FP_VERIFY_RETRY ||
r == FP_VERIFY_RETRY_TOO_SHORT ||
r == FP_VERIFY_RETRY_CENTER_FINGER ||
r == FP_VERIFY_RETRY_REMOVE_FINGER) {
g_debug ("identify_cb: stopping current identification to retry");
fp_img_free(img);
if (fp_async_identify_stop(priv->dev, identify_restart_cb, user_data) == 0) {
g_signal_emit(rdev, signals[SIGNAL_VERIFY_STATUS], 0, name, priv->action_done);
return;
}
/* fallthrough to error out if restarting failed */
}
priv->action_done = TRUE;
set_disconnected (priv, name);
g_signal_emit(rdev, signals[SIGNAL_VERIFY_STATUS], 0, name, priv->action_done);
fp_img_free(img);
......@@ -990,6 +1060,13 @@ static void fprint_device_verify_stop(FprintDevice *rdev,
return;
}
if (r == -EINPROGRESS) {
g_debug ("%s stop already in progress",
priv->current_action == ACTION_VERIFY ? "verification" : "identification");
dbus_g_method_return(context);
r = 0;
}
if (r < 0) {
g_set_error(&error, FPRINT_ERROR, FPRINT_ERROR_INTERNAL,
"Verify stop failed with error %d", r);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment