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
This commit is contained in:
Bastien Nocera
2019-08-07 15:27:37 +02:00
parent 8f90390c6b
commit 704c19b87a

View File

@ -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);